src/mame/drivers/megadriv.c
| r9365 | r9366 | |
| 327 | 327 | #define SH2_CINT_IRQ_LEVEL 8 |
| 328 | 328 | #define SH2_PINT_IRQ_LEVEL 6 |
| 329 | 329 | |
| 330 | // Fifa96 needs the CPUs swapped for the gameplay to enter due to some race conditions |
| 331 | // when using the DRC core. Needs further investigation, the non-DRC core works either |
| 332 | // way |
| 333 | #define _32X_SWAP_MASTER_SLAVE_HACK |
| 330 | 334 | |
| 331 | 335 | static UINT16* _32x_dram0; |
| 332 | 336 | static UINT16* _32x_dram1; |
| r9365 | r9366 | |
| 336 | 340 | /* SegaCD! */ |
| 337 | 341 | static cpu_device *_segacd_68k_cpu; |
| 338 | 342 | static emu_timer *segacd_gfx_conversion_timer; |
| 343 | static int segacd_wordram_mapped = 0; |
| 339 | 344 | |
| 340 | 345 | /* SVP (virtua racing) */ |
| 341 | 346 | static cpu_device *_svp_cpu; |
| r9365 | r9366 | |
| 864 | 869 | { |
| 865 | 870 | source -= 2; // the SVP introduces some kind of DMA 'lag', which we have to compensate for, this is obvious even on gfx DMAd from ROM (the Speedometer) |
| 866 | 871 | } |
| 872 | |
| 873 | // likewise segaCD, at least when reading wordram? |
| 874 | // we might need to check what mode we're in here.. |
| 875 | if (segacd_wordram_mapped) |
| 876 | { |
| 877 | source -= 2; |
| 878 | } |
| 867 | 879 | |
| 868 | 880 | return space68k->read_word(source); |
| 869 | 881 | } |
| r9365 | r9366 | |
| 3836 | 3848 | static UINT16* segacd_4meg_prgram; // pointer to SubCPU PrgRAM |
| 3837 | 3849 | static UINT16 segacd_hint_register; |
| 3838 | 3850 | static UINT16 segacd_imagebuffer_vdot_size; |
| 3851 | static UINT16 segacd_imagebuffer_vcell_size; |
| 3852 | static UINT16 segacd_imagebuffer_hdot_size; |
| 3839 | 3853 | |
| 3840 | 3854 | static UINT16 a12000_halt_reset_reg = 0x0000; |
| 3841 | 3855 | int segacd_conversion_active = 0; |
| r9365 | r9366 | |
| 3918 | 3932 | |
| 3919 | 3933 | static WRITE16_HANDLER( scd_a12002_memory_mode_w ) |
| 3920 | 3934 | { |
| 3921 | | printf("scd_a12002_memory_mode_w %04x %04x\n", data, mem_mask); |
| 3935 | //printf("scd_a12002_memory_mode_w %04x %04x\n", data, mem_mask); |
| 3922 | 3936 | |
| 3923 | 3937 | if (ACCESSING_BITS_0_7) |
| 3924 | 3938 | { |
| 3925 | 3939 | |
| 3926 | | if (data&0x0001) printf("ret bit set (invalid? can't set from main68k?)\n"); |
| 3940 | //if (data&0x0001) printf("ret bit set (invalid? can't set from main68k?)\n"); |
| 3927 | 3941 | if (data&0x0002) |
| 3928 | 3942 | { |
| 3929 | | printf("dmn set (swap requested)\n"); // give ram to sub? |
| 3943 | //printf("dmn set (swap requested)\n"); // give ram to sub? |
| 3930 | 3944 | |
| 3931 | 3945 | // this should take some time? |
| 3932 | 3946 | segacd_maincpu_has_ram_access = 0; |
| 3933 | 3947 | } |
| 3934 | 3948 | |
| 3935 | 3949 | |
| 3936 | | if (data&0x0004) printf("mode set (invalid? can't set from main68k?)\n"); |
| 3937 | | if (data&0x0038) printf("unknown bits set\n"); |
| 3950 | //if (data&0x0004) printf("mode set (invalid? can't set from main68k?)\n"); |
| 3951 | //if (data&0x0038) printf("unknown bits set\n"); |
| 3938 | 3952 | |
| 3939 | 3953 | //if (data&0x00c0) |
| 3940 | 3954 | { |
| 3941 | | printf("bank set to %02x\n", (data&0x00c0)>>6); |
| 3955 | //printf("bank set to %02x\n", (data&0x00c0)>>6); |
| 3942 | 3956 | segacd_4meg_prgbank = (data&0x00c0)>>6; |
| 3943 | 3957 | |
| 3944 | 3958 | } |
| r9365 | r9366 | |
| 3970 | 3984 | |
| 3971 | 3985 | static WRITE16_HANDLER( segacd_sub_memory_mode_w ) |
| 3972 | 3986 | { |
| 3973 | | printf("segacd_sub_memory_mode_w %04x %04x\n", data, mem_mask); |
| 3987 | //printf("segacd_sub_memory_mode_w %04x %04x\n", data, mem_mask); |
| 3974 | 3988 | |
| 3975 | 3989 | if (ACCESSING_BITS_0_7) |
| 3976 | 3990 | { |
| 3977 | 3991 | if (data&0x0001) |
| 3978 | 3992 | { |
| 3979 | | printf("ret bit set\n"); |
| 3993 | //printf("ret bit set\n"); |
| 3980 | 3994 | segacd_maincpu_has_ram_access = 1; |
| 3981 | 3995 | } |
| 3982 | 3996 | |
| 3983 | 3997 | |
| 3984 | | if (data&0x0002) printf("dmn set (swap requested) (invalid, can't be set from sub68k?\n"); |
| 3998 | //if (data&0x0002) printf("dmn set (swap requested) (invalid, can't be set from sub68k?\n"); |
| 3985 | 3999 | |
| 3986 | 4000 | //if (data&0x0004) |
| 3987 | 4001 | { |
| 3988 | 4002 | segacd_ram_mode = (data&0x0004)>>2; |
| 3989 | | printf("mode set %d\n", segacd_ram_mode); |
| 4003 | //printf("mode set %d\n", segacd_ram_mode); |
| 3990 | 4004 | } |
| 3991 | 4005 | |
| 3992 | 4006 | //if (data&0x0018) |
| 3993 | 4007 | { |
| 3994 | 4008 | |
| 3995 | 4009 | segacd_memory_priority_mode = (data&0x0018)>>3; |
| 3996 | | printf("priority mode bits set to %d\n", segacd_memory_priority_mode); |
| 4010 | //printf("priority mode bits set to %d\n", segacd_memory_priority_mode); |
| 3997 | 4011 | |
| 3998 | 4012 | } |
| 3999 | 4013 | |
| 4000 | | if (data&0x00e0) printf("unknown bits set\n"); |
| 4014 | //if (data&0x00e0) printf("unknown bits set\n"); |
| 4001 | 4015 | } |
| 4002 | 4016 | |
| 4003 | 4017 | if (ACCESSING_BITS_8_15) |
| r9365 | r9366 | |
| 4629 | 4643 | memory_install_read_bank(space, 0x0020000, 0x003ffff, 0, 0, "scd_4m_prgbank"); |
| 4630 | 4644 | memory_set_bankptr(space->machine, "scd_4m_prgbank", segacd_4meg_prgram + segacd_4meg_prgbank * 0x20000 ); |
| 4631 | 4645 | memory_install_write16_handler (space, 0x0020000, 0x003ffff, 0, 0, scd_4m_prgbank_ram_w ); |
| 4646 | segacd_wordram_mapped = 1; |
| 4647 | |
| 4632 | 4648 | |
| 4633 | 4649 | memory_install_readwrite16_handler(cputag_get_address_space(space->machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0x200000, 0x23ffff, 0, 0, segacd_main_dataram_part1_r, segacd_main_dataram_part1_w); // RAM shared with sub |
| 4634 | 4650 | |
| r9365 | r9366 | |
| 5096 | 5112 | segacd_mark_stampmaps_dirty(); |
| 5097 | 5113 | |
| 5098 | 5114 | segacd_conversion_active = 1; |
| 5099 | | timer_adjust_oneshot(segacd_gfx_conversion_timer, ATTOTIME_IN_HZ(1), 0); |
| 5115 | |
| 5116 | // todo: proper time calculation |
| 5117 | timer_adjust_oneshot(segacd_gfx_conversion_timer, ATTOTIME_IN_HZ(1000), 0); |
| 5100 | 5118 | |
| 5101 | 5119 | |
| 5102 | 5120 | int i; |
| r9365 | r9366 | |
| 5124 | 5142 | x = BITMAP_ADDR16(srcbitmap,10,10); |
| 5125 | 5143 | UINT16 datax; |
| 5126 | 5144 | datax = x[0]; |
| 5127 | | |
| 5128 | | for (int i=0;i<0x100;i++) |
| 5145 | |
| 5146 | // I don't quite understand what happens if the lower bits of hdotsize are set.. do we end up rounding up? |
| 5147 | // this 'buffersize' clearly fills the frame for the SegaCD logo screen at least |
| 5148 | int buffersize = ((segacd_imagebuffer_vcell_size+1) * (segacd_imagebuffer_hdot_size>>3)*0x20)/2; // 0x20 = 8x8x4 tile, /2 due to word offset |
| 5149 | //buffersize -= 8; |
| 5150 | |
| 5151 | for (int i=0;i< buffersize ;i++) |
| 5129 | 5152 | { |
| 5130 | 5153 | int offsetx = ((segacd_imagebuffer_start_address&0xfff8)*2)+i; |
| 5131 | 5154 | |
| r9365 | r9366 | |
| 5199 | 5222 | printf("segacd_imagebuffer_offset_w %04x\n", segacd_imagebuffer_offset); |
| 5200 | 5223 | } |
| 5201 | 5224 | |
| 5225 | static READ16_HANDLER( segacd_imagebuffer_vcell_size_r ) |
| 5226 | { |
| 5227 | return segacd_imagebuffer_vcell_size; |
| 5228 | } |
| 5202 | 5229 | |
| 5230 | static WRITE16_HANDLER( segacd_imagebuffer_vcell_size_w ) |
| 5231 | { |
| 5232 | COMBINE_DATA(&segacd_imagebuffer_vcell_size); |
| 5233 | } |
| 5234 | |
| 5235 | |
| 5236 | static READ16_HANDLER( segacd_imagebuffer_hdot_size_r ) |
| 5237 | { |
| 5238 | return segacd_imagebuffer_hdot_size; |
| 5239 | } |
| 5240 | |
| 5241 | static WRITE16_HANDLER( segacd_imagebuffer_hdot_size_w ) |
| 5242 | { |
| 5243 | COMBINE_DATA(&segacd_imagebuffer_hdot_size); |
| 5244 | } |
| 5245 | |
| 5246 | |
| 5247 | |
| 5203 | 5248 | static ADDRESS_MAP_START( segacd_map, ADDRESS_SPACE_PROGRAM, 16 ) |
| 5204 | 5249 | AM_RANGE(0x000000, 0x07ffff) AM_RAM AM_BASE(&segacd_4meg_prgram) |
| 5205 | 5250 | |
| r9365 | r9366 | |
| 5231 | 5276 | // AM_RANGE(0xff8050, 0xff8057) // Font data (read only) |
| 5232 | 5277 | AM_RANGE(0xff8058, 0xff8059) AM_READWRITE(segacd_stampsize_r, segacd_stampsize_w) // Stamp size |
| 5233 | 5278 | AM_RANGE(0xff805a, 0xff805b) AM_READWRITE(segacd_stampmap_base_address_r, segacd_stampmap_base_address_w) // Stamp map base address |
| 5234 | | // AM_RANGE(0xff805c, 0xff805d) // Image buffer V cell size |
| 5279 | AM_RANGE(0xff805c, 0xff805d) AM_READWRITE(segacd_imagebuffer_vcell_size_r, segacd_imagebuffer_vcell_size_w)// Image buffer V cell size |
| 5235 | 5280 | AM_RANGE(0xff805e, 0xff805f) AM_READWRITE(segacd_imagebuffer_start_address_r, segacd_imagebuffer_start_address_w) // Image buffer start address |
| 5236 | 5281 | AM_RANGE(0xff8060, 0xff8061) AM_READWRITE(segacd_imagebuffer_offset_r, segacd_imagebuffer_offset_w) |
| 5237 | | // AM_RANGE(0xff8062, 0xff8063) // Image buffer H dot size |
| 5282 | AM_RANGE(0xff8062, 0xff8063) AM_READWRITE(segacd_imagebuffer_hdot_size_r, segacd_imagebuffer_hdot_size_w) // Image buffer H dot size |
| 5238 | 5283 | AM_RANGE(0xff8064, 0xff8065) AM_READWRITE(segacd_imagebuffer_vdot_size_r, segacd_imagebuffer_vdot_size_w ) // Image buffer V dot size |
| 5239 | 5284 | AM_RANGE(0xff8066, 0xff8067) AM_WRITE(segacd_trace_vector_base_address_w)// Trace vector base address |
| 5240 | 5285 | // AM_RANGE(0xff8068, 0xff8069) // Subcode address |
| r9365 | r9366 | |
| 8074 | 8119 | |
| 8075 | 8120 | MACHINE_CONFIG_DERIVED( genesis_32x, megadriv ) |
| 8076 | 8121 | |
| 8122 | #ifndef _32X_SWAP_MASTER_SLAVE_HACK |
| 8077 | 8123 | MDRV_CPU_ADD("32x_master_sh2", SH2, (MASTER_CLOCK_NTSC*3)/7 ) |
| 8078 | 8124 | MDRV_CPU_PROGRAM_MAP(sh2_main_map) |
| 8079 | 8125 | MDRV_CPU_CONFIG(sh2_conf_master) |
| 8126 | #endif |
| 8080 | 8127 | |
| 8081 | 8128 | MDRV_CPU_ADD("32x_slave_sh2", SH2, (MASTER_CLOCK_NTSC*3)/7 ) |
| 8082 | 8129 | MDRV_CPU_PROGRAM_MAP(sh2_slave_map) |
| 8083 | 8130 | MDRV_CPU_CONFIG(sh2_conf_slave) |
| 8084 | 8131 | |
| 8132 | #ifdef _32X_SWAP_MASTER_SLAVE_HACK |
| 8133 | MDRV_CPU_ADD("32x_master_sh2", SH2, (MASTER_CLOCK_NTSC*3)/7 ) |
| 8134 | MDRV_CPU_PROGRAM_MAP(sh2_main_map) |
| 8135 | MDRV_CPU_CONFIG(sh2_conf_master) |
| 8136 | #endif |
| 8137 | |
| 8085 | 8138 | // brutal needs at least 30000 or the backgrounds don't animate properly / lock up, and the game |
| 8086 | 8139 | // freezes. Some stage seem to need as high as 80000 ? this *KILLS* performance |
| 8087 | 8140 | // |
| r9365 | r9366 | |
| 8114 | 8167 | |
| 8115 | 8168 | MACHINE_CONFIG_DERIVED( genesis_32x_pal, megadpal ) |
| 8116 | 8169 | |
| 8170 | #ifndef _32X_SWAP_MASTER_SLAVE_HACK |
| 8117 | 8171 | MDRV_CPU_ADD("32x_master_sh2", SH2, (MASTER_CLOCK_PAL*3)/7 ) |
| 8118 | 8172 | MDRV_CPU_PROGRAM_MAP(sh2_main_map) |
| 8119 | 8173 | MDRV_CPU_CONFIG(sh2_conf_master) |
| 8174 | #endif |
| 8120 | 8175 | |
| 8121 | 8176 | MDRV_CPU_ADD("32x_slave_sh2", SH2, (MASTER_CLOCK_PAL*3)/7 ) |
| 8122 | 8177 | MDRV_CPU_PROGRAM_MAP(sh2_slave_map) |
| 8123 | 8178 | MDRV_CPU_CONFIG(sh2_conf_slave) |
| 8124 | 8179 | |
| 8180 | #ifdef _32X_SWAP_MASTER_SLAVE_HACK |
| 8181 | MDRV_CPU_ADD("32x_master_sh2", SH2, (MASTER_CLOCK_PAL*3)/7 ) |
| 8182 | MDRV_CPU_PROGRAM_MAP(sh2_main_map) |
| 8183 | MDRV_CPU_CONFIG(sh2_conf_master) |
| 8184 | #endif |
| 8185 | |
| 8125 | 8186 | // brutal needs at least 30000 or the backgrounds don't animate properly / lock up, and the game |
| 8126 | 8187 | // freezes. Some stage seem to need as high as 80000 ? this *KILLS* performance |
| 8127 | 8188 | // |
| r9365 | r9366 | |
| 8244 | 8305 | } |
| 8245 | 8306 | |
| 8246 | 8307 | sega_cd_connected = 0; |
| 8308 | segacd_wordram_mapped = 0; |
| 8247 | 8309 | _segacd_68k_cpu = machine->device<cpu_device>("segacd_68k"); |
| 8248 | 8310 | if (_segacd_68k_cpu != NULL) |
| 8249 | 8311 | { |