trunk/src/emu/video/snes_ppu.c
| r242613 | r242614 | |
| 1810 | 1810 | * the optimized averaging algorithm. |
| 1811 | 1811 | *********************************************/ |
| 1812 | 1812 | |
| 1813 | | void snes_ppu_device::refresh_scanline( running_machine &machine, bitmap_rgb32 &bitmap, UINT16 curline ) |
| 1813 | void snes_ppu_device::refresh_scanline( bitmap_rgb32 &bitmap, UINT16 curline ) |
| 1814 | 1814 | { |
| 1815 | 1815 | UINT16 ii; |
| 1816 | 1816 | int x; |
| r242613 | r242614 | |
| 1818 | 1818 | struct SNES_SCANLINE *scanline1, *scanline2; |
| 1819 | 1819 | UINT16 c; |
| 1820 | 1820 | UINT16 prev_colour = 0; |
| 1821 | | int blurring = machine.root_device().ioport("OPTIONS")->read_safe(0) & 0x01; |
| 1821 | int blurring = machine().root_device().ioport("OPTIONS")->read_safe(0) & 0x01; |
| 1822 | 1822 | |
| 1823 | 1823 | g_profiler.start(PROFILER_VIDEO); |
| 1824 | 1824 | |
| r242613 | r242614 | |
| 1866 | 1866 | update_obsel(); |
| 1867 | 1867 | |
| 1868 | 1868 | #if SNES_LAYER_DEBUG |
| 1869 | | if (dbg_video(machine, curline)) |
| 1869 | if (dbg_video(curline)) |
| 1870 | 1870 | { |
| 1871 | 1871 | g_profiler.stop(); |
| 1872 | 1872 | return; |
| r242613 | r242614 | |
| 1978 | 1978 | static const UINT16 vram_fgr_shiftab[4] = { 0, 5, 6, 7 }; |
| 1979 | 1979 | |
| 1980 | 1980 | // utility function - latches the H/V counters. Used by IRQ, writes to WRIO, etc. |
| 1981 | | void snes_ppu_device::latch_counters( running_machine &machine ) |
| 1981 | void snes_ppu_device::latch_counters() |
| 1982 | 1982 | { |
| 1983 | | m_beam.current_horz = machine.first_screen()->hpos() / m_htmult; |
| 1984 | | m_beam.latch_vert = machine.first_screen()->vpos(); |
| 1983 | m_beam.current_horz = m_screen->hpos() / m_htmult; |
| 1984 | m_beam.latch_vert = m_screen->vpos(); |
| 1985 | 1985 | m_beam.latch_horz = m_beam.current_horz; |
| 1986 | 1986 | m_stat78 |= 0x40; // indicate we latched |
| 1987 | 1987 | // m_read_ophct = m_read_opvct = 0; // clear read flags - 2009-08: I think we must clear these when STAT78 is read... |
| r242613 | r242614 | |
| 1989 | 1989 | // printf("latched @ H %d V %d\n", m_beam.latch_horz, m_beam.latch_vert); |
| 1990 | 1990 | } |
| 1991 | 1991 | |
| 1992 | | void snes_ppu_device::dynamic_res_change( running_machine &machine ) |
| 1992 | void snes_ppu_device::dynamic_res_change() |
| 1993 | 1993 | { |
| 1994 | | rectangle visarea = machine.first_screen()->visible_area(); |
| 1994 | rectangle visarea = m_screen->visible_area(); |
| 1995 | 1995 | attoseconds_t refresh; |
| 1996 | 1996 | |
| 1997 | 1997 | visarea.min_x = visarea.min_y = 0; |
| r242613 | r242614 | |
| 2008 | 2008 | if ((m_stat78 & 0x10) == SNES_NTSC) |
| 2009 | 2009 | { |
| 2010 | 2010 | refresh = HZ_TO_ATTOSECONDS(DOTCLK_NTSC) * SNES_HTOTAL * SNES_VTOTAL_NTSC; |
| 2011 | | machine.first_screen()->configure(SNES_HTOTAL * 2, SNES_VTOTAL_NTSC * m_interlace, visarea, refresh); |
| 2011 | m_screen->configure(SNES_HTOTAL * 2, SNES_VTOTAL_NTSC * m_interlace, visarea, refresh); |
| 2012 | 2012 | } |
| 2013 | 2013 | else |
| 2014 | 2014 | { |
| 2015 | 2015 | refresh = HZ_TO_ATTOSECONDS(DOTCLK_PAL) * SNES_HTOTAL * SNES_VTOTAL_PAL; |
| 2016 | | machine.first_screen()->configure(SNES_HTOTAL * 2, SNES_VTOTAL_PAL * m_interlace, visarea, refresh); |
| 2016 | m_screen->configure(SNES_HTOTAL * 2, SNES_VTOTAL_PAL * m_interlace, visarea, refresh); |
| 2017 | 2017 | } |
| 2018 | 2018 | } |
| 2019 | 2019 | |
| r242613 | r242614 | |
| 2033 | 2033 | when interlace is active. |
| 2034 | 2034 | *************************************************/ |
| 2035 | 2035 | |
| 2036 | | inline UINT32 snes_ppu_device::get_vram_address( running_machine &machine ) |
| 2036 | inline UINT32 snes_ppu_device::get_vram_address() |
| 2037 | 2037 | { |
| 2038 | 2038 | UINT32 addr = m_vmadd; |
| 2039 | 2039 | |
| r242613 | r242614 | |
| 2308 | 2308 | return m_ppu1_open_bus; |
| 2309 | 2309 | } |
| 2310 | 2310 | case SLHV: /* Software latch for H/V counter */ |
| 2311 | | latch_counters(space.machine()); |
| 2311 | latch_counters(); |
| 2312 | 2312 | return m_openbus_cb(space, 0); /* Return value is meaningless */ |
| 2313 | 2313 | |
| 2314 | 2314 | case ROAMDATA: /* Read data from OAM (DR) */ |
| r242613 | r242614 | |
| 2323 | 2323 | return m_ppu1_open_bus; |
| 2324 | 2324 | case RVMDATAL: /* Read data from VRAM (low) */ |
| 2325 | 2325 | { |
| 2326 | | UINT32 addr = get_vram_address(space.machine()); |
| 2326 | UINT32 addr = get_vram_address(); |
| 2327 | 2327 | m_ppu1_open_bus = m_vram_read_buffer & 0xff; |
| 2328 | 2328 | |
| 2329 | 2329 | if (!m_vram_fgr_high) |
| r242613 | r242614 | |
| 2338 | 2338 | } |
| 2339 | 2339 | case RVMDATAH: /* Read data from VRAM (high) */ |
| 2340 | 2340 | { |
| 2341 | | UINT32 addr = get_vram_address(space.machine()); |
| 2341 | UINT32 addr = get_vram_address(); |
| 2342 | 2342 | m_ppu1_open_bus = (m_vram_read_buffer >> 8) & 0xff; |
| 2343 | 2343 | |
| 2344 | 2344 | if (m_vram_fgr_high) |
| r242613 | r242614 | |
| 2469 | 2469 | return; |
| 2470 | 2470 | case BGMODE: /* BG mode and character size settings */ |
| 2471 | 2471 | m_mode = data & 0x07; |
| 2472 | | dynamic_res_change(space.machine()); |
| 2472 | dynamic_res_change(); |
| 2473 | 2473 | m_bg3_priority_bit = BIT(data, 3); |
| 2474 | 2474 | m_layer[SNES_BG1].tile_size = BIT(data, 4); |
| 2475 | 2475 | m_layer[SNES_BG2].tile_size = BIT(data, 5); |
| r242613 | r242614 | |
| 2571 | 2571 | { |
| 2572 | 2572 | UINT32 addr; |
| 2573 | 2573 | m_vmadd = (m_vmadd & 0xff00) | (data << 0); |
| 2574 | | addr = get_vram_address(space.machine()); |
| 2574 | addr = get_vram_address(); |
| 2575 | 2575 | m_vram_read_buffer = vram_read(space, addr); |
| 2576 | 2576 | m_vram_read_buffer |= (vram_read(space, addr + 1) << 8); |
| 2577 | 2577 | } |
| r242613 | r242614 | |
| 2580 | 2580 | { |
| 2581 | 2581 | UINT32 addr; |
| 2582 | 2582 | m_vmadd = (m_vmadd & 0x00ff) | (data << 8); |
| 2583 | | addr = get_vram_address(space.machine()); |
| 2583 | addr = get_vram_address(); |
| 2584 | 2584 | m_vram_read_buffer = vram_read(space, addr); |
| 2585 | 2585 | m_vram_read_buffer |= (vram_read(space, addr + 1) << 8); |
| 2586 | 2586 | } |
| 2587 | 2587 | break; |
| 2588 | 2588 | case VMDATAL: /* 2118: Data for VRAM write (low) */ |
| 2589 | 2589 | { |
| 2590 | | UINT32 addr = get_vram_address(space.machine()); |
| 2590 | UINT32 addr = get_vram_address(); |
| 2591 | 2591 | vram_write(space, addr, data); |
| 2592 | 2592 | |
| 2593 | 2593 | if (!m_vram_fgr_high) |
| r242613 | r242614 | |
| 2596 | 2596 | return; |
| 2597 | 2597 | case VMDATAH: /* 2119: Data for VRAM write (high) */ |
| 2598 | 2598 | { |
| 2599 | | UINT32 addr = get_vram_address(space.machine()); |
| 2599 | UINT32 addr = get_vram_address(); |
| 2600 | 2600 | vram_write(space, addr + 1, data); |
| 2601 | 2601 | |
| 2602 | 2602 | if (m_vram_fgr_high) |
| r242613 | r242614 | |
| 2800 | 2800 | m_beam.last_visible_line = (data & 0x04) ? 240 : 225; |
| 2801 | 2801 | m_pseudo_hires = BIT(data, 3); |
| 2802 | 2802 | m_mode7.extbg = BIT(data, 6); |
| 2803 | | dynamic_res_change(space.machine()); |
| 2803 | dynamic_res_change(); |
| 2804 | 2804 | #ifdef SNES_DBG_REG_W |
| 2805 | 2805 | if ((data & 0x8) != (PPU_REG(SETINI) & 0x8)) |
| 2806 | 2806 | osd_printf_debug("Pseudo 512 mode: %s\n", (data & 0x8) ? "on" : "off"); |
| r242613 | r242614 | |
| 2827 | 2827 | popmessage MSG2; \ |
| 2828 | 2828 | } |
| 2829 | 2829 | |
| 2830 | | UINT8 snes_ppu_device::dbg_video( running_machine &machine, UINT16 curline ) |
| 2830 | UINT8 snes_ppu_device::dbg_video( UINT16 curline ) |
| 2831 | 2831 | { |
| 2832 | 2832 | int i; |
| 2833 | | UINT8 toggles = machine.root_device().ioport("DEBUG1")->read_safe(0); |
| 2833 | UINT8 toggles = machine().root_device().ioport("DEBUG1")->read_safe(0); |
| 2834 | 2834 | m_debug_options.select_pri[SNES_BG1] = (toggles & 0x03); |
| 2835 | 2835 | m_debug_options.select_pri[SNES_BG2] = (toggles & 0x0c) >> 2; |
| 2836 | 2836 | m_debug_options.select_pri[SNES_BG3] = (toggles & 0x30) >> 4; |
| 2837 | 2837 | m_debug_options.select_pri[SNES_BG4] = (toggles & 0xc0) >> 6; |
| 2838 | 2838 | |
| 2839 | | toggles = machine.root_device().ioport("DEBUG2")->read_safe(0); |
| 2839 | toggles = machine().root_device().ioport("DEBUG2")->read_safe(0); |
| 2840 | 2840 | for (i = 0; i < 4; i++) |
| 2841 | 2841 | DEBUG_TOGGLE(i, m_debug_options.bg_disabled[i], ("Debug: Disabled BG%d.\n", i + 1), ("Debug: Enabled BG%d.\n", i + 1)) |
| 2842 | 2842 | DEBUG_TOGGLE(4, m_debug_options.bg_disabled[SNES_OAM], ("Debug: Disabled OAM.\n"), ("Debug: Enabled OAM.\n")) |
| r242613 | r242614 | |
| 2844 | 2844 | DEBUG_TOGGLE(6, m_debug_options.colormath_disabled, ("Debug: Disabled Color Math.\n"), ("Debug: Enabled Color Math.\n")) |
| 2845 | 2845 | DEBUG_TOGGLE(7, m_debug_options.windows_disabled, ("Debug: Disabled Window Masks.\n"), ("Debug: Enabled Window Masks.\n")) |
| 2846 | 2846 | |
| 2847 | | toggles = machine.root_device().ioport("DEBUG4")->read_safe(0); |
| 2847 | toggles = machine().root_device().ioport("DEBUG4")->read_safe(0); |
| 2848 | 2848 | for (i = 0; i < 8; i++) |
| 2849 | 2849 | DEBUG_TOGGLE(i, m_debug_options.mode_disabled[i], ("Debug: Disabled Mode %d drawing.\n", i), ("Debug: Enabled Mode %d drawing.\n", i)) |
| 2850 | 2850 | |
| 2851 | | toggles = machine.root_device().ioport("DEBUG3")->read_safe(0); |
| 2851 | toggles = machine().root_device().ioport("DEBUG3")->read_safe(0); |
| 2852 | 2852 | DEBUG_TOGGLE(2, m_debug_options.mosaic_disabled, ("Debug: Disabled Mosaic.\n"), ("Debug: Enabled Mosaic.\n")) |
| 2853 | 2853 | m_debug_options.sprite_reversed = BIT(toggles, 7); |
| 2854 | 2854 | m_debug_options.select_pri[SNES_OAM] = (toggles & 0x70) >> 4; |