popper: Fix memory map, finish gfx rendering.

Game is fully working again.
This commit is contained in:
Dirk Best 2017-04-23 10:05:16 +02:00
parent a19e42c057
commit a1d4fd0473

View File

@ -33,7 +33,8 @@
TODO: TODO:
- According to the schematics the sub CPU ROM should be 0x2000 - According to the schematics the sub CPU ROM should be 0x2000
- Verify screen raw parameters - Verify screen raw parameters
- Finish driver - Verify graphics with real hardware
- Watchdog
***************************************************************************/ ***************************************************************************/
@ -59,16 +60,19 @@ public:
m_screen(*this, "screen"), m_screen(*this, "screen"),
m_gfxdecode(*this, "gfxdecode"), m_gfxdecode(*this, "gfxdecode"),
m_ay{ {*this, "ay1"}, {*this, "ay2"} }, m_ay{ {*this, "ay1"}, {*this, "ay2"} },
m_ram(*this, "ram"), m_video_ram(*this, "video_ram"),
m_attribute_ram(*this, "attribute_ram"),
m_sprite_ram(*this, "sprite_ram"),
m_inputs{ {*this, "in1"}, {*this, "in0"}, {*this, "dsw2"}, {*this, "dsw1"} }, m_inputs{ {*this, "in1"}, {*this, "in0"}, {*this, "dsw2"}, {*this, "dsw1"} },
m_scanline_timer(nullptr), m_scanline_timer(nullptr),
m_tilemap(nullptr), m_layer0_tilemap(nullptr), m_layer1_tilemap(nullptr),
m_nmi_enable(0), m_vram_page(0) m_nmi_enable(0), m_back_color(0), m_vram_page(0)
{ } { }
DECLARE_PALETTE_INIT(popper); DECLARE_PALETTE_INIT(popper);
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
TILE_GET_INFO_MEMBER(tile_info); TILE_GET_INFO_MEMBER(layer0_tile_info);
TILE_GET_INFO_MEMBER(layer1_tile_info);
DECLARE_WRITE8_MEMBER(nmi_control_w); DECLARE_WRITE8_MEMBER(nmi_control_w);
DECLARE_WRITE8_MEMBER(crt_direction_w); DECLARE_WRITE8_MEMBER(crt_direction_w);
@ -92,13 +96,17 @@ private:
required_device<screen_device> m_screen; required_device<screen_device> m_screen;
required_device<gfxdecode_device> m_gfxdecode; required_device<gfxdecode_device> m_gfxdecode;
required_device<ay8910_device> m_ay[2]; required_device<ay8910_device> m_ay[2];
required_shared_ptr<uint8_t> m_ram; required_shared_ptr<uint8_t> m_video_ram;
required_shared_ptr<uint8_t> m_attribute_ram;
required_shared_ptr<uint8_t> m_sprite_ram;
required_ioport m_inputs[4]; required_ioport m_inputs[4];
emu_timer *m_scanline_timer; emu_timer *m_scanline_timer;
tilemap_t *m_tilemap; tilemap_t *m_layer0_tilemap;
tilemap_t *m_layer1_tilemap;
int m_nmi_enable; int m_nmi_enable;
int m_back_color;
int m_vram_page; int m_vram_page;
}; };
@ -110,7 +118,13 @@ private:
static ADDRESS_MAP_START( main_map, AS_PROGRAM, 8, popper_state ) static ADDRESS_MAP_START( main_map, AS_PROGRAM, 8, popper_state )
AM_RANGE(0x0000, 0x7fff) AM_ROM AM_RANGE(0x0000, 0x7fff) AM_ROM
AM_RANGE(0x8000, 0xbfff) AM_NOP AM_RANGE(0x8000, 0xbfff) AM_NOP
AM_RANGE(0xc000, 0xdfff) AM_RAM AM_SHARE("ram") AM_RANGE(0xc000, 0xc0ff) AM_RAM
AM_RANGE(0xc100, 0xc6ff) AM_RAM AM_SHARE("video_ram")
AM_RANGE(0xc700, 0xc8ff) AM_RAM
AM_RANGE(0xc900, 0xceff) AM_RAM AM_SHARE("attribute_ram")
AM_RANGE(0xcf00, 0xcfff) AM_RAM
AM_RANGE(0xd000, 0xd7ff) AM_RAM AM_SHARE("sprite_ram")
AM_RANGE(0xd800, 0xdfff) AM_RAM AM_SHARE("shared")
AM_RANGE(0xe000, 0xe003) AM_MIRROR(0x03fc) AM_READ(inputs_r) AM_RANGE(0xe000, 0xe003) AM_MIRROR(0x03fc) AM_READ(inputs_r)
AM_RANGE(0xe000, 0xe000) AM_MIRROR(0x1ff8) AM_WRITE(nmi_control_w) AM_RANGE(0xe000, 0xe000) AM_MIRROR(0x1ff8) AM_WRITE(nmi_control_w)
AM_RANGE(0xe001, 0xe001) AM_MIRROR(0x1ff8) AM_WRITE(crt_direction_w) AM_RANGE(0xe001, 0xe001) AM_MIRROR(0x1ff8) AM_WRITE(crt_direction_w)
@ -128,7 +142,7 @@ static ADDRESS_MAP_START( sub_map, AS_PROGRAM, 8, popper_state )
AM_RANGE(0x2000, 0x7fff) AM_NOP AM_RANGE(0x2000, 0x7fff) AM_NOP
AM_RANGE(0x8000, 0x8003) AM_MIRROR(0x1ffc) AM_WRITE(ay1_w) AM_RANGE(0x8000, 0x8003) AM_MIRROR(0x1ffc) AM_WRITE(ay1_w)
AM_RANGE(0xa000, 0xa003) AM_MIRROR(0x1ffc) AM_DEVWRITE("ay2", ay8910_device, write_bc1_bc2) AM_RANGE(0xa000, 0xa003) AM_MIRROR(0x1ffc) AM_DEVWRITE("ay2", ay8910_device, write_bc1_bc2)
AM_RANGE(0xc000, 0xdfff) AM_RAM AM_SHARE("ram") AM_RANGE(0xc000, 0xc7ff) AM_MIRROR(0x1800) AM_RAM AM_SHARE("shared")
AM_RANGE(0xe000, 0xffff) AM_NOP AM_RANGE(0xe000, 0xffff) AM_NOP
ADDRESS_MAP_END ADDRESS_MAP_END
@ -288,7 +302,7 @@ WRITE8_MEMBER( popper_state::crt_direction_w )
WRITE8_MEMBER( popper_state::back_color_select_w ) WRITE8_MEMBER( popper_state::back_color_select_w )
{ {
logerror("back_color_select_w: %02x\n", data); m_back_color = data & 1;
} }
WRITE8_MEMBER( popper_state::vram_page_select_w ) WRITE8_MEMBER( popper_state::vram_page_select_w )
@ -301,10 +315,56 @@ uint32_t popper_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap
bitmap.fill(0, cliprect); bitmap.fill(0, cliprect);
// always draw all tiles // always draw all tiles
m_tilemap->mark_all_dirty(); m_layer0_tilemap->mark_all_dirty();
m_layer1_tilemap->mark_all_dirty();
// draw the character layer // draw the layers with lower priority
m_tilemap->draw(screen, bitmap, cliprect, 0, 0); m_layer0_tilemap->draw(screen, bitmap, cliprect, 0, 0);
m_layer1_tilemap->draw(screen, bitmap, cliprect, 0, 0);
// draw the sprites
for (int offs = 0; offs < 0x800; offs += 4)
{
// 0 76653210 Y coordinate
// 1 76543210 Code
// 2 7------- Flip Y
// 2 -6------ Flip X
// 2 --54---- Not used
// 2 ----3210 Color
// 3 76653210 X coordinate
int sx = m_sprite_ram[offs + 3];
int sy = m_sprite_ram[offs + 0];
// only render sprite if it's in the current offset range
if (((sy + (flip_screen() ? 2 : 0)) >> 4) != ((~(offs >> 7)) & 0x0f))
continue;
sx += 64;
sy = 240 - sy;
int flipx = BIT(m_sprite_ram[offs + 2], 6);
int flipy = BIT(m_sprite_ram[offs + 2], 7);
if (flip_screen())
{
flipx = !flipx;
flipy = !flipy;
sx = 232 - sx;
sx += 128;
sy = (240 + 2) - sy;
}
int code = m_sprite_ram[offs + 1];
int color = m_sprite_ram[offs + 2] & 0x0f;
m_gfxdecode->gfx(2)->transpen(bitmap, cliprect, code, color, flipx, flipy, sx, sy, 0);
}
// draw the tiles with priority over the sprites
m_layer0_tilemap->draw(screen, bitmap, cliprect, 1, 0);
m_layer1_tilemap->draw(screen, bitmap, cliprect, 1, 0);
return 0; return 0;
} }
@ -314,7 +374,18 @@ uint32_t popper_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap
// DRAWGFX LAYOUTS // DRAWGFX LAYOUTS
//************************************************************************** //**************************************************************************
static const gfx_layout charlayout = static const gfx_layout layer0_charlayout =
{
8,8,
RGN_FRAC(2,2),
1,
{ 0, 4 },
{ STEP4(8,1), STEP4(0,1) },
{ STEP8(0,16) },
16*8
};
static const gfx_layout layer1_charlayout =
{ {
8,8, 8,8,
RGN_FRAC(2,2), RGN_FRAC(2,2),
@ -337,19 +408,40 @@ static const gfx_layout spritelayout =
}; };
static GFXDECODE_START( popper ) static GFXDECODE_START( popper )
GFXDECODE_ENTRY("tiles", 0, charlayout, 0, 16) GFXDECODE_ENTRY("tiles", 0, layer0_charlayout, 0, 32)
GFXDECODE_ENTRY("tiles", 0, layer1_charlayout, 0, 16)
GFXDECODE_ENTRY("sprites", 0, spritelayout, 0, 16) GFXDECODE_ENTRY("sprites", 0, spritelayout, 0, 16)
GFXDECODE_END GFXDECODE_END
TILE_GET_INFO_MEMBER( popper_state::tile_info ) // attribute ram layout
// 7------- high priority
// -654---- layer0 color
// ----3210 layer1 color
TILE_GET_INFO_MEMBER( popper_state::layer0_tile_info )
{ {
int code = (m_vram_page << 8) | m_ram[0x100 + tile_index]; int code = (m_vram_page << 8) | m_video_ram[tile_index];
int attr = m_ram[0x900 + tile_index]; int attr = m_attribute_ram[tile_index];
int color = attr >> 4; int color = (~m_back_color & 1) << 3 | ((attr >> 4) & 7);
color <<= 1;
// high priority only applies if a color is set
tileinfo.category = BIT(attr, 7) && (attr & 0x70);
SET_TILE_INFO_MEMBER(0, code, color, 0); SET_TILE_INFO_MEMBER(0, code, color, 0);
} }
TILE_GET_INFO_MEMBER( popper_state::layer1_tile_info )
{
int code = (m_vram_page << 8) | m_video_ram[tile_index];
int attr = m_attribute_ram[tile_index];
int color = attr & 0x0f;
tileinfo.category = BIT(attr, 7);
SET_TILE_INFO_MEMBER(1, code, color, 0);
}
//************************************************************************** //**************************************************************************
// SUBCPU // SUBCPU
@ -389,26 +481,28 @@ WRITE8_MEMBER( popper_state::ay1_w )
WRITE8_MEMBER( popper_state::nmi_control_w ) WRITE8_MEMBER( popper_state::nmi_control_w )
{ {
// logerror("nmi_control_w: %02x\n", data);
m_nmi_enable = data & 1; m_nmi_enable = data & 1;
} }
WRITE8_MEMBER( popper_state::intcycle_w ) WRITE8_MEMBER( popper_state::intcycle_w )
{ {
// set to 0 and apparently not used by the game
logerror("intcycle_w: %d = %02x\n", offset, data); logerror("intcycle_w: %d = %02x\n", offset, data);
} }
READ8_MEMBER( popper_state::watchdog_clear_r ) READ8_MEMBER( popper_state::watchdog_clear_r )
{ {
logerror("watchdog_clear_r\n");
return 0; return 0;
} }
void popper_state::machine_start() void popper_state::machine_start()
{ {
// create tilemap // create tilemaps
m_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(popper_state::tile_info), this), TILEMAP_SCAN_COLS, 8, 8, 48, 32); m_layer0_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(popper_state::layer0_tile_info), this), TILEMAP_SCAN_COLS, 8, 8, 48, 32);
m_tilemap->set_transparent_pen(3); m_layer0_tilemap->set_transparent_pen(1);
m_layer1_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(popper_state::layer1_tile_info), this), TILEMAP_SCAN_COLS, 8, 8, 48, 32);
m_layer1_tilemap->set_transparent_pen(0);
// allocate and start scanline timer // allocate and start scanline timer
m_scanline_timer = timer_alloc(0); m_scanline_timer = timer_alloc(0);
@ -416,12 +510,14 @@ void popper_state::machine_start()
// register for save states // register for save states
save_item(NAME(m_nmi_enable)); save_item(NAME(m_nmi_enable));
save_item(NAME(m_back_color));
save_item(NAME(m_vram_page)); save_item(NAME(m_vram_page));
} }
void popper_state::machine_reset() void popper_state::machine_reset()
{ {
m_nmi_enable = 0; m_nmi_enable = 0;
m_back_color = 0;
m_vram_page = 0; m_vram_page = 0;
} }