MagicEngine
Forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
 Japanese English 

Tsushin Tool Keyboard Emulation Code

 
Post new topic   Reply to topic    MagicEngine Forum Index -> General
View previous topic :: View next topic  
Author Message
Mednafen
Member
Member


Joined: 01 Jan 2006
Posts: 22

PostPosted: Wed Jun 23, 2010 2:41 pm    Post subject: Tsushin Tool Keyboard Emulation Code Reply with quote

Here's the code for the keyboard emulation for the Tsushin Tool, from Mednafen 0.9.0 WIP, if anyone's interested and doesn't want to dig through the code(or didn't know about it). It was implemented through reverse-engineering and trial-and-error with the Tsushin Tool(the actual hardware isn't available AFAIK). Its scancodes seem very similar to the PC-88, but some are different(I haven't really given much thought into seeing if there's a pattern to the scancode differences).

(I would write a document, but I'm reluctant to do that with hardware emulated only through the RE'ing of a single program)

Maybe eventually I'll try emulating the modem for the Tsushin Tool. Wink

Code:

/* Mednafen - Multi-system Emulator
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "../pce.h"
#include "../input.h"
#include "tsushinkb.h"

namespace MDFN_IEN_PCE
{

class PCE_Input_TsushinKB : public PCE_Input_Device
{
 public:

 PCE_Input_TsushinKB();

 virtual void Power(int32 timestamp);
 virtual void Write(int32 timestamp, bool old_SEL, bool new_SEL, bool old_CLR, bool new_CLR);
 virtual uint8 Read(int32 timestamp);
 virtual void Update(const void *data);
 virtual int StateAction(StateMem *sm, int load, int data_only, const char *section_name);


 private:
 bool SEL, CLR;
 uint8 TsuKBState[16];
 uint8 TsuKBLatch[16 + 2 + 1];
 uint32 TsuKBIndex;
 bool last_capslock;
};

void PCE_Input_TsushinKB::Power(int32 timestamp)
{
 SEL = CLR = 0;
 memset(TsuKBState, 0, sizeof(TsuKBState));
 memset(TsuKBLatch, 0, sizeof(TsuKBLatch));
 TsuKBIndex = 0;
 last_capslock = 0;
}

PCE_Input_TsushinKB::PCE_Input_TsushinKB()
{
 Power(0);
}

void PCE_Input_TsushinKB::Update(const void *data)
{
 uint8 *data_ptr = (uint8 *)data;
 bool capslock = TsuKBState[0xE] & 0x10;
 bool new_capslock = data_ptr[0xE] & 0x10;

 if(!last_capslock && new_capslock)
  capslock ^= 1;

 for(int i = 0; i < 16; i++)
 {
  TsuKBState[i] = data_ptr[i];
 }

 TsuKBState[0xE] = (TsuKBState[0xE] & ~0x10) | (capslock ? 0x10 : 0x00);

 last_capslock = new_capslock;
}

uint8 PCE_Input_TsushinKB::Read(int32 timestamp)
{
 uint8 ret;

 ret = ((TsuKBLatch[TsuKBIndex] >> (SEL * 4)) & 0xF);

 return(ret);
}

void PCE_Input_TsushinKB::Write(int32 timestamp, bool old_SEL, bool new_SEL, bool old_CLR, bool new_CLR)
{
 SEL = new_SEL;
 CLR = new_CLR;

 //printf("Write: %d %d %d %d\n", old_SEL, new_SEL, old_CLR, new_CLR);

 if(!old_CLR && new_CLR)
 {
  TsuKBLatch[0] = 0x02;

  for(int i = 0; i < 16; i++)
   TsuKBLatch[i + 1] = TsuKBState[i] ^ 0xFF;

  TsuKBLatch[17] = 0x02;
  TsuKBIndex = 0;
  //puts("Latched");
 }
 else if(!old_SEL && new_SEL)
 {
  TsuKBIndex = (TsuKBIndex + 1) % 18;
  if(!TsuKBIndex)
  {
   for(int i = 0; i < 16; i++)
    TsuKBLatch[i + 1] = TsuKBState[i] ^ 0xFF;
  }
 }
}

int PCE_Input_TsushinKB::StateAction(StateMem *sm, int load, int data_only, const char *section_name)
{
 SFORMAT StateRegs[] =
 {
  SFVAR(SEL),
  SFVAR(CLR),
  SFARRAY(TsuKBState, sizeof(TsuKBState)),
  SFARRAY(TsuKBLatch, sizeof(TsuKBLatch)),
  SFVAR(TsuKBIndex),
  SFVAR(last_capslock),
  SFEND
 };
 int ret =  MDFNSS_StateAction(sm, load, data_only, StateRegs, section_name);
 
 return(ret);
}

const InputDeviceInputInfoStruct PCE_TsushinKBIDII[0x80] =
{
 // 0 - DONE!
 { "kp_0", "Keypad 0", 0, IDIT_BUTTON },
 { "kp_1", "Keypad 1", 0, IDIT_BUTTON },
 { "kp_2", "Keypad 2", 0, IDIT_BUTTON },
 { "kp_3", "Keypad 3", 0, IDIT_BUTTON },
 { "kp_4", "Keypad 4", 0, IDIT_BUTTON },
 { "kp_5", "Keypad 5", 0, IDIT_BUTTON },
 { "kp_6", "Keypad 6", 0, IDIT_BUTTON },
 { NULL, "empty", 0, IDIT_BUTTON },

// 1 - DONE!
 { "kp_8", "Keypad 8", 0, IDIT_BUTTON },
 { "kp_9", "Keypad 9", 0, IDIT_BUTTON },
 { "kp_multiply", "Keypad *", 0, IDIT_BUTTON },
 { "kp_plus", "Keypad +", 0, IDIT_BUTTON },
 { "kp_equals", "Keypad =", 0, IDIT_BUTTON },
 { "kp_comma", "Keypad ,", 0, IDIT_BUTTON },
 { "kp_period", "Keypad .", 0, IDIT_BUTTON },
 { NULL, "empty", 0, IDIT_BUTTON },

// 2 - DONE!
 { "at", "@", 0, IDIT_BUTTON },
 { "a", "a", 0, IDIT_BUTTON },
 { "b", "b", 0, IDIT_BUTTON },
 { "c", "c", 0, IDIT_BUTTON },
 { "d", "d", 0, IDIT_BUTTON },
 { "e", "e", 0, IDIT_BUTTON },
 { "f", "f", 0, IDIT_BUTTON },
 { NULL, "empty", 0, IDIT_BUTTON },

// 3 - DONE!
 { "h", "h", 0, IDIT_BUTTON },
 { "i", "i", 0, IDIT_BUTTON },
 { "j", "j", 0, IDIT_BUTTON },
 { "k", "k", 0, IDIT_BUTTON },
 { "l", "l", 0, IDIT_BUTTON },
 { "m", "m", 0, IDIT_BUTTON },
 { "n", "n", 0, IDIT_BUTTON },
 { NULL, "empty", 0, IDIT_BUTTON },
 
// 4 - DONE!
 { "p", "p", 0, IDIT_BUTTON },
 { "q", "q", 0, IDIT_BUTTON },
 { "r", "r", 0, IDIT_BUTTON },
 { "s", "s", 0, IDIT_BUTTON },
 { "t", "t", 0, IDIT_BUTTON },
 { "u", "u", 0, IDIT_BUTTON },
 { "v", "v", 0, IDIT_BUTTON },
 { NULL, "empty", 0, IDIT_BUTTON },

// 5 - DONE!
 { "x", "x", 0, IDIT_BUTTON },
 { "y", "y", 0, IDIT_BUTTON },
 { "z", "z", 0, IDIT_BUTTON },
 { "left_bracket", "[", 0, IDIT_BUTTON },
 { "yen", "Yen", 0, IDIT_BUTTON },
 { "right_bracket", "]", 0, IDIT_BUTTON },
 { "caret", "^", 0, IDIT_BUTTON },
 { NULL, "empty", 0, IDIT_BUTTON },

// 6 - DONE!
 { "0", "0", 0, IDIT_BUTTON },
 { "1", "1", 0, IDIT_BUTTON },
 { "2", "2", 0, IDIT_BUTTON },
 { "3", "3", 0, IDIT_BUTTON },
 { "4", "4", 0, IDIT_BUTTON },
 { "5", "5", 0, IDIT_BUTTON },
 { "6", "6", 0, IDIT_BUTTON },
 { NULL, "empty", 0, IDIT_BUTTON },

// 7 - DONE!
 { "8", "8", 0, IDIT_BUTTON },
 { "9", "9", 0, IDIT_BUTTON },
 { "colon", ":", 0, IDIT_BUTTON },
 { "semicolon", ";", 0, IDIT_BUTTON },
 { "comma", ",", 0, IDIT_BUTTON },
 { "period", ".", 0, IDIT_BUTTON },
 { "slash", "/", 0, IDIT_BUTTON },
 { NULL, "empty", 0, IDIT_BUTTON },

// 8 - DONE enough
 { "clear", "clear", 0, IDIT_BUTTON },
 { "up", "up", 0, IDIT_BUTTON },
 { "right", "right", 0, IDIT_BUTTON },
 { NULL, "empty", 0, IDIT_BUTTON },   // Alternate backspace key on PC-88 keyboard??? { "unk80", "unknown", 0, IDIT_BUTTON },
 { "grph", "GRPH", 0, IDIT_BUTTON },
 { "kana", "カナ", 0, IDIT_BUTTON },
 { NULL, "empty", 0, IDIT_BUTTON },   // Alternate shift key on PC-88 keyboard??? { "unk83", "unknown", 0, IDIT_BUTTON },
 { NULL, "empty", 0, IDIT_BUTTON },

// 9 - DONE!
 { "stop", "STOP", 0, IDIT_BUTTON },   // Break / STOP
 { "f1", "F1", 0, IDIT_BUTTON },
 { "f2", "F2", 0, IDIT_BUTTON },
 { "f3", "F3", 0, IDIT_BUTTON },
 { "f4", "F4", 0, IDIT_BUTTON },
 { "f5", "F5", 0, IDIT_BUTTON },
 { "space", "space", 0, IDIT_BUTTON },
 { NULL, "empty", 0, IDIT_BUTTON },

// A - DONE!
 { "tab", "Tab", 0, IDIT_BUTTON },      // Tab
 { "down", "down", 0, IDIT_BUTTON },
 { "left", "left", 0, IDIT_BUTTON },
 { "help", "Help", 0, IDIT_BUTTON },   // -624
 { "copy", "Copy", 0, IDIT_BUTTON },   // -623
 { "kp_minus", "Keypad Minus", 0, IDIT_BUTTON },
 { "kp_divide", "Keypad Divide", 0, IDIT_BUTTON },
 { NULL, "empty", 0, IDIT_BUTTON },

 // B - DONE(most likely)
 { "roll_down", "ROLL DOWN", 0, IDIT_BUTTON },
 { "roll_up", "ROLL UP", 0, IDIT_BUTTON },
 { NULL, "empty", 0, IDIT_BUTTON },      // { "unknownB2", "unknown", 0, IDIT_BUTTON },
 { NULL, "empty", 0, IDIT_BUTTON },      // { "unknownB3", "unknown", 0, IDIT_BUTTON },
 { "o", "o", 0, IDIT_BUTTON },
 { "underscore", "Underscore", 0, IDIT_BUTTON },
 { "g", "g", 0, IDIT_BUTTON },
 { NULL, "empty", 0, IDIT_BUTTON },

// C - DONE!
 { "f6", "f6", 0, IDIT_BUTTON },
 { "f7", "f7", 0, IDIT_BUTTON },
 { "f8", "f8", 0, IDIT_BUTTON },
 { "f9", "f9", 0, IDIT_BUTTON },
 { "f10", "F10", 0, IDIT_BUTTON },
 { "backspace", "backspace", 0, IDIT_BUTTON },
 { "insert", "insert", 0, IDIT_BUTTON },
 { NULL, "empty", 0, IDIT_BUTTON },

// D - DONE!
 { "convert", "変換", 0, IDIT_BUTTON },       // (-620) Begin marking entered text, and disable marking after pressing the
                        // end-of-block key.
 { "nonconvert", "決定", 0, IDIT_BUTTON },     // (-619) End text marking block
 { "pc", "PC", 0, IDIT_BUTTON },        // (-617) Selects between Rgana and Rkana.  SHIFT+this key switches between
                        // latin and kana/gana mode?
 { "width", "変換", 0, IDIT_BUTTON },             // (-618) Chooses font width?
 { "ctrl", "CTRL/Control", 0, IDIT_BUTTON },     // CTRL
 { "kp_7", "Keypad 7", 0, IDIT_BUTTON },
 { "w", "w", 0, IDIT_BUTTON },
 { NULL, "empty", 0, IDIT_BUTTON },

// E - DONE!
 { "return", "return", 0, IDIT_BUTTON }, // enter
 { "kp_enter", "Keypad Enter", 0, IDIT_BUTTON }, // enter
 { "left_shift", "Left Shift", 0, IDIT_BUTTON }, // Left Shift
 { "right_shift", "Right Shift", 0, IDIT_BUTTON }, // Right Shift
 { "caps_lock", "Caps Lock", 0, IDIT_BUTTON }, // Caps Lock(mechanically-locking...)
 { "delete", "Delete", 0, IDIT_BUTTON },
 { "escape", "Escape", 0, IDIT_BUTTON },
 { NULL, "empty", 0, IDIT_BUTTON },

// F - DONE(most likely)
 { NULL, "empty", 0, IDIT_BUTTON },      // { "unknownF0", "unknown", 0, IDIT_BUTTON },
 { NULL, "empty", 0, IDIT_BUTTON },      // { "unknownF1", "unknown", 0, IDIT_BUTTON },
 { NULL, "empty", 0, IDIT_BUTTON },      // { "unknownF2", "unknown", 0, IDIT_BUTTON },
 { NULL, "empty", 0, IDIT_BUTTON },      // { "unknownF3", "unknown", 0, IDIT_BUTTON },
 { NULL, "empty", 0, IDIT_BUTTON },      // { "unknownF4", "unknown", 0, IDIT_BUTTON },
 { "minus", "Minus", 0, IDIT_BUTTON },
 { "7", "7", 0, IDIT_BUTTON },
 { NULL, "empty", 0, IDIT_BUTTON },
};

PCE_Input_Device *PCEINPUT_MakeTsushinKB(void)
{
 return(new PCE_Input_TsushinKB());
}

};
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    MagicEngine Forum Index -> General All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group