c8dasm 0.99.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.
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