Seuls les membres ayant 30 points peuvent parler sur le chat.

Forum Casio - Autres questions


Index du Forum » Autres questions » key_down() bugs out GetKey()
RedcmdHors ligneMembrePoints: 211 Défis: 5 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.


Pages : 1, 2Suivante
LephenixnoirHors ligneAdministrateurPoints: 16786 Défis: 140 Message

Citer : Posté le 06/06/2019 15:06 | #


Is that Simon Lothar's CheckKeyRow() function by any chance? I've seen such a problem when experimenting with my keyboard driver, and honestly it's pretty bad.

Anyway, GetKey() uses interrupts to be notified of events, whereas key_down() reads I/O lines on-the-fly. The two just can't mix, and you probably should use GetKey() everywhere, especially if you have a timer.

If you need a GetKey() with a timeout, see if GetKeyWait() could fit your needs. This function is buggy and will never return the pressed key code. This can be solved by calling the related syscall, just don't be surprised if you try it directly in the SDK.
RedcmdHors ligneMembrePoints: 211 Défis: 5 Message

Citer : Posté le 06/06/2019 22:59 | #


Is that Simon Lothar's CheckKeyRow() function by any chance? I've seen such a problem when experimenting with my keyboard driver, and honestly it's pretty bad.

Probably is, I got different libs from
https://www.planet-casio.com/Fr/forums/topic9901-1-[C]Easy-Coding.html
https://www.planet-casio.com/Fr/forums/topic13167-1-[Librairie-C]-Controle-avance-du-clavier-V2-corrigee.html
https://www.planet-casio.com/Fr/forums/topic13183-1-[bibliotheque-C]usefull.h--plein-de-fonctions-utiles-!.html

you probably should use GetKey() everywhere, especially if you have a timer.

Im trying to make a 2 player snake game, which requires me to be able to test to see if theres 2 different keys pushed down at the same time.

you probably should use GetKey() everywhere, especially if you have a timer.If you need a GetKey() with a timeout, see if GetKeyWait() could fit your needs. This function is buggy and will never return the pressed key code. This can be solved by calling the related syscall, just don't be surprised if you try it directly in the SDK.

I need a non-pausing KeyDown() while the game is running and I was using GetKey() for menu stuff
Could I do something like test to see if anykey is down then run KeyDown() or should I just use KeyDown() for everything?
How would I get [Menu] key to exit to menu then?
RedCMD#4299 - Discord
Mandelbrot SNKEmini Minesweeper Sudoku
LephenixnoirHors ligneAdministrateurPoints: 16786 Défis: 140 Message

Citer : Posté le 07/06/2019 00:16 | #


Okay, so two simultaneous key presses is where you can't use GetKey() anymore. You have to use key_down() at least in this section of the program, and you need to do it "properly".

Your input loop must be either all-GetKey() or all-key_down(). In the section where you use key_down(), you should rely on the timer to introduce delays and regularly check whether one or more of the keys are pressed. (A major advantage of that over using GetKey() is that GetKey() may not have the delays you need. Its delays are irregular.)

In this situation, you can't return to menu directly. You could use a trick but there'd be trouble when you come back into the app. The safest way, I suppose, is to have a pause menu driven by GetKey().
RedcmdHors ligneMembrePoints: 211 Défis: 5 Message

Citer : Posté le 07/06/2019 01:00 | #


If key_down(54) is run when no key is currently being pressed down (54 is char 9) then if GetKey(&key) is run afterwards, only keys in the same row as char_9 work, every other key just doesn't do anything

Im using GetKey() to pause the game, when the user presses any button it unpauses, but if the menu key is paused it should go to the menu
So I can replace GetKey(&key) with GetKeyWait(0,0,0,&key)?
A work around is to use GetKeyWait(1,0,0,&key) to check if any key is pressed, then run key_down() - this is to stop key_down() being run when no keys are pressed at that moment - doesn't work, was able to still break it

The code above is not my snake game, it was just to show that GetKey() gets stuck after running key_down()
RedCMD#4299 - Discord
Mandelbrot SNKEmini Minesweeper Sudoku
LephenixnoirHors ligneAdministrateurPoints: 16786 Défis: 140 Message

Citer : Posté le 07/06/2019 01:15 | #


Redcmd a écrit :
If key_down(54) is run when no key is currently being pressed down (54 is char 9) then GetKey(&key) is run afterwards only keys in the same row as char_9 work, every other key just doesn't do anything

The KeyDown() function from EasyCoding is Simon's routine and I have experienced bugs with it before, such as the one you described. Don't use it as is. Also, this is a function for SH3-based models, which are extremely rare today. How old is the calculator you're targeting?

Ninestar's input.c library is also using Simon's CheckKeyRow(), so you ought to avoid that as well on SH4.

And... it's the same for usefull. All of them use Simon's incomplete routine.

Oh, now I remember why it is buggy! The data port is not restored after the call. You need to save the value of *PORTB and restore it at the end of CheckKeyRow().

But really, this method of reading the keyboard is for SH3 calculators. Check your OS version, if it's 02.xx.xxx1 then you have an SH4 calculator and you should remember that it is not the canonical way to do it.

Im using GetKey() to pause the game, when the user presses any button it unpauses, but if the menu key is paused it should go to the menu

You just need to call GetKey(). If the user presses the menu key, then GetKey() will go to the menu but the call will not terminate. Only if the user returns in the application and presses a new key will GetKey() return. Menu management is transparent for you.

A work around is to use GetKey() to check if any key is pressed, then run key_down() - this is to stop key_down() being run when no keys are pressed at that moment

This is likely not going to work, and it's still pretty bad taste if it does. Using the timer to schedule your event loop would give you regular intervals, FPS control and rid you of many inputs GetKey() could wrongly interpret for you.

The code above is not my snake game, it was just to show that GetKey() gets stuck after running key_down()

Let's sum up: to solve this you need to save *PORTB and restore it in CheckKeyRow(). This will possibly make your code work, and the rest is up to you. But I strongly suggest getting rid of the GetKey()/key_down() combo which has been bad in the past.
RedcmdHors ligneMembrePoints: 211 Défis: 5 Message

Citer : Posté le 07/06/2019 01:28 | #


I have a 9750GII, OS upgraded to SH4/02.04.0201

Who else has a 'IsKeyDown() routine that works 100% without bugs on my calc? (I dont care about SH3)

How would I save and restore *PORTB?
Like this?
[code]
unsigned char CheckKeyRow(unsigned char code) {
tempPORTB = *PORTB;
//row, column and key code stuff
*PORTB = tempPORTB;
}
[/code]

RedCMD#4299 - Discord
Mandelbrot SNKEmini Minesweeper Sudoku
LephenixnoirHors ligneAdministrateurPoints: 16786 Défis: 140 Message

Citer : Posté le 07/06/2019 01:32 | #


Yes, that would be the way. But on SH4 it is much faster to use the following scan procedure:

unsigned short scan[6];
volatile uint16_t *KEYSC = (void *)0xa44b0000;

for(int i = 0; i < 6; i++) scan[i] = KEYSC[i];

And that's all. Every key corresponds to a certain bit in the array, which is organized with one byte per row (although it is read in words) in pretty much the same way as on SH3.
RedcmdHors ligneMembrePoints: 211 Défis: 5 Message

Citer : Posté le 07/06/2019 07:20 | #


Sorry but I dont know how or where to put that code

Do you have an example program that has this code in it?
Just so I can see how its implemented and used

IDK how to fix these errors
(81) : C2500 (E) Illegal token "*"
(83) : C2225 (E) Undeclared name "KEYSC"
(83) : C2233 (E) Illegal array reference

RedCMD#4299 - Discord
Mandelbrot SNKEmini Minesweeper Sudoku
LephenixnoirHors ligneAdministrateurPoints: 16786 Défis: 140 Message

Citer : Posté le 07/06/2019 13:47 | #


Oh, sorry ! The scan array contains a complete copy of the keyboard state. The idea is to execute the two last lines regularly (generally you want to do this with a timer) and then read scan when you want to check if a key is pressed. So you have two choices :

1. Either you use a lot of functions from input/usefull/EasyCoding and you should edit them; replace their key array with scan and the CheckKeyRow() function with the two other lines. I can help for this is you indicate which library you're interested in;

2. Or you just declare scan in your own program and you wrap the other two lines in a timer callback like this:

unsigned short scan[16] = { 0 };

void scan_keyboard(void)
{
    volatile unsigned short *KEYSC = (void *)0xa44b0000;
    for(int i = 0; i < 6; i++) scan[i] = KEYSC[i];
}

int key_down(int row, int col)
{
    unsigned char *data = scan;
    return (data[row] >> col) & 1;
}

SetTimer(ID_USER_TIMER1, 50, scan_keyboard);

The key codes are replaced with "matrix codes" which tell the row and column of the key; it is not unusual to define keycodes as "10*row+column" (or the converse), this is the case in Casio Basic for instance.

The errors you get is because I had left a uint16_t in the code. This is a type for 16-bit integers but the SDK does not use this name, so I replaced it with unsigned short. Sorry for this!
RedcmdHors ligneMembrePoints: 211 Défis: 5 Message

Citer : Posté le 08/06/2019 06:36 | # | Fichier joint


error reading nonexisting memory - attached file

oh and the SDK doesn't support 'int i' inside the for loop
I just had to declare it outside the function
RedCMD#4299 - Discord
Mandelbrot SNKEmini Minesweeper Sudoku
Sentaro21Hors ligneMembrePoints: 708 Défis: 0 Message

Citer : Posté le 08/06/2019 09:16 | #


Lephenixnoir a écrit :
Oh, now I remember why it is buggy! The data port is not restored after the call. You need to save the value of *PORTB and restore it at the end of CheckKeyRow().

It seems to be able to fix the freeze bug of Getkey1 of C.Basic on SH3.
Thanks very much!
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.
RedcmdHors ligneMembrePoints: 211 Défis: 5 Message

Citer : Posté le 08/06/2019 11:38 | #


It seems to be able to fix the freeze bug of Getkey1 of C.Basic on SH3. a écrit :

Does the [Menu] key still get frozen?

Ajouté le 08/06/2019 à 16:15 :
Still getting this error:
Execution has stopped due to an error! Nonexisting memory by data read access at A44B0000
when this line gets run
scan[i] = KEYSC[i];


What am I not doing? or is it just a tiny spelling error?
RedCMD#4299 - Discord
Mandelbrot SNKEmini Minesweeper Sudoku
LephenixnoirHors ligneAdministrateurPoints: 16786 Défis: 140 Message

Citer : Posté le 08/06/2019 16:19 | #


Sentaro21 a écrit :
It seems to be able to fix the freeze bug of Getkey1 of C.Basic on SH3.
Thanks very much!

You're very welcome!

Redcmd a écrit :
Execution has stopped due to an error! Nonexisting memory by data read access at A44B0000

The emulator runs an SH3 system, and there is no robust keyboard access method that works on both SH3 and SH4...

I personally have two drivers, one for the port-driver interface of the SH3, similar to CheckKeyRow() after it is fixed, and one for the key matrix of the SH4, which I just gave you. The SH4 can use ports but it's less reliable and it's not the same ports as the SH3.

I realize this is getting complicated for you, I'm sorry about that. >_>

You should not have this error if you try on-calc.
RedcmdHors ligneMembrePoints: 211 Défis: 5 Message

Citer : Posté le 08/06/2019 16:23 | #


Ahh I thought the emulator was on SH4, but that makes sense since it has never been updated

Ok I think I know what to do now... I think

Ajouté le 08/06/2019 à 16:54 :
I think I got it working
Emulator is fine, cant check calc until later tomorrow morning
GetKey() is the same across both SH4 and SH3 right?

'isOS2' stands for SH4?
RedCMD#4299 - Discord
Mandelbrot SNKEmini Minesweeper Sudoku
LephenixnoirHors ligneAdministrateurPoints: 16786 Défis: 140 Message

Citer : Posté le 08/06/2019 17:19 | #


Yes GetKey() is the same.

I dont' know about isOS2(). That seems likely SH3 vs SH4. If you can point me the source I will be able to tell.
Sentaro21Hors ligneMembrePoints: 708 Défis: 0 Message

Citer : Posté le 09/06/2019 11:25 | #


@Lephenixnoir
isOS2 is like this.
#define isOS2 (OSVersionAsInt() >= 0x02020000)


Redcmd a écrit :
'isOS2' stands for SH4?
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
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.
RedcmdHors ligneMembrePoints: 211 Défis: 5 Message

Citer : Posté le 09/06/2019 11:31 | #


I dont remember where exalty I got this code from, might be one of the libs said above or I copy/pasted it off some code in one of the forums on this website
Code is pretty much the same as all the libs
top of part detects if SH3 or SH4 I think

#ifndef OS2Change
    #define OS2Change
    #ifndef OS2Change_GetOS2
        #define OS2Change_GetOS2
        typedef int(*sc_i2cp2sip)(char*, char*, short int*, short int*);
        const unsigned int sc0015[] = { 0xD201D002, 0x422B0009, 0x80010070, 0x0015 };
        #define GlibGetOSVersionInfo (*(sc_i2cp2sip)sc0015)
        int OSVersionAsInt(void) {
            unsigned char mainversion;
            unsigned char minorversion;
            unsigned short release;
            unsigned short build;
            GlibGetOSVersionInfo(&mainversion, &minorversion, &release, &build);
            return ((mainversion << 24) & 0xFF000000) | ((minorversion << 16) & 0x00FF0000) | (release & 0x0000FFFF);
        }
        #define isOS2 (OSVersionAsInt() >= 0x02020000)
        #define OS2(x,y) ((OSVersionAsInt() >= 0x02020000)?y:x)
    #endif
    #ifndef OS2Change_Keyboard
        #define OS2Change_Keyboard
        void delay(void) {
            char i;
            for (i = 0; i < 5; i++) {};
        }
        unsigned char CheckKeyRow(unsigned char code) {
            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;
            unsigned char column, row;

            char tempPORTB = *PORTB;

            column = code >> 4;
            row = code & 0x0F;
            smask = 0x0003 << ((row % 8) * 2);
            cmask = ~(1 << (row % 8));
            if (row < 8) {
                *PORTB_CTRL = 0xAAAA ^ smask;
                *PORTM_CTRL = (*PORTM_CTRL & 0xFF00) | 0x00AA;
                delay();
                *PORTB = cmask;
                *PORTM = (*PORTM & 0xF0) | 0x0F;
            }
            else {
                *PORTB_CTRL = 0xAAAA;
                *PORTM_CTRL = ((*PORTM_CTRL & 0xFF00) | 0x00AA) ^ smask;
                delay();
                *PORTB = 0xFF;
                *PORTM = (*PORTM & 0xF0) | cmask;
            }

            delay();
            result = (~(*PORTA)) >> column & 1;
            delay();
            *PORTB_CTRL = 0xAAAA;
            *PORTM_CTRL = (*PORTM_CTRL & 0xFF00) | 0x00AA;
            delay();
            *PORTB_CTRL = 0x5555;
            *PORTM_CTRL = (*PORTM_CTRL & 0xFF00) | 0x0055;
            delay();

            *PORTB = tempPORTB;

            return result;
        }
        unsigned char KeyDown(unsigned char keycode) {
            unsigned short key[8];
            const unsigned short* keyboardregister = (unsigned short*)0xA44B0000;
            if (isOS2) {
                unsigned char row = keycode % 10;
                memcpy(key, keyboardregister, sizeof(unsigned short) << 3);
                return (0 != (key[row >> 1] & 1 << keycode / 10 - 1 + ((row & 1) << 3)));
                //scan code goes here?
                //unsigned short scan[16] = { 0 };
                //volatile unsigned short *KEYSC = (void *)0xa44b0000;
                //for(int i = 0; i < 6; i++) scan[i] = KEYSC[i];
            }
            else {
                return CheckKeyRow((keycode % 10) + ((keycode / 10 - 1) << 4));
            }
        }
        unsigned char GetKeyMod(unsigned int* key) {
            unsigned char x, ret;

            ret = GetKey(key);

            for (x = 0; x < 80; x++)
            {
                if (KeyDown(x))
                {
                    *key = x;
                    break;
                }
            }
            return ret;
        }
        #define GetKey(x) GetKeyMod(x)
        #define IsKeyDown(x) KeyDown(x)
        #define IsKeyUp(x) !KeyDown(x)
    #endif
#endif

RedCMD#4299 - Discord
Mandelbrot SNKEmini Minesweeper Sudoku
LephenixnoirHors ligneAdministrateurPoints: 16786 Défis: 140 Message

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


If you want to detect SH3 and SH4 using the OS version, isOS2() is not reliable. It was at some point I think, but no longer.

There is a more reliable way to know. For 02.xx.xxxy OSes, the last digit y is 0 for SH3 and 1 for SH4. For 03.xx.xxxx OSes, the target is always SH4.

Or you have a hardware-based detection which is the only reliable thing in case the OS has been tweaked, as in C.Basic.

Regarding the code you posted above, you have the keyboard scan code commented with "scan code goes here?". This is not exactly the place. You should scan the keyboard regularly with a timer, and do it often. I think you can go down to 25ms with SetTimer() and this is a good start. In the timer callback you fill the scan array and then the KeyDown() procedure can read the scan array.

The reason is that you have to control the frequency of hardware access. If it's too high, you'll waste power on hardware I/O. If it's too low, the keyboard will behave strangely. I don't know why this happens specifically on SH4 but I have experienced and documented that a bit.
RedcmdHors ligneMembrePoints: 211 Défis: 5 Message

Citer : Posté le 18/06/2019 11:44 | #


so I have this code
I've tested SH3 (emulator) and SH4 (my calc) and it seems to work perfectly between both OS's
its just some test code, I'm gonna clean it all up
Why does the scanKeyboard() need to be in a timer that runs all the time?
It seems to work fine when it only gets run when the KeyDown() is run?
What sort of issues are you talking about when its not working correctly?

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?

#include "fxlib.h"
#include "stdio.h"

#ifndef OS
    #define OS (3 + !(*(volatile unsigned short*)0xFFFFFF80 || *(volatile unsigned short*)0xFFFFFF84))        //3 for SH3: 4 for SH4

    void delay(void) {
        unsigned char i;
        for (i = 0; i < 5; i++);
    }

    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;
        smask = 0x0003 << ((row % 8) * 2);
        cmask = ~(1 << (row % 8));
        tempPORTB = *PORTB;
        if (row < 8) {
            *PORTB_CTRL = 0xAAAA ^ smask;
            *PORTM_CTRL = (*PORTM_CTRL & 0xFF00) | 0x00AA;
            delay();
            *PORTB = cmask;
            *PORTM = (*PORTM & 0xF0) | 0x0F;
        }
        else {
            *PORTB_CTRL = 0xAAAA;
            *PORTM_CTRL = ((*PORTM_CTRL & 0xFF00) | 0x00AA) ^ smask;
            delay();
            *PORTB = 0xFF;
            *PORTM = (*PORTM & 0xF0) | cmask;
        }
        delay();
        result = (~(*PORTA)) >> col & 1;
        delay();
        *PORTB_CTRL = 0xAAAA;
        *PORTM_CTRL = (*PORTM_CTRL & 0xFF00) | 0x00AA;
        delay();
        *PORTB_CTRL = 0x5555;
        *PORTM_CTRL = (*PORTM_CTRL & 0xFF00) | 0x0055;
        delay();
        *PORTB = tempPORTB;
        return result;
    }

    unsigned char KeyDown(unsigned char col, unsigned char row) {
        if (OS == 3)
            return CheckKeyRow(col - 1, row);
        else {
            unsigned char i;
            unsigned char* data;
            unsigned short scan[5];
            volatile unsigned short* KEYSC = (void*)0xa44b0000;
            for (i = 0; i < 5; i++)
                scan[4 - i] = KEYSC[i];
            data = scan;
            return (data[9 - row] >> (col - 1)) & 1;
        }
    }
#endif //OS

unsigned char string[1];
unsigned int key;
unsigned int i;
unsigned char row;
unsigned char col;

int AddIn_main(int isAppli, unsigned short OptionNum) {
    sprintf(&string, "SH%d", OS);
    PrintXY(0, 30, string, 0);
    for (i = 0; i < 10000; i++) {
        for (col = 1; col <= 7; col++) {
            for (row = 0; row <= 9; row++) {
                if (KeyDown(col, row)) {
                    sprintf(&string, "%d", col * 10 + row);
                    PrintXY(5, 50, string, 0);
                    sprintf(&string, "%c", '-');
                }
                else
                    sprintf(&string, "%c", '0');
                PrintMini(90 - col * 4, 55 - row * 6, string, 0);
            }
        }
        Bdisp_PutDisp_DD();
        if (KeyDown(6, 6))
            break;
    }
    if (OS == 4)
        KillTimer(1);
    while (1)
        GetKey(&key);
    return 1;
}


#pragma section _BR_Size
unsigned long BR_Size;
#pragma section
#pragma section _TOP
int InitializeSystem(int isAppli, unsigned short OptionNum) {
    return INIT_ADDIN_APPLICATION(isAppli, OptionNum);
}
#pragma sectionction

RedCMD#4299 - Discord
Mandelbrot SNKEmini Minesweeper Sudoku
LephenixnoirHors ligneAdministrateurPoints: 16786 Défis: 140 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.
Pages : 1, 2Suivante

Planète Casio v42 © créé par Neuronix et Muelsaco 2004 - 2020 | Il y a 109 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