edevices/pzletime.cpp: cleanups

* Make video blinking more sensical;
* Convert custom ticket handling to ticket_dispenser_device;
* Convert eeprom/ticket to portw;
* Avoid potential out-of-cliprect bitmap layer drawing;
This commit is contained in:
angelosa 2024-08-23 10:17:15 +02:00
parent 78de53faec
commit ad85bfcee9
3 changed files with 82 additions and 91 deletions

View File

@ -415,4 +415,4 @@ ROM_END
*
*************************************/
GAME( 199?, mwarr, 0, mwarr, mwarr, mwarr_state, empty_init, ROT0, "Elettronica Video-Games S.R.L.", "Mighty Warriors (24/1)", MACHINE_SUPPORTS_SAVE )
GAME( 199?, mwarr, 0, mwarr, mwarr, mwarr_state, empty_init, ROT0, "Elettronica Video-Games", "Mighty Warriors (24/1)", MACHINE_SUPPORTS_SAVE )

View File

@ -1,25 +1,28 @@
// license:BSD-3-Clause
// copyright-holders:Angelo Salese, Pierpaolo Prazzoli
/*****************************************************************************************
/**************************************************************************************************
Puzzle Time (Prototype)
Elettronica Video-Games S.R.L, 199?
Puzzle Time (Prototype)
Elettronica Video-Games S.R.L, 199?
driver by Angelo Salese and Pierpaolo Prazzoli
dump and info provided by Yoshi
dump and info provided by Yoshi
To initialize the eeprom, keep Service button pressed at boot.
To initialize the eeprom keep Service button pressed at boot.
Notes:
- Text tilemap flickering could be a bit slower / faster
- Brightness effect could be a bit darker / lighter
TODO:
- Text tilemap blinking could be a bit slower / faster
- Brightness effect could be a bit darker / lighter
- Ticket test in service mode keeps outputting tickets once enabled, and flips statuses between
"IN SEDE" (online) and "FUORI SEDE" (offline). Is it intended behaviour? Verify in-game.
*****************************************************************************************/
**************************************************************************************************/
#include "emu.h"
#include "cpu/m68000/m68000.h"
#include "sound/okim6295.h"
#include "machine/eepromser.h"
#include "machine/ticket.h"
#include "sound/okim6295.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
@ -31,28 +34,35 @@ namespace {
class pzletime_state : public driver_device
{
public:
pzletime_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_video_regs(*this, "video_regs"),
m_tilemap_regs(*this, "tilemap_regs"),
m_bg_videoram(*this, "bg_videoram"),
m_mid_videoram(*this, "mid_videoram"),
m_txt_videoram(*this, "txt_videoram"),
m_spriteram(*this, "spriteram"),
m_maincpu(*this, "maincpu"),
m_oki(*this, "oki"),
m_eeprom(*this, "eeprom"),
m_gfxdecode(*this, "gfxdecode"),
m_screen(*this, "screen"),
m_palette(*this, "palette%u", 0U)
pzletime_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_oki(*this, "oki")
, m_eeprom(*this, "eeprom")
, m_gfxdecode(*this, "gfxdecode")
, m_screen(*this, "screen")
, m_palette(*this, "palette%u", 0U)
, m_ticket(*this, "ticket")
, m_video_regs(*this, "video_regs")
, m_tilemap_regs(*this, "tilemap_regs")
, m_bg_videoram(*this, "bg_videoram")
, m_mid_videoram(*this, "mid_videoram")
, m_txt_videoram(*this, "txt_videoram")
, m_spriteram(*this, "spriteram")
{ }
void pzletime(machine_config &config);
int ticket_status_r();
private:
/* memory pointers */
required_device<cpu_device> m_maincpu;
required_device<okim6295_device> m_oki;
required_device<eeprom_serial_93cxx_device> m_eeprom;
required_device<gfxdecode_device> m_gfxdecode;
required_device<screen_device> m_screen;
required_device_array<palette_device, 2> m_palette;
required_device<ticket_dispenser_device> m_ticket;
required_shared_ptr<uint16_t> m_video_regs;
required_shared_ptr<uint16_t> m_tilemap_regs;
required_shared_ptr<uint16_t> m_bg_videoram;
@ -60,32 +70,22 @@ private:
required_shared_ptr<uint16_t> m_txt_videoram;
required_shared_ptr<uint16_t> m_spriteram;
/* video-related */
tilemap_t *m_mid_tilemap = nullptr;
tilemap_t *m_txt_tilemap = nullptr;
tilemap_t *m_mid_tilemap = nullptr;
tilemap_t *m_txt_tilemap = nullptr;
/* misc */
int m_ticket = 0;
void mid_videoram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
void txt_videoram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
void ticket_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
void video_regs_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
void eeprom_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
void oki_bank_w(uint16_t data);
TILE_GET_INFO_MEMBER(get_mid_tile_info);
TILE_GET_INFO_MEMBER(get_txt_tile_info);
void main_map(address_map &map);
virtual void machine_start() override;
virtual void machine_reset() override;
virtual void video_start() override;
void pzletime_palette(palette_device &palette) const;
uint32_t screen_update_pzletime(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
required_device<cpu_device> m_maincpu;
required_device<okim6295_device> m_oki;
required_device<eeprom_serial_93cxx_device> m_eeprom;
required_device<gfxdecode_device> m_gfxdecode;
required_device<screen_device> m_screen;
required_device_array<palette_device, 2> m_palette;
void pzletime_map(address_map &map);
void mid_videoram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
void txt_videoram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
void video_regs_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
void oki_bank_w(uint16_t data);
TILE_GET_INFO_MEMBER(get_mid_tile_info);
TILE_GET_INFO_MEMBER(get_txt_tile_info);
void palette_init(palette_device &palette) const;
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
};
@ -117,10 +117,11 @@ void pzletime_state::video_start()
m_txt_tilemap->set_transparent_pen(0);
}
uint32_t pzletime_state::screen_update_pzletime(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
uint32_t pzletime_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
bitmap.fill(m_palette[0]->pen(0), cliprect); //bg pen
bitmap.fill(m_palette[0]->pen(0), cliprect);
// TODO: [3] bits 0-2 may actually control tilemap enable, per layer
m_txt_tilemap->set_scrolly(0, m_tilemap_regs[0] - 3);
m_txt_tilemap->set_scrollx(0, m_tilemap_regs[1]);
@ -135,8 +136,11 @@ uint32_t pzletime_state::screen_update_pzletime(screen_device &screen, bitmap_rg
{
for (int x = 0; x < 512; x++)
{
if (m_bg_videoram[count] & 0x8000)
bitmap.pix((y - 18) & 0xff, (x - 32) & 0x1ff) = m_palette[1]->pen(m_bg_videoram[count] & 0x7fff);
const uint16_t pen_dot = m_bg_videoram[count];
const int res_y = (y - 18) & 0xff;
const int res_x = (x - 32) & 0x1ff;
if (pen_dot & 0x8000 && cliprect.contains(res_x, res_y))
bitmap.pix(res_y, res_x) = m_palette[1]->pen(pen_dot & 0x7fff);
count++;
}
@ -162,7 +166,8 @@ uint32_t pzletime_state::screen_update_pzletime(screen_device &screen, bitmap_rg
}
m_txt_tilemap->draw(screen, bitmap, cliprect, 0, 0);
if ((screen.frame_number() % 16) != 0)
// TODO: unconfirmed blink ratio
if ((screen.frame_number() & 8) != 0)
m_txt_tilemap->draw(screen, bitmap, cliprect, 1, 0);
return 0;
@ -180,22 +185,6 @@ void pzletime_state::txt_videoram_w(offs_t offset, uint16_t data, uint16_t mem_m
m_txt_tilemap->mark_tile_dirty(offset);
}
void pzletime_state::eeprom_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
if (ACCESSING_BITS_0_7)
{
m_eeprom->di_write(data & 0x01);
m_eeprom->cs_write((data & 0x02) ? ASSERT_LINE : CLEAR_LINE );
m_eeprom->clk_write((data & 0x04) ? ASSERT_LINE : CLEAR_LINE );
}
}
void pzletime_state::ticket_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
if (ACCESSING_BITS_0_7)
m_ticket = data & 1;
}
void pzletime_state::video_regs_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
COMBINE_DATA(&m_video_regs[offset]);
@ -214,12 +203,7 @@ void pzletime_state::oki_bank_w(uint16_t data)
m_oki->set_rom_bank(data & 0x3);
}
int pzletime_state::ticket_status_r()
{
return (m_ticket && !(m_screen->frame_number() % 128));
}
void pzletime_state::pzletime_map(address_map &map)
void pzletime_state::main_map(address_map &map)
{
map(0x000000, 0x3fffff).rom();
map(0x700000, 0x700005).ram().w(FUNC(pzletime_state::video_regs_w)).share("video_regs");
@ -230,8 +214,8 @@ void pzletime_state::pzletime_map(address_map &map)
map(0xc00000, 0xc00fff).ram().w(FUNC(pzletime_state::mid_videoram_w)).share("mid_videoram");
map(0xc01000, 0xc01fff).ram().w(FUNC(pzletime_state::txt_videoram_w)).share("txt_videoram");
map(0xd00000, 0xd01fff).ram().share("spriteram");
map(0xe00000, 0xe00001).portr("INPUT").w(FUNC(pzletime_state::eeprom_w));
map(0xe00002, 0xe00003).portr("SYSTEM").w(FUNC(pzletime_state::ticket_w));
map(0xe00000, 0xe00001).portr("INPUT").portw("EEPROMOUT");
map(0xe00002, 0xe00003).portr("SYSTEM").portw("TICKETOUT");
map(0xe00004, 0xe00005).w(FUNC(pzletime_state::oki_bank_w));
map(0xf00000, 0xf0ffff).ram();
}
@ -245,8 +229,9 @@ static INPUT_PORTS_START( pzletime )
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_VBLANK("screen")
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("eeprom", eeprom_serial_93cxx_device, do_read) /* eeprom */
PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_MEMBER(pzletime_state, ticket_status_r) /* ticket dispenser */
PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("eeprom", eeprom_serial_93cxx_device, do_read)
// NOTE: was (m_ticket && !(m_screen->frame_number() % 128));
PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("ticket", ticket_dispenser_device, line_r)
PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("INPUT")
@ -266,6 +251,14 @@ static INPUT_PORTS_START( pzletime )
PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_START2 )
PORT_START("EEPROMOUT")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_WRITE_LINE_DEVICE_MEMBER("eeprom", eeprom_serial_93cxx_device, di_write)
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_WRITE_LINE_DEVICE_MEMBER("eeprom", eeprom_serial_93cxx_device, cs_write)
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_WRITE_LINE_DEVICE_MEMBER("eeprom", eeprom_serial_93cxx_device, clk_write)
PORT_START("TICKETOUT")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_WRITE_LINE_DEVICE_MEMBER("ticket", ticket_dispenser_device, motor_w)
INPUT_PORTS_END
@ -277,19 +270,17 @@ GFXDECODE_END
void pzletime_state::machine_start()
{
save_item(NAME(m_ticket));
}
void pzletime_state::machine_reset()
{
m_ticket = 0;
}
void pzletime_state::pzletime(machine_config &config)
{
/* basic machine hardware */
M68000(config, m_maincpu, 10000000);
m_maincpu->set_addrmap(AS_PROGRAM, &pzletime_state::pzletime_map);
m_maincpu->set_addrmap(AS_PROGRAM, &pzletime_state::main_map);
m_maincpu->set_vblank_int("screen", FUNC(pzletime_state::irq4_line_hold));
/* video hardware */
@ -298,7 +289,7 @@ void pzletime_state::pzletime(machine_config &config)
m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500) /* not accurate */);
m_screen->set_size(64*8, 32*8);
m_screen->set_visarea(0*8, 48*8-1, 0*8, 28*8-1);
m_screen->set_screen_update(FUNC(pzletime_state::screen_update_pzletime));
m_screen->set_screen_update(FUNC(pzletime_state::screen_update));
GFXDECODE(config, m_gfxdecode, m_palette[0], gfx_pzletime);
@ -307,8 +298,8 @@ void pzletime_state::pzletime(machine_config &config)
PALETTE(config, m_palette[1], palette_device::RGB_555);
EEPROM_93C46_16BIT(config, "eeprom");
TICKET_DISPENSER(config, m_ticket, attotime::from_msec(2000), TICKET_MOTOR_ACTIVE_HIGH, TICKET_STATUS_ACTIVE_HIGH);
/* sound hardware */
SPEAKER(config, "mono").front_center();
OKIM6295(config, m_oki, 937500, okim6295_device::PIN7_HIGH); //freq & pin7 taken from stlforce
m_oki->add_route(ALL_OUTPUTS, "mono", 1.0);
@ -360,4 +351,4 @@ ROM_END
} // anonymous namespace
GAME( 199?, pzletime, 0, pzletime, pzletime, pzletime_state, empty_init, ROT0, "Elettronica Video-Games S.R.L.", "Puzzle Time (prototype)", MACHINE_SUPPORTS_SAVE )
GAME( 199?, pzletime, 0, pzletime, pzletime, pzletime_state, empty_init, ROT0, "Elettronica Video-Games", "Puzzle Time (prototype)", MACHINE_SUPPORTS_SAVE )

View File

@ -591,6 +591,6 @@ GAME( 1994, stlforce, 0, stlforce, stlforce, stlforce_state, empty_init,
GAME( 1995, mortalr, 0, mortalr, stlforce, stlforce_state, empty_init, ROT0, "New Dream Games", "Mortal Race", MACHINE_SUPPORTS_SAVE ) // based on the same rough codebase as Top Driving tch/topdrive.cpp but not the same game, so not a clone
GAME( 1995, twinbrat, 0, twinbrat, stlforce, twinbrat_state, empty_init, ROT0, "Elettronica Video-Games S.R.L.", "Twin Brats (set 1)", MACHINE_SUPPORTS_SAVE )
GAME( 1995, twinbrata, twinbrat, twinbrat, stlforce, twinbrat_state, empty_init, ROT0, "Elettronica Video-Games S.R.L.", "Twin Brats (set 2)", MACHINE_SUPPORTS_SAVE )
GAME( 1995, twinbratb, twinbrat, twinbrat, stlforce, twinbrat_state, empty_init, ROT0, "Elettronica Video-Games S.R.L.", "Twin Brats (set 3)", MACHINE_SUPPORTS_SAVE )
GAME( 1995, twinbrat, 0, twinbrat, stlforce, twinbrat_state, empty_init, ROT0, "Elettronica Video-Games", "Twin Brats (set 1)", MACHINE_SUPPORTS_SAVE )
GAME( 1995, twinbrata, twinbrat, twinbrat, stlforce, twinbrat_state, empty_init, ROT0, "Elettronica Video-Games", "Twin Brats (set 2)", MACHINE_SUPPORTS_SAVE )
GAME( 1995, twinbratb, twinbrat, twinbrat, stlforce, twinbrat_state, empty_init, ROT0, "Elettronica Video-Games", "Twin Brats (set 3)", MACHINE_SUPPORTS_SAVE )