src/mame/drivers/megadriv.c
| r9361 | r9362 | |
| 259 | 259 | |
| 260 | 260 | |
| 261 | 261 | #include "emu.h" |
| 262 | #include "coreutil.h" |
| 262 | 263 | #include "cpu/z80/z80.h" |
| 263 | 264 | #include "sound/sn76496.h" |
| 264 | 265 | #include "sound/2612intf.h" |
| r9361 | r9362 | |
| 269 | 270 | #include "includes/megadriv.h" |
| 270 | 271 | #include "cpu/sh2/sh2.h" |
| 271 | 272 | #include "cpu/sh2/sh2comn.h" |
| 273 | #include "devices/chd_cd.h" |
| 274 | #include "sound/cdda.h" |
| 272 | 275 | |
| 273 | 276 | #define MEGADRIV_VDP_VRAM(address) megadrive_vdp_vram[(address)&0x7fff] |
| 274 | 277 | |
| r9361 | r9362 | |
| 388 | 391 | UINT8 ext; |
| 389 | 392 | UINT8 ctrl; |
| 390 | 393 | }segacd_cdd; |
| 394 | static struct |
| 395 | { |
| 396 | UINT32 current_frame; |
| 397 | UINT32 end_frame; |
| 398 | UINT32 last_frame; |
| 399 | |
| 400 | cdrom_file *cd; |
| 401 | const cdrom_toc* toc; |
| 402 | }segacd; |
| 403 | |
| 391 | 404 | static void segacd_mark_tiles_dirty(running_machine* machine, int offset); |
| 392 | 405 | |
| 393 | 406 | #ifdef UNUSED_FUNCTION |
| r9361 | r9362 | |
| 4238 | 4251 | //printf("segacd_main_dataram_part1_r in mode 0 %08x %04x\n", offset*2, segacd_dataram[offset]); |
| 4239 | 4252 | |
| 4240 | 4253 | return segacd_dataram[offset]; |
| 4241 | | |
| 4254 | |
| 4242 | 4255 | } |
| 4243 | 4256 | else |
| 4244 | 4257 | { |
| r9361 | r9362 | |
| 4312 | 4325 | |
| 4313 | 4326 | if (segacd_irq_mask & 0x02) |
| 4314 | 4327 | cputag_set_input_line(machine, "segacd_68k", 1, HOLD_LINE); |
| 4315 | | |
| 4328 | |
| 4316 | 4329 | segacd_conversion_active = 0; |
| 4317 | 4330 | } |
| 4318 | 4331 | |
| r9361 | r9362 | |
| 4685 | 4698 | } |
| 4686 | 4699 | |
| 4687 | 4700 | segacd_cdd_rx[9] = 0xf; // default checksum |
| 4701 | |
| 4702 | /* init cd-rom device */ |
| 4703 | |
| 4704 | { |
| 4705 | running_device *device; |
| 4706 | |
| 4707 | device = machine->device("cdrom"); |
| 4708 | if ( device ) |
| 4709 | { |
| 4710 | segacd.cd = mess_cd_get_cdrom_file(device); |
| 4711 | if ( segacd.cd ) |
| 4712 | { |
| 4713 | segacd.toc = cdrom_get_toc( segacd.cd ); |
| 4714 | cdda_set_cdrom( machine->device("cdda"), segacd.cd ); |
| 4715 | segacd.last_frame = cdrom_get_track_start( segacd.cd, cdrom_get_last_track( segacd.cd ) - 1 ); |
| 4716 | segacd.last_frame += segacd.toc->tracks[ cdrom_get_last_track( segacd.cd ) - 1 ].frames; |
| 4717 | segacd.end_frame = segacd.last_frame; |
| 4718 | } |
| 4719 | } |
| 4720 | } |
| 4688 | 4721 | } |
| 4689 | 4722 | |
| 4690 | 4723 | |
| r9361 | r9362 | |
| 4906 | 4939 | { |
| 4907 | 4940 | // ... |
| 4908 | 4941 | |
| 4942 | /*segacd_cdd.status = 0; |
| 4943 | segacd_cdd.minute = 0; |
| 4944 | segacd_cdd.seconds = 0; |
| 4945 | segacd_cdd.frame = 0; |
| 4946 | segacd_cdd.ext = 0;*/ |
| 4947 | |
| 4909 | 4948 | cdd_hock_irq(machine,1); |
| 4910 | 4949 | } |
| 4911 | 4950 | |
| 4912 | 4951 | static void segacd_cdd_stop_all(running_machine *machine) |
| 4913 | 4952 | { |
| 4914 | | // ... |
| 4915 | | segacd_cdd.ctrl |= 0x100; // set data bit |
| 4953 | segacd_cdd.ctrl |= 0x100; |
| 4916 | 4954 | |
| 4955 | segacd_cdd.status = 0; |
| 4956 | segacd_cdd.minute = 0; |
| 4957 | segacd_cdd.seconds = 0; |
| 4958 | segacd_cdd.frame = 0; |
| 4959 | segacd_cdd.ext = 0; |
| 4960 | |
| 4917 | 4961 | //cdd_hock_irq(machine,1); // doesn't work? |
| 4918 | 4962 | } |
| 4919 | 4963 | |
| 4920 | 4964 | |
| 4921 | 4965 | static void segacd_cdd_get_toc_info(running_machine *machine) |
| 4922 | 4966 | { |
| 4923 | | segacd_cdd.status = ((segacd_cdd_tx[3] & 0xf) << 4) | (segacd_cdd.status & 0xf); |
| 4967 | segacd_cdd.status = (segacd_cdd_tx[3] & 0xf) | (segacd_cdd.status & 0xf0); |
| 4924 | 4968 | |
| 4969 | logerror("CDD: TOC command %s issued\n",segacd_cdd_get_toc_cmd[segacd_cdd_tx[3] & 0xf]); |
| 4970 | |
| 4925 | 4971 | switch(segacd_cdd_tx[3] & 0xf) |
| 4926 | 4972 | { |
| 4927 | | default: printf("CDD: unhandled TOC command %s issued\n",segacd_cdd_get_toc_cmd[segacd_cdd_tx[3] & 0xf]); |
| 4973 | case 0x3: //Get Total Length (in MSF) |
| 4974 | if ( ! segacd.cd ) // no cd is present |
| 4975 | { |
| 4976 | segacd_cdd.status = (0) | (segacd_cdd.status & 0xf0); |
| 4977 | segacd_cdd.minute = 0; |
| 4978 | segacd_cdd.seconds = 0; |
| 4979 | segacd_cdd.frame = 0; |
| 4980 | } |
| 4981 | else |
| 4982 | { |
| 4983 | UINT32 frame,msf; |
| 4984 | |
| 4985 | frame = segacd.toc->tracks[segacd.toc->numtrks-1].physframeofs; |
| 4986 | frame += segacd.toc->tracks[segacd.toc->numtrks-1].frames; |
| 4987 | msf = lba_to_msf( frame ); |
| 4988 | |
| 4989 | segacd_cdd.status = (0x3 & 0xf) | (segacd_cdd.status & 0xf0); |
| 4990 | segacd_cdd.minute = ((msf >> 16) & 0xff); |
| 4991 | segacd_cdd.seconds = ((msf >> 8) & 0xff); |
| 4992 | segacd_cdd.frame = ((msf >> 0) & 0xff); |
| 4993 | } |
| 4994 | segacd_cdd.ext = 0; |
| 4995 | cdd_hock_irq(machine,1); |
| 4996 | return; |
| 4997 | case 0x4: //Get First and Last Track Number |
| 4998 | if ( ! segacd.cd ) // no cd is present |
| 4999 | { |
| 5000 | segacd_cdd.status = (0) | (segacd_cdd.status & 0xf0); |
| 5001 | segacd_cdd.minute = 0; |
| 5002 | segacd_cdd.seconds = 0; |
| 5003 | } |
| 5004 | else |
| 5005 | { |
| 5006 | segacd_cdd.status = (0x4 & 0xf) | (segacd_cdd.status & 0xf0); |
| 5007 | segacd_cdd.minute = dec_2_bcd(1); |
| 5008 | segacd_cdd.seconds = dec_2_bcd(segacd.toc->numtrks); |
| 5009 | } |
| 5010 | segacd_cdd.frame = 0; |
| 5011 | segacd_cdd.ext = 0; |
| 5012 | cdd_hock_irq(machine,1); |
| 5013 | return; |
| 5014 | //default: logerror("CDD: unhandled TOC command %s issued\n",segacd_cdd_get_toc_cmd[segacd_cdd_tx[3] & 0xf]); |
| 4928 | 5015 | } |
| 4929 | 5016 | |
| 4930 | 5017 | cdd_hock_irq(machine,1); |
| r9361 | r9362 | |
| 4937 | 5024 | |
| 4938 | 5025 | if(offset == 9) //execute the command when crc is sent (TODO: I wonder if we need to check if crc is valid. Plus obviously this shouldn't be instant) |
| 4939 | 5026 | { |
| 5027 | logerror("CDD: command %s issued\n",segacd_cdd_cmd[segacd_cdd_tx[0] & 0xf]); |
| 5028 | |
| 4940 | 5029 | switch(segacd_cdd_tx[0] & 0xf) |
| 4941 | 5030 | { |
| 4942 | 5031 | case 0x0: segacd_cdd_get_status(space->machine); break; |
| 4943 | 5032 | case 0x1: segacd_cdd_stop_all(space->machine); break; |
| 4944 | 5033 | case 0x2: segacd_cdd_get_toc_info(space->machine); break; |
| 4945 | | default: printf("CDD: unhandled command %s issued\n",segacd_cdd_cmd[segacd_cdd_tx[0] & 0xf]); |
| 5034 | //default: logerror("CDD: unhandled command %s issued\n",segacd_cdd_cmd[segacd_cdd_tx[0] & 0xf]); |
| 4946 | 5035 | } |
| 4947 | 5036 | } |
| 4948 | 5037 | } |
| r9361 | r9362 | |
| 4981 | 5070 | |
| 4982 | 5071 | |
| 4983 | 5072 | } |
| 4984 | | |
| 5073 | |
| 4985 | 5074 | if (ACCESSING_BITS_8_15) |
| 4986 | 5075 | { |
| 4987 | 5076 | if (data&0xff00) printf(" unused bits (MSB) set in stampsize!\n"); |
| r9361 | r9362 | |
| 4997 | 5086 | } |
| 4998 | 5087 | |
| 4999 | 5088 | logerror("segacd_trace_vector_base_address_w %04x %04x\n",data,mem_mask); |
| 5000 | | |
| 5089 | |
| 5001 | 5090 | { |
| 5002 | 5091 | int base = (data & 0xfffe) * 4; |
| 5003 | 5092 | |
| r9361 | r9362 | |
| 5008 | 5097 | |
| 5009 | 5098 | segacd_conversion_active = 1; |
| 5010 | 5099 | timer_adjust_oneshot(segacd_gfx_conversion_timer, ATTOTIME_IN_HZ(1), 0); |
| 5011 | | |
| 5012 | 5100 | |
| 5101 | |
| 5013 | 5102 | int i; |
| 5014 | 5103 | |
| 5015 | 5104 | for (i=0;i<segacd_imagebuffer_vdot_size;i++) |
| r9361 | r9362 | |
| 5021 | 5110 | UINT16 param4 = segacd_dataram[(currbase+0x6)>>1]; |
| 5022 | 5111 | |
| 5023 | 5112 | |
| 5024 | | logerror("%06x: %04x %04x %04x %04x\n", currbase, param1, param2, param3, param4); |
| 5113 | logerror("%06x: %04x %04x %04x %04x\n", currbase, param1, param2, param3, param4); |
| 5025 | 5114 | |
| 5026 | 5115 | } |
| 5027 | | |
| 5116 | |
| 5028 | 5117 | { |
| 5029 | 5118 | // not real code.. yet |
| 5030 | 5119 | // should copy part of the stamp into the imagebuffer area using the rotation / zooming parameters given |
| r9361 | r9362 | |
| 5034 | 5123 | UINT16* x; |
| 5035 | 5124 | x = BITMAP_ADDR16(srcbitmap,10,10); |
| 5036 | 5125 | UINT16 datax; |
| 5037 | | datax = x[0]; |
| 5038 | | |
| 5126 | datax = x[0]; |
| 5127 | |
| 5039 | 5128 | for (int i=0;i<0x100;i++) |
| 5040 | 5129 | { |
| 5041 | 5130 | int offsetx = ((segacd_imagebuffer_start_address&0xfff8)*2)+i; |
| r9361 | r9362 | |
| 8068 | 8157 | |
| 8069 | 8158 | MDRV_CPU_ADD("segacd_68k", M68000, SEGACD_CLOCK ) /* 12.5 MHz */ |
| 8070 | 8159 | MDRV_CPU_PROGRAM_MAP(segacd_map) |
| 8160 | |
| 8161 | MDRV_SOUND_ADD( "cdda", CDDA, 0 ) |
| 8162 | MDRV_SOUND_ROUTE( 0, "lspeaker", 1.00 ) |
| 8163 | MDRV_SOUND_ROUTE( 1, "rspeaker", 1.00 ) |
| 8164 | |
| 8165 | MDRV_CDROM_ADD( "cdrom" ) |
| 8071 | 8166 | MACHINE_CONFIG_END |
| 8072 | 8167 | |
| 8073 | 8168 | MACHINE_CONFIG_DERIVED( genesis_32x_scd, genesis_32x ) |
| 8074 | 8169 | |
| 8075 | 8170 | MDRV_CPU_ADD("segacd_68k", M68000, SEGACD_CLOCK ) /* 12.5 MHz */ |
| 8076 | 8171 | MDRV_CPU_PROGRAM_MAP(segacd_map) |
| 8172 | |
| 8173 | MDRV_SOUND_ADD( "cdda", CDDA, 0 ) |
| 8174 | MDRV_SOUND_ROUTE( 0, "lspeaker", 1.00 ) |
| 8175 | MDRV_SOUND_ROUTE( 1, "rspeaker", 1.00 ) |
| 8176 | |
| 8177 | MDRV_CDROM_ADD( "cdrom" ) |
| 8077 | 8178 | MACHINE_CONFIG_END |
| 8078 | 8179 | |
| 8079 | 8180 | |
| r9361 | r9362 | |
| 8149 | 8250 | printf("Sega CD secondary 68k cpu found '%s'\n", _segacd_68k_cpu->tag() ); |
| 8150 | 8251 | sega_cd_connected = 1; |
| 8151 | 8252 | segacd_init_main_cpu(machine); |
| 8152 | | |
| 8153 | 8253 | } |
| 8154 | 8254 | |
| 8155 | 8255 | _svp_cpu = machine->device<cpu_device>("svp"); |