和製MESSでMSX1 その5

日本語106キーボードで動作確認。キーマトリクスはここら辺を参考に実装しました。

http://d4.princess.ne.jp/msx/datas/keyscan.html

[F6]かな

[F7]CAPS

[F8]SELECT

[F9]STOP

keyboard.cpp

/*
	ASCII MSX1 Emulator 'yaMSX1'
	Skelton for retropc emulator

	Author : tanam
	Date   : 2013.06.29-

	[ keyboard ]
*/

#include "keyboard.h"
#include "../i8255.h"

static const uint8 key_map[256][2] = {
  {0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},/* 0000 */
  {7,0x20},{7,0x08},{0,0x00},{0,0x00},{0,0x00},{7,0x80},{0,0x00},{0,0x00},/* 0008 */
  {6,0x01},{6,0x02},{6,0x04},{0,0x00},{0,0x00},{0,0x00},{7,0x04},{0,0x00},/* 0010 */
  {0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},/* 0018 */
  {8,0x01},{0,0x00},{0,0x00},{0,0x00},{8,0x02},{8,0x10},{8,0x20},{8,0x80},/* 0020 */
  {8,0x40},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{8,0x04},{8,0x08},{0,0x00},/* 0028 */
  {0,0x01},{0,0x02},{0,0x04},{0,0x08},{0,0x10},{0,0x20},{0,0x40},{0,0x80},/* 0030 */
  {1,0x01},{1,0x02},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},/* 0038 */
  {0,0x00},{2,0x40},{2,0x80},{3,0x01},{3,0x02},{3,0x04},{3,0x08},{3,0x10},/* 0040 */
  {3,0x20},{3,0x40},{3,0x80},{4,0x01},{4,0x02},{4,0x04},{4,0x08},{4,0x10},/* 0048 */
  {4,0x20},{4,0x40},{4,0x80},{5,0x01},{5,0x02},{5,0x04},{5,0x08},{5,0x10},/* 0050 */
  {5,0x20},{5,0x40},{5,0x80},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},/* 0058 */
  {0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},/* 0060 */
  {0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},/* 0068 */
  {6,0x20},{6,0x40},{6,0x80},{7,0x01},{7,0x02},{6,0x10},{6,0x08},{7,0x40},/* 0070 */
  {7,0x10},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},/* 0078 */
  {0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},/* 0080 */
  {0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},/* 0088 */
  {0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},/* 0090 */
  {0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},/* 0098 */
  {0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},/* 00A0 */
  {0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},/* 00A8 */
  {0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},/* 00B0 */
  {0,0x00},{0,0x00},{2,0x01},{1,0x80},{2,0x04},{1,0x04},{2,0x08},{2,0x10},/* 00B8 */
  {1,0x20},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},/* 00C0 */
  {0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},/* 00C8 */
  {0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},/* 00D0 */
  {0,0x00},{0,0x00},{0,0x00},{1,0x40},{1,0x10},{2,0x02},{1,0x08},{0,0x00},/* 00D8 */
  {0,0x00},{0,0x00},{2,0x20},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},/* 00E0 */
  {0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},/* 00E8 */
  {0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},/* 00F0 */
  {0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},{0,0x00},/* 00F8 */
};

void KEYBOARD::initialize()
{
    memset(KeyMap,0xff,16);

	key_stat = emu->key_buffer();
	joy_stat = emu->joy_buffer();
	
	column = 0;
	break_pressed = false;
	
	// register event to update the key status
	register_frame_event(this);
}

void KEYBOARD::event_frame()
{
	bool new_pressed = (key_stat[0x13] != 0);
	if(new_pressed && !break_pressed) {
		d_cpu->write_signal(SIG_CPU_NMI, 1, 1);
	}
	break_pressed = new_pressed;
	
	update_keyboard();
}

void KEYBOARD::write_signal(int id, uint32 data, uint32 mask)
{
	if(column != (data & mask)) {
		column = data & mask;
		update_keyboard();
	}
}

void KEYBOARD::update_keyboard()
{
	for (int code=0; code < 256; code++) {
		if (key_stat[code] & 0x80) {
			KeyMap[key_map[code][0]]&=~key_map[code][1];
		} else {
			KeyMap[key_map[code][0]]|=key_map[code][1];
		}
	}

	d_pio->write_signal(SIG_I8255_PORT_B, KeyMap[column], 0xff);
}

keyboard.h

/*
	ASCII MSX1 Emulator 'yaMSX1'
	Skelton for retropc emulator

	Author : tanam
	Date   : 2013.06.29-

	[ keyboard ]
*/

#ifndef _KEYBOARD_H_
#define _KEYBOARD_H_

#include "../vm.h"
#include "../../emu.h"
#include "../device.h"

#define SIG_KEYBOARD_COLUMN	0

class KEYBOARD : public DEVICE
{
private:
	DEVICE *d_cpu, *d_pio;
	
	uint8* key_stat;
	uint32* joy_stat;
	uint8 column;
	bool break_pressed;
	byte KeyMap[16];
	
	void update_keyboard();
	
public:
	KEYBOARD(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) {}
	~KEYBOARD() {}
	
	// common functions
	void initialize();
	void event_frame();
	void write_signal(int id, uint32 data, uint32 mask);
	
	// unique functions
	void set_context_cpu(DEVICE* device) {
		d_cpu = device;
	}
	void set_context_pio(DEVICE* device) {
		d_pio = device;
	}
};

#endif