champ/parse.rb

125 lines
3.9 KiB
Ruby
Executable File

#!/usr/bin/env ruby
require 'yaml'
label_for_address = {}
symbols = []
watches = []
arg_watches = []
File::open('plot3d20_Output.txt') do |f|
f.each_line do |line|
parts = line.split('|')
next unless parts.size == 8
address = parts[6].split(' ').first.split('/')[1]
symbol = parts[7]
symbol = symbol[1, symbol.size - 1]
next if symbol[0] == '*'
next if symbol[0] == ';'
next if symbol[0] == ' '
if symbol =~ /^\w+\s+EQU\s+\$([0-9A-F]{2,4})/
address = $1
end
watch_this = symbol.match(/~(u8|s8|u16|s16)/)
watch_args = symbol.scan(/(@(u8|s8|u16|s16)[AXY])/).map { |x| x.first }
symbol = symbol.strip.split(' ').first
next if address.nil?
label_for_address[address.to_i(16)] = symbol
symbols << symbol
if watch_this
watches << {
:address => address.to_i(16),
:label => symbol,
:type => watch_this[1]
}
end
watch_args.each do |watch_arg|
arg_watches << {:register => watch_arg[watch_arg.size - 1],
:type => watch_arg.sub('@', '')[0, watch_arg.size - 2],
:address => address.to_i(16)}
end
end
end
symbols.uniq!
symbols.sort! { |a, b| a.downcase <=> b.downcase }
File::open('labels.h', 'w') do |f|
f.puts "const uint16_t LABEL_COUNT = #{symbols.size};"
f.puts "const char* LABELS[] = {";
line_length = 0
f.print ' '
symbols.each.with_index do |symbol, _|
part = "\"#{symbol}\""
if _ < symbols.size - 1
part += ', '
end
f.print part
line_length += part.size
if line_length > 60
f.puts
f.print ' '
line_length = 0
end
end
f.puts "};"
f.puts "const int16_t label_for_address[] = {"
f.print ' '
(0..0xffff).each do |address|
value = -1
if label_for_address.include?(address)
value = symbols.index(label_for_address[address]);
end
f.print "#{value}, "
if (address + 1) % 16 == 0
f.puts
f.print ' '
end
end
f.puts "};";
end
File::open('watches.h', 'w') do |f|
f.puts "const uint16_t WATCH_COUNT = #{watches.size};"
types = ['u8', 'u16', 's8', 's16'];
types.each.with_index do |x, _|
f.puts "#define WATCH_#{x.upcase} #{_ + 1}"
end
f.puts "const char* WATCH_LABELS[] = {";
f.puts watches.map { |x| " \"#{x[:label]}\"" }.join(",\n");
f.puts "};"
f.puts "const uint16_t WATCH_ADDRESSES[] = {";
f.puts watches.map { |x| " #{sprintf('0x%04x', x[:address])}" }.join(",\n");
f.puts "};"
f.puts "const uint8_t WATCH_TYPES[] = {";
f.puts watches.map { |x| " #{types.index(x[:type]) + 1}" }.join(",\n");
f.puts "};"
f.puts "const uint16_t ARG_WATCH_COUNT = #{arg_watches.size};"
types = ['u8', 'u16', 's8', 's16'];
f.puts "const uint16_t ARG_WATCH_ADDRESSES[] = {";
f.puts arg_watches.map { |x| " #{sprintf('0x%04x', x[:address])}" }.join(",\n");
f.puts "};"
f.puts "const uint8_t ARG_WATCH_TYPES[] = {";
f.puts arg_watches.map { |x| " #{types.index(x[:type]) + 1}" }.join(",\n");
f.puts "};"
registers = ['A', 'X', 'Y']
registers.each.with_index do |x, _|
f.puts "#define WATCH_#{x} #{_ + 1}"
end
f.puts "const uint8_t ARG_WATCH_REGISTERS[] = {";
f.puts arg_watches.map { |x| " #{registers.index(x[:register]) + 1}" }.join(",\n");
f.puts "};"
f.puts "const char* WATCH_REGISTER_LABELS[] = {";
f.puts " \"\","
f.puts registers.map { |x| " \"#{x}\"" }.join(",\n");
f.puts "};"
end
puts "Found #{symbols.size} labels and #{watches.size} watches."
# label_for_address.keys.sort.each do |address|
# puts sprintf("%04x %s", address, label_for_address[address])
# end