Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.
La shoutbox n'est pas chargée par défaut pour des raisons de performances. Cliquez pour charger.

Forum Casio - Autres questions


Index du Forum » Autres questions » key_down() bugs out GetKey()
Redcmd Hors ligne Membre Points: 380 Défis: 7 Message

key_down() bugs out GetKey()

Posté le 06/06/2019 14:54

I'm having a problem with key_down() messing with getkey()
I've tested usefill.c and input.c keydown commands
The problem is when that command is run, while there is no key currently being held down, when the next time GetKey() is run it only works when a key on a certain row is pushed (Like only keys on the 2nd to top row work)

Run the code
press a random key
wait for timer
press another random key
it should restart the timer, but it doesn't
any key on the 2nd to top row worked for me, but the rest didn't

while (1) {
        PrintXY(10, 10, "Press any key", 0);

        GetKey(&key);

        Bdisp_AllClr_DDVRAM();

        sprintf(&string, "%d", key);
        PrintXY(10, 20, string, 0);

        for (k = 0; k < 10; k++) {
            sprintf(&string, "%d", k);
            PrintXY(60, 30, string, 0);
            Bdisp_PutDisp_DD();

            Sleep(100);
        }
        key_down(28);
    }


This is part of the code for the keydown() from usefill.c / input.c
memcpy(&key, keyboardregister, sizeof(unsigned short) << 3);
        row = code % 10;
        return (0 != (key[row >> 1] & 1 << code / 10 - 1 + ((row & 1) << 3)));


Sorry; I don't know french, I'm using google translate.


Lephenixnoir Hors ligne Administrateur Points: 24235 Défis: 170 Message

Citer : Posté le 18/06/2019 13:23 | #


     #define OS (3 + !(*(volatile unsigned short*)0xFFFFFF80 || *(volatile unsigned short*)0xFFFFFF84))

This looks like a new detection method, but I'm not very confident. Both of these addresses ought to be address errors on SH4. Plus, although FRQCR will certainly not be 0, the WDT could run on SH3. How did you find this one?

The delay()'s going to be optimized out.

It seems to work fine when it only gets run when the KeyDown() is run?

I fought with that for a long time, my conclusion was that if you don't read the keyboard registers often enough, it will eventually return glichty data. Your example does not invalidate this conclusion yet because you run a lot of KeyDown() in your critical loop, so there's not delay between them. But any more information is welcome. See this topic (casiopeia.net) for more details.

is (void*)0xa44b0000 a memory address which the memory for the keys are located or is it a 'function' which gets the memory address of the keys?

It's the address of a peripheral module whose 6 first registers are 16-bit and hold the key state of the keyboard. There's definitely "something" backing up this module, but I don't know what. Maybe a fairly complicated circuit.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Redcmd Hors ligne Membre Points: 380 Défis: 7 Message

Citer : Posté le 18/06/2019 14:24 | #


I got that code from Sentaro21 in his comment above
This looks like a new detection method, but I'm not very confident.

As OS for SH3 is up to 2.04, isOS2 judgment can not be used. This is a judgment used in C.Basic. https://www.planet-casio.com/Fr/forums/topic14525-25-windmill-moteur-graphique-3d-new-demo.html#164573

I forgot to comment this in: //3 for SH3: 4 for SH4

Whats FRQCR and WDT?
although FRQCR will certainly not be 0, the WDT could run on SH3


Wasn't thinking about that
Your example does not invalidate this conclusion yet because you run a lot of KeyDown() in your critical loop


In what way? keys stuck on/off? everything bit shifted? only 6 keys can update their state everytime scanKeyboard is run?
It will eventually return glichty data.


Lephenixnoir Hors ligne Administrateur Points: 24235 Défis: 170 Message

Citer : Posté le 18/06/2019 14:53 | #


(Note: for quotes, the proper syntax is [quote]text[/quote], the parameter of the opening tag is when you mention the author.)

Okay, since it's from Sentaro, let's say it's safe. I'll ask him if I have any doubt. xD

FRQCR is the frequency control register of the clock generator. This is the value that sits at address 0xffffff80. The WDT is the watchdog timer and the register located at 0xffffff84 is its counter. If the WDT runs and this counter hits 0, the calculator resets.

So in short Sentaro is looking at some hardware's configuration to determine whether this is an SH3 or an SH4. What bugs me is that on SH4 there is no register sitting at these adresses, so accessing them ought to be an error.

Well, never mind.

In what way? keys stuck on/off? everything bit shifted? only 6 keys can update their state everytime scanKeyboard is run?

Mainly the bits associated with pressed keys stay at 1 when you release the keys. The least often you access the registers, the most often this phenomenon occurs.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Redcmd Hors ligne Membre Points: 380 Défis: 7 Message

Citer : Posté le 19/06/2019 05:13 | #


Is there anyway to run a function before int AddIn_main(int isAppli, unsigned short OptionNum)?
Like I want to grab which OS version it is before running the main function
other wise I have to call a function from within main 'GetOS();'
or have a 'variable' OS: #define OS (3+!(mem address stuff))
Lephenixnoir Hors ligne Administrateur Points: 24235 Défis: 170 Message

Citer : Posté le 19/06/2019 05:22 | #


Can't you just initialize a global variable when the main function starts? :o
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Sentaro21 Hors ligne Membre Points: 877 Défis: 0 Message

Citer : Posté le 19/06/2019 10:37 | #


Lephenixnoir a écrit :
Okay, since it's from Sentaro, let's say it's safe. I'll ask him if I have any doubt. xD

FRQCR is the frequency control register of the clock generator. This is the value that sits at address 0xffffff80. The WDT is the watchdog timer and the register located at 0xffffff84 is its counter. If the WDT runs and this counter hits 0, the calculator resets.

So in short Sentaro is looking at some hardware's configuration to determine whether this is an SH3 or an SH4. What bugs me is that on SH4 there is no register sitting at these adresses, so accessing them ought to be an error.

Well, never mind.

Yes,
It is an unknown address in SH4A, but there was no error in the real SH4A calculators.
So I used that judgment method.
I think that there is no problem for the moment.

Je continue à développer C.Basic. (Il est compatible avec Basic Casio.)
Overclocking utilitaire Ftune/Ptune2/Ptune3 est également disponible.
Si vous avez des questions ou un rapport de bogue, n'hésitez pas à me le faire savoir.
Redcmd Hors ligne Membre Points: 380 Défis: 7 Message

Citer : Posté le 19/06/2019 12:22 | #


doing
OS = (3 + !(*(volatile unsigned short*)0xFFFFFF80 || *(volatile unsigned short*)0xFFFFFF84));
outside a function doesn't work cause it needs to be a constant

and I dont want to (but it seems I have to) put the code at the top of main()
Lephenixnoir Hors ligne Administrateur Points: 24235 Défis: 170 Message

Citer : Posté le 19/06/2019 14:09 | #


Sentaro21 a écrit :
It is an unknown address in SH4A, but there was no error in the real SH4A calculators.
So I used that judgment method.

Aren't you playing with fire
Seems fair anyway, got it!

Redcmd a écrit :
doing (...) outside a function doesn't work cause it needs to be a constant
and I dont want to (but it seems I have to) put the code at the top of main()

You could put it in a constructor if you like (not sure the SDK supports that though), but why not at the top of the main()? I fail to see a reason.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Redcmd Hors ligne Membre Points: 380 Défis: 7 Message

Citer : Posté le 20/06/2019 09:49 | #


Is there anything obviously wrong with this code?
KeyDown() is faster than IsKeyDown() but you need to input the column and row keycodes rather than just the keycode itself

//Run GetOS(); at the start of AddIn_main();
//Put #include 'KeyDown.c" at the top of your 'program.c' code

#ifndef WhatOS_Keys
    #define WhatOS_Keys

    unsigned char OS;
    unsigned char GetOS(void) {
        OS = 3 + !(*(volatile unsigned short*)0xFFFFFF80 || *(volatile unsigned short*)0xFFFFFF84);    //3: Sh3, 4: SH4
        return OS;
    }

    unsigned char CheckKeyRow(unsigned char col, unsigned char row) {
        unsigned char result = 0;
        short* PORTB_CTRL = (void*)0xA4000102;
        short* PORTM_CTRL = (void*)0xA4000118;
        char* PORTB = (void*)0xA4000122;
        char* PORTM = (void*)0xA4000138;
        char* PORTA = (void*)0xA4000120;
        short smask;
        char cmask;
        char tempPORTB;
        unsigned char rowMod8 = row % 8;
        smask = 0x0003 << (rowMod8 << 1);
        cmask = ~(1 << rowMod8);
        tempPORTB = *PORTB;
        if (row < 8) {
            *PORTB_CTRL = 0xAAAA ^ smask;
            *PORTM_CTRL = (*PORTM_CTRL & 0xFF00) | 0x00AA;
            *PORTB = cmask;
            *PORTM = (*PORTM & 0xF0) | 0x0F;
        }
        else {
            *PORTB_CTRL = 0xAAAA;
            *PORTM_CTRL = ((*PORTM_CTRL & 0xFF00) | 0x00AA) ^ smask;
            *PORTB = 0xFF;
            *PORTM = (*PORTM & 0xF0) | cmask;
        }
        result = (~(*PORTA)) >> col & 1;
        *PORTB_CTRL = 0xAAAA;
        *PORTM_CTRL = (*PORTM_CTRL & 0xFF00) | 0x00AA;
        *PORTB_CTRL = 0x5555;
        *PORTM_CTRL = (*PORTM_CTRL & 0xFF00) | 0x0055;
        *PORTB = tempPORTB;
        return result;
    }

    unsigned char scanKeyboard(unsigned char col, unsigned char row) {
        if (OS == 4) {
            unsigned char* data;
            unsigned short scan[1];
            unsigned char string[1];
            volatile unsigned short* KEYSC = (void*)0xa44b0000;
            scan[0] = KEYSC[row >> 1];    //divide by 2 and round down
            data = scan;    //How can this be opitmized?
            return (data[!(row & 1)] >> (col - 1)) & 1;
        }
        else if (OS == 3)
            return CheckKeyRow(col - 1, row);
        else
            return 0;
    }

    #define KeyDown(x, y) scanKeyboard(x, y)
    #define KeyUp(x, y) !KeyDown(x, y)
    #define IsKeyDown(x) KeyDown((unsigned char)((x) / 10), (x) % 10)
    #define IsKeyUp(x) !IsKeyDown(x)
#endif //WhatOS_Keys

Sentaro21 Hors ligne Membre Points: 877 Défis: 0 Message

Citer : Posté le 20/06/2019 11:53 | #


Lephenixnoir a écrit :
Aren't you playing with fire
Seems fair anyway, got it!
Yes, I often play with fire.
A few years ago, I made 3 CG10 bricks in the development of Ptune2.
Recently,I got some second-hand CG10/20 and repaired.

BTW,
CheckKeyRow() for SH3 may need to save the value of *PORTM too.
C.Basic did not work well without also saving of *PORTM.

Redcmd a écrit :
doing
OS = (3 + !(*(volatile unsigned short*)0xFFFFFF80 || *(volatile unsigned short*)0xFFFFFF84));
outside a function doesn't work cause it needs to be a constant

and I dont want to (but it seems I have to) put the code at the top of main()
It is enough to check CPU once at the beginning of the program, so
I think that it is not necessary to #define.
Je continue à développer C.Basic. (Il est compatible avec Basic Casio.)
Overclocking utilitaire Ftune/Ptune2/Ptune3 est également disponible.
Si vous avez des questions ou un rapport de bogue, n'hésitez pas à me le faire savoir.
Redcmd Hors ligne Membre Points: 380 Défis: 7 Message

Citer : Posté le 20/06/2019 21:41 | #


Sentaro21 a écrit :
CheckKeyRow() for SH3 may need to save the value of *PORTM too.

Thx! That fixed the problem where the menu key wouldn't work unless running IsKeyDown(48); before GetKey();

Ajouté le 24/06/2019 à 01:39 :
I'm getting Phantom key presses on the emulator
If Im holding down a key, other keys can be pressed down, but only for like a split second
Doesn't worry me too much because it only happens on the emulator, not my calc

Sentaro21 have you ever experience this?
Lephenixnoir Hors ligne Administrateur Points: 24235 Défis: 170 Message

Citer : Posté le 24/06/2019 01:40 | #


Does this happen with one, or several pressed keys? The only situation I'm aware of where this problem occurs is ghosting.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Redcmd Hors ligne Membre Points: 380 Défis: 7 Message

Citer : Posté le 24/06/2019 01:44 | #


I can hold down a single key or multiple keys at once and it still happens
Then after a random amount of time, could be instant, could be after 6sec a random key gets tapped down for a very short amount of time

I have code like
if(IsKeyDown(UP))
move_up()
if(IsKeyDown(DOWN))
move_down()

etc...
and if Im holding down like key 8 or something
IsKeyDown(DOWN) gets triggered randomly

I've defined IsKeyDown(x) as KeyDown(x) which is the CheckKeyRow() code

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2024 | Il y a 103 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd