class
Synacor::Debugger
- Synacor::Debugger
- Reference
- Object
Defined in:
synacor/debugger.crConstant Summary
-
MAX_VALUE =
VM::MAX_VALUE -
REGISTERS =
VM::REGISTERS.to_a -
TELEPORTER_R7 =
25734_u16 -
The value
#solve_teleporterfinds for $7. Hardcoded so we can skip the ~100s brute-force at runtime.
Constructors
Instance Method Summary
- #ackermann(a : UInt16, b : UInt16, r7 : UInt16, memo) : UInt16
- #add_vm_input(input_str)
- #breakpoints : Array(Int32)
- #breakpoints=(breakpoints : Array(Int32))
- #clear_vm_output
- #continue_until_breakpoint(breakpoint : Int32 | Nil = nil)
- #continue_until_ret
- #custom_main_loop(&block : -> Bool)
- #debugger_loop
- #execute_instruction(opcode, args)
-
#fix_teleporter
Apply the teleporter fix without running the slow check: 1.
- #interpret_instruction(md)
-
#nexti
TODO allow nesting
- #output : ACON::Output::Interface
- #output=(output : ACON::Output::Interface)
- #print_breakpoints
- #print_disassemble(pc : Int32 | Nil = self.vm.pc)
- #print_registers
- #print_solved_coin_problem
- #print_solved_teleporter
- #print_stack
- #print_vm_input(position = false)
- #print_vm_output
- #remove_breakpoint(breakpoint)
-
#resume_program
Hand control back to the VM: restore output to the real terminal and run the normal main loop from the current PC.
- #resume_requested : Bool
- #resume_requested=(resume_requested : Bool)
- #set_breakpoint(breakpoint)
- #solve_coin_problem : Array(String)
-
#solve_teleporter : UInt16
The teleporter confirmation routine at address 6027 is a parameterized Ackermann function where register 7 ($7) is the free parameter:
- #stepi
- #stepo
- #vm : VM
- #vm=(vm : VM)
- #vm_output_io : IO::Memory
- #vm_output_io=(vm_output_io : IO::Memory)
Constructor Detail
Instance Method Detail
Apply the teleporter fix without running the slow check:
- Set $7 to the calibrated value (a later routine derives the printed code from $7, so this must be the genuine value, not faked).
- Patch the confirmation function at 6027 so it returns 6 immediately, since the real recursion is far too deep to actually run. The caller at 5489 only inspects $0 after the call, so: 6027: set $0 6 (1, 32768, 6) 6030: ret (18)
Hand control back to the VM: restore output to the real terminal and run the normal main loop from the current PC. Remaining buffered input (from any --load saves) is consumed first, then op_in falls back to STDIN, so the game continues interactively. HaltError and friends propagate up to RunCommand#execute, which handles them.
The teleporter confirmation routine at address 6027 is a parameterized Ackermann function where register 7 ($7) is the free parameter:
f(0, b) = b + 1 f(a, 0) = f(a - 1, $7) f(a, b) = f(a - 1, f(a, b - 1)) (all mod MAX_VALUE)
The caller at 5483 sets $0=4, $1=1, calls it, and requires f(4, 1) == 6. We brute-force every candidate for $7, memoizing per-candidate so each evaluation is cheap.