// File: /workspace/github_c_makefile_star2_O2/mrkite[P]regs/src/main.cc
// Function: main
int main(int argc, char **argv) {
  API api(iigs_dat, iigs_dat_len);

  struct arguments arguments;
  arguments.filename = "";
  arguments.keyword = nullptr;
  arguments.org = 0;
  arguments.flags = 0;
  argp_parse(&argp, argc, argv, 0, 0, &arguments);

  if (arguments.keyword) {
    api.search(arguments.keyword, arguments.org);
    return 0;
  }

  // load map if it exists
  Map map(arguments.filename, arguments.org);
  OMF omf;
  if (!omf.load(arguments.filename, map.org)) {
    std::cerr << "Failed to load " << arguments.filename << std::endl;
    return -1;
  }
  auto segments = omf.get();
  if (map.needsEntry()) {
    for (auto &s : segments) {
      if ((s.kind & 0x1f) == 0) {  // first code
        map.addEntry(s.mapped + s.entry, arguments.flags);
        break;
      }
    }
  }

  // note that we save the map here.. before we add a bunch of symbols
  // from the api
  map.save();


  auto prints = std::make_shared<Fingerprints>();
  for (auto s : api.symbols) {
    if (s.second->kind == symbol::isFunction) {
      auto f = std::static_pointer_cast<symbol::Function>(s.second);
      if (f->signature.size() >= 2) {
        if (f->signature[0] >= 0) {  // tool
          // ldx tool, jsl e1/0000
          std::vector<uint8_t> sig = { 0xa2, 0x00, 0x00,
            0x22, 0x00, 0x00, 0xe1 };
          sig[1] = f->signature[0];
          sig[2] = f->signature[1];
          prints->add(sig, f->name);
        } else if (f->signature[0] == -1) {  // p16/gsos
          // jsl e1/00a8
          std::vector<uint8_t> sig = { 0x22, 0xa8, 0x00, 0xe1, 0x00, 0x00 };
          sig[4] = f->signature[2] & 0xff;
          sig[5] = f->signature[2] >> 8;
          prints->add(sig, f->name, f->signature[1] & 0xff);
        } else if (f->signature[0] == -2) {  // p8
          // jsr bf00
          std::vector<uint8_t> sig = { 0x20, 0x00, 0xbf, 0x00 };
          sig[3] = f->signature[2];
          prints->add(sig, f->name, f->signature[1] & 0xff);
        } else if (f->signature[0] == -3) {  // smartport
          // jsr c50d
          std::vector<uint8_t> sig5 = { 0x20, 0x0d, 0xc5, 0x00 };
          std::vector<uint8_t> sig7 = { 0x20, 0x0d, 0xc7, 0x00 };
          sig5[3] = f->signature[2];
          sig7[3] = f->signature[2];
          prints->add(sig5, f->name, f->signature[1]);
          prints->add(sig7, f->name, f->signature[1]);
        } else if (f->signature[0] == -4) {  // symbol
          map.addSymbol(f->signature[1], f->name);
        }
      }
    }
  }

  Disassembler d(prints, map.getSymbols(), map.b);
  d.disassemble(segments, map.getEntries());
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x338, %rsp            # imm = 0x338
movq %rsi, %rbx
movl %edi, %ebp
movl 0x49ebc(%rip), %edx     # 0x4f514
leaq 0x1abe1(%rip), %rsi     # 0x20240
leaq 0x2d8(%rsp), %rdi
callq 0xd2f0
leaq 0xebff(%rip), %rax      # 0x14272
leaq 0x70(%rsp), %r9
movq %rax, (%r9)
xorps %xmm0, %xmm0
movups %xmm0, 0x8(%r9)
leaq 0x49e9e(%rip), %rdi     # 0x4f528
movl %ebp, %esi
movq %rbx, %rdx
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x50b0
movq 0x80(%rsp), %rsi
testq %rsi, %rsi
je 0x56e8
leaq 0x1b0(%rsp), %rdi
leaq 0x1d0(%rsp), %rdx
callq 0x5fd6
movl 0x78(%rsp), %edx
leaq 0x2d8(%rsp), %rdi
leaq 0x1b0(%rsp), %rsi
callq 0xe0e2
leaq 0x1b0(%rsp), %rdi
callq 0x5140
xorl %ebx, %ebx
jmp 0x5c82
movq 0x70(%rsp), %rsi
movl 0x78(%rsp), %edx
leaq 0x1d0(%rsp), %rdi
callq 0x8bd0
leaq 0x188(%rsp), %rdi
callq 0x6810
movq 0x70(%rsp), %rsi
movl 0x1d0(%rsp), %edx
leaq 0x188(%rsp), %rdi
callq 0x686a
testb %al, %al
je 0x576f
leaq 0x98(%rsp), %rdi
leaq 0x188(%rsp), %rsi
callq 0x75ba
leaq 0x1d0(%rsp), %rdi
callq 0x93e2
testb %al, %al
je 0x57b6
movq 0x98(%rsp), %rax
movq 0xa0(%rsp), %rcx
cmpq %rcx, %rax
je 0x57b6
testb $0x1f, 0x10(%rax)
je 0x579f
addq $0x68, %rax
jmp 0x575e
movq 0x1a872(%rip), %rdi     # 0x1ffe8
leaq 0xe8b2(%rip), %rsi      # 0x1402f
callq 0x5200
movq 0x70(%rsp), %rsi
movq %rax, %rdi
callq 0x5200
movq %rax, %rdi
callq 0x5150
pushq $-0x1
popq %rbx
jmp 0x5c68
movl 0x20(%rax), %esi
addl 0x60(%rax), %esi
movl 0x7c(%rsp), %edx
leaq 0x1d0(%rsp), %rdi
callq 0x940c
leaq 0x1d0(%rsp), %rdi
callq 0x8fbc
leaq 0x28(%rsp), %rdi
callq 0x6011
leaq 0x2e0(%rsp), %rax
movq 0x10(%rax), %r14
leaq 0x58(%rsp), %r12
leaq 0x40(%rsp), %r13
leaq 0x3c(%rsp), %rbp
leaq 0x2b8(%rsp), %r15
leaq 0xb0(%rsp), %rbx
leaq 0x2e0(%rsp), %rax
cmpq %rax, %r14
je 0x5b7b
leaq 0x20(%r14), %rsi
leaq 0x100(%rsp), %rdi
callq 0x602c
movq 0x120(%rsp), %rax
cmpl $0x6, 0x24(%rax)
jne 0x5b5e
leaq 0x8(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0x6055
movq 0x8(%rsp), %rsi
movq 0x50(%rsi), %rax
movq 0x58(%rsi), %rcx
subq %rax, %rcx
cmpq $0x5, %rcx
jb 0x5b54
movl (%rax), %ecx
testl %ecx, %ecx
js 0x58f4
movq %r14, 0x20(%rsp)
movl $0x220000a2, 0x40(%rsp) # imm = 0x220000A2
andw $0x0, 0x44(%rsp)
movb $-0x1f, 0x46(%rsp)
movq %r12, %rdi
movq %r13, %rsi
pushq $0x7
popq %rdx
movq %rbp, %rcx
callq 0x6072
movq 0x8(%rsp), %rax
movq 0x50(%rax), %rax
movb (%rax), %al
movq 0x58(%rsp), %rcx
movb %al, 0x1(%rcx)
movq 0x8(%rsp), %rax
movq 0x50(%rax), %rax
movb 0x4(%rax), %al
movq 0x58(%rsp), %rcx
movb %al, 0x2(%rcx)
movq 0x28(%rsp), %rbx
movq 0x8(%rsp), %rsi
movq %r15, %r14
movq %r15, %rdi
callq 0x52c0
movq %rbx, %rdi
movq %r12, %rbx
movq %r12, %rsi
movq %r14, %rdx
xorl %ecx, %ecx
callq 0xd1b8
movq %r14, %rdi
callq 0x5140
movq %rbx, %rdi
callq 0x6662
movq 0x20(%rsp), %r14
jmp 0x5b4c
addl $0x4, %ecx
cmpl $0x3, %ecx
ja 0x5b54
leaq 0xe6fd(%rip), %rdx      # 0x14004
movslq (%rdx,%rcx,4), %rcx
addq %rdx, %rcx
jmpq *%rcx
movl 0x4(%rax), %eax
movl %eax, 0x20(%rsp)
movq %rbx, %rdi
callq 0x52c0
leaq 0x1d0(%rsp), %rdi
movl 0x20(%rsp), %esi
movq %rbx, %rdx
callq 0x942c
movq %rbx, %rdi
callq 0x5140
jmp 0x5b54
movl $0xbf0020, 0x40(%rsp)   # imm = 0xBF0020
movq %r12, %rdi
movq %r13, %rsi
pushq $0x4
popq %rdx
movq %rbp, %rcx
callq 0x6072
movq 0x8(%rsp), %rax
movq 0x50(%rax), %rax
movb 0x8(%rax), %al
movq 0x58(%rsp), %rcx
movb %al, 0x3(%rcx)
movq 0x28(%rsp), %rbx
movq 0x8(%rsp), %rsi
leaq 0x148(%rsp), %rdi
callq 0x52c0
movq 0x8(%rsp), %rax
movq 0x50(%rax), %rax
movzbl 0x4(%rax), %ecx
movq %rbx, %rdi
movq %r12, %rbx
movq %r12, %rsi
leaq 0x148(%rsp), %rdx
callq 0xd1b8
leaq 0x148(%rsp), %rdi
jmp 0x5a3d
movl $0xe100a822, 0x40(%rsp) # imm = 0xE100A822
andw $0x0, 0x44(%rsp)
movq %r12, %rdi
movq %r13, %rsi
pushq $0x6
popq %rdx
movq %rbp, %rcx
callq 0x6072
movq 0x8(%rsp), %rax
movq 0x50(%rax), %rax
movb 0x8(%rax), %al
movq 0x58(%rsp), %rcx
movb %al, 0x4(%rcx)
movq 0x8(%rsp), %rax
movq 0x50(%rax), %rax
movb 0x9(%rax), %al
movq 0x58(%rsp), %rcx
movb %al, 0x5(%rcx)
movq 0x28(%rsp), %rbx
movq 0x8(%rsp), %rsi
leaq 0x168(%rsp), %rdi
callq 0x52c0
movq 0x8(%rsp), %rax
movq 0x50(%rax), %rax
movzbl 0x4(%rax), %ecx
movq %rbx, %rdi
movq %r12, %rbx
movq %r12, %rsi
leaq 0x168(%rsp), %rdx
callq 0xd1b8
leaq 0x168(%rsp), %rdi
callq 0x5140
movq %rbx, %rdi
jmp 0x5b47
movq %r14, 0x20(%rsp)
movl $0xc50d20, 0x40(%rsp)   # imm = 0xC50D20
movq %r12, %rdi
movq %r13, %rbx
movq %r13, %rsi
pushq $0x4
popq %rdx
movq %rbp, %r14
movq %rbp, %rcx
callq 0x6072
movl $0xc70d20, 0x3c(%rsp)   # imm = 0xC70D20
movq %rbx, %rdi
movq %r14, %rsi
pushq $0x4
popq %rdx
leaq 0x1f(%rsp), %rcx
callq 0x6072
movq 0x8(%rsp), %rax
movq 0x50(%rax), %rax
movb 0x8(%rax), %al
movq 0x58(%rsp), %rcx
movb %al, 0x3(%rcx)
movq 0x8(%rsp), %rax
movq 0x50(%rax), %rax
movb 0x8(%rax), %al
movq 0x40(%rsp), %rcx
movb %al, 0x3(%rcx)
movq 0x28(%rsp), %rbx
movq 0x8(%rsp), %rsi
leaq 0x268(%rsp), %rdi
callq 0x52c0
movq 0x20(%rsp), %r14
movq 0x8(%rsp), %rax
movq 0x50(%rax), %rax
movzbl 0x4(%rax), %ecx
movq %rbx, %rdi
movq %r12, %rsi
leaq 0x268(%rsp), %rbx
movq %rbx, %rdx
callq 0xd1b8
movq %rbx, %rdi
callq 0x5140
movq 0x28(%rsp), %rbx
movq 0x8(%rsp), %rsi
leaq 0x248(%rsp), %rdi
callq 0x52c0
movq 0x8(%rsp), %rax
movq 0x50(%rax), %rax
movzbl 0x4(%rax), %ecx
movq %rbx, %rdi
movq %r13, %rsi
leaq 0x248(%rsp), %rbx
movq %rbx, %rdx
callq 0xd1b8
movq %rbx, %rdi
callq 0x5140
leaq 0x40(%rsp), %rdi
callq 0x6662
movq %r12, %rdi
callq 0x6662
leaq 0xb0(%rsp), %rbx
leaq 0x10(%rsp), %rdi
callq 0x61e4
leaq 0x100(%rsp), %rdi
callq 0x60a8
movq %r14, %rdi
callq 0x5190
movq %rax, %r14
jmp 0x57f8
leaq 0x88(%rsp), %rdi
leaq 0x28(%rsp), %rsi
callq 0x6260
leaq 0x288(%rsp), %rdi
leaq 0x1d0(%rsp), %rsi
callq 0x93fa
movzbl 0x1d4(%rsp), %ecx
leaq 0x100(%rsp), %rdi
leaq 0x88(%rsp), %rsi
leaq 0x288(%rsp), %rdx
callq 0xadb0
leaq 0x288(%rsp), %rdi
callq 0x6274
leaq 0x90(%rsp), %rdi
callq 0x61e4
leaq 0xe8(%rsp), %rdi
leaq 0x98(%rsp), %rsi
callq 0x60be
leaq 0xd0(%rsp), %rdi
leaq 0x1d0(%rsp), %rsi
callq 0x93e8
leaq 0x100(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
leaq 0xd0(%rsp), %rdx
callq 0xae30
leaq 0xd0(%rsp), %rdi
callq 0x63d2
leaq 0xe8(%rsp), %rdi
callq 0x6118
leaq 0x100(%rsp), %rdi
callq 0x613a
leaq 0x30(%rsp), %rdi
callq 0x61e4
leaq 0x98(%rsp), %rdi
callq 0x6118
xorl %ebx, %ebx
leaq 0x188(%rsp), %rdi
callq 0x6150
leaq 0x1d0(%rsp), %rdi
callq 0x616a
leaq 0x2d8(%rsp), %rdi
callq 0x618e
movl %ebx, %eax
addq $0x338, %rsp            # imm = 0x338
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x5d95
movq %rax, %rbx
leaq 0xb0(%rsp), %rdi
callq 0x5140
jmp 0x5ddc
jmp 0x5dd9
movq %rax, %rbx
leaq 0x248(%rsp), %rdi
jmp 0x5cda
movq %rax, %rbx
leaq 0x268(%rsp), %rdi
callq 0x5140
jmp 0x5d89
jmp 0x5dca
jmp 0x5dd9
movq %rax, %rbx
leaq 0x148(%rsp), %rdi
jmp 0x5dc3
jmp 0x5dca
jmp 0x5dd9
movq %rax, %rbx
leaq 0x168(%rsp), %rdi
jmp 0x5dc3
jmp 0x5dca
jmp 0x5dd9
movq %rax, %rbx
leaq 0xd0(%rsp), %rdi
callq 0x63d2
jmp 0x5d37
movq %rax, %rbx
leaq 0xe8(%rsp), %rdi
callq 0x6118
jmp 0x5d49
movq %rax, %rbx
leaq 0x100(%rsp), %rdi
callq 0x613a
jmp 0x5e02
movq %rax, %rbx
leaq 0x288(%rsp), %rdi
callq 0x6274
jmp 0x5d70
movq %rax, %rbx
leaq 0x90(%rsp), %rdi
callq 0x61e4
jmp 0x5e02
jmp 0x5d95
jmp 0x5df5
movq %rax, %rbx
leaq 0x40(%rsp), %rdi
callq 0x6662
jmp 0x5dcd
movq %rax, %rbx
jmp 0x5e0c
movq %rax, %rbx
jmp 0x5e26
jmp 0x5dfa
movq %rax, %rbx
leaq 0x1b0(%rsp), %rdi
callq 0x5140
jmp 0x5e33
jmp 0x5dfa
movq %rax, %rbx
leaq 0x2b8(%rsp), %rdi
callq 0x5140
jmp 0x5dcd
movq %rax, %rbx
leaq 0x58(%rsp), %rdi
callq 0x6662
jmp 0x5ddc
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x61e4
leaq 0x100(%rsp), %rdi
callq 0x60a8
jmp 0x5e02
movq %rax, %rbx
jmp 0x5e19
movq %rax, %rbx
jmp 0x5e33
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x61e4
leaq 0x98(%rsp), %rdi
callq 0x6118
leaq 0x188(%rsp), %rdi
callq 0x6150
leaq 0x1d0(%rsp), %rdi
callq 0x616a
leaq 0x2d8(%rsp), %rdi
callq 0x618e
movq %rbx, %rdi
callq 0x53c0