| version 1.9, 2004/02/07 21:23:22 | version 1.18, 2004/03/31 11:59:18 | 
| Line 1 | Line 1 | 
 | #include        "compiler.h" | #include        "compiler.h" | 
 |  | #include        "cpucore.h" | 
 | #include        "commng.h" | #include        "commng.h" | 
 | #include        "pccore.h" | #include        "pccore.h" | 
 | #include        "iocore.h" | #include        "iocore.h" | 
 |  | #include        "keystat.h" | 
 |  |  | 
 |  |  | 
| static const UINT8 joykeytable[12] = { | // ---- Keyboard | 
| 0x2a,   0x34, |  | 
| 0x29,   0x1c, |  | 
| 0x3c,   0x48, |  | 
| 0x3b,   0x46, |  | 
| 0x3d,   0x4b, |  | 
| 0x3a,   0x43}; |  | 
|  |  | 
| static const UINT8 kbexflag[0x80] = { |  | 
| //       ESC,  1,  2,  3,  4,  5,  6,  7         ; 00h |  | 
| 0,   0,   0,   0,   0,   0,   0,   0, |  | 
| //        8,  9,  0,  −,  ^,  ¥,  BS, TAB         ; 08h |  | 
| 0,   0,   0,   0,   0,   0,   0,   0, |  | 
| //        Q,  W,  E,  R,  T,  Y,  U,  I         ; 10h |  | 
| 0,   0,   0,   0,   0,   0,   0,   0, |  | 
| //        O,  P,  @,  [, Ret,  A,  S,  D         ; 18h |  | 
| 0,   0,   0,   0,   1,   0,   0,   0, |  | 
| //        F,  G,  H,  J,  K,  L,  ;,  :         ; 20h |  | 
| 0,   0,   0,   0,   0,   0,   0,   0, |  | 
| //    ],  Z,  X,  C,  V,  B,  N,  M             ; 28h |  | 
| 0,   1,   1,   0,   0,   0,   0,   0, |  | 
| //    ,,  .,  /,  _, SPC,XFER,RLUP,RLDN             ; 30h |  | 
| 0,   0,   0,   0,   1,   0,   0,   0, |  | 
| //       INS, DEL,  ↑,  ←,  →,  ↓,HMCR,HELP         ; 38h |  | 
| 2,   0,   1,   1,   1,   1,   0,   0, |  | 
| //      <−>,</>,<7>,<8>,<9>,<*>,<4>,<5>         ; 40h |  | 
| 0,   0,   0,   1,   0,   0,   1,   0, |  | 
| //      <6>,<+>,<1>,<2>,<3>,<=>,<0>,<,>         ; 48h |  | 
| 1,   0,   0,   1,   0,   0,   0,   0, |  | 
| //      <.>,NFER,vf.1,vf.2,vf.3,vf.4,vf.5,             ; 50h |  | 
| 0,   0,   2,   2,   2,   2,   2,   0, |  | 
| //          ,    ,    ,    ,    ,    ,HOME,             ; 58h |  | 
| 0,   0,   0,   0,   0,   0,   0,   0, |  | 
| //      STOP,COPY, f.1, f.2, f.3, f.4, f.5, f.6         ; 60h |  | 
| 0,   0,   2,   2,   2,   2,   2,   2, |  | 
| //       f.7, f.8, f.9, f10,    ,    ,    ,             ; 68h |  | 
| 2,   2,   2,   2,   0,   0,   0,   0, |  | 
| //       SFT,CAPS,KANA,GRPH,CTRL,    ,    ,             ; 70h |  | 
| 2,   2,   2,   2,   2,   0,   0,   0, |  | 
| //          ,    ,    ,    ,    ,    ,    ,             ; 78h |  | 
| 0,   0,   0,   0,   0,   0,   0,   0}; |  | 
 |  |  | 
 |  | static void keyboard_int(BOOL absolute) { | 
 |  |  | 
| static void keybrd_int(BOOL absolute) { | if ((keybrd.ctrls) || (keybrd.buffers)) { | 
|  |  | 
| if (keybrd.buffers) { |  | 
 | if (!(keybrd.status & 2)) { | if (!(keybrd.status & 2)) { | 
 | keybrd.status |= 2; | keybrd.status |= 2; | 
| keybrd.data = keybrd.buf[keybrd.pos]; | if (keybrd.ctrls) { | 
| keybrd.pos = (keybrd.pos + 1) & KB_BUFMASK; | keybrd.ctrls--; | 
| keybrd.buffers--; | keybrd.data = keybrd.ctr[keybrd.ctrpos]; | 
|  | keybrd.ctrpos = (keybrd.ctrpos + 1) & KB_CTRMASK; | 
|  | } | 
|  | else if (keybrd.buffers) { | 
|  | keybrd.buffers--; | 
|  | keybrd.data = keybrd.buf[keybrd.bufpos]; | 
|  | keybrd.bufpos = (keybrd.bufpos + 1) & KB_BUFMASK; | 
|  | } | 
|  | TRACEOUT(("recv -> %02x", keybrd.data)); | 
 | } | } | 
 | pic_setirq(1); | pic_setirq(1); | 
 | nevent_set(NEVENT_KEYBOARD, keybrd.xferclock, | nevent_set(NEVENT_KEYBOARD, keybrd.xferclock, | 
| keybrd_callback, absolute); | keyboard_callback, absolute); | 
 | } | } | 
 | } | } | 
 |  |  | 
| void keybrd_callback(NEVENTITEM item) { | void keyboard_callback(NEVENTITEM item) { | 
 |  |  | 
 | if (item->flag & NEVENT_SETEVENT) { | if (item->flag & NEVENT_SETEVENT) { | 
| keybrd_int(NEVENT_RELATIVE); | keyboard_int(NEVENT_RELATIVE); | 
 | } | } | 
 | } | } | 
 |  |  | 
| static void keybrd_out(REG8 data) { | static void IOOUTCALL keyboard_o41(UINT port, REG8 dat) { | 
|  |  | 
| if (keybrd.buffers < KB_BUF) { |  | 
| keybrd.buf[(keybrd.pos + keybrd.buffers) & KB_BUFMASK] = data; |  | 
| keybrd.buffers++; |  | 
| if (!nevent_iswork(NEVENT_KEYBOARD)) { |  | 
| keybrd_int(NEVENT_ABSOLUTE); |  | 
| } |  | 
| } |  | 
| else { |  | 
| keybrd.status |= 0x10; |  | 
| } |  | 
| } |  | 
|  |  | 
|  |  | 
| // ---- |  | 
|  |  | 
| UINT8   keystat[0x80]; |  | 
|  |  | 
| void keystat_reset(void) { |  | 
|  |  | 
| ZeroMemory(keystat, sizeof(keystat)); |  | 
| } |  | 
|  |  | 
|  |  | 
| void keystat_senddata(REG8 data) { |  | 
|  |  | 
| REG8    key; |  | 
| BOOL    keynochange; |  | 
 |  |  | 
| key = data & 0x7f; | if (keybrd.cmd & 1) { | 
| keynochange = FALSE; | TRACEOUT(("send -> %02x", dat)); | 
|  | keystat_ctrlsend(dat); | 
| // CTRL:カナ 0x71,0x72 bit7==0でトグル処理 (標準処理) |  | 
| if ((key == 0x71) || (key == 0x72)) { |  | 
| if (data & 0x80) { |  | 
| return; |  | 
| } |  | 
| data = key | (keystat[key] & 0x80); |  | 
| keystat[key] ^= 0x80; |  | 
 | } | } | 
 | else { |  | 
 | if ((np2cfg.XSHIFT) && |  | 
 | (((key == 0x70) && (np2cfg.XSHIFT & 1)) || |  | 
 | ((key == 0x74) && (np2cfg.XSHIFT & 2)) || |  | 
 | ((key == 0x73) && (np2cfg.XSHIFT & 4)))) { |  | 
 | if (data & 0x80) { |  | 
 | return; |  | 
 | } |  | 
 | data = key | (keystat[key] & 0x80); |  | 
 | keystat[key] ^= 0x80; |  | 
 | } |  | 
 | else { |  | 
 | // CTRL:カナ 0x79,0x7a bit7をそのまま通知 |  | 
 | // (ハードウェアでメカニカル処理してる場合) |  | 
 | if ((key == 0x79) || (key == 0x7a)) { |  | 
 | key -= 0x08; |  | 
 | data -= 0x08; |  | 
 | } |  | 
 | if (!((keystat[key] ^ data) & 0x80)) { |  | 
 | keystat[key] ^= 0x80; |  | 
 | } |  | 
 | else { |  | 
 | keynochange = TRUE; |  | 
 | if (kbexflag[key] & 2) {                        // キーリピート無し |  | 
 | return; |  | 
 | } |  | 
 | } |  | 
 | } |  | 
 | } |  | 
 | if ((!np2cfg.KEY_MODE) || (!(kbexflag[key] & 1))) { |  | 
 | if (keynochange) { |  | 
 | if (data & 0x80) {                                              // ver0.30 |  | 
 | return; |  | 
 | } |  | 
 | keybrd_out((REG8)(data ^ 0x80)); |  | 
 | } |  | 
 | keybrd_out(data); |  | 
 | } |  | 
 | } |  | 
 |  |  | 
 | void keystat_resetcopyhelp(void) { |  | 
 |  |  | 
 | REG8    i; |  | 
 |  |  | 
 | for (i=0x60; i<0x62; i++) { |  | 
 | if (keystat[i] & 0x80) { |  | 
 | keystat[i] &= 0x7f; |  | 
 | keybrd_out((REG8)(i | 0x80)); |  | 
 | } |  | 
 | } |  | 
 | } |  | 
 |  |  | 
 | void keystat_allrelease(void) { |  | 
 |  |  | 
 | REG8    i; |  | 
 |  |  | 
 | for (i=0; i<0x80; i++) { |  | 
 | if (keystat[i] & 0x80) { |  | 
 | keystat[i] &= ~0x80; |  | 
 | keybrd_out((REG8)(i | 0x80)); |  | 
 | } |  | 
 | } |  | 
 | } |  | 
 |  |  | 
 | void keystat_forcerelease(REG8 value) { |  | 
 |  |  | 
 | if (keystat[value & 0x7f] & 0x80) { |  | 
 | keystat[value & 0x7f] &= ~0x80; |  | 
 | keybrd_out((REG8)(value | 0x80)); |  | 
 | } |  | 
 | } |  | 
 |  |  | 
 | void keystat_resetjoykey(void) { |  | 
 |  |  | 
 | int             i; |  | 
 | REG8    key; |  | 
 |  |  | 
 | for (i=0; i<12; i++) { |  | 
 | key = joykeytable[i]; |  | 
 | if (keystat[key] & 0x80) { |  | 
 | keystat[key] &= 0x7f; |  | 
 | keybrd_out((REG8)(key | 0x80)); |  | 
 | } |  | 
 | } |  | 
 | } |  | 
 |  |  | 
 |  |  | 
 | // ---- |  | 
 |  |  | 
 | typedef struct { |  | 
 | UINT8   joysync; |  | 
 | UINT8   joylast; |  | 
 | UINT8   mouselast; |  | 
 | UINT8   padding; |  | 
 | UINT8   d_up; |  | 
 | UINT8   d_dn; |  | 
 | UINT8   d_lt; |  | 
 | UINT8   d_rt; |  | 
 | } KEYEXT; |  | 
 |  |  | 
 | static  KEYEXT  keyext; |  | 
 | static const UINT8 mousedelta[] = {1, 1, 1, 1, |  | 
 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4}; |  | 
 | #define MOUSESTEPMAX ((sizeof(mousedelta) / sizeof(UINT8)) - 1) |  | 
 |  |  | 
 | void keyext_flash(void) { |  | 
 |  |  | 
 | keyext.joysync = 0; |  | 
 | } |  | 
 |  |  | 
 | BYTE keyext_getjoy(void) { |  | 
 |  |  | 
 | BYTE    flg; |  | 
 | const BYTE      *p; |  | 
 | BYTE    bit; |  | 
 |  |  | 
 | if (!keyext.joysync) { |  | 
 | keyext.joysync = 1; |  | 
 | flg = 0xff; |  | 
 | p = joykeytable; |  | 
 | for (bit=0x20; bit; bit>>=1) { |  | 
 | if ((keystat[p[0]] & 0x80) || (keystat[p[1]] & 0x80)) { |  | 
 | flg ^= bit; |  | 
 | } |  | 
 | p += 2; |  | 
 | } |  | 
 | keyext.joylast = flg; |  | 
 | } |  | 
 | return(keyext.joylast); |  | 
 | } |  | 
 |  |  | 
 | BYTE keyext_getmouse(SINT16 *x, SINT16 *y) { |  | 
 |  |  | 
 | BYTE    btn; |  | 
 | BYTE    acc; |  | 
 | SINT16  tmp; |  | 
 | BYTE    ret; |  | 
 |  |  | 
 | btn = keyext_getjoy(); |  | 
 | acc = btn | keyext.mouselast; |  | 
 | keyext.mouselast = btn; |  | 
 | tmp = 0; |  | 
 | if (!(btn & 1)) { |  | 
 | tmp -= mousedelta[keyext.d_up]; |  | 
 | } |  | 
 | if (!(acc & 1)) { |  | 
 | if (keyext.d_up < MOUSESTEPMAX) { |  | 
 | keyext.d_up++; |  | 
 | } |  | 
 | } |  | 
 | else { |  | 
 | keyext.d_up = 0; |  | 
 | } |  | 
 | if (!(btn & 2)) { |  | 
 | tmp += mousedelta[keyext.d_dn]; |  | 
 | } |  | 
 | if (!(acc & 2)) { |  | 
 | if (keyext.d_dn < MOUSESTEPMAX) { |  | 
 | keyext.d_dn++; |  | 
 | } |  | 
 | } |  | 
 | else { |  | 
 | keyext.d_dn = 0; |  | 
 | } |  | 
 | *y += tmp; |  | 
 |  |  | 
 | tmp = 0; |  | 
 | if (!(btn & 4)) { |  | 
 | tmp -= mousedelta[keyext.d_lt]; |  | 
 | } |  | 
 | if (!(acc & 4)) { |  | 
 | if (keyext.d_lt < MOUSESTEPMAX) { |  | 
 | keyext.d_lt++; |  | 
 | } |  | 
 | } |  | 
 | else { |  | 
 | keyext.d_lt = 0; |  | 
 | } |  | 
 | if (!(btn & 8)) { |  | 
 | tmp += mousedelta[keyext.d_rt]; |  | 
 | } |  | 
 | if (!(acc & 8)) { |  | 
 | if (keyext.d_rt < MOUSESTEPMAX) { |  | 
 | keyext.d_rt++; |  | 
 | } |  | 
 | } |  | 
 | else { |  | 
 | keyext.d_rt = 0; |  | 
 | } |  | 
 | *x += tmp; |  | 
 |  |  | 
 | ret = 0x5f; |  | 
 | ret += (btn & 0x10) << 3; |  | 
 | ret += (btn & 0x20); |  | 
 | return(ret); |  | 
 | } |  | 
 |  |  | 
 |  |  | 
 | // ---- |  | 
 |  |  | 
 | static void IOOUTCALL keybrd_o41(UINT port, REG8 dat) { |  | 
 |  |  | 
 | keybrd.mode = dat; |  | 
 | (void)port; | (void)port; | 
 | } | } | 
 |  |  | 
| static void IOOUTCALL keybrd_o43(UINT port, REG8 dat) { | static void IOOUTCALL keyboard_o43(UINT port, REG8 dat) { | 
 |  |  | 
 |  | TRACEOUT(("out43 -> %02x %.4x:%.8x", dat, CPU_CS, CPU_EIP)); | 
 | if ((!(dat & 0x08)) && (keybrd.cmd & 0x08)) { | if ((!(dat & 0x08)) && (keybrd.cmd & 0x08)) { | 
 | keyboard_resetsignal(); | keyboard_resetsignal(); | 
 | } | } | 
| Line 328  static void IOOUTCALL keybrd_o43(UINT po | Line 60  static void IOOUTCALL keybrd_o43(UINT po | 
 | (void)port; | (void)port; | 
 | } | } | 
 |  |  | 
| static REG8 IOINPCALL keybrd_i41(UINT port) { | static REG8 IOINPCALL keyboard_i41(UINT port) { | 
 |  |  | 
 | (void)port; | (void)port; | 
 | keybrd.status &= ~2; | keybrd.status &= ~2; | 
 |  | TRACEOUT(("in41 -> %02x %.4x:%.8x", keybrd.data, CPU_CS, CPU_EIP)); | 
 | return(keybrd.data); | return(keybrd.data); | 
 | } | } | 
 |  |  | 
| static REG8 IOINPCALL keybrd_i43(UINT port) { | static REG8 IOINPCALL keyboard_i43(UINT port) { | 
 |  |  | 
 | (void)port; | (void)port; | 
| return(keybrd.status); | TRACEOUT(("in43 -> %02x %.4x:%.8x", keybrd.status, CPU_CS, CPU_EIP)); | 
|  | return(keybrd.status | 0x85); | 
 | } | } | 
 |  |  | 
 |  |  | 
 | // ---- | // ---- | 
 |  |  | 
 | static const IOOUT keybrdo41[2] = { | static const IOOUT keybrdo41[2] = { | 
| keybrd_o41,     keybrd_o43}; | keyboard_o41,   keyboard_o43}; | 
 |  |  | 
 | static const IOINP keybrdi41[2] = { | static const IOINP keybrdi41[2] = { | 
| keybrd_i41,     keybrd_i43}; | keyboard_i41,   keyboard_i43}; | 
 |  |  | 
 |  |  | 
 | void keyboard_reset(void) { | void keyboard_reset(void) { | 
 |  |  | 
 | ZeroMemory(&keybrd, sizeof(keybrd)); | ZeroMemory(&keybrd, sizeof(keybrd)); | 
 | keybrd.data = 0xff; | keybrd.data = 0xff; | 
 | keybrd.mode = 0x5e; |  | 
 | } | } | 
 |  |  | 
 | void keyboard_bind(void) { | void keyboard_bind(void) { | 
| Line 365  void keyboard_bind(void) { | Line 98  void keyboard_bind(void) { | 
 | iocore_attachsysinpex(0x0041, 0x0cf1, keybrdi41, 2); | iocore_attachsysinpex(0x0041, 0x0cf1, keybrdi41, 2); | 
 | } | } | 
 |  |  | 
| void keyboard_resetsignal(void) {                                                                       // ver0.29 | void keyboard_resetsignal(void) { | 
 |  |  | 
 | int             i; |  | 
 |  |  | 
 | keybrd.mode = 0x5e; |  | 
 | keybrd.cmd = 0; | keybrd.cmd = 0; | 
 | keybrd.status = 0; | keybrd.status = 0; | 
 |  | keybrd.ctrls = 0; | 
 | keybrd.buffers = 0; | keybrd.buffers = 0; | 
| keybrd.pos = 0; | keystat_ctrlreset(); | 
| for (i=0; i<0x80; i++) { | keystat_resendstat(); | 
| if (keystat[i]) { | } | 
| keybrd_out((REG8)i); |  | 
|  | void keyboard_ctrl(REG8 data) { | 
|  |  | 
|  | if ((data == 0xfa) || (data == 0xfc)) { | 
|  | keybrd.ctrls = 0; | 
|  | } | 
|  | if (keybrd.ctrls < KB_CTR) { | 
|  | keybrd.ctr[(keybrd.ctrpos + keybrd.ctrls) & KB_CTRMASK] = data; | 
|  | keybrd.ctrls++; | 
|  | if (!nevent_iswork(NEVENT_KEYBOARD)) { | 
|  | keyboard_int(NEVENT_ABSOLUTE); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void keyboard_send(REG8 data) { | 
|  |  | 
|  | if (keybrd.buffers < KB_BUF) { | 
|  | keybrd.buf[(keybrd.bufpos + keybrd.buffers) & KB_BUFMASK] = data; | 
|  | keybrd.buffers++; | 
|  | if (!nevent_iswork(NEVENT_KEYBOARD)) { | 
|  | keyboard_int(NEVENT_ABSOLUTE); | 
 | } | } | 
 | } | } | 
 |  | else { | 
 |  | keybrd.status |= 0x10; | 
 |  | } | 
 | } | } | 
 |  |  | 
 |  |  | 
 | // ----------------------------------------------------------------------- |  | 
 |  |  | 
 |  | // ---- RS-232C | 
 |  |  | 
 | COMMNG  cm_rs232c; | COMMNG  cm_rs232c; | 
 |  |  | 
| Line 515  static void IOOUTCALL rs232c_o32(UINT po | Line 270  static void IOOUTCALL rs232c_o32(UINT po | 
 | break; | break; | 
 |  |  | 
 | case 0x02:                      // cmd | case 0x02:                      // cmd | 
 |  | sysport.c &= ~7; | 
 |  | sysport.c |= (dat & 7); | 
 | rs232c.pos++; | rs232c.pos++; | 
 | break; | break; | 
 | } | } |