32 const auto& data = rom.
vector();
33 auto byte_at = [&](uint32_t snes) ->
int {
35 return pc < data.size() ? data[pc] : -1;
38 std::vector<ObjectDrawCode> out;
39 for (
const auto& table : kDispatchTables) {
40 for (
int i = 0; i < table.count; ++i) {
41 const uint32_t entry = table.address +
static_cast<uint32_t
>(i * 2);
42 const int lo = byte_at(entry);
43 const int hi = byte_at(entry + 1);
44 if (lo < 0 || hi < 0) {
50 0x010000 |
static_cast<uint32_t
>(lo | (hi << 8));
55 std::set<uint32_t> starts;
56 for (
const auto& code : out) {
57 starts.insert(code.routine_start);
59 for (
auto& code : out) {
60 auto next = starts.upper_bound(code.routine_start);
61 const uint32_t cap = code.routine_start + kMaxRoutineBytes;
62 code.routine_end = next == starts.end() ? cap : std::min(*next, cap);
64 const int opcode = byte_at(code.routine_start);
65 const int bank = byte_at(code.routine_start + 3);
66 if ((opcode == kJsl || opcode == kJml) && bank >= kFirstExpandedBank) {
67 code.jumps_to_expanded_code =
true;
69 static_cast<uint32_t
>(byte_at(code.routine_start + 1)) |
70 (
static_cast<uint32_t
>(byte_at(code.routine_start + 2)) << 8) |
71 (
static_cast<uint32_t
>(bank) << 16);