badline 0.1.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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +40 -0
- data/exe/badline +55 -0
- data/lib/badline/address_bus.rb +206 -0
- data/lib/badline/addressable.rb +61 -0
- data/lib/badline/cartridge/magic_desk.rb +23 -0
- data/lib/badline/cartridge/ocean.rb +33 -0
- data/lib/badline/cartridge/standard.rb +31 -0
- data/lib/badline/cartridge.rb +75 -0
- data/lib/badline/chrout_trap.rb +39 -0
- data/lib/badline/cia/timer.rb +122 -0
- data/lib/badline/cia.rb +189 -0
- data/lib/badline/color_memory.rb +16 -0
- data/lib/badline/computer.rb +100 -0
- data/lib/badline/control_ports.rb +24 -0
- data/lib/badline/cpu.rb +239 -0
- data/lib/badline/cycleable.rb +35 -0
- data/lib/badline/gui/application.rb +94 -0
- data/lib/badline/gui/joy_map.rb +19 -0
- data/lib/badline/gui/key_map.rb +34 -0
- data/lib/badline/gui/palette.rb +35 -0
- data/lib/badline/gui/pane.rb +35 -0
- data/lib/badline/gui/screen_pane.rb +50 -0
- data/lib/badline/gui/window.rb +46 -0
- data/lib/badline/gui.rb +11 -0
- data/lib/badline/instruction.rb +334 -0
- data/lib/badline/instruction_set/arithmetic.rb +119 -0
- data/lib/badline/instruction_set/bitwise.rb +131 -0
- data/lib/badline/instruction_set/branch.rb +78 -0
- data/lib/badline/instruction_set/flag.rb +63 -0
- data/lib/badline/instruction_set/illegal.rb +278 -0
- data/lib/badline/instruction_set/inc_dec.rb +71 -0
- data/lib/badline/instruction_set/stack.rb +104 -0
- data/lib/badline/instruction_set/transfer.rb +137 -0
- data/lib/badline/instruction_set.rb +77 -0
- data/lib/badline/integer_helper.rb +39 -0
- data/lib/badline/joystick.rb +25 -0
- data/lib/badline/kernal_trap/file.rb +54 -0
- data/lib/badline/kernal_trap/load.rb +63 -0
- data/lib/badline/kernal_trap/save.rb +42 -0
- data/lib/badline/kernal_trap.rb +5 -0
- data/lib/badline/keyboard.rb +58 -0
- data/lib/badline/keyboard_buffer.rb +33 -0
- data/lib/badline/media.rb +59 -0
- data/lib/badline/memory.rb +43 -0
- data/lib/badline/rom.rb +23 -0
- data/lib/badline/roms/README +18 -0
- data/lib/badline/roms/basic.rom +0 -0
- data/lib/badline/roms/character.rom +0 -0
- data/lib/badline/roms/kernal.rom +0 -0
- data/lib/badline/sid.rb +25 -0
- data/lib/badline/status.rb +56 -0
- data/lib/badline/storage/crt_file.rb +53 -0
- data/lib/badline/storage/d64_image.rb +21 -0
- data/lib/badline/storage/d71_image.rb +13 -0
- data/lib/badline/storage/d81_image.rb +14 -0
- data/lib/badline/storage/disk_image.rb +71 -0
- data/lib/badline/storage/host_directory.rb +49 -0
- data/lib/badline/storage/p00.rb +24 -0
- data/lib/badline/storage.rb +28 -0
- data/lib/badline/time_of_day.rb +101 -0
- data/lib/badline/traps.rb +15 -0
- data/lib/badline/version.rb +5 -0
- data/lib/badline/vic/bank.rb +65 -0
- data/lib/badline/vic/display_state.rb +78 -0
- data/lib/badline/vic/graphics_mode.rb +139 -0
- data/lib/badline/vic/registers.rb +170 -0
- data/lib/badline/vic/sequencer.rb +237 -0
- data/lib/badline/vic/sprite.rb +121 -0
- data/lib/badline/vic/sprites.rb +112 -0
- data/lib/badline/vic.rb +192 -0
- data/lib/badline.rb +29 -0
- metadata +131 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class VIC < Cycleable
|
|
5
|
+
class Sprite
|
|
6
|
+
X_OFFSET = 104
|
|
7
|
+
ROWS = 21
|
|
8
|
+
|
|
9
|
+
attr_reader :index, :line_pixels
|
|
10
|
+
|
|
11
|
+
def initialize(index, registers, bank, width)
|
|
12
|
+
@index = index
|
|
13
|
+
@registers = registers
|
|
14
|
+
@bank = bank
|
|
15
|
+
@width = width
|
|
16
|
+
@bit = 1 << index
|
|
17
|
+
@displaying = false
|
|
18
|
+
@counter = 0
|
|
19
|
+
@bits = nil
|
|
20
|
+
@line_pixels = nil
|
|
21
|
+
@pixel_buffer = Array.new(48)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def displaying? = @displaying
|
|
25
|
+
|
|
26
|
+
def enabled? = @registers[0x15].anybits?(@bit)
|
|
27
|
+
def multicolor? = @registers[0x1c].anybits?(@bit)
|
|
28
|
+
def x_expanded? = @registers[0x1d].anybits?(@bit)
|
|
29
|
+
def y_expanded? = @registers[0x17].anybits?(@bit)
|
|
30
|
+
def priority? = @registers[0x1b].anybits?(@bit)
|
|
31
|
+
|
|
32
|
+
def x
|
|
33
|
+
msb = @registers[0x10].anybits?(@bit) ? 0x100 : 0
|
|
34
|
+
msb | @registers[index * 2]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def y = @registers[(index * 2) + 1]
|
|
38
|
+
def color = @registers[0x27 + index] & 0x0f
|
|
39
|
+
|
|
40
|
+
def leftmost = (x + X_OFFSET) % @width
|
|
41
|
+
def pixel_width = x_expanded? ? 48 : 24
|
|
42
|
+
|
|
43
|
+
def start_line(line)
|
|
44
|
+
if !@displaying && enabled? && line == y
|
|
45
|
+
@displaying = true
|
|
46
|
+
@counter = 0
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
return @line_pixels = nil unless @displaying
|
|
50
|
+
|
|
51
|
+
row = y_expanded? ? @counter / 2 : @counter
|
|
52
|
+
if row >= ROWS
|
|
53
|
+
@displaying = false
|
|
54
|
+
return @line_pixels = nil
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
@counter += 1
|
|
58
|
+
fetch(row)
|
|
59
|
+
decode_line
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def pixel(raster_x)
|
|
63
|
+
return nil unless @line_pixels
|
|
64
|
+
|
|
65
|
+
dist = raster_x - leftmost
|
|
66
|
+
dist += @width if dist.negative?
|
|
67
|
+
dist < pixel_width ? @line_pixels[dist] : nil
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
private
|
|
71
|
+
|
|
72
|
+
# Decode the fetched 24 data bits into a buffer of pixel colors (nil is
|
|
73
|
+
# transparent), so compositing can read pixels without re-deriving them.
|
|
74
|
+
def decode_line(pixels = @pixel_buffer)
|
|
75
|
+
@line_pixels = pixels
|
|
76
|
+
if multicolor?
|
|
77
|
+
decode_multicolor(pixels, x_expanded?)
|
|
78
|
+
else
|
|
79
|
+
decode_hires(pixels, x_expanded?)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def decode_hires(pixels, expanded)
|
|
84
|
+
own = color
|
|
85
|
+
last = expanded ? 48 : 24
|
|
86
|
+
i = 0
|
|
87
|
+
while i < last
|
|
88
|
+
offset = expanded ? i >> 1 : i
|
|
89
|
+
pixels[i] = (@bits >> (23 - offset)).anybits?(1) ? own : nil
|
|
90
|
+
i += 1
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def decode_multicolor(pixels, expanded)
|
|
95
|
+
shared1 = @registers[0x25] & 0x0f
|
|
96
|
+
shared2 = @registers[0x26] & 0x0f
|
|
97
|
+
own = color
|
|
98
|
+
last = expanded ? 48 : 24
|
|
99
|
+
i = 0
|
|
100
|
+
while i < last
|
|
101
|
+
offset = expanded ? i >> 1 : i
|
|
102
|
+
pixels[i] = case (@bits >> (22 - (offset & ~1))) & 0b11
|
|
103
|
+
when 0b01 then shared1
|
|
104
|
+
when 0b10 then own
|
|
105
|
+
when 0b11 then shared2
|
|
106
|
+
end
|
|
107
|
+
i += 1
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def fetch(row)
|
|
112
|
+
base = (pointer * 64) + (row * 3)
|
|
113
|
+
@bits = (@bank.peek(base) << 16) |
|
|
114
|
+
(@bank.peek(base + 1) << 8) |
|
|
115
|
+
@bank.peek(base + 2)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def pointer = @bank.peek(@registers.screen_base + 0x3f8 + index)
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "badline/vic/sprite"
|
|
4
|
+
|
|
5
|
+
module Badline
|
|
6
|
+
class VIC < Cycleable
|
|
7
|
+
class Sprites
|
|
8
|
+
# $D019 latch bits raised by the collision registers.
|
|
9
|
+
SPRITE_COLLISION_IRQ = 0x04 # IMMC, mirrors $D01E
|
|
10
|
+
DATA_COLLISION_IRQ = 0x02 # IMBC, mirrors $D01F
|
|
11
|
+
|
|
12
|
+
def initialize(registers, bank, width)
|
|
13
|
+
@registers = registers
|
|
14
|
+
@bank = bank
|
|
15
|
+
@width = width
|
|
16
|
+
@sprites = Array.new(8) { |i| Sprite.new(i, registers, bank, width) }
|
|
17
|
+
@hits = Array.new(width, 0)
|
|
18
|
+
@win_color = Array.new(width, 0)
|
|
19
|
+
@win_priority = Array.new(width, false)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def [](index) = @sprites[index]
|
|
23
|
+
|
|
24
|
+
def start_line(line)
|
|
25
|
+
@sprites.each { |sprite| sprite.start_line(line) }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def active? = @sprites.any?(&:displaying?)
|
|
29
|
+
|
|
30
|
+
# Merge each displaying sprite's line into the scratch buffers, then
|
|
31
|
+
# apply the winners over the background in a single pass over the
|
|
32
|
+
# touched span.
|
|
33
|
+
def composite(colors, mask)
|
|
34
|
+
@sprite_clash = 0
|
|
35
|
+
@data_clash = 0
|
|
36
|
+
lo = @width
|
|
37
|
+
hi = 0
|
|
38
|
+
|
|
39
|
+
@sprites.each do |sprite|
|
|
40
|
+
next unless sprite.displaying?
|
|
41
|
+
|
|
42
|
+
seg_lo, seg_hi = merge(sprite, mask)
|
|
43
|
+
lo = seg_lo if seg_lo < lo
|
|
44
|
+
hi = seg_hi if seg_hi > hi
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
apply(colors, mask, lo, hi)
|
|
48
|
+
register_collisions
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
# Write one sprite's pixels into the scratch line. The first sprite to
|
|
54
|
+
# claim a pixel wins (lowest index has priority); later hits only
|
|
55
|
+
# accumulate collision bits.
|
|
56
|
+
def merge(sprite, mask)
|
|
57
|
+
left = sprite.leftmost
|
|
58
|
+
pixels = sprite.line_pixels
|
|
59
|
+
last = sprite.pixel_width
|
|
60
|
+
bit = 1 << sprite.index
|
|
61
|
+
priority = sprite.priority?
|
|
62
|
+
|
|
63
|
+
i = 0
|
|
64
|
+
while i < last
|
|
65
|
+
color = pixels[i]
|
|
66
|
+
if color
|
|
67
|
+
x = left + i
|
|
68
|
+
x -= @width if x >= @width
|
|
69
|
+
merge_pixel(x, color, bit, priority, mask)
|
|
70
|
+
end
|
|
71
|
+
i += 1
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
right = left + last
|
|
75
|
+
right > @width ? [0, @width] : [left, right]
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def merge_pixel(pos, color, bit, priority, mask)
|
|
79
|
+
bits = @hits[pos]
|
|
80
|
+
if bits.zero?
|
|
81
|
+
@win_color[pos] = color
|
|
82
|
+
@win_priority[pos] = priority
|
|
83
|
+
else
|
|
84
|
+
@sprite_clash |= bits | bit
|
|
85
|
+
end
|
|
86
|
+
@hits[pos] = bits | bit
|
|
87
|
+
@data_clash |= bit if mask[pos]
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def apply(colors, mask, from, upto)
|
|
91
|
+
pos = from
|
|
92
|
+
while pos < upto
|
|
93
|
+
if @hits[pos].nonzero?
|
|
94
|
+
colors[pos] = @win_color[pos] unless @win_priority[pos] && mask[pos]
|
|
95
|
+
@hits[pos] = 0
|
|
96
|
+
end
|
|
97
|
+
pos += 1
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def register_collisions
|
|
102
|
+
if @sprite_clash.nonzero? && @registers.collide!(0x1e, @sprite_clash)
|
|
103
|
+
@registers.latch_irq!(SPRITE_COLLISION_IRQ)
|
|
104
|
+
end
|
|
105
|
+
return if @data_clash.zero?
|
|
106
|
+
return unless @registers.collide!(0x1f, @data_clash)
|
|
107
|
+
|
|
108
|
+
@registers.latch_irq!(DATA_COLLISION_IRQ)
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
data/lib/badline/vic.rb
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "badline/vic/bank"
|
|
4
|
+
require "badline/vic/registers"
|
|
5
|
+
require "badline/vic/display_state"
|
|
6
|
+
require "badline/vic/sequencer"
|
|
7
|
+
require "badline/vic/sprites"
|
|
8
|
+
|
|
9
|
+
module Badline
|
|
10
|
+
class VIC < Cycleable
|
|
11
|
+
include Addressable
|
|
12
|
+
include IntegerHelper
|
|
13
|
+
|
|
14
|
+
attr_reader :address_bus, :display, :width, :height, :vic_bank, :column,
|
|
15
|
+
:rasterline, :dirty_lines
|
|
16
|
+
|
|
17
|
+
SPRITE_BA_RANGES = [
|
|
18
|
+
55..59, 57..61, 59..62,
|
|
19
|
+
0..2, 0..4, 2..6, 4..8, 6..10
|
|
20
|
+
].freeze
|
|
21
|
+
|
|
22
|
+
def initialize(address_bus = nil, debug: false)
|
|
23
|
+
addressable_at(0xd000, length: 2**10)
|
|
24
|
+
@address_bus = address_bus || AddressBus.new
|
|
25
|
+
@vic_bank = VIC::Bank.new(@address_bus)
|
|
26
|
+
@debug = debug
|
|
27
|
+
|
|
28
|
+
@width = 504
|
|
29
|
+
@height = 312
|
|
30
|
+
|
|
31
|
+
@registers = VIC::Registers.new
|
|
32
|
+
@display_state = VIC::DisplayState.new(@registers)
|
|
33
|
+
@sequencer = VIC::Sequencer.new(@width, @registers, @vic_bank)
|
|
34
|
+
@sprites = VIC::Sprites.new(@registers, @vic_bank, @width)
|
|
35
|
+
@display = Array.new(@width * @height, 0)
|
|
36
|
+
@dirty_lines = Array.new(@height, true)
|
|
37
|
+
|
|
38
|
+
@column = 0
|
|
39
|
+
@rasterline = 0
|
|
40
|
+
@columns_per_line = @width / 8
|
|
41
|
+
@last_line = @height - 1
|
|
42
|
+
|
|
43
|
+
@character_buffer = Array.new(40, 0)
|
|
44
|
+
@color_buffer = Array.new(40, 0)
|
|
45
|
+
@sprite_ba = Array.new(@width / 8, false)
|
|
46
|
+
|
|
47
|
+
super()
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def cycle!
|
|
51
|
+
if @column.zero?
|
|
52
|
+
@display_state.new_frame if @rasterline.zero?
|
|
53
|
+
check_raster_irq!
|
|
54
|
+
@sequencer.new_line(@rasterline)
|
|
55
|
+
@sprites.start_line(@rasterline)
|
|
56
|
+
rebuild_sprite_ba
|
|
57
|
+
@display_state.new_line
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
@display_state.cycle(@rasterline, @column)
|
|
61
|
+
|
|
62
|
+
fetch_character_data! if dma_active?
|
|
63
|
+
|
|
64
|
+
draw!
|
|
65
|
+
|
|
66
|
+
@column += 1
|
|
67
|
+
if @column == @columns_per_line
|
|
68
|
+
finish_line!
|
|
69
|
+
@column = 0
|
|
70
|
+
@rasterline = @rasterline == @last_line ? 0 : @rasterline + 1
|
|
71
|
+
end
|
|
72
|
+
nil
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# The IRQ line is held asserted while any enabled latch bit is set in
|
|
76
|
+
# $D019/$D01A, until the program acknowledges it by writing to $D019.
|
|
77
|
+
def interrupted?
|
|
78
|
+
@registers.irq_line?
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def peek(addr)
|
|
82
|
+
i = index(addr) % (2**6)
|
|
83
|
+
case i
|
|
84
|
+
when 0x11 then (@registers[0x11] & 0x7f) | ((rasterline & 0x100) >> 1)
|
|
85
|
+
when 0x12 then rasterline & 0xff
|
|
86
|
+
when 0x19 then irq_status # Latch + master IRQ bit, unused bits read 1
|
|
87
|
+
else @registers.read(i)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def poke(addr, value)
|
|
92
|
+
@registers.write(index(addr) % (2**6), value)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def position
|
|
96
|
+
(@rasterline * @width) + (@column * 8)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def dma_active?
|
|
100
|
+
@display_state.bad_line? && @column >= 15 && @column < 55
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def ba_low?
|
|
104
|
+
return true if @sprite_ba[@column]
|
|
105
|
+
|
|
106
|
+
@display_state.bad_line? && @column >= 13 && @column < 56
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def hblank?
|
|
110
|
+
@column < 10 || @column > 60
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def vblank?
|
|
114
|
+
@rasterline < 16 || @rasterline > 299
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def blanking?
|
|
118
|
+
@rasterline < 16 || @rasterline > 299 || @column < 10 || @column > 60
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Reset the dirty flags once the frontend has consumed them.
|
|
122
|
+
def clear_dirty_lines!
|
|
123
|
+
@dirty_lines.fill(false)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
private
|
|
127
|
+
|
|
128
|
+
def rebuild_sprite_ba
|
|
129
|
+
@sprite_ba.fill(false)
|
|
130
|
+
SPRITE_BA_RANGES.each_with_index do |range, n|
|
|
131
|
+
next unless @sprites[n].displaying?
|
|
132
|
+
|
|
133
|
+
range.each { |c| @sprite_ba[c] = true }
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def draw!
|
|
138
|
+
return if blanking?
|
|
139
|
+
|
|
140
|
+
col = @column - 16
|
|
141
|
+
unless @display_state.display?
|
|
142
|
+
@sequencer.emit_idle(col)
|
|
143
|
+
return
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
cell = (@display_state.vc_base + col) & 0x3ff
|
|
147
|
+
screencode = @character_buffer[col] || 0
|
|
148
|
+
@sequencer.emit(screencode, @color_buffer[col] || 1, col,
|
|
149
|
+
cell, @display_state.rc)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def finish_line!
|
|
153
|
+
return if vblank?
|
|
154
|
+
|
|
155
|
+
# Composite the active sprites over the finished background line
|
|
156
|
+
# and copy the line into the frame display.
|
|
157
|
+
if @sprites.active?
|
|
158
|
+
@sprites.composite(@sequencer.colors, @sequencer.fg)
|
|
159
|
+
@sequencer.apply_border
|
|
160
|
+
end
|
|
161
|
+
base = @rasterline * @width
|
|
162
|
+
colors = @sequencer.colors
|
|
163
|
+
return if @display[base, @width] == colors
|
|
164
|
+
|
|
165
|
+
@display[base, @width] = colors
|
|
166
|
+
@dirty_lines[@rasterline] = true
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def video_matrix(index)
|
|
170
|
+
vic_bank.peek(@registers.screen_base + index)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def check_raster_irq!
|
|
174
|
+
return unless @rasterline == @registers.raster_target
|
|
175
|
+
|
|
176
|
+
# Latch the raster IRQ flag. The line asserts via #interrupted? when the
|
|
177
|
+
# matching mask bit in $D01A is set.
|
|
178
|
+
@registers.latch_raster_irq!
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def irq_status
|
|
182
|
+
(@registers[0x19] & 0x0f) | 0x70 | (interrupted? ? 0x80 : 0)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def fetch_character_data!
|
|
186
|
+
vmli = @column - 15
|
|
187
|
+
vc = (@display_state.vc_base + vmli) & 0x3ff
|
|
188
|
+
@character_buffer[vmli] = video_matrix(vc)
|
|
189
|
+
@color_buffer[vmli] = vic_bank.peek_color(vc)
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|
data/lib/badline.rb
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "badline/version"
|
|
4
|
+
require "badline/integer_helper"
|
|
5
|
+
require "badline/addressable"
|
|
6
|
+
require "badline/memory"
|
|
7
|
+
require "badline/color_memory"
|
|
8
|
+
require "badline/rom"
|
|
9
|
+
require "badline/address_bus"
|
|
10
|
+
require "badline/instruction"
|
|
11
|
+
require "badline/instruction_set"
|
|
12
|
+
require "badline/status"
|
|
13
|
+
require "badline/keyboard"
|
|
14
|
+
require "badline/joystick"
|
|
15
|
+
require "badline/control_ports"
|
|
16
|
+
require "badline/cycleable"
|
|
17
|
+
require "badline/time_of_day"
|
|
18
|
+
require "badline/cia"
|
|
19
|
+
require "badline/sid"
|
|
20
|
+
require "badline/traps"
|
|
21
|
+
require "badline/cpu"
|
|
22
|
+
require "badline/vic"
|
|
23
|
+
require "badline/keyboard_buffer"
|
|
24
|
+
require "badline/computer"
|
|
25
|
+
require "badline/storage"
|
|
26
|
+
require "badline/cartridge"
|
|
27
|
+
require "badline/kernal_trap"
|
|
28
|
+
require "badline/chrout_trap"
|
|
29
|
+
require "badline/media"
|
metadata
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: badline
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Inge Jørgensen
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: ruby-sdl2
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0.3'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0.3'
|
|
26
|
+
description: Badline is a Commodore 64 emulator written in Ruby, implementing cycle-accurate
|
|
27
|
+
timing and hardware behavior. Supports PRG/P00 programs, D64/D71/D81 disk images
|
|
28
|
+
and CRT cartridges.
|
|
29
|
+
email:
|
|
30
|
+
- inge@elektronaut.no
|
|
31
|
+
executables:
|
|
32
|
+
- badline
|
|
33
|
+
extensions: []
|
|
34
|
+
extra_rdoc_files: []
|
|
35
|
+
files:
|
|
36
|
+
- MIT-LICENSE
|
|
37
|
+
- README.md
|
|
38
|
+
- exe/badline
|
|
39
|
+
- lib/badline.rb
|
|
40
|
+
- lib/badline/address_bus.rb
|
|
41
|
+
- lib/badline/addressable.rb
|
|
42
|
+
- lib/badline/cartridge.rb
|
|
43
|
+
- lib/badline/cartridge/magic_desk.rb
|
|
44
|
+
- lib/badline/cartridge/ocean.rb
|
|
45
|
+
- lib/badline/cartridge/standard.rb
|
|
46
|
+
- lib/badline/chrout_trap.rb
|
|
47
|
+
- lib/badline/cia.rb
|
|
48
|
+
- lib/badline/cia/timer.rb
|
|
49
|
+
- lib/badline/color_memory.rb
|
|
50
|
+
- lib/badline/computer.rb
|
|
51
|
+
- lib/badline/control_ports.rb
|
|
52
|
+
- lib/badline/cpu.rb
|
|
53
|
+
- lib/badline/cycleable.rb
|
|
54
|
+
- lib/badline/gui.rb
|
|
55
|
+
- lib/badline/gui/application.rb
|
|
56
|
+
- lib/badline/gui/joy_map.rb
|
|
57
|
+
- lib/badline/gui/key_map.rb
|
|
58
|
+
- lib/badline/gui/palette.rb
|
|
59
|
+
- lib/badline/gui/pane.rb
|
|
60
|
+
- lib/badline/gui/screen_pane.rb
|
|
61
|
+
- lib/badline/gui/window.rb
|
|
62
|
+
- lib/badline/instruction.rb
|
|
63
|
+
- lib/badline/instruction_set.rb
|
|
64
|
+
- lib/badline/instruction_set/arithmetic.rb
|
|
65
|
+
- lib/badline/instruction_set/bitwise.rb
|
|
66
|
+
- lib/badline/instruction_set/branch.rb
|
|
67
|
+
- lib/badline/instruction_set/flag.rb
|
|
68
|
+
- lib/badline/instruction_set/illegal.rb
|
|
69
|
+
- lib/badline/instruction_set/inc_dec.rb
|
|
70
|
+
- lib/badline/instruction_set/stack.rb
|
|
71
|
+
- lib/badline/instruction_set/transfer.rb
|
|
72
|
+
- lib/badline/integer_helper.rb
|
|
73
|
+
- lib/badline/joystick.rb
|
|
74
|
+
- lib/badline/kernal_trap.rb
|
|
75
|
+
- lib/badline/kernal_trap/file.rb
|
|
76
|
+
- lib/badline/kernal_trap/load.rb
|
|
77
|
+
- lib/badline/kernal_trap/save.rb
|
|
78
|
+
- lib/badline/keyboard.rb
|
|
79
|
+
- lib/badline/keyboard_buffer.rb
|
|
80
|
+
- lib/badline/media.rb
|
|
81
|
+
- lib/badline/memory.rb
|
|
82
|
+
- lib/badline/rom.rb
|
|
83
|
+
- lib/badline/roms/README
|
|
84
|
+
- lib/badline/roms/basic.rom
|
|
85
|
+
- lib/badline/roms/character.rom
|
|
86
|
+
- lib/badline/roms/kernal.rom
|
|
87
|
+
- lib/badline/sid.rb
|
|
88
|
+
- lib/badline/status.rb
|
|
89
|
+
- lib/badline/storage.rb
|
|
90
|
+
- lib/badline/storage/crt_file.rb
|
|
91
|
+
- lib/badline/storage/d64_image.rb
|
|
92
|
+
- lib/badline/storage/d71_image.rb
|
|
93
|
+
- lib/badline/storage/d81_image.rb
|
|
94
|
+
- lib/badline/storage/disk_image.rb
|
|
95
|
+
- lib/badline/storage/host_directory.rb
|
|
96
|
+
- lib/badline/storage/p00.rb
|
|
97
|
+
- lib/badline/time_of_day.rb
|
|
98
|
+
- lib/badline/traps.rb
|
|
99
|
+
- lib/badline/version.rb
|
|
100
|
+
- lib/badline/vic.rb
|
|
101
|
+
- lib/badline/vic/bank.rb
|
|
102
|
+
- lib/badline/vic/display_state.rb
|
|
103
|
+
- lib/badline/vic/graphics_mode.rb
|
|
104
|
+
- lib/badline/vic/registers.rb
|
|
105
|
+
- lib/badline/vic/sequencer.rb
|
|
106
|
+
- lib/badline/vic/sprite.rb
|
|
107
|
+
- lib/badline/vic/sprites.rb
|
|
108
|
+
homepage: https://github.com/elektronaut/badline
|
|
109
|
+
licenses:
|
|
110
|
+
- MIT
|
|
111
|
+
metadata:
|
|
112
|
+
source_code_uri: https://github.com/elektronaut/badline
|
|
113
|
+
rubygems_mfa_required: 'true'
|
|
114
|
+
rdoc_options: []
|
|
115
|
+
require_paths:
|
|
116
|
+
- lib
|
|
117
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
118
|
+
requirements:
|
|
119
|
+
- - ">="
|
|
120
|
+
- !ruby/object:Gem::Version
|
|
121
|
+
version: '4.0'
|
|
122
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
|
+
requirements:
|
|
124
|
+
- - ">="
|
|
125
|
+
- !ruby/object:Gem::Version
|
|
126
|
+
version: '0'
|
|
127
|
+
requirements: []
|
|
128
|
+
rubygems_version: 4.0.3
|
|
129
|
+
specification_version: 4
|
|
130
|
+
summary: A cycle-accurate Commodore 64 emulator
|
|
131
|
+
test_files: []
|