Rdcpu16 0.0.3.1 → 0.0.4.alpha
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.
- data/bin/dcpu16.rb +32 -0
- data/lib/dcpu16/assembler.rb +260 -18
- data/lib/dcpu16/{instruction.rb → cpu/instruction.rb} +32 -30
- data/lib/dcpu16/cpu/operand.rb +43 -0
- data/lib/dcpu16/cpu/register.rb +37 -0
- data/lib/dcpu16/cpu.rb +25 -17
- data/lib/dcpu16/debugger.rb +31 -0
- data/lib/dcpu16/memory/word.rb +22 -0
- data/lib/dcpu16/memory.rb +6 -5
- data/lib/dcpu16/screen.rb +155 -0
- data/lib/dcpu16/version.rb +1 -1
- data/lib/dcpu16/version.rb~ +1 -1
- data/lib/dcpu16.rb +4 -0
- data/spec/fixtures/example.dasm16 +20 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/unit/assembler_spec.rb +14 -0
- data/spec/unit/{dcpu16_cpu_spec.rb → cpu/cpu_spec.rb} +4 -4
- data/spec/unit/{dcpu16_instruction_spec.rb → cpu/instruction_spec.rb} +7 -7
- data/spec/unit/{dcpu16_operand_spec.rb → cpu/operand_spec.rb} +14 -14
- data/spec/unit/cpu/register_spec.rb +6 -0
- data/spec/unit/{dcpu16_memory_spec.rb → memory/memory_spec.rb} +1 -1
- data/spec/unit/{dcpu16_word_spec.rb → memory/word_spec.rb} +3 -3
- data/spec/unit/screen_spec.rb +51 -0
- data/spec/unit/support/screen_observer.rb +13 -0
- metadata +36 -29
- data/lib/dcpu16/operand.rb +0 -61
- data/lib/dcpu16/register.rb +0 -35
- data/lib/dcpu16/word.rb +0 -20
- data/spec/fixtures/example.asm +0 -29
- data/spec/unit/dcpu16_assembler_spec.rb +0 -10
- data/spec/unit/dcpu16_register_spec.rb +0 -6
- /data/spec/unit/{dcpu16_instructions_spec.rb → cpu/instructions_spec.rb} +0 -0
@@ -0,0 +1,155 @@
|
|
1
|
+
require 'observer'
|
2
|
+
|
3
|
+
# Text VRAM starts at 0x8000 and is word-based (16bits per address cell)
|
4
|
+
# like other memory and is in the same address space as the rest of the processor uses.
|
5
|
+
|
6
|
+
# The low 8 bits determine the character shown.
|
7
|
+
|
8
|
+
# The high 8 bits determine the color;
|
9
|
+
# the highest 4 are the foreground and the lowest 4 are the background.
|
10
|
+
|
11
|
+
# The color nibbles use (from LSB to MSB) blue, green, red, highlight.
|
12
|
+
# (Normal 16color from PCs, though probably with darkyellow instead of brown)
|
13
|
+
|
14
|
+
# The screen appears to be 32 characters by 12 lines, with a character cell of 4x8 pixels,
|
15
|
+
# suggesting possible graphics modes of 128x96 pixels at that resolution.
|
16
|
+
|
17
|
+
# require 'dcpu16'; cpu = DCPU16::CPU.new; screen = DCPU16::Screen.new(cpu.memory); cpu.memory.write(0x8000, 0x30)
|
18
|
+
|
19
|
+
|
20
|
+
# TODO: OUTPUT
|
21
|
+
# require 'dcpu16'; debugger = DCPU16::Debugger.new
|
22
|
+
module DCPU16
|
23
|
+
class Screen
|
24
|
+
include Observable
|
25
|
+
|
26
|
+
X_OFFSET = 2
|
27
|
+
Y_OFFSET = 2
|
28
|
+
|
29
|
+
attr_reader :width, :height, :memory_offset, :chars
|
30
|
+
|
31
|
+
def initialize(memory, options = {})
|
32
|
+
@memory = memory
|
33
|
+
@width = options[:width] || 32
|
34
|
+
@height = options[:height] || 12
|
35
|
+
@memory_offset = options[:memory_offset] || 0x8000
|
36
|
+
|
37
|
+
@x_offset = options[:x_offset] || X_OFFSET
|
38
|
+
@y_offset = options[:y_offset] || Y_OFFSET
|
39
|
+
|
40
|
+
|
41
|
+
# Initial Screen dump
|
42
|
+
@chars = []
|
43
|
+
@height.times do |h|
|
44
|
+
@width.times do |w|
|
45
|
+
offset = h * @width + w
|
46
|
+
value = @memory.read(@memory_offset + 2*offset).value
|
47
|
+
@chars[offset] = Char.new(value, w + @x_offset, h + @y_offset)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
@memory.add_observer(self)
|
52
|
+
# print self
|
53
|
+
end
|
54
|
+
|
55
|
+
def size
|
56
|
+
@size ||= @width * @height
|
57
|
+
end
|
58
|
+
|
59
|
+
def memory_offset_end
|
60
|
+
@memory_offset_end ||= 0x82FE#@memory_offset + size*2 - 2
|
61
|
+
end
|
62
|
+
|
63
|
+
def to_s
|
64
|
+
return @to_s if @to_s
|
65
|
+
|
66
|
+
@to_s = "\e[?1049h\e[17;1H"
|
67
|
+
@to_s << chars.join
|
68
|
+
@to_s << frame
|
69
|
+
end
|
70
|
+
|
71
|
+
# Use a fancy border around console
|
72
|
+
def frame
|
73
|
+
return @frame if @frame
|
74
|
+
|
75
|
+
chars = []
|
76
|
+
# 4 corners
|
77
|
+
chars << Char.new(0x23, @x_offset - 1, @y_offset - 1) # TopLeft
|
78
|
+
chars << Char.new(0x23, @x_offset + @width, @y_offset - 1) # TopRight
|
79
|
+
chars << Char.new(0x23, @x_offset - 1, @y_offset + @height) # BottomLeft
|
80
|
+
chars << Char.new(0x23, @x_offset + @width, @y_offset + @height) # BottomRight
|
81
|
+
|
82
|
+
# horiz
|
83
|
+
@width.times { |x| chars << Char.new(0x2d, x + @x_offset, @y_offset - 1) }
|
84
|
+
@width.times { |x| chars << Char.new(0x2d, x + @x_offset, @y_offset + @height) }
|
85
|
+
|
86
|
+
# vertical
|
87
|
+
@height.times { |y| chars << Char.new(0x7c, @x_offset - 1, y + @y_offset) }
|
88
|
+
@height.times { |y| chars << Char.new(0x7c, @x_offset + @width, y + @y_offset) }
|
89
|
+
@frame = ""
|
90
|
+
@frame << chars.join
|
91
|
+
end
|
92
|
+
|
93
|
+
# Callback from observed memory
|
94
|
+
def update(offset, value)
|
95
|
+
return unless (memory_offset..memory_offset_end).include?(offset)
|
96
|
+
# @to_s = nil
|
97
|
+
|
98
|
+
diff = (offset - @memory_offset) / 2
|
99
|
+
h = diff / @width
|
100
|
+
w = diff % @width
|
101
|
+
@chars[diff] = Char.new(value, w + @x_offset, h + @y_offset)
|
102
|
+
print @chars[diff]
|
103
|
+
# changed
|
104
|
+
# notify_observers(self)
|
105
|
+
# print @chars[diff]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# DOC
|
110
|
+
# Inspired by: https://github.com/judofyr/rcpu/blob/master/lib/rcpu/libraries.rb
|
111
|
+
class Char
|
112
|
+
attr_reader :output
|
113
|
+
def initialize(value, x, y)
|
114
|
+
@char = (value & 0x007F).chr
|
115
|
+
# @bg_color = (value >> 8) & 0x0F
|
116
|
+
# @fg_color = value >> 12
|
117
|
+
|
118
|
+
args = []
|
119
|
+
args << (value >> 15)
|
120
|
+
if value > 0x7F
|
121
|
+
args << color_to_ansi(value >> 12) + 30
|
122
|
+
args << color_to_ansi(value >> 8) + 40
|
123
|
+
end
|
124
|
+
|
125
|
+
@char = " " if @char.ord.zero?
|
126
|
+
@color = "\e[#{args*';'}m"
|
127
|
+
@output = "\e7\e[#{y};#{x}H#{@color}#{@char}\e8"
|
128
|
+
end
|
129
|
+
|
130
|
+
def to_s
|
131
|
+
@output
|
132
|
+
end
|
133
|
+
|
134
|
+
def color_to_ansi(bit)
|
135
|
+
((bit & 1) << 2) | (bit & 2) | ((bit & 4) >> 2)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
|
142
|
+
#The high 8 bits determine the color; the highest 4 are the foreground and the lowest 4 are the background
|
143
|
+
|
144
|
+
#args = []
|
145
|
+
#args << (value >> 15)
|
146
|
+
#if value > 0x7F
|
147
|
+
# args << color_to_ansi(value >> 12) + 30
|
148
|
+
# args << color_to_ansi(value >> 8) + 40
|
149
|
+
#end
|
150
|
+
|
151
|
+
#char = " " if char.ord.zero?
|
152
|
+
|
153
|
+
#color = "\e[#{args*';'}m"
|
154
|
+
#print "\e7\e[#{rows+1};#{cols+1}H#{color}#{char}\e8"
|
155
|
+
|
data/lib/dcpu16/version.rb
CHANGED
data/lib/dcpu16/version.rb~
CHANGED
data/lib/dcpu16.rb
CHANGED
@@ -0,0 +1,20 @@
|
|
1
|
+
; Patrick Helm, deradon87@gmail.com
|
2
|
+
;
|
3
|
+
; Flash Screen with chars (Benchmark)
|
4
|
+
;
|
5
|
+
; Output:
|
6
|
+
; * Cycle: 519002 (Cycle needed to finish)
|
7
|
+
; * Clock: 100000 (Clock-Speed of CPU [defined])
|
8
|
+
; * HZ: 99999.02 (Clock-Speed of CPU [real])
|
9
|
+
|
10
|
+
SET C, 0x30 ; Init OuterLoop
|
11
|
+
:outer_loop SET B, 0 ; Init InnerLoop
|
12
|
+
:inner_loop SET [0x8000+B], C ;draw
|
13
|
+
ADD B, 1
|
14
|
+
IFG 0x0300, B
|
15
|
+
SET PC, inner_loop ;jmp inner_loop
|
16
|
+
|
17
|
+
ADD C,1
|
18
|
+
IFG 0x7B, C
|
19
|
+
SET PC, outer_loop ;jmp outer_loop
|
20
|
+
|
data/spec/spec_helper.rb
CHANGED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
|
3
|
+
describe DCPU16::Assembler do
|
4
|
+
let(:asm) { File.open(File.join('spec', 'fixtures', 'example.dasm16')).read }
|
5
|
+
subject { DCPU16::Assembler.new(asm) }
|
6
|
+
|
7
|
+
its(:input) { should == asm }
|
8
|
+
its(:dump) { should be_a_kind_of(Array) }
|
9
|
+
specify do
|
10
|
+
# puts subject.dump
|
11
|
+
puts subject.dump.first.bytes.length
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
@@ -7,11 +7,11 @@ describe DCPU16::CPU do
|
|
7
7
|
|
8
8
|
describe "Register" do
|
9
9
|
its(:registers) { subject.length == 8 }
|
10
|
-
its(:registers) { subject[0] == be_kind_of(DCPU16::Register) }
|
10
|
+
its(:registers) { subject[0] == be_kind_of(DCPU16::CPU::Register) }
|
11
11
|
|
12
|
-
its(:PC) { should be_kind_of(DCPU16::Register) }
|
13
|
-
its(:SP) { should be_kind_of(DCPU16::Register) }
|
14
|
-
its(:O) { should be_kind_of(DCPU16::Register) }
|
12
|
+
its(:PC) { should be_kind_of(DCPU16::CPU::Register) }
|
13
|
+
its(:SP) { should be_kind_of(DCPU16::CPU::Register) }
|
14
|
+
its(:O) { should be_kind_of(DCPU16::CPU::Register) }
|
15
15
|
end
|
16
16
|
|
17
17
|
its(:cycle) { should == 0 }
|
@@ -1,25 +1,25 @@
|
|
1
1
|
require 'spec_helper.rb'
|
2
2
|
|
3
|
-
describe DCPU16::Instruction do
|
3
|
+
describe DCPU16::CPU::Instruction do
|
4
4
|
context "when initialized with 0x00" do
|
5
|
-
let(:word) { DCPU16::Word.new(0x00) }
|
6
|
-
subject { DCPU16::Instruction.new(word) }
|
5
|
+
let(:word) { DCPU16::Memory::Word.new(0x00) }
|
6
|
+
subject { DCPU16::CPU::Instruction.new(word) }
|
7
7
|
its(:opcode) { should == 0 }
|
8
8
|
its(:a) { should == 0 }
|
9
9
|
its(:b) { should be_nil }
|
10
10
|
end
|
11
11
|
|
12
12
|
context "when initialized with 0x0001" do
|
13
|
-
let(:word) { DCPU16::Word.new(0x0001) }
|
14
|
-
subject { DCPU16::Instruction.new(word) }
|
13
|
+
let(:word) { DCPU16::Memory::Word.new(0x0001) }
|
14
|
+
subject { DCPU16::CPU::Instruction.new(word) }
|
15
15
|
its(:opcode) { should == 1 }
|
16
16
|
its(:a) { should == 0 }
|
17
17
|
its(:b) { should == 0 }
|
18
18
|
end
|
19
19
|
|
20
20
|
context "when initialized with 0xa861" do
|
21
|
-
let(:word) { DCPU16::Word.new(0xa861) }
|
22
|
-
subject { DCPU16::Instruction.new(word) }
|
21
|
+
let(:word) { DCPU16::Memory::Word.new(0xa861) }
|
22
|
+
subject { DCPU16::CPU::Instruction.new(word) }
|
23
23
|
its(:opcode) { should == 1 }
|
24
24
|
its(:a) { should == 0x6 }
|
25
25
|
its(:b) { should == 0xa + 0x20 } # Literal value (offset += 0x20)
|
@@ -4,14 +4,14 @@ describe DCPU16::Instructions do
|
|
4
4
|
let(:cpu) { DCPU16::CPU.new }
|
5
5
|
|
6
6
|
context "when value is between 0x00 and 0x07" do
|
7
|
-
specify {
|
8
|
-
specify {
|
9
|
-
specify {
|
10
|
-
specify {
|
11
|
-
specify {
|
12
|
-
specify {
|
13
|
-
specify {
|
14
|
-
specify {
|
7
|
+
specify { cpu.get_operand(0x0).should == cpu.A }
|
8
|
+
specify { cpu.get_operand(0x1).should == cpu.B }
|
9
|
+
specify { cpu.get_operand(0x2).should == cpu.C }
|
10
|
+
specify { cpu.get_operand(0x3).should == cpu.X }
|
11
|
+
specify { cpu.get_operand(0x4).should == cpu.Y }
|
12
|
+
specify { cpu.get_operand(0x5).should == cpu.Z }
|
13
|
+
specify { cpu.get_operand(0x6).should == cpu.I }
|
14
|
+
specify { cpu.get_operand(0x7).should == cpu.J }
|
15
15
|
end
|
16
16
|
|
17
17
|
context "when value is between 0x08 and 0x17" do
|
@@ -20,8 +20,8 @@ describe DCPU16::Instructions do
|
|
20
20
|
cpu.registers.each { |r| r.write(0x1000) }
|
21
21
|
end
|
22
22
|
|
23
|
-
specify {
|
24
|
-
specify {
|
23
|
+
specify { cpu.get_operand(0x8).value.should == 0x2a }
|
24
|
+
specify { cpu.get_operand(0xF).value.should == 0x2a }
|
25
25
|
end
|
26
26
|
|
27
27
|
|
@@ -62,15 +62,15 @@ describe DCPU16::Instructions do
|
|
62
62
|
end
|
63
63
|
|
64
64
|
context "when value is between 0x20 and 0x3f" do
|
65
|
-
specify {
|
66
|
-
specify {
|
67
|
-
specify {
|
65
|
+
specify { cpu.get_operand(0x20).should be_a_kind_of(DCPU16::Literal) }
|
66
|
+
specify { cpu.get_operand(0x20).value.should == 0x0 }
|
67
|
+
specify { cpu.get_operand(0x3f).value.should == 0x1f }
|
68
68
|
end
|
69
69
|
|
70
70
|
context "when value is > 0x3f" do
|
71
71
|
specify do
|
72
72
|
expect {
|
73
|
-
|
73
|
+
cpu.get_operand(0x40)
|
74
74
|
}.to raise_error(DCPU16::Operand::NotFound)
|
75
75
|
end
|
76
76
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'spec_helper.rb'
|
2
2
|
|
3
|
-
describe DCPU16::Word do
|
3
|
+
describe DCPU16::Memory::Word do
|
4
4
|
let(:memory) { DCPU16::Memory.new }
|
5
|
-
subject { DCPU16::Word.new(2, memory, 0) }
|
5
|
+
subject { DCPU16::Memory::Word.new(2, memory, 0) }
|
6
6
|
|
7
|
-
specify { subject.should be_a_kind_of(DCPU16::Word) }
|
7
|
+
specify { subject.should be_a_kind_of(DCPU16::Memory::Word) }
|
8
8
|
its(:value) { should == 2 }
|
9
9
|
its(:read) { should == 2 }
|
10
10
|
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'unit/support/screen_observer'
|
3
|
+
|
4
|
+
describe DCPU16::Screen do
|
5
|
+
let(:memory) { DCPU16::Memory.new }
|
6
|
+
subject { DCPU16::Screen.new(memory) }
|
7
|
+
|
8
|
+
describe "initialize" do
|
9
|
+
specify { expect { DCPU16::Screen.new }.to raise_error(ArgumentError) }
|
10
|
+
specify { expect { DCPU16::Screen.new(memory) }.to_not raise_error }
|
11
|
+
its(:width) { should == 32 }
|
12
|
+
its(:height) { should == 12 }
|
13
|
+
its(:memory_offset) { should == 0x8000 }
|
14
|
+
its(:chars) { subject.length.should == 32*12 } # width * height + newlines
|
15
|
+
|
16
|
+
context "when called with options" do
|
17
|
+
let(:options) { {:width => 40, :height => 200, :memory_offset => 0x9000} }
|
18
|
+
subject { DCPU16::Screen.new(memory, options) }
|
19
|
+
|
20
|
+
its(:width) { should == 40 }
|
21
|
+
its(:height) { should == 200 }
|
22
|
+
its(:memory_offset) { should == 0x9000 }
|
23
|
+
its(:chars) { subject.length.should == 40 * 200 }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#to_s" do
|
28
|
+
context "in initial state" do
|
29
|
+
pending
|
30
|
+
# let(:expected) { String.new(" "*32 + "\n") * 12 }
|
31
|
+
# its(:to_s) { should == expected }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "observable" do
|
36
|
+
let(:observer) { DCPU16::ScreenObserver.new }
|
37
|
+
before(:all) { subject.add_observer(observer) }
|
38
|
+
|
39
|
+
specify { subject.should_receive(:update).tap { memory.write(0x8000, 40) } }
|
40
|
+
context "memory outside of screen changed" do
|
41
|
+
specify { observer.should_not_receive(:update).tap { memory.write(0x7FFF, 40) } }
|
42
|
+
specify { observer.should_not_receive(:update).tap { memory.write(0x8000 + 0x180, 40) } }
|
43
|
+
end
|
44
|
+
context "memory of screen changed" do
|
45
|
+
pending "Disabled Observer right now!"
|
46
|
+
# specify { observer.should_receive(:update).tap { memory.write(0x8000, 40) } }
|
47
|
+
# specify { observer.should_receive(:update).tap { memory.write(0x82FE, 40) } }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
metadata
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: Rdcpu16
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.4.alpha
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Patrick Helm
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-04-
|
12
|
+
date: 2012-04-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &85435200 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: '2.6'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *85435200
|
25
25
|
description: This is a simple Ruby port of the fictive 16-bit-cpu DCPU16.
|
26
26
|
email:
|
27
27
|
- deradon87@gmail.com
|
@@ -29,34 +29,39 @@ executables: []
|
|
29
29
|
extensions: []
|
30
30
|
extra_rdoc_files: []
|
31
31
|
files:
|
32
|
+
- bin/dcpu16.rb
|
32
33
|
- lib/dcpu16/cpu.rb
|
33
34
|
- lib/dcpu16/assembler.rb
|
34
|
-
- lib/dcpu16/operand.rb
|
35
35
|
- lib/dcpu16/memory.rb
|
36
|
-
- lib/dcpu16/word.rb
|
37
36
|
- lib/dcpu16/version.rb
|
37
|
+
- lib/dcpu16/memory/word.rb
|
38
|
+
- lib/dcpu16/cpu/operand.rb
|
39
|
+
- lib/dcpu16/cpu/instruction.rb
|
38
40
|
- lib/dcpu16/cpu/instructions.rb
|
41
|
+
- lib/dcpu16/cpu/register.rb
|
42
|
+
- lib/dcpu16/screen.rb
|
39
43
|
- lib/dcpu16/support/debug.rb
|
40
44
|
- lib/dcpu16/version.rb~
|
41
45
|
- lib/dcpu16/literal.rb
|
42
|
-
- lib/dcpu16/
|
43
|
-
- lib/dcpu16/register.rb
|
46
|
+
- lib/dcpu16/debugger.rb
|
44
47
|
- lib/dcpu16.rb
|
45
48
|
- MIT-LICENSE
|
46
49
|
- Rakefile
|
47
50
|
- README.rdoc
|
48
|
-
- spec/fixtures/example.
|
51
|
+
- spec/fixtures/example.dasm16
|
49
52
|
- spec/integration/example1_spec.rb
|
50
|
-
- spec/unit/
|
51
|
-
- spec/unit/
|
53
|
+
- spec/unit/assembler_spec.rb
|
54
|
+
- spec/unit/memory/memory_spec.rb
|
55
|
+
- spec/unit/memory/word_spec.rb
|
56
|
+
- spec/unit/cpu/operand_spec.rb
|
57
|
+
- spec/unit/cpu/instruction_spec.rb
|
58
|
+
- spec/unit/cpu/register_spec.rb
|
59
|
+
- spec/unit/cpu/instructions_spec.rb
|
60
|
+
- spec/unit/cpu/cpu_spec.rb
|
52
61
|
- spec/unit/support/sample_observer.rb
|
62
|
+
- spec/unit/support/screen_observer.rb
|
53
63
|
- spec/unit/support/memory_observer.rb
|
54
|
-
- spec/unit/
|
55
|
-
- spec/unit/dcpu16_cpu_spec.rb
|
56
|
-
- spec/unit/dcpu16_memory_spec.rb
|
57
|
-
- spec/unit/dcpu16_instructions_spec.rb
|
58
|
-
- spec/unit/dcpu16_operand_spec.rb
|
59
|
-
- spec/unit/dcpu16_instruction_spec.rb
|
64
|
+
- spec/unit/screen_spec.rb
|
60
65
|
- spec/spec_helper.rb
|
61
66
|
homepage: https://github.com/Deradon/Rdcpu16
|
62
67
|
licenses: []
|
@@ -73,9 +78,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
73
78
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
79
|
none: false
|
75
80
|
requirements:
|
76
|
-
- - ! '
|
81
|
+
- - ! '>'
|
77
82
|
- !ruby/object:Gem::Version
|
78
|
-
version:
|
83
|
+
version: 1.3.1
|
79
84
|
requirements: []
|
80
85
|
rubyforge_project:
|
81
86
|
rubygems_version: 1.8.10
|
@@ -83,16 +88,18 @@ signing_key:
|
|
83
88
|
specification_version: 3
|
84
89
|
summary: Ruby port of DCPU16
|
85
90
|
test_files:
|
86
|
-
- spec/fixtures/example.
|
91
|
+
- spec/fixtures/example.dasm16
|
87
92
|
- spec/integration/example1_spec.rb
|
88
|
-
- spec/unit/
|
89
|
-
- spec/unit/
|
93
|
+
- spec/unit/assembler_spec.rb
|
94
|
+
- spec/unit/memory/memory_spec.rb
|
95
|
+
- spec/unit/memory/word_spec.rb
|
96
|
+
- spec/unit/cpu/operand_spec.rb
|
97
|
+
- spec/unit/cpu/instruction_spec.rb
|
98
|
+
- spec/unit/cpu/register_spec.rb
|
99
|
+
- spec/unit/cpu/instructions_spec.rb
|
100
|
+
- spec/unit/cpu/cpu_spec.rb
|
90
101
|
- spec/unit/support/sample_observer.rb
|
102
|
+
- spec/unit/support/screen_observer.rb
|
91
103
|
- spec/unit/support/memory_observer.rb
|
92
|
-
- spec/unit/
|
93
|
-
- spec/unit/dcpu16_cpu_spec.rb
|
94
|
-
- spec/unit/dcpu16_memory_spec.rb
|
95
|
-
- spec/unit/dcpu16_instructions_spec.rb
|
96
|
-
- spec/unit/dcpu16_operand_spec.rb
|
97
|
-
- spec/unit/dcpu16_instruction_spec.rb
|
104
|
+
- spec/unit/screen_spec.rb
|
98
105
|
- spec/spec_helper.rb
|
data/lib/dcpu16/operand.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
# TODO: Test && Refacoring
|
2
|
-
module DCPU16
|
3
|
-
class Operand
|
4
|
-
class NotFound < StandardError; end
|
5
|
-
|
6
|
-
def self.new(cpu, value)
|
7
|
-
if (0x00..0x07).include?(value)
|
8
|
-
# register (A, B, C, X, Y, Z, I or J, in that order)
|
9
|
-
return cpu.registers[value]
|
10
|
-
elsif (0x08..0x0f).include?(value)
|
11
|
-
# [register]
|
12
|
-
register = cpu.registers[value - DCPU16::CPU::REGISTERS_COUNT]
|
13
|
-
return cpu.memory.read(register)
|
14
|
-
elsif (0x10..0x17).include?(value)
|
15
|
-
cpu.cycle += 1
|
16
|
-
offset = cpu.memory.read(cpu.PC).value
|
17
|
-
cpu.PC += 1
|
18
|
-
return cpu.memory.read(offset + cpu.registers[value - 0x10].read)
|
19
|
-
elsif value == 0x18
|
20
|
-
# POP / [SP++]
|
21
|
-
r = cpu.memory.read(cpu.SP)
|
22
|
-
cpu.SP += 1
|
23
|
-
return r
|
24
|
-
elsif value == 0x19
|
25
|
-
# PEEK / [SP]
|
26
|
-
return cpu.memory.read(cpu.SP)
|
27
|
-
elsif value == 0x1a
|
28
|
-
# PUSH / [--SP]
|
29
|
-
cpu.SP -= 1
|
30
|
-
cpu.memory.read(cpu.SP)
|
31
|
-
elsif value == 0x1b
|
32
|
-
# SP
|
33
|
-
return cpu.SP
|
34
|
-
elsif value == 0x1c
|
35
|
-
# PC
|
36
|
-
return cpu.PC
|
37
|
-
elsif value == 0x1d
|
38
|
-
# O
|
39
|
-
return cpu.O
|
40
|
-
elsif value == 0x1e
|
41
|
-
# [next word]
|
42
|
-
cpu.cycle += 1
|
43
|
-
offset = cpu.memory.read(cpu.PC)
|
44
|
-
cpu.PC += 1
|
45
|
-
return cpu.memory.read(offset)
|
46
|
-
elsif value == 0x1f
|
47
|
-
# next word (literal)
|
48
|
-
cpu.cycle += 1
|
49
|
-
r = cpu.memory.read(cpu.PC)
|
50
|
-
cpu.PC += 1
|
51
|
-
return r
|
52
|
-
elsif (0x20..0x3f).include?(value)
|
53
|
-
# literal value 0x00-0x1f (literal)
|
54
|
-
DCPU16::Literal.new(value - 0x20)
|
55
|
-
else
|
56
|
-
raise NotFound
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
data/lib/dcpu16/register.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
module DCPU16
|
2
|
-
class Register
|
3
|
-
attr_reader :value
|
4
|
-
|
5
|
-
def initialize(value = 0x0)
|
6
|
-
@default_value = value
|
7
|
-
reset
|
8
|
-
end
|
9
|
-
|
10
|
-
def value
|
11
|
-
warn "[Register #{self}] No Value defined" unless @value
|
12
|
-
@value
|
13
|
-
end
|
14
|
-
alias_method :read, :value
|
15
|
-
|
16
|
-
def +(value)
|
17
|
-
@value += value
|
18
|
-
self
|
19
|
-
end
|
20
|
-
|
21
|
-
def -(value)
|
22
|
-
@value -= value
|
23
|
-
self
|
24
|
-
end
|
25
|
-
|
26
|
-
def write(value)
|
27
|
-
@value = value
|
28
|
-
end
|
29
|
-
|
30
|
-
def reset
|
31
|
-
@value = @default_value
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
data/lib/dcpu16/word.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
module DCPU16
|
2
|
-
class Word
|
3
|
-
def initialize(value, memory = nil, offset = nil)
|
4
|
-
@value = value
|
5
|
-
@memory = memory
|
6
|
-
@offset = offset
|
7
|
-
end
|
8
|
-
|
9
|
-
def value
|
10
|
-
@value
|
11
|
-
end
|
12
|
-
alias_method :read, :value
|
13
|
-
|
14
|
-
def write(value)
|
15
|
-
@value = value
|
16
|
-
@memory.write(@offset, value)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|