trunk/src/mame/drivers/cobra.c
| r17383 | r17384 | |
| 278 | 278 | #include "machine/pci.h" |
| 279 | 279 | #include "machine/idectrl.h" |
| 280 | 280 | #include "machine/timekpr.h" |
| 281 | #include "machine/jvshost.h" |
| 282 | #include "machine/jvsdev.h" |
| 281 | 283 | #include "video/polynew.h" |
| 282 | 284 | #include "sound/rf5c400.h" |
| 283 | 285 | |
| r17383 | r17384 | |
| 286 | 288 | #define M2SFIFO_VERBOSE 0 |
| 287 | 289 | #define S2MFIFO_VERBOSE 0 |
| 288 | 290 | |
| 291 | |
| 292 | /* Cobra Renderer class */ |
| 293 | |
| 289 | 294 | struct cobra_polydata |
| 290 | 295 | { |
| 291 | 296 | }; |
| r17383 | r17384 | |
| 354 | 359 | }; |
| 355 | 360 | }; |
| 356 | 361 | |
| 362 | |
| 363 | /* FIFO class */ |
| 357 | 364 | class cobra_fifo |
| 358 | 365 | { |
| 359 | 366 | public: |
| r17383 | r17384 | |
| 402 | 409 | event_delegate m_event_callback; |
| 403 | 410 | }; |
| 404 | 411 | |
| 412 | |
| 413 | /* Cobra JVS Device class */ |
| 414 | |
| 415 | class cobra_jvs : public jvs_device |
| 416 | { |
| 417 | public: |
| 418 | cobra_jvs(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 419 | |
| 420 | protected: |
| 421 | virtual bool switches(UINT8 *&buf, UINT8 count_players, UINT8 bytes_per_switch); |
| 422 | virtual bool coin_counters(UINT8 *&buf, UINT8 count); |
| 423 | }; |
| 424 | |
| 425 | const device_type COBRA_JVS = &device_creator<cobra_jvs>; |
| 426 | |
| 427 | cobra_jvs::cobra_jvs(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 428 | : jvs_device(mconfig, COBRA_JVS, "COBRA_JVS", tag, owner, clock) |
| 429 | { |
| 430 | |
| 431 | } |
| 432 | |
| 433 | bool cobra_jvs::switches(UINT8 *&buf, UINT8 count_players, UINT8 bytes_per_switch) |
| 434 | { |
| 435 | printf("jvs switch read: num players %d, bytes %d\n", count_players, bytes_per_switch); |
| 436 | |
| 437 | if (count_players > 2 || bytes_per_switch > 2) |
| 438 | return false; |
| 439 | |
| 440 | static const char* player_ports[2] = { ":P1", ":P2" }; |
| 441 | |
| 442 | *buf++ = ioport(":TEST")->read_safe(0); |
| 443 | |
| 444 | for (int i=0; i < count_players; i++) |
| 445 | { |
| 446 | UINT32 pval = ioport(player_ports[i])->read_safe(0); |
| 447 | for (int j=0; j < bytes_per_switch; j++) |
| 448 | { |
| 449 | *buf++ = (UINT8)(pval >> ((1-j) * 8)); |
| 450 | } |
| 451 | } |
| 452 | return true; |
| 453 | } |
| 454 | |
| 455 | bool cobra_jvs::coin_counters(UINT8 *&buf, UINT8 count) |
| 456 | { |
| 457 | printf("jvs coin counter read: count %d\n", count); |
| 458 | |
| 459 | if (count > 2) |
| 460 | return false; |
| 461 | |
| 462 | *buf++ = 0x00; |
| 463 | *buf++ = 0x01; |
| 464 | |
| 465 | return true; |
| 466 | } |
| 467 | |
| 468 | |
| 469 | class cobra_jvs_host : public jvs_host |
| 470 | { |
| 471 | public: |
| 472 | cobra_jvs_host(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 473 | void write(UINT8, const UINT8 *&rec_data, UINT32 &rec_size); |
| 474 | |
| 475 | private: |
| 476 | UINT8 m_send[512]; |
| 477 | int m_send_ptr; |
| 478 | }; |
| 479 | |
| 480 | const device_type COBRA_JVS_HOST = &device_creator<cobra_jvs_host>; |
| 481 | |
| 482 | cobra_jvs_host::cobra_jvs_host(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 483 | : jvs_host(mconfig, COBRA_JVS_HOST, "COBRA_JVS_HOST", tag, owner, clock) |
| 484 | { |
| 485 | m_send_ptr = 0; |
| 486 | } |
| 487 | |
| 488 | void cobra_jvs_host::write(UINT8 data, const UINT8 *&rec_data, UINT32 &rec_size) |
| 489 | { |
| 490 | m_send[m_send_ptr++] = data; |
| 491 | push(data); |
| 492 | |
| 493 | if (m_send[0] == 0xe0) |
| 494 | { |
| 495 | if (m_send_ptr > 2) |
| 496 | { |
| 497 | UINT8 length = m_send[2]; |
| 498 | if (length == 0xff) |
| 499 | length = 4; |
| 500 | else |
| 501 | length = length + 3; |
| 502 | |
| 503 | if (m_send_ptr >= length) |
| 504 | { |
| 505 | commit_encoded(); |
| 506 | |
| 507 | get_encoded_reply(rec_data, rec_size); |
| 508 | |
| 509 | m_send_ptr = 0; |
| 510 | return; |
| 511 | } |
| 512 | } |
| 513 | } |
| 514 | else |
| 515 | { |
| 516 | m_send_ptr = 0; |
| 517 | } |
| 518 | |
| 519 | rec_data = NULL; |
| 520 | rec_size = 0; |
| 521 | } |
| 522 | |
| 523 | |
| 524 | /* Cobra driver class */ |
| 525 | |
| 405 | 526 | class cobra_state : public driver_device |
| 406 | 527 | { |
| 407 | 528 | public: |
| r17383 | r17384 | |
| 465 | 586 | void m2sfifo_event_callback(cobra_fifo::EventType event); |
| 466 | 587 | void s2mfifo_event_callback(cobra_fifo::EventType event); |
| 467 | 588 | |
| 589 | enum |
| 590 | { |
| 591 | MAIN_INT_M2S = 0x01, |
| 592 | MAIN_INT_S2M = 0x02, |
| 593 | }; |
| 594 | |
| 468 | 595 | UINT8 m_m2s_int_enable; |
| 469 | 596 | UINT8 m_s2m_int_enable; |
| 470 | 597 | UINT8 m_vblank_enable; |
| r17383 | r17384 | |
| 503 | 630 | int m_gfx_fifo_loopback; |
| 504 | 631 | int m_gfx_unknown_v1; |
| 505 | 632 | int m_gfx_status_byte; |
| 633 | |
| 506 | 634 | DECLARE_DRIVER_INIT(racjamdx); |
| 507 | 635 | DECLARE_DRIVER_INIT(bujutsu); |
| 508 | 636 | DECLARE_DRIVER_INIT(cobra); |
| r17383 | r17384 | |
| 510 | 638 | |
| 511 | 639 | void cobra_renderer::render_color_scan(INT32 scanline, const extent_t &extent, const cobra_polydata &extradata, int threadid) |
| 512 | 640 | { |
| 513 | | /* |
| 514 | 641 | UINT32 *fb = &m_framebuffer->pix32(scanline); |
| 515 | 642 | |
| 516 | | UINT32 color = 0xffff0000; // TODO |
| 643 | UINT32 color = 0xff000000; // TODO |
| 517 | 644 | |
| 518 | 645 | for (int x = extent.startx; x < extent.stopx; x++) |
| 519 | 646 | { |
| 520 | 647 | fb[x] = color; |
| 521 | 648 | } |
| 522 | | */ |
| 523 | 649 | } |
| 524 | 650 | |
| 525 | 651 | void cobra_renderer::render_texture_scan(INT32 scanline, const extent_t &extent, const cobra_polydata &extradata, int threadid) |
| r17383 | r17384 | |
| 873 | 999 | |
| 874 | 1000 | if (m_m2s_int_enable & 0x80) |
| 875 | 1001 | { |
| 1002 | if (!m_m2s_int_mode) |
| 1003 | m_main_int_active |= MAIN_INT_M2S; |
| 1004 | |
| 876 | 1005 | cputag_set_input_line(machine(), "maincpu", INPUT_LINE_IRQ0, ASSERT_LINE); |
| 877 | 1006 | } |
| 878 | 1007 | |
| r17383 | r17384 | |
| 895 | 1024 | switch (event) |
| 896 | 1025 | { |
| 897 | 1026 | case cobra_fifo::EVENT_EMPTY: |
| 1027 | m_main_int_active &= ~MAIN_INT_S2M; |
| 898 | 1028 | break; |
| 899 | 1029 | |
| 900 | 1030 | case cobra_fifo::EVENT_HALF_FULL: |
| r17383 | r17384 | |
| 1036 | 1166 | |
| 1037 | 1167 | int value = 0x01; |
| 1038 | 1168 | |
| 1039 | | if (m_s2mfifo->is_empty()) // TODO: this is an interrupt |
| 1040 | | { |
| 1041 | | value |= 0x2; |
| 1042 | | } |
| 1043 | | |
| 1044 | | //value |= (m_main_int_active & 2) ? 0x00 : 0x02; |
| 1045 | | value |= (m_main_int_active & 1) ? 0x00 : 0x08; |
| 1169 | value |= (m_main_int_active & MAIN_INT_S2M) ? 0x00 : 0x02; |
| 1170 | value |= (m_main_int_active & MAIN_INT_M2S) ? 0x00 : 0x08; |
| 1046 | 1171 | value |= (m_gfx_unk_flag & 0x80) ? 0x00 : 0x04; |
| 1047 | 1172 | |
| 1048 | 1173 | r |= (UINT64)(value) << 32; |
| r17383 | r17384 | |
| 1060 | 1185 | |
| 1061 | 1186 | m_m2sfifo->push(&space.device(), (UINT8)(data >> 40)); |
| 1062 | 1187 | |
| 1188 | if (!m_m2s_int_mode) |
| 1189 | m_main_int_active &= ~MAIN_INT_M2S; |
| 1190 | |
| 1063 | 1191 | cputag_set_input_line(space.machine(), "subcpu", INPUT_LINE_IRQ0, ASSERT_LINE); |
| 1064 | 1192 | |
| 1065 | 1193 | // EXISR needs to update for the *next* instruction during FIFO tests |
| r17383 | r17384 | |
| 1082 | 1210 | { |
| 1083 | 1211 | if (!m_m2sfifo->is_half_full()) |
| 1084 | 1212 | { |
| 1085 | | m_main_int_active |= 1; |
| 1213 | m_main_int_active |= MAIN_INT_M2S; |
| 1086 | 1214 | } |
| 1087 | 1215 | else |
| 1088 | 1216 | { |
| 1089 | | m_main_int_active &= ~1; |
| 1217 | m_main_int_active &= ~MAIN_INT_M2S; |
| 1090 | 1218 | } |
| 1091 | 1219 | } |
| 1092 | 1220 | else |
| 1093 | 1221 | { |
| 1094 | 1222 | if (m_m2sfifo->is_empty()) |
| 1095 | 1223 | { |
| 1096 | | m_main_int_active |= 1; |
| 1224 | m_main_int_active |= MAIN_INT_M2S; |
| 1097 | 1225 | } |
| 1098 | 1226 | else |
| 1099 | 1227 | { |
| 1100 | | m_main_int_active &= ~1; |
| 1228 | m_main_int_active &= ~MAIN_INT_M2S; |
| 1101 | 1229 | } |
| 1102 | 1230 | } |
| 1103 | 1231 | |
| r17383 | r17384 | |
| 1133 | 1261 | |
| 1134 | 1262 | if ((m_s2m_int_enable & 0x80) == 0) |
| 1135 | 1263 | { |
| 1136 | | m_main_int_active &= ~2; |
| 1264 | m_main_int_active &= ~MAIN_INT_S2M; |
| 1137 | 1265 | |
| 1138 | 1266 | // clear the interrupt |
| 1139 | 1267 | cputag_set_input_line(space.machine(), "maincpu", INPUT_LINE_IRQ0, CLEAR_LINE); |
| r17383 | r17384 | |
| 1346 | 1474 | |
| 1347 | 1475 | m_s2mfifo->push(&space.device(), (UINT8)(data >> 24)); |
| 1348 | 1476 | |
| 1477 | m_main_int_active |= MAIN_INT_S2M; |
| 1478 | |
| 1349 | 1479 | // fire off an interrupt if enabled |
| 1350 | 1480 | if (m_s2m_int_enable & 0x80) |
| 1351 | 1481 | { |
| 1352 | | m_main_int_active |= 2; |
| 1353 | | |
| 1354 | 1482 | cputag_set_input_line(space.machine(), "maincpu", INPUT_LINE_IRQ0, ASSERT_LINE); |
| 1355 | 1483 | } |
| 1356 | 1484 | } |
| r17383 | r17384 | |
| 1553 | 1681 | |
| 1554 | 1682 | static void sub_jvs_w(device_t *device, UINT8 data) |
| 1555 | 1683 | { |
| 1684 | cobra_jvs_host *jvs = downcast<cobra_jvs_host *>(device->machine().device("cobra_jvs_host")); |
| 1556 | 1685 | printf("sub_jvs_w: %02X\n", data); |
| 1686 | |
| 1687 | const UINT8 *rec_data; |
| 1688 | UINT32 rec_size; |
| 1689 | |
| 1690 | jvs->write(data, rec_data, rec_size); |
| 1691 | |
| 1692 | if (rec_size > 0) |
| 1693 | { |
| 1694 | printf("jvs reply "); |
| 1695 | for (int i=0; i < rec_size; i++) |
| 1696 | { |
| 1697 | printf("%02X ", rec_data[i]); |
| 1698 | } |
| 1699 | printf("\n"); |
| 1700 | } |
| 1557 | 1701 | } |
| 1558 | 1702 | |
| 1559 | 1703 | static ADDRESS_MAP_START( cobra_sub_map, AS_PROGRAM, 32, cobra_state ) |
| r17383 | r17384 | |
| 1938 | 2082 | } |
| 1939 | 2083 | else |
| 1940 | 2084 | { |
| 1941 | | //render_delegate rd = render_delegate(FUNC(cobra_renderer::render_color_scan), this); |
| 2085 | render_delegate rd = render_delegate(FUNC(cobra_renderer::render_color_scan), this); |
| 1942 | 2086 | for (int i=2; i < units; i++) |
| 1943 | 2087 | { |
| 1944 | | //render_triangle(visarea, rd, 6, vert[i-2], vert[i-1], vert[i]); |
| 1945 | | draw_point(visarea, vert[i-2], 0xffff0000); |
| 1946 | | draw_point(visarea, vert[i-1], 0xffff0000); |
| 1947 | | draw_point(visarea, vert[i], 0xffff0000); |
| 2088 | render_triangle(visarea, rd, 6, vert[i-2], vert[i-1], vert[i]); |
| 2089 | //draw_point(visarea, vert[i-2], 0xffff0000); |
| 2090 | //draw_point(visarea, vert[i-1], 0xffff0000); |
| 2091 | //draw_point(visarea, vert[i], 0xffff0000); |
| 1948 | 2092 | } |
| 1949 | 2093 | } |
| 1950 | 2094 | break; |
| r17383 | r17384 | |
| 2539 | 2683 | /*****************************************************************************/ |
| 2540 | 2684 | |
| 2541 | 2685 | INPUT_PORTS_START( cobra ) |
| 2542 | | PORT_START("IN0") |
| 2543 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START1 ) |
| 2544 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1) |
| 2545 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1) |
| 2546 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1) |
| 2547 | | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1) |
| 2548 | | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) |
| 2549 | | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) |
| 2550 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1) |
| 2686 | PORT_START("TEST") |
| 2687 | PORT_SERVICE_NO_TOGGLE( 0x80, IP_ACTIVE_LOW) /* Test Button */ |
| 2688 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Service") PORT_CODE(KEYCODE_7) |
| 2689 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_SERVICE2 ) |
| 2690 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) |
| 2691 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 2692 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 2693 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 2694 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 2551 | 2695 | |
| 2696 | PORT_START("P1") |
| 2697 | PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(1) |
| 2698 | PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_PLAYER(1) |
| 2699 | PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1) |
| 2700 | PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1) |
| 2701 | PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1) |
| 2702 | PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1) |
| 2703 | PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) |
| 2704 | PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) |
| 2705 | PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1) |
| 2706 | PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1) |
| 2707 | PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(1) |
| 2708 | PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_PLAYER(1) |
| 2709 | PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_PLAYER(1) |
| 2710 | PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_PLAYER(1) |
| 2711 | PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_PLAYER(1) |
| 2712 | PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_PLAYER(1) |
| 2713 | |
| 2714 | PORT_START("P2") |
| 2715 | PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(2) |
| 2716 | PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_PLAYER(2) |
| 2717 | PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2) |
| 2718 | PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2) |
| 2719 | PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2) |
| 2720 | PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2) |
| 2721 | PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) |
| 2722 | PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) |
| 2723 | PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2) |
| 2724 | PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2) |
| 2725 | PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(2) |
| 2726 | PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_PLAYER(2) |
| 2727 | PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_PLAYER(2) |
| 2728 | PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_PLAYER(2) |
| 2729 | PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_PLAYER(2) |
| 2730 | PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_PLAYER(2) |
| 2552 | 2731 | INPUT_PORTS_END |
| 2553 | 2732 | |
| 2554 | 2733 | static powerpc_config main_ppc_cfg = |
| r17383 | r17384 | |
| 2627 | 2806 | |
| 2628 | 2807 | MCFG_QUANTUM_TIME(attotime::from_hz(15005)) |
| 2629 | 2808 | |
| 2630 | | MCFG_MACHINE_RESET( cobra ) |
| 2809 | MCFG_MACHINE_RESET(cobra) |
| 2631 | 2810 | |
| 2632 | 2811 | MCFG_PCI_BUS_LEGACY_ADD("pcibus", 0) |
| 2633 | 2812 | MCFG_PCI_BUS_LEGACY_DEVICE(0, NULL, mpc106_pci_r, mpc106_pci_w) |
| r17383 | r17384 | |
| 2650 | 2829 | MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) |
| 2651 | 2830 | MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) |
| 2652 | 2831 | |
| 2653 | | MCFG_M48T58_ADD( "m48t58" ) |
| 2832 | MCFG_M48T58_ADD("m48t58") |
| 2654 | 2833 | |
| 2834 | MCFG_DEVICE_ADD("cobra_jvs_host", COBRA_JVS_HOST, 4000000) |
| 2835 | MCFG_JVS_DEVICE_ADD("cobra_jvs", COBRA_JVS, "cobra_jvs_host") |
| 2836 | |
| 2655 | 2837 | MACHINE_CONFIG_END |
| 2656 | 2838 | |
| 2657 | 2839 | /*****************************************************************************/ |