trunk/src/mame/machine/megadriv.c
r17951 | r17952 | |
37 | 37 | #include "cpu/sh2/sh2comn.h" |
38 | 38 | #include "cpu/z80/z80.h" |
39 | 39 | #include "sound/2612intf.h" |
40 | | #include "sound/cdda.h" |
| 40 | |
41 | 41 | #include "sound/dac.h" |
42 | | #include "sound/rf5c68.h" |
| 42 | |
43 | 43 | #include "sound/sn76496.h" |
44 | 44 | #include "imagedev/chd_cd.h" |
45 | 45 | #include "includes/megadriv.h" |
46 | 46 | #include "machine/nvram.h" |
47 | 47 | #include "cpu/ssp1601/ssp1601.h" |
48 | | #include "megacd.lh" |
49 | 48 | |
50 | 49 | #include "machine/megavdp.h" |
51 | 50 | |
r17951 | r17952 | |
1302 | 1301 | |
1303 | 1302 | |
1304 | 1303 | MACHINE_CONFIG_DERIVED( genesis_scd, megadriv ) |
1305 | | MCFG_NVRAM_HANDLER_CLEAR() |
1306 | | MCFG_CPU_ADD("segacd_68k", M68000, SEGACD_CLOCK ) /* 12.5 MHz */ |
1307 | | MCFG_CPU_PROGRAM_MAP(segacd_map) |
1308 | | |
1309 | | MCFG_TIMER_ADD("sw_timer", NULL) //stopwatch timer |
1310 | | |
1311 | | MCFG_DEFAULT_LAYOUT( layout_megacd ) |
1312 | | |
1313 | | MCFG_NVRAM_ADD_0FILL("backupram") |
1314 | | |
1315 | | MCFG_SOUND_ADD( "cdda", CDDA, 0 ) |
1316 | | MCFG_SOUND_ROUTE( 0, "lspeaker", 0.50 ) // TODO: accurate volume balance |
1317 | | MCFG_SOUND_ROUTE( 1, "rspeaker", 0.50 ) |
1318 | | |
1319 | | MCFG_SOUND_ADD("rfsnd", RF5C68, SEGACD_CLOCK) // RF5C164! |
1320 | | MCFG_SOUND_ROUTE( 0, "lspeaker", 0.50 ) |
1321 | | MCFG_SOUND_ROUTE( 1, "rspeaker", 0.50 ) |
1322 | | |
1323 | | MCFG_TIMER_ADD("scd_dma_timer", scd_dma_timer_callback) |
1324 | | |
1325 | | MCFG_QUANTUM_PERFECT_CPU("segacd_68k") // perfect sync to the fastest cpu |
| 1304 | MCFG_DEVICE_ADD("segacd", SEGA_SEGACD_US, 0) |
1326 | 1305 | MACHINE_CONFIG_END |
1327 | 1306 | |
1328 | 1307 | struct cdrom_interface scd_cdrom = |
r17951 | r17952 | |
1349 | 1328 | |
1350 | 1329 | MACHINE_CONFIG_DERIVED( genesis_32x_scd, genesis_32x ) |
1351 | 1330 | |
1352 | | MCFG_CPU_ADD("segacd_68k", M68000, SEGACD_CLOCK ) /* 12.5 MHz */ |
1353 | | MCFG_CPU_PROGRAM_MAP(segacd_map) |
1354 | | |
1355 | | MCFG_TIMER_ADD("sw_timer", NULL) //stopwatch timer |
1356 | | MCFG_NVRAM_ADD_0FILL("backupram") |
1357 | | MCFG_TIMER_ADD("scd_dma_timer", scd_dma_timer_callback) |
1358 | | |
1359 | | MCFG_DEFAULT_LAYOUT( layout_megacd ) |
1360 | | |
1361 | | MCFG_SOUND_ADD( "cdda", CDDA, 0 ) |
1362 | | MCFG_SOUND_ROUTE( 0, "lspeaker", 0.50 ) |
1363 | | MCFG_SOUND_ROUTE( 1, "rspeaker", 0.50 ) |
1364 | | |
1365 | | MCFG_SOUND_ADD("rfsnd", RF5C68, SEGACD_CLOCK) // RF5C164 |
1366 | | MCFG_SOUND_ROUTE( 0, "lspeaker", 0.25 ) |
1367 | | MCFG_SOUND_ROUTE( 1, "rspeaker", 0.25 ) |
1368 | | |
1369 | | MCFG_CDROM_ADD( "cdrom", scd_cdrom) |
1370 | | MCFG_SOFTWARE_LIST_ADD("cd_list","segacd") |
1371 | | |
| 1331 | MCFG_DEVICE_ADD("segacd", SEGA_SEGACD_US, 0) |
1372 | 1332 | //MCFG_QUANTUM_PERFECT_CPU("32x_master_sh2") |
1373 | 1333 | MACHINE_CONFIG_END |
1374 | 1334 | |
r17951 | r17952 | |
1410 | 1370 | |
1411 | 1371 | sega_cd_connected = 0; |
1412 | 1372 | segacd_wordram_mapped = 0; |
1413 | | _segacd_68k_cpu = machine.device<cpu_device>("segacd_68k"); |
| 1373 | _segacd_68k_cpu = machine.device<cpu_device>(":segacd:segacd_68k"); |
1414 | 1374 | if (_segacd_68k_cpu != NULL) |
1415 | 1375 | { |
1416 | 1376 | printf("Sega CD secondary 68k cpu found '%s'\n", _segacd_68k_cpu->tag() ); |
1417 | 1377 | sega_cd_connected = 1; |
1418 | 1378 | segacd_init_main_cpu(machine); |
1419 | | scd_dma_timer = machine.device<timer_device>("scd_dma_timer"); |
| 1379 | scd_dma_timer = machine.device<timer_device>(":segacd:scd_dma_timer"); |
1420 | 1380 | |
1421 | 1381 | } |
1422 | 1382 | |
trunk/src/mame/machine/megacd.c
r17951 | r17952 | |
1 | 1 | |
2 | 2 | #include "includes/megadriv.h" |
| 3 | #include "megacd.lh" |
| 4 | #include "sound/cdda.h" |
| 5 | #include "sound/rf5c68.h" |
3 | 6 | |
4 | 7 | // the main MD emulation needs to know the state of these because it appears in the MD regs / affect DMA operations |
5 | 8 | int sega_cd_connected = 0x00; |
6 | 9 | int segacd_wordram_mapped = 0; |
7 | 10 | |
8 | 11 | |
| 12 | |
| 13 | |
| 14 | |
| 15 | const device_type SEGA_SEGACD_US = &device_creator<sega_segacd_us_device>; |
| 16 | const device_type SEGA_SEGACD_JAPAN = &device_creator<sega_segacd_japan_device>; |
| 17 | const device_type SEGA_SEGACD_EUROPE = &device_creator<sega_segacd_europe_device>; |
| 18 | |
| 19 | sega_segacd_device::sega_segacd_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock, device_type type) |
| 20 | : device_t(mconfig, type, "sega_segacd_device", tag, owner, clock) |
| 21 | { |
| 22 | |
| 23 | } |
| 24 | |
| 25 | sega_segacd_us_device::sega_segacd_us_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 26 | : sega_segacd_device(mconfig, tag, owner, clock, SEGA_SEGACD_US) |
| 27 | { |
| 28 | |
| 29 | } |
| 30 | |
| 31 | sega_segacd_japan_device::sega_segacd_japan_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 32 | : sega_segacd_device(mconfig, tag, owner, clock, SEGA_SEGACD_JAPAN) |
| 33 | { |
| 34 | |
| 35 | } |
| 36 | |
| 37 | sega_segacd_europe_device::sega_segacd_europe_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 38 | : sega_segacd_device(mconfig, tag, owner, clock, SEGA_SEGACD_EUROPE) |
| 39 | { |
| 40 | |
| 41 | } |
| 42 | |
| 43 | |
| 44 | static MACHINE_CONFIG_FRAGMENT( segacd_fragment ) |
| 45 | |
| 46 | MCFG_CPU_ADD("segacd_68k", M68000, SEGACD_CLOCK ) /* 12.5 MHz */ |
| 47 | MCFG_CPU_PROGRAM_MAP(segacd_map) |
| 48 | |
| 49 | MCFG_TIMER_ADD("sw_timer", NULL) //stopwatch timer |
| 50 | |
| 51 | MCFG_DEFAULT_LAYOUT( layout_megacd ) |
| 52 | |
| 53 | MCFG_SOUND_ADD( "cdda", CDDA, 0 ) |
| 54 | MCFG_SOUND_ROUTE( 0, ":lspeaker", 0.50 ) // TODO: accurate volume balance |
| 55 | MCFG_SOUND_ROUTE( 1, ":rspeaker", 0.50 ) |
| 56 | |
| 57 | MCFG_SOUND_ADD("rfsnd", RF5C68, SEGACD_CLOCK) // RF5C164! |
| 58 | MCFG_SOUND_ROUTE( 0, ":lspeaker", 0.50 ) |
| 59 | MCFG_SOUND_ROUTE( 1, ":rspeaker", 0.50 ) |
| 60 | |
| 61 | MCFG_TIMER_ADD("scd_dma_timer", scd_dma_timer_callback) |
| 62 | |
| 63 | MCFG_NVRAM_HANDLER_CLEAR() |
| 64 | MCFG_NVRAM_ADD_0FILL("backupram") |
| 65 | |
| 66 | MCFG_QUANTUM_PERFECT_CPU("segacd_68k") // perfect sync to the fastest cpu |
| 67 | MACHINE_CONFIG_END |
| 68 | |
| 69 | |
| 70 | |
| 71 | machine_config_constructor sega_segacd_device::device_mconfig_additions() const |
| 72 | { |
| 73 | return MACHINE_CONFIG_NAME( segacd_fragment ); |
| 74 | } |
| 75 | |
| 76 | |
9 | 77 | /* Sega CD stuff */ |
10 | 78 | cpu_device *_segacd_68k_cpu; |
11 | 79 | |
r17951 | r17952 | |
153 | 221 | #define CHECK_SCD_LV5_INTERRUPT \ |
154 | 222 | if (segacd_irq_mask & 0x20) \ |
155 | 223 | { \ |
156 | | machine.device("segacd_68k")->execute().set_input_line(5, HOLD_LINE); \ |
| 224 | machine.device(":segacd:segacd_68k")->execute().set_input_line(5, HOLD_LINE); \ |
157 | 225 | } \ |
158 | 226 | |
159 | 227 | #define CHECK_SCD_LV4_INTERRUPT \ |
160 | 228 | if (segacd_irq_mask & 0x10) \ |
161 | 229 | { \ |
162 | | machine.device("segacd_68k")->execute().set_input_line(4, HOLD_LINE); \ |
| 230 | machine.device(":segacd:segacd_68k")->execute().set_input_line(4, HOLD_LINE); \ |
163 | 231 | } \ |
164 | 232 | |
165 | 233 | #define CHECK_SCD_LV3_INTERRUPT \ |
166 | 234 | if (segacd_irq_mask & 0x08) \ |
167 | 235 | { \ |
168 | | machine.device("segacd_68k")->execute().set_input_line(3, HOLD_LINE); \ |
| 236 | machine.device(":segacd:segacd_68k")->execute().set_input_line(3, HOLD_LINE); \ |
169 | 237 | } \ |
170 | 238 | |
171 | 239 | #define CHECK_SCD_LV2_INTERRUPT \ |
172 | 240 | if (segacd_irq_mask & 0x04) \ |
173 | 241 | { \ |
174 | | machine.device("segacd_68k")->execute().set_input_line(2, HOLD_LINE); \ |
| 242 | machine.device(":segacd:segacd_68k")->execute().set_input_line(2, HOLD_LINE); \ |
175 | 243 | } \ |
176 | 244 | |
177 | 245 | #define CHECK_SCD_LV1_INTERRUPT \ |
178 | 246 | if (segacd_irq_mask & 0x02) \ |
179 | 247 | { \ |
180 | | machine.device("segacd_68k")->execute().set_input_line(1, HOLD_LINE); \ |
| 248 | machine.device(":segacd:segacd_68k")->execute().set_input_line(1, HOLD_LINE); \ |
181 | 249 | } \ |
182 | 250 | |
183 | 251 | #define CURRENT_TRACK_IS_DATA \ |
r17951 | r17952 | |
542 | 610 | SCD_STATUS = CDD_STOPPED; |
543 | 611 | CDD_STATUS = 0x0000; |
544 | 612 | SET_CDD_DATA_MODE |
545 | | cdda_stop_audio( machine.device( "cdda" ) ); //stop any pending CD-DA |
| 613 | cdda_stop_audio( machine.device( ":segacd:cdda" ) ); //stop any pending CD-DA |
546 | 614 | } |
547 | 615 | |
548 | 616 | |
r17951 | r17952 | |
672 | 740 | printf("%d Track played\n",SCD_CURTRK); |
673 | 741 | CDD_MIN = to_bcd(SCD_CURTRK, false); |
674 | 742 | if(!(CURRENT_TRACK_IS_DATA)) |
675 | | cdda_start_audio( machine.device( "cdda" ), SCD_CURLBA, end_msf - SCD_CURLBA ); |
| 743 | cdda_start_audio( machine.device( ":segacd:cdda" ), SCD_CURLBA, end_msf - SCD_CURLBA ); |
676 | 744 | SET_CDC_READ |
677 | 745 | } |
678 | 746 | |
r17951 | r17952 | |
699 | 767 | CDD_STATUS = SCD_STATUS; |
700 | 768 | SET_CDD_DATA_MODE |
701 | 769 | |
702 | | //segacd.current_frame = cdda_get_audio_lba( machine.device( "cdda" ) ); |
| 770 | //segacd.current_frame = cdda_get_audio_lba( machine.device( ":segacd:cdda" ) ); |
703 | 771 | //if(!(CURRENT_TRACK_IS_DATA)) |
704 | | cdda_pause_audio( machine.device( "cdda" ), 1 ); |
| 772 | cdda_pause_audio( machine.device( ":segacd:cdda" ), 1 ); |
705 | 773 | } |
706 | 774 | |
707 | 775 | void CDD_Resume(running_machine &machine) |
r17951 | r17952 | |
715 | 783 | CDD_MIN = to_bcd (SCD_CURTRK, false); |
716 | 784 | SET_CDC_READ |
717 | 785 | //if(!(CURRENT_TRACK_IS_DATA)) |
718 | | cdda_pause_audio( machine.device( "cdda" ), 0 ); |
| 786 | cdda_pause_audio( machine.device( ":segacd:cdda" ), 0 ); |
719 | 787 | } |
720 | 788 | |
721 | 789 | |
r17951 | r17952 | |
816 | 884 | |
817 | 885 | void CDC_Do_DMA(running_machine& machine, int rate) |
818 | 886 | { |
819 | | address_space* space = machine.device("segacd_68k")->memory().space(AS_PROGRAM); |
| 887 | address_space* space = machine.device(":segacd:segacd_68k")->memory().space(AS_PROGRAM); |
820 | 888 | |
821 | 889 | UINT32 dstoffset, length; |
822 | 890 | UINT8 *dest; |
r17951 | r17952 | |
1174 | 1242 | // reset line |
1175 | 1243 | if (a12000_halt_reset_reg&0x0001) |
1176 | 1244 | { |
1177 | | space->machine().device("segacd_68k")->execute().set_input_line(INPUT_LINE_RESET, CLEAR_LINE); |
| 1245 | space->machine().device(":segacd:segacd_68k")->execute().set_input_line(INPUT_LINE_RESET, CLEAR_LINE); |
1178 | 1246 | if (!(old_halt&0x0001)) printf("clear reset slave\n"); |
1179 | 1247 | } |
1180 | 1248 | else |
1181 | 1249 | { |
1182 | | space->machine().device("segacd_68k")->execute().set_input_line(INPUT_LINE_RESET, ASSERT_LINE); |
| 1250 | space->machine().device(":segacd:segacd_68k")->execute().set_input_line(INPUT_LINE_RESET, ASSERT_LINE); |
1183 | 1251 | if ((old_halt&0x0001)) printf("assert reset slave\n"); |
1184 | 1252 | } |
1185 | 1253 | |
1186 | 1254 | // request BUS |
1187 | 1255 | if (a12000_halt_reset_reg&0x0002) |
1188 | 1256 | { |
1189 | | space->machine().device("segacd_68k")->execute().set_input_line(INPUT_LINE_HALT, ASSERT_LINE); |
| 1257 | space->machine().device(":segacd:segacd_68k")->execute().set_input_line(INPUT_LINE_HALT, ASSERT_LINE); |
1190 | 1258 | if (!(old_halt&0x0002)) printf("halt slave\n"); |
1191 | 1259 | } |
1192 | 1260 | else |
1193 | 1261 | { |
1194 | | space->machine().device("segacd_68k")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE); |
| 1262 | space->machine().device(":segacd:segacd_68k")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE); |
1195 | 1263 | if ((old_halt&0x0002)) printf("resume slave\n"); |
1196 | 1264 | } |
1197 | 1265 | } |
r17951 | r17952 | |
1480 | 1548 | { |
1481 | 1549 | // clear this bit |
1482 | 1550 | a12000_halt_reset_reg &= ~0x0100; |
1483 | | device->machine().device("segacd_68k")->execute().set_input_line(2, CLEAR_LINE); |
| 1551 | device->machine().device(":segacd:segacd_68k")->execute().set_input_line(2, CLEAR_LINE); |
1484 | 1552 | } |
1485 | 1553 | |
1486 | 1554 | return (0x60+irqline*4)/4; // vector address |
r17951 | r17952 | |
2236 | 2304 | { |
2237 | 2305 | address_space* space = machine.device("maincpu")->memory().space(AS_PROGRAM); |
2238 | 2306 | |
2239 | | segacd_font_bits = reinterpret_cast<UINT16 *>(machine.root_device().memshare("segacd_font")->ptr()); |
2240 | | segacd_backupram = reinterpret_cast<UINT16 *>(machine.root_device().memshare("backupram")->ptr()); |
2241 | | segacd_dataram = reinterpret_cast<UINT16 *>(machine.root_device().memshare("dataram")->ptr()); |
2242 | | segacd_dataram2 = reinterpret_cast<UINT16 *>(machine.root_device().memshare("dataram2")->ptr()); |
2243 | | segacd_4meg_prgram = reinterpret_cast<UINT16 *>(machine.root_device().memshare("segacd_program")->ptr()); |
| 2307 | segacd_font_bits = reinterpret_cast<UINT16 *>(machine.root_device().memshare(":segacd:segacd_font")->ptr()); |
| 2308 | segacd_backupram = reinterpret_cast<UINT16 *>(machine.root_device().memshare(":segacd:backupram")->ptr()); |
| 2309 | segacd_dataram = reinterpret_cast<UINT16 *>(machine.root_device().memshare(":segacd:dataram")->ptr()); |
| 2310 | segacd_dataram2 = reinterpret_cast<UINT16 *>(machine.root_device().memshare(":segacd:dataram2")->ptr()); |
| 2311 | segacd_4meg_prgram = reinterpret_cast<UINT16 *>(machine.root_device().memshare(":segacd:segacd_program")->ptr()); |
2244 | 2312 | |
2245 | 2313 | segacd_4meg_prgbank = 0; |
2246 | 2314 | |
r17951 | r17952 | |
2272 | 2340 | |
2273 | 2341 | |
2274 | 2342 | |
2275 | | machine.device("segacd_68k")->execute().set_irq_acknowledge_callback(segacd_sub_int_callback); |
| 2343 | machine.device(":segacd:segacd_68k")->execute().set_irq_acknowledge_callback(segacd_sub_int_callback); |
2276 | 2344 | |
2277 | 2345 | space->install_legacy_read_handler (0x0000070, 0x0000073, FUNC(scd_hint_vector_r) ); |
2278 | 2346 | |
r17951 | r17952 | |
2354 | 2422 | if ( segacd.cd ) |
2355 | 2423 | { |
2356 | 2424 | segacd.toc = cdrom_get_toc( segacd.cd ); |
2357 | | cdda_set_cdrom( machine.device("cdda"), segacd.cd ); |
2358 | | cdda_stop_audio( machine.device( "cdda" ) ); //stop any pending CD-DA |
| 2425 | cdda_set_cdrom( machine.device(":segacd:cdda"), segacd.cd ); |
| 2426 | cdda_stop_audio( machine.device( ":segacd:cdda" ) ); //stop any pending CD-DA |
2359 | 2427 | } |
2360 | 2428 | } |
2361 | 2429 | } |
r17951 | r17952 | |
2369 | 2437 | |
2370 | 2438 | |
2371 | 2439 | hock_cmd = 0; |
2372 | | stopwatch_timer = machine.device<timer_device>("sw_timer"); |
| 2440 | stopwatch_timer = machine.device<timer_device>(":segacd:sw_timer"); |
2373 | 2441 | |
2374 | 2442 | scd_dma_timer->adjust(attotime::zero); |
2375 | 2443 | |
r17951 | r17952 | |
2962 | 3030 | |
2963 | 3031 | //printf("%f\n",cdfader_vol); |
2964 | 3032 | |
2965 | | cdda_set_volume(space->machine().device("cdda"), cdfader_vol); |
| 3033 | cdda_set_volume(space->machine().device(":segacd:cdda"), cdfader_vol); |
2966 | 3034 | } |
2967 | 3035 | |
2968 | 3036 | READ16_HANDLER( segacd_backupram_r ) |
r17951 | r17952 | |
3062 | 3130 | ADDRESS_MAP_END |
3063 | 3131 | |
3064 | 3132 | |
| 3133 | |
| 3134 | |
| 3135 | void sega_segacd_device::device_start() |
| 3136 | { |
| 3137 | |
| 3138 | } |
| 3139 | |
| 3140 | void sega_segacd_device::device_reset() |
| 3141 | { |
| 3142 | |
| 3143 | } |
| 3144 | |
| 3145 | |