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 | /*****************************************************************************/ |