z80_disassembler 0.2.2 → 0.2.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6d345233ff0d5429ba5c05cdb82c304de2ef46b6ebe7761bda8b805c986c85e2
4
- data.tar.gz: e43f8bf8fd592ec156d5bb6c942e6847691e853701a65e2b0afdaffd827c626e
3
+ metadata.gz: 7fda0599a6e835b5063fc6115dcdc364cfc895b2a7cbf1dba8f57965698526a5
4
+ data.tar.gz: 705361c3aa8d088e967411643e9774a1d1cbc169a9e7ce57d8ffa8087a833f68
5
5
  SHA512:
6
- metadata.gz: 991885755e9d4fbe5128b6b81fdb5e4804d6921850acbf9e07bc8c0c66fb290d293ea32be1fc56c1a9da06d55a64d4100b2558f488999812ba832d9a8ab2434c
7
- data.tar.gz: db4bdd7cb73f1ba8bdf430c54578f02f1a74ca5de3373bf2b1e4dda855b400652fa0604ca6e1e7cd1b3b0a228f0f4aa79ffb22e9d1d4116c6a0663d625c73bc7
6
+ metadata.gz: 6b2b887c58d4bf48e32094f9753e71520ff3b1c12d7d7ab46870c0179628005b3e13be8c191c0fd305e78004c3b2b630833536fceb77ff49f004ed19cb17b59e
7
+ data.tar.gz: cfd8680fc373ed1031ffd89af3ad8ff7c1cdb67f6fa5e5aa53f15b9f1d4e172c7c5983f14d62914f2baa3e0d49249472f744cb851b69770c546205e51f3c4b5e
data/README.md CHANGED
@@ -28,8 +28,8 @@ Or install it yourself as:
28
28
  - example: parse.C >> parse.C.txt and compare with parse.txt
29
29
  ```ruby
30
30
  z = Z80Disassembler::Disassembler.new(params[:file], 32768)
31
- z.start # return [25114, "#621A", "LD IX,#6300", "DD 21 00 63", " ! c"
32
- z.text # return asm text " LD IX,link_1 ; #621A / 25114 ; DD 21 00 63 ; ! c ;"
31
+ z.start # return [ [25114, "#621A", "LD IX,#6300", "DD 21 00 63", " ! c"], [...], ... ]
32
+ z.text # return " LD IX,link_1 ; #621A / 25114 ; DD 21 00 63 ; ! c ;\n"
33
33
  ```
34
34
  ## Development
35
35
 
@@ -6,6 +6,8 @@ module Z80Disassembler
6
6
  class Error < StandardError; end
7
7
 
8
8
  class Disassembler
9
+ attr_reader :org
10
+
9
11
  # 0 1 2 3 4 5 6 7
10
12
  T_R = [ 'B', 'C', 'D', 'E', 'H', 'L', '(HL)', 'A'].freeze
11
13
  T_CC = [ 'NZ', 'Z', 'NC', 'C', 'PO', 'PE', 'P', 'M'].freeze
@@ -14,7 +16,6 @@ module Z80Disassembler
14
16
  T_IM = [ '0', '0/1', '1', '2', '0', '0/1', '1', '2'].freeze
15
17
  T_RP = [ 'BC', 'DE', 'HL', 'SP'].freeze
16
18
  T_RP2 = [ 'BC', 'DE', 'HL', 'AF'].freeze
17
-
18
19
  ASCII = [
19
20
  ' ', '!', '"', '#', '$', '%', '&', "'", '(', ')', '*', '+', ',', '-', '.', '/',
20
21
  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
@@ -24,52 +25,83 @@ module Z80Disassembler
24
25
  'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~'
25
26
  ].freeze
26
27
 
27
- def initialize(file_name, addr = 32_768)
28
- @file_name = file_name; @addr = addr.to_i
28
+ def initialize(file, org = 32_768)
29
+ @file = file; @org = org.to_i
30
+ if file.original_filename[-3..-1] == '.$C'
31
+ File.open(@file) do |f|
32
+ z = f.read(17)
33
+ @file_name = "#{z[0..7]}.#{z[8]}"
34
+ @org = bytes_to_int(z[ 9..10])
35
+ @file_size = bytes_to_int(z[11..12])
36
+ @sectors = bytes_to_int(z[13..14])
37
+ checksum1 = bytes_to_int(z[15..16])
38
+ checksum2 = (z[0..14].sum * 257 + 105).to_s(16)[-4..-1].hex
39
+ @code = f.read(@file_size).bytes if checksum1 == checksum2
40
+ end
41
+ end
42
+ @code ||= File.open(@file).read.bytes
43
+ @file_size ||= @file.size
29
44
  @x = 0; @y = 0; @z = 0; @p = 0; @q = 0; @xx = nil
30
- @lambda = nil; @prefix = nil; @prev = nil
31
- @bytes = []; @ascii = []; @result = []
45
+ @lambda = nil; @prefix = nil; @prev = nil; @result = []
32
46
  end
33
47
 
34
48
  def start
35
- File.open(@file_name).each_byte do |byte|
49
+ addr = @org
50
+ bytes = []; ascii = []
51
+ @code.each do |byte|
36
52
  load_vars(byte)
37
53
  str = command_from_byte(byte)
38
54
  @prev = byte.to_s(16)
39
- @ascii << ((32..126).include?(byte) ? ASCII[byte - 32] : ' ')
40
- @bytes << @prev.rjust(2, '0').upcase
55
+ ascii << ((32..126).include?(byte) ? ASCII[byte - 32] : ' ')
56
+ bytes << @prev.rjust(2, '0').upcase
41
57
  next unless str
42
58
 
43
- @result << [@addr, "##{@addr.to_s(16)}".upcase, str, @bytes.join(' '), @ascii.join]
44
- @addr += @bytes.size
45
- @bytes = []
46
- @ascii = []
59
+ @result << [addr, "##{addr.to_s(16)}".upcase, str, bytes.join(' '), ascii.join]
60
+ addr += bytes.size
61
+ bytes = []
62
+ ascii = []
47
63
  end
48
64
  @result
49
65
  end
50
66
 
51
67
  def text
52
- org = @addr - @file_name.size
53
68
  hash_links = {}
69
+ del_links = []
54
70
  link_num = 0
55
- int_addrs = org..@addr
71
+ int_addrs = @org..(@org + @file_size)
56
72
  with_links = @result.select { |z| z[2] =~ /#[0-F]{4}/ && int_addrs.include?(z[2].split('#').last[0..3].hex) }
57
- with_links.each { |x| hash_links["##{x[2].split('#').last[0..3]}"] = "link_#{link_num += 1}" }
73
+ with_links.each do |x|
74
+ z = "##{x[2].split('#').last[0..3]}"
75
+ hash_links[z] = "link_#{link_num += 1}" unless hash_links[z]
76
+ end
77
+
78
+ code = @result.map do |addr, addr16, str, bytes, ascii|
79
+ del_links << hash_links[addr16] if hash_links[addr16]
80
+ link = (hash_links[addr16] || '').ljust(16, ' ')
81
+ adr = '#' + str.split('#').last[0..3]
82
+ string = hash_links.keys.include?(adr) ? str.sub(adr, hash_links[adr]) : str
83
+ "#{link} #{string.ljust(16, ' ')}; #{addr16.ljust(5, ' ')} / #{addr.to_s.ljust(5, ' ')} ; #{bytes.ljust(14, ' ')} ; #{ascii.ljust(4, ' ')} ;"
84
+ end.join("\n")
85
+
58
86
  [
59
- " device zxspectrum48",
60
- " ORG #{org}",
61
- "begin_file:\n"
62
- ].join("\n") +
63
- @result.map do |addr, addr16, str, bytes, ascii|
64
- link = (hash_links[addr16] || '').ljust(16, ' ')
65
- adr = '#' + str.split('#').last[0..3]
66
- string = hash_links.keys.include?(adr) ? str.sub(adr, hash_links[adr]) : str
67
- "#{link} #{string.ljust(16, ' ')}; #{addr16.ljust(5, ' ')} / #{addr.to_s.ljust(5, ' ')} ; #{bytes.ljust(14, ' ')} ; #{ascii.ljust(4, ' ')} ;"
68
- end.join("\n")
87
+ ' device zxspectrum48',
88
+ ' ORG #' + @org.to_s(16),
89
+ hash_links.map { |key, val| "#{val.ljust(16, ' ')} equ #{key}" unless del_links.include?(val) }.compact.join("\n"),
90
+ 'begin:',
91
+ code,
92
+ 'end:',
93
+ ' savesna "disasm.sna", begin',
94
+ ' savebin "disasm.C", begin, end - begin',
95
+ ''
96
+ ].join("\n")
69
97
  end
70
98
 
71
99
  private
72
100
 
101
+ def bytes_to_int(array)
102
+ array.bytes.reverse.map { |x| x.to_s(16).rjust(2, "0") }.join.hex
103
+ end
104
+
73
105
  def command_from_byte(byte)
74
106
  case @prefix
75
107
  when 'cb' then @prefix = nil; cb_prefix
@@ -88,6 +120,11 @@ module Z80Disassembler
88
120
  end
89
121
  resp = hl_to_xx(resp, @xx) unless @xx.nil?
90
122
  @xx = nil
123
+ if resp.include?('JR') || resp.include?('DJNZ')
124
+ z = resp.split('#')
125
+ z[1] = z[1].hex < 127 ? "$+#{z[1].hex}" : "$-#{255 - z[1].hex}"
126
+ resp = z.join
127
+ end
91
128
  resp
92
129
  else command
93
130
  end
@@ -133,8 +170,8 @@ module Z80Disassembler
133
170
  case @y
134
171
  when 0 then 'NOP'
135
172
  when 1 then 'EX AF, AF\''
136
- when 2 then calc_bytes(->(a, b){ "DJNZ ##{b}" }, nil, 1)
137
- when 3 then calc_bytes(->(a, b){ "JR ##{b}" }, nil, 1)
173
+ when 2 then calc_bytes(->(a, b){ "DJNZ ##{b}" }, nil, 1)
174
+ when 3 then calc_bytes(->(a, b){ "JR ##{b}" }, nil, 1)
138
175
  else calc_bytes(->(a, b){ "JR #{a},##{b}" }, T_CC[@y - 4], 1)
139
176
  end
140
177
  when 1 then @q ? "ADD HL,#{T_RP[@p]}" : calc_bytes(->(a, b){ "LD #{a},##{b}" }, T_RP[@p], 2)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Z80Disassembler
4
- VERSION = '0.2.2'
4
+ VERSION = '0.2.3'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: z80_disassembler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - dvitvitskiy
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-06-06 00:00:00.000000000 Z
11
+ date: 2021-06-07 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: