trunk/src/mame/drivers/coolridr.c
| r21475 | r21476 | |
| 10 | 10 | http://www.google.com/patents/US6141122 |
| 11 | 11 | |
| 12 | 12 | TODO: |
| 13 | | - walk the dog |
| 13 | - Understand what the 0x400000c reads on SH-2 really do. |
| 14 | - Remove SH-2 watchdog hack, if we ever bother about it ... |
| 14 | 15 | - improve sound emulation |
| 15 | | - i8237 purpose is unknown, might even not be at the right place ... |
| 16 | - i8237 purpose is unknown (missing ROM for comms?). |
| 16 | 17 | - verify zooming etc. our current algorithm is a bit ugly for text |
| 17 | 18 | |
| 18 | 19 | |
| 19 | | |
| 20 | 20 | ======================================================================================================= |
| 21 | 21 | |
| 22 | 22 | Cool Riders |
| r21475 | r21476 | |
| 277 | 277 | |
| 278 | 278 | |
| 279 | 279 | #include "emu.h" |
| 280 | | #include "debugger.h" |
| 281 | 280 | #include "cpu/sh2/sh2.h" |
| 282 | 281 | #include "cpu/m68000/m68000.h" |
| 283 | 282 | #include "sound/scsp.h" |
| 284 | | #include "machine/am9517a.h" |
| 285 | 283 | #include "machine/nvram.h" |
| 286 | 284 | #include "rendlay.h" |
| 287 | 285 | |
| r21475 | r21476 | |
| 342 | 340 | UINT32 m_clipvals[2][3]; |
| 343 | 341 | UINT8 m_clipblitterMode[2]; // hack |
| 344 | 342 | |
| 345 | | |
| 346 | 343 | required_device<cpu_device> m_maincpu; |
| 347 | 344 | required_device<cpu_device> m_subcpu; |
| 348 | 345 | required_device<cpu_device> m_soundcpu; |
| r21475 | r21476 | |
| 373 | 370 | bitmap_ind16 m_bg_bitmap; |
| 374 | 371 | bitmap_ind16 m_bg_bitmap2; |
| 375 | 372 | |
| 376 | | |
| 377 | 373 | bitmap_ind16 m_screen1_bitmap; |
| 378 | 374 | bitmap_ind16 m_screen2_bitmap; |
| 379 | 375 | int m_scsp_last_line; |
| r21475 | r21476 | |
| 452 | 448 | static void *draw_object_threaded(void *param, int threadid); |
| 453 | 449 | int m_usethreads; |
| 454 | 450 | |
| 455 | | |
| 456 | | |
| 457 | 451 | struct cool_render_object |
| 458 | 452 | { |
| 459 | 453 | UINT8* indirect_tiles; |
| r21475 | r21476 | |
| 476 | 470 | int m_listcount1; |
| 477 | 471 | int m_listcount2; |
| 478 | 472 | |
| 479 | | |
| 480 | | |
| 481 | | |
| 482 | | |
| 483 | 473 | // the decode cache mechansim is an optimization |
| 484 | 474 | // we know all gfx are in ROM, and that calling the RLE decompression every time they're used is slow, so we cache the decoded tiles |
| 485 | 475 | // and objects after they're used, for future re-use, quite handy with a driving game. |
| r21475 | r21476 | |
| 515 | 505 | |
| 516 | 506 | }; |
| 517 | 507 | |
| 518 | | |
| 519 | 508 | struct objcachemanager |
| 520 | 509 | { |
| 521 | 510 | int current_object; |
| r21475 | r21476 | |
| 526 | 515 | }; |
| 527 | 516 | |
| 528 | 517 | objcachemanager decode[2]; |
| 529 | | |
| 530 | | |
| 531 | | |
| 532 | | |
| 533 | 518 | }; |
| 534 | 519 | |
| 535 | 520 | #define PRINT_BLIT_STUFF \ |
| r21475 | r21476 | |
| 567 | 552 | machine().primary_screen->register_screen_bitmap(m_bg_bitmap); |
| 568 | 553 | machine().primary_screen->register_screen_bitmap(m_bg_bitmap2); |
| 569 | 554 | |
| 570 | | |
| 571 | | |
| 572 | 555 | machine().primary_screen->register_screen_bitmap(m_screen1_bitmap); |
| 573 | 556 | machine().primary_screen->register_screen_bitmap(m_screen2_bitmap); |
| 574 | 557 | |
| 575 | 558 | machine().gfx[m_gfx_index] = auto_alloc(machine(), gfx_element(machine(), h1_tile_layout, m_h1_pcg, 8, 0)); |
| 576 | 559 | } |
| 577 | 560 | |
| 578 | | // might be a page 'map / base' setup somewhere, but it's just used for ingame backgrounds |
| 579 | | /* 0x00000 - 0x1ffff = screen 1 */ |
| 580 | | /* 0x20000 - 0x3ffff = screen 2 */ |
| 581 | | /* 0x40000 - 0xfffff = ? */ |
| 582 | 561 | /* |
| 583 | 562 | vregs are setted up with one of DMA commands (see below) |
| 584 | 563 | 0x3e09b80 screen 1 base, 0x3e9bc0 screen 2 base |
| r21475 | r21476 | |
| 590 | 569 | (everything else is unknown at current time) |
| 591 | 570 | */ |
| 592 | 571 | |
| 593 | | |
| 594 | | |
| 595 | | |
| 596 | | |
| 597 | 572 | #define COOLRIDERS_DRAWGFX_CORE(PIXEL_TYPE, COOL_PIXEL_OP) \ |
| 598 | 573 | do { \ |
| 599 | 574 | do { \ |
| r21475 | r21476 | |
| 790 | 765 | |
| 791 | 766 | void coolridr_state::draw_bg_coolridr(bitmap_ind16 &bitmap, const rectangle &cliprect, int which) |
| 792 | 767 | { |
| 793 | | |
| 794 | 768 | int bg_r,bg_g,bg_b; |
| 795 | 769 | |
| 796 | | |
| 797 | | |
| 798 | | |
| 799 | | |
| 800 | 770 | if(m_pen_fill[which]) |
| 801 | 771 | { |
| 802 | 772 | #if 0 |
| r21475 | r21476 | |
| 811 | 781 | bg_g = (((m_pen_fill[which] >> 8) & 0x78) >> 2) | (((m_pen_fill[which] >> 8) & 0x80) >> 7); |
| 812 | 782 | bg_b = (((m_pen_fill[which] >> 0) & 0x78) >> 2) | (((m_pen_fill[which] >> 0) & 0x80) >> 7); |
| 813 | 783 | bitmap.fill( (bg_r<<10) | (bg_g << 5) | bg_b ,cliprect); |
| 814 | | |
| 815 | 784 | } |
| 816 | 785 | else |
| 817 | 786 | { |
| r21475 | r21476 | |
| 837 | 806 | |
| 838 | 807 | bitmap.fill(VREG(0x3c),cliprect); |
| 839 | 808 | |
| 840 | | |
| 809 | |
| 841 | 810 | UINT16 basey = scrolly>>4; |
| 842 | 811 | for (int y=0;y<25;y++) |
| 843 | 812 | { |
| r21475 | r21476 | |
| 864 | 833 | { |
| 865 | 834 | if(m_rgb_ctrl[which].gradient) |
| 866 | 835 | { |
| 867 | | if( (m_rgb_ctrl[which].setting == 0x1240) || (m_rgb_ctrl[which].setting == 0x920) || (m_rgb_ctrl[which].setting == 0x800) ) |
| 836 | if( (m_rgb_ctrl[which].setting == 0x1240) || (m_rgb_ctrl[which].setting == 0x920) || (m_rgb_ctrl[which].setting == 0x800) ) |
| 868 | 837 | { |
| 869 | 838 | } |
| 870 | 839 | else |
| r21475 | r21476 | |
| 883 | 852 | if(m_rgb_ctrl[which].gradient) |
| 884 | 853 | { |
| 885 | 854 | /* fade-in / outs */ |
| 886 | | if(m_rgb_ctrl[which].setting == 0x1240) |
| 855 | if(m_rgb_ctrl[which].setting == 0x1240) |
| 887 | 856 | { |
| 888 | 857 | r -= m_rgb_ctrl[which].gradient; |
| 889 | 858 | g -= m_rgb_ctrl[which].gradient; |
| r21475 | r21476 | |
| 914 | 883 | m_fadedpals[i] = (r<<10|g<<5|b); |
| 915 | 884 | } |
| 916 | 885 | |
| 917 | | |
| 918 | | |
| 919 | 886 | if (which==0) |
| 920 | 887 | { |
| 921 | 888 | for (int y=0;y<384;y++) |
| r21475 | r21476 | |
| 972 | 939 | /* end video */ |
| 973 | 940 | |
| 974 | 941 | |
| 975 | | |
| 976 | | |
| 977 | | |
| 978 | 942 | #define RLE_BLOCK(writeaddrxor) \ |
| 979 | 943 | /* skip the decoding if it's the same tile as last time! */ \ |
| 980 | 944 | if (!current_decoded) \ |
| r21475 | r21476 | |
| 1381 | 1345 | // b1colorNumber = space.machine().rand()&0xfff; |
| 1382 | 1346 | } |
| 1383 | 1347 | |
| 1384 | | |
| 1385 | | |
| 1386 | | |
| 1387 | 1348 | // if(b1colorNumber > 0x60 || b2colorNumber) |
| 1388 | 1349 | // printf("%08x %08x\n",b1colorNumber,b2colorNumber); |
| 1389 | 1350 | |
| r21475 | r21476 | |
| 1954 | 1915 | int hPosition = 0; |
| 1955 | 1916 | |
| 1956 | 1917 | |
| 1957 | | |
| 1918 | |
| 1958 | 1919 | if (!indirect_zoom_enable) |
| 1959 | 1920 | { |
| 1960 | 1921 | |
| r21475 | r21476 | |
| 1990 | 1951 | { |
| 1991 | 1952 | |
| 1992 | 1953 | int current_decoded = false; |
| 1993 | | |
| 1954 | |
| 1994 | 1955 | if (!indirect_tile_enable && size < DECODECACHE_NUMSPRITETILES) |
| 1995 | 1956 | { |
| 1996 | 1957 | tempshape = object->state->decode[screen].objcache[use_object].tiles[v*used_hCellCount + h].tempshape_multi; |
| r21475 | r21476 | |
| 2028 | 1989 | if (blit_rotate) |
| 2029 | 1990 | { |
| 2030 | 1991 | #define GET_PIX GET_PIX_ROTATED |
| 2031 | | YXLOOP |
| 1992 | YXLOOP |
| 2032 | 1993 | #undef GET_PIX |
| 2033 | 1994 | } |
| 2034 | 1995 | else // no rotate |
| 2035 | 1996 | { |
| 2036 | 1997 | #define GET_PIX GET_PIX_NORMAL |
| 2037 | | YXLOOP |
| 1998 | YXLOOP |
| 2038 | 1999 | #undef GET_PIX |
| 2039 | 2000 | |
| 2040 | 2001 | } |
| r21475 | r21476 | |
| 2609 | 2570 | |
| 2610 | 2571 | // copy our old buffer to the actual screen |
| 2611 | 2572 | copybitmap(m_screen1_bitmap, m_temp_bitmap_sprites, 0, 0, 0, 0, visarea); |
| 2612 | | |
| 2613 | 2573 | |
| 2614 | 2574 | |
| 2615 | 2575 | |
| 2576 | |
| 2616 | 2577 | //m_temp_bitmap_sprites2.fill(0xff000000, visarea); |
| 2617 | 2578 | // render the tilemap to the backbuffer, ready for having sprites drawn on it |
| 2618 | 2579 | draw_bg_coolridr(m_temp_bitmap_sprites, visarea, 0); |
| 2619 | | // wipe the z-buffer ready for the sprites |
| 2580 | // wipe the z-buffer ready for the sprites |
| 2620 | 2581 | /* m_zbuffer_bitmap.fill(0xffff, visarea); */ |
| 2621 | 2582 | // almost certainly wrong |
| 2622 | 2583 | m_clipvals[0][0] = 0; |
| 2623 | 2584 | m_clipvals[0][1] = 0; |
| 2624 | 2585 | m_clipvals[0][2] = 0; |
| 2625 | 2586 | m_clipblitterMode[0] = 0xff; |
| 2626 | | |
| 2587 | |
| 2627 | 2588 | /* bubble sort, might be something better to use instead */ |
| 2628 | 2589 | for (int pass = 0 ; pass < ( m_listcount1 - 1 ); pass++) |
| 2629 | 2590 | { |
| r21475 | r21476 | |
| 2648 | 2609 | { |
| 2649 | 2610 | draw_object_threaded((void*)m_cool_render_object_list1[i],0); |
| 2650 | 2611 | } |
| 2651 | | } |
| 2652 | | |
| 2612 | } |
| 2613 | |
| 2653 | 2614 | m_listcount1 = 0; |
| 2654 | | |
| 2655 | 2615 | |
| 2616 | |
| 2656 | 2617 | } |
| 2657 | 2618 | else if(m_blitterClearMode == 0x8c800000) |
| 2658 | 2619 | { |
| r21475 | r21476 | |
| 2661 | 2622 | |
| 2662 | 2623 | // copy our old buffer to the actual screen |
| 2663 | 2624 | copybitmap(m_screen2_bitmap, m_temp_bitmap_sprites2, 0, 0, 0, 0, visarea); |
| 2664 | | |
| 2665 | 2625 | |
| 2666 | 2626 | |
| 2667 | 2627 | |
| 2628 | |
| 2668 | 2629 | //m_temp_bitmap_sprites2.fill(0xff000000, visarea); |
| 2669 | 2630 | // render the tilemap to the backbuffer, ready for having sprites drawn on it |
| 2670 | 2631 | draw_bg_coolridr(m_temp_bitmap_sprites2, visarea, 1); |
| 2671 | | // wipe the z-buffer ready for the sprites |
| 2632 | // wipe the z-buffer ready for the sprites |
| 2672 | 2633 | /* m_zbuffer_bitmap2.fill(0xffff, visarea); */ |
| 2673 | 2634 | // almost certainly wrong |
| 2674 | 2635 | m_clipvals[1][0] = 0; |
| 2675 | 2636 | m_clipvals[1][1] = 0; |
| 2676 | 2637 | m_clipvals[1][2] = 0; |
| 2677 | 2638 | m_clipblitterMode[1] = 0xff; |
| 2678 | | |
| 2639 | |
| 2679 | 2640 | /* bubble sort, might be something better to use instead */ |
| 2680 | 2641 | for (int pass = 0 ; pass < ( m_listcount2 - 1 ); pass++) |
| 2681 | 2642 | { |
| r21475 | r21476 | |
| 2700 | 2661 | { |
| 2701 | 2662 | draw_object_threaded((void*)m_cool_render_object_list2[i],0); |
| 2702 | 2663 | } |
| 2703 | | } |
| 2704 | | |
| 2664 | } |
| 2665 | |
| 2705 | 2666 | m_listcount2 = 0; |
| 2706 | | |
| 2667 | |
| 2707 | 2668 | } |
| 2708 | 2669 | |
| 2709 | 2670 | //printf("frame\n"); |
| r21475 | r21476 | |
| 2719 | 2680 | |
| 2720 | 2681 | READ32_MEMBER(coolridr_state::sysh1_unk_blit_r) |
| 2721 | 2682 | { |
| 2722 | | // if(offset == 0x0c/4) reads |
| 2683 | // if(offset == 0x0c/4) // TODO |
| 2723 | 2684 | |
| 2724 | 2685 | return m_sysh1_txt_blit[offset]; |
| 2725 | 2686 | } |
| r21475 | r21476 | |
| 2771 | 2732 | do{ |
| 2772 | 2733 | cmd = (m_framebuffer_vram[(0+dma_index)/4] & 0xfc000000) >> 24; |
| 2773 | 2734 | |
| 2774 | | |
| 2775 | 2735 | switch(cmd) |
| 2776 | 2736 | { |
| 2777 | 2737 | case 0x00: /* end of list marker */ |
| r21475 | r21476 | |
| 2854 | 2814 | case 0x44: /* screen 2 / */ |
| 2855 | 2815 | m_rgb_ctrl[(cmd & 4) >> 2].setting = m_framebuffer_vram[(0+dma_index)/4] & 0xffffe0; |
| 2856 | 2816 | m_rgb_ctrl[(cmd & 4) >> 2].gradient = m_framebuffer_vram[(0+dma_index)/4] & 0x1f; |
| 2857 | | |
| 2858 | | |
| 2859 | 2817 | dma_index+=4; |
| 2860 | 2818 | break; |
| 2861 | 2819 | default: |
| r21475 | r21476 | |
| 3046 | 3004 | AM_RANGE(0x03200000, 0x0327ffff) AM_READWRITE16(h1_soundram2_r, h1_soundram2_w,0xffffffff) //AM_SHARE("soundram2") |
| 3047 | 3005 | AM_RANGE(0x03300000, 0x03300fff) AM_DEVREADWRITE16_LEGACY("scsp2", scsp_r, scsp_w, 0xffffffff) |
| 3048 | 3006 | |
| 3049 | | // AM_RANGE(0x04000000, 0x0400001f) AM_DEVREADWRITE8("i8237", am9517a_device, read, write, 0xffffffff) |
| 3050 | 3007 | AM_RANGE(0x04000000, 0x0400003f) AM_READWRITE(sysh1_sound_dma_r,sysh1_sound_dma_w) AM_SHARE("sound_dma") |
| 3051 | | // AM_RANGE(0x04200000, 0x0420003f) AM_RAM /* hi-word for DMA? */ |
| 3008 | // AM_RANGE(0x04200000, 0x0420003f) AM_RAM /* unknown */ |
| 3052 | 3009 | |
| 3053 | 3010 | AM_RANGE(0x05000000, 0x05000fff) AM_RAM |
| 3054 | 3011 | AM_RANGE(0x05200000, 0x052001ff) AM_RAM |
| r21475 | r21476 | |
| 3073 | 3030 | WRITE8_MEMBER(coolridr_state::sound_to_sh1_w) |
| 3074 | 3031 | { |
| 3075 | 3032 | sound_fifo = data; |
| 3076 | | // sound_data = data; |
| 3077 | | // printf("%02x sound\n",data); |
| 3078 | 3033 | } |
| 3079 | 3034 | |
| 3080 | 3035 | static ADDRESS_MAP_START( system_h1_sound_map, AS_PROGRAM, 16, coolridr_state ) |
| r21475 | r21476 | |
| 3444 | 3399 | |
| 3445 | 3400 | if(scanline == 0) |
| 3446 | 3401 | m_maincpu->set_input_line(6, HOLD_LINE); |
| 3447 | | |
| 3448 | 3402 | } |
| 3449 | 3403 | |
| 3450 | 3404 | TIMER_DEVICE_CALLBACK_MEMBER(coolridr_state::system_h1_sub) |
| 3451 | 3405 | { |
| 3452 | 3406 | int scanline = param; |
| 3453 | 3407 | |
| 3454 | | /* 10: reads from 0x4000000 (sound irq) */ |
| 3455 | | /* 12: reads from inputs (so presumably V-Blank) */ |
| 3456 | | /* 14: tries to r/w to 0x62***** area (network irq?) */ |
| 3408 | /* 0xa: reads from 0x4000000 (sound irq) */ |
| 3409 | /* 0xc: reads from inputs (so presumably V-Blank) */ |
| 3410 | /* 0xe: tries to r/w to 0x62***** area (network irq?) */ |
| 3457 | 3411 | |
| 3458 | 3412 | if(scanline == 384) |
| 3459 | 3413 | m_subcpu->set_input_line(0xc, HOLD_LINE); |
| r21475 | r21476 | |
| 3476 | 3430 | |
| 3477 | 3431 | romoffset += (_20bitwordnum>>3)*2; |
| 3478 | 3432 | |
| 3479 | | |
| 3480 | | |
| 3481 | 3433 | if (temp==0) |
| 3482 | 3434 | { |
| 3483 | 3435 | testvalue = READ_COMPRESSED_ROM(0+inc); |
| r21475 | r21476 | |
| 3587 | 3539 | |
| 3588 | 3540 | void coolridr_state::machine_reset() |
| 3589 | 3541 | { |
| 3590 | | // machine().device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, ASSERT_LINE); |
| 3591 | 3542 | m_soundcpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); |
| 3592 | 3543 | |
| 3593 | | |
| 3594 | | |
| 3595 | | // memcpy(m_soundram, memregion("soundcpu")->base()+0x80000, 0x80000); |
| 3596 | | // m_soundcpu->reset(); |
| 3597 | | |
| 3598 | 3544 | m_usethreads = m_io_config->read()&1; |
| 3599 | 3545 | } |
| 3600 | 3546 | |
| 3601 | | #if 0 |
| 3602 | | static I8237_INTERFACE( dmac_intf ) |
| 3603 | | { |
| 3604 | | DEVCB_NULL, //DEVCB_DRIVER_LINE_MEMBER(coolridr_state, coolridr_dma_hrq_changed), |
| 3605 | | DEVCB_NULL, //DEVCB_DRIVER_LINE_MEMBER(coolridr_state, coolridr_tc_w), |
| 3606 | | DEVCB_NULL, //DEVCB_DRIVER_MEMBER(coolridr_state, coolridr_dma_read_byte), |
| 3607 | | DEVCB_NULL,//DEVCB_DRIVER_MEMBER(coolridr_state, coolridr_dma_write_byte), |
| 3608 | | { DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL }, |
| 3609 | | { DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL }, |
| 3610 | | { DEVCB_NULL /*DEVCB_DRIVER_LINE_MEMBER(coolridr_state, coolridr_dack0_w)*/, |
| 3611 | | DEVCB_NULL/*DEVCB_DRIVER_LINE_MEMBER(coolridr_state, coolridr_dack1_w)*/, |
| 3612 | | DEVCB_NULL/*DEVCB_DRIVER_LINE_MEMBER(coolridr_state, coolridr_dack2_w)*/, |
| 3613 | | DEVCB_NULL/*DEVCB_DRIVER_LINE_MEMBER(coolridr_state, coolridr_dack3_w)*/ } |
| 3614 | | }; |
| 3615 | | #endif |
| 3616 | | |
| 3617 | 3547 | static void scsp_irq(device_t *device, int irq) |
| 3618 | 3548 | { |
| 3619 | 3549 | coolridr_state *state = device->machine().driver_data<coolridr_state>(); |
| r21475 | r21476 | |
| 3682 | 3612 | MCFG_CPU_PROGRAM_MAP(coolridr_submap) |
| 3683 | 3613 | MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer2", coolridr_state, system_h1_sub, "lscreen", 0, 1) |
| 3684 | 3614 | |
| 3685 | | // MCFG_I8237_ADD("i8237", 16000000, dmac_intf) |
| 3686 | 3615 | MCFG_NVRAM_ADD_0FILL("nvram") |
| 3687 | 3616 | |
| 3688 | 3617 | MCFG_GFXDECODE(coolridr) |
| r21475 | r21476 | |
| 3788 | 3717 | { |
| 3789 | 3718 | offs_t pc = downcast<cpu_device *>(&space.device())->pc(); |
| 3790 | 3719 | |
| 3791 | | |
| 3792 | 3720 | if(pc == 0x6002cba || pc == 0x6002d42) |
| 3793 | 3721 | return 0; |
| 3794 | 3722 | |
| r21475 | r21476 | |
| 3805 | 3733 | { |
| 3806 | 3734 | machine().device("maincpu")->memory().space(AS_PROGRAM).install_read_handler(0x60d8894, 0x060d8897, read32_delegate(FUNC(coolridr_state::coolridr_hack2_r), this)); |
| 3807 | 3735 | |
| 3808 | | |
| 3809 | 3736 | sh2drc_set_options(machine().device("maincpu"), SH2DRC_FASTEST_OPTIONS); |
| 3810 | 3737 | sh2drc_set_options(machine().device("sub"), SH2DRC_FASTEST_OPTIONS); |
| 3811 | 3738 | } |