/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// NintendoSpy Firmware for Arduino
// v1.0.1
// Written by jaburns
//
// Anti-spazzing mod by eN-t
// GameCube controller only!

#define PIN_READ (PIND&(1<<(5)))
#define MICROSECOND_NOPS "nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n"
#define WAIT_FALLING_EDGE while(!PIN_READ); while(PIN_READ);

#define ZERO  '\0'
#define ONE    '1'
#define SPLIT '\n'

unsigned char rawData[128];

void setup() {
  PORTD = 0x00;
  DDRD  = 0x00;
  PORTC = 0xFF;
  DDRC  = 0x00;
  Serial.begin(115200);
}

void read_oneWire() {
  unsigned char *rawDataPtr = rawData;
  unsigned char bits = 89;

read_loop:
  WAIT_FALLING_EDGE;
  asm volatile(MICROSECOND_NOPS MICROSECOND_NOPS);
  *rawDataPtr = PIN_READ;
  ++rawDataPtr;
  if (--bits == 0) return;
  goto read_loop;
}

inline void sendRawData() {
  for (unsigned char i = 25; i < 89; i++) {
    Serial.write(rawData[i] ? ONE : ZERO);
  }
  Serial.write(SPLIT);
}

void loop() {
  noInterrupts();
  read_oneWire();
  interrupts();
  sendRawData();
  delay(11);
}
