summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/video/ppu2c0x.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/video/ppu2c0x.cpp')
-rw-r--r--src/devices/video/ppu2c0x.cpp110
1 files changed, 69 insertions, 41 deletions
diff --git a/src/devices/video/ppu2c0x.cpp b/src/devices/video/ppu2c0x.cpp
index dd895b469f1..39023752c8f 100644
--- a/src/devices/video/ppu2c0x.cpp
+++ b/src/devices/video/ppu2c0x.cpp
@@ -123,6 +123,8 @@ ppu2c0x_device::ppu2c0x_device(const machine_config& mconfig, device_type type,
m_space_config("videoram", ENDIANNESS_LITTLE, 8, 17, 0, internal_map),
m_cpu(*this, finder_base::DUMMY_TAG),
m_scanline(0), // reset the scanline count
+ m_videoram_addr_mask(0x3fff),
+ m_global_refresh_mask(0x7fff),
m_line_write_increment_large(32),
m_paletteram_in_ppuspace(false),
m_tile_page(0),
@@ -803,6 +805,65 @@ void ppu2c0x_device::read_extra_sprite_bits(int sprite_index)
// needed for some clones
}
+bool ppu2c0x_device::is_spritepixel_opaque(int pixel_data, int color)
+{
+ if (pixel_data)
+ return true;
+ else
+ return false;
+}
+
+void ppu2c0x_device::draw_sprite_pixel_low(bitmap_rgb32& bitmap, int pixel_data, int pixel, int sprite_xpos, int color, int sprite_index, uint8_t* line_priority)
+{
+ if (is_spritepixel_opaque(pixel_data, color))
+ {
+ /* has the background (or another sprite) already been drawn here? */
+ if ((sprite_xpos + pixel) < VISIBLE_SCREEN_WIDTH)
+ {
+ if (!line_priority[sprite_xpos + pixel])
+ {
+ /* no, draw */
+ draw_sprite_pixel(sprite_xpos, color, pixel, pixel_data, bitmap);
+ }
+ /* indicate that a sprite was drawn at this location, even if it's not seen */
+ line_priority[sprite_xpos + pixel] |= 0x01;
+ }
+ }
+
+ /* set the "sprite 0 hit" flag if appropriate */
+ if (sprite_index == 0 && (pixel_data & 0x03) && ((sprite_xpos + pixel) < 255) && (line_priority[sprite_xpos + pixel] & 0x02))
+ m_regs[PPU_STATUS] |= PPU_STATUS_SPRITE0_HIT;
+}
+
+void ppu2c0x_device::draw_sprite_pixel_high(bitmap_rgb32& bitmap, int pixel_data, int pixel, int sprite_xpos, int color, int sprite_index, uint8_t* line_priority)
+{
+ if (is_spritepixel_opaque(pixel_data, color))
+ {
+ if ((sprite_xpos + pixel) < VISIBLE_SCREEN_WIDTH)
+ {
+ /* has another sprite been drawn here? */
+ if (!(line_priority[sprite_xpos + pixel] & 0x01))
+ {
+ /* no, draw */
+ draw_sprite_pixel(sprite_xpos, color, pixel, pixel_data, bitmap);
+ line_priority[sprite_xpos + pixel] |= 0x01;
+ }
+ }
+ }
+
+ /* set the "sprite 0 hit" flag if appropriate */
+ if (sprite_index == 0 && (pixel_data & 0x03) && ((sprite_xpos + pixel) < 255) && (line_priority[sprite_xpos + pixel] & 0x02))
+ m_regs[PPU_STATUS] |= PPU_STATUS_SPRITE0_HIT;
+}
+
+int ppu2c0x_device::apply_sprite_pattern_page(int index1, int size)
+{
+ if (size == 8)
+ index1 += ((m_sprite_page == 0) ? 0 : 0x1000);
+
+ return index1;
+}
+
void ppu2c0x_device::draw_sprites(uint8_t* line_priority)
{
bitmap_rgb32& bitmap = *m_bitmap;
@@ -881,8 +942,8 @@ void ppu2c0x_device::draw_sprites(uint8_t* line_priority)
}
index1 = tile * 16;
- if (size == 8)
- index1 += ((m_sprite_page == 0) ? 0 : 0x1000);
+
+ index1 = apply_sprite_pattern_page(index1, size);
read_sprite_plane_data(index1 + sprite_line);
@@ -913,24 +974,7 @@ void ppu2c0x_device::draw_sprites(uint8_t* line_priority)
/* is this pixel non-transparent? */
if (sprite_xpos + pixel >= first_pixel)
{
- if (pixel_data)
- {
- /* has the background (or another sprite) already been drawn here? */
- if ((sprite_xpos + pixel) < VISIBLE_SCREEN_WIDTH)
- {
- if (!line_priority[sprite_xpos + pixel])
- {
- /* no, draw */
- draw_sprite_pixel(sprite_xpos, color, pixel, pixel_data, bitmap);
- }
- /* indicate that a sprite was drawn at this location, even if it's not seen */
- line_priority[sprite_xpos + pixel] |= 0x01;
- }
- }
-
- /* set the "sprite 0 hit" flag if appropriate */
- if (sprite_index == 0 && (pixel_data & 0x03) && ((sprite_xpos + pixel) < 255) && (line_priority[sprite_xpos + pixel] & 0x02))
- m_regs[PPU_STATUS] |= PPU_STATUS_SPRITE0_HIT;
+ draw_sprite_pixel_low(bitmap, pixel_data, pixel, sprite_xpos, color, sprite_index, line_priority);
}
}
}
@@ -945,23 +989,7 @@ void ppu2c0x_device::draw_sprites(uint8_t* line_priority)
/* is this pixel non-transparent? */
if (sprite_xpos + pixel >= first_pixel)
{
- if (pixel_data)
- {
- if ((sprite_xpos + pixel) < VISIBLE_SCREEN_WIDTH)
- {
- /* has another sprite been drawn here? */
- if (!(line_priority[sprite_xpos + pixel] & 0x01))
- {
- /* no, draw */
- draw_sprite_pixel(sprite_xpos, color, pixel, pixel_data, bitmap);
- line_priority[sprite_xpos + pixel] |= 0x01;
- }
- }
- }
-
- /* set the "sprite 0 hit" flag if appropriate */
- if (sprite_index == 0 && (pixel_data & 0x03) && ((sprite_xpos + pixel) < 255) && (line_priority[sprite_xpos + pixel] & 0x02))
- m_regs[PPU_STATUS] |= PPU_STATUS_SPRITE0_HIT;
+ draw_sprite_pixel_high(bitmap, pixel_data, pixel, sprite_xpos, color, sprite_index, line_priority);
}
}
}
@@ -1292,7 +1320,7 @@ void ppu2c0x_device::write(offs_t offset, uint8_t data)
else
{
/* first write */
- m_refresh_latch &= 0x7fe0;
+ m_refresh_latch &= (0xffe0 & m_global_refresh_mask);
m_refresh_latch |= (data & 0xf8) >> 3;
m_x_fine = data & 7;
@@ -1306,7 +1334,7 @@ void ppu2c0x_device::write(offs_t offset, uint8_t data)
if (m_toggle)
{
/* second write */
- m_refresh_latch &= 0x7f00;
+ m_refresh_latch &= (0xff00 & m_global_refresh_mask);
m_refresh_latch |= data;
m_refresh_data = m_refresh_latch;
@@ -1317,7 +1345,7 @@ void ppu2c0x_device::write(offs_t offset, uint8_t data)
{
/* first write */
m_refresh_latch &= 0x00ff;
- m_refresh_latch |= (data & 0x3f) << 8;
+ m_refresh_latch |= (data & (m_videoram_addr_mask >>8) ) << 8;
//logerror("vram addr write 1: %02x, %04x (scanline: %d)\n", data, m_refresh_latch, m_scanline);
}
@@ -1326,7 +1354,7 @@ void ppu2c0x_device::write(offs_t offset, uint8_t data)
case PPU_DATA: /* 7 */
{
- int tempAddr = m_videomem_addr & 0x3fff;
+ int tempAddr = m_videomem_addr & m_videoram_addr_mask;
if (!m_latch.isnull())
m_latch(tempAddr);