z80_disassembler 0.3.1 → 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
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: