Banner publicitario de PCBWay

Arduino, cambio de dirección output/input sin romper nada

¡Hola! :)

soy nuevo en el foro. Mis conocimientos de electrónica son muy elementales, he estado probando algunas cosas con Arduino y han funcionado bien, pero quisiera consultar una cosa para no romper nada.

Tengo un Arduino conectado al puerto usuario de un Commodore 64. Hay 8 pines de Arduino configurados como output, conectados a respectivos 8 pines del C64 configurados como input (por defecto, cuando el C64 se enciende, estos pines están como input). Hasta ahora ha funcionado todo sin problemas. También he puesto alguna conexión al revés: Arduino input, C64 output y también funciona. Ahora bien, estas configuraciones las he probado “fijas”, es decir, desde que enciendo Arduino y el C64, están con esos input y outputs y no cambian.

Ahora quisiera que durante la ejecución del programa, algunas de esas líneas cambien de sentido. Por ejemplo, un pin de Arduino que estuviera como output, ponerlo como input, y el correspondiente pin del C64, pasarlo de input a output.

Mi pregunta es, ¿en qué orden debo hacer el cambio para no quemar nada? Me imagino que en algún momento de transición, si ambos están como input, no pasará nada, pero si ambos están como output, aunque sea durante unos instantes, se podría romper algo. ¿Antes de cambiar de input a output o viceversa, conviene que ponga el pin en LOW, o esto da igual?

Creo que alguna vez hice por error una conexión output – output y no pasó nada, pero prefiero no arriesgarme.

Esto que pregunto, ¿es aplicable a conexiones en general entre dos mictrocontroladores?

Espero haberme explicado... Soy principiante y quizá me falle la terminología.

¡Muchas gracias! :)
 
bienvenido al foro.
Necesitaría que te explayes un poco mas para poder entrar en contexto, ya que no se si queres establecer algun tipo de comunicacion o que cosa. Ese puerto no solo podes emplearlo como un puerto paralelo, sino que tambien admite comunicacion RS232 por software, entre otras cosas mas... Quizas, si nos comentas un poco que estas queriendo hacer, no resulte util esa consigna para recomendarte algo "practico y seguro"
 
Creo que alguna vez hice por error una conexión output – output y no pasó nada, pero prefiero no arriesgarme.

Esto que pregunto, ¿es aplicable a conexiones en general entre dos mictrocontroladores?
La respuesta es..."depende", pero para hacerlo de forma segura, sobre todo si los cambios don frecuentes, lo mejor es colocar ambos puertos como entradas y luego conmutar uno de ellos al estado I/O correcto.
Por supuesto que el "depende" se refiere a la configuración del hardware, pero no es muy normal estar cambiando de modo I/O todo el tiempo a menos que haya algun mecanismo de sincronización entre ambos extremos.
 
Muchas gracias a ambos por las respuestas!

Intento explicar mejor el contexto. Esto es para un proyecto que empecé hace unos años y viene funcionado bien. Se trata de conectar un teclado MIDI a Arduino y Arduino al Commodore 64, para tocar el C 64 como si fuera un instrumento.
Aquí está la página con todos los detalles de hardware y software (por ahora en inglés, pero hoy en día se traduce fácilmente)


Uso los 8 pins del puerto paralelo del C64. Hasta ahora había usado 7 de esos pins (PB0 - PB6) para que Arduino transmita datos y mande la señal "handshake" al C64, y un 1 pin (PB7), al revés, para que el C64 envíe la señal handshake a Arduino. Hasta ahí todo bien. Hace poco he aprendido a usar otros dos pines que no son del puerto serie para que Arduino y C64 hagan el handshake. Quedan entonces libres los 8 pines del puerto paralelo para datos (estos dos nuevos pines son el PA2, que funciona como cualquiera de los PB0 - 7, y uno que llaman FLAG2, que permite a C64 reconocer una bajada de 5 a 0; los dos me funcionan bien, pero creo que no son relevantes para lo que quiero hacer ahora).

En la versión más reciente (sin actualizar en la página), Arduino usa los 8 pines del paralelo para transmitir al C64, es decir, son todos output en Arduino, y todos input para el C64. Todo esto, mientras Arduino lee las notas MIDI y las pasa al C64.

Pero quisiera hacer una cosa más, y es que el C64, en alguna "pausa", es decir, desactivando la lectura de MIDI en Arduino, le pase algunos datos a Arduino en la otra dirección. No es algo para hacerlo continuamente, sino sólo cuando el usuario deja de tocar y pasa a un "modo edición". (Me sirve el dato de que no es normal estar cambiando continuamente I/O, ¿es por algún peligro de quemar algo?)

En resumen, quisiera poder hacer ese cambio de dirección en los cables que van del puerto paralelo del C64 al Arduino, sin romper nada en el intento. Muchas gracias! :)

(Edito: ¿serviría de algo poner resistencias "preventivas" entre cada par de pines?)
 
Perdón, no sé qué he tocado, que me sale siempre este cuadro de texto
Si quisiste adjuntar algo, no se ve. Mira mi firma, que tengo los enlaces para saber cómo subir archivos...

Yo optaría como dice el Doc, todos entradas y esperando datos, hasta que uno de los dos se configure como salida.


Si tienes forma previa de comunicar entre si, yo te diría que hagas a uno maestro y el otro esclavo, entonces cuando necesitas cambiar el tipo de datos, el maestro le dice al esclavo cómo operar.

También sería bueno el tema de resistencias, Pero como puedes controlar ambos, no debería ser necesarias, eso sí, quizás a modo de pullup o pulldown, según requiera la conexión....
 
Me sirve el dato de que no es normal estar cambiando continuamente I/O, ¿es por algún peligro de quemar algo?
Los componentes digitales "generalmente" no se queman por hacer cortocircuito entre salidas, pero pueden alterarse sus niveles lógicos y dañarse a la larga.
El principal problema con los cambios de función E/S entre dispositivos es que si no hay una sincronización correcta vas a terminar leyendo/escribiendo cualquier verdura. Y esas fallas son difíciles de detectar si no tenes conocimientos ni instrumental adecuado.
 
Muchas gracias a ambos por las respuestas!

Intento explicar mejor el contexto. Esto es para un proyecto que empecé hace unos años y viene funcionado bien. Se trata de conectar un teclado MIDI a Arduino y Arduino al Commodore 64, para tocar el C 64 como si fuera un instrumento.
Aquí está la página con todos los detalles de hardware y software (por ahora en inglés, pero hoy en día se traduce fácilmente)


Uso los 8 pins del puerto paralelo del C64. Hasta ahora había usado 7 de esos pins (PB0 - PB6) para que Arduino transmita datos y mande la señal "handshake" al C64, y un 1 pin (PB7), al revés, para que el C64 envíe la señal handshake a Arduino. Hasta ahí todo bien. Hace poco he aprendido a usar otros dos pines que no son del puerto serie para que Arduino y C64 hagan el handshake. Quedan entonces libres los 8 pines del puerto paralelo para datos (estos dos nuevos pines son el PA2, que funciona como cualquiera de los PB0 - 7, y uno que llaman FLAG2, que permite a C64 reconocer una bajada de 5 a 0; los dos me funcionan bien, pero creo que no son relevantes para lo que quiero hacer ahora).

En la versión más reciente (sin actualizar en la página), Arduino usa los 8 pines del paralelo para transmitir al C64, es decir, son todos output en Arduino, y todos input para el C64. Todo esto, mientras Arduino lee las notas MIDI y las pasa al C64.

Pero quisiera hacer una cosa más, y es que el C64, en alguna "pausa", es decir, desactivando la lectura de MIDI en Arduino, le pase algunos datos a Arduino en la otra dirección. No es algo para hacerlo continuamente, sino sólo cuando el usuario deja de tocar y pasa a un "modo edición". (Me sirve el dato de que no es normal estar cambiando continuamente I/O, ¿es por algún peligro de quemar algo?)

En resumen, quisiera poder hacer ese cambio de dirección en los cables que van del puerto paralelo del C64 al Arduino, sin romper nada en el intento. Muchas gracias! :)

(Edito: ¿serviría de algo poner resistencias "preventivas" entre cada par de pines?)
Para, me tome un rato para pegarle bien un vistazo a lapagina que citas y la verdad, no entiendo por que queres hacer que el mismo puerto trabaje como entrada y salida :unsure: ... Al implementar el User Port de la Comodore64 para recibir datos MIDI del Arduino a través de una conexión paralela de 8 bits, no necesitas que los pines actúen como entrada y salida simultáneamente.
El Arduino envía datos, o sea, sus puertos trabajan en cnofiguracion de salida, mientra que los puertos de la retroCOMPU, sus puertos se comportan como entrada y reciben el paquete... Es mas, el programa que cita de la C64, los puertos estan configurados como entrada.... No tengo la bola de cristal... lo lei en el sketch que compartio el autor en su pagina:

CSS:
//08.01.2026

int X = 0;
int X_original = 0;   
int X_original_2 = 0;
int CO = 1;   // Antes era CO = 0;
int TocaSuelta = 0;                    //Estamos usando X para dos cosas diferentes, no da problemas de casualidad. Usar TocaSuelta en lugar de X en los lugares que se indican más abajo.
int voz[4];   // Array 0 - 3
int edad[4];  // Array 0 - 3       

//int modoActual = 1;        //PARECE que NO SE ESTà USANDO en ningún sitio.
int modoso[6];                //02.07.2021 Array 0 - 6, vamos a usar 1 - 6.   
//modoso[1] = 1;            //02.07.2021 Darle valor a un elemento del array no se puede poner aquÃ, tiene que ir en Setup.

int intervalo;
int maximo;
int minimo;
int sustituida;
int pordebajo;             //No se está usando en ningún sitio.   
int Sub = 1;                        //El valor inicial podrÃa ser 0, da igual.
int SubPin = 0;         //El valor inicial podrÃa ser 1, da igual.   
int xx = 0;             //No se está usando en ningún sitio.   
int top = 0;           
int split = 0;          //Esto se usa solo en combinación con NewTest, que actualmente no se llama desde ningún sitio.
int enladerecha = 0;   

int corte = 0;                  //09.08.2018 SerÃa más claro llamaro puntocorte.
int cortepulsado_1 = 0;       //09.08.2018 Para que corte de inmediato la lectura de la pulsación una vez que se ha pulsado.
int cortepulsado_2 = 0;       //02.07.2021
int cortepulsado_3 = 0;       //02.07.2021
int corteinvertido = 0;            //03.09.2018 Para determinar si las mitades del teclado se invierten (1) o no (0, como hasta ahora).

int MitadDelTeclado = 0;
int SwitchTeclado = 0;
int Modo = 0;
int Gate = 0;                //06.03.2023 Parece que no se usa, sólo aparece en un solo sitio, y al cuete.

int CuentaLeds = 0;        //30.06.2021
// Las siguientes variables son unsigned long porque el tiempo, medido en milisegundos,
// enseguida se vuelve un número enorme que no cabe en un int.
unsigned long lastDebounce_1 = 0;              // 02.07.2021                26.09.2023    Vuelta a los push buttons
unsigned long lastDebounce_2 = 0;              // 02.07.2021                26.09.2023    Vuelta a los push buttons
unsigned long lastDebounce_3 = 0;              // 02.07.2021                26.09.2023    Vuelta a los push buttons
unsigned long debounceDelay = 500;        // the debounce time; increase if the output flickers

unsigned long previousMillis = 0;          // will store last time LED was updated                // Nuevo 06.03.2023
unsigned long currentMillis;                    // Se usa en previousMillis = currentMillis;     // Nuevo 06.03.2023
const long intervalito = 250;                  // interval at which to blink (milliseconds)    // Nuevo 06.03.2023
unsigned long previousMillis2 = 0;      // will store last time se tocó un CC, que puede ser una ruedita        // Nuevo 15.09.2023
unsigned long currentMillis2;                    // Se usa en previousMillis = currentMillis;                                                  // Nuevo 15.09.2023
int DefineSplit = 0;                                    // Nuevo 16.09.2023 Para determinar el punto de corte del teclado simplemente tocando una tecla.
int CambiaModo = 0;                                        // Nuevo 26.09.2023
int InvierteTeclado = 0;                            // Nuevo 26.09.2023

// Sección MIDI
// Mira aquel vÃdeo, en particular 5:30 (Video_muy_util.txt)
int noteON = 144;             //144 = 10010000 Note on command             //Los bits 0 - 3 indican el canal, 0 = canal 1
int noteOFF = 128;            //128 = 10000000 Note off command         //Los bits 4 - 6 indican de qué tipo de datos se trata. El bit 7 = 1 indica que se trata del inicio del paquete.
int ControlChange = 176;     //176 = 10110000 Continuous controller, aka, Control Change    //+++ Nuevo 09.03.2022

int CCmode = 97;
int CCsplit = 96;
int CCswap = 66;
int AsignarCC = 0;                // Nuevo 06.03.2023
int Parpadeo = 0;                    // Nuevo 06.03.2023

byte commandByte;                      // 1er byte, ya sean noteON, noteOFF o CC

byte noteByte;                            // 2do byte
// byte velocityByte;             // 3er byte     Lo leÃa del buffer, pero nunca lo habÃamos usado hasta soluciones
byte esperandoVelocity;            // Flag de espera del 3er byte        Soluciones

byte ccByte;                                // 2do byte                                            Soluciones
// byte ccValue;                 // 3er byte                                            Soluciones
byte esperandoCCvalue;            // Flag de espera del 3er byte        Soluciones

byte status;                                //                                                                 Soluciones
bool mensajeListo = false;    //                                                                 Soluciones

byte puffer;
byte ccBytePrevio = 0;        // Nuevo 16.09.2023    Sólo se usa en la reasignación de controles, para que limitar el recorrido continuo de las rueditas.
                                                     // Soluciones (05.01.2026) Lo correcto, para evitar confusiones, será llamar a esto ccBytePrevio, porque se trata
                                                     // de reasignar CCs, no tiene nada que ver con números de notas.
                                                     // OJO 05.01.2026 Antes tenÃa el pésimo nombre de noteBytePrevio, pero esto sólo se usa con CCs.
// Fin sección MIDI

void setup() {
  pinMode(2, OUTPUT);     //pin 1 C64
  pinMode(3, OUTPUT);     //pin 2 C64
  pinMode(4, OUTPUT);     //pin 4 C64
  pinMode(5, OUTPUT);     //pin 8 C64
  pinMode(6, OUTPUT);     //pin 16 C64
  pinMode(7, OUTPUT);     //pin 32 C64
  pinMode(8, OUTPUT);     //pin 64 C64
  pinMode(9, INPUT);      //pin 128 C64

  // ***** Pines para el 9veno bit del C64, el dÃa que haga falta *********************************
  // pinMode(12, INPUT);        //Nuevo pin para el user port PA2, 26.03.2023 Probado durante meses, funka.
  // pinMode(13, OUTPUT);        //Nuevo pin para el user port PA2, 26.03.2023 Probado durante meses, funka.

  // ***** Pines para los PUSH BUTTON, pensando en controladores MIDI que no tendrán botones.
  pinMode(12, INPUT);   //BLANCO Para seleccionar modo, con/sin teclado partido SIN acordes.                        // Cambiar a PIN 12
  pinMode(11, INPUT);     //MARRÓN Para desplazar el punto de corte del teclado (09.08.2018)                            // Cambiar a PIN 11
  pinMode(10, INPUT);     //AZUL Para invertir la partición del teclado. 03.09.2018        ANTES era el 13.

 
  pinMode(A1, OUTPUT);    //CuentaLeds 30.06.2021
  pinMode(A2, OUTPUT);    //CuentaLeds 30.06.2021
  pinMode(A3, OUTPUT);    //CuentaLeds 30.06.2021

  // Sección MIDI
  //Serial.begin(9600);
  Serial.begin(31250);  //MIDI baud rate. Los pins 0 y 1 son por defecto serial receive y serial transfer, respectivamente.
                        //No hace falta definirlos como INPUT o OUTPUT.
  // Fin sección MIDI

  digitalWrite(A3, HIGH);    //Modo 1 por defecto 03.07.2021
  //CuentaLeds = 1;                //03.07.2021
  modoso[0] = 1;                    //02.07.2021 modoso[0] es el modo actual (1 - 6), y sirve también para contar los LEDs.
  modoso[1] = 3;                    //Luego se queda como estaba (en realidad no hay luego, porque en el segundo bloque entra solo si Modo > 3)
  modoso[2] = 9;                    //Luego puede ser 11
  modoso[3] = 7;                    //Luego puede ser 1
  modoso[4] = 9;                    //Luego puede ser 1
  modoso[5] = 7;                     //Luego puede ser 11
  modoso[6] = 13;                    //Luego se queda como estaba

  digitalWrite(8, LOW);        //Aunque en teorÃa los pin output están por defecto como LOW, conviene por si las moscas explicitarlo.

}

void loop() {

        if (digitalRead(11) == HIGH && cortepulsado_1 == 0 && (millis() - lastDebounce_1) > debounceDelay)        // Cambiar a PIN 11
    {
      DefineSplit = 1;                        // Nuevo 26.09.2023
      cortepulsado_1 = 1;
      lastDebounce_1 = millis();
    }
    else if (digitalRead(11) == LOW && cortepulsado_1 == 1)                                                                                                // Cambiar a PIN 11
    {cortepulsado_1 = 0;}
    //----------------------------------------------------------------------

        if (digitalRead(12) == HIGH && cortepulsado_2 == 0 && (millis() - lastDebounce_2) > debounceDelay)        // Cambiar a PIN 12
    {
      CambiaModo = 1;                            // Nuevo 26.09.2023
      cortepulsado_2 = 1;
      lastDebounce_2 = millis();
    }
    else if (digitalRead(12) == LOW && cortepulsado_2 == 1)                                                                                                // Cambiar a PIN 12
    {cortepulsado_2 = 0;}
    //----------------------------------------------------------------------
    
    if (digitalRead(10) == HIGH && cortepulsado_3 == 0 && (millis() - lastDebounce_3) > debounceDelay)             // ANTES era el 13
    {
        InvierteTeclado = 1;                // Nuevo 26.09.2023
      cortepulsado_3 = 1;
      lastDebounce_3 = millis();
    }
    else if (digitalRead(10) == LOW && cortepulsado_3 == 1)                                                                                                    // ANTES era el 13
    {cortepulsado_3 = 0;}
    //----------------------------------------------------------------------

    if (CambiaModo == 1)
    {
           modoso[0] = modoso[0] + 1;
            if (modoso[0] > 6){modoso[0] = 1;}
            digitalWrite(A3, LOW);
            digitalWrite(A2, LOW);
            digitalWrite(A1, LOW);
            if (modoso[0] & 1){digitalWrite(A3, HIGH);}
            if (modoso[0] & 2){digitalWrite(A2, HIGH);}
            if (modoso[0] & 4){digitalWrite(A1, HIGH);}
           CambiaModo = 0;
    }

    if (InvierteTeclado == 1)
    {
        if (SwitchTeclado == 1){SwitchTeclado = 0;}
      else if (SwitchTeclado == 0){SwitchTeclado = 1;}        // 06.03.23 Esto se puede simplificar más, obviamente.
        InvierteTeclado = 0;
    }


    // ***** Pines para el 9veno bit del C64, el dÃa que haga falta *********************************
    // if (digitalRead(12) == HIGH) {            //Nuevo pin para el user port PA2, 26.03.2023 Probado durante meses, funka.
    //         digitalWrite(13, HIGH);}                //Nuevo pin para el user port PA2, 26.03.2023 Probado durante meses, funka.
    // else {digitalWrite(13, LOW);}            //Nuevo pin para el user port PA2, 26.03.2023 Probado durante meses, funka.

    // ***** Este bloque se usa solo en combinación con NewTest, que actualmente no se llama desde ningún sitio. ********
    // top = 0;                         
  // for (int n = 1; n < 4; n++){     
  //     if (voz[n] > top){       
  //       top = voz[n];
  //       split = top - 5;}
  // }                       
  // ***** //Fin del bloque que se usa solo en combinación con NewTest. ***************************


    if (CO == 0 && digitalRead(9) == HIGH) {

        X = -1;        // Servirá para ver si no se ha cumplido ninguna de las condiciones. Se verÃa más limpio e inteligible con Switch Case.
      
      switch (Modo) {

        case 1:
               X = Modo;                      // Va a tocar una nota del acorde por la voz 1.                // Antes X = 1, ahora X = 4         // 0000 0100
                  voz[1] = noteByte;     // Si el bit 5 = 1 (32) indica que la voz 3 se va a acoplar a la 1 para modularla, pero esto lo hace en el C64.
                  break;
        
         case 0:
                  X = Modo;                      // Va a soltar una nota del acorde por la voz 1.            // Antes X = 0, ahora X = 0
                 voz[1] = 0;                 // Ãdem con el bit 5
                 break;
        
         case 3:                                                                                                         // Ésta es la variante más "polifónica" con 2 o 3 notas independientes (o 1 sola, llegado el caso, revisar).
                  if (voz[1] == 0) {             X = 3;    voz[1] = noteByte; }        // En OldFunka, para probar voz[1] como sustituible, se pone la única condición de que Modo == 3.
                 else if (voz[2] == 0) { X = 5;    voz[2] = noteByte; }
                 else if (voz[3] == 0) { X = 7;     voz[3] = noteByte; }
                 else {OldFunka(); }
                 break;
                 // Antes X = 3, ahora X = 5         // 0000 0101
                 // Antes X = 5, ahora X = 6         // 0000 0110
                 // Antes X = 7, ahora X = 7         // 0000 0111

         case 2:
                  if (voz[1] == noteByte) {                X = 2; voz[1] = 0;}         // Antes X = 2, ahora X = 1         // 0000 0001
                 else if (voz[2] == noteByte) {     X = 4; voz[2] = 0;}         // Antes X = 4, ahora X = 2         // 0000 0010
                 else if (voz[3] == noteByte) {     X = 6; voz[3] = 0;}         // Antes X = 6, ahora X = 3         // 0000 0011
                 break;
        
         case 5:
                 X = 5;                            // El último modo (el más complicado). Sólo la voz[2] está disponible para tocar en una mitad del teclado. En la otra está la voz[1] como acordes
                 voz[2] = noteByte;     // y la voz[3] acoplada modulándola. Funciona, pero no es muy interesante y hace un ruido raro (11.09.2018). No está implementado, no? (01.11.2024)
                 break;
                 // Antes X = 5, ahora X = 6         // 0000 0110

         case 4:
                 if (voz[2] == noteByte) {             X = 4; voz[2] = 0; }
                 break;
                 // Antes X = 4, ahora X = 2         // 0000 0010
                                    
         case 7:                                                                                                                     // voz[2] y voz[3] son independientes en una mitad, en la otra mitad puede haber acordes o la voz[1] independiente,
                  if (voz[2] == 0) {                             X = 5; voz[2] = noteByte; }        // pero separada en su mitad. Este último modo es uno de los que nos faltaba. No lo he probado todavÃa (11.09.2018).
                 else if (voz[3] == 0) {                 X = 7; voz[3] = noteByte; }
                 else { OldFunka(); }
                 break;
                 // Antes X = 5, ahora X = 6         // 0000 0110
                 // Antes X = 7, ahora X = 7         // 0000 0111

         case 6:
                 if (voz[2] == noteByte) {             X = 4; voz[2] = 0; }
              else if (voz[3] == noteByte) {     X = 6; voz[3] = 0; }
              break;
              // Antes X = 4, ahora X = 2         // 0000 0010
                 // Antes X = 6, ahora X = 3         // 0000 0011
        
        case 9:
              X = 7;                                // El modo clásico que tenÃamos hasta ahora con el Suboscilador 2 modulando al 3. Más abajo, el envÃo de 2 paquetes
                 voz[3] = noteByte;        // se identificará por el Modo == 9 || Modo == 8.
                 voz[2] = noteByte;
                 break;
                 // Antes X = 7, ahora X = 7         // 0000 0111   
        
         case 8:                                                                             // No habÃa comentarios sobre esto, ni hace nada cuando no se cumple la condición.
                 if (voz[3] == noteByte) { X = 6;
                                                                     voz[3] = 0;         // Está puesto el 3 antes que el 2 (también en case 9) para acordarnos de que el osc 2 modula al 3. // 05.03.2023
                                                                     voz[2] = 0; }     // Obviamente, a efectos de ejecución da exactamente igual.
                 break;
                // Antes X = 6, ahora X = 3         // 0000 0011

         case 11:
                  X = 3;                                // 1 sola nota voz[1] en una mitad, 2 notas acopladas voz[2] y voz[3] en la otra mitad. El más sencillo de los dos modos nuevos.
                 voz[1] = noteByte;
                 break;
                // Antes X = 3, ahora X = 5         // 0000 0101

         case 10:                                                                             // No habÃa comentarios sobre esto, ni hace nada cuando no se cumple la condición.
                 if (voz[1] == noteByte) { X = 2; voz[1] = 0; }
                  break;

         case 13:
                 X = 7;                                // Las 3 voces acopladas.
                 voz[1] = noteByte;
                 voz[2] = noteByte;
                 voz[3] = noteByte;
                 break;
                 // Antes X = 7, ahora X = 7         // 0000 0101

         case 12:
                 if (voz[1] == noteByte) { X = 6;
                                                                       voz[1] = 0;
                                                                       voz[2] = 0;
                                                                       voz[3] = 0; }
                 break;
                 // Antes X = 6, ahora X = 3         // 0000 0101
 
       }    // Fin de Switch(Modo)

      if (X > -1)       
        { X_original = X;         // X puede entrar siendo 1, 0, 3, 2, 5, 4, 7 o 6. CREO (revisar) que esto le vale al C64 como voz 1 con pseudoacordes, voz 1 normal, voz 2 o voz 3.
          X_original_2 = X;        // SÃ, hacen falta dos X_original, porque puede entrar en el segundo bloque de modos,
                                                            // en el tercero, o en ambos. Lo que habrÃa que hacer es buscar un método más limpio.

            HighLow();                    // EnvÃa el primer paquete. 
            digitalWrite(8, HIGH);
            do{} while (digitalRead(9) == HIGH);        // Oremos 3... 01.03.2023     Se mostró algo inestable, pero parecen las ofensas habituales ante la novedad.

            X = noteByte - 36;
            HighLow();              // EnvÃa el segundo paquete.
            digitalWrite(8, LOW);
            do{} while (digitalRead(9) == LOW);   

            
            if (Modo == 9 || Modo == 8 || Modo == 13 || Modo == 12)        // ***** OSC 2 acoplado a OSC 3    *****, o también los tres OSC acoplados entre sÃ.
              {    X = X_original - 2;                // X viene de ser 6 o 7 y se queda en 4 o 5.
                   HighLow();                       // EnvÃa el primer paquete. 
                   digitalWrite(8, HIGH);
                   do{} while (digitalRead(9) == HIGH);        // Oremos 1... 01.03.2023

                   X = noteByte - 36; 
                HighLow();                 // EnvÃa el segundo paquete.
                digitalWrite(8, LOW);
                do{} while (digitalRead(9) == LOW);            // Lo movemos dentro del corchete. 02.03.2023
                }
            

            if (Modo == 13 || Modo == 12)   // ***** Los tres OSC acoplados entre sà *****
              {    X = X_original_2 - 4;               // X viene de ser 6 o 7 y se queda en 2 o 3.
                   HighLow();                        // EnvÃa el primer paquete. 
                   digitalWrite(8, HIGH);
                   do{} while (digitalRead(9) == HIGH);        // Oremos 2... 01.03.2023

                X = noteByte - 36; 
                HighLow();                  // EnvÃa el segundo paquete.
                digitalWrite(8, LOW);
                do{} while (digitalRead(9) == LOW);            // Agregado por una cuestión de orden. 01.03.2023     Al principio se ofendió, pero funcionó.
                }
            
            CO = 1;

            if (DefineSplit == 1 && (Modo % 2) == 0) {                // Nuevo 16.09.2023 Para determinar el punto de corte del teclado simplemente tocando una tecla.
                            corte = noteByte - 60;                                                    // Nuevo 16.09.2023 Por qué tiene que ser - 60 no está claro, algún dÃa habrá que desbrozar estas cuentas.
                            DefineSplit = 0;}                                                                // Nuevo 16.09.2023 Con (Modo % 2) se asegura de que sólo entre si se ha soltado la tecla.

        }   // FIN de if (X > -1)
    }            // FIN de if (CO == 0 && digitalRead(9) == HIGH) 


    // Fundamental para la vida. Aquà lee las notas del teclado MIDI cuando el bit 7 (128, pin 9) de 56577 indica que el C64 ha terminado de procesar.
    // if (digitalRead(9) == HIGH  && Serial.available() > 2) {LecturaMIDI();}         // ###
    if (digitalRead(9) == HIGH) {LecturaMIDI();}                                                                     // ### 🔴🔴🔴 Buena recomendación de soluciones.

    if (AsignarCC > 0) {                                     // PARPADEOS
            currentMillis = millis();
            if (currentMillis - previousMillis >= intervalito) {
                previousMillis = currentMillis;            // save the last time you blinked the LED
                    if (Parpadeo == 1) {
                            if (AsignarCC & 1){digitalWrite(A3, HIGH);} // else { digitalWrite(A3, LOW);}         // digitalWrite(A3, LOW);
                            if (AsignarCC & 2){digitalWrite(A2, HIGH);} // else { digitalWrite(A2, LOW);}            // digitalWrite(A2, LOW);
                            digitalWrite(A1, LOW);        // Por una cuestión de orden
                            Parpadeo = 0; }
                    else {
                            digitalWrite(A3, LOW);        // if (AsignarCC & 1){digitalWrite(A3, HIGH);}        // digitalWrite(A3, HIGH);
                            digitalWrite(A2, LOW);        // if (AsignarCC & 2){digitalWrite(A2, HIGH);}        // digitalWrite(A2, HIGH);
                            digitalWrite(A1, LOW);                            // digitalWrite(A1, HIGH);        //Ponemos este A1, LOW por una cuestión de orden.
                            Parpadeo = 1;
                    }
            } // Final de if (currentMillis - previousMillis >= intervalito)
    } // Final de if (AsignarCC > 0)

}    // Final de void loop()

void LecturaMIDI(){

    // ----- Lo que sigue es el código sugerido por soluciones 02.01.2026 --------------------------------
    while (Serial.available()) {

      byte b = Serial.read();

      // ###
      // 1) Realtime MIDI: ignorar sin tocar nada
            if (b >= 0xF8) {
              continue;
            }
            // 2) System Common / SysEx: ignorar y NO tocar running status
            if (b >= 0xF0) {
              // esperandoVelocity = false;        // 🔴🔴🔴 Soluciones recomienda aniadir esto,
            // esperandoCCvalue  = false;        // aunque funciona perfectamente sin esta parte,
            // status = 0;                                    // también con el Casio, y sigo fiel a la máxima "if it works don't repair it."
              continue;
            }
            // ###
      
      // STATUS BYTE
      if (b & 128) {                     // Examina si el bit 7 de b está = 1. Si lo está, es un byte de estado.
        status = b;                   // Es un byte de estado, como por ejemplo, noteON, noteOFF o CC.
        // Resetea flags de espera del segundo dato: como acaba de leer un byte de estado, lo que viene a continuación
        //                                                                                     es el primero de los bytes de datos.
        esperandoVelocity = false;
        esperandoCCvalue = false;
        continue;
      }

      // Filtra para aceptar solo noteON, noteOFF o CC.
      byte tipo = status & 240;
      if (tipo != noteON && tipo != noteOFF && tipo != ControlChange) {     
        continue; // ignorar TODO lo demás
      }

      // Procesa noteON / noteOFF
      if (tipo == noteON || tipo == noteOFF) {
                  
                  commandByte = tipo;         // Esto lo agrego yo, no soluciones. Lo estoy poniendo 2 veces y seguramente se pueda unificar.

                  if (!esperandoVelocity) {          // Si no está esperando la velocidad, entonces este byte es la nota.
                    noteByte = b;
                    esperandoVelocity = true;            // Esto por ahora solo se usa para que noteON && velocity sea noteOFF
                  } else {                                                 // pero en el futuro podrá servir para la dinámica de las notas.
                    byte velocity = b;            // Si está esperando la velocidad, entonces este byte es la velocidad.
                    esperandoVelocity = false;

                    // Note On con velocity 0 = Note Off
                    // byte comando = tipo;
                    if (tipo == noteON && velocity == 0) {
                      //comando = noteOFF;
                      commandByte = noteOFF;
                    }

                    // 🔴🔴🔴 MENSAJE COMPLETO 🔴🔴🔴
                mensajeListo = true;
                  }
                  // procesarNota(comando, note, velocity);    // procesarNota es lo que yo llamaba MIDImessage (está más abajo, sin capar en gris)
                 continue; // ignorar TODO lo demás    ESTO LO AGREGO YO, porque las notas se procesan en otro sitio,
            }
            // Procesa Control Change (CC)
            else if (tipo == ControlChange) {

                    commandByte = tipo;         // Esto lo agrego yo, no soluciones. Lo estoy poniendo 2 veces y seguramente se pueda unificar.

                    if (!esperandoCCvalue) {                 // No está esperando el 3er byte, entonces es que está esperando el 2do,
                        ccByte = b;                                        // que por ahora es el único que necesitamos.
                        esperandoCCvalue = true;
                    } else {                                               
                        byte ccValue = b;                            // Esta primera lÃnea por ahora no se usa
                        esperandoCCvalue = false;            // pero esta segunda lÃnea sà sirve para resetear el flag.

                        // 🔴🔴🔴 MENSAJE COMPLETO 🔴🔴🔴
            mensajeListo = true;

                        // procesarCC(ccByte, ccValue)
                    }
            }
    }
    // ----- Fin del código sugerido por soluciones -----------------------------------------------
 
  // 🔴🔴🔴 Al terminar el bloque while 🔴🔴🔴
  if (!mensajeListo) return;
    mensajeListo = false;


    // Ojo, pese a los experimentos hechos con puffer y arturia + korg, si en esta condición ponemos == 3 y tocamos
    // tres notas simultáneamente, sólo reconoce una y se queda colgado. Parece que va mejor con > 2. ¡Los pseudoacordes son más de 3!
    
    /* ANTIGUO NO soluciones
    commandByte = Serial.read();       //Lee byte 1
    noteByte = Serial.read();          //Lee byte 2            Ojo, tener enchufado el USB mientras tocas puede causar que todos los valores sean = 255.
    velocityByte = Serial.read();      //Lee byte final         En tal caso, desenchufar el USB y usar una baterÃa como alimentación.
    // Para commandByte == CC, el segundo byte NO es la nota, y el tercero NO es la velocidad, pero le dejamos esos nombres de todos modos.
    */

    if (AsignarCC > 0) {                                        // ***** Nuevo 06.03.2023 *****

            if (commandByte == ControlChange) {                       
                switch (AsignarCC) {
                case 3:
                    currentMillis2 = millis();                                                                            // Nuevo 15.09.2023        SÃ, tiene que venir aquÃ, dentro de Case 3. La primera cuenta el tiempo; las siguientes,
                    if (currentMillis2 - previousMillis2 >= (intervalito * 4)) {         // Nuevo 15.09.2023                                     las notas previamente pulsadas.
                        CCmode = ccByte;                        // CCmode = noteByte;
                        AsignarCC = 2;
                        ccBytePrevio = ccByte;}         // noteBytePrevio = noteByte;}
                    break;
                case 2:
                    if (ccByte != ccBytePrevio) {            // if (noteByte != noteBytePrevio) {   
                        CCsplit = ccByte;                                // CCsplit = noteByte;
                        AsignarCC = 1;
                        ccBytePrevio = ccByte;}                    // noteBytePrevio = noteByte;}
                    break;
                case 1:
                        if (ccByte != ccBytePrevio) {        // if (noteByte != noteBytePrevio) {
                        CCswap = ccByte;
                        AsignarCC = 0;
                        digitalWrite(A3, LOW);                            // Y devuelve las luces a la normalidad del modo.
                        digitalWrite(A2, LOW);
                        digitalWrite(A1, LOW);
                        if (modoso[0] & 1){digitalWrite(A3, HIGH);}
                        if (modoso[0] & 2){digitalWrite(A2, HIGH);}
                        if (modoso[0] & 4){digitalWrite(A1, HIGH);}        // Y devuelve las luces a la normalidad del modo.
                         }
                    break;
                } // Final de switch
            }        // Final de if (commandByte == ControlChange)
        return;        // 🔴🔴🔴 Soluciones quitarÃa esto, pero quitándolo se quedan notas colgadas por el camino.
    }    // Final de if (AsignarCC > 0)                            // ***** Nuevo 06.03.2023 *****

    //+++ Nuevo 09.03.2022
    if (commandByte == ControlChange) {

        // if (noteByte == CCmode){                                     // 97        65, botón B6, para probar si funka.
        if (ccByte == CCmode){                                                 // 97        65, botón B6, para probar si funka.
            CambiaModo = 1;
        }
        // else if (noteByte == CCsplit) {                        // 96
        else if (ccByte == CCsplit) {                                    // 96
            DefineSplit = 1;                                                                            // Nuevo 16.09.2023 Para determinar el punto de corte del teclado simplemente tocando una tecla.
        }
        // else if (noteByte == CCswap) {                                // 66
        else if (ccByte == CCswap) {                                        // 66
          InvierteTeclado = 1;
        }
        else {                                                                                // 06.03.23 Nuevo     Si se toca un control no asignado, inicia el proceso de asignación de los tres controles.
            AsignarCC = 3;
            digitalWrite(A3, LOW);                                             // Apaga el led 3, que es el bit 2, luego encenderá los led 2 y 1 (bits 1 y 0) en Parpadeos.
            previousMillis2 = millis();                                    // 16.09.2023
        }                                         // 06.03.23 Nuevo
        
        // 🔴🔴🔴 Soluciones quitarÃa la siguiente lÃnea, pero quitándola se quedan notas colgadas por el camino.
        return;     //https://www.arduino.cc/en/Reference.Return        // Al salir de aquÃ, CO deberÃa seguir siendo = 1.
    }    //+++ Nuevo 09.03.2022     Final if (commandByte == ControlChange

    //modoso[1] = 3        Luego se queda como estaba (en realidad no hay luego, porque en el segundo bloque entra solo si Modo > 3)
    //modoso[2] = 9        Luego puede ser 11
    //modoso[3] = 7        Luego puede ser 1
    //modoso[4] = 9        Luego puede ser 1
    //modoso[5] = 7        Luego puede ser 11
    //modoso[6] = 13    Luego se queda como estaba

    //09.03.2022 En ningún sitio verifica si commandByte == noteON. Procesa sin más el número de la tecla que se ha pulsado (noteByte) y el Modo que esté seleccionado.
    //Considera por defecto que es noteON. Después de procesar la nota y el Modo, si resulta que commandByte == noteOFF, le quita 1 al Modo, lo cual indica gate off.

    // Anda, aclara en algún comentario las diferencias entre Modo, modoso[] y X. Son diferentes y necesarios; modoActual parece que está al pedo.

    CO = 0;
    // modoActual = modoso[0];                    //modoActual es uno de los modos para el usuario, del 1 al 6. PARECE que NO SE ESTà USANDO en ningún sitio.
    Modo = modoso[modoso[0]];                     //Modo es uno de los modos en Arduino: 3, 9, 7, 9, 7, 13, que luego pueden cambiar (algunos) a 1 u 11.
        
        
    MitadDelTeclado = 0;            // También será 0 cuando NO haya que partir el teclado (Modo 1) pero lo ignorará.
                                                        // 0 -> pasa la nota a la mitad derecha, 1 -> pasa la nota a la mitad izquierda.
    if (Modo > 3) {
        
        if (noteByte < (60 + corte) && SwitchTeclado == 0) {MitadDelTeclado = 1; }
         else if (noteByte > (59 + corte) && SwitchTeclado == 1) {MitadDelTeclado = 1; }

         if (MitadDelTeclado == 1) {
            if (modoso[0] == 2){Modo = 11; }                // 2 - Viene de ser Modo = 9    Aquà hacen falta tres condiciones para diferenciarlo de 6.
            else if (modoso[0] == 3){Modo = 1; }        // 3 - Viene de ser Modo = 7
            else if (modoso[0] == 4){Modo = 1; }        // 4 - Viene de ser Modo = 9
            else if (modoso[0] == 5){Modo = 11; }        // 5 - Viene de ser Modo = 7    Nuevo, funka bien, pero nos faltan las tres posiciones.
        }
    }

    // En ninún sitio se asigna noteON al commandByte explÃcitamente. Se lo da por supuesto como noteON al leerlo del buffer.
    // if (commandByte == noteON)     {Gate = 1; }
    if (commandByte == noteOFF) {     
        Gate = 0;                                         
        Modo = Modo - 1;
    }
    
}

void HighLow(){
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  digitalWrite(7, LOW);

  if (X & 1){digitalWrite(2, HIGH);}
  if (X & 2){digitalWrite(3, HIGH);}
  if (X & 4){digitalWrite(4, HIGH);}
  if (X & 8){digitalWrite(5, HIGH);}
  if (X & 16){digitalWrite(6, HIGH);}
  if (X & 32){digitalWrite(7, HIGH);}
}

void OldFunka(){                                                                    //Función para sustituir una de las 3 notas tocadas, cuando se toca una cuarta.
  minimo = 100;  // 100, por poner algo menor que lo cual siempre habrá algo.

  if (Modo == 3)                                                                     // Y SI el Modo == 7 ? No hace falta. Esto viene del modo 3 o del 7. Si viene del 7, con esta lÃnea aseguramos que la voz 1 no se mancha.
  {intervalo = voz[1] - noteByte;                                  // abs(a++);   // avoid this - yields incorrect results.                                                                                                     
  minimo = abs(intervalo);
  sustituida = 1;}                                       
          
  intervalo = voz[2] - noteByte;
  intervalo = abs(intervalo);
  if (intervalo < minimo)
  {minimo = intervalo;
  sustituida = 2;}             
          
  intervalo = voz[3] - noteByte;
  intervalo = abs(intervalo);
  if (intervalo < minimo)
  {sustituida = 3;}                 

  voz[sustituida] = noteByte;
  X = (sustituida * 2) + 1;  //X = (sustituida * 16) + 1; ***
}

void NewTest(){                                                                         //Función para sustituir una de las 3 notas tocadas, cuando se toca una cuarta.

// Si ha entrado aquÃ, es porque están todos los canales ocupados.
// Lo primero es ver si la nota tocada está a la derecha del split.

  enladerecha = 0;
  for (int n = 1; n < 4; n++){     
    if (voz[n] > split){enladerecha = ++enladerecha;}
  }                               

  if (enladerecha > 1)
  {
    if (edad[3] > split){sustituida = edad[3];}
    else if (edad[2] > split){sustituida = edad[2];}
    else if (edad[1] > split){sustituida = edad[1];}

    if (voz[1] = sustituida){sustituida = 1;}
    else if(voz[2] = sustituida){sustituida =2;}
    else if(voz[3] = sustituida){sustituida =3;}

    voz[sustituida] = noteByte;
    X = (sustituida * 2) + 1;  //X = (sustituida * 16) + 1; ***
  }

  else    //Es decir, a la derecha del split hay como mucho una nota (o puede que ninguna).
  {
    OldFunka();
  }

}

//Send MIDI message. No hace falta para el C64, porque no se le envÃa MIDI, sino bits por los pins 2 - 7 (8 y 9).
void MIDImessage(int command, int MIDInote, int MIDIvelocity) {
  Serial.write(command);       //EnvÃa note on o note off command       
  Serial.write(MIDInote);      //EnvÃa pitch data                       
  Serial.write(MIDIvelocity);  //EnvÃa velocity data
}

O sea, pasando en limpio: Como la RetroCOMPU no entiende ni a palos MIDI, se implementa el arduino como puente / traductor y envia el colectivo de señales por medio de los pines D2/3/4/5/6/7/8 a la C64... la Comodore al terminar de reproducir el midi o lo que este haciendo con el midi, envia un mensaje por PA2, el arduino recibe el aviso en el pin D9 y manda la siguiente nota. No hay mucha magia... no necesitas hacer que el puerto trabaje como entreda y salida al mismo tiempo.
saludos
 
No hay mucha magia... no necesitas hacer que el puerto trabaje como entreda y salida al mismo tiempo.
Es que el pretende hacer algunas otras cosas mas allá del gateway MIDI que hacer Arduino. El antes había escrito:
Pero quisiera hacer una cosa más, y es que el C64, en alguna "pausa", es decir, desactivando la lectura de MIDI en Arduino, le pase algunos datos a Arduino en la otra dirección. No es algo para hacerlo continuamente, sino sólo cuando el usuario deja de tocar y pasa a un "modo edición".
 
Es que el pretende hacer algunas otras cosas mas allá del gateway MIDI que hacer Arduino. El antes había escrito:
entonces tiene que trabajar a nivel software agregando una señal mas desde el puerto de usuario para indicarle al arduino mediante una interrupcion por hardware (le sobran pines en el arduino) que no le mande nada por que esta en modo edicion.... Ahi use C64 PRG/BASIC converter para ver el programa de la C64

Código:
0 PRINTCHR$(14)"{CLEAR}       {R}EAD DATA? Y/N":B=0:AL=50152:BA=50164:CI=50000
1 BY=256:FT=1.0595:FI=262.39:CT=.000595:GOSUB7
2 GETA$:N=1-1*(A$="Y")-2*(A$="N"):ONNGOTO2,3,1000
3 PRINT"{DOWN}PAYPAL DONATIONS APPRECIATED":PRINT"A{CM @}---------------"
4 FORN=49152TO49971:READA:POKEN,A:PRINT"{HOME}"N:NEXT:GOSUB1500
5 FORN=51024TO51118:READA:POKEN,A:PRINT"{HOME}"N:NEXT
6 FORN=50040TO50116:READA:POKEN,A:PRINT"{HOME}"N:NEXT:GOTO1000
7 FQ=FI*(1+B*CT):FORN=.TO11:FQ=FQ*FT:HI=INT(FQ/BY):LO=FQ-(HI*BY)
8 POKEAL+N,HI:POKEBA+N,LO:PRINT"{HOME}"N"{LEFT} ":NEXT:RETURN
10 PRINT"{HOME}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}                                       {UP}"
11 GETA$:IFA$=""THEN11
12 A=ASC(A$):IFA>48THENIFA<52THENV=A-49:V7=V*7:PRINTVZ$(V):GOTO10
13 IFA=32THEN28
14 IFA>64ANDA<72THENA=A-64:ONAGOTO310,150,170,40,160,44,50
15 IFA>71ANDA<79THENA=A-71:ONAGOTO140,142,190,200,96,98,100
16 IFA=194THENBP=ABS(BP-1):GOSUB30
17 IFA=204THENLP=ABS(LP-1):GOSUB30
18 IFA=200THENHP=ABS(HP-1):GOSUB30
20 IFA>136THENIFA<140THENA=A-136:F(A)=F(A)+1+3*(F(A)=2):GOSUB30
21 IFA>132THENIFA<136THENA=A-129:GOTO60
23 PK=PEEK(51121+V7):IFA=17THENPK=PK+12*(PK>11):GOSUB38:GOTO10
24 IFA=145THENPK=PK-12*(PK<244):GOSUB38:GOTO10
25 IFA=157THENPK=PK+(PK>.):GOSUB38:GOTO10
26 IFA=29THENPK=PK-(PK<255):GOSUB38:GOTO10
27 GOTO11
28 SYS49152:GOTO10:REM SYS49815
30 POKE54295,16*RE-4*(F(3)>.)-2*(F(2)>.)-(F(1)>.):FORN=1TO3:POKE1615+N,F(N):NEXT
31 F1=-21*(F(1)=2):F2=7-14*(F(2)=2):F3=14-7*(F(3)=2)
32 POKE51104,F1:POKE51106,F1:POKE51108,F2:POKE51110,F3
33 POKE54296,15+16*LP+32*BP+64*HP
34 POKECR+585,14-7*LP:POKECR+587,14-7*BP:POKECR+589,14-7*HP:RETURN
38 PL(V7/7)=PK:POKE51121+V7,PK
39 PRINT"{HOME}{DOWN}"SPC(21+V7)"   {LEFT}{LEFT}{LEFT}{LEFT}"PK:RETURN
40 A=0:B=2:IC=496:AH=0:B8=V*8:GOTO106
44 A=0:B=0:IC=576:AH=3:B8=0:GOTO106
50 A=0:B=2:IC=616:AH=4:B8=V*8:GOTO107
60 F(A)=F(A)+1+5*(F(A)=4):POKE1260+A*7,F(A):GOSUB61:GOTO11
61 GL=F(A+3):IFF(A)=2THENGL=GL-1:GL=(GLOR255)ANDNOT(GLAND255)
62 POKE51092+A*7,GL:RETURN
96 INPUT"POKEA,B";A,B:POKEA,B:GOTO10
98 INPUT"V,F. TUNING";A,B
99 GOSUB7:GOSUB1502:PRINT"{HOME}   ":GOTO10
100 INPUT"GLIDE INTERVAL 1,2,3";F(7),F(8),F(9)
101 A=4:GOSUB61:A=5:GOSUB61:A=6:GOSUB61:GOTO10
106 PRINT"GO-MI-MX-DIR-LOP"
107 PP=0:POKECR+IC+B8,7
109 GETA$:IFA$=""THEN109
110 IFA$<>"{LEFT}"THENIFA$<>"{RIGHT}"THEN115
112 POKECR+IC+B8+PP,14:IFA$="{LEFT}"THEN:PP=PP-1:IFPP<.THENPP=4
113 IFA$="{RIGHT}"THENPP=PP+1:IFPP=5THENPP=.
114 POKECR+IC+B8+PP,7:GOTO109
115 IFA$>"/"THENIFA$<":"THENPOKEMV+IC+B8+PP,ASC(A$):A$="{RIGHT}":GOTO112
116 IFA$>"@"THENIFA$<"G"THENPOKEMV+IC+B8+PP,ASC(A$)-64:A$="{RIGHT}":GOTO112
118 IFA$="T"THEN130
119 IFA$<>CHR$(13)THEN109
120 FORN=ATOB:NP=N+AH:PF$(NP)=""
122 FORM=0TO4:C=PEEK(MV+IC+N*8+M):B$="-":IFC>47THENB$=CHR$(C)
124 IFC<7THENB$=CHR$(C+64)
126 PF$(NP)=PF$(NP)+B$:NEXTM,N:POKECR+IC+B8+PP,14:GOSUB1250:GOTO10
130 FORN=ATOB:FORM=0TO4:POKEMV+IC+N*8+M,PEEK(MV+IC+B8+M):NEXTM,N
132 GOTO109
140 INPUT"SAVE FILE";N$:GOTO1300
142 INPUT"LOAD FILE";N$:GOTO1400
150 INPUT"ARPEGIO DELAY 1,2,3";D1,D2,D3
152 POKEDN,D1:POKEDN+7,D2:POKEDN+14,D3:GOTO1154
160 INPUT"CUT OFF U,D,SQ,RES.";FC(0),FC(1),SQ(3),RE
161 POKE51166,FC(0):POKE51167,FC(1):POKE51101,SQ(3):POKE51102,ABS(1-SQ(3))
162 GOSUB30:GOTO180
170 INPUT"PW RATE UP,DW,SQ";PW(0),PW(1),SQ(0):FORN=.TO14STEP7
171 POKE51080+N,SQ(0):POKE51081+N,ABS(1-SQ(0))
172 POKE51145+N,PW(0):POKE51146+N,PW(1):NEXT
180 PRINTTAB(30)"     {UP}":GOTO1150
190 INPUT"GLIDE DLY/TRM 1,2,3 ";D1,D2,D3,E1,E2,E3
191 POKEDY,E1:POKEDY+7,E2:POKEDY+14,E3:TF=137:TN=29
192 E1=-TF*(E1=.)-TN*(E1>.):E2=-TF*(E2=.)-TN*(E2>.):E3=-TF*(E3=.)-TN*(E3>.)
193 POKEDT,E1:POKEDT+7,E2:POKEDT+14,E3
194 POKEDG,D1:POKEDG+7,D2:POKEDG+14,D3:GOTO1190
200 INPUT"WAVETABLE DELAY 1,2,3";D1,D2,D3
202 POKEDW,D1:POKEDW+7,D2:POKEDW+14,D3:GOTO1194
310 X=8:Y=3:CU=40:PC=55424:GOTO360
315 GETA$:IFA$=""THEN315
316 A=ASC(A$):IFA=32THENPOKEPC,14:GOTO11
318 IFA>132THENIFA<137THEN400
321 KK=7:IFA=129THENA=49:GOTO375
322 IFA>148THENIFA<156THENA=A-99:GOTO375
323 KK=.:IFA>48THENIFA<57THEN375
324 IFA>63THENIFA<91THENIFY>5THENPOKEMV+X+CU*Y,A-64:A=29:GOTO340
325 IFA>32THENIFA<39THEN390
330 IFA=188THENPP=PEEK(PD):A=29:GOTO340
335 IFA=190THENPOKEPD,PP:A=29
340 AA=1-(AAND128)/64:IF(AAND29)=29THENX=X+AA:GOTO360
345 IFAAND17THENY=Y+AA
360 Y=Y2(Y):X=X2(X):POKEPC,14:PC=CR+X+CU*Y:POKEPC,7:PD=PC-S
370 MC=CR+137:VY=PEEK(PD):FORN=7TO.STEP-1:POKEMC+N,VYAND1:VY=VY/2:NEXT:GOTO315
375 IFY>5THENIFA<53THENPOKEMV+CU*Y,A:POKENA+(Y-6)*7,A-48:GOTO315
380 CL=1-PEEK(CR+88+A)AND1:POKECR+88+A,CL
384 C8=PD+(KK=7)*(X-8)
385 BI=2^(56-A):FORN=.TOKK:POKEC8+N,PEEK(C8+N)AND(255-BI)OR(BI*CL):NEXT:GOTO315
390 YY=A-30:FORN=8TO15:POKEMV+N+40*YY,PEEK(MV+N+40*Y):NEXT:GOTO315
400 IFY<6THENPOKE1190,A-84:POKEDR,A-132:GOTO315
405 POKE1030+40*Y,A-84:POKECN+7*(Y-6),14-3*(A-132):GOTO315
900 L=4:IFPK<100THENL=3
905 IFPK<10THENL=2
910 RETURN
1000 PRINT"{CLEAR}":DR=49402:MV=1024:CR=55296:S=54272:FORN=STOS+24:POKEN,.:NEXT
1001 NA=51033:DW=NA+1:DG=NA+3:DN=NA+5:CN=NA+6:DT=NA+4:DY=NA+86
1002 FORN=.TO3:PF$(N)="41712":PF$(N+4)="11F9-":PW(N)=1:FC(N)=1:SQ(N)=0
1003 POKE51145+N*7,1:POKE51146+N*7,1:POKEDT+N*7,137:NEXT:GOSUB1251
1004 PK=24:FORV7=.TO14STEP7:GOSUB38:NEXT
1005 GOSUB1270:V=0:V7=0:LP=1:BP=.:HP=.:FORK=1TO3:F(K)=2:F(K+3)=2:F(K+6)=12
1006 NEXT:RE=15
1011 POKE56579,128:POKE56577,128
1012 DIMX2(16):FORN=8TO15:X2(N)=N:NEXT:X2(7)=15:X2(16)=8
1014 DIMY2(9):FORN=3TO8:Y2(N)=N:NEXT:Y2(2)=8:Y2(9)=3
1015 I$(2)="  ":I$(3)=" ":I$(4)=""
1016 DE$(0)="/":DE$(1)="{REVERSE ON}/{REVERSE OFF}"
1020 PS$="{HOME}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}":VZ$(0)=PS$+"{YELLOW}1{LIGHT BLUE}       2       3"
1022 VZ$(1)=PS$+"1       {YELLOW}2{LIGHT BLUE}       3"
1024 VZ$(2)=PS$+"1       2       {YELLOW}3{LIGHT BLUE}"
1025 PRINTCHR$(142)"{HOME}"
1026 PRINT"  P      P      P"
1037 PRINT"{HOME}{DOWN}{DOWN}{DOWN}        {A}{A}{A}{A}{SH ASTERISK}{SH ASTERISK}{SH ASTERISK}{SH ASTERISK} {CM +}{P}/VTRSG  H SAVE PATCH"
1038 PRINT"        {A}{A}{A}{A}{SH ASTERISK}{SH ASTERISK}{SH ASTERISK}{SH ASTERISK} 12345678  I LOAD PATCH"
1039 PRINT"        {A}{A}{A}{A}{SH ASTERISK}{SH ASTERISK}{SH ASTERISK}{SH ASTERISK}           J GLIDE"
1043 A$="        @@@@@@@@":PRINTA$"{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}B{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}B{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}B"
1044 A=4:GOSUB61:A=5:GOSUB61:A=6:GOSUB61
1045 PRINTA$:PRINTA$:PRINT"{UP}{UP}"
1150 PRINTVZ$(V7/7):POKE1190,PEEK(DR)+48
1152 FORY=.TO2:POKE1264+40*Y,PEEK(NA+7*Y)+48
1153 POKE1270+40*Y,53-(PEEK(CN+7*Y)+1)/3:NEXT
1154 PRINT"{HOME}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}":FORN=.TO2:PK=PEEK(DN+N*7):L=LEN(STR$(PK))
1155 PRINT"{RIGHT}{PINK}"I$(L)PK"{LIGHT BLUE}":NEXT
1156 PRINT"{DOWN}{PINK}B ARP DELAY{LIGHT BLUE}"
1157 PK=PW(0):GOSUB900:L1=L:PK=PW(1):GOSUB900:L2=L:PK=SQ(0):GOSUB900:L3=L
1158 PRINT"C PW RATE"TAB(14)I$(L1)PW(0)"{LEFT}"PW(1)"{LEFT}"I$(L2);
1159 PRINTI$(L1)PW(0)"{LEFT}"PW(1)"{LEFT}"I$(L2);
1160 PRINTI$(L1)PW(0)"{LEFT}"PW(1)"{LEFT}"I$(L2)
1161 PRINT"{UP}"TAB(18)DE$(SQ(0))SPC(7)DE$(SQ(0))SPC(7)DE$(SQ(0))
1162 PRINT"D PW ENV LOOP"SPC(3)PF$(0)"  {RIGHT}"PF$(1)"   "PF$(2)
1167 PK=FC(0):GOSUB900:L1=L:PK=FC(1):GOSUB900:L2=L:PK=SQ(3):GOSUB900:L3=L
1168 PRINT"E CUTOFF RATE"TAB(14)I$(L1)FC(0)"{LEFT}"FC(1)"{LEFT}"I$(L2)
1169 PRINT"{UP}"TAB(18)DE$(SQ(3));:PK=RE:GOSUB900:L4=L:PRINTTAB(22)I$(L4)RE"{LEFT} "
1170 PRINT"F FILTER"SPC(8)PF$(3)"    L B H"
1180 PRINT"G ADSR"SPC(10)PF$(4)"   "PF$(5)"   "PF$(6)
1190 FORN=.TO2:PK=PEEK(DG+N*7):L=LEN(STR$(PK))
1192 PRINT"{HOME}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}"TAB(21+N*7)I$(L)PK:PK=PEEK(DY+N*7):L=LEN(STR$(PK))
1193 PRINT"{HOME}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}"TAB(21+N*7)I$(L)PK:NEXT
1194 PRINT"{HOME}{DOWN}{DOWN}":FORN=.TO2:PK=PEEK(DW+N*7):L=LEN(STR$(PK))
1195 PRINT"{RIGHT}"I$(L)PK:NEXT
1200 GOSUB30:GOTO10
1250 IFAH=4THEN1270
1251 FORN=0TO3:B7=N*7
1252 FORM=1TO5:K=ASC(MID$(PF$(N),M,1))-48:IFK>16THENK=K-7
1254 P(M)=K:NEXT:P(3)=P(3)+1:P(2)=P(2)-1:IFP(2)=-1THENP(2)=255
1256 POKE51144+B7,P(1)+P(4):POKE51142+B7,P(2):POKE51143+B7,P(3)
1258 IFP(5)THENP(5)=P(5)+1
1259 POKE51141+B7,P(4)+(P(5)+4)*32:NEXT:RETURN
1270 FORN=0TO2:B7=N*7
1272 FORM=1TO4:K=ASC(MID$(PF$(N+4),M,1))-48:IFK>16THENK=K-7
1274 P(M)=K:NEXT
1276 POKE54277+B7,16*P(1)+P(2):POKE54278+B7,16*P(3)+P(4)
1278 NEXT:RETURN
1300 L=LEN(N$):IFL<1ORL>16THEN1150
1302 PK=51168:PE=1152
1303 O=.:FORN=.TO5:FORM=.TO7:POKEPK+O,PEEK(PE+N*40+M):O=O+1:NEXTM,N
1314 PK=51216
1315 O=.:FORN=.TO6:FORM=1TO5:POKEPK+O,ASC(MID$(PF$(N),M,1)):O=O+1:NEXTM,N
1317 POKE51075,RE:POKE51082,LP:POKE51089,BP:POKE51096,HP
1318 POKE51124,F(1):POKE51131,F(2):POKE51138,F(3)
1340 PK=51140:POKEPK+7,F(4)
1350 POKEPK+14,F(5):POKEPK+21,F(6):GOSUB4000:GOTO1150
1400 L=LEN(N$):IFL<1ORL>16THEN1150
1402 GOSUB5000:PK=51168
1403 PE=1152:O=.:FORN=.TO5:FORM=.TO7:POKEPE+N*40+M,PEEK(PK+O):O=O+1:NEXTM,N
1414 PK=51216:O=.:FORN=.TO6:PF$(N)=""
1415 FORM=1TO5:A=PEEK(PK+O):PF$(N)=PF$(N)+CHR$(A):O=O+1:NEXTM,N
1417 RE=PEEK(51075):LP=PEEK(51082):BP=PEEK(51089):HP=PEEK(51096)
1418 F(1)=PEEK(51124):F(2)=PEEK(51131):F(3)=PEEK(51138)
1421 PE=51121:B7=V7:FORV7=.TO14STEP7:PK=PEEK(PE+V7):GOSUB39:NEXT:V7=B7
1422 A=1:B=PEEK(51122):GOSUB7:GOSUB1505
1423 A=2:B=PEEK(51129):GOSUB7:GOSUB1510
1424 A=3:B=PEEK(51136):GOSUB7:GOSUB1520
1440 PE=51140:FORN=1TO3:F(N+3)=PEEK(PE+N*7):NEXT
1450 POKE1288,F(4):POKE1295,F(5):POKE1302,F(6)
1455 GOSUB1251:GOSUB1270:PRINT"{HOME}   ":GOTO1150
1500 FORN=CITOCI+39:READA:POKEN,A:PRINT"{HOME}"N:NEXT:A=4:B=0
1502 IFA=1ORA=4THENPOKE51122,B
1503 IFA=2ORA=4THENPOKE51129,B
1504 IFA=3ORA=4THENPOKE51136,B
1505 IFA=1ORA=4THENPOKE50021,196:POKE50026,195:SYSCI
1510 IFA=2ORA=4THENPOKE50021,197:POKE50026,196:SYSCI
1520 IFA=3ORA=4THENPOKE50021,198:POKE50026,197:SYSCI
1530 RETURN
2330 DATA162,77,181,56,157,60,3,234,189,81,199,149,56,202,16,242,234,234,234
2350 DATA44,1,221,112,3,76,164,192,173,1,221,41,7,168,190,159,199,142,79,4
2352 DATA74,72,234,234,144,42
2354 DATA189,200,199,157,113,7,189,197,199,157,114,7,169,128
2355 DATA157,112,7,224,21,208,5,190,158,199,16,230
2356 DATA169,1,149,86,149,87,149,88,181,69,149,90,169,11,149,91
2358 DATA234,234,234
2360 DATA142,1,221,44,1,221,112,251,173,1,221,41,63,234,125,177,199
2366 DATA157,86,4,185,167,199,149,85,234,41,4,234,234,234,208,3,76,176,194
2368 DATA104,208,3,76,192,193,169,128,141,1,221
2374 DATA165,197,141,231,7,74,208,130,234,234,234
2400 DATA162,77,189,60,3,149,56,202,16,248,96
2410 DATA234,234,234,234,234
2415 DATA165,63,240,31,234,165,162,201,5,144,24
2420 DATA162,3,189,248,4,157,252,4,202,208,247
2430 DATA165,56,133,62,165,64,133,61,134,162,234,234,234
2490 DATA162,21,32,67,194,240,23
2500 DATA173,134,7,133,254,173,133,7,141,21,212,70,254,106,70,254,106
2510 DATA70,254,106,141,22,212,162,14,234,234,181,115,133,108,133,110
2520 DATA214,86,208,16,169,4,213,87,176,4,169,1,149,87,246,87,181,65,149,86
2525 DATA234,234,234,234
2535 DATA189,8,5,208,95,24,180,64,185,143,195
2540 DATA117,91,168,181,85,121,149,195,168
2545 DATA189,86,4,121,248,4
2550 DATA168,234,234,177,107,157,1,212,177,109,157,0,212
2552 DATA24,181,85,117,87,168,185,126,4,157,4,212
2555 DATA214,90,208,18,181,69,149,90,234,234,234
2560 DATA214,91
2565 DATA16,7,181,70,234,234,234,149,91
2570 DATA32,67,194,240,12
2575 DATA189,112,7,157,2,212,189,113,7,157,3,212
2580 DATA138,56,233,7,170,176,129
2612 DATA76,137,192
2660 DATA214,88,208,203,234,234,234,181,67,149,88
2662 DATA214,89,16,9,181,68,141,130,193,246,89,240,137
2665 DATA24,189,153,7,157,0,212,125,156,7,157,153,7
2670 DATA189,152,7,157,1,212,125,155,7
2675 DATA157,152,7,76,46,193,234
2680 DATA56,189,156,7,233,1,73,255,157,156,7
2690 DATA189,155,7,233,0,73,255,157,155,7,189,175,199,149,89,16,199
2692 DATA234,234,234,234
2695 DATA165,63,208,2
2700 DATA133,64,166,64,173,86,4,164,85,234,234,240,34
2710 DATA234,202,48,62,213,56,208,249,181,57,149,56
2715 DATA232,228,64,208,247,202,134,64,234,234
2717 DATA208,45,165,61,133,64,165,62,234,234,16,58
2720 DATA224,4,240,3,232,134,64,234,234,149,55
2730 DATA202,234,181,55,213,56,144,10,180,56,149,56,234,234,148,55
2740 DATA176,238,232,134,2
2750 DATA166,64,56,202,240,9,181,56,229,56,157,248,4,176,244
2771 DATA234,134,162,134,85,232,234,234,234
2810 DATA165,56,141,86,4,134,63
2811 DATA234,234,165,64,10,10,101,2,168,185,120,195,133,91,76,132,192
2860 REM DATA234,234,234,234,234
2870 DATA189,114,7,168,74,41,64,240,59,189,112,7,133,254,144,20
2880 DATA253,202,199,157,112,7,176,33,189,113,7,233,0,221,198,199,208,20,240,27
2890 DATA125,201,199,157,112,7,144,13,189,113,7,105,0
2900 DATA221,199,199,240,9,157,113,7,181,112,96,234,234,234
2950 DATA165,254,157,112,7
2980 DATA152,41,63,133,254,152,10,41,192,5,254,73,1,157,114,7,181,111,96,234
3010 DATA234,234,234,234,234,234,234,234,234,234,234,234
3015 DATA234,234,234,234,234,234,234,234,234,181,115,133,108,133,110
3020 DATA234,234,234,234,234,234,234,234,234,234,234,234,234
3040 DATA188,8,5,192,4,240,49,192,3,208,25
3045 DATA164,250,185,152,7,157,152,7,185,153,7,157,153,7,234,176,25
3050 DATA234,234,234,234,234,234,234,234
3055 DATA189,86,4,125,176,199,168,177,107,157,152,7,177,109,157,153,7
3060 DATA234,134,250,189,86,4,234,234,234,168
3070 DATA56,177,109,253,153,7,133,252,177,107,253,152,7
3080 DATA133,251,169,255,105,0
3090 DATA234,234,160,2,6,252,38,251,42,136,16,248,234,234,157,155,7
3110 DATA165,251,234,234,157,156,7,169,33,149,89
3120 DATA76,126,192
3200 DATA162,11,189,232,195,133,254,189,244,195,133,253,138,24
3210 DATA105,12,168,165,253,153,85,196,165,254,153,244,195
3220 DATA6,253,38,254,152,234,234,144,234,202,16,219,96
3400 DATA0,255,255,255,255,255,32,32,0
3402 DATA4,32,.,2,.,12,11
3404 DATA4,32,.,2,.,12,11
3406 DATA4,32,.,2,.,12,11
3412 DATA4,0,1,0,0,0,0
3414 DATA44,0,1,0,0,0,0
3416 DATA84,0,1,0,0,0,0
3500 DATA.,0,0,97,0,0,1
3502 DATA.,0,196,97,196,0,1
3504 DATA.,0,197,97,197,0,1
3506 DATA.,0,198,97,198,0,1
3550 DATA0,21,0,21,7,21,14,21
3560 DATA4,0,4,0,44,40,84,80
3600 DATA32,4,8,12,16,11,11,11,11,11,10,10,10
3610 DATA11,10,9,9,11,10,9,8,32,32,32,0,12,24,36,32
3620 DATA0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0
3630 DATA2,2,2,2,1,1,1,1,0,0,0,0,3,3,3,2,2,2,1,1,1,0,0,0
4000 FORK=1TOL:POKE51007+K,ASC(MID$(N$,K,1)):NEXT
4020 POKE780,2:POKE781,8:POKE782,0:SYS65466:REM SETFLS
4030 POKE780,L:POKE781,64:POKE782,199:SYS65469:REM SETNAM
4040 POKE251,80:POKE252,199:POKE780,251:POKE781,51:POKE782,200:SYS65496:REM SAVE
4045 RETURN
5000 FORK=1TOL:POKE51007+K,ASC(MID$(N$,K,1)):NEXT
5020 POKE780,2:POKE781,8:POKE782,0:SYS65466:REM SETFLS
5030 POKE780,L:POKE781,64:POKE782,199:SYS65469:REM SETNAM
5040 POKE780,0:POKE781,80:POKE782,199:SYS65493:REM LOAD
5045 RETURN
y quizas... no tan rebuscadamente se tenga que tocar el software.... Se podria hacer un automute en el arduino fisicamente y por tiempo. O sea, cuando no detecta MIDI por un determinado tiempo o cuando fisicamente le indicamos al arduino que vamos a entrar en modo edicion, no envia nada... Estan comentados justamente los puertos D12/D13, o bien implementar cualquier otro puerto que este libre... Pasando en limpio:
- Puerto paralelo: pines D2–D8 siguen siendo tu canal de datos con C64.
- Botón físico de modo edición: lo conectás a un pin libre fuera de D2–D8, por ejemplo D9 o D10.
- Modo edición activado cuando:
1_Hay inactividad MIDI (sin notas nuevas en X ms)
2_O se presiona el botón (físico)
- En modo edición, el Arduino puede leer o enviar datos por el puerto paralelo D2–D8 solo en esos momentos, evitando interferencias con el flujo normal MIDI.
- Para interactividad física + tiempo de espera, usás algo así:


CSS:
const int pinesPuerto[] = {2,3,4,5,6,7,8}; // Puerto paralelo C64
const int pinBotonEdicion = 9;             // Pin libre para botón
const int pinLED = 10;

bool modoEdicion = false;
unsigned long ultimaNotaMIDI = 0;
const unsigned long tiempoInactividad = 2000;

void setup() {
  for(int i=0;i<7;i++) pinMode(pinesPuerto[i], OUTPUT); // config puerto paralelo
  pinMode(pinBotonEdicion, INPUT_PULLUP);
  pinMode(pinLED, OUTPUT);
  Serial.begin(xxxx);
}

void loop() {
  // Detectar actividad MIDI
  if(hayNotaMIDI()) {
    ultimaNotaMIDI = millis();
    modoEdicion = false;
  }

  // Detectar botón físico
  if(digitalRead(pinBotonEdicion)==LOW){
    modoEdicion = !modoEdicion;
    delay(200); // anti-rebote
  }

  // Activar modo edición por inactividad
  if(millis()-ultimaNotaMIDI > tiempoInactividad) modoEdicion = true;

  // LED indicador
  digitalWrite(pinLED, modoEdicion ? HIGH : LOW);

  if(modoEdicion){
    // Lectura o envío por el puerto paralelo
    // Ejemplo simple de lectura:
    byte datosC64 = 0;
    for(int i=0;i<7;i++){
      datosC64 |= (digitalRead(pinesPuerto[i]) << i);
    }
    if(datosC64){
      Serial.print("Dato recibido: "); Serial.println(datosC64,BIN);
      // Respuesta simple al C64
      for(int i=0;i<7;i++){
        digitalWrite(pinesPuerto[i], (datosC64>>i)&1);
      }
    }
  } else {
    // Lectura MIDI normal
    LecturaMIDI();
  }
}

bool hayNotaMIDI(){
  // Acá la función real que chequea buffer MIDI
  return false;
}

Con esto, El puerto paralelo D2–D8 sigue intacto. El botón físico te permite forzar el modo edición aunque haya silencios largos entre notas. LED te da feedback visual de que el Arduino está en modo edición, y todo esto no interfiere con la lectura MIDI mientras se toca.... Tendria que dedicarle varias horas para editarlo completo y no romper el sketch, pero es mas viable atacarlo a nivel arduino... no se si es muy descabellada la idea
entonces tiene que trabajar a nivel software agregando una señal mas desde el puerto de usuario para indicarle al arduino mediante una interrupcion por hardware (le sobran pines en el arduino) que no le mande nada por que esta en modo edicion.... Ahi use C64 PRG/BASIC converter para ver el programa de la C64

Código:
0 PRINTCHR$(14)"{CLEAR}       {R}EAD DATA? Y/N":B=0:AL=50152:BA=50164:CI=50000
1 BY=256:FT=1.0595:FI=262.39:CT=.000595:GOSUB7
2 GETA$:N=1-1*(A$="Y")-2*(A$="N"):ONNGOTO2,3,1000
3 PRINT"{DOWN}PAYPAL DONATIONS APPRECIATED":PRINT"A{CM @}---------------"
4 FORN=49152TO49971:READA:POKEN,A:PRINT"{HOME}"N:NEXT:GOSUB1500
5 FORN=51024TO51118:READA:POKEN,A:PRINT"{HOME}"N:NEXT
6 FORN=50040TO50116:READA:POKEN,A:PRINT"{HOME}"N:NEXT:GOTO1000
7 FQ=FI*(1+B*CT):FORN=.TO11:FQ=FQ*FT:HI=INT(FQ/BY):LO=FQ-(HI*BY)
8 POKEAL+N,HI:POKEBA+N,LO:PRINT"{HOME}"N"{LEFT} ":NEXT:RETURN
10 PRINT"{HOME}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}                                       {UP}"
11 GETA$:IFA$=""THEN11
12 A=ASC(A$):IFA>48THENIFA<52THENV=A-49:V7=V*7:PRINTVZ$(V):GOTO10
13 IFA=32THEN28
14 IFA>64ANDA<72THENA=A-64:ONAGOTO310,150,170,40,160,44,50
15 IFA>71ANDA<79THENA=A-71:ONAGOTO140,142,190,200,96,98,100
16 IFA=194THENBP=ABS(BP-1):GOSUB30
17 IFA=204THENLP=ABS(LP-1):GOSUB30
18 IFA=200THENHP=ABS(HP-1):GOSUB30
20 IFA>136THENIFA<140THENA=A-136:F(A)=F(A)+1+3*(F(A)=2):GOSUB30
21 IFA>132THENIFA<136THENA=A-129:GOTO60
23 PK=PEEK(51121+V7):IFA=17THENPK=PK+12*(PK>11):GOSUB38:GOTO10
24 IFA=145THENPK=PK-12*(PK<244):GOSUB38:GOTO10
25 IFA=157THENPK=PK+(PK>.):GOSUB38:GOTO10
26 IFA=29THENPK=PK-(PK<255):GOSUB38:GOTO10
27 GOTO11
28 SYS49152:GOTO10:REM SYS49815
30 POKE54295,16*RE-4*(F(3)>.)-2*(F(2)>.)-(F(1)>.):FORN=1TO3:POKE1615+N,F(N):NEXT
31 F1=-21*(F(1)=2):F2=7-14*(F(2)=2):F3=14-7*(F(3)=2)
32 POKE51104,F1:POKE51106,F1:POKE51108,F2:POKE51110,F3
33 POKE54296,15+16*LP+32*BP+64*HP
34 POKECR+585,14-7*LP:POKECR+587,14-7*BP:POKECR+589,14-7*HP:RETURN
38 PL(V7/7)=PK:POKE51121+V7,PK
39 PRINT"{HOME}{DOWN}"SPC(21+V7)"   {LEFT}{LEFT}{LEFT}{LEFT}"PK:RETURN
40 A=0:B=2:IC=496:AH=0:B8=V*8:GOTO106
44 A=0:B=0:IC=576:AH=3:B8=0:GOTO106
50 A=0:B=2:IC=616:AH=4:B8=V*8:GOTO107
60 F(A)=F(A)+1+5*(F(A)=4):POKE1260+A*7,F(A):GOSUB61:GOTO11
61 GL=F(A+3):IFF(A)=2THENGL=GL-1:GL=(GLOR255)ANDNOT(GLAND255)
62 POKE51092+A*7,GL:RETURN
96 INPUT"POKEA,B";A,B:POKEA,B:GOTO10
98 INPUT"V,F. TUNING";A,B
99 GOSUB7:GOSUB1502:PRINT"{HOME}   ":GOTO10
100 INPUT"GLIDE INTERVAL 1,2,3";F(7),F(8),F(9)
101 A=4:GOSUB61:A=5:GOSUB61:A=6:GOSUB61:GOTO10
106 PRINT"GO-MI-MX-DIR-LOP"
107 PP=0:POKECR+IC+B8,7
109 GETA$:IFA$=""THEN109
110 IFA$<>"{LEFT}"THENIFA$<>"{RIGHT}"THEN115
112 POKECR+IC+B8+PP,14:IFA$="{LEFT}"THEN:PP=PP-1:IFPP<.THENPP=4
113 IFA$="{RIGHT}"THENPP=PP+1:IFPP=5THENPP=.
114 POKECR+IC+B8+PP,7:GOTO109
115 IFA$>"/"THENIFA$<":"THENPOKEMV+IC+B8+PP,ASC(A$):A$="{RIGHT}":GOTO112
116 IFA$>"@"THENIFA$<"G"THENPOKEMV+IC+B8+PP,ASC(A$)-64:A$="{RIGHT}":GOTO112
118 IFA$="T"THEN130
119 IFA$<>CHR$(13)THEN109
120 FORN=ATOB:NP=N+AH:PF$(NP)=""
122 FORM=0TO4:C=PEEK(MV+IC+N*8+M):B$="-":IFC>47THENB$=CHR$(C)
124 IFC<7THENB$=CHR$(C+64)
126 PF$(NP)=PF$(NP)+B$:NEXTM,N:POKECR+IC+B8+PP,14:GOSUB1250:GOTO10
130 FORN=ATOB:FORM=0TO4:POKEMV+IC+N*8+M,PEEK(MV+IC+B8+M):NEXTM,N
132 GOTO109
140 INPUT"SAVE FILE";N$:GOTO1300
142 INPUT"LOAD FILE";N$:GOTO1400
150 INPUT"ARPEGIO DELAY 1,2,3";D1,D2,D3
152 POKEDN,D1:POKEDN+7,D2:POKEDN+14,D3:GOTO1154
160 INPUT"CUT OFF U,D,SQ,RES.";FC(0),FC(1),SQ(3),RE
161 POKE51166,FC(0):POKE51167,FC(1):POKE51101,SQ(3):POKE51102,ABS(1-SQ(3))
162 GOSUB30:GOTO180
170 INPUT"PW RATE UP,DW,SQ";PW(0),PW(1),SQ(0):FORN=.TO14STEP7
171 POKE51080+N,SQ(0):POKE51081+N,ABS(1-SQ(0))
172 POKE51145+N,PW(0):POKE51146+N,PW(1):NEXT
180 PRINTTAB(30)"     {UP}":GOTO1150
190 INPUT"GLIDE DLY/TRM 1,2,3 ";D1,D2,D3,E1,E2,E3
191 POKEDY,E1:POKEDY+7,E2:POKEDY+14,E3:TF=137:TN=29
192 E1=-TF*(E1=.)-TN*(E1>.):E2=-TF*(E2=.)-TN*(E2>.):E3=-TF*(E3=.)-TN*(E3>.)
193 POKEDT,E1:POKEDT+7,E2:POKEDT+14,E3
194 POKEDG,D1:POKEDG+7,D2:POKEDG+14,D3:GOTO1190
200 INPUT"WAVETABLE DELAY 1,2,3";D1,D2,D3
202 POKEDW,D1:POKEDW+7,D2:POKEDW+14,D3:GOTO1194
310 X=8:Y=3:CU=40:PC=55424:GOTO360
315 GETA$:IFA$=""THEN315
316 A=ASC(A$):IFA=32THENPOKEPC,14:GOTO11
318 IFA>132THENIFA<137THEN400
321 KK=7:IFA=129THENA=49:GOTO375
322 IFA>148THENIFA<156THENA=A-99:GOTO375
323 KK=.:IFA>48THENIFA<57THEN375
324 IFA>63THENIFA<91THENIFY>5THENPOKEMV+X+CU*Y,A-64:A=29:GOTO340
325 IFA>32THENIFA<39THEN390
330 IFA=188THENPP=PEEK(PD):A=29:GOTO340
335 IFA=190THENPOKEPD,PP:A=29
340 AA=1-(AAND128)/64:IF(AAND29)=29THENX=X+AA:GOTO360
345 IFAAND17THENY=Y+AA
360 Y=Y2(Y):X=X2(X):POKEPC,14:PC=CR+X+CU*Y:POKEPC,7:PD=PC-S
370 MC=CR+137:VY=PEEK(PD):FORN=7TO.STEP-1:POKEMC+N,VYAND1:VY=VY/2:NEXT:GOTO315
375 IFY>5THENIFA<53THENPOKEMV+CU*Y,A:POKENA+(Y-6)*7,A-48:GOTO315
380 CL=1-PEEK(CR+88+A)AND1:POKECR+88+A,CL
384 C8=PD+(KK=7)*(X-8)
385 BI=2^(56-A):FORN=.TOKK:POKEC8+N,PEEK(C8+N)AND(255-BI)OR(BI*CL):NEXT:GOTO315
390 YY=A-30:FORN=8TO15:POKEMV+N+40*YY,PEEK(MV+N+40*Y):NEXT:GOTO315
400 IFY<6THENPOKE1190,A-84:POKEDR,A-132:GOTO315
405 POKE1030+40*Y,A-84:POKECN+7*(Y-6),14-3*(A-132):GOTO315
900 L=4:IFPK<100THENL=3
905 IFPK<10THENL=2
910 RETURN
1000 PRINT"{CLEAR}":DR=49402:MV=1024:CR=55296:S=54272:FORN=STOS+24:POKEN,.:NEXT
1001 NA=51033:DW=NA+1:DG=NA+3:DN=NA+5:CN=NA+6:DT=NA+4:DY=NA+86
1002 FORN=.TO3:PF$(N)="41712":PF$(N+4)="11F9-":PW(N)=1:FC(N)=1:SQ(N)=0
1003 POKE51145+N*7,1:POKE51146+N*7,1:POKEDT+N*7,137:NEXT:GOSUB1251
1004 PK=24:FORV7=.TO14STEP7:GOSUB38:NEXT
1005 GOSUB1270:V=0:V7=0:LP=1:BP=.:HP=.:FORK=1TO3:F(K)=2:F(K+3)=2:F(K+6)=12
1006 NEXT:RE=15
1011 POKE56579,128:POKE56577,128
1012 DIMX2(16):FORN=8TO15:X2(N)=N:NEXT:X2(7)=15:X2(16)=8
1014 DIMY2(9):FORN=3TO8:Y2(N)=N:NEXT:Y2(2)=8:Y2(9)=3
1015 I$(2)="  ":I$(3)=" ":I$(4)=""
1016 DE$(0)="/":DE$(1)="{REVERSE ON}/{REVERSE OFF}"
1020 PS$="{HOME}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}":VZ$(0)=PS$+"{YELLOW}1{LIGHT BLUE}       2       3"
1022 VZ$(1)=PS$+"1       {YELLOW}2{LIGHT BLUE}       3"
1024 VZ$(2)=PS$+"1       2       {YELLOW}3{LIGHT BLUE}"
1025 PRINTCHR$(142)"{HOME}"
1026 PRINT"  P      P      P"
1037 PRINT"{HOME}{DOWN}{DOWN}{DOWN}        {A}{A}{A}{A}{SH ASTERISK}{SH ASTERISK}{SH ASTERISK}{SH ASTERISK} {CM +}{P}/VTRSG  H SAVE PATCH"
1038 PRINT"        {A}{A}{A}{A}{SH ASTERISK}{SH ASTERISK}{SH ASTERISK}{SH ASTERISK} 12345678  I LOAD PATCH"
1039 PRINT"        {A}{A}{A}{A}{SH ASTERISK}{SH ASTERISK}{SH ASTERISK}{SH ASTERISK}           J GLIDE"
1043 A$="        @@@@@@@@":PRINTA$"{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}B{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}B{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}B"
1044 A=4:GOSUB61:A=5:GOSUB61:A=6:GOSUB61
1045 PRINTA$:PRINTA$:PRINT"{UP}{UP}"
1150 PRINTVZ$(V7/7):POKE1190,PEEK(DR)+48
1152 FORY=.TO2:POKE1264+40*Y,PEEK(NA+7*Y)+48
1153 POKE1270+40*Y,53-(PEEK(CN+7*Y)+1)/3:NEXT
1154 PRINT"{HOME}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}":FORN=.TO2:PK=PEEK(DN+N*7):L=LEN(STR$(PK))
1155 PRINT"{RIGHT}{PINK}"I$(L)PK"{LIGHT BLUE}":NEXT
1156 PRINT"{DOWN}{PINK}B ARP DELAY{LIGHT BLUE}"
1157 PK=PW(0):GOSUB900:L1=L:PK=PW(1):GOSUB900:L2=L:PK=SQ(0):GOSUB900:L3=L
1158 PRINT"C PW RATE"TAB(14)I$(L1)PW(0)"{LEFT}"PW(1)"{LEFT}"I$(L2);
1159 PRINTI$(L1)PW(0)"{LEFT}"PW(1)"{LEFT}"I$(L2);
1160 PRINTI$(L1)PW(0)"{LEFT}"PW(1)"{LEFT}"I$(L2)
1161 PRINT"{UP}"TAB(18)DE$(SQ(0))SPC(7)DE$(SQ(0))SPC(7)DE$(SQ(0))
1162 PRINT"D PW ENV LOOP"SPC(3)PF$(0)"  {RIGHT}"PF$(1)"   "PF$(2)
1167 PK=FC(0):GOSUB900:L1=L:PK=FC(1):GOSUB900:L2=L:PK=SQ(3):GOSUB900:L3=L
1168 PRINT"E CUTOFF RATE"TAB(14)I$(L1)FC(0)"{LEFT}"FC(1)"{LEFT}"I$(L2)
1169 PRINT"{UP}"TAB(18)DE$(SQ(3));:PK=RE:GOSUB900:L4=L:PRINTTAB(22)I$(L4)RE"{LEFT} "
1170 PRINT"F FILTER"SPC(8)PF$(3)"    L B H"
1180 PRINT"G ADSR"SPC(10)PF$(4)"   "PF$(5)"   "PF$(6)
1190 FORN=.TO2:PK=PEEK(DG+N*7):L=LEN(STR$(PK))
1192 PRINT"{HOME}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}"TAB(21+N*7)I$(L)PK:PK=PEEK(DY+N*7):L=LEN(STR$(PK))
1193 PRINT"{HOME}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}"TAB(21+N*7)I$(L)PK:NEXT
1194 PRINT"{HOME}{DOWN}{DOWN}":FORN=.TO2:PK=PEEK(DW+N*7):L=LEN(STR$(PK))
1195 PRINT"{RIGHT}"I$(L)PK:NEXT
1200 GOSUB30:GOTO10
1250 IFAH=4THEN1270
1251 FORN=0TO3:B7=N*7
1252 FORM=1TO5:K=ASC(MID$(PF$(N),M,1))-48:IFK>16THENK=K-7
1254 P(M)=K:NEXT:P(3)=P(3)+1:P(2)=P(2)-1:IFP(2)=-1THENP(2)=255
1256 POKE51144+B7,P(1)+P(4):POKE51142+B7,P(2):POKE51143+B7,P(3)
1258 IFP(5)THENP(5)=P(5)+1
1259 POKE51141+B7,P(4)+(P(5)+4)*32:NEXT:RETURN
1270 FORN=0TO2:B7=N*7
1272 FORM=1TO4:K=ASC(MID$(PF$(N+4),M,1))-48:IFK>16THENK=K-7
1274 P(M)=K:NEXT
1276 POKE54277+B7,16*P(1)+P(2):POKE54278+B7,16*P(3)+P(4)
1278 NEXT:RETURN
1300 L=LEN(N$):IFL<1ORL>16THEN1150
1302 PK=51168:PE=1152
1303 O=.:FORN=.TO5:FORM=.TO7:POKEPK+O,PEEK(PE+N*40+M):O=O+1:NEXTM,N
1314 PK=51216
1315 O=.:FORN=.TO6:FORM=1TO5:POKEPK+O,ASC(MID$(PF$(N),M,1)):O=O+1:NEXTM,N
1317 POKE51075,RE:POKE51082,LP:POKE51089,BP:POKE51096,HP
1318 POKE51124,F(1):POKE51131,F(2):POKE51138,F(3)
1340 PK=51140:POKEPK+7,F(4)
1350 POKEPK+14,F(5):POKEPK+21,F(6):GOSUB4000:GOTO1150
1400 L=LEN(N$):IFL<1ORL>16THEN1150
1402 GOSUB5000:PK=51168
1403 PE=1152:O=.:FORN=.TO5:FORM=.TO7:POKEPE+N*40+M,PEEK(PK+O):O=O+1:NEXTM,N
1414 PK=51216:O=.:FORN=.TO6:PF$(N)=""
1415 FORM=1TO5:A=PEEK(PK+O):PF$(N)=PF$(N)+CHR$(A):O=O+1:NEXTM,N
1417 RE=PEEK(51075):LP=PEEK(51082):BP=PEEK(51089):HP=PEEK(51096)
1418 F(1)=PEEK(51124):F(2)=PEEK(51131):F(3)=PEEK(51138)
1421 PE=51121:B7=V7:FORV7=.TO14STEP7:PK=PEEK(PE+V7):GOSUB39:NEXT:V7=B7
1422 A=1:B=PEEK(51122):GOSUB7:GOSUB1505
1423 A=2:B=PEEK(51129):GOSUB7:GOSUB1510
1424 A=3:B=PEEK(51136):GOSUB7:GOSUB1520
1440 PE=51140:FORN=1TO3:F(N+3)=PEEK(PE+N*7):NEXT
1450 POKE1288,F(4):POKE1295,F(5):POKE1302,F(6)
1455 GOSUB1251:GOSUB1270:PRINT"{HOME}   ":GOTO1150
1500 FORN=CITOCI+39:READA:POKEN,A:PRINT"{HOME}"N:NEXT:A=4:B=0
1502 IFA=1ORA=4THENPOKE51122,B
1503 IFA=2ORA=4THENPOKE51129,B
1504 IFA=3ORA=4THENPOKE51136,B
1505 IFA=1ORA=4THENPOKE50021,196:POKE50026,195:SYSCI
1510 IFA=2ORA=4THENPOKE50021,197:POKE50026,196:SYSCI
1520 IFA=3ORA=4THENPOKE50021,198:POKE50026,197:SYSCI
1530 RETURN
2330 DATA162,77,181,56,157,60,3,234,189,81,199,149,56,202,16,242,234,234,234
2350 DATA44,1,221,112,3,76,164,192,173,1,221,41,7,168,190,159,199,142,79,4
2352 DATA74,72,234,234,144,42
2354 DATA189,200,199,157,113,7,189,197,199,157,114,7,169,128
2355 DATA157,112,7,224,21,208,5,190,158,199,16,230
2356 DATA169,1,149,86,149,87,149,88,181,69,149,90,169,11,149,91
2358 DATA234,234,234
2360 DATA142,1,221,44,1,221,112,251,173,1,221,41,63,234,125,177,199
2366 DATA157,86,4,185,167,199,149,85,234,41,4,234,234,234,208,3,76,176,194
2368 DATA104,208,3,76,192,193,169,128,141,1,221
2374 DATA165,197,141,231,7,74,208,130,234,234,234
2400 DATA162,77,189,60,3,149,56,202,16,248,96
2410 DATA234,234,234,234,234
2415 DATA165,63,240,31,234,165,162,201,5,144,24
2420 DATA162,3,189,248,4,157,252,4,202,208,247
2430 DATA165,56,133,62,165,64,133,61,134,162,234,234,234
2490 DATA162,21,32,67,194,240,23
2500 DATA173,134,7,133,254,173,133,7,141,21,212,70,254,106,70,254,106
2510 DATA70,254,106,141,22,212,162,14,234,234,181,115,133,108,133,110
2520 DATA214,86,208,16,169,4,213,87,176,4,169,1,149,87,246,87,181,65,149,86
2525 DATA234,234,234,234
2535 DATA189,8,5,208,95,24,180,64,185,143,195
2540 DATA117,91,168,181,85,121,149,195,168
2545 DATA189,86,4,121,248,4
2550 DATA168,234,234,177,107,157,1,212,177,109,157,0,212
2552 DATA24,181,85,117,87,168,185,126,4,157,4,212
2555 DATA214,90,208,18,181,69,149,90,234,234,234
2560 DATA214,91
2565 DATA16,7,181,70,234,234,234,149,91
2570 DATA32,67,194,240,12
2575 DATA189,112,7,157,2,212,189,113,7,157,3,212
2580 DATA138,56,233,7,170,176,129
2612 DATA76,137,192
2660 DATA214,88,208,203,234,234,234,181,67,149,88
2662 DATA214,89,16,9,181,68,141,130,193,246,89,240,137
2665 DATA24,189,153,7,157,0,212,125,156,7,157,153,7
2670 DATA189,152,7,157,1,212,125,155,7
2675 DATA157,152,7,76,46,193,234
2680 DATA56,189,156,7,233,1,73,255,157,156,7
2690 DATA189,155,7,233,0,73,255,157,155,7,189,175,199,149,89,16,199
2692 DATA234,234,234,234
2695 DATA165,63,208,2
2700 DATA133,64,166,64,173,86,4,164,85,234,234,240,34
2710 DATA234,202,48,62,213,56,208,249,181,57,149,56
2715 DATA232,228,64,208,247,202,134,64,234,234
2717 DATA208,45,165,61,133,64,165,62,234,234,16,58
2720 DATA224,4,240,3,232,134,64,234,234,149,55
2730 DATA202,234,181,55,213,56,144,10,180,56,149,56,234,234,148,55
2740 DATA176,238,232,134,2
2750 DATA166,64,56,202,240,9,181,56,229,56,157,248,4,176,244
2771 DATA234,134,162,134,85,232,234,234,234
2810 DATA165,56,141,86,4,134,63
2811 DATA234,234,165,64,10,10,101,2,168,185,120,195,133,91,76,132,192
2860 REM DATA234,234,234,234,234
2870 DATA189,114,7,168,74,41,64,240,59,189,112,7,133,254,144,20
2880 DATA253,202,199,157,112,7,176,33,189,113,7,233,0,221,198,199,208,20,240,27
2890 DATA125,201,199,157,112,7,144,13,189,113,7,105,0
2900 DATA221,199,199,240,9,157,113,7,181,112,96,234,234,234
2950 DATA165,254,157,112,7
2980 DATA152,41,63,133,254,152,10,41,192,5,254,73,1,157,114,7,181,111,96,234
3010 DATA234,234,234,234,234,234,234,234,234,234,234,234
3015 DATA234,234,234,234,234,234,234,234,234,181,115,133,108,133,110
3020 DATA234,234,234,234,234,234,234,234,234,234,234,234,234
3040 DATA188,8,5,192,4,240,49,192,3,208,25
3045 DATA164,250,185,152,7,157,152,7,185,153,7,157,153,7,234,176,25
3050 DATA234,234,234,234,234,234,234,234
3055 DATA189,86,4,125,176,199,168,177,107,157,152,7,177,109,157,153,7
3060 DATA234,134,250,189,86,4,234,234,234,168
3070 DATA56,177,109,253,153,7,133,252,177,107,253,152,7
3080 DATA133,251,169,255,105,0
3090 DATA234,234,160,2,6,252,38,251,42,136,16,248,234,234,157,155,7
3110 DATA165,251,234,234,157,156,7,169,33,149,89
3120 DATA76,126,192
3200 DATA162,11,189,232,195,133,254,189,244,195,133,253,138,24
3210 DATA105,12,168,165,253,153,85,196,165,254,153,244,195
3220 DATA6,253,38,254,152,234,234,144,234,202,16,219,96
3400 DATA0,255,255,255,255,255,32,32,0
3402 DATA4,32,.,2,.,12,11
3404 DATA4,32,.,2,.,12,11
3406 DATA4,32,.,2,.,12,11
3412 DATA4,0,1,0,0,0,0
3414 DATA44,0,1,0,0,0,0
3416 DATA84,0,1,0,0,0,0
3500 DATA.,0,0,97,0,0,1
3502 DATA.,0,196,97,196,0,1
3504 DATA.,0,197,97,197,0,1
3506 DATA.,0,198,97,198,0,1
3550 DATA0,21,0,21,7,21,14,21
3560 DATA4,0,4,0,44,40,84,80
3600 DATA32,4,8,12,16,11,11,11,11,11,10,10,10
3610 DATA11,10,9,9,11,10,9,8,32,32,32,0,12,24,36,32
3620 DATA0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0
3630 DATA2,2,2,2,1,1,1,1,0,0,0,0,3,3,3,2,2,2,1,1,1,0,0,0
4000 FORK=1TOL:POKE51007+K,ASC(MID$(N$,K,1)):NEXT
4020 POKE780,2:POKE781,8:POKE782,0:SYS65466:REM SETFLS
4030 POKE780,L:POKE781,64:POKE782,199:SYS65469:REM SETNAM
4040 POKE251,80:POKE252,199:POKE780,251:POKE781,51:POKE782,200:SYS65496:REM SAVE
4045 RETURN
5000 FORK=1TOL:POKE51007+K,ASC(MID$(N$,K,1)):NEXT
5020 POKE780,2:POKE781,8:POKE782,0:SYS65466:REM SETFLS
5030 POKE780,L:POKE781,64:POKE782,199:SYS65469:REM SETNAM
5040 POKE780,0:POKE781,80:POKE782,199:SYS65493:REM LOAD
5045 RETURN
@Dr. Zoidberg , no te trae un poco de nostalgia? :cry:

 
Última edición:
Atrás
Arriba