trunk/src/mess/drivers/nes.c
| r23721 | r23722 | |
| 59 | 59 | |
| 60 | 60 | |
| 61 | 61 | static INPUT_PORTS_START( nes_pads12 ) |
| 62 | | PORT_START("PAD1") /* Joypad 1 */ |
| 62 | PORT_START("PAD1") |
| 63 | 63 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P1 A") PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0001) |
| 64 | 64 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P1 B") PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0001) |
| 65 | 65 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0001) |
| r23721 | r23722 | |
| 69 | 69 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0001) |
| 70 | 70 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0001) |
| 71 | 71 | |
| 72 | | PORT_START("PAD2") /* Joypad 2 */ |
| 72 | PORT_START("PAD2") |
| 73 | 73 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P2 A") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0010) |
| 74 | 74 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P2 B") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0010) |
| 75 | 75 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0010) |
| r23721 | r23722 | |
| 82 | 82 | INPUT_PORTS_END |
| 83 | 83 | |
| 84 | 84 | static INPUT_PORTS_START( nes_pads34 ) |
| 85 | | PORT_START("PAD3") /* Joypad 3 */ |
| 85 | PORT_START("PAD3") |
| 86 | 86 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P3 A") PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0x0f00, EQUALS, 0x0100) |
| 87 | 87 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P3 B") PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0x0f00, EQUALS, 0x0100) |
| 88 | 88 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0x0f00, EQUALS, 0x0100) |
| r23721 | r23722 | |
| 92 | 92 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0x0f00, EQUALS, 0x0100) |
| 93 | 93 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0x0f00, EQUALS, 0x0100) |
| 94 | 94 | |
| 95 | | PORT_START("PAD4") /* Joypad 4 */ |
| 95 | PORT_START("PAD4") |
| 96 | 96 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P4 A") PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x1000) |
| 97 | 97 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P4 B") PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x1000) |
| 98 | 98 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x1000) |
| r23721 | r23722 | |
| 105 | 105 | INPUT_PORTS_END |
| 106 | 106 | |
| 107 | 107 | static INPUT_PORTS_START( nes_zapper1 ) |
| 108 | | PORT_START("ZAPPER1_X") /* P1 zapper */ |
| 108 | PORT_START("ZAPPER1_X") |
| 109 | 109 | PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(70) PORT_KEYDELTA(30) PORT_MINMAX(0,255) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0002) |
| 110 | | PORT_START("ZAPPER1_Y") /* P1 zapper */ |
| 110 | PORT_START("ZAPPER1_Y") |
| 111 | 111 | PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(50) PORT_KEYDELTA(30) PORT_MINMAX(0,255) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0002) |
| 112 | | PORT_START("ZAPPER1_T") /* P1 zapper trigger */ |
| 112 | PORT_START("ZAPPER1_T") |
| 113 | 113 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("P1 Lightgun Trigger") PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0002) |
| 114 | 114 | INPUT_PORTS_END |
| 115 | 115 | |
| 116 | 116 | static INPUT_PORTS_START( nes_zapper2 ) |
| 117 | | PORT_START("ZAPPER2_X") /* P2 zapper */ |
| 117 | PORT_START("ZAPPER2_X") |
| 118 | 118 | PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(70) PORT_KEYDELTA(30) PORT_MINMAX(0,255 ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0020) |
| 119 | | PORT_START("ZAPPER2_Y") /* P2 zapper */ |
| 119 | PORT_START("ZAPPER2_Y") |
| 120 | 120 | PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(50) PORT_KEYDELTA(30) PORT_MINMAX(0,255 ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0020) |
| 121 | | PORT_START("ZAPPER2_T") /* P2 zapper trigger */ |
| 121 | PORT_START("ZAPPER2_T") |
| 122 | 122 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("P2 Lightgun Trigger") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0020) |
| 123 | 123 | INPUT_PORTS_END |
| 124 | 124 | |
| 125 | 125 | static INPUT_PORTS_START( nes_paddle ) |
| 126 | | PORT_START("PADDLE") /* Arkanoid paddle */ |
| 126 | PORT_START("PADDLE") |
| 127 | 127 | PORT_BIT( 0xff, 0x7f, IPT_PADDLE) PORT_SENSITIVITY(25) PORT_KEYDELTA(25) PORT_CENTERDELTA(0) PORT_MINMAX(0x62,0xf2) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0040) |
| 128 | | PORT_START("PADDLE_BUTTON") /* Arkanoid paddle button */ |
| 128 | PORT_START("PADDLE_BUTTON") |
| 129 | 129 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("Paddle button") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0040) |
| 130 | 130 | INPUT_PORTS_END |
| 131 | 131 | |
| r23721 | r23722 | |
| 136 | 136 | PORT_INCLUDE( nes_zapper2 ) |
| 137 | 137 | PORT_INCLUDE( nes_paddle ) |
| 138 | 138 | |
| 139 | | PORT_START("CTRLSEL") /* Select Controller Type */ |
| 139 | PORT_START("CTRLSEL") |
| 140 | 140 | PORT_CONFNAME( 0x000f, 0x0001, "P1 Controller") |
| 141 | 141 | PORT_CONFSETTING( 0x0000, "Unconnected" ) |
| 142 | 142 | PORT_CONFSETTING( 0x0001, "Gamepad" ) |
| r23721 | r23722 | |
| 154 | 154 | PORT_CONFSETTING( 0x0000, "Unconnected" ) |
| 155 | 155 | PORT_CONFSETTING( 0x1000, "Gamepad" ) |
| 156 | 156 | |
| 157 | | PORT_START("CONFIG") /* configuration */ |
| 157 | PORT_START("CONFIG") |
| 158 | 158 | PORT_CONFNAME( 0x01, 0x00, "Draw Top/Bottom 8 Lines") |
| 159 | 159 | PORT_CONFSETTING( 0x01, DEF_STR(No) ) |
| 160 | 160 | PORT_CONFSETTING( 0x00, DEF_STR(Yes) ) |
| r23721 | r23722 | |
| 165 | 165 | |
| 166 | 166 | |
| 167 | 167 | static INPUT_PORTS_START( fc_pads12 ) |
| 168 | | PORT_START("PAD1") /* Joypad 1 */ |
| 168 | PORT_START("PAD1") |
| 169 | 169 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P1 A") PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0001) |
| 170 | 170 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P1 B") PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0001) |
| 171 | 171 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0001) |
| r23721 | r23722 | |
| 175 | 175 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0001) |
| 176 | 176 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0001) |
| 177 | 177 | |
| 178 | | PORT_START("PAD2") /* Joypad 2 */ |
| 178 | PORT_START("PAD2") |
| 179 | 179 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P2 A") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0010) |
| 180 | 180 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P2 B") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0010) |
| 181 | 181 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0010) |
| r23721 | r23722 | |
| 188 | 188 | INPUT_PORTS_END |
| 189 | 189 | |
| 190 | 190 | static INPUT_PORTS_START( fc_pads34 ) |
| 191 | | PORT_START("PAD3") /* Joypad 3 */ |
| 191 | PORT_START("PAD3") |
| 192 | 192 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P3 A") PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0x0f00, EQUALS, 0x0100) |
| 193 | 193 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P3 B") PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0x0f00, EQUALS, 0x0100) |
| 194 | 194 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0x0f00, EQUALS, 0x0100) |
| r23721 | r23722 | |
| 198 | 198 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0x0f00, EQUALS, 0x0100) |
| 199 | 199 | PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0x0f00, EQUALS, 0x0100) |
| 200 | 200 | |
| 201 | | PORT_START("PAD4") /* Joypad 4 */ |
| 201 | PORT_START("PAD4") |
| 202 | 202 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P4 A") PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x1000) |
| 203 | 203 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P4 B") PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x1000) |
| 204 | 204 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x1000) |
| r23721 | r23722 | |
| 210 | 210 | INPUT_PORTS_END |
| 211 | 211 | |
| 212 | 212 | static INPUT_PORTS_START( fc_lightgun ) |
| 213 | | PORT_START("ZAPPER2_X") /* P2 zapper */ |
| 213 | PORT_START("ZAPPER2_X") |
| 214 | 214 | PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(70) PORT_KEYDELTA(30) PORT_MINMAX(0,255) PORT_PLAYER(2) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x01) |
| 215 | | PORT_START("ZAPPER2_Y") /* P2 zapper */ |
| 215 | PORT_START("ZAPPER2_Y") |
| 216 | 216 | PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(50) PORT_KEYDELTA(30) PORT_MINMAX(0,255) PORT_PLAYER(2) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x01) |
| 217 | | PORT_START("ZAPPER2_T") /* P2 zapper trigger */ |
| 217 | PORT_START("ZAPPER2_T") |
| 218 | 218 | PORT_BIT( 0x03, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("Lightgun Trigger") PORT_PLAYER(2) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x01) |
| 219 | 219 | INPUT_PORTS_END |
| 220 | 220 | |
| 221 | 221 | static INPUT_PORTS_START( fc_paddle ) |
| 222 | | PORT_START("PADDLE") /* Arkanoid paddle */ |
| 223 | | PORT_BIT( 0xff, 0x7f, IPT_PADDLE) PORT_SENSITIVITY(25) PORT_KEYDELTA(3) PORT_MINMAX(0x62,0xf2) PORT_PLAYER(2) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x04) |
| 222 | PORT_START("PADDLE") |
| 223 | PORT_BIT( 0xff, 0x7f, IPT_PADDLE) PORT_SENSITIVITY(25) PORT_KEYDELTA(25) PORT_CENTERDELTA(0) PORT_MINMAX(0x62,0xf2) PORT_PLAYER(2) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x04) |
| 224 | PORT_START("PADDLE_BUTTON") |
| 225 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("Paddle button") PORT_PLAYER(2) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x04) |
| 224 | 226 | INPUT_PORTS_END |
| 225 | 227 | |
| 226 | 228 | static INPUT_PORTS_START( fc_cclimb ) |
| r23721 | r23722 | |
| 502 | 504 | PORT_INCLUDE( fc_pads12 ) |
| 503 | 505 | PORT_INCLUDE( fc_pads34 ) |
| 504 | 506 | PORT_INCLUDE( fc_lightgun ) |
| 507 | // FIXME: was it possible to attache two paddles in a Famicom (as the Arkanoid 2 box suggests)?!? investigate... |
| 505 | 508 | PORT_INCLUDE( fc_paddle ) |
| 506 | 509 | // Crazy Climber is not really a separate controller, but a couple of small sticks to be |
| 507 | 510 | // put on top of d-pads of the regular controllers. Users should then control the game |
| r23721 | r23722 | |
| 511 | 514 | PORT_INCLUDE( subor_keyboard ) |
| 512 | 515 | PORT_INCLUDE( mahjong_panel ) |
| 513 | 516 | |
| 514 | | PORT_START("CTRLSEL") /* Select Controller Type */ |
| 517 | PORT_START("CTRLSEL") |
| 515 | 518 | PORT_CONFNAME( 0x000f, 0x0001, "P1 Controller") |
| 516 | 519 | PORT_CONFSETTING( 0x0000, "Unconnected" ) |
| 517 | 520 | PORT_CONFSETTING( 0x0001, "Gamepad" ) |
| r23721 | r23722 | |
| 527 | 530 | PORT_CONFSETTING( 0x0000, "Unconnected" ) |
| 528 | 531 | PORT_CONFSETTING( 0x1000, "Gamepad" ) |
| 529 | 532 | |
| 530 | | PORT_START("EXP") /* expansion port */ |
| 533 | PORT_START("EXP") |
| 531 | 534 | PORT_CONFNAME( 0x0f, 0x00, "Expansion Port") |
| 532 | 535 | PORT_CONFSETTING( 0x00, "(Empty)" ) |
| 533 | 536 | PORT_CONFSETTING( 0x01, "Light Gun" ) |
| r23721 | r23722 | |
| 538 | 541 | PORT_CONFSETTING( 0x06, "Mahjong Panel" ) |
| 539 | 542 | PORT_CONFSETTING( 0x07, "Hori Twin Adapter" ) |
| 540 | 543 | |
| 541 | | PORT_START("CONFIG") /* configuration */ |
| 544 | PORT_START("CONFIG") |
| 542 | 545 | PORT_CONFNAME( 0x01, 0x00, "Draw Top/Bottom 8 Lines") |
| 543 | 546 | PORT_CONFSETTING( 0x01, DEF_STR(No) ) |
| 544 | 547 | PORT_CONFSETTING( 0x00, DEF_STR(Yes) ) |
| r23721 | r23722 | |
| 546 | 549 | PORT_CONFSETTING( 0x02, DEF_STR(No) ) |
| 547 | 550 | PORT_CONFSETTING( 0x00, DEF_STR(Yes) ) |
| 548 | 551 | |
| 549 | | PORT_START("FLIPDISK") /* fake keys */ |
| 552 | PORT_START("FLIPDISK") /* fake key */ |
| 550 | 553 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON3) PORT_NAME("Change Disk Side") |
| 551 | 554 | INPUT_PORTS_END |
| 552 | 555 | |
trunk/src/mess/machine/nes.c
| r23721 | r23722 | |
| 81 | 81 | state->save_item(NAME(state->m_zapper_latch)); |
| 82 | 82 | state->save_item(NAME(state->m_paddle_latch)); |
| 83 | 83 | state->save_item(NAME(state->m_paddle_btn_latch)); |
| 84 | state->save_item(NAME(state->m_mjpanel_latch)); |
| 84 | 85 | } |
| 85 | 86 | |
| 86 | 87 | |
| r23721 | r23722 | |
| 245 | 246 | } |
| 246 | 247 | |
| 247 | 248 | if (LOG_JOY) |
| 248 | | logerror("joy 0 read, val: %02x, pc: %04x, bits read: %d, chan0: %08x\n", ret, space.device().safe_pc(), m_in_0.shift, m_in_0.i0); |
| 249 | logerror("joy 0 read, val: %02x, pc: %04x\n", ret, space.device().safe_pc()); |
| 249 | 250 | |
| 250 | 251 | return ret; |
| 251 | 252 | } |
| r23721 | r23722 | |
| 296 | 297 | } |
| 297 | 298 | |
| 298 | 299 | if (LOG_JOY) |
| 299 | | logerror("joy 1 read, val: %02x, pc: %04x, bits read: %d, chan0: %08x\n", ret, space.device().safe_pc(), m_in_1.shift, m_in_1.i0); |
| 300 | logerror("joy 1 read, val: %02x, pc: %04x\n", ret, space.device().safe_pc()); |
| 300 | 301 | |
| 301 | 302 | return ret; |
| 302 | 303 | } |
| r23721 | r23722 | |
| 304 | 305 | WRITE8_MEMBER(nes_state::nes_in0_w) |
| 305 | 306 | { |
| 306 | 307 | int cfg = m_io_ctrlsel->read(); |
| 307 | | |
| 308 | |
| 309 | if (LOG_JOY) |
| 310 | logerror("joy write, val: %02x, pc: %04x\n", data, space.device().safe_pc()); |
| 311 | |
| 308 | 312 | // Check if lightgun has been chosen as input: if so, enable crosshair |
| 309 | 313 | timer_set(attotime::zero, TIMER_ZAPPER_TICK); |
| 310 | 314 | |
| r23721 | r23722 | |
| 319 | 323 | m_zapper_latch[0][2] = 0; |
| 320 | 324 | m_zapper_latch[1][0] = 0; |
| 321 | 325 | m_zapper_latch[1][1] = 0; |
| 322 | | m_zapper_latch[1][2] = 0; |
| 326 | m_zapper_latch[1][2] = 0; |
| 327 | m_paddle_btn_latch = 0; |
| 323 | 328 | m_paddle_latch = 0; |
| 324 | 329 | |
| 325 | 330 | // P1 inputs |
| r23721 | r23722 | |
| 354 | 359 | m_paddle_latch = (UINT8) (m_io_paddle->read() ^ 0xff); |
| 355 | 360 | break; |
| 356 | 361 | } |
| 357 | | |
| 362 | |
| 363 | // P3 & P4 inputs in NES Four Score are read serially with P1 & P2 |
| 358 | 364 | // P3 inputs |
| 359 | 365 | if ((cfg & 0x0f00)) |
| 360 | 366 | m_pad_latch[0] |= ((m_io_pad[2]->read() << 8) | (0x08 << 16)); // pad 3 + signature |
| r23721 | r23722 | |
| 373 | 379 | READ8_MEMBER(nes_state::fc_in0_r) |
| 374 | 380 | { |
| 375 | 381 | int exp = m_io_exp->read(); |
| 376 | | /* Some games expect bit 6 to be set because the last entry on the data bus shows up */ |
| 377 | | /* in the unused upper 3 bits, so typically a read from $4016 leaves 0x40 there. */ |
| 382 | |
| 383 | // Some games expect bit 6 to be set because the last entry on the data bus shows up |
| 384 | // in the unused upper 3 bits, so typically a read from $4016 leaves 0x40 there. |
| 378 | 385 | UINT8 ret = 0x40; |
| 386 | ret |= (m_pad_latch[0] & 0x01); |
| 379 | 387 | |
| 380 | | if ((exp & 0x0f) == 0x02) |
| 381 | | { |
| 382 | | // tape input |
| 383 | | if ((m_cassette->get_state() & CASSETTE_MASK_UISTATE) == CASSETTE_PLAY) |
| 384 | | { |
| 385 | | double level = m_cassette->input(); |
| 386 | | if (level < 0) |
| 387 | | ret |= 0x00; |
| 388 | | else |
| 389 | | ret |= 0x02; |
| 390 | | } |
| 388 | // shift |
| 389 | m_pad_latch[0] >>= 1; |
| 390 | |
| 391 | // EXP input |
| 392 | switch (exp & 0x0f) |
| 393 | { |
| 394 | case 0x02: // FC Keyboard: tape input |
| 395 | if ((m_cassette->get_state() & CASSETTE_MASK_UISTATE) == CASSETTE_PLAY) |
| 396 | { |
| 397 | double level = m_cassette->input(); |
| 398 | if (level < 0) |
| 399 | ret |= 0x00; |
| 400 | else |
| 401 | ret |= 0x02; |
| 402 | } |
| 403 | break; |
| 404 | |
| 405 | case 0x04: // Arkanoid paddle |
| 406 | ret |= (m_paddle_btn_latch << 1); // button |
| 407 | break; |
| 408 | |
| 409 | case 0x06: // Mahjong Panel |
| 410 | ret |= ((m_mjpanel_latch & 0x01) << 1); |
| 411 | m_mjpanel_latch >>= 1; |
| 412 | break; |
| 413 | |
| 414 | case 0x07: // 'multitap' p3 |
| 415 | ret |= ((m_pad_latch[2] & 0x01) << 1); |
| 416 | m_pad_latch[2] >>= 1; |
| 417 | break; |
| 391 | 418 | } |
| 392 | 419 | |
| 393 | | ret |= ((m_in_0.i0 >> m_in_0.shift) & 0x01); |
| 394 | | |
| 395 | 420 | if (LOG_JOY) |
| 396 | | logerror("joy 0 read, val: %02x, pc: %04x, bits read: %d, chan0: %08x\n", ret, space.device().safe_pc(), m_in_0.shift, m_in_0.i0); |
| 421 | logerror("joy 0 read, val: %02x, pc: %04x\n", ret, space.device().safe_pc()); |
| 397 | 422 | |
| 398 | | m_in_0.shift++; |
| 399 | | |
| 400 | 423 | return ret; |
| 401 | 424 | } |
| 402 | 425 | |
| 403 | 426 | READ8_MEMBER(nes_state::fc_in1_r) |
| 404 | 427 | { |
| 405 | 428 | int exp = m_io_exp->read(); |
| 406 | | /* Some games expect bit 6 to be set because the last entry on the data bus shows up */ |
| 407 | | /* in the unused upper 3 bits, so typically a read from $4017 leaves 0x40 there. */ |
| 429 | |
| 430 | // Some games expect bit 6 to be set because the last entry on the data bus shows up |
| 431 | // in the unused upper 3 bits, so typically a read from $4017 leaves 0x40 there. |
| 408 | 432 | UINT8 ret = 0x40; |
| 433 | ret |= (m_pad_latch[1] & 0x01); |
| 409 | 434 | |
| 410 | | // row of the keyboard matrix are read 4-bits at time, and gets returned as bit1->bit4 |
| 411 | | if ((exp & 0x0f) == 0x02) |
| 412 | | { |
| 413 | | if (m_fck_scan < 9) |
| 414 | | ret |= ~(((m_io_fckey[m_fck_scan]->read() >> (m_fck_mode * 4)) & 0x0f) << 1) & 0x1e; |
| 415 | | else |
| 416 | | ret |= 0x1e; |
| 417 | | } |
| 435 | // shift |
| 436 | m_pad_latch[1] >>= 1; |
| 437 | |
| 418 | 438 | |
| 419 | | if ((exp & 0x0f) == 0x03) |
| 439 | // EXP input |
| 440 | switch (exp & 0x0f) |
| 420 | 441 | { |
| 421 | | if (m_fck_scan < 12) |
| 422 | | ret |= ~(((m_io_subkey[m_fck_scan]->read() >> (m_fck_mode * 4)) & 0x0f) << 1) & 0x1e; |
| 423 | | else |
| 424 | | ret |= 0x1e; |
| 442 | case 0x01: // Lightgun |
| 443 | { |
| 444 | int x = m_zapper_latch[0][1]; // x-position |
| 445 | int y = m_zapper_latch[0][2]; // y-position |
| 446 | UINT32 pix, color_base; |
| 447 | |
| 448 | // get the pixel at the gun position |
| 449 | pix = m_ppu->get_pixel(x, y); |
| 450 | |
| 451 | // get the color base from the ppu |
| 452 | color_base = m_ppu->get_colorbase(); |
| 453 | |
| 454 | // check if the cursor is over a bright pixel |
| 455 | if ((pix == color_base + 0x20) || (pix == color_base + 0x30) || |
| 456 | (pix == color_base + 0x33) || (pix == color_base + 0x34)) |
| 457 | ret &= ~0x08; // sprite hit |
| 458 | else |
| 459 | ret |= 0x08; // no sprite hit |
| 460 | |
| 461 | // light gun trigger |
| 462 | ret |= (m_zapper_latch[0][0] << 4); |
| 463 | } |
| 464 | break; |
| 465 | |
| 466 | case 0x02: // FC Keyboard: rows of the keyboard matrix are read 4-bits at time and returned as bit1->bit4 |
| 467 | if (m_fck_scan < 9) |
| 468 | ret |= ~(((m_io_fckey[m_fck_scan]->read() >> (m_fck_mode * 4)) & 0x0f) << 1) & 0x1e; |
| 469 | else |
| 470 | ret |= 0x1e; |
| 471 | break; |
| 472 | |
| 473 | case 0x03: // Subor Keyboard: rows of the keyboard matrix are read 4-bits at time and returned as bit1->bit4 |
| 474 | if (m_fck_scan < 12) |
| 475 | ret |= ~(((m_io_subkey[m_fck_scan]->read() >> (m_fck_mode * 4)) & 0x0f) << 1) & 0x1e; |
| 476 | else |
| 477 | ret |= 0x1e; |
| 478 | break; |
| 479 | |
| 480 | case 0x04: // Arkanoid paddle |
| 481 | ret |= ((m_paddle_latch & 0x80) >> 6); // paddle data |
| 482 | m_paddle_latch <<= 1; |
| 483 | m_paddle_latch &= 0xff; |
| 484 | break; |
| 485 | |
| 486 | case 0x06: // Mahjong Panel |
| 487 | ret |= ((m_mjpanel_latch & 0x01) << 1); |
| 488 | m_mjpanel_latch >>= 1; |
| 489 | break; |
| 490 | |
| 491 | case 0x07: // 'multitap' p4 |
| 492 | ret |= ((m_pad_latch[3] & 0x01) << 1); |
| 493 | m_pad_latch[3] >>= 1; |
| 494 | break; |
| 425 | 495 | } |
| 426 | 496 | |
| 427 | | /* Handle data line 0's serial output */ |
| 428 | | if ((exp & 0x0f) == 0x06) |
| 429 | | ret |= (((m_in_1.i0 >> m_in_1.shift) & 0x01) << 1); |
| 430 | | else |
| 431 | | ret |= ((m_in_1.i0 >> m_in_1.shift) & 0x01); |
| 432 | | |
| 433 | | /* zapper */ |
| 434 | | if ((exp & 0x0f) == 0x01) |
| 435 | | { |
| 436 | | int x = m_in_1.i1; /* read Zapper x-position */ |
| 437 | | int y = m_in_1.i2; /* read Zapper y-position */ |
| 438 | | UINT32 pix, color_base; |
| 439 | | |
| 440 | | /* get the pixel at the gun position */ |
| 441 | | pix = m_ppu->get_pixel(x, y); |
| 442 | | |
| 443 | | /* get the color base from the ppu */ |
| 444 | | color_base = m_ppu->get_colorbase(); |
| 445 | | |
| 446 | | /* look at the screen and see if the cursor is over a bright pixel */ |
| 447 | | if ((pix == color_base + 0x20) || (pix == color_base + 0x30) || |
| 448 | | (pix == color_base + 0x33) || (pix == color_base + 0x34)) |
| 449 | | { |
| 450 | | ret &= ~0x08; /* sprite hit */ |
| 451 | | } |
| 452 | | else |
| 453 | | ret |= 0x08; /* no sprite hit */ |
| 454 | | |
| 455 | | /* If button 1 is pressed, indicate the light gun trigger is pressed */ |
| 456 | | ret |= ((m_in_1.i0 & 0x01) << 4); |
| 457 | | } |
| 458 | | |
| 459 | | /* arkanoid dial */ |
| 460 | | if ((exp & 0x0f) == 0x04) |
| 461 | | { |
| 462 | | /* Handle data line 2's serial output */ |
| 463 | | ret |= ((m_in_1.i2 >> m_in_1.shift) & 0x01) << 3; |
| 464 | | |
| 465 | | /* Handle data line 3's serial output - bits are reversed */ |
| 466 | | /* NPW 27-Nov-2007 - there is no third subscript! commenting out */ |
| 467 | | /* ret |= ((m_in_1[3] >> m_in_1.shift) & 0x01) << 4; */ |
| 468 | | /* ret |= ((m_in_1[3] << m_in_1.shift) & 0x80) >> 3; */ |
| 469 | | } |
| 470 | | |
| 471 | 497 | if (LOG_JOY) |
| 472 | | logerror("joy 1 read, val: %02x, pc: %04x, bits read: %d, chan0: %08x\n", ret, space.device().safe_pc(), m_in_1.shift, m_in_1.i0); |
| 498 | logerror("joy 1 read, val: %02x, pc: %04x\n", ret, space.device().safe_pc()); |
| 473 | 499 | |
| 474 | | m_in_1.shift++; |
| 475 | | |
| 476 | 500 | return ret; |
| 477 | 501 | } |
| 478 | 502 | |
| r23721 | r23722 | |
| 480 | 504 | { |
| 481 | 505 | int cfg = m_io_ctrlsel->read(); |
| 482 | 506 | int exp = m_io_exp->read(); |
| 483 | | |
| 484 | | /* Check if lightgun has been chosen as input: if so, enable crosshair */ |
| 507 | |
| 508 | if (LOG_JOY) |
| 509 | logerror("joy write, val: %02x, pc: %04x\n", data, space.device().safe_pc()); |
| 510 | |
| 511 | // Check if lightgun has been chosen as input: if so, enable crosshair |
| 485 | 512 | timer_set(attotime::zero, TIMER_LIGHTGUN_TICK); |
| 486 | 513 | |
| 487 | 514 | if ((exp & 0x0f) == 0x02 || (exp & 0x0f) == 0x03) |
| r23721 | r23722 | |
| 504 | 531 | m_fck_scan = 0; |
| 505 | 532 | } |
| 506 | 533 | } |
| 507 | | |
| 508 | | // check 'standard' inputs |
| 534 | |
| 509 | 535 | if (data & 0x01) |
| 510 | 536 | return; |
| 511 | 537 | |
| 512 | | if (LOG_JOY) |
| 513 | | logerror("joy 0 bits read: %d\n", m_in_0.shift); |
| 538 | // Toggling bit 0 high then low resets controllers |
| 539 | m_pad_latch[0] = 0; |
| 540 | m_pad_latch[1] = 0; |
| 541 | m_pad_latch[2] = 0; |
| 542 | m_pad_latch[3] = 0; |
| 543 | m_zapper_latch[0][0] = 0; |
| 544 | m_zapper_latch[0][1] = 0; |
| 545 | m_zapper_latch[0][2] = 0; |
| 546 | m_paddle_btn_latch = 0; |
| 547 | m_paddle_latch = 0; |
| 548 | m_mjpanel_latch = 0; |
| 514 | 549 | |
| 515 | | /* Toggling bit 0 high then low resets both controllers */ |
| 516 | | m_in_0.shift = 0; |
| 517 | | m_in_1.shift = 0; |
| 518 | | m_in_0.i0 = 0; |
| 519 | | m_in_0.i1 = 0; |
| 520 | | m_in_0.i2 = 0; |
| 521 | | m_in_1.i0 = 0; |
| 522 | | m_in_1.i1 = 0; |
| 523 | | m_in_1.i2 = 0; |
| 524 | | m_in_2.i0 = 0; |
| 525 | | m_in_2.i1 = 0; |
| 526 | | m_in_2.i2 = 0; |
| 527 | | m_in_3.i0 = 0; |
| 528 | | m_in_3.i1 = 0; |
| 529 | | m_in_3.i2 = 0; |
| 530 | | |
| 531 | 550 | // P1 inputs |
| 532 | | if ((cfg & 0x000f) == 0x0001) /* gamepad 1 */ |
| 533 | | m_in_0.i0 = m_io_pad[0]->read(); |
| 534 | | else if ((cfg & 0x000f) == 0x0002) /* crazy climber controller (left stick) */ |
| 535 | | m_in_0.i0 = m_io_cc_left->read(); |
| 551 | switch (cfg & 0x000f) |
| 552 | { |
| 553 | case 0x01: // pad 1 |
| 554 | m_pad_latch[0] = m_io_pad[0]->read(); |
| 555 | break; |
| 556 | |
| 557 | case 0x02: // crazy climber (left stick) |
| 558 | m_pad_latch[0] = m_io_cc_left->read(); |
| 559 | break; |
| 560 | } |
| 536 | 561 | |
| 537 | 562 | // P2 inputs |
| 538 | | if ((cfg & 0x00f0) == 0x0010) /* gamepad 2 */ |
| 539 | | m_in_1.i0 = m_io_pad[1]->read(); |
| 540 | | else if ((cfg & 0x00f0) == 0x0020) /* crazy climber controller (right stick) */ |
| 541 | | m_in_1.i0 = m_io_cc_right->read(); |
| 563 | switch ((cfg & 0x00f0) >> 4) |
| 564 | { |
| 565 | case 0x01: // pad 2 |
| 566 | m_pad_latch[1] = m_io_pad[1]->read(); |
| 567 | break; |
| 568 | |
| 569 | case 0x02: // crazy climber (right stick) |
| 570 | m_pad_latch[1] = m_io_cc_right->read(); |
| 571 | break; |
| 572 | |
| 573 | } |
| 542 | 574 | |
| 575 | // P3 & P4 inputs in Famicom (e.g. through Hori Twin Adapter or Hori 4 Players Adapter) |
| 576 | // are read in parallel with P1 & P2 (just using diff bits) |
| 543 | 577 | // P3 inputs |
| 544 | 578 | if ((exp & 0x0f) == 7 && (cfg & 0x0f00) == 0x0100) |
| 545 | | { |
| 546 | | m_in_2.i0 = m_io_pad[2]->read(); |
| 547 | | m_in_0.i0 |= (m_in_2.i0 << 8) | (0x08 << 16); |
| 548 | | } |
| 579 | m_pad_latch[2] = m_io_pad[2]->read(); // pad 3 |
| 549 | 580 | |
| 550 | 581 | // P4 inputs |
| 551 | 582 | if ((exp & 0x0f) == 7 && (cfg & 0xf000) == 0x1000) |
| 552 | | { |
| 553 | | m_in_3.i0 = m_io_pad[3]->read(); |
| 554 | | m_in_1.i0 |= (m_in_3.i0 << 8) | (0x04 << 16); |
| 555 | | } |
| 583 | m_pad_latch[3] = m_io_pad[3]->read(); // pad 4 |
| 556 | 584 | |
| 557 | | |
| 585 | |
| 558 | 586 | // EXP input |
| 559 | 587 | switch (exp & 0x0f) |
| 560 | 588 | { |
| 561 | 589 | case 0x01: // Lightgun |
| 562 | | m_in_0.i0 = m_io_zapper2_t->read(); |
| 563 | | m_in_0.i1 = m_io_zapper2_x->read(); |
| 564 | | m_in_0.i2 = m_io_zapper2_y->read(); |
| 590 | m_zapper_latch[0][0] = m_io_zapper2_t->read(); |
| 591 | m_zapper_latch[0][1] = m_io_zapper2_x->read(); |
| 592 | m_zapper_latch[0][2] = m_io_zapper2_y->read(); |
| 565 | 593 | break; |
| 566 | | #if 0 |
| 594 | |
| 567 | 595 | case 0x02: // FC Keyboard |
| 568 | | // here we should also have the tape output |
| 569 | | if (BIT(data, 2)) // keyboard active |
| 570 | | { |
| 571 | | UINT8 out = BIT(data, 1); // scan |
| 572 | | |
| 573 | | if (m_fck_mode && !out && ++m_fck_scan > 9) |
| 574 | | m_fck_scan = 0; |
| 575 | | |
| 576 | | m_fck_mode = out; // access lower or upper 4 bits |
| 577 | | |
| 578 | | if (BIT(data, 0)) // reset |
| 579 | | m_fck_scan = 0; |
| 580 | | } |
| 581 | | break; |
| 582 | | |
| 583 | 596 | case 0x03: // Subor Keyboard |
| 584 | | if (BIT(data, 2)) // keyboard active |
| 585 | | { |
| 586 | | UINT8 out = BIT(data, 1); // scan |
| 587 | | |
| 588 | | if (m_fck_mode && !out && ++m_fck_scan > 12) |
| 589 | | m_fck_scan = 0; |
| 590 | | |
| 591 | | m_fck_mode = out; // access lower or upper 4 bits |
| 592 | | |
| 593 | | if (BIT(data, 0)) // reset |
| 594 | | m_fck_scan = 0; |
| 595 | | } |
| 597 | // these are scanned differently than other devices: |
| 598 | // writes to $4016 with bit2 set always update the |
| 599 | // line counter and writing bit0 set resets the counter |
| 596 | 600 | break; |
| 597 | | #endif |
| 601 | |
| 598 | 602 | case 0x04: // Arkanoid paddle |
| 599 | | m_in_1.i0 |= (UINT8) ((UINT8) m_io_paddle->read() + (UINT8)0x52) ^ 0xff; |
| 603 | m_paddle_btn_latch = m_io_paddle_btn->read(); |
| 604 | m_paddle_latch = (UINT8) (m_io_paddle->read() ^ 0xff); |
| 600 | 605 | break; |
| 601 | 606 | |
| 602 | 607 | case 0x06: // Mahjong Panel |
| 603 | 608 | if (data & 0xf8) |
| 604 | 609 | logerror("Error: Mahjong panel read with mux data %02x\n", (data & 0xfe)); |
| 605 | 610 | else |
| 606 | | m_in_1.i0 = m_io_mahjong[(data & 0xfe) >> 1]->read(); |
| 611 | m_mjpanel_latch = m_io_mahjong[(data & 0xfe) >> 1]->read(); |
| 607 | 612 | break; |
| 608 | 613 | } |
| 609 | 614 | |