badline 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -0
- data/CLAUDE.md +15 -5
- data/README.md +68 -8
- data/doc/pinned-behaviour.md +145 -0
- data/doc/snapshot-format.md +188 -38
- data/doc/snapshots.md +18 -1
- data/lib/badline/audio/bare_player.rb +4 -8
- data/lib/badline/audio/machine_player.rb +2 -12
- data/lib/badline/c128/banks.rb +1 -3
- data/lib/badline/c128/bus.rb +19 -1
- data/lib/badline/c128/mmu_pages.rb +7 -0
- data/lib/badline/c64/bus/extra_sids.rb +80 -0
- data/lib/badline/c64/bus.rb +1 -0
- data/lib/badline/c64/cartridge/action_replay.rb +6 -2
- data/lib/badline/c64/cartridge/comal80.rb +1 -0
- data/lib/badline/c64/cartridge/dinamic.rb +3 -1
- data/lib/badline/c64/cartridge/final_cartridge3.rb +1 -0
- data/lib/badline/c64/cartridge/fun_play.rb +2 -1
- data/lib/badline/c64/cartridge/game_system.rb +2 -1
- data/lib/badline/c64/cartridge/keyed_state.rb +155 -34
- data/lib/badline/c64/cartridge/magic_desk.rb +2 -1
- data/lib/badline/c64/cartridge/ocean.rb +1 -0
- data/lib/badline/c64/cartridge/pagefox.rb +1 -0
- data/lib/badline/c64/cartridge/rgcd.rb +2 -1
- data/lib/badline/c64/cartridge/super_games.rb +3 -2
- data/lib/badline/c64/cartridge/zaxxon.rb +1 -0
- data/lib/badline/c64/cartridge.rb +3 -3
- data/lib/badline/c64/keyed_modules.rb +6 -2
- data/lib/badline/chips/ted/beam.rb +13 -14
- data/lib/badline/chips/ted/fetches.rb +199 -0
- data/lib/badline/chips/ted/keyed_state.rb +156 -0
- data/lib/badline/chips/ted/modes.rb +134 -0
- data/lib/badline/chips/ted/palette.rb +43 -0
- data/lib/badline/chips/ted/picture.rb +182 -0
- data/lib/badline/chips/ted/sound/output.rb +86 -0
- data/lib/badline/chips/ted/sound.rb +284 -0
- data/lib/badline/chips/ted.rb +53 -6
- data/lib/badline/chips/tia.rb +12 -0
- data/lib/badline/drives/datasette/keyed_state.rb +7 -2
- data/lib/badline/drives/datasette.rb +22 -5
- data/lib/badline/frontend/boot.rb +3 -1
- data/lib/badline/frontend/controls.rb +7 -3
- data/lib/badline/frontend/keys.rb +14 -2
- data/lib/badline/frontend/media_slots.rb +11 -1
- data/lib/badline/frontend/menu/menu_dialogs.rb +2 -1
- data/lib/badline/frontend/menu/menu_media.rb +13 -3
- data/lib/badline/frontend/menu/menu_pages.rb +8 -8
- data/lib/badline/frontend/menu/menu_ports.rb +13 -1
- data/lib/badline/frontend/screen.rb +33 -12
- data/lib/badline/frontend/screens.rb +2 -1
- data/lib/badline/frontend/sound.rb +4 -4
- data/lib/badline/frontend/timeline.rb +19 -6
- data/lib/badline/machine/settling.rb +1 -1
- data/lib/badline/machine.rb +26 -6
- data/lib/badline/media/plus4_media.rb +68 -0
- data/lib/badline/media/program.rb +20 -6
- data/lib/badline/media.rb +33 -12
- data/lib/badline/options/family.rb +1 -0
- data/lib/badline/options/help.rb +30 -6
- data/lib/badline/options/table.rb +15 -2
- data/lib/badline/options/validation.rb +26 -4
- data/lib/badline/options.rb +37 -9
- data/lib/badline/plus4/bus.rb +77 -14
- data/lib/badline/plus4/cassette_sense.rb +21 -0
- data/lib/badline/plus4/keyboard_port.rb +35 -10
- data/lib/badline/plus4/keyed_modules.rb +99 -0
- data/lib/badline/plus4/keyed_parts.rb +143 -0
- data/lib/badline/plus4/keyed_state.rb +41 -0
- data/lib/badline/plus4.rb +92 -16
- data/lib/badline/snapshot/container.rb +2 -0
- data/lib/badline/snapshot/field_doc/markdown.rb +7 -6
- data/lib/badline/snapshot/field_doc.rb +46 -7
- data/lib/badline/snapshot/image.rb +12 -3
- data/lib/badline/snapshot/plus4_setup.rb +39 -0
- data/lib/badline/snapshot.rb +9 -4
- data/lib/badline/storage/g64_image.rb +1 -1
- data/lib/badline/storage/tap.rb +21 -12
- data/lib/badline/support/checkpoint.rb +3 -2
- data/lib/badline/support/plus4_checkpoint.rb +42 -0
- data/lib/badline/version.rb +1 -1
- metadata +15 -1
|
@@ -12,13 +12,15 @@ module Badline
|
|
|
12
12
|
|
|
13
13
|
def peek(addr)
|
|
14
14
|
if addr < 0xde10
|
|
15
|
-
@
|
|
15
|
+
@bank = addr & 0x0f
|
|
16
|
+
@roml = bank(@banks, @bank)
|
|
16
17
|
changed!
|
|
17
18
|
end
|
|
18
19
|
open_bus(addr)
|
|
19
20
|
end
|
|
20
21
|
|
|
21
22
|
def reset
|
|
23
|
+
@bank = 0
|
|
22
24
|
@roml = bank(@banks, 0)
|
|
23
25
|
changed!
|
|
24
26
|
end
|
|
@@ -10,7 +10,8 @@ module Badline
|
|
|
10
10
|
def poke(addr, value)
|
|
11
11
|
return if addr > 0xdeff
|
|
12
12
|
|
|
13
|
-
@
|
|
13
|
+
@bank = self.class.bank_number(value)
|
|
14
|
+
@roml = bank(@banks, @bank)
|
|
14
15
|
case value & 0xc6
|
|
15
16
|
when 0x00 then self.mode = :rom8k
|
|
16
17
|
when 0x86 then self.mode = :off
|
|
@@ -6,9 +6,13 @@ module Badline
|
|
|
6
6
|
# A cartridge's fields in a keyed snapshot module (Snapshot::Keyed,
|
|
7
7
|
# BL-CART): the CRT image it was built from and its jumpers, which
|
|
8
8
|
# build it again (Cartridge.from_fields), the EXROM and GAME lines,
|
|
9
|
-
# its pull on NMI, the button, and
|
|
10
|
-
#
|
|
11
|
-
#
|
|
9
|
+
# its pull on NMI, the button, and each mapper's own registers, from
|
|
10
|
+
# which a load works out where ROML and ROMH point again.
|
|
11
|
+
#
|
|
12
|
+
# Snapshots from 0.14.0 name the bank or view each window shows
|
|
13
|
+
# instead (window_labels), under roml and romh. A load reads those
|
|
14
|
+
# when the mapper's register isn't there, and works the register out
|
|
15
|
+
# from the windows.
|
|
12
16
|
module KeyedState
|
|
13
17
|
def save_fields(out)
|
|
14
18
|
save_setup_fields(out)
|
|
@@ -34,12 +38,28 @@ module Badline
|
|
|
34
38
|
|
|
35
39
|
def save_jumper_fields(_out); end
|
|
36
40
|
|
|
37
|
-
def save_mapper_fields(
|
|
38
|
-
|
|
39
|
-
end
|
|
41
|
+
def save_mapper_fields(_out); end
|
|
42
|
+
|
|
43
|
+
def load_mapper_fields(_input); end
|
|
44
|
+
|
|
45
|
+
# The register at `key`, cut to `mask`, or nil for a snapshot that
|
|
46
|
+
# names the windows instead, with the windows put back from their
|
|
47
|
+
# names.
|
|
48
|
+
def latch_or_windows(input, key, default, mask)
|
|
49
|
+
return input.masked(key, default, mask) if input.tags.key?(key)
|
|
40
50
|
|
|
41
|
-
def load_mapper_fields(input)
|
|
42
51
|
load_window_fields(input)
|
|
52
|
+
nil
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# The number of the bank among `banks` that `window` shows, or of the
|
|
56
|
+
# first the image leaves out for erased ROM.
|
|
57
|
+
def number_showing(banks, window)
|
|
58
|
+
number = banks.index { |each| each.equal?(window) }
|
|
59
|
+
return number if number
|
|
60
|
+
return 0 unless window.equal?(EMPTY_BANK)
|
|
61
|
+
|
|
62
|
+
banks.index(nil) || banks.length
|
|
43
63
|
end
|
|
44
64
|
|
|
45
65
|
# The name of each of `windows`, in the same order: bank<N> for the
|
|
@@ -51,21 +71,6 @@ module Badline
|
|
|
51
71
|
[*Array.new(banks.length) { |number| "bank#{number}" }, "empty"]
|
|
52
72
|
end
|
|
53
73
|
|
|
54
|
-
def save_window_fields(out)
|
|
55
|
-
choices = windows
|
|
56
|
-
return unless choices
|
|
57
|
-
|
|
58
|
-
labels = window_labels
|
|
59
|
-
save_window(out, "roml", @roml, choices, labels)
|
|
60
|
-
save_window(out, "romh", @romh, choices, labels)
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def save_window(out, key, window, choices, labels)
|
|
64
|
-
return if window.nil?
|
|
65
|
-
|
|
66
|
-
out.text(key, labels.fetch(window_index(window, choices)))
|
|
67
|
-
end
|
|
68
|
-
|
|
69
74
|
def load_window_fields(input)
|
|
70
75
|
choices = windows
|
|
71
76
|
return unless choices
|
|
@@ -97,21 +102,104 @@ module Badline
|
|
|
97
102
|
def from_jumper_fields(crt, _input) = new(crt)
|
|
98
103
|
end
|
|
99
104
|
|
|
100
|
-
#
|
|
105
|
+
# One bank register, under bank, selecting the bank ROML shows.
|
|
106
|
+
module BankLatch
|
|
107
|
+
private
|
|
108
|
+
|
|
109
|
+
def save_mapper_fields(out)
|
|
110
|
+
out.int("bank", @bank)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def load_mapper_fields(input)
|
|
114
|
+
latch = latch_or_windows(input, "bank", @bank, bank_latch_mask)
|
|
115
|
+
if latch.nil?
|
|
116
|
+
@bank = number_showing(@banks, @roml)
|
|
117
|
+
else
|
|
118
|
+
@bank = latch
|
|
119
|
+
show_bank
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def show_bank
|
|
124
|
+
@roml = bank(@banks, @bank)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Two banks of ROM, one behind each window: roml<N> and romh<N>, both
|
|
129
|
+
# selected by one bank register, under bank.
|
|
101
130
|
module SplitBanks
|
|
102
131
|
private
|
|
103
132
|
|
|
133
|
+
def save_mapper_fields(out)
|
|
134
|
+
out.int("bank", @bank)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def load_mapper_fields(input)
|
|
138
|
+
latch = latch_or_windows(input, "bank", @bank, bank_latch_mask)
|
|
139
|
+
if latch.nil?
|
|
140
|
+
@bank = number_showing(@roml_banks, @roml)
|
|
141
|
+
else
|
|
142
|
+
@bank = latch
|
|
143
|
+
@roml = bank(@roml_banks, @bank)
|
|
144
|
+
@romh = bank(@romh_banks, @bank)
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
104
148
|
def window_labels
|
|
105
149
|
[*Array.new(@roml_banks.length) { |number| "roml#{number}" },
|
|
106
150
|
*Array.new(@romh_banks.length) { |number| "romh#{number}" }, "empty"]
|
|
107
151
|
end
|
|
108
152
|
end
|
|
109
153
|
|
|
154
|
+
class Ocean
|
|
155
|
+
include BankLatch
|
|
156
|
+
|
|
157
|
+
private
|
|
158
|
+
|
|
159
|
+
def bank_latch_mask = @bank_mask
|
|
160
|
+
|
|
161
|
+
def show_bank = select_bank(@bank)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
class FunPlay
|
|
165
|
+
include BankLatch
|
|
166
|
+
|
|
167
|
+
private
|
|
168
|
+
|
|
169
|
+
def bank_latch_mask = 0x0f
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
class GameSystem
|
|
173
|
+
include BankLatch
|
|
174
|
+
|
|
175
|
+
private
|
|
176
|
+
|
|
177
|
+
def bank_latch_mask = 0x3f
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
class Dinamic
|
|
181
|
+
include BankLatch
|
|
182
|
+
|
|
183
|
+
private
|
|
184
|
+
|
|
185
|
+
def bank_latch_mask = 0x0f
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
class MagicDesk
|
|
189
|
+
include BankLatch
|
|
190
|
+
|
|
191
|
+
private
|
|
192
|
+
|
|
193
|
+
def bank_latch_mask = @bank_mask
|
|
194
|
+
end
|
|
195
|
+
|
|
110
196
|
class SuperGames
|
|
111
197
|
include SplitBanks
|
|
112
198
|
|
|
113
199
|
private
|
|
114
200
|
|
|
201
|
+
def bank_latch_mask = 0x03
|
|
202
|
+
|
|
115
203
|
def save_mapper_fields(out)
|
|
116
204
|
super
|
|
117
205
|
out.bool("locked", @locked)
|
|
@@ -125,6 +213,10 @@ module Badline
|
|
|
125
213
|
|
|
126
214
|
class Comal80
|
|
127
215
|
include SplitBanks
|
|
216
|
+
|
|
217
|
+
private
|
|
218
|
+
|
|
219
|
+
def bank_latch_mask = 0x07
|
|
128
220
|
end
|
|
129
221
|
|
|
130
222
|
class FinalCartridge3
|
|
@@ -132,6 +224,8 @@ module Badline
|
|
|
132
224
|
|
|
133
225
|
private
|
|
134
226
|
|
|
227
|
+
def bank_latch_mask = @bank_mask
|
|
228
|
+
|
|
135
229
|
def save_mapper_fields(out)
|
|
136
230
|
super
|
|
137
231
|
out.bool("register_visible", @register_visible).bool("phi1_ultimax", @phi1_ultimax)
|
|
@@ -146,8 +240,12 @@ module Badline
|
|
|
146
240
|
end
|
|
147
241
|
|
|
148
242
|
class RGCD
|
|
243
|
+
include BankLatch
|
|
244
|
+
|
|
149
245
|
private
|
|
150
246
|
|
|
247
|
+
def bank_latch_mask = @bank_mask
|
|
248
|
+
|
|
151
249
|
def save_mapper_fields(out)
|
|
152
250
|
super
|
|
153
251
|
out.bool("disabled", @disabled)
|
|
@@ -162,12 +260,11 @@ module Badline
|
|
|
162
260
|
class Zaxxon
|
|
163
261
|
class High
|
|
164
262
|
def save_fields(out)
|
|
165
|
-
out.int("high_bank",
|
|
263
|
+
out.int("high_bank", @number)
|
|
166
264
|
end
|
|
167
265
|
|
|
168
266
|
def load_fields(input)
|
|
169
|
-
|
|
170
|
-
@bank = choices.fetch(input.int("high_bank", 0).clamp(0, choices.length - 1))
|
|
267
|
+
select(input.int("high_bank", 0).clamp(0, @banks.length))
|
|
171
268
|
end
|
|
172
269
|
end
|
|
173
270
|
|
|
@@ -204,18 +301,35 @@ module Badline
|
|
|
204
301
|
end
|
|
205
302
|
|
|
206
303
|
def save_mapper_fields(out)
|
|
207
|
-
|
|
208
|
-
out.text("rom", window_labels.fetch(window_index(@rom, windows))).bool("active", @active)
|
|
209
|
-
out.bool("io2_ram", @io2_ram).bytes("ram", @ram_data)
|
|
304
|
+
out.int("control", @control).bool("active", @active).bytes("ram", @ram_data)
|
|
210
305
|
end
|
|
211
306
|
|
|
212
307
|
def load_mapper_fields(input)
|
|
213
|
-
|
|
308
|
+
latch = latch_or_windows(input, "control", @control, 0xff)
|
|
309
|
+
if latch.nil?
|
|
310
|
+
load_legacy_fields(input)
|
|
311
|
+
else
|
|
312
|
+
@control = latch
|
|
313
|
+
@rom = bank(@rom_banks, (@control >> 3) & 0x03)
|
|
314
|
+
configure(@control)
|
|
315
|
+
end
|
|
316
|
+
@active = input.bool("active", @active)
|
|
317
|
+
input.bytes_into("ram", @ram_data)
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
# The ROM bank by name, and whether I/O 2 shows the RAM, from which
|
|
321
|
+
# the register is worked out.
|
|
322
|
+
def load_legacy_fields(input)
|
|
214
323
|
labels = window_labels
|
|
215
324
|
@rom = window_named(input.choice("rom", labels, "rom0"), windows, labels)
|
|
216
|
-
@active = input.bool("active", @active)
|
|
217
325
|
@io2_ram = input.bool("io2_ram", @io2_ram)
|
|
218
|
-
|
|
326
|
+
number = number_showing(@rom_banks, @rom) << 3
|
|
327
|
+
@control = if @roml.equal?(@contended) || @romh.equal?(@isolated)
|
|
328
|
+
0x22 | number
|
|
329
|
+
else
|
|
330
|
+
mode = @exrom.zero? ? 1 - @game : 3 - @game
|
|
331
|
+
mode | (@io2_ram ? 0x20 : 0) | number
|
|
332
|
+
end
|
|
219
333
|
end
|
|
220
334
|
end
|
|
221
335
|
|
|
@@ -237,12 +351,19 @@ module Badline
|
|
|
237
351
|
end
|
|
238
352
|
|
|
239
353
|
def save_mapper_fields(out)
|
|
240
|
-
|
|
354
|
+
out.int("control", @control)
|
|
241
355
|
@ram_banks.each_with_index { |ram, number| out.bytes("ram#{number}.data", ram.data) }
|
|
242
356
|
end
|
|
243
357
|
|
|
244
358
|
def load_mapper_fields(input)
|
|
245
|
-
|
|
359
|
+
latch = latch_or_windows(input, "control", @control, 0xff)
|
|
360
|
+
if latch.nil?
|
|
361
|
+
selected = (0...8).find { |select| window(select >> 1, select & 0x01) == [@roml, @romh] } || 0
|
|
362
|
+
@control = (selected << 1) | (@exrom == 1 && @game == 1 ? 0x10 : 0)
|
|
363
|
+
else
|
|
364
|
+
@control = latch
|
|
365
|
+
@roml, @romh = window((@control >> 2) & 0x03, (@control >> 1) & 0x01)
|
|
366
|
+
end
|
|
246
367
|
@ram_banks.each_with_index { |ram, number| input.bytes_into("ram#{number}.data", ram.data) }
|
|
247
368
|
end
|
|
248
369
|
end
|
|
@@ -24,8 +24,9 @@ module Badline
|
|
|
24
24
|
def windows = [*@roml_banks, *@romh_banks, EMPTY_BANK]
|
|
25
25
|
|
|
26
26
|
def select(value)
|
|
27
|
-
@
|
|
28
|
-
@
|
|
27
|
+
@bank = value & 0x03
|
|
28
|
+
@roml = bank(@roml_banks, @bank)
|
|
29
|
+
@romh = bank(@romh_banks, @bank)
|
|
29
30
|
self.mode = value.anybits?(0x04) ? :off : :rom16k
|
|
30
31
|
@locked = value.anybits?(0x08)
|
|
31
32
|
end
|
|
@@ -152,9 +152,9 @@ module Badline
|
|
|
152
152
|
|
|
153
153
|
private
|
|
154
154
|
|
|
155
|
-
# The banks and views ROML and ROMH can point at, which a
|
|
156
|
-
# names them by: the mapper's banks, or nothing for a mapper
|
|
157
|
-
# windows stay where install_chips put them.
|
|
155
|
+
# The banks and views ROML and ROMH can point at, which a 0.14.0
|
|
156
|
+
# snapshot names them by: the mapper's banks, or nothing for a mapper
|
|
157
|
+
# whose windows stay where install_chips put them.
|
|
158
158
|
def windows
|
|
159
159
|
[*@banks, EMPTY_BANK] if @banks
|
|
160
160
|
end
|
|
@@ -4,8 +4,9 @@ module Badline
|
|
|
4
4
|
class C64
|
|
5
5
|
# The whole machine as keyed snapshot modules (Snapshot::Keyed), in the
|
|
6
6
|
# order a load applies them: BL-MACHINE with the setup, the memories,
|
|
7
|
-
# the cartridge, the CPU with its port, the chips
|
|
8
|
-
# datasette, device 8 through the traps
|
|
7
|
+
# the cartridge, the CPU with its port, the chips with any extra SIDs
|
|
8
|
+
# (Bus::ExtraSIDs), an REU, the datasette, device 8 through the traps
|
|
9
|
+
# and the true drives. A load
|
|
9
10
|
# reads the CPU's port before the chips, so the banks are mapped as the
|
|
10
11
|
# chips load, and the CPU's own fields after them. What each unit works
|
|
11
12
|
# out again from its fields comes last, once every unit is loaded.
|
|
@@ -60,6 +61,7 @@ module Badline
|
|
|
60
61
|
sections << Snapshot::Keyed.section("BL-CIA1") { |out| @cia1.save_fields(out) }
|
|
61
62
|
sections << Snapshot::Keyed.section("BL-CIA2") { |out| @cia2.save_fields(out) }
|
|
62
63
|
sections << Snapshot::Keyed.section("BL-SID") { |out| @sid.save_fields(out) }
|
|
64
|
+
bus.save_extra_sid_modules(sections)
|
|
63
65
|
end
|
|
64
66
|
|
|
65
67
|
def load_chip_modules(modules, cpu)
|
|
@@ -67,6 +69,7 @@ module Badline
|
|
|
67
69
|
@cia1.load_fields(modules.required("BL-CIA1"))
|
|
68
70
|
@cia2.load_fields(modules.required("BL-CIA2"))
|
|
69
71
|
@sid.load_fields(modules.required("BL-SID"))
|
|
72
|
+
address_bus.load_extra_sid_modules(modules)
|
|
70
73
|
@reu&.load_fields(modules.required("BL-REU"))
|
|
71
74
|
@cpu.load_fields(cpu)
|
|
72
75
|
end
|
|
@@ -94,6 +97,7 @@ module Badline
|
|
|
94
97
|
@cia1.restored!
|
|
95
98
|
@cia2.restored!
|
|
96
99
|
@sid.restored!
|
|
100
|
+
address_bus.extra_sids.each(&:restored!)
|
|
97
101
|
@reu&.restored!
|
|
98
102
|
machine_restored!
|
|
99
103
|
end
|
|
@@ -46,6 +46,11 @@ module Badline
|
|
|
46
46
|
DOUBLE_COLUMNS = (43..49)
|
|
47
47
|
LAST_DISPLAY_LINE = 203
|
|
48
48
|
|
|
49
|
+
# The DMA a line makes: none, the attributes or the pointers.
|
|
50
|
+
NO_DMA = 0
|
|
51
|
+
ATTRIBUTE_DMA = 1
|
|
52
|
+
POINTER_DMA = 2
|
|
53
|
+
|
|
49
54
|
# The single clock cycle in the line, 0-56.
|
|
50
55
|
attr_reader :column
|
|
51
56
|
|
|
@@ -67,7 +72,6 @@ module Badline
|
|
|
67
72
|
def reset_beam
|
|
68
73
|
@column = 0
|
|
69
74
|
@line = 0
|
|
70
|
-
@dma_line = false
|
|
71
75
|
@ba_low = false
|
|
72
76
|
@cpu_slots = 1
|
|
73
77
|
end
|
|
@@ -79,14 +83,19 @@ module Badline
|
|
|
79
83
|
return unless column == LINE_STEP_COLUMN
|
|
80
84
|
|
|
81
85
|
line = @line + 1
|
|
82
|
-
|
|
86
|
+
if line >= lines_per_frame
|
|
87
|
+
line = 0
|
|
88
|
+
end_frame
|
|
89
|
+
end
|
|
90
|
+
step_row_line(line)
|
|
91
|
+
step_scanline(line)
|
|
83
92
|
self.line = line
|
|
84
93
|
end
|
|
85
94
|
|
|
95
|
+
# The clock for the cycle. Freeze leaves single clock, without DMA.
|
|
86
96
|
def decide_clock
|
|
87
97
|
column = @column
|
|
88
|
-
@
|
|
89
|
-
if @dma_line && (column >= BA_COLUMN || column <= DMA_END_COLUMN)
|
|
98
|
+
if @dma_kind != NO_DMA && (column >= BA_COLUMN || column <= DMA_END_COLUMN) && !frozen?
|
|
90
99
|
@ba_low = true
|
|
91
100
|
@cpu_slots = column >= DMA_COLUMN || column <= DMA_END_COLUMN ? 0 : 1
|
|
92
101
|
return
|
|
@@ -103,16 +112,6 @@ module Badline
|
|
|
103
112
|
end
|
|
104
113
|
|
|
105
114
|
def display_window? = @registers[0x06].anybits?(0x10) && @line <= LAST_DISPLAY_LINE
|
|
106
|
-
|
|
107
|
-
def dma_line?
|
|
108
|
-
return false unless @registers[0x06].anybits?(0x10)
|
|
109
|
-
|
|
110
|
-
phase = (@line - (@registers[0x06] & 0x07)) & 0x07
|
|
111
|
-
return false if phase > 1
|
|
112
|
-
|
|
113
|
-
row = phase.zero? ? @line + 1 : @line
|
|
114
|
-
row <= LAST_DISPLAY_LINE
|
|
115
|
-
end
|
|
116
115
|
end
|
|
117
116
|
end
|
|
118
117
|
end
|