pc98_usb: Update reset and LED control command

This commit is contained in:
tmk 2018-09-08 21:23:30 +09:00
parent cb1f428488
commit 5d24932e78
3 changed files with 68 additions and 34 deletions

View file

@ -147,6 +147,7 @@ Its scan code map is very different from standard types. This is not tested.
Other PC98 converter projects and resource
------------------------------------------
PC-9800シリーズ テクニカルデータブック HARDWARE 編 1993年 p139, p343
https://archive.org/stream/PC9800TechnicalDataBookHARDWARE1993/PC-9800TechnicalDataBook_HARDWARE1993#page/n151
https://archive.org/stream/PC9800TechnicalDataBookHARDWARE1993/PC-9800TechnicalDataBook_HARDWARE1993#page/n355
PC98 to USB
@ -158,3 +159,25 @@ http://www.tsp.ne.jp/~sawada/mago/src/gka98at.asm
scan code:
http://ixsvr.dyndns.org/usb2pc98
NOTES
-----
### Tested on
- PC-9801V
- DIGITAL WAVE Dboard
### RDY
Current firmware does not control RDY line and it is drived as low to receive data always. While sending command firmware drive the line high.
PC98 host keeps RDY line high to prevent keyboard from sending data while processing.
https://archive.org/stream/PC9800TechnicalDataBookHARDWARE1993/PC-9800TechnicalDataBook_HARDWARE1993#page/n359
### Inhibit key repeating
The command(9Ch, 70h) works with Raku Raku keybaord but not with Dboard.
### LED indicater
Dboard has LEDs but it seems to ignore LED control command.

View file

@ -43,7 +43,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define LOCKING_RESYNC_ENABLE
/* Control LED indicatiors, which doesn't work well with locking support */
//#define PC98_LED_CONTROL
#define PC98_LED_CONTROL
/* PC98 Reset Port shared with TXD */

View file

@ -68,23 +68,34 @@ static int16_t pc98_wait_response(void)
static void pc98_inhibit_repeat(void)
{
uint16_t code;
// clear recv buffer
while (serial_recv()) ;
RETRY:
_delay_ms(100);
pc98_send(0x9C);
code = pc98_wait_response();
if (code != -1) xprintf("PC98: send 9C: %02X\n", code);
if (code != 0xFA) goto RETRY;
_delay_ms(100);
pc98_send(0x70);
code = pc98_wait_response();
if (code != -1) xprintf("PC98: send 70: %02X\n", code);
if (code != 0xFA) goto RETRY;
}
static uint8_t pc98_led = 0;
static void pc98_led_set(void)
{
uint16_t code;
RETRY:
pc98_send(0x9D);
code = pc98_wait_response();
if (code != -1) xprintf("PC98: send 9D: %02X\n", code);
if (code != 0xFA) goto RETRY;
pc98_send(pc98_led);
code = pc98_wait_response();
if (code != -1) xprintf("PC98: send %02X: %02X\n", pc98_led, code);
if (code != 0xFA) goto RETRY;
}
void matrix_init(void)
{
debug_keyboard = true;
@ -99,36 +110,40 @@ void matrix_init(void)
serial_init();
// PC98 reset
/*
PC98_RST_PORT &= ~(1<<PC98_RST_BIT);
_delay_us(15);
PC98_RST_PORT |= (1<<PC98_RST_BIT);
_delay_us(13);
PC98_RDY_PORT &= ~(1<<PC98_RDY_BIT);
*/
// https://archive.org/stream/PC9800TechnicalDataBookHARDWARE1993/PC-9800TechnicalDataBook_HARDWARE1993#page/n359
PC98_RDY_PORT |= (1<<PC98_RDY_BIT); // RDY: high
PC98_RST_PORT &= ~(1<<PC98_RST_BIT); // RST: low
_delay_us(15); // > 13us
PC98_RST_PORT |= (1<<PC98_RST_BIT); // RST: high
_delay_ms(500);
_delay_ms(50);
pc98_inhibit_repeat();
// PC98 ready
PC98_RDY_PORT &= ~(1<<PC98_RDY_BIT);
// initialize matrix state: all keys off
for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
debug("init\n");
// ready to receive from keyboard
PC98_RDY_PORT &= ~(1<<PC98_RDY_BIT); // RDY: low
print("matrix_init done.\n");
return;
}
uint8_t matrix_scan(void)
{
uint16_t code;
PC98_RDY_PORT |= (1<<PC98_RDY_BIT);
//_delay_us(30);
code = serial_recv2();
PC98_RDY_PORT &= ~(1<<PC98_RDY_BIT);
if (code == -1) return 0;
if (code == -1) {
#ifdef PC98_LED_CONTROL
// Before sending command we have to make sure that there is no unprocessed key in queue
// otherwise keys will be missed during sending command
if (pc98_led) {
pc98_led_set();
pc98_led = 0;
}
#endif
return 0;
}
print_hex8(code); print(" ");
@ -154,15 +169,11 @@ uint8_t matrix_get_row(uint8_t row)
void led_set(uint8_t usb_led)
{
#ifdef PC98_LED_CONTROL
uint8_t led_state = 0x70;
if (usb_led & (1<<USB_LED_NUM_LOCK)) led_state |= (1<<0);
if (usb_led & (1<<USB_LED_CAPS_LOCK)) led_state |= (1<<2);
xprintf("led_set: %02X\n", led_state);
pc98_send(0x9D);
_delay_ms(100);
pc98_send(led_state);
// responses(FA or FC) will be ignored in matrix_scan()
#endif
// https://archive.org/stream/PC9800TechnicalDataBookHARDWARE1993/PC-9800TechnicalDataBook_HARDWARE1993#page/n161
// http://www.webtech.co.jp/company/doc/undocumented_mem/io_kb.txt
pc98_led = 0x70;
if (usb_led & (1<<USB_LED_NUM_LOCK)) pc98_led |= (1<<0);
if (usb_led & (1<<USB_LED_CAPS_LOCK)) pc98_led |= (1<<2);
xprintf("usb_led: %02X\n", usb_led);
xprintf("pc98_led: %02X\n", pc98_led);
}