NINTV-DS/arm9/source/emucore/ECSKeyboard.cpp

175 lines
7.2 KiB
C++

// =====================================================================================
// Copyright (c) 2021-2023 Dave Bernazzani (wavemotion-dave)
//
// Copying and distribution of this emulator, its source code and associated
// readme files, with or without modification, are permitted in any medium without
// royalty provided the this copyright notice is used and wavemotion-dave (NINTV-DS)
// and Kyle Davis (BLISS) are thanked profusely.
//
// The NINTV-DS emulator is offered as-is, without any warranty.
// =====================================================================================
#include "ECSKeyboard.h"
#include "HandController.h"
UINT8 ecs_key_pressed = 0;
ECSKeyboard::ECSKeyboard(INT32 id)
: InputConsumer(id),
directionIO(0),
rowsOrColumnsToScan(0)
{
memset(rowInputValues, 0, sizeof(rowInputValues));
}
ECSKeyboard::~ECSKeyboard()
{
}
void ECSKeyboard::resetInputConsumer()
{
rowsOrColumnsToScan = 0;
for (UINT16 i = 0; i < 8; i++)
rowInputValues[i] = 0;
}
// $00FE | $00FF bits
// bits | 0 1 2 3 4 5 6 7
// ------+-----------------------------------------------------------------
// 0 | left, period, scolon, p, esc, 0, enter, [n/a]
// 1 | comma, m, k, i, 9, 8, o, l
// 2 | n, b, h, y, 7, 6, u, j
// 3 | v, c, f, r, 5, 4, t, g
// 4 | x, z, s, w, 3, 2, e, d
// 5 | space, down, up, q, 1, right, ctl, a
// 6 | [n/a], [n/a], [n/a], [n/a], [n/a], [n/a], [n/a], shift
void ECSKeyboard::evaluateInputs()
{
extern UINT8 bUseECS;
for (UINT16 i = 0; i < 8; i++) rowInputValues[i] = 0x00;
if (ecs_key_pressed == 255) // No mini-keyboard so just use dual-purpose the main keypad
{
if (ds_key_input[0][0]) rowInputValues[5] |= 0x10; // '1'
if (ds_key_input[0][1]) rowInputValues[4] |= 0x20; // '2'
if (ds_key_input[0][2]) rowInputValues[4] |= 0x10; // '3'
if (ds_key_input[0][3]) rowInputValues[3] |= 0x20; // '4'
if (ds_key_input[0][4]) rowInputValues[3] |= 0x10; // '5'
if (bUseECS == 2) // Special for Mind Strike which needs START to run... sigh...
{
if (ds_key_input[0][5]) rowInputValues[4] |= 0x04; // 'S'
if (ds_key_input[0][6]) rowInputValues[3] |= 0x40; // 'T'
if (ds_key_input[0][7]) rowInputValues[5] |= 0x80; // 'A'
if (ds_key_input[0][8]) rowInputValues[3] |= 0x08; // 'R'
}
else
{
if (ds_key_input[0][5]) rowInputValues[2] |= 0x20; // '6'
if (ds_key_input[0][6]) rowInputValues[2] |= 0x10; // '7'
if (ds_key_input[0][7]) rowInputValues[1] |= 0x20; // '8'
if (ds_key_input[0][8]) rowInputValues[1] |= 0x10; // '9'
}
if (ds_key_input[0][9]) rowInputValues[5] |= 0x01; // SP
if (ds_key_input[0][10]) rowInputValues[2] |= 0x01; // 'N'
if (ds_key_input[0][11]) rowInputValues[0] |= 0x40; // CR
}
else
{
// If a key on the ECS Mini-Keyboard was pressed...
switch (ecs_key_pressed)
{
case (1) : rowInputValues[5] |= 0x10; break; // '1'
case (2) : rowInputValues[4] |= 0x20; break; // '2'
case (3) : rowInputValues[4] |= 0x10; break; // '3'
case (4) : rowInputValues[3] |= 0x20; break; // '4'
case (5) : rowInputValues[3] |= 0x10; break; // '5'
case (6) : rowInputValues[2] |= 0x20; break; // '6'
case (7) : rowInputValues[2] |= 0x10; break; // '7'
case (8) : rowInputValues[1] |= 0x20; break; // '8'
case (9) : rowInputValues[1] |= 0x10; break; // '9'
case (10): rowInputValues[0] |= 0x20; break; // '0'
case (11): rowInputValues[5] |= 0x80; break; // 'A'
case (12): rowInputValues[2] |= 0x02; break; // 'B'
case (13): rowInputValues[3] |= 0x02; break; // 'C'
case (14): rowInputValues[4] |= 0x80; break; // 'D'
case (15): rowInputValues[4] |= 0x40; break; // 'E'
case (16): rowInputValues[3] |= 0x04; break; // 'F'
case (17): rowInputValues[3] |= 0x80; break; // 'G'
case (18): rowInputValues[2] |= 0x04; break; // 'H'
case (19): rowInputValues[1] |= 0x08; break; // 'I'
case (20): rowInputValues[2] |= 0x80; break; // 'J'
case (21): rowInputValues[1] |= 0x04; break; // 'K'
case (22): rowInputValues[1] |= 0x80; break; // 'L'
case (23): rowInputValues[1] |= 0x02; break; // 'M'
case (24): rowInputValues[2] |= 0x01; break; // 'N'
case (25): rowInputValues[1] |= 0x40; break; // 'O'
case (26): rowInputValues[0] |= 0x08; break; // 'P'
case (27): rowInputValues[5] |= 0x08; break; // 'Q'
case (28): rowInputValues[3] |= 0x08; break; // 'R'
case (29): rowInputValues[4] |= 0x04; break; // 'S'
case (30): rowInputValues[3] |= 0x40; break; // 'T'
case (31): rowInputValues[2] |= 0x40; break; // 'U'
case (32): rowInputValues[3] |= 0x01; break; // 'V'
case (33): rowInputValues[4] |= 0x08; break; // 'W'
case (34): rowInputValues[4] |= 0x01; break; // 'X'
case (35): rowInputValues[2] |= 0x08; break; // 'Y'
case (36): rowInputValues[4] |= 0x02; break; // 'Z'
case (37): rowInputValues[0] |= 0x01; break; // LEFT
case (38): rowInputValues[5] |= 0x02; break; // DOWN
case (39): rowInputValues[5] |= 0x04; break; // UP
case (40): rowInputValues[5] |= 0x20; break; // RIGHT
case (41): rowInputValues[5] |= 0x01; break; // SPACE
case (42): rowInputValues[0] |= 0x40; break; // RETURN (CR)
}
}
}
UINT16 ECSKeyboard::getInputValue()
{
UINT16 inputValue = 0;
if ((directionIO & 0xC0) == 0x40) // Normal key scanning row/column
{
UINT16 rowMask = 1;
for (UINT16 row = 0; row < 8; row++)
{
if ((rowsOrColumnsToScan & rowMask) == 0)
{
inputValue |= rowInputValues[row];
}
rowMask = (UINT16)(rowMask << 1);
}
}
else if ((directionIO & 0xC0) == 0x80) // Transposed key scanning column/row
{
UINT16 colMask = 1;
for (UINT16 col = 0; col < 8; col++)
{
if ((rowsOrColumnsToScan & colMask) == 0)
{
for (UINT16 i=0; i<8; i++)
{
if (rowInputValues[i] & (1<<col)) inputValue |= (1<<i);
}
}
colMask = (UINT16)(colMask << 1);
}
}
return (UINT16)(0xFF ^ inputValue);
}
void ECSKeyboard::setOutputValue(UINT16 value)
{
this->rowsOrColumnsToScan = value;
}
void ECSKeyboard::setDirectionIO(UINT16 value)
{
this->directionIO = value;
}