vxKernel/src/modules/keyboard/keycache.c

105 lines
1.9 KiB
C

#include <vhex/keyboard.h>
#include <vhex/drivers/cpu.h>
/* Internal cache, used like chained list.
@note:
The KEYSC have 6 key data 16-bits registers this is why we used 6 * 16 = 96
cache slots. */
struct keycache_s keycache[96];
struct keycache_s *keylist;
//---
// Private functions
//---
/* keycache_alloc() : Try to alloc a new keycache node */
static struct keycache_s *keycache_alloc(int keycode, int keyframe)
{
void *node;
cpu_atomic_start();
node = NULL;
for (int i = 0; i < 96 ; ++i) {
if (keycache[i].keycode == KEY_UNUSED) {
keycache[i].keycode = keycode;
keycache[i].keyframe = keyframe;
keycache[i].repeated = 0;
node = &keycache[i];
break;
}
}
cpu_atomic_end();
return (node);
}
//---
// Secret entries
//---
/* keycache_init() : keycache constructor */
void keycache_init(void)
{
for (int i = 0; i < 96 ; ++i) {
keycache[i].keycode = KEY_UNUSED;
keycache[i].next = NULL;
}
keylist = NULL;
}
//---
// Public API
//---
/* keycache_update() : Add / update key code node */
void keycache_update(int row, int column, uint8_t keyframe)
{
struct keycache_s *node;
uint8_t keycode;
keycode = KEYCODE_GEN(row, column);
cpu_atomic_start();
node = keylist;
while (node != NULL) {
if (node->keycode == keycode) {
node->keyframe = keyframe;
break;
}
node = node->next;
}
if (node == NULL) {
node = keycache_alloc(keycode, keyframe);
if (node != NULL) {
node->next = keylist;
keylist = node;
}
}
cpu_atomic_end();
}
/* keycache_clean() : Remove dirty node */
void keycache_clean(int keyframe)
{
struct keycache_s **current_node;
cpu_atomic_start();
current_node = &keylist;
while (*current_node != NULL) {
if ((*current_node)->keyframe != keyframe) {
(*current_node)->keycode = KEY_UNUSED;
*current_node = (*current_node)->next;
continue;
}
(*current_node)->repeated = (*current_node)->repeated + 1;
current_node = &(*current_node)->next;
}
cpu_atomic_end();
}