Adjunto los fuentes modificados a partir de los últimos que ha publicado @neuro_999, así como el fichero .HEX listo para flashear, que como veis respeta el último nombre elegido por neuro en su github.
Lo primero que he hecho es entrar en la BIOS del ZXUno y ver exactamente qué estaba sucediendo al pulsar cualquier tecla especial en un modo cualquiera distinto al inicial del Spectrum (tecla especial sería combinación con shift o con symbol) y ya desde ahí se puede ver un comportamiento extraño, observándose múltiples repeticiones de dicha tecla especial combinada. Si conectamos un teclado convencional y hacemos las mismas combinaciones vemos que esto no sucede, las teclas se mantienen pulsadas, que es como debe ser.
Analizado dicho comportamiento extraño, revisé las funciones
pulsaysueltateclaconsymbol y
pulsaysueltateclaconshift. En estas se puede observar que se realiza la pulsación de dichas combinaciones y acto seguido tras el transcurso de un periodo excesivamente corto (delay), se sueltan... con lo que en muchas ocasiones esto provoca que al core correspondiente no le de tiempo de procesarlo y por tanto a mostrarse en pantalla. Tras ello, se realiza otro delay variable según el core (que es a lo que neuro se refería con los timmings), esta función es continuamente llamada mientras la combinación de teclas sea mantenida, y aquí realmente es donde se encuentra el fallo. La gestión de repetición de teclas hay que dejar que la lleve a cabo el propio core, nosotros lo único que tenemos que hacer enviar los scancodes de pulsación y esperar hasta que se suelte la tecla correspondiente, tras lo cual enviamos los scancodes de liberación, y esto precisamente es lo que he hecho, eliminar
cualquier relación de los timmings y separar la función en dos, una que se encarga de pulsar la combinación y otra que se encarga de soltarla:
Código: Seleccionar todo
/*
void pulsaysueltateclaconsymbol(unsigned char row, unsigned char col, enum KBMODE modokb)
{
unsigned char key=0, shift=0;
if(modokb==cpc) {key=mapCPC[row][col]; shift=modCPC[row][col];}
if(modokb==msx) {key=mapMSX[row][col]; shift=modMSX[row][col];}
if(modokb==c64) {key=mapC64[row][col]; shift=modC64[row][col];}
if(modokb==at8) {key=mapAT8[row][col]; shift=modAT8[row][col];}
if(modokb==bbc) {key=mapBBC[row][col]; shift=modBBC[row][col];}
if(modokb==aco) {key=mapACO[row][col]; shift=modACO[row][col];}
if(modokb==ap2) {key=mapAP2[row][col]; shift=modAP2[row][col];}
if(modokb==vic) {key=mapVIC[row][col]; shift=modVIC[row][col];}
if(modokb==ori) {key=mapORI[row][col]; shift=modORI[row][col];}
if(modokb==sam) {key=mapSAM[row][col]; shift=modSAM[row][col];}
if(modokb==jup) {key=mapJUP[row][col]; shift=modJUP[row][col];}
if(modokb==xt1) {key=mapXT1[row][col]; shift=modXT1[row][col];}
if(shift) {if(codeset==2) sendPS2(KEY_RSHIFT); else sendPS2(KS1_RSHIFT); }// _delay_us(5);}
sendPS2(key); _delay_us(50);
if(codeset==2) {sendPS2(0xF0);sendPS2(key);} else sendPS2(key+KS1_RELEASE);
if(shift) {if(codeset==2) {sendPS2(0xF0); sendPS2(KEY_RSHIFT);} else sendPS2(KS1_RSHIFT+KS1_RELEASE); }// _delay_us(5);}
_delay_ms(KBp); //Pequeña pausa para evitar la "super-repeticion-atodapastilla"
matriz[row][col]=0;
}
*/
void pulsateclaconsymbol(unsigned char row, unsigned char col, enum KBMODE modokb)
{
unsigned char key = 0, shift = 0;
if (modokb == cpc) { key = mapCPC[row][col]; shift = modCPC[row][col]; }
if (modokb == msx) { key = mapMSX[row][col]; shift = modMSX[row][col]; }
if (modokb == c64) { key = mapC64[row][col]; shift = modC64[row][col]; }
if (modokb == at8) { key = mapAT8[row][col]; shift = modAT8[row][col]; }
if (modokb == bbc) { key = mapBBC[row][col]; shift = modBBC[row][col]; }
if (modokb == aco) { key = mapACO[row][col]; shift = modACO[row][col]; }
if (modokb == ap2) { key = mapAP2[row][col]; shift = modAP2[row][col]; }
if (modokb == vic) { key = mapVIC[row][col]; shift = modVIC[row][col]; }
if (modokb == ori) { key = mapORI[row][col]; shift = modORI[row][col]; }
if (modokb == sam) { key = mapSAM[row][col]; shift = modSAM[row][col]; }
if (modokb == jup) { key = mapJUP[row][col]; shift = modJUP[row][col]; }
if (modokb == xt1) { key = mapXT1[row][col]; shift = modXT1[row][col]; }
if (shift) { if (codeset == 2) sendPS2(KEY_RSHIFT); else sendPS2(KS1_RSHIFT); }
sendPS2(key);
matriz[row][col] = 3;
}
void sueltateclaconsymbol(unsigned char row, unsigned char col, enum KBMODE modokb)
{
unsigned char key=0, shift=0;
if(modokb==cpc) {key=mapCPC[row][col]; shift=modCPC[row][col];}
if(modokb==msx) {key=mapMSX[row][col]; shift=modMSX[row][col];}
if(modokb==c64) {key=mapC64[row][col]; shift=modC64[row][col];}
if(modokb==at8) {key=mapAT8[row][col]; shift=modAT8[row][col];}
if(modokb==bbc) {key=mapBBC[row][col]; shift=modBBC[row][col];}
if(modokb==aco) {key=mapACO[row][col]; shift=modACO[row][col];}
if(modokb==ap2) {key=mapAP2[row][col]; shift=modAP2[row][col];}
if(modokb==vic) {key=mapVIC[row][col]; shift=modVIC[row][col];}
if(modokb==ori) {key=mapORI[row][col]; shift=modORI[row][col];}
if(modokb==sam) {key=mapSAM[row][col]; shift=modSAM[row][col];}
if(modokb==jup) {key=mapJUP[row][col]; shift=modJUP[row][col];}
if(modokb==xt1) {key=mapXT1[row][col]; shift=modXT1[row][col];}
if(codeset==2) {sendPS2(0xF0);sendPS2(key);} else sendPS2(key+KS1_RELEASE);
if(shift) {if(codeset==2) {sendPS2(0xF0); sendPS2(KEY_RSHIFT);} else sendPS2(KS1_RSHIFT+KS1_RELEASE); }
matriz[row][col]=0;
}
/*
void pulsaysueltateclaconshift(unsigned char row, unsigned char col, unsigned char key)
{
unsigned char cursores=0;
if(!key) //si no esta mapeada saca la mayuscula
{
if(codeset==2) sendPS2(KEY_RSHIFT); else sendPS2(KS1_RSHIFT);//_delay_us(5);
if(codeset==2) sendPS2(mapZX[row][col]); else sendPS2(mapSET1[row][col]);
_delay_us(5);
if(codeset==2) {sendPS2(0xF0); sendPS2(mapZX[row][col]); sendPS2(0xF0); sendPS2(KEY_RSHIFT); } //_delay_us(5);
else {sendPS2(mapSET1[row][col]+KS1_RELEASE); sendPS2(KS1_RSHIFT+KS1_RELEASE);}
}else
{
if(codeset==2 && (key==KEY_LEFT || key==KEY_RIGHT || key==KEY_UP || key==KEY_DOWN)) {sendPS2(0xE0); cursores=1;} //Es una tecla del codeset2 que necesita E0
if(codeset==1 && (key==KS1_LEFT || key==KS1_RIGHT || key==KS1_UP || key==KS1_DOWN)) {sendPS2(0xE0); cursores=1;}//Es una tecla del codeset1 que necesita E0
sendPS2(key); _delay_us(5);
if(codeset==2 && (key==KEY_LEFT || key==KEY_RIGHT || key==KEY_UP || key==KEY_DOWN)) sendPS2(0xE0); //Es una tecla del codeset2 que necesita E0
if(codeset==1 && (key==KS1_LEFT || key==KS1_RIGHT || key==KS1_UP || key==KS1_DOWN)) sendPS2(0xE0); //Es una tecla del codeset1 que necesita E0
if(codeset==2) {sendPS2(0xF0); sendPS2(key);} else sendPS2(key+KS1_RELEASE); //_delay_us(5);
}
if(!cursores) _delay_ms(KBp); else if(KBc) _delay_ms(KBc); //Pequeña pausa para evitar la "super-repeticion-atodapastilla"
matriz[row][col]=0;
}
*/
void pulsateclaconshift(unsigned char row, unsigned char col, unsigned char key)
{
unsigned char cursores = 0;
if (!key) //si no esta mapeada saca la mayuscula
{
if (codeset == 2) sendPS2(KEY_RSHIFT); else sendPS2(KS1_RSHIFT);
if (codeset == 2) sendPS2(mapZX[row][col]); else sendPS2(mapSET1[row][col]);
}
else
{
if (codeset == 2 && (key == KEY_LEFT || key == KEY_RIGHT || key == KEY_UP || key == KEY_DOWN)) { sendPS2(0xE0); cursores = 1; } //Es una tecla del codeset2 que necesita E0
if (codeset == 1 && (key == KS1_LEFT || key == KS1_RIGHT || key == KS1_UP || key == KS1_DOWN)) { sendPS2(0xE0); cursores = 1; }//Es una tecla del codeset1 que necesita E0
sendPS2(key);
}
matriz[row][col] = 3;
}
void sueltateclaconshift(unsigned char row, unsigned char col, unsigned char key)
{
unsigned char cursores = 0;
if (!key) //si no esta mapeada saca la mayuscula
{
if (codeset == 2) { sendPS2(0xF0); sendPS2(mapZX[row][col]); sendPS2(0xF0); sendPS2(KEY_RSHIFT); }
else { sendPS2(mapSET1[row][col] + KS1_RELEASE); sendPS2(KS1_RSHIFT + KS1_RELEASE); }
}
else
{
if (codeset == 2 && (key == KEY_LEFT || key == KEY_RIGHT || key == KEY_UP || key == KEY_DOWN)) sendPS2(0xE0); //Es una tecla del codeset2 que necesita E0
if (codeset == 1 && (key == KS1_LEFT || key == KS1_RIGHT || key == KS1_UP || key == KS1_DOWN)) sendPS2(0xE0); //Es una tecla del codeset1 que necesita E0
if (codeset == 2) { sendPS2(0xF0); sendPS2(key); }
else sendPS2(key + KS1_RELEASE);
}
matriz[row][col] = 0;
}
Código: Seleccionar todo
//Si esta pulsada la tecla symbol se pulsa y suelta esa tecla
if (symbolmod == 3)
{
for (r = 0; r<ROWS; r++) for (c = 0; c<COLS; c++)
{
//if(matriz[r][c]>1 && matriz[r][c]<4) pulsaysueltateclaconsymbol(r,c,modo);
if (matriz[r][c] == 2) pulsateclaconsymbol(r, c, modo);
if (matriz[r][c] == 1) sueltateclaconsymbol(r, c, modo);
//if(matriz[r][c]==1) matriz[r][c]=0; //Si esta marcada para soltar se pone a 0
}
}
//Si esta pulsada la tecla shift se pulsa y suelta esa tecla
if (shiftmod == 3)
{
for (r = 0; r<ROWS; r++) for (c = 0; c<COLS; c++)
{
//if(matriz[r][c]>1 && matriz[r][c]<4) { if(codeset==2) pulsaysueltateclaconshift(r,c,mapEXT[r][c]); else pulsaysueltateclaconshift(r,c,mapEXT1[r][c]); }
if (matriz[r][c] == 2) { if (codeset == 2) pulsateclaconshift(r, c, mapEXT[r][c]); else pulsateclaconshift(r, c, mapEXT1[r][c]); }
if (matriz[r][c] == 1) { if (codeset == 2) sueltateclaconshift(r, c, mapEXT[r][c]); else sueltateclaconshift(r, c, mapEXT1[r][c]); }
}
}
Y eso es todo amigos
, ahora sí, a disfrutarlo a tope