video/ppu2c0x*.cpp: Implemented device_palette_interface and cleaned up code: (#13491)

* Implement device_palette_interface for color palette functionality.
* Added some missing members to save states, and use fixed-size integer types for members that need to be saved.
* Moved many internal functions into protected: and private: sections.
* Use more appropriate integer types, made many local variables const.
This commit is contained in:
cam900 2025-04-09 05:33:43 +09:00 committed by GitHub
parent 689ed7c59d
commit 633e196e59
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 322 additions and 362 deletions

View File

@ -85,10 +85,11 @@ void ppu2c0x_device::device_config_complete()
m_latch.set(nullptr);
}
ppu2c0x_device::ppu2c0x_device(const machine_config& mconfig, device_type type, const char* tag, device_t* owner, uint32_t clock, address_map_constructor internal_map) :
ppu2c0x_device::ppu2c0x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor internal_map) :
device_t(mconfig, type, tag, owner, clock),
device_memory_interface(mconfig, *this),
device_video_interface(mconfig, *this),
device_palette_interface(mconfig, *this),
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
@ -100,7 +101,7 @@ ppu2c0x_device::ppu2c0x_device(const machine_config& mconfig, device_type type,
m_back_color(0),
m_refresh_data(0),
m_x_fine(0),
m_toggle(0),
m_toggle(false),
m_tilecount(0),
m_latch(*this),
m_scanline_callback_proc(*this),
@ -116,7 +117,7 @@ ppu2c0x_device::ppu2c0x_device(const machine_config& mconfig, device_type type,
m_scan_scale(1), // set the scan scale (this is for dual monitor vertical setups)
m_draw_phase(0)
{
for (auto& elem : m_regs)
for (auto &elem : m_regs)
elem = 0;
m_scanlines_per_frame = NTSC_SCANLINES_PER_FRAME;
@ -126,45 +127,45 @@ ppu2c0x_device::ppu2c0x_device(const machine_config& mconfig, device_type type,
m_security_value = 0;
}
ppu2c0x_device::ppu2c0x_device(const machine_config& mconfig, device_type type, const char* tag, device_t* owner, uint32_t clock) :
ppu2c0x_device::ppu2c0x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) :
ppu2c0x_device(mconfig, type, tag, owner, clock, address_map_constructor(FUNC(ppu2c0x_device::ppu2c0x), this))
{
m_paletteram_in_ppuspace = true;
}
ppu2c0x_rgb_device::ppu2c0x_rgb_device(const machine_config& mconfig, device_type type, const char* tag, device_t* owner, uint32_t clock) :
ppu2c0x_rgb_device::ppu2c0x_rgb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) :
ppu2c0x_device(mconfig, type, tag, owner, clock),
m_palette_data(*this, "palette")
{
}
// NTSC NES
ppu2c02_device::ppu2c02_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) :
ppu2c02_device::ppu2c02_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
ppu2c0x_device(mconfig, PPU_2C02, tag, owner, clock)
{
}
// Playchoice 10
ppu2c03b_device::ppu2c03b_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) :
ppu2c03b_device::ppu2c03b_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
ppu2c0x_rgb_device(mconfig, PPU_2C03B, tag, owner, clock)
{
}
// Vs. Unisystem
ppu2c04_device::ppu2c04_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) :
ppu2c04_device::ppu2c04_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
ppu2c0x_rgb_device(mconfig, PPU_2C04, tag, owner, clock)
{
}
// PAL NES
ppu2c07_device::ppu2c07_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) :
ppu2c07_device::ppu2c07_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
ppu2c0x_device(mconfig, PPU_2C07, tag, owner, clock)
{
m_scanlines_per_frame = PAL_SCANLINES_PER_FRAME;
}
// PAL clones
ppupalc_device::ppupalc_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) :
ppupalc_device::ppupalc_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
ppu2c0x_device(mconfig, PPU_PALC, tag, owner, clock)
{
m_scanlines_per_frame = PAL_SCANLINES_PER_FRAME;
@ -173,32 +174,32 @@ ppupalc_device::ppupalc_device(const machine_config& mconfig, const char* tag, d
// The PPU_2C05 variants have different protection value, set at device start, but otherwise are all the same...
// Vs. Unisystem (Ninja Jajamaru Kun)
ppu2c05_01_device::ppu2c05_01_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) :
ppu2c05_01_device::ppu2c05_01_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
ppu2c0x_rgb_device(mconfig, PPU_2C05_01, tag, owner, clock)
{
m_security_value = 0x1b; // game (jajamaru) doesn't seem to ever actually check it
}
// Vs. Unisystem (Mighty Bomb Jack)
ppu2c05_02_device::ppu2c05_02_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) :
ppu2c05_02_device::ppu2c05_02_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
ppu2c0x_rgb_device(mconfig, PPU_2C05_02, tag, owner, clock)
{
m_security_value = 0x3d;
}
// Vs. Unisystem (Gumshoe)
ppu2c05_03_device::ppu2c05_03_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) :
ppu2c05_03_device::ppu2c05_03_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
ppu2c0x_rgb_device(mconfig, PPU_2C05_03, tag, owner, clock)
{
m_security_value = 0x1c;
}
// Vs. Unisystem (Top Gun)
ppu2c05_04_device::ppu2c05_04_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) :
ppu2c05_04_device::ppu2c05_04_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
ppu2c0x_rgb_device(mconfig, PPU_2C05_04, tag, owner, clock)
{
m_security_value = 0x1b;
}
// Vs. Unisystem (Super Mario Bros. bootlegs)
ppu2c04_clone_device::ppu2c04_clone_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) :
ppu2c04_clone_device::ppu2c04_clone_device(const machine_config &mconfig, const char *tag, device_t* owner, u32 clock) :
ppu2c0x_device(mconfig, PPU_2C04C, tag, owner, clock),
m_palette_data(*this, "palette")
{
@ -206,7 +207,7 @@ ppu2c04_clone_device::ppu2c04_clone_device(const machine_config& mconfig, const
m_vblank_first_scanline = VBLANK_FIRST_SCANLINE_VS_CLONE;
// background and sprites are always enabled; monochrome and color emphasis aren't supported
m_regs[PPU_CONTROL1] = ~(PPU_CONTROL1_COLOR_EMPHASIS | PPU_CONTROL1_DISPLAY_MONO);
m_regs[PPU_CONTROL1] = u8(~(PPU_CONTROL1_COLOR_EMPHASIS | PPU_CONTROL1_DISPLAY_MONO));
}
//-------------------------------------------------
@ -226,8 +227,8 @@ void ppu2c0x_device::start_nopalram()
m_nmi_timer->adjust(attotime::never);
/* allocate a screen bitmap, videomem and spriteram, a dirtychar array and the monochromatic colortable */
m_bitmap = std::make_unique<bitmap_rgb32>(VISIBLE_SCREEN_WIDTH, VISIBLE_SCREEN_HEIGHT);
m_spriteram = make_unique_clear<uint8_t[]>(SPRITERAM_SIZE);
m_bitmap.allocate(VISIBLE_SCREEN_WIDTH, VISIBLE_SCREEN_HEIGHT);
m_spriteram = make_unique_clear<u8[]>(SPRITERAM_SIZE);
init_palette_tables();
@ -252,7 +253,7 @@ void ppu2c0x_device::start_nopalram()
save_item(NAME(m_tilecount));
save_pointer(NAME(m_spriteram), SPRITERAM_SIZE);
save_item(NAME(*m_bitmap));
save_item(NAME(m_bitmap));
}
void ppu2c0x_device::device_start()
@ -280,7 +281,7 @@ void ppu2c04_clone_device::device_start()
also generally affects PPU-side read timings involving the OAM, but
this still doesn't seem to matter for Vs. SMB specifically)
*/
m_spritebuf = make_unique_clear<uint8_t[]>(SPRITERAM_SIZE);
m_spritebuf = make_unique_clear<u8[]>(SPRITERAM_SIZE);
save_pointer(NAME(m_spritebuf), SPRITERAM_SIZE);
}
@ -292,7 +293,7 @@ void ppu2c04_clone_device::device_start()
// readbyte - read a byte at the given address
//-------------------------------------------------
uint8_t ppu2c0x_device::readbyte(offs_t address)
u8 ppu2c0x_device::readbyte(offs_t address)
{
return space().read_byte(address);
}
@ -302,15 +303,15 @@ uint8_t ppu2c0x_device::readbyte(offs_t address)
// writebyte - write a byte at the given address
//-------------------------------------------------
inline void ppu2c0x_device::writebyte(offs_t address, uint8_t data)
inline void ppu2c0x_device::writebyte(offs_t address, u8 data)
{
space().write_byte(address, data);
}
inline uint16_t ppu2c0x_device::apply_grayscale_and_emphasis(uint8_t color)
inline u16 ppu2c0x_device::apply_grayscale_and_emphasis(u8 color)
{
uint16_t palval = color;
u16 palval = color;
palval &= (m_regs[PPU_CONTROL1] & PPU_CONTROL1_DISPLAY_MONO) ? 0x30 : 0x3f;
palval |= (m_regs[PPU_CONTROL1] & PPU_CONTROL1_COLOR_EMPHASIS) << 1;
@ -413,7 +414,7 @@ rgb_t ppu2c0x_device::nespal_to_RGB(int color_intensity, int color_num, int colo
void ppu2c0x_device::init_palette_tables()
{
bool is_pal = m_scanlines_per_frame != NTSC_SCANLINES_PER_FRAME;
const bool is_pal = m_scanlines_per_frame != NTSC_SCANLINES_PER_FRAME;
/* This routine builds a palette using a transformation from */
/* the YUV (Y, B-Y, R-Y) to the RGB color space */
@ -433,9 +434,9 @@ void ppu2c0x_device::init_palette_tables()
/* loop through the 16 colors */
for (int color_num = 0; color_num < 16; color_num++)
{
rgb_t col = nespal_to_RGB(color_intensity, color_num, color_emphasis, is_pal);
const rgb_t col = nespal_to_RGB(color_intensity, color_num, color_emphasis, is_pal);
m_nespens[entry] = (uint32_t)col;
set_pen_color(entry, col);
entry++;
}
@ -451,11 +452,11 @@ void ppu2c0x_rgb_device::init_palette_tables()
{
for (int color_num = 0; color_num < 64; color_num++)
{
int R = ((color_emphasis & 1) ? 7 : m_palette_data[color_num * 3]);
int G = ((color_emphasis & 2) ? 7 : m_palette_data[color_num * 3 + 1]);
int B = ((color_emphasis & 4) ? 7 : m_palette_data[color_num * 3 + 2]);
const int R = ((color_emphasis & 1) ? 7 : m_palette_data[color_num * 3]);
const int G = ((color_emphasis & 2) ? 7 : m_palette_data[color_num * 3 + 1]);
const int B = ((color_emphasis & 4) ? 7 : m_palette_data[color_num * 3 + 2]);
m_nespens[entry] = (pal3bit(R)<<16) | (pal3bit(G)<<8) | pal3bit(B);
set_pen_color(entry, rgb_t(pal3bit(R), pal3bit(G), pal3bit(B)));
//set_pen_color(entry++, pal3bit(R), pal3bit(G), pal3bit(B));
entry++;
@ -472,12 +473,12 @@ void ppu2c04_clone_device::init_palette_tables()
for (int color_num = 0; color_num < 64*2; color_num++)
{
/* A7 line on palette ROMs is always high, color bits are in reverse order */
u8 color = m_palette_data[color_num | 0x80];
int R = bitswap<3>(color, 0, 1, 2);
int G = bitswap<3>(color, 3, 4, 5);
int B = bitswap<2>(color, 6, 7);
const u8 color = m_palette_data[color_num | 0x80];
const int R = bitswap<3>(color, 0, 1, 2);
const int G = bitswap<3>(color, 3, 4, 5);
const int B = bitswap<2>(color, 6, 7);
m_nespens[color_num] = (pal3bit(R) << 16) | (pal3bit(G) << 8) | pal2bit(B);
set_pen_color(color_num, rgb_t(pal3bit(R), pal3bit(G), pal2bit(B)));
}
}
@ -493,8 +494,8 @@ void ppu2c04_clone_device::init_palette_tables()
TIMER_CALLBACK_MEMBER(ppu2c0x_device::hblank_tick)
{
bool blanked = (m_regs[PPU_CONTROL1] & (PPU_CONTROL1_BACKGROUND | PPU_CONTROL1_SPRITES)) == 0;
bool vblank = (m_scanline >= m_vblank_first_scanline - 1) && (m_scanline < m_scanlines_per_frame - 1);
const bool blanked = (m_regs[PPU_CONTROL1] & (PPU_CONTROL1_BACKGROUND | PPU_CONTROL1_SPRITES)) == 0;
const bool vblank = (m_scanline >= m_vblank_first_scanline - 1) && (m_scanline < m_scanlines_per_frame - 1);
//update_scanline();
@ -515,8 +516,8 @@ TIMER_CALLBACK_MEMBER(ppu2c0x_device::nmi_tick)
TIMER_CALLBACK_MEMBER(ppu2c0x_device::scanline_tick)
{
bool blanked = (m_regs[PPU_CONTROL1] & (PPU_CONTROL1_BACKGROUND | PPU_CONTROL1_SPRITES)) == 0;
bool vblank = ((m_scanline >= m_vblank_first_scanline - 1) && (m_scanline < m_scanlines_per_frame - 1)) ? 1 : 0;
const bool blanked = (m_regs[PPU_CONTROL1] & (PPU_CONTROL1_BACKGROUND | PPU_CONTROL1_SPRITES)) == 0;
const bool vblank = ((m_scanline >= m_vblank_first_scanline - 1) && (m_scanline < m_scanlines_per_frame - 1)) ? 1 : 0;
/* if a callback is available, call it */
if (!m_scanline_callback_proc.isnull())
@ -585,30 +586,30 @@ void ppu2c0x_device::read_tile_plane_data(int address, int color)
m_planebuf[1] = readbyte((address + 8) & 0x1fff);
}
void ppu2c0x_device::shift_tile_plane_data(uint8_t& pix)
void ppu2c0x_device::shift_tile_plane_data(u8& pix)
{
pix = BIT(m_planebuf[0], 7) | (BIT(m_planebuf[1], 7) << 1);
m_planebuf[0] <<= 1;
m_planebuf[1] <<= 1;
}
void ppu2c0x_device::draw_tile_pixel(uint8_t pix, int color, uint32_t back_pen, uint32_t*& dest)
void ppu2c0x_device::draw_tile_pixel(u8 pix, int color, u32 back_pen, u32*& dest)
{
uint16_t palval = pix ? m_palette_ram[((4 * color) + pix) & 0x1f] : back_pen;
const u16 palval = pix ? m_palette_ram[((4 * color) + pix) & 0x1f] : back_pen;
*dest = m_nespens[apply_grayscale_and_emphasis(palval)];
*dest = pen_color(apply_grayscale_and_emphasis(palval));
}
void ppu2c0x_device::draw_tile(uint8_t* line_priority, int color_byte, int color_bits, int address, int start_x, uint32_t back_pen, uint32_t*& dest)
void ppu2c0x_device::draw_tile(u8* line_priority, int color_byte, int color_bits, int address, int start_x, u32 back_pen, u32*& dest)
{
int color = (color_byte >> color_bits) & 0x03;
const int color = (color_byte >> color_bits) & 0x03;
read_tile_plane_data(address, color);
/* render the pixel */
for (int i = 0; i < 8; i++)
{
uint8_t pix;
u8 pix;
shift_tile_plane_data(pix);
if ((start_x + i) >= 0 && (start_x + i) < VISIBLE_SCREEN_WIDTH)
@ -628,16 +629,14 @@ void ppu2c0x_device::draw_tile(uint8_t* line_priority, int color_byte, int color
// making raster effects more complex than on other systems
// https://retrocomputing.stackexchange.com/questions/1898/how-can-i-create-a-split-scroll-effect-in-an-nes-game
void ppu2c0x_device::draw_background(uint8_t* line_priority)
void ppu2c0x_device::draw_background(u8* line_priority)
{
bitmap_rgb32& bitmap = *m_bitmap;
/* determine where in the nametable to start drawing from */
/* based on the current scanline and scroll regs */
uint8_t scroll_x_coarse = m_refresh_data & 0x001f;
uint8_t scroll_y_coarse = (m_refresh_data & 0x03e0) >> 5;
uint16_t nametable = m_refresh_data & 0x0c00;
uint8_t scroll_y_fine = (m_refresh_data & 0x7000) >> 12;
const u8 scroll_x_coarse = m_refresh_data & 0x001f;
const u8 scroll_y_coarse = (m_refresh_data & 0x03e0) >> 5;
const u16 nametable = m_refresh_data & 0x0c00;
const u8 scroll_y_fine = (m_refresh_data & 0x7000) >> 12;
int x = scroll_x_coarse;
@ -646,33 +645,27 @@ void ppu2c0x_device::draw_background(uint8_t* line_priority)
/* set up dest */
int start_x = (m_x_fine ^ 0x07) - 7;
uint32_t* dest = &bitmap.pix(m_scanline, start_x);
u32* dest = &m_bitmap.pix(m_scanline, start_x);
m_tilecount = 0;
/* draw the 32 or 33 tiles that make up a line */
while (m_tilecount < 34)
{
int color_byte;
int color_bits;
int pos;
int index1;
int page, page2, address;
index1 = tile_index + x;
const int index1 = tile_index + x;
// page2 is the output of the nametable read (this section is the FIRST read per tile!)
page2 = readbyte(index1);
const int page2 = readbyte(index1);
// this is attribute table stuff! (actually read 2 in PPUspeak)!
/* Figure out which byte in the color table to use */
pos = ((index1 & 0x380) >> 4) | ((index1 & 0x1f) >> 2);
page = (index1 & 0x0c00) >> 10;
address = 0x3c0 + pos;
color_byte = readbyte((((page * 0x400) + address) & 0xfff) + 0x2000);
const int pos = ((index1 & 0x380) >> 4) | ((index1 & 0x1f) >> 2);
const int page = (index1 & 0x0c00) >> 10;
int address = 0x3c0 + pos;
const int color_byte = readbyte((((page * 0x400) + address) & 0xfff) + 0x2000);
/* figure out which bits in the color table to use */
color_bits = ((index1 & 0x40) >> 4) + (index1 & 0x02);
const int color_bits = ((index1 & 0x40) >> 4) + (index1 & 0x02);
// 27/12/2002
if (!m_latch.isnull())
@ -681,7 +674,7 @@ void ppu2c0x_device::draw_background(uint8_t* line_priority)
if (start_x < VISIBLE_SCREEN_WIDTH)
{
// need to read 0x0000 or 0x1000 + 16*nametable data
address = ((m_tile_page) ? 0x1000 : 0) + (page2 * 16);
address = (m_tile_page ? 0x1000 : 0) + (page2 * 16);
// plus something that accounts for y
address += scroll_y_fine;
@ -703,7 +696,7 @@ void ppu2c0x_device::draw_background(uint8_t* line_priority)
/* if the left 8 pixels for the background are off, blank 'em */
if (!(m_regs[PPU_CONTROL1] & PPU_CONTROL1_BACKGROUND_L8))
{
dest = &bitmap.pix(m_scanline);
dest = &m_bitmap.pix(m_scanline);
for (int i = 0; i < 8; i++)
{
draw_back_pen(dest, m_back_color);
@ -714,7 +707,7 @@ void ppu2c0x_device::draw_background(uint8_t* line_priority)
}
}
void ppu2c04_clone_device::draw_background(uint8_t* line_priority)
void ppu2c04_clone_device::draw_background(u8* line_priority)
{
// nametable selection is ignored below the hardwired scroll split position
if (m_scanline < 31)
@ -723,18 +716,16 @@ void ppu2c04_clone_device::draw_background(uint8_t* line_priority)
ppu2c0x_device::draw_background(line_priority);
}
void ppu2c0x_device::draw_back_pen(uint32_t* dest, int back_pen)
void ppu2c0x_device::draw_back_pen(u32* dest, int back_pen)
{
*dest = m_nespens[apply_grayscale_and_emphasis(back_pen)];
*dest = pen_color(apply_grayscale_and_emphasis(back_pen));
}
void ppu2c0x_device::draw_background_pen()
{
bitmap_rgb32& bitmap = *m_bitmap;
// Fill this scanline with the background pen.
for (int i = 0; i < bitmap.width(); i++)
draw_back_pen(&bitmap.pix(m_scanline, i), m_back_color);
for (int i = 0; i < m_bitmap.width(); i++)
draw_back_pen(&m_bitmap.pix(m_scanline, i), m_back_color);
}
void ppu2c0x_device::read_sprite_plane_data(int address)
@ -743,7 +734,7 @@ void ppu2c0x_device::read_sprite_plane_data(int address)
m_planebuf[1] = readbyte((address + 8) & 0x1fff);
}
void ppu2c0x_device::make_sprite_pixel_data(uint8_t& pixel_data, int flipx)
void ppu2c0x_device::make_sprite_pixel_data(u8 &pixel_data, bool flipx)
{
if (flipx)
{
@ -759,23 +750,20 @@ void ppu2c0x_device::make_sprite_pixel_data(uint8_t& pixel_data, int flipx)
}
}
void ppu2c0x_device::draw_sprite_pixel(int sprite_xpos, int color, int pixel, uint8_t pixel_data, bitmap_rgb32& bitmap)
void ppu2c0x_device::draw_sprite_pixel(int sprite_xpos, int color, int pixel, u8 pixel_data, bitmap_rgb32 &bitmap)
{
uint16_t palval = m_palette_ram[((4 * color) | pixel_data) & 0x1f];
uint32_t pix = m_nespens[apply_grayscale_and_emphasis(palval)];
bitmap.pix(m_scanline, sprite_xpos + pixel) = pix;
const u16 palval = m_palette_ram[((4 * color) | pixel_data) & 0x1f];
bitmap.pix(m_scanline, sprite_xpos + pixel) = pen_color(apply_grayscale_and_emphasis(palval));
}
void ppu2c04_clone_device::draw_sprite_pixel(int sprite_xpos, int color, int pixel, uint8_t pixel_data, bitmap_rgb32 &bitmap)
void ppu2c04_clone_device::draw_sprite_pixel(int sprite_xpos, int color, int pixel, u8 pixel_data, bitmap_rgb32 &bitmap)
{
/* clone PPU clips sprites at the screen edges */
if ((sprite_xpos + pixel < 8) || (sprite_xpos + pixel) >= (VISIBLE_SCREEN_WIDTH - 6))
return;
uint16_t palval = m_palette_ram[((4 * color) | pixel_data) & 0x1f];
uint32_t pix = m_nespens[palval | 0x40];
bitmap.pix(m_scanline, sprite_xpos + pixel) = pix;
const u16 palval = m_palette_ram[((4 * color) | pixel_data) & 0x1f];
bitmap.pix(m_scanline, sprite_xpos + pixel) = pen_color(palval | 0x40);
}
void ppu2c0x_device::read_extra_sprite_bits(int sprite_index)
@ -791,7 +779,7 @@ bool ppu2c0x_device::is_spritepixel_opaque(int pixel_data, int color)
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)
void ppu2c0x_device::draw_sprite_pixel_low(bitmap_rgb32 &bitmap, int pixel_data, int pixel, int sprite_xpos, int color, int sprite_index, u8 *line_priority)
{
if (is_spritepixel_opaque(pixel_data, color))
{
@ -813,14 +801,14 @@ void ppu2c0x_device::draw_sprite_pixel_low(bitmap_rgb32& bitmap, int pixel_data,
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)
void ppu2c0x_device::draw_sprite_pixel_high(bitmap_rgb32 &bitmap, int pixel_data, int pixel, int sprite_xpos, int color, int sprite_index, u8 *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))
if (BIT(~line_priority[sprite_xpos + pixel], 0))
{
/* no, draw */
draw_sprite_pixel(sprite_xpos, color, pixel, pixel_data, bitmap);
@ -842,31 +830,19 @@ int ppu2c0x_device::apply_sprite_pattern_page(int index1, int size)
return index1;
}
void ppu2c0x_device::draw_sprites(uint8_t* line_priority)
void ppu2c0x_device::draw_sprites(u8 *line_priority)
{
bitmap_rgb32& bitmap = *m_bitmap;
int sprite_xpos, sprite_ypos, sprite_index;
int tile, index1;
int pri;
int flipx, flipy, color;
int size;
int sprite_count = 0;
int sprite_line;
int first_pixel;
int pixel;
/* determine if the sprites are 8x8 or 8x16 */
size = (m_regs[PPU_CONTROL0] & PPU_CONTROL0_SPRITE_SIZE) ? 16 : 8;
int size = (m_regs[PPU_CONTROL0] & PPU_CONTROL0_SPRITE_SIZE) ? 16 : 8;
first_pixel = (m_regs[PPU_CONTROL1] & PPU_CONTROL1_SPRITES_L8) ? 0 : 8;
int first_pixel = (m_regs[PPU_CONTROL1] & PPU_CONTROL1_SPRITES_L8) ? 0 : 8;
for (sprite_index = 0; sprite_index < SPRITERAM_SIZE; sprite_index += 4)
for (int sprite_index = 0; sprite_index < SPRITERAM_SIZE; sprite_index += 4)
{
sprite_ypos = m_spriteram[sprite_index] + 1;
sprite_xpos = m_spriteram[sprite_index + 3];
int sprite_ypos = m_spriteram[sprite_index] + 1;
int sprite_xpos = m_spriteram[sprite_index + 3];
// The sprite collision acts funny on the last pixel of a scanline.
// The various scanline latches update while the last few pixels
@ -887,17 +863,17 @@ void ppu2c0x_device::draw_sprites(uint8_t* line_priority)
if ((sprite_ypos + size <= m_scanline) || (sprite_ypos > m_scanline))
continue;
tile = m_spriteram[sprite_index + 1];
color = (m_spriteram[sprite_index + 2] & 0x03) + 4;
pri = m_spriteram[sprite_index + 2] & 0x20;
flipx = m_spriteram[sprite_index + 2] & 0x40;
flipy = m_spriteram[sprite_index + 2] & 0x80;
int tile = m_spriteram[sprite_index + 1];
const int color = (m_spriteram[sprite_index + 2] & 0x03) + 4;
const bool pri = BIT(m_spriteram[sprite_index + 2], 5);
const bool flipx = BIT(m_spriteram[sprite_index + 2], 6);
const bool flipy = BIT(m_spriteram[sprite_index + 2], 7);
read_extra_sprite_bits(sprite_index);
if (size == 16)
{
/* if it's 8x16 and odd-numbered, draw the other half instead */
if (tile & 0x01)
if (BIT(tile, 0))
{
tile &= ~0x01;
tile |= 0x100;
@ -908,7 +884,7 @@ void ppu2c0x_device::draw_sprites(uint8_t* line_priority)
m_latch((m_sprite_page << 10) | ((tile & 0xff) << 4));
/* compute the character's line to draw */
sprite_line = m_scanline - sprite_ypos;
int sprite_line = m_scanline - sprite_ypos;
if (flipy)
sprite_line = (size - 1) - sprite_line;
@ -919,7 +895,7 @@ void ppu2c0x_device::draw_sprites(uint8_t* line_priority)
sprite_line -= 8;
}
index1 = tile * 16;
int index1 = tile * 16;
index1 = apply_sprite_pattern_page(index1, size);
@ -944,37 +920,37 @@ void ppu2c0x_device::draw_sprites(uint8_t* line_priority)
if (pri)
{
/* draw the low-priority sprites */
for (pixel = 0; pixel < 8; pixel++)
for (int pixel = 0; pixel < 8; pixel++)
{
uint8_t pixel_data;
u8 pixel_data;
make_sprite_pixel_data(pixel_data, flipx);
/* is this pixel non-transparent? */
if (sprite_xpos + pixel >= first_pixel)
{
draw_sprite_pixel_low(bitmap, pixel_data, pixel, sprite_xpos, color, sprite_index, line_priority);
draw_sprite_pixel_low(m_bitmap, pixel_data, pixel, sprite_xpos, color, sprite_index, line_priority);
}
}
}
else
{
/* draw the high-priority sprites */
for (pixel = 0; pixel < 8; pixel++)
for (int pixel = 0; pixel < 8; pixel++)
{
uint8_t pixel_data;
u8 pixel_data;
make_sprite_pixel_data(pixel_data, flipx);
/* is this pixel non-transparent? */
if (sprite_xpos + pixel >= first_pixel)
{
draw_sprite_pixel_high(bitmap, pixel_data, pixel, sprite_xpos, color, sprite_index, line_priority);
draw_sprite_pixel_high(m_bitmap, pixel_data, pixel, sprite_xpos, color, sprite_index, line_priority);
}
}
}
}
}
void ppu2c04_clone_device::draw_sprites(uint8_t *line_priority)
void ppu2c04_clone_device::draw_sprites(u8 *line_priority)
{
ppu2c0x_device::draw_sprites(line_priority);
@ -995,7 +971,7 @@ void ppu2c04_clone_device::draw_sprites(uint8_t *line_priority)
void ppu2c0x_device::render_scanline()
{
uint8_t line_priority[VISIBLE_SCREEN_WIDTH];
u8 line_priority[VISIBLE_SCREEN_WIDTH];
// lets see how long it takes
auto profile = g_profiler.start(PROFILER_USER1);
@ -1027,8 +1003,7 @@ void ppu2c0x_device::scanline_increment_fine_ycounter()
/* if it's rolled, increment the coarse y-scroll */
if (m_refresh_data & 0x8000)
{
uint16_t tmp;
tmp = (m_refresh_data & 0x03e0) + 0x20;
const u16 tmp = (m_refresh_data & 0x03e0) + 0x20;
m_refresh_data &= 0x7c1f;
/* handle bizarro scrolling rollover at the 30th (not 32nd) vertical tile */
@ -1057,8 +1032,7 @@ void ppu2c0x_device::update_visible_enabled_scanline()
void ppu2c0x_device::update_visible_disabled_scanline()
{
bitmap_rgb32& bitmap = *m_bitmap;
uint32_t back_pen = m_back_color;
u32 back_pen = m_back_color;
if (m_paletteram_in_ppuspace)
{
@ -1075,8 +1049,8 @@ void ppu2c0x_device::update_visible_disabled_scanline()
}
// Fill this scanline with the background pen.
for (int i = 0; i < bitmap.width(); i++)
draw_back_pen(&bitmap.pix(m_scanline, i), back_pen);
for (int i = 0; i < m_bitmap.width(); i++)
draw_back_pen(&m_bitmap.pix(m_scanline, i), back_pen);
}
void ppu2c0x_device::update_visible_scanline()
@ -1111,7 +1085,7 @@ void ppu2c0x_device::update_scanline()
*
*************************************/
void ppu2c0x_device::palette_write(offs_t offset, uint8_t data)
void ppu2c0x_device::palette_write(offs_t offset, u8 data)
{
// palette RAM is only 6 bits wide
data &= 0x3f;
@ -1132,7 +1106,7 @@ void ppu2c0x_device::palette_write(offs_t offset, uint8_t data)
}
}
uint8_t ppu2c0x_device::palette_read(offs_t offset)
u8 ppu2c0x_device::palette_read(offs_t offset)
{
if (m_regs[PPU_CONTROL1] & PPU_CONTROL1_DISPLAY_MONO)
return m_palette_ram[offset & 0x1f] & 0x30;
@ -1146,7 +1120,7 @@ uint8_t ppu2c0x_device::palette_read(offs_t offset)
*
*************************************/
uint8_t ppu2c0x_device::read(offs_t offset)
u8 ppu2c0x_device::read(offs_t offset)
{
if (offset >= PPU_MAX_REG)
{
@ -1166,7 +1140,7 @@ uint8_t ppu2c0x_device::read(offs_t offset)
m_data_latch = m_regs[PPU_STATUS] | (m_data_latch & 0x1f);
// Reset hi/lo scroll toggle
m_toggle = 0;
m_toggle = false;
// If the vblank bit is set, clear all status bits but the 2 sprite flags
if (m_data_latch & PPU_STATUS_VBLANK)
@ -1203,7 +1177,7 @@ uint8_t ppu2c0x_device::read(offs_t offset)
return m_data_latch;
}
uint8_t ppu2c04_clone_device::read(offs_t offset)
u8 ppu2c04_clone_device::read(offs_t offset)
{
switch (offset & 7)
{
@ -1227,7 +1201,7 @@ uint8_t ppu2c04_clone_device::read(offs_t offset)
*
*************************************/
void ppu2c0x_device::write(offs_t offset, uint8_t data)
void ppu2c0x_device::write(offs_t offset, u8 data)
{
if (offset >= PPU_MAX_REG)
{
@ -1301,7 +1275,7 @@ void ppu2c0x_device::write(offs_t offset, uint8_t data)
//logerror("scroll write 1: %d, %04x (scanline: %d)\n", data, m_refresh_latch, m_scanline);
}
m_toggle ^= 1;
m_toggle = !m_toggle;
break;
case PPU_ADDRESS: /* 6 */
@ -1323,12 +1297,12 @@ void ppu2c0x_device::write(offs_t offset, uint8_t data)
//logerror("vram addr write 1: %02x, %04x (scanline: %d)\n", data, m_refresh_latch, m_scanline);
}
m_toggle ^= 1;
m_toggle = !m_toggle;
break;
case PPU_DATA: /* 7 */
{
int tempAddr = m_videomem_addr & m_videoram_addr_mask;
const int tempAddr = m_videomem_addr & m_videoram_addr_mask;
if (!m_latch.isnull())
m_latch(tempAddr);
@ -1360,7 +1334,7 @@ void ppu2c0x_device::write(offs_t offset, uint8_t data)
m_data_latch = data;
}
void ppu2c04_clone_device::write(offs_t offset, uint8_t data)
void ppu2c04_clone_device::write(offs_t offset, u8 data)
{
switch (offset & 7)
{
@ -1396,19 +1370,19 @@ void ppu2c04_clone_device::write(offs_t offset, uint8_t data)
set_vram_dest((get_vram_dest() & 0x00ff) | (data << 8));
}
m_toggle ^= 1;
m_toggle = !m_toggle;
return;
}
ppu2c0x_device::write(offset, data);
}
uint16_t ppu2c0x_device::get_vram_dest()
u16 ppu2c0x_device::get_vram_dest()
{
return m_videomem_addr;
}
void ppu2c0x_device::set_vram_dest(uint16_t dest)
void ppu2c0x_device::set_vram_dest(u16 dest)
{
m_videomem_addr = dest;
}
@ -1419,13 +1393,13 @@ void ppu2c0x_device::set_vram_dest(uint16_t dest)
*
*************************************/
void ppu2c0x_device::spriteram_dma(address_space& space, const uint8_t page)
void ppu2c0x_device::spriteram_dma(address_space& space, const u8 page)
{
int address = page << 8;
const int address = page << 8;
for (int i = 0; i < SPRITERAM_SIZE; i++)
{
uint8_t spriteData = space.read_byte(address + i);
const u8 spriteData = space.read_byte(address + i);
space.write_byte(0x2004, spriteData);
}
@ -1439,17 +1413,17 @@ void ppu2c0x_device::spriteram_dma(address_space& space, const uint8_t page)
*
*************************************/
void ppu2c0x_device::render(bitmap_rgb32& bitmap, int flipx, int flipy, int sx, int sy, const rectangle& cliprect)
void ppu2c0x_device::render(bitmap_rgb32& bitmap, bool flipx, bool flipy, int sx, int sy, const rectangle& cliprect)
{
if (m_scanline_timer->remaining() != attotime::zero)
{
// Partial line update, need to render first (especially for light gun emulation).
update_scanline();
}
copybitmap(bitmap, *m_bitmap, flipx, flipy, sx, sy, cliprect);
copybitmap(bitmap, m_bitmap, flipx, flipy, sx, sy, cliprect);
}
uint32_t ppu2c0x_device::screen_update(screen_device& screen, bitmap_rgb32& bitmap, const rectangle& cliprect)
u32 ppu2c0x_device::screen_update(screen_device& screen, bitmap_rgb32& bitmap, const rectangle& cliprect)
{
render(bitmap, 0, 0, 0, 0, cliprect);
return 0;

View File

@ -42,7 +42,8 @@
class ppu2c0x_device : public device_t,
public device_memory_interface,
public device_video_interface
public device_video_interface,
public device_palette_interface
{
public:
typedef device_delegate<void (int scanline, bool vblank, bool blanked)> scanline_delegate;
@ -69,47 +70,17 @@ public:
// are non-rendering and non-vblank.
};
virtual uint8_t read(offs_t offset);
virtual void write(offs_t offset, uint8_t data);
virtual uint8_t palette_read(offs_t offset);
virtual void palette_write(offs_t offset, uint8_t data);
virtual u8 read(offs_t offset);
virtual void write(offs_t offset, u8 data);
virtual u8 palette_read(offs_t offset);
virtual void palette_write(offs_t offset, u8 data);
template <typename T> void set_cpu_tag(T &&tag) { m_cpu.set_tag(std::forward<T>(tag)); }
auto int_callback() { return m_int_callback.bind(); }
/* routines */
void apply_color_emphasis_and_clamp(bool is_pal_or_dendy, int color_emphasis, double& R, double& G, double& B);
rgb_t nespal_to_RGB(int color_intensity, int color_num, int color_emphasis, bool is_pal_or_dendy);
virtual void init_palette_tables();
virtual void read_tile_plane_data(int address, int color);
virtual void shift_tile_plane_data(uint8_t &pix);
virtual void draw_tile_pixel(uint8_t pix, int color, uint32_t back_pen, uint32_t *&dest);
virtual void draw_tile(uint8_t *line_priority, int color_byte, int color_bits, int address, int start_x, uint32_t back_pen, uint32_t *&dest);
virtual void draw_background( uint8_t *line_priority );
virtual void draw_back_pen(uint32_t* dst, int back_pen);
void draw_background_pen();
virtual void read_sprite_plane_data(int address);
virtual void make_sprite_pixel_data(uint8_t &pixel_data, int flipx);
virtual void draw_sprite_pixel(int sprite_xpos, int color, int pixel, uint8_t pixel_data, bitmap_rgb32 &bitmap);
virtual bool is_spritepixel_opaque(int pixel_data, int color);
virtual void draw_sprite_pixel_low(bitmap_rgb32& bitmap, int pixel_data, int pixel, int sprite_xpos, int color, int sprite_index, uint8_t* line_priority);
virtual void draw_sprite_pixel_high(bitmap_rgb32& bitmap, int pixel_data, int pixel, int sprite_xpos, int color, int sprite_index, uint8_t* line_priority);
virtual void read_extra_sprite_bits(int sprite_index);
virtual int apply_sprite_pattern_page(int index1, int size);
virtual void draw_sprites(uint8_t *line_priority);
void render_scanline();
virtual void scanline_increment_fine_ycounter();
void update_visible_enabled_scanline();
void update_visible_disabled_scanline();
void update_visible_scanline();
void update_scanline();
void spriteram_dma(address_space &space, const uint8_t page);
void render(bitmap_rgb32 &bitmap, int flipx, int flipy, int sx, int sy, const rectangle &cliprect);
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
void spriteram_dma(address_space &space, const u8 page);
void render(bitmap_rgb32 &bitmap, bool flipx, bool flipy, int sx, int sy, const rectangle &cliprect);
u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
int get_current_scanline() { return m_scanline; }
template <typename... T> void set_scanline_callback(T &&... args) { m_scanline_callback_proc.set(std::forward<T>(args)...); m_scanline_callback_proc.resolve(); /* FIXME: if this is supposed to be set at config time, it should be resolved on start */ }
@ -127,14 +98,12 @@ public:
// void update_screen(bitmap_t &bitmap, const rectangle &cliprect);
uint16_t get_vram_dest();
void set_vram_dest(uint16_t dest);
void ppu2c0x(address_map &map) ATTR_COLD;
u16 get_vram_dest();
void set_vram_dest(u16 dest);
bool in_vblanking() { return (m_scanline >= m_vblank_first_scanline - 1); }
protected:
ppu2c0x_device(const machine_config& mconfig, device_type type, const char* tag, device_t* owner, uint32_t clock, address_map_constructor internal_map);
ppu2c0x_device(const machine_config& mconfig, device_type type, const char* tag, device_t* owner, u32 clock, address_map_constructor internal_map);
// registers definition
enum
@ -172,7 +141,7 @@ protected:
};
// construction/destruction
ppu2c0x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock = 0);
ppu2c0x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock = 0);
virtual void device_start() override ATTR_COLD;
virtual void device_config_complete() override;
@ -180,10 +149,42 @@ protected:
// device_config_memory_interface overrides
virtual space_config_vector memory_space_config() const override;
virtual u32 palette_entries() const noexcept override { return 0x40 * 8; }
TIMER_CALLBACK_MEMBER(hblank_tick);
TIMER_CALLBACK_MEMBER(nmi_tick);
TIMER_CALLBACK_MEMBER(scanline_tick);
/* routines */
void apply_color_emphasis_and_clamp(bool is_pal_or_dendy, int color_emphasis, double& R, double& G, double& B);
rgb_t nespal_to_RGB(int color_intensity, int color_num, int color_emphasis, bool is_pal_or_dendy);
virtual void init_palette_tables();
virtual void read_tile_plane_data(int address, int color);
virtual void shift_tile_plane_data(u8 &pix);
virtual void draw_tile_pixel(u8 pix, int color, u32 back_pen, u32 *&dest);
virtual void draw_tile(u8 *line_priority, int color_byte, int color_bits, int address, int start_x, u32 back_pen, u32 *&dest);
virtual void draw_background( u8 *line_priority );
virtual void draw_back_pen(u32* dst, int back_pen);
void draw_background_pen();
virtual void read_sprite_plane_data(int address);
virtual void make_sprite_pixel_data(u8 &pixel_data, bool flipx);
virtual void draw_sprite_pixel(int sprite_xpos, int color, int pixel, u8 pixel_data, bitmap_rgb32 &bitmap);
virtual bool is_spritepixel_opaque(int pixel_data, int color);
virtual void draw_sprite_pixel_low(bitmap_rgb32& bitmap, int pixel_data, int pixel, int sprite_xpos, int color, int sprite_index, u8* line_priority);
virtual void draw_sprite_pixel_high(bitmap_rgb32& bitmap, int pixel_data, int pixel, int sprite_xpos, int color, int sprite_index, u8* line_priority);
virtual void read_extra_sprite_bits(int sprite_index);
virtual int apply_sprite_pattern_page(int index1, int size);
virtual void draw_sprites(u8 *line_priority);
void render_scanline();
virtual void scanline_increment_fine_ycounter();
void update_visible_enabled_scanline();
void update_visible_disabled_scanline();
void update_visible_scanline();
void update_scanline();
// address space configurations
const address_space_config m_space_config;
@ -196,47 +197,46 @@ protected:
int m_vblank_first_scanline; /* the very first scanline where VBLANK occurs */
// used in rendering
uint8_t m_planebuf[2];
int m_scanline; /* scanline count */
std::unique_ptr<uint8_t[]> m_spriteram; /* sprite ram */
u8 m_planebuf[2];
s32 m_scanline; /* scanline count */
std::unique_ptr<u8[]> m_spriteram; /* sprite ram */
int m_videoram_addr_mask;
int m_global_refresh_mask;
int m_line_write_increment_large;
bool m_paletteram_in_ppuspace; // sh6578 doesn't have the palette in PPU space, so various side-effects don't apply
std::vector<uint8_t> m_palette_ram; /* shouldn't be in main memory! */
std::unique_ptr<bitmap_rgb32> m_bitmap; /* target bitmap */
int m_regs[PPU_MAX_REG]; /* registers */
int m_tile_page; /* current tile page */
int m_back_color; /* background color */
int m_refresh_data; /* refresh-related */
int m_x_fine; /* refresh-related */
int m_toggle; /* used to latch hi-lo scroll */
int m_tilecount; /* MMC5 can change attributes to subsets of the 34 visible tiles */
std::vector<u8> m_palette_ram; /* shouldn't be in main memory! */
bitmap_rgb32 m_bitmap; /* target bitmap */
u8 m_regs[PPU_MAX_REG]; /* registers */
u32 m_tile_page; /* current tile page */
u8 m_back_color; /* background color */
s32 m_refresh_data; /* refresh-related */
u8 m_x_fine; /* refresh-related */
bool m_toggle; /* used to latch hi-lo scroll */
s32 m_tilecount; /* MMC5 can change attributes to subsets of the 34 visible tiles */
latch_delegate m_latch;
uint8_t readbyte(offs_t address);
u8 readbyte(offs_t address);
uint32_t m_nespens[0x40*8];
void ppu2c0x(address_map &map) ATTR_COLD;
private:
inline void writebyte(offs_t address, uint8_t data);
inline uint16_t apply_grayscale_and_emphasis(uint8_t color);
inline void writebyte(offs_t address, u8 data);
inline u16 apply_grayscale_and_emphasis(u8 color);
scanline_delegate m_scanline_callback_proc; /* optional scanline callback */
hblank_delegate m_hblank_callback_proc; /* optional hblank callback */
vidaccess_delegate m_vidaccess_callback_proc; /* optional video access callback */
devcb_write_line m_int_callback; /* nmi access callback from interface */
int m_refresh_latch; /* refresh-related */
int m_add; /* vram increment amount */
int m_videomem_addr; /* videomem address pointer */
int m_data_latch; /* latched videomem data */
int m_buffered_data;
int m_sprite_page; /* current sprite page */
int m_scan_scale; /* scan scale */
int m_draw_phase; /* MMC5 uses different regs for BG and OAM */
s32 m_refresh_latch; /* refresh-related */
s32 m_add; /* vram increment amount */
u32 m_videomem_addr; /* videomem address pointer */
u8 m_data_latch; /* latched videomem data */
u8 m_buffered_data;
u32 m_sprite_page; /* current sprite page */
s32 m_scan_scale; /* scan scale */
s32 m_draw_phase; /* MMC5 uses different regs for BG and OAM */
// timers
emu_timer *m_hblank_timer; /* hblank period at end of each scanline */
@ -246,79 +246,81 @@ private:
class ppu2c0x_rgb_device : public ppu2c0x_device {
protected:
ppu2c0x_rgb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock = 0);
ppu2c0x_rgb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock = 0);
virtual void init_palette_tables() override;
private:
required_region_ptr<uint8_t> m_palette_data;
required_region_ptr<u8> m_palette_data;
};
class ppu2c02_device : public ppu2c0x_device {
public:
ppu2c02_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
ppu2c02_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
};
class ppu2c03b_device : public ppu2c0x_rgb_device {
public:
ppu2c03b_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
ppu2c03b_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
};
class ppu2c04_device : public ppu2c0x_rgb_device {
public:
ppu2c04_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
ppu2c04_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
};
class ppu2c07_device : public ppu2c0x_device {
public:
ppu2c07_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
ppu2c07_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
};
class ppupalc_device : public ppu2c0x_device {
public:
ppupalc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
ppupalc_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
};
class ppu2c05_01_device : public ppu2c0x_rgb_device {
public:
ppu2c05_01_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
ppu2c05_01_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
};
class ppu2c05_02_device : public ppu2c0x_rgb_device {
public:
ppu2c05_02_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
ppu2c05_02_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
};
class ppu2c05_03_device : public ppu2c0x_rgb_device {
public:
ppu2c05_03_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
ppu2c05_03_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
};
class ppu2c05_04_device : public ppu2c0x_rgb_device {
public:
ppu2c05_04_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
ppu2c05_04_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
};
class ppu2c04_clone_device : public ppu2c0x_device {
public:
ppu2c04_clone_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
ppu2c04_clone_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
virtual uint8_t read(offs_t offset) override;
virtual void write(offs_t offset, uint8_t data) override;
virtual void draw_background(uint8_t *line_priority) override;
virtual void draw_sprite_pixel(int sprite_xpos, int color, int pixel, uint8_t pixel_data, bitmap_rgb32 &bitmap) override;
virtual void draw_sprites(uint8_t *line_priority) override;
virtual void init_palette_tables() override;
virtual u8 read(offs_t offset) override;
virtual void write(offs_t offset, u8 data) override;
protected:
virtual void device_start() override ATTR_COLD;
private:
required_region_ptr<uint8_t> m_palette_data;
virtual u32 palette_entries() const noexcept override { return 0x40 * 2; }
std::unique_ptr<uint8_t[]> m_spritebuf; /* buffered sprite ram for next frame */
virtual void draw_background(u8 *line_priority) override;
virtual void draw_sprite_pixel(int sprite_xpos, int color, int pixel, u8 pixel_data, bitmap_rgb32 &bitmap) override;
virtual void draw_sprites(u8 *line_priority) override;
virtual void init_palette_tables() override;
private:
required_region_ptr<u8> m_palette_data;
std::unique_ptr<u8[]> m_spritebuf; /* buffered sprite ram for next frame */
};
// device type definition

View File

@ -59,6 +59,8 @@ void ppu_sh6578_device::device_start()
m_palette_ram[i] = 0x00;
save_item(NAME(m_palette_ram));
save_item(NAME(m_extplanebuf));
save_item(NAME(m_colsel_pntstart));
}
void ppu_sh6578_device::device_reset()
@ -73,10 +75,9 @@ void ppu_sh6578_device::scanline_increment_fine_ycounter()
m_refresh_data += 0x1000;
/* if it's rolled, increment the coarse y-scroll */
if (m_refresh_data & 0x8000)
if (BIT(m_refresh_data, 15))
{
uint16_t tmp;
tmp = (m_refresh_data & 0x03e0) + 0x20;
const uint16_t tmp = (m_refresh_data & 0x03e0) + 0x20;
m_refresh_data &= 0x7c1f;
if (tmp == 0x0400)
@ -90,8 +91,7 @@ void ppu_sh6578_device::scanline_increment_fine_ycounter()
void ppu_sh6578_device::draw_sprite_pixel(int sprite_xpos, int color, int pixel, uint8_t pixel_data, bitmap_rgb32& bitmap)
{
uint8_t palval = m_palette_ram[(pixel_data | color << 2)] & 0x3f;
bitmap.pix(m_scanline, sprite_xpos + pixel) = m_nespens[palval];
bitmap.pix(m_scanline, sprite_xpos + pixel) = pen_color(m_palette_ram[(pixel_data | color << 2)] & 0x3f);
}
void ppu_sh6578_device::read_tile_plane_data(int address, int color)
@ -110,7 +110,7 @@ void ppu_sh6578_device::draw_tile(uint8_t* line_priority, int color_byte, int co
{
int color = color_byte;
if (m_colsel_pntstart & 0x80)
if (BIT(m_colsel_pntstart, 7))
{
color &= 0xc;
}
@ -146,11 +146,9 @@ void ppu_sh6578_device::draw_tile(uint8_t* line_priority, int color_byte, int co
if ((start_x + i) >= 0 && (start_x + i) < VISIBLE_SCREEN_WIDTH)
{
pen_t pen;
rgb_t pen;
uint8_t palval;
palval = m_palette_ram[(pix | color << 2)] & 0x3f;
const uint8_t palval = m_palette_ram[(pix | color << 2)] & 0x3f;
bool trans = false;
if ((palval & 0x1f) == 0x1f)
@ -158,12 +156,12 @@ void ppu_sh6578_device::draw_tile(uint8_t* line_priority, int color_byte, int co
if (!trans)
{
pen = m_nespens[palval];
pen = pen_color(palval);
}
else
{
uint8_t palval = m_palette_ram[0x0] & 0x3f;
pen = m_nespens[palval];
const uint8_t palval = m_palette_ram[0x0] & 0x3f;
pen = pen_color(palval);
}
*dest = pen;
@ -178,8 +176,6 @@ void ppu_sh6578_device::draw_tile(uint8_t* line_priority, int color_byte, int co
void ppu_sh6578_device::draw_background(uint8_t* line_priority)
{
bitmap_rgb32& bitmap = *m_bitmap;
uint8_t color_mask = 0xff;
//const pen_t* color_table;
@ -197,34 +193,30 @@ void ppu_sh6578_device::draw_background(uint8_t* line_priority)
/* cache the background pen */
pen_t back_pen = m_nespens[m_back_color & color_mask];
const pen_t back_pen = pen_color(m_back_color & color_mask);
/* determine where in the nametable to start drawing from */
/* based on the current scanline and scroll regs */
uint8_t scroll_x_coarse = m_refresh_data & 0x001f;
uint8_t scroll_y_coarse = (m_refresh_data & 0x03e0) >> 5;
uint16_t nametable = (m_refresh_data & 0x0c00);
uint8_t scroll_y_fine = (m_refresh_data & 0x7000) >> 12;
const uint8_t scroll_x_coarse = m_refresh_data & 0x001f;
const uint8_t scroll_y_coarse = (m_refresh_data & 0x03e0) >> 5;
const uint16_t nametable = (m_refresh_data & 0x0c00);
const uint8_t scroll_y_fine = (m_refresh_data & 0x7000) >> 12;
int x = scroll_x_coarse;
/* get the tile index */
int tile_index = (nametable<<1) + scroll_y_coarse * 64;
int tile_index = (nametable << 1) + scroll_y_coarse * 64;
/* set up dest */
int start_x = (m_x_fine ^ 0x07) - 7;
uint32_t* dest = &bitmap.pix(m_scanline, start_x);
uint32_t* dest = &m_bitmap.pix(m_scanline, start_x);
m_tilecount = 0;
/* draw the 32 or 33 tiles that make up a line */
while (m_tilecount < 34)
{
int color_byte;
int index1;
int page2, address;
index1 = tile_index + (x << 1);
int index1 = tile_index + (x << 1);
if (m_colsel_pntstart & 1)
{
@ -237,14 +229,14 @@ void ppu_sh6578_device::draw_background(uint8_t* line_priority)
}
// page2 is the output of the nametable read (this section is the FIRST read per tile!)
page2 = readbyte(index1);
const int page2 = readbyte(index1);
/* Figure out which byte in the color table to use */
color_byte = readbyte(index1 + 1);
const int color_byte = readbyte(index1 + 1);
if (start_x < VISIBLE_SCREEN_WIDTH)
{
address = ((page2 | (color_byte<<8)) & 0x0fff) << 4;
int address = ((page2 | (color_byte<<8)) & 0x0fff) << 4;
// plus something that accounts for y
address += scroll_y_fine;
@ -266,7 +258,7 @@ void ppu_sh6578_device::draw_background(uint8_t* line_priority)
/* if the left 8 pixels for the background are off, blank 'em */
if (!(m_regs[PPU_CONTROL1] & PPU_CONTROL1_BACKGROUND_L8))
{
dest = &bitmap.pix(m_scanline);
dest = &m_bitmap.pix(m_scanline);
for (int i = 0; i < 8; i++)
{
*(dest++) = back_pen;

View File

@ -24,22 +24,22 @@ public:
protected:
ppu_sh6578_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
void ppu_internal_map(address_map &map) ATTR_COLD;
private:
virtual void device_start() override ATTR_COLD;
virtual void device_reset() override ATTR_COLD;
virtual void draw_sprite_pixel(int sprite_xpos, int color, int pixel, uint8_t pixel_data, bitmap_rgb32 &bitmap) override;
//virtual void draw_sprites(uint8_t *line_priority) override;
virtual void draw_background(uint8_t *line_priority) override;
virtual int apply_sprite_pattern_page(int index1, int size) override;
virtual void read_sprite_plane_data(int address) override;
void ppu_internal_map(address_map &map) ATTR_COLD;
private:
void scanline_increment_fine_ycounter() override;
void read_tile_plane_data(int address, int color) override;
void draw_tile(uint8_t* line_priority, int color_byte, int color_bits, int address, int start_x, uint32_t back_pen, uint32_t*& dest) override;
virtual void draw_sprite_pixel(int sprite_xpos, int color, int pixel, uint8_t pixel_data, bitmap_rgb32& bitmap) override;
//virtual void draw_sprites(uint8_t* line_priority) override;
virtual void draw_background(uint8_t* line_priority) override;
virtual int apply_sprite_pattern_page(int index1, int size) override;
virtual void read_sprite_plane_data(int address) override;
void draw_tile(uint8_t *line_priority, int color_byte, int color_bits, int address, int start_x, uint32_t back_pen, uint32_t *&dest) override;
uint8_t m_extplanebuf[2];
uint8_t m_colsel_pntstart;
@ -48,7 +48,7 @@ private:
class ppu_sh6578pal_device : public ppu_sh6578_device
{
public:
ppu_sh6578pal_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock);
ppu_sh6578pal_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};
DECLARE_DEVICE_TYPE(PPU_SH6578, ppu_sh6578_device)

View File

@ -146,10 +146,10 @@ void ppu_vt03_device::init_vtxx_rgb555_palette_tables()
{
for (int palval = 0; palval < 0x8000; palval++)
{
// uint16_t rgbval = (m_palette_ram[i & 0x7f] & 0xff) | ((m_palette_ram[(i & 0x7f) + 0x80] & 0xff) << 8);
uint8_t blue = (palval & 0x001f) << 3;
uint8_t green = (palval & 0x3e0) >> 2;
uint8_t red = (palval & 0x7C00) >> 7;
//uint16_t rgbval = (m_palette_ram[i & 0x7f] & 0xff) | ((m_palette_ram[(i & 0x7f) + 0x80] & 0xff) << 8);
const uint8_t blue = (palval & 0x001f) << 3;
const uint8_t green = (palval & 0x3e0) >> 2;
const uint8_t red = (palval & 0x7C00) >> 7;
// TODO: apply emphasis values if they work in this mode
m_vtpens_rgb555[entry] = rgb_t(red, green, blue);
@ -166,9 +166,9 @@ void ppu_vt03_device::init_vtxx_rgb444_palette_tables()
for (int palval = 0; palval < 0x1000; palval++)
{
//uint16_t rgbval = (m_palette_ram[i & 0x7f] & 0x3f) | ((m_palette_ram[(i & 0x7f) + 0x80] & 0x3f) << 6);
uint8_t red = (palval & 0x000f) << 4;
uint8_t green = (palval & 0x0f0);
uint8_t blue = (palval & 0xf00) >> 4;
const uint8_t red = (palval & 0x000f) << 4;
const uint8_t green = (palval & 0x0f0);
const uint8_t blue = (palval & 0xf00) >> 4;
// TODO: apply emphasis values if they work in this mode
m_vtpens_rgb444[entry] = rgb_t(red, green, blue);
@ -205,7 +205,7 @@ void ppu_vt03_device::init_vt03_palette_tables(int palmode)
float fLuma = (nLuma - 4) / 9.625; // Value determined from matching saturation =0 phases 1-12
float fChroma = nChroma / 18.975; // Value determined from matching phases 0 and 13 across all luminance and saturation levels
float fPhase = ((nPhase - 2) * 30.0 + phaseOffset) * M_PI / 180.0;
const float fPhase = ((nPhase - 2) * 30.0 + phaseOffset) * M_PI / 180.0;
if (palmode == 1)
{
@ -223,8 +223,8 @@ void ppu_vt03_device::init_vt03_palette_tables(int palmode)
if (nPhase == 13) Y -= fChroma; // Phase 13 is the lower bound of the waveform
if (nPhase >= 14) Y = 0.0; // Phases 14 and 15 always black
float V = sin(fPhase) * C * 1.05; // 1.05 needed to get closer to EmuVT palette's color levels in phases 1-12
float U = cos(fPhase) * C * 1.05;
const float V = sin(fPhase) * C * 1.05; // 1.05 needed to get closer to EmuVT palette's color levels in phases 1-12
const float U = cos(fPhase) * C * 1.05;
float R = Y + 1.1400 * V + 0.0000 * U;
float G = Y - 0.5807 * V - 0.3940 * U;
float B = Y - 0.0000 * V + 2.0290 * U;
@ -234,15 +234,15 @@ void ppu_vt03_device::init_vt03_palette_tables(int palmode)
if (G > 1.0) G = 1.0;
if (B < 0.0) B = 0.0;
if (B > 1.0) B = 1.0;
int RV = R * 255.0;
int GV = G * 255.0;
int BV = B * 255.0;
const int RV = R * 255.0;
const int GV = G * 255.0;
const int BV = B * 255.0;
// does this really apply to the VT palette?
//bool is_pal = m_scanlines_per_frame != NTSC_SCANLINES_PER_FRAME;
//apply_color_emphasis_and_clamp(is_pal, color_emphasis, R, G, B);
m_vtpens[entry] = rgb_t(RV, GV, BV);
set_pen_color(YUV444_COLOR + entry, rgb_t(RV, GV, BV));
entry++;
}
}
@ -258,6 +258,10 @@ void ppu_vt03_device::device_start()
m_palette_ram[i] = 0x00;
save_item(NAME(m_palette_ram));
save_item(NAME(m_read_bg4_bg3));
save_item(NAME(m_va34));
save_item(NAME(m_extplanebuf));
save_item(NAME(m_extra_sprite_bits));
save_item(NAME(m_201x_regs));
init_vt03_palette_tables(0);
@ -289,7 +293,7 @@ void ppu_vt03_device::device_reset()
set_201x_reg(i, 0x00);
m_read_bg4_bg3 = 0;
m_va34 = 0;
m_va34 = false;
}
@ -306,26 +310,26 @@ uint8_t ppu_vt03_device::get_va34()
void ppu_vt03_device::read_sprite_plane_data(int address)
{
m_va34 = 0;
m_va34 = false;
m_planebuf[0] = m_read_sp((address + 0) & 0x1fff);
m_planebuf[1] = m_read_sp((address + 8) & 0x1fff);
int is4bpp = get_201x_reg(0x0) & 0x04;
const bool is4bpp = BIT(get_201x_reg(0x0), 2);
if (is4bpp)
{
m_va34 = 1;
m_va34 = true;
m_extplanebuf[0] = m_read_sp((address + 0) & 0x1fff);
m_extplanebuf[1] = m_read_sp((address + 8) & 0x1fff);
}
}
void ppu_vt03_device::make_sprite_pixel_data(uint8_t& pixel_data, int flipx)
void ppu_vt03_device::make_sprite_pixel_data(uint8_t& pixel_data, bool flipx)
{
ppu2c0x_device::make_sprite_pixel_data(pixel_data, flipx);
int is4bpp = get_201x_reg(0x0) & 0x04;
int is16pix = get_201x_reg(0x0) & 0x01;
const bool is4bpp = BIT(get_201x_reg(0x0), 2);
const bool is16pix = BIT(get_201x_reg(0x0), 0);
if (is4bpp)
{
@ -338,8 +342,8 @@ void ppu_vt03_device::make_sprite_pixel_data(uint8_t& pixel_data, int flipx)
if (is16pix)
{
uint8_t pix0 = pixel_data & 0x03;
uint8_t pix1 = (pixel_data >> 5) & 0x03;
const uint8_t pix0 = pixel_data & 0x03;
const uint8_t pix1 = (pixel_data >> 5) & 0x03;
pixel_data = pix1 | (pix0 << 5);
}
}
@ -354,14 +358,14 @@ void ppu_vt03_device::make_sprite_pixel_data(uint8_t& pixel_data, int flipx)
void ppu_vt03_device::draw_sprite_pixel(int sprite_xpos, int color, int pixel, uint8_t pixel_data, bitmap_rgb32& bitmap)
{
int is4bpp = get_201x_reg(0x0) & 0x04;
int is16pix = get_201x_reg(0x0) & 0x01;
const bool is4bpp = BIT(get_201x_reg(0x0), 2);
const bool is16pix = BIT(get_201x_reg(0x0), 0);
if (is4bpp)
{
if (!is16pix)
{
uint8_t pen = pixel_data + (4 * color);
const uint8_t pen = pixel_data + (4 * color);
draw_tile_pixel_inner(pen, &bitmap.pix(m_scanline, sprite_xpos + pixel));
}
else
@ -371,13 +375,13 @@ void ppu_vt03_device::draw_sprite_pixel(int sprite_xpos, int color, int pixel, u
cliprect - not seen used yet */
if ((pixel_data & 0x03) != 0)
{
uint8_t pen = (pixel_data & 0x03) + (4 * color);
const uint8_t pen = (pixel_data & 0x03) + (4 * color);
draw_tile_pixel_inner(pen, &bitmap.pix(m_scanline, sprite_xpos + pixel));
}
if (((pixel_data >> 5) & 0x03) != 0)
{
uint8_t pen = ((pixel_data >> 5) & 0x03) + (4 * color);
const uint8_t pen = ((pixel_data >> 5) & 0x03) + (4 * color);
draw_tile_pixel_inner(pen, &bitmap.pix(m_scanline, sprite_xpos + pixel + 8));
}
//ppu2c0x_device::draw_sprite_pixel(sprite_xpos, color, pixel, pixel_data & 0x03, bitmap);
@ -392,7 +396,7 @@ void ppu_vt03_device::draw_sprite_pixel(int sprite_xpos, int color, int pixel, u
void ppu_vt03_device::read_tile_plane_data(int address, int color)
{
int is4bpp = get_201x_reg(0x0) & 0x02;
const bool is4bpp = BIT(get_201x_reg(0x0), 1);
if (m_201x_regs[0] & 0x10) // extended mode
m_read_bg4_bg3 = color;
@ -401,16 +405,16 @@ void ppu_vt03_device::read_tile_plane_data(int address, int color)
if (is4bpp)
{
m_va34 = 0;
m_va34 = false;
m_planebuf[0] = m_read_bg((address & 0x1fff));
m_planebuf[1] = m_read_bg((address + 8) & 0x1fff);
m_va34 = 1;
m_va34 = true;
m_extplanebuf[0] = m_read_bg((address & 0x1fff));
m_extplanebuf[1] = m_read_bg((address + 8) & 0x1fff);
}
else
{
m_va34 = 0;
m_va34 = false;
m_planebuf[0] = m_read_bg((address & 0x1fff));
m_planebuf[1] = m_read_bg((address + 8) & 0x1fff);
}
@ -418,7 +422,7 @@ void ppu_vt03_device::read_tile_plane_data(int address, int color)
void ppu_vt03_device::shift_tile_plane_data(uint8_t& pix)
{
int is4bpp = get_201x_reg(0x0) & 0x02;
const bool is4bpp = BIT(get_201x_reg(0x0), 1);
ppu2c0x_device::shift_tile_plane_data(pix);
@ -441,21 +445,18 @@ void ppu_vt03_device::draw_back_pen(uint32_t* dst, int back_pen)
else
{
// in normal modes we still have the data from the palette writes as the 'backpen' so treat it as before
uint32_t pix;
pix = m_nespens[back_pen & 0x1ff];
*dst = pix;
*dst = pen_color(back_pen & 0x1ff);
}
}
void ppu_vt03_device::draw_tile_pixel_inner(uint8_t pen, uint32_t *dest)
{
if (m_201x_regs[0] & 0x80)
if (BIT(m_201x_regs[0], 7))
{
if (m_pal_mode == PAL_MODE_NEW_RGB) // unknown newer VT mode
{
uint32_t palval;
palval = (m_palette_ram[pen & 0x7f] & 0xff) | ((m_palette_ram[(pen & 0x7f) + 0x80] & 0x7f) << 8);
uint32_t palval = (m_palette_ram[pen & 0x7f] & 0xff) | ((m_palette_ram[(pen & 0x7f) + 0x80] & 0x7f) << 8);
// does grayscale mode exist here? (we haven't calculated any colours for it)
//if (m_regs[PPU_CONTROL1] & PPU_CONTROL1_DISPLAY_MONO)
@ -464,14 +465,11 @@ void ppu_vt03_device::draw_tile_pixel_inner(uint8_t pen, uint32_t *dest)
// apply colour emphasis (does it really exist here?) (we haven't calculated any colours for it, so ths has no effect)
palval |= ((m_regs[PPU_CONTROL1] & PPU_CONTROL1_COLOR_EMPHASIS) << 10);
uint32_t pix;
pix = m_vtpens_rgb555[palval & 0x3ffff];
*dest = pix;
*dest = m_vtpens_rgb555[palval & 0x3ffff];
}
else if (m_pal_mode == PAL_MODE_NEW_RGB12) // unknown newer VT mode
{
uint32_t palval;
palval = (m_palette_ram[pen & 0x7f] & 0x3f) | ((m_palette_ram[(pen & 0x7f) + 0x80] & 0x3f) << 6);
uint32_t palval = (m_palette_ram[pen & 0x7f] & 0x3f) | ((m_palette_ram[(pen & 0x7f) + 0x80] & 0x3f) << 6);
// does grayscale mode exist here? (we haven't calculated any colours for it)
//if (m_regs[PPU_CONTROL1] & PPU_CONTROL1_DISPLAY_MONO)
@ -480,14 +478,11 @@ void ppu_vt03_device::draw_tile_pixel_inner(uint8_t pen, uint32_t *dest)
// apply colour emphasis (does it really exist here?) (we haven't calculated any colours for it, so ths has no effect)
palval |= ((m_regs[PPU_CONTROL1] & PPU_CONTROL1_COLOR_EMPHASIS) << 7);
uint32_t pix;
pix = m_vtpens_rgb444[palval & 0x7fff];
*dest = pix;
*dest = m_vtpens_rgb444[palval & 0x7fff];
}
else // VT03 mode
{
uint32_t palval;
palval = (m_palette_ram[pen & 0x7f] & 0x3f) | ((m_palette_ram[(pen & 0x7f) + 0x80] & 0x3f) << 6);
uint32_t palval = (m_palette_ram[pen & 0x7f] & 0x3f) | ((m_palette_ram[(pen & 0x7f) + 0x80] & 0x3f) << 6);
// does grayscale mode exist here? (we haven't calculated any colours for it)
//if (m_regs[PPU_CONTROL1] & PPU_CONTROL1_DISPLAY_MONO)
@ -496,15 +491,12 @@ void ppu_vt03_device::draw_tile_pixel_inner(uint8_t pen, uint32_t *dest)
// apply colour emphasis (does it really exist here?) (we calculate values for it when building the palette lookup)
palval |= ((m_regs[PPU_CONTROL1] & PPU_CONTROL1_COLOR_EMPHASIS) << 7);
uint32_t pix;
pix = m_vtpens[palval & 0x7fff];
*dest = pix;
*dest = pen_color(YUV444_COLOR + (palval & 0x7fff));
}
}
else // old colour compatible mode
{
uint16_t palval;
palval = (m_palette_ram[pen & 0x7f] & 0x3f);
uint16_t palval = (m_palette_ram[pen & 0x7f] & 0x3f);
if (m_regs[PPU_CONTROL1] & PPU_CONTROL1_DISPLAY_MONO)
palval &= 0x30;
@ -512,14 +504,12 @@ void ppu_vt03_device::draw_tile_pixel_inner(uint8_t pen, uint32_t *dest)
// apply colour emphasis
palval |= ((m_regs[PPU_CONTROL1] & PPU_CONTROL1_COLOR_EMPHASIS) << 1);
uint32_t pix;
pix = m_nespens[palval & 0x1ff];
*dest = pix;
*dest = pen_color(palval & 0x1ff);
}
}
void ppu_vt03_device::draw_tile_pixel(uint8_t pix, int color, uint32_t back_pen, uint32_t*& dest)
{
int is4bpp = get_201x_reg(0x0) & 0x02;
const bool is4bpp = BIT(get_201x_reg(0x0), 1);
if (!is4bpp)
{

View File

@ -39,24 +39,6 @@ public:
virtual uint8_t palette_read(offs_t offset) override;
virtual void palette_write(offs_t offset, uint8_t data) override;
void init_vt03_palette_tables(int palmode);
void init_vtxx_rgb555_palette_tables();
void init_vtxx_rgb444_palette_tables();
virtual void read_tile_plane_data(int address, int color) override;
virtual void shift_tile_plane_data(uint8_t &pix) override;
virtual void draw_tile_pixel(uint8_t pix, int color, uint32_t back_pen, uint32_t *&dest) override;
inline void draw_tile_pixel_inner(uint8_t pen, uint32_t *dest);
virtual void draw_back_pen(uint32_t* dst, int back_pen) override;
virtual void read_sprite_plane_data(int address) override;
virtual void make_sprite_pixel_data(uint8_t &pixel_data, int flipx) override;
virtual void draw_sprite_pixel(int sprite_xpos, int color, int pixel, uint8_t pixel_data, bitmap_rgb32 &bitmap) override;
virtual void read_extra_sprite_bits(int sprite_index) override;
virtual void device_start() override ATTR_COLD;
virtual void device_reset() override ATTR_COLD;
void set_201x_reg(int reg, uint8_t data);
uint8_t get_201x_reg(int reg);
@ -68,10 +50,25 @@ public:
bool get_is_50hz() { return m_is_50hz; }
protected:
virtual void device_start() override ATTR_COLD;
virtual void device_reset() override ATTR_COLD;
virtual u32 palette_entries() const noexcept override { return (0x40 * 8) + (0x1000 * 8); }
virtual void read_tile_plane_data(int address, int color) override;
virtual void shift_tile_plane_data(uint8_t &pix) override;
virtual void draw_tile_pixel(uint8_t pix, int color, uint32_t back_pen, uint32_t *&dest) override;
inline void draw_tile_pixel_inner(uint8_t pen, uint32_t *dest);
virtual void draw_back_pen(uint32_t* dst, int back_pen) override;
virtual void read_sprite_plane_data(int address) override;
virtual void make_sprite_pixel_data(uint8_t &pixel_data, bool flipx) override;
virtual void draw_sprite_pixel(int sprite_xpos, int color, int pixel, uint8_t pixel_data, bitmap_rgb32 &bitmap) override;
virtual void read_extra_sprite_bits(int sprite_index) override;
bool m_is_pal;
bool m_is_50hz;
uint32_t m_vtpens[0x1000*8];
uint32_t m_vtpens_rgb555[0x8000*8];
uint32_t m_vtpens_rgb444[0x1000*8];
@ -79,8 +76,8 @@ private:
devcb_read8 m_read_bg;
devcb_read8 m_read_sp;
int m_read_bg4_bg3;
int m_va34;
int32_t m_read_bg4_bg3;
bool m_va34;
uint8_t m_extplanebuf[2];
uint8_t m_extra_sprite_bits;
@ -92,6 +89,11 @@ private:
vtxx_pal_mode m_pal_mode = PAL_MODE_VT0x;
void set_2010_reg(uint8_t data);
void init_vt03_palette_tables(int palmode);
void init_vtxx_rgb555_palette_tables();
void init_vtxx_rgb444_palette_tables();
static constexpr unsigned YUV444_COLOR = (0x40 * 8);
};
class ppu_vt03pal_device : public ppu_vt03_device {