trunk/src/mame/machine/mega32x.c
r22020 | r22021 | |
199 | 199 | #include "includes/megadriv.h" |
200 | 200 | |
201 | 201 | |
202 | | |
203 | | /* the main Megadrive emulation needs to know this */ |
204 | | cpu_device *_32x_master_cpu; |
205 | | cpu_device *_32x_slave_cpu; |
206 | | |
207 | 202 | /* need to make fifo callback part of device */ |
208 | 203 | static UINT16 fifo_block_a[4]; |
209 | 204 | static UINT16 fifo_block_b[4]; |
r22020 | r22021 | |
221 | 216 | |
222 | 217 | sega_32x_device::sega_32x_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock, device_type type) |
223 | 218 | : device_t(mconfig, type, "sega_32x_device", tag, owner, clock), |
| 219 | m_master_cpu(*this, "32x_master_sh2"), |
| 220 | m_slave_cpu(*this, "32x_slave_sh2"), |
224 | 221 | m_lch_pwm(*this, "lch_pwm"), |
225 | 222 | m_rch_pwm(*this, "rch_pwm") |
226 | 223 | { |
r22020 | r22021 | |
567 | 564 | current_fifo_block = fifo_block_b; |
568 | 565 | current_fifo_readblock = fifo_block_a; |
569 | 566 | // incase we have a stalled DMA in progress, let the SH2 know there is data available |
570 | | sh2_notify_dma_data_available(space.machine().device(_32X_MASTER_TAG)); |
571 | | sh2_notify_dma_data_available(space.machine().device(_32X_SLAVE_TAG)); |
| 567 | sh2_notify_dma_data_available(m_master_cpu); |
| 568 | sh2_notify_dma_data_available(m_slave_cpu); |
572 | 569 | |
573 | 570 | } |
574 | 571 | current_fifo_write_pos = 0; |
r22020 | r22021 | |
582 | 579 | current_fifo_block = fifo_block_a; |
583 | 580 | current_fifo_readblock = fifo_block_b; |
584 | 581 | // incase we have a stalled DMA in progress, let the SH2 know there is data available |
585 | | sh2_notify_dma_data_available(space.machine().device(_32X_MASTER_TAG)); |
586 | | sh2_notify_dma_data_available(space.machine().device(_32X_SLAVE_TAG)); |
| 582 | sh2_notify_dma_data_available(m_master_cpu); |
| 583 | sh2_notify_dma_data_available(m_slave_cpu); |
587 | 584 | |
588 | 585 | } |
589 | 586 | |
r22020 | r22021 | |
662 | 659 | |
663 | 660 | if (data & 0x02) |
664 | 661 | { |
665 | | _32x_master_cpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); |
666 | | _32x_slave_cpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); |
| 662 | m_master_cpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); |
| 663 | m_slave_cpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); |
667 | 664 | } |
668 | 665 | |
669 | 666 | if (data & 0x01) |
r22020 | r22021 | |
723 | 720 | |
724 | 721 | if (data&0x1) |
725 | 722 | { |
726 | | if (m_sh2_master_cmdint_enable) _32x_master_cpu->set_input_line(SH2_CINT_IRQ_LEVEL,ASSERT_LINE); |
| 723 | if (m_sh2_master_cmdint_enable) m_master_cpu->set_input_line(SH2_CINT_IRQ_LEVEL,ASSERT_LINE); |
727 | 724 | else printf("master cmdint when masked!\n"); |
728 | 725 | } |
729 | 726 | |
730 | 727 | if (data&0x2) |
731 | 728 | { |
732 | | if (m_sh2_slave_cmdint_enable) _32x_slave_cpu->set_input_line(SH2_CINT_IRQ_LEVEL,ASSERT_LINE); |
| 729 | if (m_sh2_slave_cmdint_enable) m_slave_cpu->set_input_line(SH2_CINT_IRQ_LEVEL,ASSERT_LINE); |
733 | 730 | else printf("slave cmdint when masked!\n"); |
734 | 731 | } |
735 | 732 | } |
r22020 | r22021 | |
855 | 852 | if(m_pwm_timer_tick == m_pwm_tm_reg) |
856 | 853 | { |
857 | 854 | m_pwm_timer_tick = 0; |
858 | | if(sh2_master_pwmint_enable) { _32x_master_cpu->set_input_line(SH2_PINT_IRQ_LEVEL,ASSERT_LINE); } |
859 | | if(sh2_slave_pwmint_enable) { _32x_slave_cpu->set_input_line(SH2_PINT_IRQ_LEVEL,ASSERT_LINE); } |
| 855 | if(sh2_master_pwmint_enable) { m_master_cpu->set_input_line(SH2_PINT_IRQ_LEVEL,ASSERT_LINE); } |
| 856 | if(sh2_slave_pwmint_enable) { m_slave_cpu->set_input_line(SH2_PINT_IRQ_LEVEL,ASSERT_LINE); } |
860 | 857 | } |
861 | 858 | |
862 | 859 | m_32x_pwm_timer->adjust(attotime::from_hz((PWM_CLOCK) / (m_pwm_cycle - 1))); |
r22020 | r22021 | |
1314 | 1311 | // VRES (md reset button interrupt) clear |
1315 | 1312 | /**********************************************************************************************/ |
1316 | 1313 | |
1317 | | WRITE16_MEMBER( sega_32x_device::_32x_sh2_master_4014_w ){ _32x_master_cpu->set_input_line(SH2_VRES_IRQ_LEVEL,CLEAR_LINE);} |
1318 | | WRITE16_MEMBER( sega_32x_device::_32x_sh2_slave_4014_w ) { _32x_slave_cpu->set_input_line(SH2_VRES_IRQ_LEVEL,CLEAR_LINE);} |
| 1314 | WRITE16_MEMBER( sega_32x_device::_32x_sh2_master_4014_w ){ m_master_cpu->set_input_line(SH2_VRES_IRQ_LEVEL,CLEAR_LINE);} |
| 1315 | WRITE16_MEMBER( sega_32x_device::_32x_sh2_slave_4014_w ) { m_slave_cpu->set_input_line(SH2_VRES_IRQ_LEVEL,CLEAR_LINE);} |
1319 | 1316 | |
1320 | 1317 | /**********************************************************************************************/ |
1321 | 1318 | // SH2 side 4016 |
r22020 | r22021 | |
1330 | 1327 | // HINT (horizontal interrupt) clear |
1331 | 1328 | /**********************************************************************************************/ |
1332 | 1329 | |
1333 | | WRITE16_MEMBER( sega_32x_device::_32x_sh2_master_4018_w ){ _32x_master_cpu->set_input_line(SH2_HINT_IRQ_LEVEL,CLEAR_LINE);} |
1334 | | WRITE16_MEMBER( sega_32x_device::_32x_sh2_slave_4018_w ) { _32x_slave_cpu->set_input_line(SH2_HINT_IRQ_LEVEL,CLEAR_LINE);} |
| 1330 | WRITE16_MEMBER( sega_32x_device::_32x_sh2_master_4018_w ){ m_master_cpu->set_input_line(SH2_HINT_IRQ_LEVEL,CLEAR_LINE);} |
| 1331 | WRITE16_MEMBER( sega_32x_device::_32x_sh2_slave_4018_w ) { m_slave_cpu->set_input_line(SH2_HINT_IRQ_LEVEL,CLEAR_LINE);} |
1335 | 1332 | |
1336 | 1333 | /**********************************************************************************************/ |
1337 | 1334 | // SH2 side 401A |
r22020 | r22021 | |
1339 | 1336 | // Note: flag cleared here is a guess, according to After Burner behaviour |
1340 | 1337 | /**********************************************************************************************/ |
1341 | 1338 | |
1342 | | WRITE16_MEMBER( sega_32x_device::_32x_sh2_master_401a_w ){ m_32x_68k_a15102_reg &= ~1; _32x_master_cpu->set_input_line(SH2_CINT_IRQ_LEVEL,CLEAR_LINE);} |
1343 | | WRITE16_MEMBER( sega_32x_device::_32x_sh2_slave_401a_w ) { m_32x_68k_a15102_reg &= ~2; _32x_slave_cpu->set_input_line(SH2_CINT_IRQ_LEVEL,CLEAR_LINE);} |
| 1339 | WRITE16_MEMBER( sega_32x_device::_32x_sh2_master_401a_w ){ m_32x_68k_a15102_reg &= ~1; m_master_cpu->set_input_line(SH2_CINT_IRQ_LEVEL,CLEAR_LINE);} |
| 1340 | WRITE16_MEMBER( sega_32x_device::_32x_sh2_slave_401a_w ) { m_32x_68k_a15102_reg &= ~2; m_slave_cpu->set_input_line(SH2_CINT_IRQ_LEVEL,CLEAR_LINE);} |
1344 | 1341 | |
1345 | 1342 | /**********************************************************************************************/ |
1346 | 1343 | // SH2 side 401C |
1347 | 1344 | // PINT (PWM timer interrupt) clear |
1348 | 1345 | /**********************************************************************************************/ |
1349 | 1346 | |
1350 | | WRITE16_MEMBER( sega_32x_device::_32x_sh2_master_401c_w ){ _32x_master_cpu->set_input_line(SH2_PINT_IRQ_LEVEL,CLEAR_LINE);} |
1351 | | WRITE16_MEMBER( sega_32x_device::_32x_sh2_slave_401c_w ) { _32x_slave_cpu->set_input_line(SH2_PINT_IRQ_LEVEL,CLEAR_LINE);} |
| 1347 | WRITE16_MEMBER( sega_32x_device::_32x_sh2_master_401c_w ){ m_master_cpu->set_input_line(SH2_PINT_IRQ_LEVEL,CLEAR_LINE);} |
| 1348 | WRITE16_MEMBER( sega_32x_device::_32x_sh2_slave_401c_w ) { m_slave_cpu->set_input_line(SH2_PINT_IRQ_LEVEL,CLEAR_LINE);} |
1352 | 1349 | |
1353 | 1350 | /**********************************************************************************************/ |
1354 | 1351 | // SH2 side 401E |
r22020 | r22021 | |
1558 | 1555 | |
1559 | 1556 | void sega_32x_device::_32x_check_irqs(running_machine& machine) |
1560 | 1557 | { |
1561 | | if (m_sh2_master_vint_enable && m_sh2_master_vint_pending) _32x_master_cpu->set_input_line(SH2_VINT_IRQ_LEVEL,ASSERT_LINE); |
1562 | | else _32x_master_cpu->set_input_line(SH2_VINT_IRQ_LEVEL,CLEAR_LINE); |
| 1558 | if (m_sh2_master_vint_enable && m_sh2_master_vint_pending) m_master_cpu->set_input_line(SH2_VINT_IRQ_LEVEL,ASSERT_LINE); |
| 1559 | else m_master_cpu->set_input_line(SH2_VINT_IRQ_LEVEL,CLEAR_LINE); |
1563 | 1560 | |
1564 | | if (m_sh2_slave_vint_enable && m_sh2_slave_vint_pending) _32x_slave_cpu->set_input_line(SH2_VINT_IRQ_LEVEL,ASSERT_LINE); |
1565 | | else _32x_slave_cpu->set_input_line(SH2_VINT_IRQ_LEVEL,CLEAR_LINE); |
| 1561 | if (m_sh2_slave_vint_enable && m_sh2_slave_vint_pending) m_slave_cpu->set_input_line(SH2_VINT_IRQ_LEVEL,ASSERT_LINE); |
| 1562 | else m_slave_cpu->set_input_line(SH2_VINT_IRQ_LEVEL,CLEAR_LINE); |
1566 | 1563 | } |
1567 | 1564 | |
1568 | 1565 | void sega_32x_device::_32x_scanline_cb0(running_machine& machine) |
r22020 | r22021 | |
1583 | 1580 | |
1584 | 1581 | if(genesis_scanline_counter < 224 || m_sh2_hint_in_vbl) |
1585 | 1582 | { |
1586 | | if(m_sh2_master_hint_enable) { _32x_master_cpu->set_input_line(SH2_HINT_IRQ_LEVEL,ASSERT_LINE); } |
1587 | | if(m_sh2_slave_hint_enable) { _32x_slave_cpu->set_input_line(SH2_HINT_IRQ_LEVEL,ASSERT_LINE); } |
| 1583 | if(m_sh2_master_hint_enable) { m_master_cpu->set_input_line(SH2_HINT_IRQ_LEVEL,ASSERT_LINE); } |
| 1584 | if(m_sh2_slave_hint_enable) { m_slave_cpu->set_input_line(SH2_HINT_IRQ_LEVEL,ASSERT_LINE); } |
1588 | 1585 | } |
1589 | 1586 | } |
1590 | 1587 | } |
r22020 | r22021 | |
1907 | 1904 | |
1908 | 1905 | |
1909 | 1906 | // checking if these help brutal, they don't. |
1910 | | sh2drc_set_options(machine().device(_32X_MASTER_TAG), SH2DRC_COMPATIBLE_OPTIONS); |
1911 | | sh2drc_set_options(machine().device(_32X_SLAVE_TAG), SH2DRC_COMPATIBLE_OPTIONS); |
| 1907 | sh2drc_set_options(m_master_cpu, SH2DRC_COMPATIBLE_OPTIONS); |
| 1908 | sh2drc_set_options(m_slave_cpu, SH2DRC_COMPATIBLE_OPTIONS); |
1912 | 1909 | |
1913 | 1910 | |
1914 | 1911 | // install these now, otherwise we'll get the following (incorrect) warnings on startup.. |
r22020 | r22021 | |
1921 | 1918 | membank("masterbios")->set_entry(0); |
1922 | 1919 | membank("slavebios")->set_entry(0); |
1923 | 1920 | } |
| 1921 | |
| 1922 | // if the system has a 32x, the extra CPUs are paused at start |
| 1923 | void sega_32x_device::pause_cpu() |
| 1924 | { |
| 1925 | m_master_cpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); |
| 1926 | m_slave_cpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); |
| 1927 | } |
trunk/src/mame/machine/megadriv.c
r22020 | r22021 | |
923 | 923 | /* default state of z80 = reset, with bus */ |
924 | 924 | mame_printf_debug("Resetting Megadrive / Genesis\n"); |
925 | 925 | |
926 | | if (machine.device("genesis_snd_z80") != NULL) |
| 926 | if (state->m_z80snd) |
927 | 927 | { |
928 | 928 | state->m_genz80.z80_is_reset = 1; |
929 | 929 | state->m_genz80.z80_has_bus = 1; |
r22020 | r22021 | |
951 | 951 | megadriv_reset_vdp(machine); |
952 | 952 | |
953 | 953 | |
954 | | |
955 | | /* if any of these extra CPUs exist, pause them until we actually turn them on */ |
956 | | if (_32x_master_cpu != NULL) |
957 | | { |
958 | | _32x_master_cpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); |
959 | | } |
960 | | |
961 | | if (_32x_slave_cpu != NULL) |
962 | | { |
963 | | _32x_slave_cpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); |
964 | | } |
965 | | |
966 | | |
967 | | |
| 954 | // if the system has a 32x, pause the extra CPUs until they are actually turned on |
| 955 | if (state->m_32x) |
| 956 | state->m_32x->pause_cpu(); |
968 | 957 | } |
969 | 958 | |
970 | 959 | void megadriv_stop_scanline_timer(running_machine &machine) |
r22020 | r22021 | |
1223 | 1212 | membank("bank1")->set_base(m_genz80.z80_prgram); |
1224 | 1213 | } |
1225 | 1214 | |
1226 | | /* Look to see if this system has the 32x Master SH2 */ |
1227 | | _32x_master_cpu = machine().device<cpu_device>(_32X_MASTER_TAG); |
1228 | | if (_32x_master_cpu != NULL) |
1229 | | { |
1230 | | printf("32x MASTER SH2 cpu found '%s'\n", _32x_master_cpu->tag() ); |
1231 | | } |
1232 | | |
1233 | | /* Look to see if this system has the 32x Slave SH2 */ |
1234 | | _32x_slave_cpu = machine().device<cpu_device>(_32X_SLAVE_TAG); |
1235 | | if (_32x_slave_cpu != NULL) |
1236 | | { |
1237 | | printf("32x SLAVE SH2 cpu found '%s'\n", _32x_slave_cpu->tag() ); |
1238 | | } |
1239 | | |
1240 | 1215 | machine().device("maincpu")->execute().set_irq_acknowledge_callback(device_irq_acknowledge_delegate(FUNC(md_base_state::genesis_int_callback),this)); |
1241 | 1216 | megadriv_backupram = NULL; |
1242 | 1217 | megadriv_backupram_length = 0; |
1243 | 1218 | |
1244 | 1219 | vdp_get_word_from_68k_mem = vdp_get_word_from_68k_mem_default; |
1245 | 1220 | |
| 1221 | if (machine().device("sega32x")) |
| 1222 | printf("32X found 'sega32x'\n"); |
1246 | 1223 | if (machine().device("svp")) |
1247 | 1224 | { |
1248 | | printf("SVP (cpu) found '%s'\n", machine().device("svp")->tag()); |
| 1225 | printf("SVP (cpu) found 'svp'\n"); |
1249 | 1226 | vdp_get_word_from_68k_mem = vdp_get_word_from_68k_mem_delayed; |
1250 | 1227 | } |
1251 | 1228 | if (machine().device("segacd")) |
1252 | 1229 | { |
1253 | | printf("SegaCD found '%s'\n", machine().device("segacd")->tag()); |
| 1230 | printf("SegaCD found 'segacd'\n"); |
1254 | 1231 | vdp_get_word_from_68k_mem = vdp_get_word_from_68k_mem_delayed; |
1255 | 1232 | } |
1256 | 1233 | |