z80_disassembler 0.3.1 → 0.3.6

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: 02a2e2d32e438dfeec508dbb3d7c2d9346144a401398a5d1d512352c59750b89
4
- data.tar.gz: 6b502bcf23a6d7fcb77468b18be19bc8bcd679a8382896d9468afee8a21b3b11
3
+ metadata.gz: 5823cf66cb0d52c7313ddb8659a0bda9b44c06569feaea6043af3b5481ca8025
4
+ data.tar.gz: 291863116b95b7397b901bb17ff66a15ab2ca2b0ac8148ad92cae57acf1ce7ba
5
5
  SHA512:
6
- metadata.gz: 07a73a8a7504f85f2c91e952d249a4521e16e567b45387f011d0821d24d941aaa7faa1f1e3eedac1a621e234e139cb6feef413ebd548bf7ca0b9526bae24ee83
7
- data.tar.gz: 482d90cf0c3e6b5938e9323319c086e93435178bbcd3c4c38be33b0871b932a8b99e016dce7546253be39be99a3a36d216ab8e14635488df046f7c01dc2a2816
6
+ metadata.gz: c15db9eb11f397f32d2fa27b86370baae9d3ec1726a73d5d472fd5b56c33e9dc85b3fbb5e5182ee38a254e981a60d767517c847f69fc75a9a374213f46891c93
7
+ data.tar.gz: 7a1ea4f6b42f360eac3e7ba9b6492b9857597bcbc92bbda9b392cf74979e27afbda9e1f0a6ff543e1c064bc627de5d0ed41fda750da5d29a1ac4a8d8269d8c8b
data/README.md CHANGED
@@ -20,16 +20,20 @@ Or install it yourself as:
20
20
 
21
21
  ## Usage
22
22
 
23
- - prepare: parse.asm >> parse.C
24
- ```bash
25
- sjasmplus parse.asm
26
- ```
23
+ * Example: zxn.ru/disasm - DEMO button
27
24
 
28
- - example: parse.C >> parse.C.txt and compare with parse.txt
29
25
  ```ruby
30
26
  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 " LD IX,link_1 ; #621A / 25114 ; DD 21 00 63 ; ! c ;\n"
27
+ text = z.start
28
+ z.file_size
29
+ z.org
30
+ file_name = 'tmp/disasm'
31
+ file = Tempfile.new(file_name)
32
+ file.write(text)
33
+ file.write(Z80Disassembler::Disassembler.compile_text(file_name))
34
+ file.close
35
+ compiled = system "sjasmplus --nologo #{file.path} 2> #{file_name}.log"
36
+ logs = File.open("#{file_name}.log").read.split("\n")
33
37
  ```
34
38
  ## Development
35
39
 
@@ -6,7 +6,7 @@ module Z80Disassembler
6
6
  class Error < StandardError; end
7
7
 
8
8
  class Disassembler
9
- attr_reader :org, :file_size
9
+ attr_reader :org, :file_size, :rmda
10
10
 
11
11
  # 0 1 2 3 4 5 6 7
12
12
  T_R = [ 'B', 'C', 'D', 'E', 'H', 'L', '(HL)', 'A'].freeze
@@ -42,10 +42,22 @@ module Z80Disassembler
42
42
  @code ||= File.open(@file).read.bytes
43
43
  @file_size ||= @file.size
44
44
  @x = 0; @y = 0; @z = 0; @p = 0; @q = 0; @xx = nil
45
- @lambda = nil; @prefix = nil; @prev = nil; @result = []
45
+ @lambda = nil; @prefix = nil; @prev = nil
46
+ @hash_links = {}; @del_links = []
47
+ @rmda = """
48
+ ;--- #{Date.today} --- https://rmda.su
49
+ ; _______ _/| __ ______ ____
50
+ ; / __ // |/ \\\\ _ \\ / \\
51
+ ; / _/ _// \\\\ \\\\ \\\\ \\ \\
52
+ ; \\___\\ \\\\___\\/___//______//__/\\__\\
53
+ ; \\__/
54
+ ;--- size: #{@file_size}b #{"--- filename: #{@file_name}" if @file_name}
55
+
56
+ """
46
57
  end
47
58
 
48
59
  def start
60
+ result = []
49
61
  addr = @org
50
62
  bytes = []; ascii = []
51
63
  @code.each do |byte|
@@ -56,58 +68,51 @@ module Z80Disassembler
56
68
  bytes << @prev.rjust(2, '0').upcase
57
69
  next unless str
58
70
 
59
- @result << [addr, "##{addr.to_s(16)}".upcase, str, bytes.join(' '), ascii.join]
71
+ result << [addr, "##{addr.to_s(16)}".upcase, str, bytes.join(' '), ascii.join]
60
72
  addr += bytes.size
61
73
  bytes = []
62
74
  ascii = []
63
75
  end
64
- @result
65
- end
66
76
 
67
- def text
68
- hash_links = {}
69
- del_links = []
70
77
  link_num = 0
71
78
  int_addrs = @org..(@org + @file_size)
72
- @result.select { |z| z[2] =~ /#[0-F]{4}/ && int_addrs.include?(z[2].split('#').last[0..3].hex) }.each do |x|
79
+ result.select { |z| z[2] =~ /#[0-F]{4}/ && int_addrs.include?(z[2].split('#').last[0..3].hex) }.each do |x|
73
80
  z = "##{x[2].split('#').last[0..3]}"
74
- hash_links[z] = "link_#{link_num += 1}" unless hash_links[z]
81
+ @hash_links[z] = "link_#{link_num += 1}" unless @hash_links[z]
75
82
  end
76
- @result.select { |z| z[2] =~ /\$/ }.each do |x|
83
+ result.select { |z| z[2] =~ /\$/ }.each do |x|
77
84
  z = "##{ (x[0] + x[2].split('$').last.to_i).to_s(16).upcase }"
78
- hash_links[z] = "link_#{link_num += 1}" unless hash_links[z]
85
+ @hash_links[z] = "link_#{link_num += 1}" unless @hash_links[z]
79
86
  end
80
- code = @result.map do |addr, addr16, str, bytes, ascii|
81
- del_links << hash_links[addr16] if hash_links[addr16]
82
- link = (hash_links[addr16] ? (hash_links[addr16] + ':') : '').ljust(16, ' ')
87
+ code = result.map do |addr_, addr16, str, bytes_, ascii_|
88
+ @del_links << @hash_links[addr16] if @hash_links[addr16]
89
+ link = (@hash_links[addr16] ? (@hash_links[addr16] + ':') : '').ljust(16, ' ')
83
90
  substr, adr = if str.include?('$')
84
- ["$#{str.split('$').last}", "##{(addr + str.split('$').last.to_i).to_s(16).upcase}"]
91
+ ["$#{str.split('$').last}", "##{(addr_ + str.split('$').last.to_i).to_s(16).upcase}"]
85
92
  else
86
93
  adr = "##{str.split('#').last[0..3]}"
87
94
  [adr, adr]
88
95
  end
89
- string = hash_links.keys.include?(adr) ? str.sub(substr, hash_links[adr]) : str
96
+ string = @hash_links.keys.include?(adr) ? str.sub(substr, @hash_links[adr]) : str
90
97
 
91
- "#{link} #{string.ljust(16, ' ')}; #{addr16.ljust(5, ' ')} / #{addr.to_s.ljust(5, ' ')} ; #{bytes.ljust(14, ' ')} ; #{ascii.ljust(4, ' ')} ;"
98
+ defb = bytes_.split(" ").map { |x| "##{x}"}.join(",")
99
+ "#{link} #{string.ljust(16, ' ')}; #{addr16.ljust(5, ' ')} / #{addr_.to_s.ljust(5, ' ')} ; #{ascii_.ljust(4, ' ')} ; #{defb}"
92
100
  end.join("\n")
101
+ [
102
+ @rmda,
103
+ ' device zxspectrum128',
104
+ ' ORG #' + @org.to_s(16),
105
+ @hash_links.map { |key, val| "#{(val + ':').ljust(16, ' ')} EQU #{key}" unless @del_links.include?(val) }.compact.join("\n"),
106
+ 'begin:',
107
+ code,
108
+ 'end:',
109
+ ''
110
+ ].join("\n")
111
+ end
93
112
 
94
- header = [
95
- ";--- #{Date.today} --- https://rmda.su ",
96
- '; _______ _/| __ ______ ____ ',
97
- '; / __ // |/ \\\\ _ \ / \ ',
98
- '; / _/ _// \\\\ \\\\ \\\\ \ \ ',
99
- '; \___\ \\\\___\/___//______//__/\__\ ',
100
- '; \__/ ',
101
- ";--- size: #{@file_size} --- filename: #{@file_name} "
102
- ]
113
+ def self.compile_text(file_name)
114
+ name = file_name.split('/').last
103
115
  [
104
- *header,
105
- ' device zxspectrum48',
106
- ' ORG #' + @org.to_s(16),
107
- hash_links.map { |key, val| "#{val.ljust(16, ' ')} equ #{key}" unless del_links.include?(val) }.compact.join("\n"),
108
- 'begin:',
109
- code,
110
- 'end:',
111
116
  'length equ end - begin',
112
117
  'CODE = #AF',
113
118
  'USR = #C0',
@@ -115,29 +120,28 @@ module Z80Disassembler
115
120
  'CLEAR = #FD',
116
121
  'RANDOMIZE = #F9',
117
122
  ' org #5C00',
118
- 'baszac db 0, 1', # Line number
119
- ' dw linlen', # Line length
120
- 'linzac',
121
- ' db CLEAR, "8", #0E, 0, 0',
123
+ 'baszac db 0,1', # Line number
124
+ ' dw linlen', # Line length
125
+ 'linzac db CLEAR, "8", #0E, 0, 0',
122
126
  ' dw begin - 1',
123
127
  ' db 0, ":"',
124
128
  ' db LOAD, "\""',
125
- 'codnam ds 10, 32',
129
+ 'codnam ds 10, 32',
126
130
  ' org codnam',
127
131
  ' db "disasm"',
128
132
  ' org codnam + 10',
129
133
  ' db "\"", CODE, ":"',
130
134
  ' db RANDOMIZE, USR, "8", #0E, 0, 0',
131
- ' dw begin', # call address
135
+ ' dw begin', # call address
132
136
  ' db 0, #0D',
133
137
  'linlen = $ - linzac',
134
138
  'baslen = $ - baszac',
135
- ' emptytap "disasm.tap"',
136
- ' savetap "disasm.tap", BASIC, "disasm", baszac, baslen, 1',
137
- ' savetap "disasm.tap", CODE, "disasm", begin, length, begin',
138
- ' savesna "disasm.sna", begin',
139
- ' savebin "disasm.C", begin, length',
140
- ' savehob "disasm.$C", "disasm.C", begin, length',
139
+ " emptytap '#{file_name}.tap'",
140
+ " savetap '#{file_name}.tap', BASIC, '#{name}', baszac, baslen, 1",
141
+ " savetap '#{file_name}.tap', CODE, '#{name}', begin, length, begin",
142
+ " savesna '#{file_name}.sna', begin",
143
+ " savebin '#{file_name}.bin', begin, length",
144
+ " savehob '#{file_name}.$C', '#{file_name}.bin', begin, length",
141
145
  ''
142
146
  ].join("\n")
143
147
  end
@@ -145,13 +149,13 @@ module Z80Disassembler
145
149
  private
146
150
 
147
151
  def bytes_to_int(array)
148
- array.bytes.reverse.map { |x| x.to_s(16).rjust(2, "0") }.join.hex
152
+ array.bytes.reverse.map { |x| x.to_s(16).rjust(2, '0') }.join.hex
149
153
  end
150
154
 
151
155
  def command_from_byte(byte)
152
156
  case @prefix
153
157
  when 'cb' then @prefix = nil; cb_prefix
154
- when 'ed' then @prefix = nil; ed_prefix
158
+ when 'ed' then @prefix = nil; ed_prefix(byte)
155
159
  when 'dd' then @xx = 'IX'; xx_prefix(byte)
156
160
  when 'fd' then @xx = 'IY'; xx_prefix(byte)
157
161
  when 'xx' then temp = @temp; @temp = nil; displacement(byte, temp)
@@ -167,7 +171,7 @@ module Z80Disassembler
167
171
  elsif temp
168
172
  resp += temp
169
173
  end
170
- resp = hl_to_xx(resp, @xx) unless @xx.nil?
174
+ resp = hl_to_xx(resp) unless @xx.nil?
171
175
  if resp.include?('JR') || resp.include?('DJNZ')
172
176
  z = resp.split('#')
173
177
  z[1] = z[1].hex < 127 ? "$+#{z[1].hex + 2}" : "$-#{255 - z[1].hex - 1}"
@@ -178,21 +182,22 @@ module Z80Disassembler
178
182
  end
179
183
  end
180
184
 
181
- def hl_to_xx(temp, reg)
182
- @xx = nil
183
- if temp.include?('HL')
184
- temp.sub('HL', reg)
185
+ def hl_to_xx(temp)
186
+ resp = if temp.include?('HL')
187
+ temp.sub('HL', @xx)
185
188
  elsif temp.include?(' L')
186
- temp.sub(' L', " #{reg}L")
189
+ temp.sub(' L', " #{@xx}L")
187
190
  elsif temp.include?(',L')
188
- temp.sub(',L', ",#{reg}L")
191
+ temp.sub(',L', ",#{@xx}L")
189
192
  elsif temp.include?(' H')
190
- temp.sub(' H', " #{reg}H")
193
+ temp.sub(' H', " #{@xx}H")
191
194
  elsif temp.include?(',H')
192
- temp.sub(',H', ",#{reg}H")
195
+ temp.sub(',H', ",#{@xx}H")
193
196
  else
194
- temp
197
+ @xx ? "DB ##{@xx == 'IX' ? 'DD' : 'FD'} ;\n#{''.ljust(16, ' ')} #{temp.ljust(16, ' ')}" : temp
195
198
  end
199
+ @xx = nil
200
+ resp
196
201
  end
197
202
 
198
203
  def displacement(byte, temp)
@@ -284,7 +289,7 @@ module Z80Disassembler
284
289
  @prefix = 'xx'; nil
285
290
  elsif ['dd', 'fd'].include?(@prev) && @temp
286
291
  temp = @temp; @temp = nil; @prefix = nil
287
- hl_to_xx(temp, @xx)
292
+ hl_to_xx(temp)
288
293
  elsif @lambda && !@arg&.include?('HL')
289
294
  @prefix = 1; @temp
290
295
  else
@@ -296,7 +301,7 @@ module Z80Disassembler
296
301
  ["#{T_ROT[@y]} ", "BIT #{@y},", "RES #{@y},", "SET #{@y},"][@x] + T_R[@z]
297
302
  end
298
303
 
299
- def ed_prefix
304
+ def ed_prefix(byte)
300
305
  if @x == 1
301
306
  case @z
302
307
  when 0 then "IN #{"#{T_R[@y]}," if @y != 6}(C)"
@@ -311,7 +316,7 @@ module Z80Disassembler
311
316
  elsif @x == 2 && @z <= 3 && @y >= 4
312
317
  [['LDI','CPI','INI','OUTI'],['LDD','CPD','IND','OUTD'],['LDIR','CPIR','INIR','OTIR'],['LDDR','CPDR','INDR','OTDR']][@y - 4][@z]
313
318
  else
314
- 'NOP'
319
+ "#{'DB #ED'}, ##{byte.to_s(16).rjust(2, '0').upcase}"
315
320
  end
316
321
  end
317
322
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Z80Disassembler
4
- VERSION = '0.3.1'
4
+ VERSION = '0.3.6'
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.3.1
4
+ version: 0.3.6
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-17 00:00:00.000000000 Z
11
+ date: 2021-07-12 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: