namespace FMTOWNS {
void KEYBOARD::initialize()
{
+ DEVICE::initialize();
key_buf = new FIFO(64);
+ cmd_buf = new FIFO(16);
register_frame_event(this);
}
void KEYBOARD::release()
{
+ cmd_buf->release();
key_buf->release();
delete key_buf;
+ delete cmd_buf;
}
void KEYBOARD::reset()
{
memset(table, 0, sizeof(table));
key_buf->clear();
+ cmd_buf->clear();
kbstat = kbdata = kbint = kbmsk = 0;
+ device_order = false;
+ repeat_start_ms = 400;
+ repeat_tick_ms = 30;
+ enable_double_pressed_cursor = true;
+ nmi_status = false;
+ write_signals(&output_intr_line, 0);
+ write_signals(&output_nmi_line, 0);
}
+void KEYBOARD::do_common_command(uint8_t cmd)
+{
+ static const int type_start_ms[] = {400, 500, 300};
+ static const int type_repeat_ms[] = {50, 30, 20};
+
+ switch(cmd) {
+ case 0xa1:
+ this->reset(); // RESET
+ break;
+ case 0xa4:
+ // Check double press (for OYAYUBI-Shift)
+ break;
+ case 0xa5:
+ // Don't check double press (for OYAYUBI-Shift)
+ break;
+ case 0xa9:
+ case 0xaa:
+ case 0xab:
+ repeat_start_ms = type_start_ms[cmd - 0xa9];
+ break;
+ case 0xac:
+ case 0xad:
+ case 0xae:
+ repeat_tick_ms = type_repeat_ms[cmd - 0xac];
+ break;
+ case 0xb0:
+ enable_double_pressed_cursor = true;
+ break;
+ case 0xb1:
+ enable_double_pressed_cursor = false;
+ break;
+ case 0xb2:
+ write_signals(&output_nmi_line, 0);
+ nmi_status = false;
+ break;
+ default:
+ break;
+ }
+}
+
+// Mame 0.216
void KEYBOARD::write_io8(uint32_t addr, uint32_t data)
{
+// out_debug_log(_T("WRITE I/O ADDR=%04X VAL=%02X"), addr, data);
switch(addr) {
case 0x600:
// data
-// kbstat |= 2;
+ kbstat &= ~0x08;
+ kbstat |= 1;
break;
case 0x602:
// command
+ if((data & 0x80) == 0x00) {
+ // Second byte
+ if((device_order) && (cmd_buf->count() > 0)) {
+ cmd_buf->write(data & 0x7f);
+ } else {
+ // Illegal
+ cmd_buf->clear();
+ device_order = false;
+ }
+ kbstat |= 0x08;
+ } else if(data & 0xe0 == 0xc0) {
+ // Device order
+ if((cmd_buf->count() > 0) && (device_order)){
+ // DO DEVICE ORDER
+ }
+ cmd_buf->clear();
+ cmd_buf->write(data & 0xff);
+ device_order = false;
+ kbstat |= 0x08;
+ } else if(data & 0xe0 == 0xa0) {
+ // Common order
+ if((cmd_buf->count() > 0) && (device_order)){
+ // DO DEVICE ORDER
+ }
+ device_order = false;
+ kbstat |= 0x08;
+ do_common_command(data);
+ }
break;
case 0x604:
kbmsk = data;
uint32_t KEYBOARD::read_io8(uint32_t addr)
{
+ uint8_t kbtmp = kbdata;
switch(addr) {
case 0x600:
kbint &= ~1;
write_signals(&output_intr_line, 0);
- kbstat &= ~1;
- return kbdata;
+ if(key_buf->empty()) {
+ kbstat &= ~1;
+ } else {
+ kbdata = key_buf->read();
+ }
+// out_debug_log(_T("READ I/O ADDR=%04X VAL=%02X"), addr, kbdata);
+ return kbtmp;
case 0x602:
+// out_debug_log(_T("READ I/O ADDR=%04X VAL=%02X"), addr, kbstat);
return kbstat;
case 0x604:
- return kbint | 0xfc;
+// out_debug_log(_T("READ I/O ADDR=%04X VAL=%02X"), addr, kbint);
+ return (((kbint & 1) != 0) ? 1 : 0) | ((nmi_status) ? 2 : 0);
+ break;
}
return 0;
}
table[code] = 1;
if(code = key_table[code]) {
// $11:CTRL, $10:SHIFT
- key_buf->write(0xa0 | (table[0x11] ? 8 : 0) | (table[0x10] ? 4 : 0));
- key_buf->write(code);
+ key_buf->write(0xc0 | (table[0x11] ? 8 : 0) | (table[0x10] ? 4 : 0));
+ key_buf->write(code & 0x7f);
}
// }
}
// if(table[code]) {
table[code] = 0;
if(code = key_table[code]) {
- key_buf->write(0xb0);
- key_buf->write(code);
+ key_buf->write(0xd0 | (table[0x11] ? 8 : 0) | (table[0x10] ? 4 : 0));
+ key_buf->write(code & 0x7f);
}
// }
}
if(!(key_buf->process_state((void *)state_fio, loading))) {
return false;
}
+ if(!(cmd_buf->process_state((void *)state_fio, loading))) {
+ return false;
+ }
state_fio->StateValue(kbstat);
state_fio->StateValue(kbdata);
state_fio->StateValue(kbint);
state_fio->StateValue(kbmsk);
+
+ state_fio->StateValue(nmi_status);
+ state_fio->StateValue(repeat_start_ms);
+ state_fio->StateValue(repeat_tick_ms);
+ state_fio->StateValue(enable_double_pressed_cursor);
+ state_fio->StateValue(device_order);
+
state_fio->StateArray(table, sizeof(table), 1);
return true;
#include "../vm.h"
#include "../../emu.h"
#include "../device.h"
+#include "../../fifo.h"
/*
ひらがな/ローマ字 ひらがな
namespace FMTOWNS {
class KEYBOARD : public DEVICE
{
-private:
+protected:
outputs_t output_intr_line;
outputs_t output_nmi_line;
FIFO *key_buf;
+ FIFO *cmd_buf;
+
uint8_t kbstat, kbdata, kbint, kbmsk;
+ int repeat_start_ms;
+ int repeat_tick_ms;
+ bool enable_double_pressed_cursor;
+ bool device_order;
+
+ bool nmi_status;
uint8_t table[256];
+
+ virtual void do_common_command(uint8_t cmd);
public:
KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
{
+ key_buf = NULL;
+ cmd_buf = NULL;
+
initialize_output_signals(&output_intr_line);
initialize_output_signals(&output_nmi_line);
+ set_device_name(_T("FM-Towns Keyboard (JIS)"));
}
~KEYBOARD() {}
void initialize();
void release();
void reset();
- void write_io8(uint32_t addr, uint32_t data);
- uint32_t read_io8(uint32_t addr);
+ void __FASTCALL write_io8(uint32_t addr, uint32_t data);
+ uint32_t __FASTCALL read_io8(uint32_t addr);
void event_frame();
bool process_state(FILEIO* state_fio, bool loading);