trunk/src/mame/video/snes.c
| r21560 | r21561 | |
| 109 | 109 | { (112*32), (112*32)+32, (112*32)+64, (112*32)+96, (112*32)+128, (112*32)+160, (112*32)+192, (112*32)+224 } |
| 110 | 110 | }; |
| 111 | 111 | |
| 112 | | struct SCANLINE |
| 113 | | { |
| 114 | | int enable, clip; |
| 115 | 112 | |
| 116 | | UINT16 buffer[SNES_SCR_WIDTH]; |
| 117 | | UINT8 priority[SNES_SCR_WIDTH]; |
| 118 | | UINT8 layer[SNES_SCR_WIDTH]; |
| 119 | | UINT8 blend_exception[SNES_SCR_WIDTH]; |
| 120 | | }; |
| 121 | | |
| 122 | | static struct SCANLINE scanlines[2]; |
| 123 | | //struct SNES_PPU_STRUCT snes_ppu; |
| 124 | | |
| 125 | 113 | enum |
| 126 | 114 | { |
| 127 | 115 | SNES_COLOR_DEPTH_2BPP = 0, |
| r21560 | r21561 | |
| 161 | 149 | |
| 162 | 150 | inline void snes_ppu_class::set_scanline_pixel( int screen, INT16 x, UINT16 color, UINT8 priority, UINT8 layer, int blend ) |
| 163 | 151 | { |
| 164 | | scanlines[screen].buffer[x] = color; |
| 165 | | scanlines[screen].priority[x] = priority; |
| 166 | | scanlines[screen].layer[x] = layer; |
| 167 | | scanlines[screen].blend_exception[x] = blend; |
| 152 | m_scanlines[screen].buffer[x] = color; |
| 153 | m_scanlines[screen].priority[x] = priority; |
| 154 | m_scanlines[screen].layer[x] = layer; |
| 155 | m_scanlines[screen].blend_exception[x] = blend; |
| 168 | 156 | } |
| 169 | 157 | |
| 170 | 158 | /************************************************************************************************* |
| r21560 | r21561 | |
| 197 | 185 | |
| 198 | 186 | for (screen = SNES_MAINSCREEN; screen <= SNES_SUBSCREEN; screen++) |
| 199 | 187 | { |
| 200 | | if (ii >= 0 && ii < SNES_SCR_WIDTH && scanlines[screen].enable) |
| 188 | if (ii >= 0 && ii < SNES_SCR_WIDTH && m_scanlines[screen].enable) |
| 201 | 189 | { |
| 202 | | if (scanlines[screen].priority[ii] <= priority) |
| 190 | if (m_scanlines[screen].priority[ii] <= priority) |
| 203 | 191 | { |
| 204 | 192 | UINT8 clr = colour; |
| 205 | 193 | UINT8 clipmask = m_clipmasks[layer][ii]; |
| r21560 | r21561 | |
| 210 | 198 | #endif /* SNES_LAYER_DEBUG */ |
| 211 | 199 | |
| 212 | 200 | /* Clip to windows */ |
| 213 | | if (scanlines[screen].clip) |
| 201 | if (m_scanlines[screen].clip) |
| 214 | 202 | clr &= clipmask; |
| 215 | 203 | |
| 216 | 204 | /* Only draw if we have a colour (0 == transparent) */ |
| r21560 | r21561 | |
| 232 | 220 | for (screen = SNES_MAINSCREEN; screen <= SNES_SUBSCREEN; screen++) |
| 233 | 221 | { |
| 234 | 222 | // odd pixels to main screen, even pixels to sub screen |
| 235 | | if (ii >= 0 && ii < (SNES_SCR_WIDTH << 1) && ((ii & 1) ^ screen) && scanlines[screen].enable) |
| 223 | if (ii >= 0 && ii < (SNES_SCR_WIDTH << 1) && ((ii & 1) ^ screen) && m_scanlines[screen].enable) |
| 236 | 224 | { |
| 237 | | if (scanlines[screen].priority[ii >> 1] <= priority) |
| 225 | if (m_scanlines[screen].priority[ii >> 1] <= priority) |
| 238 | 226 | { |
| 239 | 227 | UINT8 clr = colour; |
| 240 | 228 | UINT8 clipmask = m_clipmasks[layer][ii >> 1]; |
| r21560 | r21561 | |
| 245 | 233 | #endif /* SNES_LAYER_DEBUG */ |
| 246 | 234 | |
| 247 | 235 | /* Clip to windows */ |
| 248 | | if (scanlines[screen].clip) |
| 236 | if (m_scanlines[screen].clip) |
| 249 | 237 | clr &= clipmask; |
| 250 | 238 | |
| 251 | 239 | /* Only draw if we have a colour (0 == transparent) */ |
| r21560 | r21561 | |
| 268 | 256 | |
| 269 | 257 | for (screen = SNES_MAINSCREEN; screen <= SNES_SUBSCREEN; screen++) |
| 270 | 258 | { |
| 271 | | if (pos >= 0 && pos < SNES_SCR_WIDTH && scanlines[screen].enable) |
| 259 | if (pos >= 0 && pos < SNES_SCR_WIDTH && m_scanlines[screen].enable) |
| 272 | 260 | { |
| 273 | 261 | UINT8 clr = colour; |
| 274 | 262 | UINT8 clipmask = m_clipmasks[SNES_OAM][pos]; |
| r21560 | r21561 | |
| 279 | 267 | #endif /* SNES_LAYER_DEBUG */ |
| 280 | 268 | |
| 281 | 269 | /* Clip to windows */ |
| 282 | | if (scanlines[screen].clip) |
| 270 | if (m_scanlines[screen].clip) |
| 283 | 271 | clr &= clipmask; |
| 284 | 272 | |
| 285 | 273 | /* Only draw if we have a colour (0 == transparent) */ |
| r21560 | r21561 | |
| 427 | 415 | return; |
| 428 | 416 | #endif /* SNES_LAYER_DEBUG */ |
| 429 | 417 | |
| 430 | | scanlines[SNES_MAINSCREEN].enable = m_layer[layer].main_bg_enabled; |
| 431 | | scanlines[SNES_SUBSCREEN].enable = m_layer[layer].sub_bg_enabled; |
| 432 | | scanlines[SNES_MAINSCREEN].clip = m_layer[layer].main_window_enabled; |
| 433 | | scanlines[SNES_SUBSCREEN].clip = m_layer[layer].sub_window_enabled; |
| 418 | m_scanlines[SNES_MAINSCREEN].enable = m_layer[layer].main_bg_enabled; |
| 419 | m_scanlines[SNES_SUBSCREEN].enable = m_layer[layer].sub_bg_enabled; |
| 420 | m_scanlines[SNES_MAINSCREEN].clip = m_layer[layer].main_window_enabled; |
| 421 | m_scanlines[SNES_SUBSCREEN].clip = m_layer[layer].sub_window_enabled; |
| 434 | 422 | |
| 435 | | if (!scanlines[SNES_MAINSCREEN].enable && !scanlines[SNES_SUBSCREEN].enable) |
| 423 | if (!m_scanlines[SNES_MAINSCREEN].enable && !m_scanlines[SNES_SUBSCREEN].enable) |
| 436 | 424 | return; |
| 437 | 425 | |
| 438 | 426 | /* Handle Mosaic effects */ |
| r21560 | r21561 | |
| 609 | 597 | return; |
| 610 | 598 | #endif /* SNES_LAYER_DEBUG */ |
| 611 | 599 | |
| 612 | | scanlines[SNES_MAINSCREEN].enable = m_layer[layer].main_bg_enabled; |
| 613 | | scanlines[SNES_SUBSCREEN].enable = m_layer[layer].sub_bg_enabled; |
| 614 | | scanlines[SNES_MAINSCREEN].clip = m_layer[layer].main_window_enabled; |
| 615 | | scanlines[SNES_SUBSCREEN].clip = m_layer[layer].sub_window_enabled; |
| 600 | m_scanlines[SNES_MAINSCREEN].enable = m_layer[layer].main_bg_enabled; |
| 601 | m_scanlines[SNES_SUBSCREEN].enable = m_layer[layer].sub_bg_enabled; |
| 602 | m_scanlines[SNES_MAINSCREEN].clip = m_layer[layer].main_window_enabled; |
| 603 | m_scanlines[SNES_SUBSCREEN].clip = m_layer[layer].sub_window_enabled; |
| 616 | 604 | |
| 617 | | if (!scanlines[SNES_MAINSCREEN].enable && !scanlines[SNES_SUBSCREEN].enable) |
| 605 | if (!m_scanlines[SNES_MAINSCREEN].enable && !m_scanlines[SNES_SUBSCREEN].enable) |
| 618 | 606 | return; |
| 619 | 607 | |
| 620 | 608 | ma = m_mode7.matrix_a; |
| r21560 | r21561 | |
| 728 | 716 | |
| 729 | 717 | for (screen = SNES_MAINSCREEN; screen <= SNES_SUBSCREEN; screen++) |
| 730 | 718 | { |
| 731 | | if (scanlines[screen].enable) |
| 719 | if (m_scanlines[screen].enable) |
| 732 | 720 | { |
| 733 | 721 | UINT8 clr = colour; |
| 734 | 722 | UINT8 clipmask = m_clipmasks[layer][xpos]; |
| r21560 | r21561 | |
| 739 | 727 | #endif /* SNES_LAYER_DEBUG */ |
| 740 | 728 | |
| 741 | 729 | /* Clip to windows */ |
| 742 | | if (scanlines[screen].clip) |
| 730 | if (m_scanlines[screen].clip) |
| 743 | 731 | clr &= clipmask; |
| 744 | 732 | |
| 745 | 733 | /* Draw pixel if appropriate */ |
| 746 | | if (scanlines[screen].priority[xpos] <= priority && clr > 0) |
| 734 | if (m_scanlines[screen].priority[xpos] <= priority && clr > 0) |
| 747 | 735 | { |
| 748 | 736 | /* Direct select, but only outside EXTBG! */ |
| 749 | 737 | // Direct color format is: 0 | BB000 | GGG00 | RRR00, HW confirms that the data is zero padded. |
| r21560 | r21561 | |
| 1049 | 1037 | |
| 1050 | 1038 | /* set Range Over flag if necessary */ |
| 1051 | 1039 | if (range_over > 32) |
| 1052 | | m_stat77_flags |= 0x40; |
| 1040 | m_stat77 |= 0x40; |
| 1053 | 1041 | |
| 1054 | 1042 | /* set Time Over flag if necessary */ |
| 1055 | 1043 | if (time_over > 34) |
| 1056 | | m_stat77_flags |= 0x80; |
| 1044 | m_stat77 |= 0x80; |
| 1057 | 1045 | } |
| 1058 | 1046 | |
| 1059 | 1047 | /********************************************* |
| r21560 | r21561 | |
| 1073 | 1061 | return; |
| 1074 | 1062 | #endif /* SNES_LAYER_DEBUG */ |
| 1075 | 1063 | |
| 1076 | | scanlines[SNES_MAINSCREEN].enable = m_layer[SNES_OAM].main_bg_enabled; |
| 1077 | | scanlines[SNES_SUBSCREEN].enable = m_layer[SNES_OAM].sub_bg_enabled; |
| 1078 | | scanlines[SNES_MAINSCREEN].clip = m_layer[SNES_OAM].main_window_enabled; |
| 1079 | | scanlines[SNES_SUBSCREEN].clip = m_layer[SNES_OAM].sub_window_enabled; |
| 1064 | m_scanlines[SNES_MAINSCREEN].enable = m_layer[SNES_OAM].main_bg_enabled; |
| 1065 | m_scanlines[SNES_SUBSCREEN].enable = m_layer[SNES_OAM].sub_bg_enabled; |
| 1066 | m_scanlines[SNES_MAINSCREEN].clip = m_layer[SNES_OAM].main_window_enabled; |
| 1067 | m_scanlines[SNES_SUBSCREEN].clip = m_layer[SNES_OAM].sub_window_enabled; |
| 1080 | 1068 | |
| 1081 | | if (!scanlines[SNES_MAINSCREEN].enable && !scanlines[SNES_SUBSCREEN].enable) |
| 1069 | if (!m_scanlines[SNES_MAINSCREEN].enable && !m_scanlines[SNES_SUBSCREEN].enable) |
| 1082 | 1070 | return; |
| 1083 | 1071 | |
| 1084 | 1072 | charaddr = m_layer[SNES_OAM].charmap << 13; |
| r21560 | r21561 | |
| 1389 | 1377 | (prevent_color_math == SNES_CLIP_OUT && m_clipmasks[SNES_COLOR][offset])) |
| 1390 | 1378 | { |
| 1391 | 1379 | UINT16 r, g, b; |
| 1392 | | struct SCANLINE *subscreen; |
| 1380 | struct SNES_SCANLINE *subscreen; |
| 1393 | 1381 | int clip_max = 0; // if add then clip to 0x1f, if sub then clip to 0 |
| 1394 | 1382 | |
| 1395 | 1383 | #if SNES_LAYER_DEBUG |
| 1396 | 1384 | /* Toggle drawing of SNES_SUBSCREEN or SNES_MAINSCREEN */ |
| 1397 | 1385 | if (debug_options.draw_subscreen) |
| 1398 | 1386 | { |
| 1399 | | subscreen = switch_screens ? &scanlines[SNES_SUBSCREEN] : &scanlines[SNES_MAINSCREEN]; |
| 1387 | subscreen = switch_screens ? &m_scanlines[SNES_SUBSCREEN] : &m_scanlines[SNES_MAINSCREEN]; |
| 1400 | 1388 | } |
| 1401 | 1389 | else |
| 1402 | 1390 | #endif /* SNES_LAYER_DEBUG */ |
| 1403 | 1391 | { |
| 1404 | | subscreen = switch_screens ? &scanlines[SNES_MAINSCREEN] : &scanlines[SNES_SUBSCREEN]; |
| 1392 | subscreen = switch_screens ? &m_scanlines[SNES_MAINSCREEN] : &m_scanlines[SNES_SUBSCREEN]; |
| 1405 | 1393 | } |
| 1406 | 1394 | |
| 1407 | 1395 | if (m_sub_add_mode) /* SNES_SUBSCREEN*/ |
| r21560 | r21561 | |
| 1497 | 1485 | UINT16 ii; |
| 1498 | 1486 | int x; |
| 1499 | 1487 | int fade; |
| 1500 | | struct SCANLINE *scanline1, *scanline2; |
| 1488 | struct SNES_SCANLINE *scanline1, *scanline2; |
| 1501 | 1489 | UINT16 c; |
| 1502 | 1490 | UINT16 prev_colour = 0; |
| 1503 | 1491 | int blurring = machine.root_device().ioport("OPTIONS")->read_safe(0) & 0x01; |
| r21560 | r21561 | |
| 1517 | 1505 | update_offsets(); |
| 1518 | 1506 | |
| 1519 | 1507 | /* Clear priority */ |
| 1520 | | memset(scanlines[SNES_MAINSCREEN].priority, 0, SNES_SCR_WIDTH); |
| 1521 | | memset(scanlines[SNES_SUBSCREEN].priority, 0, SNES_SCR_WIDTH); |
| 1508 | memset(m_scanlines[SNES_MAINSCREEN].priority, 0, SNES_SCR_WIDTH); |
| 1509 | memset(m_scanlines[SNES_SUBSCREEN].priority, 0, SNES_SCR_WIDTH); |
| 1522 | 1510 | |
| 1523 | 1511 | /* Clear layers */ |
| 1524 | | memset(scanlines[SNES_MAINSCREEN].layer, SNES_COLOR, SNES_SCR_WIDTH); |
| 1525 | | memset(scanlines[SNES_SUBSCREEN].layer, SNES_COLOR, SNES_SCR_WIDTH); |
| 1512 | memset(m_scanlines[SNES_MAINSCREEN].layer, SNES_COLOR, SNES_SCR_WIDTH); |
| 1513 | memset(m_scanlines[SNES_SUBSCREEN].layer, SNES_COLOR, SNES_SCR_WIDTH); |
| 1526 | 1514 | |
| 1527 | 1515 | /* Clear blend_exception (only used for OAM) */ |
| 1528 | | memset(scanlines[SNES_MAINSCREEN].blend_exception, 0, SNES_SCR_WIDTH); |
| 1529 | | memset(scanlines[SNES_SUBSCREEN].blend_exception, 0, SNES_SCR_WIDTH); |
| 1516 | memset(m_scanlines[SNES_MAINSCREEN].blend_exception, 0, SNES_SCR_WIDTH); |
| 1517 | memset(m_scanlines[SNES_SUBSCREEN].blend_exception, 0, SNES_SCR_WIDTH); |
| 1530 | 1518 | |
| 1531 | 1519 | /* Draw back colour */ |
| 1532 | 1520 | for (ii = 0; ii < SNES_SCR_WIDTH; ii++) |
| 1533 | 1521 | { |
| 1534 | 1522 | if (m_mode == 5 || m_mode == 6 || m_pseudo_hires) |
| 1535 | | scanlines[SNES_SUBSCREEN].buffer[ii] = m_cgram[0]; |
| 1523 | m_scanlines[SNES_SUBSCREEN].buffer[ii] = m_cgram[0]; |
| 1536 | 1524 | else |
| 1537 | | scanlines[SNES_SUBSCREEN].buffer[ii] = m_cgram[FIXED_COLOUR]; |
| 1525 | m_scanlines[SNES_SUBSCREEN].buffer[ii] = m_cgram[FIXED_COLOUR]; |
| 1538 | 1526 | |
| 1539 | | scanlines[SNES_MAINSCREEN].buffer[ii] = m_cgram[0]; |
| 1527 | m_scanlines[SNES_MAINSCREEN].buffer[ii] = m_cgram[0]; |
| 1540 | 1528 | } |
| 1541 | 1529 | |
| 1542 | 1530 | /* Prepare OAM for this scanline */ |
| r21560 | r21561 | |
| 1557 | 1545 | /* Toggle drawing of SNES_SUBSCREEN or SNES_MAINSCREEN */ |
| 1558 | 1546 | if (debug_options.draw_subscreen) |
| 1559 | 1547 | { |
| 1560 | | scanline1 = &scanlines[SNES_SUBSCREEN]; |
| 1561 | | scanline2 = &scanlines[SNES_MAINSCREEN]; |
| 1548 | scanline1 = &m_scanlines[SNES_SUBSCREEN]; |
| 1549 | scanline2 = &m_scanlines[SNES_MAINSCREEN]; |
| 1562 | 1550 | } |
| 1563 | 1551 | else |
| 1564 | 1552 | #endif /* SNES_LAYER_DEBUG */ |
| 1565 | 1553 | { |
| 1566 | | scanline1 = &scanlines[SNES_MAINSCREEN]; |
| 1567 | | scanline2 = &scanlines[SNES_SUBSCREEN]; |
| 1554 | scanline1 = &m_scanlines[SNES_MAINSCREEN]; |
| 1555 | scanline2 = &m_scanlines[SNES_SUBSCREEN]; |
| 1568 | 1556 | } |
| 1569 | 1557 | |
| 1570 | 1558 | /* Draw the scanline to screen */ |
| r21560 | r21561 | |
| 1778 | 1766 | state_save_register_global(machine, m_screen_disabled); |
| 1779 | 1767 | state_save_register_global(machine, m_pseudo_hires); |
| 1780 | 1768 | state_save_register_global(machine, m_color_modes); |
| 1781 | | state_save_register_global(machine, m_stat77_flags); |
| 1769 | state_save_register_global(machine, m_stat77); |
| 1770 | state_save_register_global(machine, m_stat78); |
| 1782 | 1771 | |
| 1783 | 1772 | state_save_register_global(machine, m_htmult); |
| 1784 | 1773 | state_save_register_global(machine, m_cgram_address); |
| r21560 | r21561 | |
| 1806 | 1795 | static const UINT16 vram_fgr_shiftab[4] = { 0, 5, 6, 7 }; |
| 1807 | 1796 | |
| 1808 | 1797 | // utility function - latches the H/V counters. Used by IRQ, writes to WRIO, etc. |
| 1809 | | void snes_ppu_class::latch_counters( running_machine &machine, UINT8 *ram_ptr ) |
| 1798 | void snes_ppu_class::latch_counters( running_machine &machine ) |
| 1810 | 1799 | { |
| 1811 | 1800 | m_beam.current_horz = machine.primary_screen->hpos() / m_htmult; |
| 1812 | 1801 | m_beam.latch_vert = machine.primary_screen->vpos(); |
| 1813 | 1802 | m_beam.latch_horz = m_beam.current_horz; |
| 1814 | | ram_ptr[STAT78] |= 0x40; // indicate we latched |
| 1803 | m_stat78 |= 0x40; // indicate we latched |
| 1815 | 1804 | // m_read_ophct = m_read_opvct = 0; // clear read flags - 2009-08: I think we must clear these when STAT78 is read... |
| 1816 | 1805 | |
| 1817 | 1806 | // printf("latched @ H %d V %d\n", m_beam.latch_horz, m_beam.latch_vert); |
| 1818 | 1807 | } |
| 1819 | 1808 | |
| 1820 | | void snes_ppu_class::dynamic_res_change( running_machine &machine, UINT8 *ram_ptr ) |
| 1809 | void snes_ppu_class::dynamic_res_change( running_machine &machine ) |
| 1821 | 1810 | { |
| 1822 | 1811 | rectangle visarea = machine.primary_screen->visible_area(); |
| 1823 | 1812 | attoseconds_t refresh; |
| r21560 | r21561 | |
| 1833 | 1822 | m_htmult = 1; |
| 1834 | 1823 | |
| 1835 | 1824 | /* FIXME: does the timing changes when the gfx mode is equal to 5 or 6? */ |
| 1836 | | if ((ram_ptr[STAT78] & 0x10) == SNES_NTSC) |
| 1825 | if ((m_stat78 & 0x10) == SNES_NTSC) |
| 1826 | { |
| 1837 | 1827 | refresh = HZ_TO_ATTOSECONDS(DOTCLK_NTSC) * SNES_HTOTAL * SNES_VTOTAL_NTSC; |
| 1838 | | else |
| 1839 | | refresh = HZ_TO_ATTOSECONDS(DOTCLK_PAL) * SNES_HTOTAL * SNES_VTOTAL_PAL; |
| 1840 | | |
| 1841 | | if ((ram_ptr[STAT78] & 0x10) == SNES_NTSC) |
| 1842 | 1828 | machine.primary_screen->configure(SNES_HTOTAL * 2, SNES_VTOTAL_NTSC * m_interlace, visarea, refresh); |
| 1829 | } |
| 1843 | 1830 | else |
| 1831 | { |
| 1832 | refresh = HZ_TO_ATTOSECONDS(DOTCLK_PAL) * SNES_HTOTAL * SNES_VTOTAL_PAL; |
| 1844 | 1833 | machine.primary_screen->configure(SNES_HTOTAL * 2, SNES_VTOTAL_PAL * m_interlace, visarea, refresh); |
| 1834 | } |
| 1845 | 1835 | } |
| 1846 | 1836 | |
| 1847 | 1837 | /************************************************* |
| r21560 | r21561 | |
| 1885 | 1875 | { |
| 1886 | 1876 | UINT16 v = space.machine().primary_screen->vpos(); |
| 1887 | 1877 | UINT16 h = space.machine().primary_screen->hpos(); |
| 1888 | | UINT16 ls = (((snes_ram[STAT78] & 0x10) == SNES_NTSC ? 525 : 625) >> 1) - 1; |
| 1878 | UINT16 ls = (((m_stat78 & 0x10) == SNES_NTSC ? 525 : 625) >> 1) - 1; |
| 1889 | 1879 | |
| 1890 | 1880 | if (m_interlace == 2) |
| 1891 | 1881 | ls++; |
| r21560 | r21561 | |
| 2135 | 2125 | return m_ppu1_open_bus; |
| 2136 | 2126 | } |
| 2137 | 2127 | case SLHV: /* Software latch for H/V counter */ |
| 2138 | | latch_counters(space.machine(), ram_ptr); |
| 2128 | latch_counters(space.machine()); |
| 2139 | 2129 | return snes_open_bus_r(space, 0); /* Return value is meaningless */ |
| 2140 | 2130 | case ROAMDATA: /* Read data from OAM (DR) */ |
| 2141 | 2131 | m_ppu1_open_bus = oam_read(space, m_oam.address); |
| r21560 | r21561 | |
| 2213 | 2203 | m_read_opvct ^= 1; |
| 2214 | 2204 | return m_ppu2_open_bus; |
| 2215 | 2205 | case STAT77: /* PPU status flag and version number */ |
| 2216 | | value = m_stat77_flags & 0xc0; // 0x80 & 0x40 are Time Over / Range Over Sprite flags, set by the video code |
| 2206 | value = m_stat77 & 0xc0; // 0x80 & 0x40 are Time Over / Range Over Sprite flags, set by the video code |
| 2217 | 2207 | // 0x20 - Master/slave mode select. Little is known about this bit. We always seem to read back 0 here. |
| 2218 | 2208 | value |= (m_ppu1_open_bus & 0x10); |
| 2219 | 2209 | value |= (m_ppu1_version & 0x0f); |
| 2220 | | m_stat77_flags = value; // not sure if this is needed... |
| 2210 | m_stat77 = value; // not sure if this is needed... |
| 2221 | 2211 | m_ppu1_open_bus = value; |
| 2222 | 2212 | return m_ppu1_open_bus; |
| 2223 | 2213 | case STAT78: /* PPU status flag and version number */ |
| 2224 | 2214 | m_read_ophct = 0; |
| 2225 | 2215 | m_read_opvct = 0; |
| 2226 | 2216 | if(ram_ptr[WRIO] & 0x80) |
| 2227 | | ram_ptr[STAT78] &= ~0x40; //clear ext latch if bit 7 of WRIO is set |
| 2228 | | ram_ptr[STAT78] = (ram_ptr[STAT78] & ~0x2f) | (m_ppu2_open_bus & 0x20) | (m_ppu2_version & 0x0f); |
| 2229 | | m_ppu2_open_bus = ram_ptr[STAT78]; |
| 2217 | m_stat78 &= ~0x40; //clear ext latch if bit 7 of WRIO is set |
| 2218 | m_stat78 = (m_stat78 & ~0x2f) | (m_ppu2_open_bus & 0x20) | (m_ppu2_version & 0x0f); |
| 2219 | m_ppu2_open_bus = m_stat78; |
| 2230 | 2220 | return m_ppu2_open_bus; |
| 2231 | 2221 | } |
| 2232 | 2222 | |
| r21560 | r21561 | |
| 2295 | 2285 | return; |
| 2296 | 2286 | case BGMODE: /* BG mode and character size settings */ |
| 2297 | 2287 | m_mode = data & 0x07; |
| 2298 | | dynamic_res_change(space.machine(), ram_ptr); |
| 2288 | dynamic_res_change(space.machine()); |
| 2299 | 2289 | m_bg3_priority_bit = BIT(data, 3); |
| 2300 | 2290 | m_layer[SNES_BG1].tile_size = BIT(data, 4); |
| 2301 | 2291 | m_layer[SNES_BG2].tile_size = BIT(data, 5); |
| r21560 | r21561 | |
| 2468 | 2458 | m_cgram_address = (m_cgram_address + 1) % (SNES_CGRAM_SIZE - 2); |
| 2469 | 2459 | break; |
| 2470 | 2460 | case W12SEL: /* Window mask settings for BG1-2 */ |
| 2471 | | if (data != ram_ptr[offset]) |
| 2461 | if (data != ram_ptr[W12SEL]) |
| 2472 | 2462 | { |
| 2473 | 2463 | m_layer[SNES_BG1].window1_invert = BIT(data, 0); |
| 2474 | 2464 | m_layer[SNES_BG1].window1_enabled = BIT(data, 1); |
| r21560 | r21561 | |
| 2482 | 2472 | } |
| 2483 | 2473 | break; |
| 2484 | 2474 | case W34SEL: /* Window mask settings for BG3-4 */ |
| 2485 | | if (data != ram_ptr[offset]) |
| 2475 | if (data != ram_ptr[W34SEL]) |
| 2486 | 2476 | { |
| 2487 | 2477 | m_layer[SNES_BG3].window1_invert = BIT(data, 0); |
| 2488 | 2478 | m_layer[SNES_BG3].window1_enabled = BIT(data, 1); |
| r21560 | r21561 | |
| 2496 | 2486 | } |
| 2497 | 2487 | break; |
| 2498 | 2488 | case WOBJSEL: /* Window mask settings for objects */ |
| 2499 | | if (data != ram_ptr[offset]) |
| 2489 | if (data != ram_ptr[WOBJSEL]) |
| 2500 | 2490 | { |
| 2501 | 2491 | m_layer[SNES_OAM].window1_invert = BIT(data, 0); |
| 2502 | 2492 | m_layer[SNES_OAM].window1_enabled = BIT(data, 1); |
| r21560 | r21561 | |
| 2510 | 2500 | } |
| 2511 | 2501 | break; |
| 2512 | 2502 | case WH0: /* Window 1 left position */ |
| 2513 | | if (data != ram_ptr[offset]) |
| 2503 | if (data != ram_ptr[WH0]) |
| 2514 | 2504 | { |
| 2515 | 2505 | m_window1_left = data; |
| 2516 | 2506 | m_update_windows = 1; |
| 2517 | 2507 | } |
| 2518 | 2508 | break; |
| 2519 | 2509 | case WH1: /* Window 1 right position */ |
| 2520 | | if (data != ram_ptr[offset]) |
| 2510 | if (data != ram_ptr[WH1]) |
| 2521 | 2511 | { |
| 2522 | 2512 | m_window1_right = data; |
| 2523 | 2513 | m_update_windows = 1; |
| 2524 | 2514 | } |
| 2525 | 2515 | break; |
| 2526 | 2516 | case WH2: /* Window 2 left position */ |
| 2527 | | if (data != ram_ptr[offset]) |
| 2517 | if (data != ram_ptr[WH2]) |
| 2528 | 2518 | { |
| 2529 | 2519 | m_window2_left = data; |
| 2530 | 2520 | m_update_windows = 1; |
| 2531 | 2521 | } |
| 2532 | 2522 | break; |
| 2533 | 2523 | case WH3: /* Window 2 right position */ |
| 2534 | | if (data != ram_ptr[offset]) |
| 2524 | if (data != ram_ptr[WH3]) |
| 2535 | 2525 | { |
| 2536 | 2526 | m_window2_right = data; |
| 2537 | 2527 | m_update_windows = 1; |
| 2538 | 2528 | } |
| 2539 | 2529 | break; |
| 2540 | 2530 | case WBGLOG: /* Window mask logic for BG's */ |
| 2541 | | if (data != ram_ptr[offset]) |
| 2531 | if (data != ram_ptr[WBGLOG]) |
| 2542 | 2532 | { |
| 2543 | 2533 | m_layer[SNES_BG1].wlog_mask = data & 0x03; |
| 2544 | 2534 | m_layer[SNES_BG2].wlog_mask = (data & 0x0c) >> 2; |
| r21560 | r21561 | |
| 2548 | 2538 | } |
| 2549 | 2539 | break; |
| 2550 | 2540 | case WOBJLOG: /* Window mask logic for objects */ |
| 2551 | | if (data != ram_ptr[offset]) |
| 2541 | if (data != ram_ptr[WOBJLOG]) |
| 2552 | 2542 | { |
| 2553 | 2543 | m_layer[SNES_OAM].wlog_mask = data & 0x03; |
| 2554 | 2544 | m_layer[SNES_COLOR].wlog_mask = (data & 0x0c) >> 2; |
| r21560 | r21561 | |
| 2626 | 2616 | m_beam.last_visible_line = (data & 0x04) ? 240 : 225; |
| 2627 | 2617 | m_pseudo_hires = BIT(data, 3); |
| 2628 | 2618 | m_mode7.extbg = BIT(data, 6); |
| 2629 | | dynamic_res_change(space.machine(), ram_ptr); |
| 2619 | dynamic_res_change(space.machine()); |
| 2630 | 2620 | #ifdef SNES_DBG_REG_W |
| 2631 | 2621 | if ((data & 0x8) != (ram_ptr[SETINI] & 0x8)) |
| 2632 | 2622 | mame_printf_debug("Pseudo 512 mode: %s\n", (data & 0x8) ? "on" : "off"); |