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 | |