-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathwarp_data_labels.rb
88 lines (74 loc) · 2.37 KB
/
warp_data_labels.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#!/usr/bin/env ruby
require "json"
require "pry-byebug"
BANK_SIZE = Integer("4000", 16)
ROM_FILE = ENV.fetch("ROM_FILE", "./crystal-speedchoice.gbc")
ROM_FILE_BASENAME = File.basename(ROM_FILE, File.extname(ROM_FILE))
SYM_FILE = "#{ROM_FILE_BASENAME}.sym"
OUT_FILE = "#{ROM_FILE_BASENAME}-warp-label-details.json"
# there's no ASM-level label for this, so we have to handle it
# specially.
ILEX_FOREST_TREE = 721295
def rom
@rom ||= IO.binread(ROM_FILE)
end
def byte_to_string(byte)
"$#{byte.ord.to_s(16)}"
end
def label_hex_addresses
File
.read(SYM_FILE)
.split("\n")
.select { |l| l.include?("cwri") }
.map { |line| line.split(" ") }
.map { |address, label| [label, address] }
end
def label_addresses
@label_addresses ||= Hash[label_hex_addresses.map do |label, hex_address|
bank, internal_address = hex_address.split(":").map { |val| Integer(val, 16) }
address = (internal_address % BANK_SIZE) + (bank * BANK_SIZE)
[label, address]
end]
end
def rom_bytes_to_integers(rom_bytes)
rom_bytes.split('').map(&:bytes).flatten.join(" ")
end
def ilex_forest_diff
{
"integer_values" => rom_bytes_to_integers(rom[ILEX_FOREST_TREE]),
"address_range" => {
"begin" => ILEX_FOREST_TREE,
"end" => ILEX_FOREST_TREE + 1,
},
"label" => "Remove cuttable tree in Ilex Forest",
}
end
def main
label_address_ranges =
label_addresses
.keys
.reject { |label| label.include?("cwri_AFTER") }
.map do |label|
post_label = label.gsub("cwri_BEFORE", "cwri_AFTER")
puts(label)
puts(label_addresses[label])
puts(post_label)
puts(label_addresses[post_label])
puts(label_addresses[label]...label_addresses[post_label])
address_range = label_addresses[label]...label_addresses[post_label]
[label, address_range]
end
label_details =
label_address_ranges.map do |label, address_range|
{
"label" => label,
"address_range" => { "begin" => address_range.begin, "end" => address_range.end },
"integer_values" => rom_bytes_to_integers(rom[address_range]),
"hex_values" => rom[address_range].each_char.map(&method(:byte_to_string)).join(" "),
}
end.sort_by { |details| details["label"] }
label_details << ilex_forest_diff
File.write(OUT_FILE, JSON.pretty_generate(label_details))
STDERR.puts "generated #{OUT_FILE}"
end
main