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.
Citer : Posté le 18/06/2019 13:23 | #
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.
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.
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.
Citer : Posté le 18/06/2019 14:24 | #
I got that code from Sentaro21 in his comment above
I forgot to comment this in: //3 for SH3: 4 for SH4
Whats FRQCR and WDT?
Wasn't thinking about that
In what way? keys stuck on/off? everything bit shifted? only 6 keys can update their state everytime scanKeyboard is run?
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.
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.
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))
Citer : Posté le 19/06/2019 05:22 | #
Can't you just initialize a global variable when the main function starts? :o
Citer : Posté le 19/06/2019 10:37 | #
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.
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.
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()
Citer : Posté le 19/06/2019 14:09 | #
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!
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.
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
//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
Citer : Posté le 20/06/2019 11:53 | #
Aren't you playing with fire
Seems fair anyway, got it!
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.
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()
I think that it is not necessary to #define.
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.
Citer : Posté le 20/06/2019 21:41 | #
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?
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.
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
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