trunk/src/mame/machine/megacd.c
| r22021 | r22022 | |
| 4 | 4 | #include "sound/rf5c68.h" |
| 5 | 5 | |
| 6 | 6 | |
| 7 | | // not in the state because the IRQ_CALLBACK needs it, and that can't be a member function? |
| 8 | | UINT16 a12000_halt_reset_reg = 0x0000; |
| 9 | | |
| 10 | 7 | /* Callback when the genesis enters interrupt code */ |
| 11 | | // needs to be a member |
| 12 | 8 | IRQ_CALLBACK_MEMBER(sega_segacd_device::segacd_sub_int_callback) |
| 13 | 9 | { |
| 14 | 10 | if (irqline==2) |
| 15 | 11 | { |
| 16 | 12 | // clear this bit |
| 17 | | a12000_halt_reset_reg &= ~0x0100; |
| 18 | | device.machine().device(":segacd:segacd_68k")->execute().set_input_line(2, CLEAR_LINE); |
| 13 | m_a12000_halt_reset_reg &= ~0x0100; |
| 14 | m_scdcpu->set_input_line(2, CLEAR_LINE); |
| 19 | 15 | } |
| 20 | 16 | |
| 21 | 17 | return (0x60+irqline*4)/4; // vector address |
| 22 | 18 | } |
| 23 | 19 | |
| 24 | 20 | |
| 25 | | |
| 26 | | |
| 27 | 21 | const device_type SEGA_SEGACD_US = &device_creator<sega_segacd_us_device>; |
| 28 | 22 | const device_type SEGA_SEGACD_JAPAN = &device_creator<sega_segacd_japan_device>; |
| 29 | 23 | const device_type SEGA_SEGACD_EUROPE = &device_creator<sega_segacd_europe_device>; |
| 30 | 24 | |
| 31 | 25 | sega_segacd_device::sega_segacd_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock, device_type type) |
| 32 | | : device_t(mconfig, type, "sega_segacd_device", tag, owner, clock) |
| 26 | : device_t(mconfig, type, "sega_segacd_device", tag, owner, clock), |
| 27 | m_scdcpu(*this, "segacd_68k") |
| 33 | 28 | { |
| 34 | 29 | } |
| 35 | 30 | |
| r22021 | r22022 | |
| 137 | 132 | MCFG_TIMER_DRIVER_ADD("scd_dma_timer", sega_segacd_device, scd_dma_timer_callback) |
| 138 | 133 | |
| 139 | 134 | |
| 140 | | |
| 141 | 135 | MCFG_DEFAULT_LAYOUT( layout_megacd ) |
| 142 | 136 | |
| 143 | 137 | |
| 144 | | |
| 145 | 138 | MCFG_RF5C68_ADD("rfsnd", SEGACD_CLOCK) // RF5C164! |
| 146 | 139 | MCFG_SOUND_ROUTE( 0, ":lspeaker", 0.50 ) |
| 147 | 140 | MCFG_SOUND_ROUTE( 1, ":rspeaker", 0.50 ) |
| r22021 | r22022 | |
| 165 | 158 | |
| 166 | 159 | |
| 167 | 160 | |
| 168 | | |
| 169 | | |
| 170 | | |
| 171 | | |
| 172 | 161 | inline void sega_segacd_device::write_pixel(running_machine& machine, UINT8 pix, int pixeloffset ) |
| 173 | 162 | { |
| 174 | 163 | int shift = 12-(4*(pixeloffset&0x3)); |
| r22021 | r22022 | |
| 292 | 281 | |
| 293 | 282 | WRITE16_MEMBER( sega_segacd_device::scd_a12000_halt_reset_w ) |
| 294 | 283 | { |
| 295 | | UINT16 old_halt = a12000_halt_reset_reg; |
| 284 | UINT16 old_halt = m_a12000_halt_reset_reg; |
| 296 | 285 | |
| 297 | | COMBINE_DATA(&a12000_halt_reset_reg); |
| 286 | COMBINE_DATA(&m_a12000_halt_reset_reg); |
| 298 | 287 | |
| 299 | 288 | if (ACCESSING_BITS_0_7) |
| 300 | 289 | { |
| 301 | 290 | // reset line |
| 302 | | if (a12000_halt_reset_reg&0x0001) |
| 291 | if (m_a12000_halt_reset_reg & 0x0001) |
| 303 | 292 | { |
| 304 | | space.machine().device(":segacd:segacd_68k")->execute().set_input_line(INPUT_LINE_RESET, CLEAR_LINE); |
| 293 | m_scdcpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); |
| 305 | 294 | if (!(old_halt&0x0001)) printf("clear reset slave\n"); |
| 306 | 295 | } |
| 307 | 296 | else |
| 308 | 297 | { |
| 309 | | space.machine().device(":segacd:segacd_68k")->execute().set_input_line(INPUT_LINE_RESET, ASSERT_LINE); |
| 298 | m_scdcpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); |
| 310 | 299 | if ((old_halt&0x0001)) printf("assert reset slave\n"); |
| 311 | 300 | } |
| 312 | 301 | |
| 313 | 302 | // request BUS |
| 314 | | if (a12000_halt_reset_reg&0x0002) |
| 303 | if (m_a12000_halt_reset_reg & 0x0002) |
| 315 | 304 | { |
| 316 | | space.machine().device(":segacd:segacd_68k")->execute().set_input_line(INPUT_LINE_HALT, ASSERT_LINE); |
| 305 | m_scdcpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); |
| 317 | 306 | if (!(old_halt&0x0002)) printf("halt slave\n"); |
| 318 | 307 | } |
| 319 | 308 | else |
| 320 | 309 | { |
| 321 | | space.machine().device(":segacd:segacd_68k")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE); |
| 310 | m_scdcpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE); |
| 322 | 311 | if ((old_halt&0x0002)) printf("resume slave\n"); |
| 323 | 312 | } |
| 324 | 313 | } |
| 325 | 314 | |
| 326 | 315 | if (ACCESSING_BITS_8_15) |
| 327 | 316 | { |
| 328 | | if (a12000_halt_reset_reg&0x0100) |
| 317 | if (m_a12000_halt_reset_reg & 0x0100) |
| 329 | 318 | { |
| 330 | 319 | running_machine& machine = space.machine(); |
| 331 | 320 | CHECK_SCD_LV2_INTERRUPT |
| 332 | 321 | } |
| 333 | 322 | |
| 334 | | if (a12000_halt_reset_reg&0x8000) |
| 323 | if (m_a12000_halt_reset_reg & 0x8000) |
| 335 | 324 | { |
| 336 | 325 | // not writable.. but can read irq mask here? |
| 337 | | //printf("a12000_halt_reset_reg & 0x8000 set\n"); // irq2 mask? |
| 326 | //printf("m_a12000_halt_reset_reg & 0x8000 set\n"); // irq2 mask? |
| 338 | 327 | } |
| 339 | 328 | |
| 340 | 329 | |
| r22021 | r22022 | |
| 343 | 332 | |
| 344 | 333 | READ16_MEMBER( sega_segacd_device::scd_a12000_halt_reset_r ) |
| 345 | 334 | { |
| 346 | | return a12000_halt_reset_reg; |
| 335 | return m_a12000_halt_reset_reg; |
| 347 | 336 | } |
| 348 | 337 | |
| 349 | 338 | |
| r22021 | r22022 | |
| 1562 | 1551 | |
| 1563 | 1552 | void sega_segacd_device::device_start() |
| 1564 | 1553 | { |
| 1565 | | _segacd_68k_cpu = machine().device<cpu_device>(":segacd:segacd_68k"); |
| 1566 | | |
| 1567 | 1554 | segacd_gfx_conversion_timer = machine().device<timer_device>(":segacd:stamp_timer"); |
| 1568 | 1555 | segacd_irq3_timer = machine().device<timer_device>(":segacd:irq3_timer"); |
| 1569 | 1556 | scd_dma_timer = machine().device<timer_device>(":segacd:scd_dma_timer"); |
| r22021 | r22022 | |
| 1603 | 1590 | |
| 1604 | 1591 | |
| 1605 | 1592 | |
| 1606 | | machine().device(":segacd:segacd_68k")->execute().set_irq_acknowledge_callback(device_irq_acknowledge_delegate(FUNC(sega_segacd_device::segacd_sub_int_callback),this)); |
| 1593 | m_scdcpu->set_irq_acknowledge_callback(device_irq_acknowledge_delegate(FUNC(sega_segacd_device::segacd_sub_int_callback),this)); |
| 1607 | 1594 | |
| 1608 | 1595 | space.install_read_handler (0x0000070, 0x0000073, read16_delegate(FUNC(sega_segacd_device::scd_hint_vector_r),this) ); |
| 1609 | 1596 | |
| r22021 | r22022 | |
| 1650 | 1637 | |
| 1651 | 1638 | void sega_segacd_device::device_reset() |
| 1652 | 1639 | { |
| 1653 | | _segacd_68k_cpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); |
| 1654 | | _segacd_68k_cpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); |
| 1640 | m_scdcpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); |
| 1641 | m_scdcpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); |
| 1655 | 1642 | |
| 1656 | 1643 | segacd_hint_register = 0xffff; // -1 |
| 1657 | 1644 | |
| 1645 | m_a12000_halt_reset_reg = 0x0000; |
| 1658 | 1646 | |
| 1659 | | |
| 1660 | 1647 | scd_rammode = 0; |
| 1661 | 1648 | scd_mode_dmna_ret_flags = 0x5421; |
| 1662 | 1649 | |
| r22021 | r22022 | |
| 1675 | 1662 | // time. Changing the CDHock timer to 50hz from 75hz also stops the hang, but then the video is |
| 1676 | 1663 | // too slow and has bad sound. -- Investigate! |
| 1677 | 1664 | |
| 1678 | | _segacd_68k_cpu->set_clock_scale(1.5000f); |
| 1665 | m_scdcpu->set_clock_scale(1.5000f); |
| 1679 | 1666 | |
| 1680 | 1667 | |
| 1681 | 1668 | // initialize some stuff on reset |