// Nasty 7-bit audio from the floppy port
// 7 bit because every 8th bit is a clock sync bit
// Every byte sent requires the LSB to be set in order for this to sync properly.
// This code uses the Input Capture feature of the Arduino to track which bit
// it should be on. This is based on my work from my Drawbridge boards
// https://rev26.robsmith.dev
// https://robsmithdev.co.uk
// RobSmithDev


#define PIN_READ_DATA            8          // Reads RAW floppy data on this pin.  
#define PIN_WRITE_GATE           9          // Reads RAW floppy data on this pin.  
#define PIN_WRITE_GATE_MASK      B00000010  // The mask for the port
#define PIN_READ_DATA_MASK       B00000001  // The mask for the port

#define PIN_READ_DATA_PORT       PINB       // The port the above pin is on
#define PIN_WRITE_GATE_PORT      PINB

void setup() {
    // Disable all interrupts - we dont want them!
    Serial.begin(9600);
    cli();
    TIMSK0=0;
    TIMSK1=0;
    TIMSK2=0;
    PCICR = 0;
    PCIFR = 0;
    PCMSK0 = 0;
    PCMSK2 = 0;
    PCMSK1 = 0;
    EIMSK&=~B00000011;  // disable INT0/1 interrupt mask

    TCCR1A = 0;
    TCCR1B = bit(CS10); // Capture from pin 8, falling edge. falling edge input capture, prescaler 1, no output compare
    TCCR1C = 0;
	
    pinMode(PIN_READ_DATA, INPUT_PULLUP);
    pinMode(PIN_WRITE_GATE, INPUT_PULLUP);
    pinMode(10,OUTPUT);
    pinMode(11,OUTPUT);
    pinMode(12,OUTPUT);

    // Use timer 0 to count the correct number of ms
    TCCR0A = 0;         // Simple counter
    TCCR0B = bit(CS00);  // No prescaler, ticks = 62.5uSec
    TCCR0A = bit(WGM01);
    TCNT0 = 0;             // Reset counter; 
    OCR0A = 31;   
    OCR0B = 0;     // default timing window
    pinMode(13,OUTPUT); 
    DDRD = B11111111;
}

void loop() {   
	PORTB &= ~B1100;
    while (PIN_WRITE_GATE_PORT&PIN_WRITE_GATE_MASK) {};
    PORTB |= B1000;  
    
    while (!(PIN_WRITE_GATE_PORT&PIN_WRITE_GATE_MASK)) {
        uint8_t data = 1;
        // Wait for first pulse to sync with - this is the LSB of the first WORD and it's discarded as a SYNC clock
        TIFR1|=bit(ICF1);
        while (!(TIFR1 & bit(ICF1))) {};
        TIFR1|=bit(ICF1);
        TCNT0=0;
        for (uint8_t b=0; b<7; b++) {
            data <<= 1;
            // read a byte
            // Wait a maximum of 2us
            TIFR0 |= bit(OCF0A);
            // PORTB |= B0100;
            while (!(TIFR0 & bit(OCF0A))) {
                // Was a pulse detected?
                if (TIFR1 & bit(ICF1)) {
                    TIFR1|=bit(ICF1);
                    data |= 1;
                    TCNT0=1;  // reset maximum timeout for SYNC
                    break;
                }
            }  
        } 
        PORTD = data;
    }
}    


