c8dasm 0.99.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +3 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +15 -0
  7. data/README.md +109 -0
  8. data/Rakefile +7 -0
  9. data/bin/c8dasm +13 -0
  10. data/c8dasm.gemspec +24 -0
  11. data/lib/c8dasm.rb +11 -0
  12. data/lib/c8dasm/assemblies.rb +18 -0
  13. data/lib/c8dasm/assemblies/asm0.rb +15 -0
  14. data/lib/c8dasm/assemblies/asm1.rb +10 -0
  15. data/lib/c8dasm/assemblies/asm2.rb +10 -0
  16. data/lib/c8dasm/assemblies/asm3.rb +10 -0
  17. data/lib/c8dasm/assemblies/asm4.rb +9 -0
  18. data/lib/c8dasm/assemblies/asm5.rb +12 -0
  19. data/lib/c8dasm/assemblies/asm6.rb +9 -0
  20. data/lib/c8dasm/assemblies/asm7.rb +9 -0
  21. data/lib/c8dasm/assemblies/asm8.rb +23 -0
  22. data/lib/c8dasm/assemblies/asm9.rb +11 -0
  23. data/lib/c8dasm/assemblies/asm_base.rb +26 -0
  24. data/lib/c8dasm/assemblies/asma.rb +11 -0
  25. data/lib/c8dasm/assemblies/asmb.rb +12 -0
  26. data/lib/c8dasm/assemblies/asmc.rb +11 -0
  27. data/lib/c8dasm/assemblies/asmd.rb +11 -0
  28. data/lib/c8dasm/assemblies/asme.rb +16 -0
  29. data/lib/c8dasm/assemblies/asmf.rb +20 -0
  30. data/lib/c8dasm/assembly.rb +22 -0
  31. data/lib/c8dasm/chip8_reader.rb +38 -0
  32. data/lib/c8dasm/comment.rb +23 -0
  33. data/lib/c8dasm/comments.rb +17 -0
  34. data/lib/c8dasm/comments/comment0.rb +14 -0
  35. data/lib/c8dasm/comments/comment1.rb +10 -0
  36. data/lib/c8dasm/comments/comment2.rb +11 -0
  37. data/lib/c8dasm/comments/comment3.rb +11 -0
  38. data/lib/c8dasm/comments/comment4.rb +11 -0
  39. data/lib/c8dasm/comments/comment5.rb +12 -0
  40. data/lib/c8dasm/comments/comment6.rb +11 -0
  41. data/lib/c8dasm/comments/comment7.rb +11 -0
  42. data/lib/c8dasm/comments/comment8.rb +25 -0
  43. data/lib/c8dasm/comments/comment9.rb +11 -0
  44. data/lib/c8dasm/comments/comment_base.rb +26 -0
  45. data/lib/c8dasm/comments/commenta.rb +11 -0
  46. data/lib/c8dasm/comments/commentb.rb +12 -0
  47. data/lib/c8dasm/comments/commentc.rb +11 -0
  48. data/lib/c8dasm/comments/commentd.rb +11 -0
  49. data/lib/c8dasm/comments/commente.rb +15 -0
  50. data/lib/c8dasm/comments/commentf.rb +30 -0
  51. data/lib/c8dasm/opcode.rb +34 -0
  52. data/lib/c8dasm/version.rb +3 -0
  53. data/spec/15-puzzle.ch8 +0 -0
  54. data/spec/MAZE +0 -0
  55. data/spec/c8dasm_spec.rb +7 -0
  56. data/spec/chip8_reader_spec.rb +27 -0
  57. data/spec/opcode_0_spec.rb +39 -0
  58. data/spec/opcode_1_spec.rb +23 -0
  59. data/spec/opcode_2_spec.rb +23 -0
  60. data/spec/opcode_3_spec.rb +23 -0
  61. data/spec/opcode_4_spec.rb +23 -0
  62. data/spec/opcode_5_spec.rb +25 -0
  63. data/spec/opcode_6_spec.rb +23 -0
  64. data/spec/opcode_7_spec.rb +23 -0
  65. data/spec/opcode_8_spec.rb +119 -0
  66. data/spec/opcode_9_spec.rb +24 -0
  67. data/spec/opcode_a_spec.rb +23 -0
  68. data/spec/opcode_b_spec.rb +24 -0
  69. data/spec/opcode_c_spec.rb +23 -0
  70. data/spec/opcode_d_spec.rb +23 -0
  71. data/spec/opcode_e_spec.rb +39 -0
  72. data/spec/opcode_f_spec.rb +151 -0
  73. data/spec/opcode_spec.rb +45 -0
  74. data/spec/spec_helper.rb +2 -0
  75. metadata +183 -0
@@ -0,0 +1,11 @@
1
+ module C8dasm
2
+
3
+ class Asmd < AsmBase
4
+
5
+ def to_s
6
+ "DRW V#{x}, V#{y}, #{@opcode[3]}"
7
+ end
8
+
9
+ end
10
+ end
11
+
@@ -0,0 +1,16 @@
1
+ module C8dasm
2
+
3
+ class Asme < AsmBase
4
+
5
+ def to_s
6
+ if kk == 'a1'
7
+ "SKNP V#{x}"
8
+ elsif kk == '9e'
9
+ "SKP V#{x}"
10
+ end
11
+ end
12
+
13
+ end
14
+ end
15
+
16
+
@@ -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,14 @@
1
+ module C8dasm
2
+
3
+ class Comment0 < CommentBase
4
+
5
+ def to_s
6
+ if @opcode == '00ee'
7
+ "Returns from this subroutine."
8
+ elsif @opcode == '00e0'
9
+ "Clear the display."
10
+ end
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,10 @@
1
+ module C8dasm
2
+
3
+ class Comment1 < CommentBase
4
+
5
+ def to_s
6
+ "Jump to location #{nnn}."
7
+ end
8
+
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ module C8dasm
2
+
3
+ class Comment2 < CommentBase
4
+
5
+ def to_s
6
+ "Call subroutine at #{nnn}."
7
+ end
8
+
9
+ end
10
+ end
11
+
@@ -0,0 +1,11 @@
1
+ module C8dasm
2
+
3
+ class Comment3 < CommentBase
4
+
5
+ def to_s
6
+ "Skip next instruction if V#{x} = #{kk}."
7
+ end
8
+
9
+ end
10
+ end
11
+
@@ -0,0 +1,11 @@
1
+ module C8dasm
2
+
3
+ class Comment4 < CommentBase
4
+
5
+ def to_s
6
+ "Skip next instruction if V#{x} != #{kk}."
7
+ end
8
+
9
+ end
10
+ end
11
+
@@ -0,0 +1,12 @@
1
+ module C8dasm
2
+
3
+ class Comment5 < CommentBase
4
+
5
+ def to_s
6
+ "Skip next instruction if V#{x} = V#{y}."
7
+ end
8
+
9
+ end
10
+
11
+ end
12
+
@@ -0,0 +1,11 @@
1
+ module C8dasm
2
+
3
+ class Comment6 < CommentBase
4
+
5
+ def to_s
6
+ "Puts the value #{kk} into register V#{x}."
7
+ end
8
+
9
+ end
10
+ end
11
+
@@ -0,0 +1,11 @@
1
+ module C8dasm
2
+
3
+ class Comment7 < CommentBase
4
+
5
+ def to_s
6
+ "V#{x} = V#{x} + #{kk}."
7
+ end
8
+
9
+ end
10
+ end
11
+
@@ -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,11 @@
1
+ module C8dasm
2
+
3
+ class Comment9 < CommentBase
4
+
5
+ def to_s
6
+ "Skip next instruction if V#{x} != V#{y}."
7
+ end
8
+
9
+ end
10
+
11
+ 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,11 @@
1
+ module C8dasm
2
+
3
+ class Commenta < CommentBase
4
+
5
+ def to_s
6
+ "Puts #{nnn} into register I."
7
+ end
8
+
9
+ end
10
+ end
11
+
@@ -0,0 +1,12 @@
1
+ module C8dasm
2
+
3
+ class Commentb < CommentBase
4
+
5
+ def to_s
6
+ "Jump to location #{nnn} + V0."
7
+ end
8
+
9
+ end
10
+
11
+ end
12
+
@@ -0,0 +1,11 @@
1
+ module C8dasm
2
+
3
+ class Commentc < CommentBase
4
+
5
+ def to_s
6
+ "Puts random byte AND #{kk} into register V#{x}."
7
+ end
8
+
9
+ end
10
+ end
11
+
@@ -0,0 +1,11 @@
1
+ module C8dasm
2
+
3
+ class Commentd < CommentBase
4
+
5
+ def to_s
6
+ "Draws #{@opcode[3]}-byte sprite from I at (V#{x}, V#{y})"
7
+ end
8
+
9
+ end
10
+ end
11
+
@@ -0,0 +1,15 @@
1
+ module C8dasm
2
+
3
+ class Commente < CommentBase
4
+
5
+ def to_s
6
+ if kk == 'a1'
7
+ "Skip next inst. if V#{x} key is not pressed."
8
+ elsif kk == '9e'
9
+ "Skip next inst. if V#{x} key is pressed."
10
+ end
11
+ end
12
+
13
+ end
14
+ end
15
+
@@ -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