   ARM_DWT_CYCCNT = 0;
 }
 
-static long readTimer()
+static uint32_t readTimer()
 {
   return ARM_DWT_CYCCNT;
 }
+
+static bool timer64Started = false;
+
+static void start64Timer()
+{
+  // turn on PIT
+  SIM_SCGC6 |= SIM_SCGC6_PIT;
+  __asm__ volatile("nop"); // solves timing problem on Teensy 3.5
+  PIT_MCR = 0x00;
+
+  // Timer 1
+  PIT_TCTRL1 = 0x0; // disable timer 1 and its interrupts
+  PIT_LDVAL1 = 0xFFFFFFFF; // setup timer 1 for maximum counting period
+  PIT_TCTRL1 |= PIT_TCTRL_CHN; // chain timer 1 to timer 0
+  PIT_TCTRL1 |= PIT_TCTRL_TEN; // start timer 1
+
+  // Timer 0
+  PIT_TCTRL0 = 0; // disable timer 0 and its interrupts
+  PIT_LDVAL0 = 0xFFFFFFFF; // setup timer 0 for maximum counting period
+  PIT_TCTRL0 = PIT_TCTRL_TEN; // start timer 0
+  timer64Started = true;
+}
+
+static uint64_t read64Timer()
+{
+  if (!timer64Started)
+    return 0;
+  
+#ifndef PIT_LTMR64H
+#define PIT_LTMR64H             (*(volatile uint32_t *)0x400370E0) // PIT Upper Lifetime Timer Register
+#define PIT_LTMR64L             (*(volatile uint32_t *)0x400370E4) // PIT Lower Lifetime Timer Register
+#endif
+
+  uint64_t current_uptime = (uint64_t)PIT_LTMR64H << 32;
+  current_uptime = current_uptime + PIT_LTMR64L;
+  return 0xffffffffffffffffull - current_uptime;
+}
+
 
 static size_t getNextRegion(size_t& size) {
   size_t currentPos = bufferPos;

  ARM_DEMCR |= ARM_DEMCR_TRCENA;
  ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;

  Serial.begin(SERIAL_BAUD_RATE);
  while (!Serial) { ; } // wait for serial port to connect. Needed for native USB port only

  // Status LED
  digitalWrite(STATUS_PIN, LOW);

            // blast out the pre-assembled array in output_buffer
            n64_send(output_buffer, 4, 1);

            logFrame(output_buffer, 4, curFrame + (haveFrame ? 1 : 0));

            if (!haveFrame)
              break;

            // update input buffer and make sure it doesn't take too long

