c8dasm 0.99.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +16 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +15 -0
- data/README.md +109 -0
- data/Rakefile +7 -0
- data/bin/c8dasm +13 -0
- data/c8dasm.gemspec +24 -0
- data/lib/c8dasm.rb +11 -0
- data/lib/c8dasm/assemblies.rb +18 -0
- data/lib/c8dasm/assemblies/asm0.rb +15 -0
- data/lib/c8dasm/assemblies/asm1.rb +10 -0
- data/lib/c8dasm/assemblies/asm2.rb +10 -0
- data/lib/c8dasm/assemblies/asm3.rb +10 -0
- data/lib/c8dasm/assemblies/asm4.rb +9 -0
- data/lib/c8dasm/assemblies/asm5.rb +12 -0
- data/lib/c8dasm/assemblies/asm6.rb +9 -0
- data/lib/c8dasm/assemblies/asm7.rb +9 -0
- data/lib/c8dasm/assemblies/asm8.rb +23 -0
- data/lib/c8dasm/assemblies/asm9.rb +11 -0
- data/lib/c8dasm/assemblies/asm_base.rb +26 -0
- data/lib/c8dasm/assemblies/asma.rb +11 -0
- data/lib/c8dasm/assemblies/asmb.rb +12 -0
- data/lib/c8dasm/assemblies/asmc.rb +11 -0
- data/lib/c8dasm/assemblies/asmd.rb +11 -0
- data/lib/c8dasm/assemblies/asme.rb +16 -0
- data/lib/c8dasm/assemblies/asmf.rb +20 -0
- data/lib/c8dasm/assembly.rb +22 -0
- data/lib/c8dasm/chip8_reader.rb +38 -0
- data/lib/c8dasm/comment.rb +23 -0
- data/lib/c8dasm/comments.rb +17 -0
- data/lib/c8dasm/comments/comment0.rb +14 -0
- data/lib/c8dasm/comments/comment1.rb +10 -0
- data/lib/c8dasm/comments/comment2.rb +11 -0
- data/lib/c8dasm/comments/comment3.rb +11 -0
- data/lib/c8dasm/comments/comment4.rb +11 -0
- data/lib/c8dasm/comments/comment5.rb +12 -0
- data/lib/c8dasm/comments/comment6.rb +11 -0
- data/lib/c8dasm/comments/comment7.rb +11 -0
- data/lib/c8dasm/comments/comment8.rb +25 -0
- data/lib/c8dasm/comments/comment9.rb +11 -0
- data/lib/c8dasm/comments/comment_base.rb +26 -0
- data/lib/c8dasm/comments/commenta.rb +11 -0
- data/lib/c8dasm/comments/commentb.rb +12 -0
- data/lib/c8dasm/comments/commentc.rb +11 -0
- data/lib/c8dasm/comments/commentd.rb +11 -0
- data/lib/c8dasm/comments/commente.rb +15 -0
- data/lib/c8dasm/comments/commentf.rb +30 -0
- data/lib/c8dasm/opcode.rb +34 -0
- data/lib/c8dasm/version.rb +3 -0
- data/spec/15-puzzle.ch8 +0 -0
- data/spec/MAZE +0 -0
- data/spec/c8dasm_spec.rb +7 -0
- data/spec/chip8_reader_spec.rb +27 -0
- data/spec/opcode_0_spec.rb +39 -0
- data/spec/opcode_1_spec.rb +23 -0
- data/spec/opcode_2_spec.rb +23 -0
- data/spec/opcode_3_spec.rb +23 -0
- data/spec/opcode_4_spec.rb +23 -0
- data/spec/opcode_5_spec.rb +25 -0
- data/spec/opcode_6_spec.rb +23 -0
- data/spec/opcode_7_spec.rb +23 -0
- data/spec/opcode_8_spec.rb +119 -0
- data/spec/opcode_9_spec.rb +24 -0
- data/spec/opcode_a_spec.rb +23 -0
- data/spec/opcode_b_spec.rb +24 -0
- data/spec/opcode_c_spec.rb +23 -0
- data/spec/opcode_d_spec.rb +23 -0
- data/spec/opcode_e_spec.rb +39 -0
- data/spec/opcode_f_spec.rb +151 -0
- data/spec/opcode_spec.rb +45 -0
- data/spec/spec_helper.rb +2 -0
- metadata +183 -0
@@ -0,0 +1,20 @@
|
|
1
|
+
module C8dasm
|
2
|
+
|
3
|
+
class Asmf < AsmBase
|
4
|
+
|
5
|
+
def to_s
|
6
|
+
case kk
|
7
|
+
when '07' then "LD V#{x}, DT"
|
8
|
+
when '0a' then "LD V#{x}, KEY"
|
9
|
+
when '15' then "LD DT, V#{x}"
|
10
|
+
when '18' then "LD ST, V#{x}"
|
11
|
+
when '1e' then "ADD I, V#{x}"
|
12
|
+
when '29' then "LD F, V#{x}"
|
13
|
+
when '33' then "LD B, V#{x}"
|
14
|
+
when '55' then "LD [I], V#{x}"
|
15
|
+
when '65' then "LD V#{x}, [I]"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module C8dasm
|
2
|
+
|
3
|
+
class Assembly
|
4
|
+
|
5
|
+
def initialize(opcode)
|
6
|
+
@opcode = opcode
|
7
|
+
@assembly = build_assembly.to_s || ''
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_s
|
11
|
+
@assembly
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def build_assembly
|
17
|
+
klass = Kernel.const_get('C8dasm::Asm' + @opcode[0])
|
18
|
+
klass.new(@opcode)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module C8dasm
|
2
|
+
|
3
|
+
# Read a Chip-8 binary file.
|
4
|
+
#
|
5
|
+
# Examples
|
6
|
+
#
|
7
|
+
# reader = Chip8Reader.new('./MAZE')
|
8
|
+
# p reader.opcodes.first
|
9
|
+
# #=> "a21e"
|
10
|
+
class Chip8Reader
|
11
|
+
|
12
|
+
# Creates a Chip8Reader instance.
|
13
|
+
#
|
14
|
+
# filename - The String name of the binary file to read.
|
15
|
+
def initialize(filename)
|
16
|
+
@file = File.new(filename, 'rb')
|
17
|
+
@opcodes = []
|
18
|
+
binaries_to_opcodes
|
19
|
+
@file.close
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns an Array of String Chip-8 opcodes.
|
23
|
+
attr_reader :opcodes
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def binaries_to_opcodes
|
28
|
+
while not @file.eof?
|
29
|
+
@opcodes << sprintf("%02x%02x", @file.readbyte, @file.readbyte)
|
30
|
+
end
|
31
|
+
rescue EOFError
|
32
|
+
puts 'Error while reading entry file.'
|
33
|
+
exit(2)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module C8dasm
|
2
|
+
|
3
|
+
class Comment
|
4
|
+
|
5
|
+
def initialize(opcode)
|
6
|
+
@opcode = opcode
|
7
|
+
@comment = build_comment.to_s || '***WARNING*** UNKNOWN INSTRUCTION!'
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_s
|
11
|
+
@comment
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def build_comment
|
17
|
+
klass = Kernel.const_get('C8dasm::Comment' + @opcode[0])
|
18
|
+
klass.new(@opcode)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "c8dasm/comments/comment_base"
|
2
|
+
require "c8dasm/comments/comment0"
|
3
|
+
require "c8dasm/comments/comment1"
|
4
|
+
require "c8dasm/comments/comment2"
|
5
|
+
require "c8dasm/comments/comment3"
|
6
|
+
require "c8dasm/comments/comment4"
|
7
|
+
require "c8dasm/comments/comment5"
|
8
|
+
require "c8dasm/comments/comment6"
|
9
|
+
require "c8dasm/comments/comment7"
|
10
|
+
require "c8dasm/comments/comment8"
|
11
|
+
require "c8dasm/comments/comment9"
|
12
|
+
require "c8dasm/comments/commenta"
|
13
|
+
require "c8dasm/comments/commentb"
|
14
|
+
require "c8dasm/comments/commentc"
|
15
|
+
require "c8dasm/comments/commentd"
|
16
|
+
require "c8dasm/comments/commente"
|
17
|
+
require "c8dasm/comments/commentf"
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module C8dasm
|
2
|
+
|
3
|
+
class Comment8 < CommentBase
|
4
|
+
|
5
|
+
def to_s
|
6
|
+
case @opcode[3]
|
7
|
+
when '0'
|
8
|
+
"Set V#{x} = V#{y}."
|
9
|
+
when '2'
|
10
|
+
"Set V#{x} = V#{x} AND V#{y}."
|
11
|
+
when '3'
|
12
|
+
"Set V#{x} = V#{x} XOR V#{y}."
|
13
|
+
when '4'
|
14
|
+
"Set V#{x} = V#{x} + V#{y}, set VF = carry."
|
15
|
+
when '5'
|
16
|
+
"Set V#{x} = V#{x} - V#{y}, set VF = NOT borrow."
|
17
|
+
when '6'
|
18
|
+
"Set V#{x} = V#{y} SHR 1."
|
19
|
+
when 'e'
|
20
|
+
"Set V#{x} = V#{y} SHL 1."
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module C8dasm
|
2
|
+
|
3
|
+
class CommentBase
|
4
|
+
|
5
|
+
def initialize(opcode)
|
6
|
+
@opcode = opcode
|
7
|
+
end
|
8
|
+
|
9
|
+
def nnn
|
10
|
+
@opcode[1, 3]
|
11
|
+
end
|
12
|
+
|
13
|
+
def kk
|
14
|
+
@opcode[2, 2]
|
15
|
+
end
|
16
|
+
|
17
|
+
def x
|
18
|
+
@opcode[1]
|
19
|
+
end
|
20
|
+
|
21
|
+
def y
|
22
|
+
@opcode[2]
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module C8dasm
|
2
|
+
|
3
|
+
class Commentf < CommentBase
|
4
|
+
|
5
|
+
def to_s
|
6
|
+
case kk
|
7
|
+
when '07'
|
8
|
+
"Set V#{x} = delay timer value."
|
9
|
+
when '0a'
|
10
|
+
"Wait key press, store its value in V#{x}."
|
11
|
+
when '15'
|
12
|
+
"Set delay timer = V#{x}."
|
13
|
+
when '18'
|
14
|
+
"Set sound timer = V#{x}."
|
15
|
+
when '1e'
|
16
|
+
"Set I = I + V#{x}."
|
17
|
+
when '29'
|
18
|
+
"Set I = location of sprite for digit V#{x}."
|
19
|
+
when '33'
|
20
|
+
"Store BCD of V#{x} at I, I+1, and I+2."
|
21
|
+
when '55'
|
22
|
+
"Store registers V0..V#{x} starting at I."
|
23
|
+
when '65'
|
24
|
+
"Load registers V0..V#{x} starting from I."
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module C8dasm
|
2
|
+
|
3
|
+
# Represents an opcode, in the sense of a disassembly file.
|
4
|
+
#
|
5
|
+
# Examples
|
6
|
+
#
|
7
|
+
# o = Opcode.new('a21e')
|
8
|
+
# o.line #=> '200:a21e LD I, 21e ;Puts 21e into register I.'
|
9
|
+
#
|
10
|
+
# o.opcode #=> 'a21e'
|
11
|
+
# o.assembly #=> 'LD I, 21e'
|
12
|
+
# o.comment #=> 'Puts 21e into register I.'
|
13
|
+
# o.address #=> '200'
|
14
|
+
class Opcode
|
15
|
+
|
16
|
+
# Creates a new Opcode instance.
|
17
|
+
#
|
18
|
+
# opcode - The String opcode to represents.
|
19
|
+
# address - The Fixnum address of this opcode. Default is 0x200.
|
20
|
+
def initialize(opcode, address: 0x200)
|
21
|
+
@assembly = Assembly.new(opcode).to_s
|
22
|
+
@opcode = opcode
|
23
|
+
@comment = Comment.new(opcode).to_s
|
24
|
+
@address = sprintf("%03x", address)
|
25
|
+
@line = "#@address:#@opcode " +
|
26
|
+
sprintf("%-14s", @assembly) +
|
27
|
+
";#@comment"
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_reader :opcode, :assembly, :comment, :address, :line
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|