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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +193 -0
- data/CLAUDE.md +19 -7
- data/CONTRIBUTING.md +11 -1
- data/README.md +178 -26
- data/doc/library.md +5 -1
- data/doc/media.md +3 -2
- data/doc/pinned-behaviour.md +169 -1
- data/doc/snapshot-format.md +302 -35
- data/doc/snapshots.md +97 -26
- data/doc/vice.md +344 -0
- data/exe/badline-ruby +5 -0
- data/lib/badline/audio/renderer.rb +4 -8
- data/lib/badline/audio/terminal.rb +34 -2
- data/lib/badline/c128/keyed_state.rb +2 -0
- data/lib/badline/c128.rb +5 -0
- data/lib/badline/c64/bus/fittings.rb +6 -0
- data/lib/badline/c64/keyed_state.rb +2 -0
- data/lib/badline/c64.rb +7 -0
- data/lib/badline/cbm2/keyed_state.rb +4 -0
- data/lib/badline/cbm2/p500.rb +9 -3
- data/lib/badline/cbm2.rb +10 -3
- data/lib/badline/chips/cia/timer.rb +2 -2
- data/lib/badline/chips/cpu/core.rb +29 -4
- data/lib/badline/chips/cpu/instruction_set.rb +1 -1
- data/lib/badline/chips/cpu/interrupts.rb +9 -0
- data/lib/badline/chips/cpu/keyed_state.rb +15 -9
- data/lib/badline/chips/cpu/microcode.rb +10 -0
- data/lib/badline/chips/m6809/arithmetic.rb +140 -0
- data/lib/badline/chips/m6809/bus_steps.rb +223 -0
- data/lib/badline/chips/m6809/core.rb +149 -0
- data/lib/badline/chips/m6809/indexed.rb +82 -0
- data/lib/badline/chips/m6809/interrupts.rb +159 -0
- data/lib/badline/chips/m6809/keyed_state.rb +147 -0
- data/lib/badline/chips/m6809/opcodes.rb +159 -0
- data/lib/badline/chips/m6809/operations.rb +258 -0
- data/lib/badline/chips/m6809/plans.rb +143 -0
- data/lib/badline/chips/m6809/registers.rb +82 -0
- data/lib/badline/chips/m6809/stack.rb +140 -0
- data/lib/badline/chips/m6809.rb +13 -0
- data/lib/badline/chips/riot/timer.rb +14 -3
- data/lib/badline/chips/rriot.rb +8 -3
- data/lib/badline/chips/sid/decimator.rb +1 -1
- data/lib/badline/chips/sid/filter.rb +4 -4
- data/lib/badline/chips/sid/keyed_parts.rb +51 -18
- data/lib/badline/chips/sid/waveform.rb +6 -6
- data/lib/badline/chips/sid.rb +6 -2
- data/lib/badline/chips/vic_i/keyed_parts.rb +12 -2
- data/lib/badline/chips/vic_i/light_pen.rb +89 -0
- data/lib/badline/chips/vic_i.rb +91 -23
- data/lib/badline/data_path.rb +3 -3
- data/lib/badline/drives/ieee_models.rb +54 -0
- data/lib/badline/drives/model1001.rb +37 -0
- data/lib/badline/drives/model1541/sector_reader.rb +20 -3
- data/lib/badline/drives/model1541.rb +1 -0
- data/lib/badline/drives/model1551.rb +1 -0
- data/lib/badline/drives/model1571.rb +1 -0
- data/lib/badline/drives/model1581.rb +1 -0
- data/lib/badline/drives/model2031.rb +7 -0
- data/lib/badline/drives/model4040/disk.rb +62 -0
- data/lib/badline/drives/model4040/ip_bus.rb +46 -0
- data/lib/badline/drives/model4040/keyed_state.rb +57 -0
- data/lib/badline/drives/model4040/mechanism.rb +195 -0
- data/lib/badline/drives/model4040/parts.rb +20 -0
- data/lib/badline/drives/model4040.rb +195 -0
- data/lib/badline/drives/model8050/board.rb +79 -0
- data/lib/badline/drives/model8050/dos_board.rb +134 -0
- data/lib/badline/drives/model8050/fdc_bus.rb +7 -0
- data/lib/badline/drives/model8050/idle.rb +148 -31
- data/lib/badline/drives/model8050/keyed_state.rb +5 -2
- data/lib/badline/drives/model8050.rb +32 -130
- data/lib/badline/drives/model9060/idle.rb +169 -0
- data/lib/badline/drives/model9060/keyed_state.rb +123 -0
- data/lib/badline/drives/model9060/parts.rb +98 -0
- data/lib/badline/drives/model9060/sasi_bus.rb +88 -0
- data/lib/badline/drives/model9060/sasi_commands.rb +168 -0
- data/lib/badline/drives/model9060/sasi_target.rb +161 -0
- data/lib/badline/drives/model9060.rb +197 -0
- data/lib/badline/frontend/app.rb +8 -0
- data/lib/badline/frontend/boot.rb +3 -2
- data/lib/badline/frontend/controls.rb +62 -6
- data/lib/badline/frontend/keys.rb +36 -0
- data/lib/badline/frontend/kim1_panel.rb +208 -0
- data/lib/badline/frontend/media_slots.rb +8 -1
- data/lib/badline/frontend/menu/drive_types.rb +56 -0
- data/lib/badline/frontend/menu/menu_dialogs.rb +61 -14
- data/lib/badline/frontend/menu/menu_media.rb +42 -12
- data/lib/badline/frontend/menu/menu_pages.rb +97 -2
- data/lib/badline/frontend/menu/menu_ports.rb +38 -1
- data/lib/badline/frontend/menu/pause_menu.rb +5 -1
- data/lib/badline/frontend/pet_keyboard.rb +23 -1
- data/lib/badline/frontend/screen.rb +1 -1
- data/lib/badline/frontend/screens.rb +40 -2
- data/lib/badline/frontend/teletype_pane.rb +152 -0
- data/lib/badline/frontend/timeline.rb +31 -2
- data/lib/badline/frontend.rb +3 -0
- data/lib/badline/input/joystick.rb +15 -2
- data/lib/badline/kim1/bus.rb +117 -0
- data/lib/badline/kim1/cpu.rb +25 -0
- data/lib/badline/kim1/host_terminal.rb +74 -0
- data/lib/badline/kim1/key_entry.rb +74 -0
- data/lib/badline/kim1/keyed_modules.rb +53 -0
- data/lib/badline/kim1/keyed_state.rb +133 -0
- data/lib/badline/kim1/panel.rb +176 -0
- data/lib/badline/kim1/rriots.rb +28 -0
- data/lib/badline/kim1/sound.rb +29 -0
- data/lib/badline/kim1/tape.rb +118 -0
- data/lib/badline/kim1/teletype.rb +193 -0
- data/lib/badline/kim1.rb +194 -0
- data/lib/badline/machine/ieee_drives.rb +94 -117
- data/lib/badline/machine/keyboard_buffer.rb +20 -3
- data/lib/badline/machine/line_sound.rb +122 -0
- data/lib/badline/machine.rb +49 -15
- data/lib/badline/media/extensions.rb +8 -4
- data/lib/badline/media/kim1_media.rb +150 -0
- data/lib/badline/media/pet_media.rb +3 -1
- data/lib/badline/media/true_drive.rb +52 -45
- data/lib/badline/media/vic20_media.rb +4 -2
- data/lib/badline/media.rb +16 -6
- data/lib/badline/memory.rb +2 -4
- data/lib/badline/options/family.rb +98 -8
- data/lib/badline/options/help.rb +44 -12
- data/lib/badline/options/table.rb +44 -12
- data/lib/badline/options/validation.rb +44 -8
- data/lib/badline/options.rb +27 -8
- data/lib/badline/pet/bus.rb +16 -2
- data/lib/badline/pet/keyboard_ports.rb +9 -2
- data/lib/badline/pet/keyed_state.rb +4 -0
- data/lib/badline/pet/model.rb +11 -2
- data/lib/badline/pet/rom_sets.rb +1 -0
- data/lib/badline/pet/sound.rb +5 -105
- data/lib/badline/pet/superpet/acia.rb +12 -0
- data/lib/badline/pet/superpet/board.rb +221 -0
- data/lib/badline/pet/superpet/dongle.rb +92 -0
- data/lib/badline/pet/superpet/keyed_modules.rb +63 -0
- data/lib/badline/pet/superpet/keyed_parts.rb +76 -0
- data/lib/badline/pet/superpet/m6809.rb +32 -0
- data/lib/badline/pet/superpet/waterloo_traps.rb +199 -0
- data/lib/badline/pet/superpet.rb +221 -0
- data/lib/badline/pet.rb +23 -3
- data/lib/badline/plus4/keyed_state.rb +2 -0
- data/lib/badline/plus4.rb +5 -0
- data/lib/badline/roms/1001/fdc-251257-02a.rom +0 -0
- data/lib/badline/roms/4040/dos-1.2.rom +0 -0
- data/lib/badline/roms/4040/dos-2.1-rev.rom +0 -0
- data/lib/badline/roms/4040/dos-2.1.rom +0 -0
- data/lib/badline/roms/4040/fdc-901466-02.rom +0 -0
- data/lib/badline/roms/4040/fdc-901466-04.rom +0 -0
- data/lib/badline/roms/9060/dos-3.0.rom +0 -0
- data/lib/badline/roms/9060/sasi-300515-revb.rom +0 -0
- data/lib/badline/roms/README +176 -0
- data/lib/badline/roms/kim1/6530-002.rom +0 -0
- data/lib/badline/roms/kim1/6530-003.rom +0 -0
- data/lib/badline/roms/pet/characters-superpet.rom +0 -0
- data/lib/badline/roms/pet/superpet-a000.rom +0 -0
- data/lib/badline/roms/pet/superpet-c000.rom +0 -0
- data/lib/badline/roms/pet/superpet-e000-50hz.rom +0 -0
- data/lib/badline/roms/pet/superpet-e000.rom +0 -0
- data/lib/badline/snapshot/container.rb +8 -4
- data/lib/badline/snapshot/field_doc/markdown.rb +1 -1
- data/lib/badline/snapshot/field_doc.rb +35 -10
- data/lib/badline/snapshot/image.rb +19 -7
- data/lib/badline/snapshot/kim1_setup.rb +28 -0
- data/lib/badline/snapshot/pet_setup.rb +27 -11
- data/lib/badline/snapshot/storage_setup.rb +4 -1
- data/lib/badline/snapshot/vic20_setup.rb +11 -7
- data/lib/badline/snapshot/vice/pet.rb +14 -7
- data/lib/badline/snapshot/vice/pet_cpu.rb +39 -5
- data/lib/badline/snapshot/vice/pet_crtc.rb +15 -2
- data/lib/badline/snapshot/vice/pet_dongle.rb +72 -0
- data/lib/badline/snapshot/vice/pet_drive8050.rb +188 -68
- data/lib/badline/snapshot/vice/pet_mem.rb +55 -5
- data/lib/badline/snapshot/vice/pet_restore.rb +40 -11
- data/lib/badline/snapshot/vice/vic20.rb +70 -0
- data/lib/badline/snapshot/vice/vic20_cpu.rb +61 -0
- data/lib/badline/snapshot/vice/vic20_mem.rb +85 -0
- data/lib/badline/snapshot/vice/vic20_restore.rb +124 -0
- data/lib/badline/snapshot/vice/vic20_vici.rb +200 -0
- data/lib/badline/snapshot/vice.rb +1 -0
- data/lib/badline/snapshot.rb +8 -4
- data/lib/badline/status.rb +30 -30
- data/lib/badline/storage/d67_image.rb +55 -0
- data/lib/badline/storage/d90_image.rb +180 -0
- data/lib/badline/storage/kim_tape.rb +254 -0
- data/lib/badline/storage/papertape.rb +90 -0
- data/lib/badline/storage.rb +4 -0
- data/lib/badline/support/kim1_checkpoint.rb +41 -0
- data/lib/badline/support/superpet_checkpoint.rb +35 -0
- data/lib/badline/version.rb +1 -1
- data/lib/badline/vic20/keyed_modules.rb +6 -3
- data/lib/badline/vic20/keyed_state.rb +6 -4
- data/lib/badline/vic20/port_wiring.rb +11 -0
- data/lib/badline/vic20.rb +30 -12
- data/lib/badline.rb +1 -0
- metadata +85 -1
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Snapshot
|
|
5
|
+
module Vice
|
|
6
|
+
module Vic20
|
|
7
|
+
# The VIC-I as xvic 3.10 saves it, VIC-I 0.4. The layout was inferred
|
|
8
|
+
# from xvic's snapshots of known states, set from its monitor and
|
|
9
|
+
# stepped an instruction at a time, against what its monitor's io
|
|
10
|
+
# command and its registers showed:
|
|
11
|
+
#
|
|
12
|
+
# - $00 dword: 1 while the frame is interlaced, $04 dword: the field,
|
|
13
|
+
# 0 the long one and 1 the short one; $08 qword: the clock at the
|
|
14
|
+
# frame's first cycle
|
|
15
|
+
# - $10 byte: the cycle in the line; $11 word: the raster line; $13
|
|
16
|
+
# byte: the text window, 0 before it, 1 on its first line until
|
|
17
|
+
# the column in $9000, 2 on its lines after that and 3 after it;
|
|
18
|
+
# $15 byte: the line's fetches, 0 off the window or before the
|
|
19
|
+
# column in $9000, 1 from there, 2 from the cycle before the first
|
|
20
|
+
# fetch, then 3 with a pattern fetch next and 2 with a code fetch
|
|
21
|
+
# next, 4 once done; $17 word: the line again
|
|
22
|
+
# - $1B dword: the columns; $1F dword: the rows; $23 dword: the
|
|
23
|
+
# columns again; $27 dword: 0 on a line after one of the
|
|
24
|
+
# window's, 1 on the others; $2B dword: the video matrix
|
|
25
|
+
# offset the text row starts at; $33 dword: the text rows done;
|
|
26
|
+
# $37 dword: while the fetches wait, the cycles left until the
|
|
27
|
+
# cycle before the first, then the characters fetched, and the
|
|
28
|
+
# columns while $15 is 0
|
|
29
|
+
# - $3D and $41 dwords: the light pen's latch, $9006 and $9007;
|
|
30
|
+
# $45 dword: 1 in every snapshot xvic wrote; $49: 8 bytes of $FF;
|
|
31
|
+
# $51 byte: the last character code fetched
|
|
32
|
+
# - $52: the colour RAM, 1,024 bytes; $452: the registers, 16
|
|
33
|
+
# bytes, with $9003 bit 7 and $9004 as written; $462 dword: the
|
|
34
|
+
# raster line again
|
|
35
|
+
# - $466 dword: the width of xvic's picture, $46A dword: its lines,
|
|
36
|
+
# 312 on the 6561 and 262 on the 6560; $46E dword: its pitch,
|
|
37
|
+
# then the picture itself, twice its lines and 8 more of pitch
|
|
38
|
+
# bytes, and 4 bytes after it, 0 in every snapshot
|
|
39
|
+
#
|
|
40
|
+
# Bytes the layout leaves out, $14, $16, $19-$1A, $2F-$32 and
|
|
41
|
+
# $3B-$3C, were 0 in every snapshot.
|
|
42
|
+
#
|
|
43
|
+
# Written: all of it from badline's VIC, the picture as zeros. The
|
|
44
|
+
# cycle is badline's column, which is where xvic's monitor puts
|
|
45
|
+
# the cycle at an instruction boundary. Read: the registers, the
|
|
46
|
+
# beam, the frame and field, the text window's counters and the
|
|
47
|
+
# line's fetches, the light pen and the colour RAM; the character
|
|
48
|
+
# line is worked out from the line and $9001, as xvic's monitor
|
|
49
|
+
# works it out. The picture is painted afresh.
|
|
50
|
+
module VICI
|
|
51
|
+
NAME = "VIC-I"
|
|
52
|
+
MAJOR = 0
|
|
53
|
+
MINOR = 4
|
|
54
|
+
HEADER = 0x472
|
|
55
|
+
COLOR_RAM = 0x52
|
|
56
|
+
REGISTERS = 0x452
|
|
57
|
+
# xvic's picture: width, lines and pitch, by model.
|
|
58
|
+
PICTURES = { "pal" => [1648, 312, 1648], "ntsc" => [1536, 262, 1536] }.freeze
|
|
59
|
+
AREA_BEFORE = 0
|
|
60
|
+
AREA_FIRST = 1
|
|
61
|
+
AREA_IN = 2
|
|
62
|
+
AREA_AFTER = 3
|
|
63
|
+
FETCH_WAITING = 1
|
|
64
|
+
FETCH_CODE = 2
|
|
65
|
+
FETCH_PATTERN = 3
|
|
66
|
+
FETCH_DONE = 4
|
|
67
|
+
LIGHT_PEN_FLAG = 1
|
|
68
|
+
FILLER = 0xff
|
|
69
|
+
|
|
70
|
+
module_function
|
|
71
|
+
|
|
72
|
+
def reads?(section) = section.major == MAJOR && section.minor == MINOR && section.data.bytesize >= HEADER
|
|
73
|
+
|
|
74
|
+
# The model whose picture the module's size says, or nil.
|
|
75
|
+
def model(section)
|
|
76
|
+
lines = FieldReader.new(section).skip(0x46a).dword
|
|
77
|
+
PICTURES.find { |_, picture| picture[1] == lines }&.first
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# The module for `machine` from its BL-VICI and BL-COLORRAM fields.
|
|
81
|
+
def export(machine, vic, color_ram)
|
|
82
|
+
profile = machine.vic.profile
|
|
83
|
+
registers = vic.bytes("registers", "\0".b * 16).bytes
|
|
84
|
+
line = vic.int("raster", 0)
|
|
85
|
+
column = vic.int("column", 0)
|
|
86
|
+
frame_lines = vic.int("frame_lines", profile.lines_per_frame)
|
|
87
|
+
fields = FieldWriter.new
|
|
88
|
+
interlaced = frame_lines != profile.lines_per_frame
|
|
89
|
+
fields.dword(interlaced ? 1 : 0).dword(interlaced && frame_lines != profile.interlaced_lines ? 1 : 0)
|
|
90
|
+
fields.qword(machine.cycles - (line * profile.cycles_per_line) - column)
|
|
91
|
+
window(fields, vic, registers, line, column)
|
|
92
|
+
fields.dword(vic.int("pen.x", 0)).dword(vic.int("pen.y", 0)).dword(LIGHT_PEN_FLAG)
|
|
93
|
+
fields.bytes(Array.new(8, FILLER)).byte(vic.int("code", 0))
|
|
94
|
+
colors = color_ram.bytes("ram", "".b).bytes
|
|
95
|
+
fields.bytes(Array.new(0x400) { |cell| colors.fetch(cell, 0) & 0x0f })
|
|
96
|
+
fields.bytes(registers).dword(line)
|
|
97
|
+
picture(fields, PICTURES.fetch(machine.model))
|
|
98
|
+
fields.section(NAME, MAJOR, MINOR)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def window(fields, vic, registers, line, column)
|
|
102
|
+
open = vic.bool("window_open", false)
|
|
103
|
+
done = vic.bool("window_done", false)
|
|
104
|
+
columns = registers[2] & 0x7f
|
|
105
|
+
rows = (registers[3] >> 1) & 0x3f
|
|
106
|
+
first = open && vic.int("text_rows", 0).zero? && vic.int("char_line", 0).zero?
|
|
107
|
+
origin = registers[0] & 0x7f
|
|
108
|
+
area = if open then first && column < origin ? AREA_FIRST : AREA_IN
|
|
109
|
+
else done ? AREA_AFTER : AREA_BEFORE
|
|
110
|
+
end
|
|
111
|
+
state, count = fetches(vic, open && column >= origin, columns, column)
|
|
112
|
+
fields.byte(column).word(line).byte(area).byte(0).byte(state).byte(0).word(line).word(0)
|
|
113
|
+
fields.dword(columns).dword(rows).dword(columns)
|
|
114
|
+
fields.dword(border?(open, first, done, registers, line) ? 1 : 0)
|
|
115
|
+
fields.dword(vic.int("row_start", 0)).dword(0).dword(vic.int("text_rows", 0)).dword(count).word(0)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# The line's fetches as xvic counts them, from the column in
|
|
119
|
+
# $9000 on: waiting, with the cycles left until the cycle before
|
|
120
|
+
# the first fetch, then fetching, with the characters fetched.
|
|
121
|
+
# Before that column, and off the window's lines, the count is
|
|
122
|
+
# the columns.
|
|
123
|
+
def fetches(vic, started, columns, column)
|
|
124
|
+
return [0, columns] unless started
|
|
125
|
+
|
|
126
|
+
from = vic.int("fetch_from", 0)
|
|
127
|
+
return [FETCH_WAITING, from - 1 - column] if column < from - 1
|
|
128
|
+
return [FETCH_CODE, 0] if column < from
|
|
129
|
+
|
|
130
|
+
fetched = vic.int("fetched", 0)
|
|
131
|
+
return [FETCH_DONE, columns] if fetched >= columns
|
|
132
|
+
|
|
133
|
+
[(column - from).even? ? FETCH_PATTERN : FETCH_CODE, fetched]
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Whether xvic's flag at $27 is set: unless the window was open
|
|
137
|
+
# on the line before.
|
|
138
|
+
def border?(open, first, done, registers, line)
|
|
139
|
+
return first if open
|
|
140
|
+
return true unless done
|
|
141
|
+
|
|
142
|
+
height = registers[3].anybits?(0x01) ? 16 : 8
|
|
143
|
+
line != (registers[1] * 2) + (((registers[3] >> 1) & 0x3f) * height)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def picture(fields, (width, lines, pitch))
|
|
147
|
+
fields.dword(width).dword(lines).dword(pitch).zeros((((2 * lines) + 8) * pitch) + 4)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# The colour RAM's cells, low nibbles.
|
|
151
|
+
def colors(section) = FieldReader.new(section).skip(COLOR_RAM).bytes(0x400).map { |cell| cell & 0x0f }
|
|
152
|
+
|
|
153
|
+
# BL-VICI's fields for `machine`'s profile, in a keyed module's
|
|
154
|
+
# writer.
|
|
155
|
+
def import(section, out, profile)
|
|
156
|
+
fields = FieldReader.new(section)
|
|
157
|
+
interlaced = fields.dword == 1
|
|
158
|
+
short = fields.dword == 1
|
|
159
|
+
fields.skip(8)
|
|
160
|
+
column = fields.byte
|
|
161
|
+
line = fields.word
|
|
162
|
+
area = fields.byte
|
|
163
|
+
fields.skip(1)
|
|
164
|
+
state = fields.byte
|
|
165
|
+
fields.skip(5 + 16)
|
|
166
|
+
row_start = fields.dword
|
|
167
|
+
fields.skip(4)
|
|
168
|
+
text_rows = fields.dword
|
|
169
|
+
count = fields.dword
|
|
170
|
+
fields.skip(2)
|
|
171
|
+
pen_x = fields.dword
|
|
172
|
+
pen_y = fields.dword
|
|
173
|
+
fields.skip(4 + 8)
|
|
174
|
+
code = fields.byte
|
|
175
|
+
registers = FieldReader.new(section).skip(REGISTERS).bytes(16)
|
|
176
|
+
out.bytes("registers", registers).int("raster", line).int("column", column)
|
|
177
|
+
frame_lines = if interlaced then short ? profile.interlaced_lines - 1 : profile.interlaced_lines
|
|
178
|
+
else profile.lines_per_frame
|
|
179
|
+
end
|
|
180
|
+
out.int("frame_lines", frame_lines).bool("long_field", !interlaced || short)
|
|
181
|
+
open = [AREA_FIRST, AREA_IN].include?(area)
|
|
182
|
+
out.bool("window_open", open).bool("window_done", area == AREA_AFTER)
|
|
183
|
+
fetching = open && state != FETCH_WAITING && state != 0
|
|
184
|
+
out.int("row_start", row_start).int("matrix", row_start + (fetching ? count : 0))
|
|
185
|
+
out.int("char_line", open ? char_line(registers, line) : 0).int("text_rows", text_rows)
|
|
186
|
+
out.int("fetch_from", open ? (registers[0] & 0x7f) + Chips::VICI::FETCH_DELAY : 0)
|
|
187
|
+
out.int("fetched", fetching ? count : 0).int("code", code)
|
|
188
|
+
out.int("pen.x", pen_x & 0xff).int("pen.y", pen_y & 0xff)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# The line of the character row the window is on.
|
|
192
|
+
def char_line(registers, line)
|
|
193
|
+
height = registers[3].anybits?(0x01) ? 16 : 8
|
|
194
|
+
(line - (registers[1] * 2)) % height
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
@@ -14,6 +14,7 @@ require "badline/snapshot/vice/vicii"
|
|
|
14
14
|
require "badline/snapshot/vice/vicii_import"
|
|
15
15
|
require "badline/snapshot/vice/restore"
|
|
16
16
|
require "badline/snapshot/vice/pet"
|
|
17
|
+
require "badline/snapshot/vice/vic20"
|
|
17
18
|
require "badline/snapshot/vice/cbm2"
|
|
18
19
|
require "badline/snapshot/vice/p500"
|
|
19
20
|
require "badline/snapshot/vice/p500_restore"
|
data/lib/badline/snapshot.rb
CHANGED
|
@@ -25,8 +25,8 @@ module Badline
|
|
|
25
25
|
path
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
# Saves the machine's snapshot with VICE's modules ahead of its own
|
|
29
|
-
#
|
|
28
|
+
# Saves the machine's snapshot with VICE's modules ahead of its own, so
|
|
29
|
+
# x64sc, xvic, xpet, xcbm2 or xcbm5x0 opens it too (Image.exported).
|
|
30
30
|
def export(computer, path)
|
|
31
31
|
File.binwrite(path, Image.exported(computer).to_s)
|
|
32
32
|
path
|
|
@@ -56,8 +56,8 @@ module Badline
|
|
|
56
56
|
module Files
|
|
57
57
|
def save_snapshot(path) = Snapshot.save(self, path)
|
|
58
58
|
|
|
59
|
-
# Saves the snapshot with VICE's modules too,
|
|
60
|
-
# opens it as well as badline.
|
|
59
|
+
# Saves the snapshot with VICE's modules too, so VICE's emulator for
|
|
60
|
+
# the machine opens it as well as badline (Image.exported).
|
|
61
61
|
def export_snapshot(path) = Snapshot.export(self, path)
|
|
62
62
|
|
|
63
63
|
def restore_snapshot(path, &) = Snapshot.restore(self, path, &)
|
|
@@ -100,6 +100,10 @@ module Badline
|
|
|
100
100
|
include Snapshot::Files
|
|
101
101
|
end
|
|
102
102
|
|
|
103
|
+
class KIM1
|
|
104
|
+
include Snapshot::Files
|
|
105
|
+
end
|
|
106
|
+
|
|
103
107
|
class CBM2
|
|
104
108
|
include Snapshot::Files
|
|
105
109
|
|
data/lib/badline/status.rb
CHANGED
|
@@ -36,7 +36,7 @@ module Badline
|
|
|
36
36
|
@value = enabled && enabled != 0 ? @value | 0x01 : @value & ~0x01
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
-
def carry? = @value
|
|
39
|
+
def carry? = @value.anybits?(0x01)
|
|
40
40
|
|
|
41
41
|
def carry = @value.nobits?(0x01) ? 0 : 1
|
|
42
42
|
|
|
@@ -44,7 +44,7 @@ module Badline
|
|
|
44
44
|
@value = enabled && enabled != 0 ? @value | 0x02 : @value & ~0x02
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
def zero? = @value
|
|
47
|
+
def zero? = @value.anybits?(0x02)
|
|
48
48
|
|
|
49
49
|
def zero = @value.nobits?(0x02) ? 0 : 1
|
|
50
50
|
|
|
@@ -52,7 +52,7 @@ module Badline
|
|
|
52
52
|
@value = enabled && enabled != 0 ? @value | 0x04 : @value & ~0x04
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
-
def interrupt? = @value
|
|
55
|
+
def interrupt? = @value.anybits?(0x04)
|
|
56
56
|
|
|
57
57
|
def interrupt = @value.nobits?(0x04) ? 0 : 1
|
|
58
58
|
|
|
@@ -60,7 +60,7 @@ module Badline
|
|
|
60
60
|
@value = enabled && enabled != 0 ? @value | 0x08 : @value & ~0x08
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
-
def decimal? = @value
|
|
63
|
+
def decimal? = @value.anybits?(0x08)
|
|
64
64
|
|
|
65
65
|
def decimal = @value.nobits?(0x08) ? 0 : 1
|
|
66
66
|
|
|
@@ -68,7 +68,7 @@ module Badline
|
|
|
68
68
|
@value = enabled && enabled != 0 ? @value | 0x10 : @value & ~0x10
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
-
def break? = @value
|
|
71
|
+
def break? = @value.anybits?(0x10)
|
|
72
72
|
|
|
73
73
|
def break = @value.nobits?(0x10) ? 0 : 1
|
|
74
74
|
|
|
@@ -76,7 +76,7 @@ module Badline
|
|
|
76
76
|
@value = enabled && enabled != 0 ? @value | 0x40 : @value & ~0x40
|
|
77
77
|
end
|
|
78
78
|
|
|
79
|
-
def overflow? = @value
|
|
79
|
+
def overflow? = @value.anybits?(0x40)
|
|
80
80
|
|
|
81
81
|
def overflow = @value.nobits?(0x40) ? 0 : 1
|
|
82
82
|
|
|
@@ -84,7 +84,7 @@ module Badline
|
|
|
84
84
|
@value = enabled && enabled != 0 ? @value | 0x80 : @value & ~0x80
|
|
85
85
|
end
|
|
86
86
|
|
|
87
|
-
def negative? = @value
|
|
87
|
+
def negative? = @value.anybits?(0x80)
|
|
88
88
|
|
|
89
89
|
def negative = @value.nobits?(0x80) ? 0 : 1
|
|
90
90
|
end
|
|
@@ -95,7 +95,7 @@ module Badline
|
|
|
95
95
|
@value = enabled && enabled != 0 ? @value | 0x01 : @value & ~0x01
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
-
def basic? = @value
|
|
98
|
+
def basic? = @value.anybits?(0x01)
|
|
99
99
|
|
|
100
100
|
def basic = @value.nobits?(0x01) ? 0 : 1
|
|
101
101
|
|
|
@@ -103,7 +103,7 @@ module Badline
|
|
|
103
103
|
@value = enabled && enabled != 0 ? @value | 0x02 : @value & ~0x02
|
|
104
104
|
end
|
|
105
105
|
|
|
106
|
-
def kernal? = @value
|
|
106
|
+
def kernal? = @value.anybits?(0x02)
|
|
107
107
|
|
|
108
108
|
def kernal = @value.nobits?(0x02) ? 0 : 1
|
|
109
109
|
|
|
@@ -111,7 +111,7 @@ module Badline
|
|
|
111
111
|
@value = enabled && enabled != 0 ? @value | 0x04 : @value & ~0x04
|
|
112
112
|
end
|
|
113
113
|
|
|
114
|
-
def io? = @value
|
|
114
|
+
def io? = @value.anybits?(0x04)
|
|
115
115
|
|
|
116
116
|
def io = @value.nobits?(0x04) ? 0 : 1
|
|
117
117
|
|
|
@@ -119,7 +119,7 @@ module Badline
|
|
|
119
119
|
@value = enabled && enabled != 0 ? @value | 0x08 : @value & ~0x08
|
|
120
120
|
end
|
|
121
121
|
|
|
122
|
-
def tape_out? = @value
|
|
122
|
+
def tape_out? = @value.anybits?(0x08)
|
|
123
123
|
|
|
124
124
|
def tape_out = @value.nobits?(0x08) ? 0 : 1
|
|
125
125
|
|
|
@@ -127,7 +127,7 @@ module Badline
|
|
|
127
127
|
@value = enabled && enabled != 0 ? @value | 0x10 : @value & ~0x10
|
|
128
128
|
end
|
|
129
129
|
|
|
130
|
-
def tape_switch? = @value
|
|
130
|
+
def tape_switch? = @value.anybits?(0x10)
|
|
131
131
|
|
|
132
132
|
def tape_switch = @value.nobits?(0x10) ? 0 : 1
|
|
133
133
|
|
|
@@ -135,7 +135,7 @@ module Badline
|
|
|
135
135
|
@value = enabled && enabled != 0 ? @value | 0x20 : @value & ~0x20
|
|
136
136
|
end
|
|
137
137
|
|
|
138
|
-
def tape_motor? = @value
|
|
138
|
+
def tape_motor? = @value.anybits?(0x20)
|
|
139
139
|
|
|
140
140
|
def tape_motor = @value.nobits?(0x20) ? 0 : 1
|
|
141
141
|
end
|
|
@@ -146,7 +146,7 @@ module Badline
|
|
|
146
146
|
@value = enabled && enabled != 0 ? @value | 0x01 : @value & ~0x01
|
|
147
147
|
end
|
|
148
148
|
|
|
149
|
-
def start? = @value
|
|
149
|
+
def start? = @value.anybits?(0x01)
|
|
150
150
|
|
|
151
151
|
def start = @value.nobits?(0x01) ? 0 : 1
|
|
152
152
|
|
|
@@ -154,7 +154,7 @@ module Badline
|
|
|
154
154
|
@value = enabled && enabled != 0 ? @value | 0x02 : @value & ~0x02
|
|
155
155
|
end
|
|
156
156
|
|
|
157
|
-
def output? = @value
|
|
157
|
+
def output? = @value.anybits?(0x02)
|
|
158
158
|
|
|
159
159
|
def output = @value.nobits?(0x02) ? 0 : 1
|
|
160
160
|
|
|
@@ -162,7 +162,7 @@ module Badline
|
|
|
162
162
|
@value = enabled && enabled != 0 ? @value | 0x04 : @value & ~0x04
|
|
163
163
|
end
|
|
164
164
|
|
|
165
|
-
def out_mode? = @value
|
|
165
|
+
def out_mode? = @value.anybits?(0x04)
|
|
166
166
|
|
|
167
167
|
def out_mode = @value.nobits?(0x04) ? 0 : 1
|
|
168
168
|
|
|
@@ -170,7 +170,7 @@ module Badline
|
|
|
170
170
|
@value = enabled && enabled != 0 ? @value | 0x08 : @value & ~0x08
|
|
171
171
|
end
|
|
172
172
|
|
|
173
|
-
def run_mode? = @value
|
|
173
|
+
def run_mode? = @value.anybits?(0x08)
|
|
174
174
|
|
|
175
175
|
def run_mode = @value.nobits?(0x08) ? 0 : 1
|
|
176
176
|
|
|
@@ -178,7 +178,7 @@ module Badline
|
|
|
178
178
|
@value = enabled && enabled != 0 ? @value | 0x10 : @value & ~0x10
|
|
179
179
|
end
|
|
180
180
|
|
|
181
|
-
def load? = @value
|
|
181
|
+
def load? = @value.anybits?(0x10)
|
|
182
182
|
|
|
183
183
|
def load = @value.nobits?(0x10) ? 0 : 1
|
|
184
184
|
|
|
@@ -186,7 +186,7 @@ module Badline
|
|
|
186
186
|
@value = enabled && enabled != 0 ? @value | 0x20 : @value & ~0x20
|
|
187
187
|
end
|
|
188
188
|
|
|
189
|
-
def in_mode? = @value
|
|
189
|
+
def in_mode? = @value.anybits?(0x20)
|
|
190
190
|
|
|
191
191
|
def in_mode = @value.nobits?(0x20) ? 0 : 1
|
|
192
192
|
|
|
@@ -194,7 +194,7 @@ module Badline
|
|
|
194
194
|
@value = enabled && enabled != 0 ? @value | 0x40 : @value & ~0x40
|
|
195
195
|
end
|
|
196
196
|
|
|
197
|
-
def serial_mode? = @value
|
|
197
|
+
def serial_mode? = @value.anybits?(0x40)
|
|
198
198
|
|
|
199
199
|
def serial_mode = @value.nobits?(0x40) ? 0 : 1
|
|
200
200
|
|
|
@@ -202,7 +202,7 @@ module Badline
|
|
|
202
202
|
@value = enabled && enabled != 0 ? @value | 0x80 : @value & ~0x80
|
|
203
203
|
end
|
|
204
204
|
|
|
205
|
-
def clock_frequency? = @value
|
|
205
|
+
def clock_frequency? = @value.anybits?(0x80)
|
|
206
206
|
|
|
207
207
|
def clock_frequency = @value.nobits?(0x80) ? 0 : 1
|
|
208
208
|
|
|
@@ -210,7 +210,7 @@ module Badline
|
|
|
210
210
|
@value = enabled && enabled != 0 ? @value | 0x20 : @value & ~0x20
|
|
211
211
|
end
|
|
212
212
|
|
|
213
|
-
def in_cnt? = @value
|
|
213
|
+
def in_cnt? = @value.anybits?(0x20)
|
|
214
214
|
|
|
215
215
|
def in_cnt = @value.nobits?(0x20) ? 0 : 1
|
|
216
216
|
|
|
@@ -218,7 +218,7 @@ module Badline
|
|
|
218
218
|
@value = enabled && enabled != 0 ? @value | 0x40 : @value & ~0x40
|
|
219
219
|
end
|
|
220
220
|
|
|
221
|
-
def in_timer_a? = @value
|
|
221
|
+
def in_timer_a? = @value.anybits?(0x40)
|
|
222
222
|
|
|
223
223
|
def in_timer_a = @value.nobits?(0x40) ? 0 : 1
|
|
224
224
|
|
|
@@ -226,7 +226,7 @@ module Badline
|
|
|
226
226
|
@value = enabled && enabled != 0 ? @value | 0x80 : @value & ~0x80
|
|
227
227
|
end
|
|
228
228
|
|
|
229
|
-
def alarm? = @value
|
|
229
|
+
def alarm? = @value.anybits?(0x80)
|
|
230
230
|
|
|
231
231
|
def alarm = @value.nobits?(0x80) ? 0 : 1
|
|
232
232
|
end
|
|
@@ -237,7 +237,7 @@ module Badline
|
|
|
237
237
|
@value = enabled && enabled != 0 ? @value | 0x01 : @value & ~0x01
|
|
238
238
|
end
|
|
239
239
|
|
|
240
|
-
def timer_a? = @value
|
|
240
|
+
def timer_a? = @value.anybits?(0x01)
|
|
241
241
|
|
|
242
242
|
def timer_a = @value.nobits?(0x01) ? 0 : 1
|
|
243
243
|
|
|
@@ -245,7 +245,7 @@ module Badline
|
|
|
245
245
|
@value = enabled && enabled != 0 ? @value | 0x02 : @value & ~0x02
|
|
246
246
|
end
|
|
247
247
|
|
|
248
|
-
def timer_b? = @value
|
|
248
|
+
def timer_b? = @value.anybits?(0x02)
|
|
249
249
|
|
|
250
250
|
def timer_b = @value.nobits?(0x02) ? 0 : 1
|
|
251
251
|
|
|
@@ -253,7 +253,7 @@ module Badline
|
|
|
253
253
|
@value = enabled && enabled != 0 ? @value | 0x04 : @value & ~0x04
|
|
254
254
|
end
|
|
255
255
|
|
|
256
|
-
def alarm? = @value
|
|
256
|
+
def alarm? = @value.anybits?(0x04)
|
|
257
257
|
|
|
258
258
|
def alarm = @value.nobits?(0x04) ? 0 : 1
|
|
259
259
|
|
|
@@ -261,7 +261,7 @@ module Badline
|
|
|
261
261
|
@value = enabled && enabled != 0 ? @value | 0x08 : @value & ~0x08
|
|
262
262
|
end
|
|
263
263
|
|
|
264
|
-
def serial? = @value
|
|
264
|
+
def serial? = @value.anybits?(0x08)
|
|
265
265
|
|
|
266
266
|
def serial = @value.nobits?(0x08) ? 0 : 1
|
|
267
267
|
|
|
@@ -269,7 +269,7 @@ module Badline
|
|
|
269
269
|
@value = enabled && enabled != 0 ? @value | 0x10 : @value & ~0x10
|
|
270
270
|
end
|
|
271
271
|
|
|
272
|
-
def flag? = @value
|
|
272
|
+
def flag? = @value.anybits?(0x10)
|
|
273
273
|
|
|
274
274
|
def flag = @value.nobits?(0x10) ? 0 : 1
|
|
275
275
|
|
|
@@ -277,7 +277,7 @@ module Badline
|
|
|
277
277
|
@value = enabled && enabled != 0 ? @value | 0x80 : @value & ~0x80
|
|
278
278
|
end
|
|
279
279
|
|
|
280
|
-
def interrupt? = @value
|
|
280
|
+
def interrupt? = @value.anybits?(0x80)
|
|
281
281
|
|
|
282
282
|
def interrupt = @value.nobits?(0x80) ? 0 : 1
|
|
283
283
|
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Storage
|
|
5
|
+
# A 2040's disk, as DOS 1 formats it: the 1541's 35 tracks and speed
|
|
6
|
+
# zones, with 20 sectors on tracks 18 to 24 in place of 19, 690 blocks
|
|
7
|
+
# in all. The BAM and the directory are where a 1541's are, on 18/0
|
|
8
|
+
# and 18/1, but the BAM's format byte is $01 and the header has no DOS
|
|
9
|
+
# type after the ID, as c1541 formats a .d67.
|
|
10
|
+
class D67Image < DiskImage
|
|
11
|
+
ERROR_TABLES = { 177_330 => 690 }.freeze
|
|
12
|
+
|
|
13
|
+
# The sectors a track holds in each of the 1541's speed zones, by its
|
|
14
|
+
# number, from zone 0, the innermost.
|
|
15
|
+
ZONE_SECTORS = [17, 18, 20, 21].freeze
|
|
16
|
+
|
|
17
|
+
# The tracks the image holds.
|
|
18
|
+
def track_count = 35
|
|
19
|
+
|
|
20
|
+
def sides = 1
|
|
21
|
+
|
|
22
|
+
def sectors_in(track) = ZONE_SECTORS[D64Image.zone(track)]
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def error_tables = ERROR_TABLES
|
|
27
|
+
|
|
28
|
+
def header_name = 0x90
|
|
29
|
+
def directory_track = 18
|
|
30
|
+
def directory_sector = 1
|
|
31
|
+
def directory_interleave = 3
|
|
32
|
+
def interleave = 10
|
|
33
|
+
def reserved_tracks = [18]
|
|
34
|
+
|
|
35
|
+
def bam_tracks = 1..35
|
|
36
|
+
def bam_count(track) = [18, 0, 4 * track]
|
|
37
|
+
def bam_bitmap(track) = [18, 0, (4 * track) + 1]
|
|
38
|
+
def bitmap_size = 3
|
|
39
|
+
|
|
40
|
+
def header_link = [18, 1]
|
|
41
|
+
def dos_type = " "
|
|
42
|
+
def header_tail = 5
|
|
43
|
+
def bam_headers(_id) = []
|
|
44
|
+
|
|
45
|
+
# The link to the directory, the format byte $01, and after the name
|
|
46
|
+
# the ID and two spaces.
|
|
47
|
+
def write_header(name, id)
|
|
48
|
+
write_at(*header_block, 0, [*header_link, 0x01, 0])
|
|
49
|
+
write_at(*header_block, header_name,
|
|
50
|
+
encode_name(name) + [NAME_PADDING, NAME_PADDING] + id + dos_type.bytes +
|
|
51
|
+
Array.new(header_tail, NAME_PADDING))
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|