trunk/src/mame/video/snes.c
| r17395 | r17396 | |
| 131 | 131 | }; |
| 132 | 132 | |
| 133 | 133 | static UINT8 *snes_vram; /* Video RAM (Should be 16-bit, but it's easier this way) */ |
| 134 | | static UINT16 *snes_cgram; /* Colour RAM */ |
| 135 | 134 | |
| 136 | 135 | /***************************************** |
| 137 | 136 | * snes_get_bgcolor() |
| r17395 | r17396 | |
| 150 | 149 | c |= ((palette & 0x04) >> 1) | ((palette & 0x08) << 3) | ((palette & 0x10) << 8); |
| 151 | 150 | } |
| 152 | 151 | else |
| 153 | | c = snes_cgram[(palette + color) % FIXED_COLOUR]; |
| 152 | c = m_snes_cgram[(palette + color) % FIXED_COLOUR]; |
| 154 | 153 | |
| 155 | 154 | return c; |
| 156 | 155 | } |
| r17395 | r17396 | |
| 289 | 288 | /* Only draw if we have a colour (0 == transparent) */ |
| 290 | 289 | if (clr) |
| 291 | 290 | { |
| 292 | | c = snes_cgram[(pal + clr) % FIXED_COLOUR]; |
| 291 | c = m_snes_cgram[(pal + clr) % FIXED_COLOUR]; |
| 293 | 292 | blend = (pal + clr < 192) ? 1 : 0; |
| 294 | 293 | snes_set_scanline_pixel(screen, pos, c, priority, SNES_OAM, blend); |
| 295 | 294 | } |
| r17395 | r17396 | |
| 1429 | 1428 | if (b > 0x1f) b = 0; |
| 1430 | 1429 | } |
| 1431 | 1430 | /* only halve if the color is not the back colour */ |
| 1432 | | if (BIT(snes_ppu.color_modes, 6) && (subscreen->buffer[offset] != snes_cgram[FIXED_COLOUR])) |
| 1431 | if (BIT(snes_ppu.color_modes, 6) && (subscreen->buffer[offset] != m_snes_cgram[FIXED_COLOUR])) |
| 1433 | 1432 | { |
| 1434 | 1433 | r >>= 1; |
| 1435 | 1434 | g >>= 1; |
| r17395 | r17396 | |
| 1441 | 1440 | if (!BIT(snes_ppu.color_modes, 7)) |
| 1442 | 1441 | { |
| 1443 | 1442 | /* 0x00 add */ |
| 1444 | | r = (*colour & 0x1f) + (snes_cgram[FIXED_COLOUR] & 0x1f); |
| 1445 | | g = ((*colour & 0x3e0) >> 5) + ((snes_cgram[FIXED_COLOUR] & 0x3e0) >> 5); |
| 1446 | | b = ((*colour & 0x7c00) >> 10) + ((snes_cgram[FIXED_COLOUR] & 0x7c00) >> 10); |
| 1443 | r = (*colour & 0x1f) + (m_snes_cgram[FIXED_COLOUR] & 0x1f); |
| 1444 | g = ((*colour & 0x3e0) >> 5) + ((m_snes_cgram[FIXED_COLOUR] & 0x3e0) >> 5); |
| 1445 | b = ((*colour & 0x7c00) >> 10) + ((m_snes_cgram[FIXED_COLOUR] & 0x7c00) >> 10); |
| 1447 | 1446 | clip_max = 1; |
| 1448 | 1447 | } |
| 1449 | 1448 | else |
| 1450 | 1449 | { |
| 1451 | 1450 | /* 0x80: sub */ |
| 1452 | | r = (*colour & 0x1f) - (snes_cgram[FIXED_COLOUR] & 0x1f); |
| 1453 | | g = ((*colour & 0x3e0) >> 5) - ((snes_cgram[FIXED_COLOUR] & 0x3e0) >> 5); |
| 1454 | | b = ((*colour & 0x7c00) >> 10) - ((snes_cgram[FIXED_COLOUR] & 0x7c00) >> 10); |
| 1451 | r = (*colour & 0x1f) - (m_snes_cgram[FIXED_COLOUR] & 0x1f); |
| 1452 | g = ((*colour & 0x3e0) >> 5) - ((m_snes_cgram[FIXED_COLOUR] & 0x3e0) >> 5); |
| 1453 | b = ((*colour & 0x7c00) >> 10) - ((m_snes_cgram[FIXED_COLOUR] & 0x7c00) >> 10); |
| 1455 | 1454 | if (r > 0x1f) r = 0; |
| 1456 | 1455 | if (g > 0x1f) g = 0; |
| 1457 | 1456 | if (b > 0x1f) b = 0; |
| r17395 | r17396 | |
| 1536 | 1535 | for (ii = 0; ii < SNES_SCR_WIDTH; ii++) |
| 1537 | 1536 | { |
| 1538 | 1537 | if (snes_ppu.mode == 5 || snes_ppu.mode == 6 || snes_ppu.pseudo_hires) |
| 1539 | | scanlines[SNES_SUBSCREEN].buffer[ii] = snes_cgram[0]; |
| 1538 | scanlines[SNES_SUBSCREEN].buffer[ii] = m_snes_cgram[0]; |
| 1540 | 1539 | else |
| 1541 | | scanlines[SNES_SUBSCREEN].buffer[ii] = snes_cgram[FIXED_COLOUR]; |
| 1540 | scanlines[SNES_SUBSCREEN].buffer[ii] = m_snes_cgram[FIXED_COLOUR]; |
| 1542 | 1541 | |
| 1543 | | scanlines[SNES_MAINSCREEN].buffer[ii] = snes_cgram[0]; |
| 1542 | scanlines[SNES_MAINSCREEN].buffer[ii] = m_snes_cgram[0]; |
| 1544 | 1543 | } |
| 1545 | 1544 | |
| 1546 | 1545 | /* Prepare OAM for this scanline */ |
| r17395 | r17396 | |
| 1665 | 1664 | #endif |
| 1666 | 1665 | |
| 1667 | 1666 | snes_vram = auto_alloc_array(machine, UINT8, SNES_VRAM_SIZE); |
| 1668 | | snes_cgram = auto_alloc_array(machine, UINT16, SNES_CGRAM_SIZE/2); |
| 1667 | state->m_snes_cgram = auto_alloc_array(machine, UINT16, SNES_CGRAM_SIZE/2); |
| 1669 | 1668 | state->m_snes_oam = auto_alloc_array(machine, UINT16, SNES_OAM_SIZE/2); |
| 1670 | 1669 | |
| 1671 | 1670 | /* Inititialize registers/variables */ |
| r17395 | r17396 | |
| 1689 | 1688 | /* Init VRAM */ |
| 1690 | 1689 | memset(snes_vram, 0, SNES_VRAM_SIZE); |
| 1691 | 1690 | |
| 1692 | | /* Init Colour RAM */ |
| 1693 | | memset((UINT8 *)snes_cgram, 0, SNES_CGRAM_SIZE); |
| 1691 | /* Init Character Graphics RAM */ |
| 1692 | memset((UINT8 *)state->m_snes_cgram, 0, SNES_CGRAM_SIZE); |
| 1694 | 1693 | |
| 1695 | 1694 | /* Init oam RAM */ |
| 1696 | 1695 | memset(state->m_snes_oam, 0xff, SNES_OAM_SIZE); |
| r17395 | r17396 | |
| 1784 | 1783 | state_save_register_global(machine, snes_ppu.stat77_flags); |
| 1785 | 1784 | |
| 1786 | 1785 | state_save_register_global_pointer(machine, snes_vram, SNES_VRAM_SIZE); |
| 1787 | | state_save_register_global_pointer(machine, snes_cgram, SNES_CGRAM_SIZE/2); |
| 1786 | state_save_register_global_pointer(machine, state->m_snes_cgram, SNES_CGRAM_SIZE/2); |
| 1788 | 1787 | state_save_register_global_pointer(machine, state->m_snes_oam, SNES_OAM_SIZE/2); |
| 1789 | 1788 | } |
| 1790 | 1789 | |
| r17395 | r17396 | |
| 2037 | 2036 | solution adopted by BSNES without enabling it. |
| 2038 | 2037 | *************************************************/ |
| 2039 | 2038 | |
| 2040 | | static READ8_HANDLER( snes_cgram_read ) |
| 2039 | READ8_MEMBER( snes_state::snes_cgram_read ) |
| 2041 | 2040 | { |
| 2042 | 2041 | UINT8 res = 0; |
| 2043 | 2042 | offset &= 0x1ff; |
| r17395 | r17396 | |
| 2053 | 2052 | } |
| 2054 | 2053 | #endif |
| 2055 | 2054 | |
| 2056 | | res = ((UINT8 *)snes_cgram)[offset]; |
| 2055 | res = ((UINT8 *)m_snes_cgram)[offset]; |
| 2057 | 2056 | |
| 2058 | 2057 | // CGRAM palette data format is 15-bits (0,bbbbb,ggggg,rrrrr). |
| 2059 | 2058 | // Highest bit is simply ignored. |
| r17395 | r17396 | |
| 2063 | 2062 | return res; |
| 2064 | 2063 | } |
| 2065 | 2064 | |
| 2066 | | static WRITE8_HANDLER( snes_cgram_write ) |
| 2065 | WRITE8_MEMBER( snes_state::snes_cgram_write ) |
| 2067 | 2066 | { |
| 2068 | 2067 | offset &= 0x1ff; |
| 2069 | 2068 | |
| r17395 | r17396 | |
| 2086 | 2085 | if (offset & 0x01) |
| 2087 | 2086 | data &= 0x7f; |
| 2088 | 2087 | |
| 2089 | | ((UINT8 *)snes_cgram)[offset] = data; |
| 2088 | ((UINT8 *)m_snes_cgram)[offset] = data; |
| 2090 | 2089 | } |
| 2091 | 2090 | |
| 2092 | 2091 | READ8_HANDLER( snes_ppu_read ) |
| r17395 | r17396 | |
| 2182 | 2181 | } |
| 2183 | 2182 | case RCGDATA: /* Read data from CGRAM */ |
| 2184 | 2183 | if (!(state->m_cgram_address & 0x01)) |
| 2185 | | snes_ppu.ppu2_open_bus = snes_cgram_read(space, state->m_cgram_address); |
| 2184 | snes_ppu.ppu2_open_bus = state->snes_cgram_read(*space, state->m_cgram_address); |
| 2186 | 2185 | else |
| 2187 | 2186 | { |
| 2188 | 2187 | snes_ppu.ppu2_open_bus &= 0x80; |
| 2189 | | snes_ppu.ppu2_open_bus |= snes_cgram_read(space, state->m_cgram_address) & 0x7f; |
| 2188 | snes_ppu.ppu2_open_bus |= state->snes_cgram_read(*space, state->m_cgram_address) & 0x7f; |
| 2190 | 2189 | } |
| 2191 | 2190 | |
| 2192 | 2191 | state->m_cgram_address = (state->m_cgram_address + 1) % (SNES_CGRAM_SIZE - 2); |
| r17395 | r17396 | |
| 2469 | 2468 | state->m_cgram_address = data << 1; |
| 2470 | 2469 | break; |
| 2471 | 2470 | case CGDATA: /* Data for colour RAM */ |
| 2472 | | snes_cgram_write(space, state->m_cgram_address, data); |
| 2471 | state->snes_cgram_write(*space, state->m_cgram_address, data); |
| 2473 | 2472 | state->m_cgram_address = (state->m_cgram_address + 1) % (SNES_CGRAM_SIZE - 2); |
| 2474 | 2473 | break; |
| 2475 | 2474 | case W12SEL: /* Window mask settings for BG1-2 */ |
| r17395 | r17396 | |
| 2613 | 2612 | UINT8 r, g, b; |
| 2614 | 2613 | |
| 2615 | 2614 | /* Get existing value. */ |
| 2616 | | r = snes_cgram[FIXED_COLOUR] & 0x1f; |
| 2617 | | g = (snes_cgram[FIXED_COLOUR] & 0x3e0) >> 5; |
| 2618 | | b = (snes_cgram[FIXED_COLOUR] & 0x7c00) >> 10; |
| 2615 | r = state->m_snes_cgram[FIXED_COLOUR] & 0x1f; |
| 2616 | g = (state->m_snes_cgram[FIXED_COLOUR] & 0x3e0) >> 5; |
| 2617 | b = (state->m_snes_cgram[FIXED_COLOUR] & 0x7c00) >> 10; |
| 2619 | 2618 | /* Set new value */ |
| 2620 | 2619 | if (data & 0x20) |
| 2621 | 2620 | r = data & 0x1f; |
| r17395 | r17396 | |
| 2623 | 2622 | g = data & 0x1f; |
| 2624 | 2623 | if (data & 0x80) |
| 2625 | 2624 | b = data & 0x1f; |
| 2626 | | snes_cgram[FIXED_COLOUR] = (r | (g << 5) | (b << 10)); |
| 2625 | state->m_snes_cgram[FIXED_COLOUR] = (r | (g << 5) | (b << 10)); |
| 2627 | 2626 | } break; |
| 2628 | 2627 | case SETINI: /* Screen mode/video select */ |
| 2629 | 2628 | snes_ppu.interlace = (data & 0x01) ? 2 : 1; |