// File: daniel5151[P]mips241/src/debug.cc
// Function: MIPS::Debugger::debugREPL()
void Debugger::debugREPL() {
  // If we are not stepping each cycle, then we might be able
  //  to skip some instructions
  if (!cycleStep) {
    // If we are not in Stage 0, don't debug
    if (cpu.getStage() != 0) return;

    // If we are stepping, or there is a breakpoint, debug
    if (step || breakpoints.count(cpu.getPC()) != 0) {
      // do the debug
    } else return;
  }

  debugPrint();

  // the worst REPL you've ever seen
  for (;;) {
    cerr << prevInput << "> "; // prompt

    string input;
    getline(cin, input);

    if (input == "") {
      input = prevInput; // Redo prev input
    }

    prevInput = input; // Save new input in history

    stringstream in_ss (input);

    bool valid = true;

    string tok;
    while (in_ss >> tok) {
      if (tok == "step") {
        step = true;  return;
      }
      else if (tok == "run")  {
        step = false;

        // "clear" screen
        cerr << string(100, '\n');
        return;
      }
      else if (tok == "+bp") {
        uint32_t bp_addr;
        in_ss >> hex >> bp_addr;
        breakpoints.insert(bp_addr);
        higlight[bp_addr] = '!';
      }
      else if (tok == "-bp") {
        uint32_t bp_addr;
        in_ss >> hex >> bp_addr;
        breakpoints.erase(bp_addr);
           higlight.erase(bp_addr);
      }
      else if (tok == "peek") {
        uint32_t memaddr;
        in_ss >> hex >> memaddr;
        cerr << toHex(bus.load(memaddr)) << endl;
      }
      else if (tok == "poke") {
        uint32_t memaddr;
        uint32_t new_val;
        in_ss
          >> hex >> memaddr
          >> hex >> new_val;

        bus.store(memaddr, new_val);
      }
      else if (tok == "+watch") {
        uint32_t memaddr;
        in_ss >> hex >> memaddr;
        watch.insert(memaddr);
      }
      else if (tok == "-watch") {
        uint32_t memaddr;
        in_ss >> hex >> memaddr;
        watch.erase(memaddr);
      }
      else if (tok == "print") {
        debugPrint();
      }
      else if (tok == "help") {
        cerr
          << "  step              - exec one instruction"         << endl
          << "  run               - resume regular execution"     << endl
          << "  +bp <addr>        - add breakpoint at <addr>"     << endl
          << "  -bp <addr>        - remove breakpoint at <addr>"  << endl
          << "  peek <addr>       - print out contents of <addr>" << endl
          << "  poke <addr> <val> - edit contents of <addr>"      << endl
          << "  +watch <addr>     - keep an eye on <addr>"        << endl
          << "  -watch <addr>     - don't keep an eye on <addr>"  << endl
          << "  print             - display debug data"           << endl;
      }

      else {
        valid = false;
        break;

      }
    }
    if (!valid) cerr << "Unknown command." << endl;
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x400, %rsp            # imm = 0x400
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x288(%rbp)
testb $0x1, 0x48(%rax)
jne 0x76e4
movq -0x288(%rbp), %rax
movq (%rax), %rdi
callq 0x5550
cmpl $0x0, %eax
je 0x767d
jmp 0x808d
movq -0x288(%rbp), %rcx
movb $0x1, %al
testb $0x1, 0x49(%rcx)
movb %al, -0x289(%rbp)
jne 0x76cf
movq -0x288(%rbp), %rax
movq %rax, %rcx
addq $0x50, %rcx
movq %rcx, -0x298(%rbp)
movq (%rax), %rdi
callq 0x5570
movq -0x298(%rbp), %rdi
movl %eax, -0xc(%rbp)
leaq -0xc(%rbp), %rsi
callq 0x85e0
cmpq $0x0, %rax
setne %al
movb %al, -0x289(%rbp)
movb -0x289(%rbp), %al
testb $0x1, %al
jne 0x76db
jmp 0x76dd
jmp 0x76e2
jmp 0x808d
jmp 0x76e4
movq -0x288(%rbp), %rdi
callq 0x7310
movq -0x288(%rbp), %rsi
addq $0xb0, %rsi
movq 0xf8eb(%rip), %rdi      # 0x16ff0
callq 0x3220
movq %rax, %rdi
leaq 0x8b1b(%rip), %rsi      # 0x1022f
callq 0x3250
leaq -0x30(%rbp), %rdi
movq %rdi, -0x2a0(%rbp)
callq 0x33d0
movq -0x2a0(%rbp), %rsi
movq 0xf8a1(%rip), %rdi      # 0x16fd8
callq 0x3080
jmp 0x773e
leaq 0x88c0(%rip), %rsi      # 0x10005
leaq -0x30(%rbp), %rdi
callq 0x5ee0
movb %al, -0x2a1(%rbp)
jmp 0x7756
movb -0x2a1(%rbp), %al
testb $0x1, %al
jne 0x7762
jmp 0x778e
movq -0x288(%rbp), %rsi
addq $0xb0, %rsi
leaq -0x30(%rbp), %rdi
callq 0x3040
jmp 0x777b
jmp 0x778e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
jmp 0x8082
movq -0x288(%rbp), %rdi
addq $0xb0, %rdi
leaq -0x30(%rbp), %rsi
callq 0x3040
jmp 0x77a7
movl $0x10, %edi
movl $0x8, %esi
callq 0x8640
movl %eax, -0x2a8(%rbp)
jmp 0x77be
movl -0x2a8(%rbp), %edx
leaq -0x1c8(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x3420
jmp 0x77d6
movb $0x1, -0x1c9(%rbp)
leaq -0x1f0(%rbp), %rdi
callq 0x33d0
leaq -0x1c8(%rbp), %rdi
leaq -0x1f0(%rbp), %rsi
callq 0x3380
movq %rax, -0x2b0(%rbp)
jmp 0x7805
movq -0x2b0(%rbp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x3360
movb %al, -0x2b1(%rbp)
jmp 0x7823
movb -0x2b1(%rbp), %al
testb $0x1, %al
jne 0x7832
jmp 0x7ff0
leaq 0x8865(%rip), %rsi      # 0x1009e
leaq -0x1f0(%rbp), %rdi
callq 0x5ee0
movb %al, -0x2b2(%rbp)
jmp 0x784d
movb -0x2b2(%rbp), %al
testb $0x1, %al
jne 0x7859
jmp 0x7884
movq -0x288(%rbp), %rax
movb $0x1, 0x49(%rax)
movl $0x1, -0x1f4(%rbp)
jmp 0x8036
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
jmp 0x806a
leaq 0x89a7(%rip), %rsi      # 0x10232
leaq -0x1f0(%rbp), %rdi
callq 0x5ee0
movb %al, -0x2b3(%rbp)
jmp 0x789f
movb -0x2b3(%rbp), %al
testb $0x1, %al
jne 0x78ae
jmp 0x795e
movq -0x288(%rbp), %rax
movb $0x0, 0x49(%rax)
leaq -0x219(%rbp), %rdi
movq %rdi, -0x2c0(%rbp)
callq 0x34d0
movq -0x2c0(%rbp), %rcx
leaq -0x218(%rbp), %rdi
movl $0x64, %esi
movl $0xa, %edx
callq 0x3ce0
jmp 0x78eb
movq 0xf6fe(%rip), %rdi      # 0x16ff0
leaq -0x218(%rbp), %rsi
callq 0x3220
jmp 0x7900
leaq -0x218(%rbp), %rdi
callq 0x3528
leaq -0x219(%rbp), %rdi
callq 0x32d0
movl $0x1, -0x1f4(%rbp)
jmp 0x8036
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
jmp 0x794d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0x218(%rbp), %rdi
callq 0x3528
leaq -0x219(%rbp), %rdi
callq 0x32d0
jmp 0x806a
leaq 0x88d1(%rip), %rsi      # 0x10236
leaq -0x1f0(%rbp), %rdi
callq 0x5ee0
movb %al, -0x2c1(%rbp)
jmp 0x7979
movb -0x2c1(%rbp), %al
testb $0x1, %al
jne 0x7988
jmp 0x7a28
leaq 0xcd1(%rip), %rsi       # 0x8660
leaq -0x1c8(%rbp), %rdi
callq 0x3480
movq %rax, -0x2d0(%rbp)
jmp 0x79a4
movq -0x2d0(%rbp), %rdi
leaq -0x220(%rbp), %rsi
callq 0x3050
jmp 0x79b9
movq -0x288(%rbp), %rdi
addq $0x50, %rdi
leaq -0x220(%rbp), %rsi
callq 0x8690
movb %dl, -0x2d9(%rbp)
movq %rax, -0x2d8(%rbp)
jmp 0x79df
movq -0x288(%rbp), %rdi
movb -0x2d9(%rbp), %al
movq -0x2d8(%rbp), %rcx
movq %rcx, -0x230(%rbp)
movb %al, -0x228(%rbp)
addq $0x18, %rdi
leaq -0x220(%rbp), %rsi
callq 0x81d0
movq %rax, -0x2e8(%rbp)
jmp 0x7a19
movq -0x2e8(%rbp), %rax
movb $0x21, (%rax)
jmp 0x7fe7
leaq 0x880b(%rip), %rsi      # 0x1023a
leaq -0x1f0(%rbp), %rdi
callq 0x5ee0
movb %al, -0x2e9(%rbp)
jmp 0x7a43
movb -0x2e9(%rbp), %al
testb $0x1, %al
jne 0x7a4f
jmp 0x7ab7
leaq 0xc0a(%rip), %rsi       # 0x8660
leaq -0x1c8(%rbp), %rdi
callq 0x3480
movq %rax, -0x2f8(%rbp)
jmp 0x7a6b
movq -0x2f8(%rbp), %rdi
leaq -0x234(%rbp), %rsi
callq 0x3050
jmp 0x7a80
movq -0x288(%rbp), %rdi
addq $0x50, %rdi
leaq -0x234(%rbp), %rsi
callq 0x86e0
jmp 0x7a99
movq -0x288(%rbp), %rdi
addq $0x18, %rdi
leaq -0x234(%rbp), %rsi
callq 0x84b0
jmp 0x7ab2
jmp 0x7fe5
leaq 0x8780(%rip), %rsi      # 0x1023e
leaq -0x1f0(%rbp), %rdi
callq 0x5ee0
movb %al, -0x2f9(%rbp)
jmp 0x7ad2
movb -0x2f9(%rbp), %al
testb $0x1, %al
jne 0x7ae1
jmp 0x7bb0
leaq 0xb78(%rip), %rsi       # 0x8660
leaq -0x1c8(%rbp), %rdi
callq 0x3480
movq %rax, -0x308(%rbp)
jmp 0x7afd
movq -0x308(%rbp), %rdi
leaq -0x238(%rbp), %rsi
callq 0x3050
jmp 0x7b12
movq -0x288(%rbp), %rax
movq 0x10(%rax), %rdi
movl -0x238(%rbp), %esi
callq 0x37f0
movl %eax, -0x30c(%rbp)
jmp 0x7b30
movl -0x30c(%rbp), %eax
movl %eax, -0x25c(%rbp)
leaq -0x258(%rbp), %rdi
leaq -0x25c(%rbp), %rsi
callq 0x82b0
jmp 0x7b51
movq 0xf498(%rip), %rdi      # 0x16ff0
leaq -0x258(%rbp), %rsi
callq 0x3220
movq %rax, -0x318(%rbp)
jmp 0x7b6d
movq -0x318(%rbp), %rdi
movq 0xf42d(%rip), %rsi      # 0x16fa8
callq 0x32a0
jmp 0x7b82
leaq -0x258(%rbp), %rdi
callq 0x3528
jmp 0x7fe3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0x258(%rbp), %rdi
callq 0x3528
jmp 0x806a
leaq 0x868c(%rip), %rsi      # 0x10243
leaq -0x1f0(%rbp), %rdi
callq 0x5ee0
movb %al, -0x319(%rbp)
jmp 0x7bcb
movb -0x319(%rbp), %al
testb $0x1, %al
jne 0x7bda
jmp 0x7c66
leaq 0xa7f(%rip), %rsi       # 0x8660
leaq -0x1c8(%rbp), %rdi
callq 0x3480
movq %rax, -0x328(%rbp)
jmp 0x7bf6
movq -0x328(%rbp), %rdi
leaq -0x260(%rbp), %rsi
callq 0x3050
movq %rax, -0x330(%rbp)
jmp 0x7c12
movq -0x330(%rbp), %rdi
leaq 0xa40(%rip), %rsi       # 0x8660
callq 0x3480
movq %rax, -0x338(%rbp)
jmp 0x7c2e
movq -0x338(%rbp), %rdi
leaq -0x264(%rbp), %rsi
callq 0x3050
jmp 0x7c43
movq -0x288(%rbp), %rax
movq 0x10(%rax), %rdi
movl -0x260(%rbp), %esi
movl -0x264(%rbp), %edx
callq 0x3930
jmp 0x7c61
jmp 0x7fe1
leaq 0x85db(%rip), %rsi      # 0x10248
leaq -0x1f0(%rbp), %rdi
callq 0x5ee0
movb %al, -0x339(%rbp)
jmp 0x7c81
movb -0x339(%rbp), %al
testb $0x1, %al
jne 0x7c8d
jmp 0x7d03
leaq 0x9cc(%rip), %rsi       # 0x8660
leaq -0x1c8(%rbp), %rdi
callq 0x3480
movq %rax, -0x348(%rbp)
jmp 0x7ca9
movq -0x348(%rbp), %rdi
leaq -0x268(%rbp), %rsi
callq 0x3050
jmp 0x7cbe
movq -0x288(%rbp), %rdi
subq $-0x80, %rdi
leaq -0x268(%rbp), %rsi
callq 0x8690
movb %dl, -0x351(%rbp)
movq %rax, -0x350(%rbp)
jmp 0x7ce4
movb -0x351(%rbp), %al
movq -0x350(%rbp), %rcx
movq %rcx, -0x278(%rbp)
movb %al, -0x270(%rbp)
jmp 0x7fdf
leaq 0x8545(%rip), %rsi      # 0x1024f
leaq -0x1f0(%rbp), %rdi
callq 0x5ee0
movb %al, -0x352(%rbp)
jmp 0x7d1e
movb -0x352(%rbp), %al
testb $0x1, %al
jne 0x7d2a
jmp 0x7d79
leaq 0x92f(%rip), %rsi       # 0x8660
leaq -0x1c8(%rbp), %rdi
callq 0x3480
movq %rax, -0x360(%rbp)
jmp 0x7d46
movq -0x360(%rbp), %rdi
leaq -0x27c(%rbp), %rsi
callq 0x3050
jmp 0x7d5b
movq -0x288(%rbp), %rdi
subq $-0x80, %rdi
leaq -0x27c(%rbp), %rsi
callq 0x86e0
jmp 0x7d74
jmp 0x7fdd
leaq 0x84d6(%rip), %rsi      # 0x10256
leaq -0x1f0(%rbp), %rdi
callq 0x5ee0
movb %al, -0x361(%rbp)
jmp 0x7d94
movb -0x361(%rbp), %al
testb $0x1, %al
jne 0x7da0
jmp 0x7db3
movq -0x288(%rbp), %rdi
callq 0x7310
jmp 0x7dae
jmp 0x7fdb
leaq 0x84a2(%rip), %rsi      # 0x1025c
leaq -0x1f0(%rbp), %rdi
callq 0x5ee0
movb %al, -0x362(%rbp)
jmp 0x7dce
movb -0x362(%rbp), %al
testb $0x1, %al
jne 0x7ddd
jmp 0x7fd0
movq 0xf20c(%rip), %rdi      # 0x16ff0
leaq 0x8476(%rip), %rsi      # 0x10261
callq 0x3250
movq %rax, -0x370(%rbp)
jmp 0x7df9
movq -0x370(%rbp), %rdi
movq 0xf1a1(%rip), %rsi      # 0x16fa8
callq 0x32a0
movq %rax, -0x378(%rbp)
jmp 0x7e15
movq -0x378(%rbp), %rdi
leaq 0x8469(%rip), %rsi      # 0x1028c
callq 0x3250
movq %rax, -0x380(%rbp)
jmp 0x7e31
movq -0x380(%rbp), %rdi
movq 0xf169(%rip), %rsi      # 0x16fa8
callq 0x32a0
movq %rax, -0x388(%rbp)
jmp 0x7e4d
movq -0x388(%rbp), %rdi
leaq 0x8460(%rip), %rsi      # 0x102bb
callq 0x3250
movq %rax, -0x390(%rbp)
jmp 0x7e69
movq -0x390(%rbp), %rdi
movq 0xf131(%rip), %rsi      # 0x16fa8
callq 0x32a0
movq %rax, -0x398(%rbp)
jmp 0x7e85
movq -0x398(%rbp), %rdi
leaq 0x8457(%rip), %rsi      # 0x102ea
callq 0x3250
movq %rax, -0x3a0(%rbp)
jmp 0x7ea1
movq -0x3a0(%rbp), %rdi
movq 0xf0f9(%rip), %rsi      # 0x16fa8
callq 0x32a0
movq %rax, -0x3a8(%rbp)
jmp 0x7ebd
movq -0x3a8(%rbp), %rdi
leaq 0x8451(%rip), %rsi      # 0x1031c
callq 0x3250
movq %rax, -0x3b0(%rbp)
jmp 0x7ed9
movq -0x3b0(%rbp), %rdi
movq 0xf0c1(%rip), %rsi      # 0x16fa8
callq 0x32a0
movq %rax, -0x3b8(%rbp)
jmp 0x7ef5
movq -0x3b8(%rbp), %rdi
leaq 0x844c(%rip), %rsi      # 0x1034f
callq 0x3250
movq %rax, -0x3c0(%rbp)
jmp 0x7f11
movq -0x3c0(%rbp), %rdi
movq 0xf089(%rip), %rsi      # 0x16fa8
callq 0x32a0
movq %rax, -0x3c8(%rbp)
jmp 0x7f2d
movq -0x3c8(%rbp), %rdi
leaq 0x8442(%rip), %rsi      # 0x1037d
callq 0x3250
movq %rax, -0x3d0(%rbp)
jmp 0x7f49
movq -0x3d0(%rbp), %rdi
movq 0xf051(%rip), %rsi      # 0x16fa8
callq 0x32a0
movq %rax, -0x3d8(%rbp)
jmp 0x7f65
movq -0x3d8(%rbp), %rdi
leaq 0x8436(%rip), %rsi      # 0x103a9
callq 0x3250
movq %rax, -0x3e0(%rbp)
jmp 0x7f81
movq -0x3e0(%rbp), %rdi
movq 0xf019(%rip), %rsi      # 0x16fa8
callq 0x32a0
movq %rax, -0x3e8(%rbp)
jmp 0x7f9d
movq -0x3e8(%rbp), %rdi
leaq 0x8430(%rip), %rsi      # 0x103db
callq 0x3250
movq %rax, -0x3f0(%rbp)
jmp 0x7fb9
movq -0x3f0(%rbp), %rdi
movq 0xefe1(%rip), %rsi      # 0x16fa8
callq 0x32a0
jmp 0x7fce
jmp 0x7fd9
movb $0x0, -0x1c9(%rbp)
jmp 0x7ff0
jmp 0x7fdb
jmp 0x7fdd
jmp 0x7fdf
jmp 0x7fe1
jmp 0x7fe3
jmp 0x7fe5
jmp 0x7fe7
jmp 0x7fe9
jmp 0x7feb
jmp 0x77e9
testb $0x1, -0x1c9(%rbp)
jne 0x802c
movq 0xeff0(%rip), %rdi      # 0x16ff0
leaq 0x83fd(%rip), %rsi      # 0x10404
callq 0x3250
movq %rax, -0x3f8(%rbp)
jmp 0x8015
movq -0x3f8(%rbp), %rdi
movq 0xef85(%rip), %rsi      # 0x16fa8
callq 0x32a0
jmp 0x802a
jmp 0x802c
movl $0x0, -0x1f4(%rbp)
leaq -0x1f0(%rbp), %rdi
callq 0x3528
leaq -0x1c8(%rbp), %rdi
callq 0x31d0
leaq -0x30(%rbp), %rdi
callq 0x3528
movl -0x1f4(%rbp), %eax
testl %eax, %eax
je 0x8065
jmp 0x8063
jmp 0x808d
jmp 0x76f0
leaq -0x1f0(%rbp), %rdi
callq 0x3528
leaq -0x1c8(%rbp), %rdi
callq 0x31d0
leaq -0x30(%rbp), %rdi
callq 0x3528
jmp 0x8096
addq $0x400, %rsp            # imm = 0x400
popq %rbp
retq
movq -0x38(%rbp), %rdi
callq 0x34c0
nop