

void TransmitByteSlow(unsigned char val) {

    unsigned char mask = 0x80;

    for (int i = 0; i<8; i++) {

        if (val & mask) {

            //Transmit 1

            IRQ = 0;

            __delay_us(20); //Wait 10 micro seconds for interrupt to trigger (approx. 10 cycles)

            IRQ = 1;

            __delay_us(200); //Wait 2000 micro seconds for interrupt to finish it's job (approx. 200 cycles)



        } else {

            //Transmit 0

            NMI = 0;

            __delay_us(20); //Wait 10 micro seconds for interrupt to trigger (approx. 10 cycles)

            NMI = 1;

            __delay_us(200); //Wait 2000 micro seconds for interrupt to finish it's job (approx. 200 cycles)



        }

        mask = mask>>1;

    }

}



void TransmitByteFast(unsigned char val) {

    unsigned char mask = 0x80;

    for (int i = 0; i<8; i++) {

        if (val & mask) {

            //Transmit 1

            IRQ = 0;

            __delay_us(20); //Wait 10 micro seconds for interrupt to trigger (approx. 10 cycles)

            IRQ = 1;

            __delay_us(100); //Wait 1000 micro seconds for interrupt to finish it's job (approx. 100 cycles)



        } else {

            //Transmit 0

            NMI = 0;

            __delay_us(20); //Wait 10 micro seconds for interrupt to trigger (approx. 10 cycles)

            NMI = 1;

            __delay_us(100); //Wait 2000 micro seconds for interrupt to finish it's job (approx. 100 cycles)

        }

        mask = mask>>1;

    }



}



void SignalContinue() {

    SO = 0; //We should wait at least 3 6502 cycles or 24 pic cycles... 6 pic instructions.

    #asm

    NOP;

    NOP;

    NOP;

    NOP;

    NOP;

    NOP;

    NOP;

    NOP;

    NOP;

    #endasm

    SO = 1;

    __delay_us(1000); //Wait

}



void TransferSidFileAndPlayNew(unsigned char * sid, int length) {

    USARTWriteLine("IRQ hacking starts...");

    // This part is timing critical so interrupts should be disabled.

    RCIE=0;

    PEIE=0;

    Reset6502();



    __delay_us(2000);



    /* Transfer addresses */

    TransmitByteSlow(0x00); //Low byte for player

    TransmitByteSlow(0xFC); //High byte for player

    TransmitByteSlow(0x00); //Low byte for sid

    TransmitByteSlow(0x10); //High byte for sid



    SignalContinue(); //Go to player transfer state



    /* Transfer player */

    for (int i = 0;i<256;i++) {

        TransmitByteSlow(Player[i]);

    }



    SignalContinue(); //Go to sid transfer state



    /* Transfer sid */

    for (int i = 0;i<length;i++) {

        TransmitByteFast(sid[0x7E + i]);

    }



    SignalContinue(); // Jump to player on 6502 side



    RCIE=1;

    PEIE=1;

    USARTWriteLine("IRQ hacking ends...");

}