class

Synacor::Debugger

Inherits Reference < Object

Constants

MAX_VALUE = VM::MAX_VALUE
REGISTERS = VM::REGISTERS.to_a
TELEPORTER_R7 = 25734_u16

The value solve_teleporter finds for $7. Hardcoded so we can skip the ~100s brute-force at runtime.

Constructors

new(vm : Synacor::VM, output : Athena::Console::Output::Interface)
Source

Instance methods

ackermann(a : UInt16, b : UInt16, r7 : UInt16, memo) : UInt16
Source
add_vm_input(input_str)
Source
breakpoints
Source
breakpoints=(breakpoints : Array(Int32))
Source
clear_vm_output
Source
continue_until_breakpoint(breakpoint : Int32 | Nil = nil)
Source
continue_until_ret
Source
custom_main_loop
Source
debugger_loop
Source
execute_instruction(opcode, args)
Source
fix_teleporter

Apply the teleporter fix without running the slow check:

  1. Set $7 to the calibrated value (a later routine derives the printed code from $7, so this must be the genuine value, not faked).
  2. 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)
Source
interpret_instruction(md)
Source
nexti

TODO: allow nesting

Source
output
Source
output=(output : ACON::Output::Interface)
Source
remove_breakpoint(breakpoint)
Source
resume_program

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.

Source
resume_requested
Source
resume_requested=(resume_requested : Bool)
Source
set_breakpoint(breakpoint)
Source
solve_coin_problem
Source
solve_teleporter

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.

Source
stepi
Source
stepo
Source
vm=(vm : VM)
Source
vm_output_io
Source
vm_output_io=(vm_output_io : IO::Memory)
Source