mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
- galaxian/galaxold.cpp: updated clock for superbikg as per measurement
- olympia/dday.cpp, olympia/portrait.cpp: consolidated drivers in single files - skeleton/elcirculo.cpp: added a basic memory map - vtech/vsmilepro.cpp: demoted to MIS
This commit is contained in:
parent
f1a11f8b23
commit
855efc855c
@ -1863,7 +1863,7 @@ void galaxold_state::superbikg(machine_config &config)
|
||||
{
|
||||
galaxold_base(config);
|
||||
|
||||
s2650_device &s2650(S2650(config.replace(), m_maincpu, PIXEL_CLOCK / 4));
|
||||
s2650_device &s2650(S2650(config.replace(), m_maincpu, 1'500'000)); // 1.53292 MHz measured with logic analyzer
|
||||
s2650.set_addrmap(AS_PROGRAM, &galaxold_state::superbikg_map);
|
||||
s2650.set_addrmap(AS_IO, &galaxold_state::superbikg_io);
|
||||
s2650.set_addrmap(AS_DATA, &galaxold_state::superbikg_data);
|
||||
|
@ -1,5 +1,6 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Zsolt Vasvari
|
||||
// copyright-holders: Zsolt Vasvari
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
D-Day
|
||||
@ -52,27 +53,399 @@ write:
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "dday.h"
|
||||
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "sound/ay8910.h"
|
||||
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
#include "tilemap.h"
|
||||
|
||||
|
||||
void dday_state::dday_map(address_map &map)
|
||||
namespace {
|
||||
|
||||
class dday_state : public driver_device
|
||||
{
|
||||
public:
|
||||
dday_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
driver_device(mconfig, type, tag),
|
||||
m_textvideoram(*this, "textvideoram"),
|
||||
m_fgvideoram(*this, "fgvideoram"),
|
||||
m_bgvideoram(*this, "bgvideoram"),
|
||||
m_colorram(*this, "colorram"),
|
||||
m_sl_map(*this, "sl_map"),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_gfxdecode(*this, "gfxdecode"),
|
||||
m_screen(*this, "screen"),
|
||||
m_palette(*this, "palette"),
|
||||
m_ay1(*this, "ay1")
|
||||
{ }
|
||||
|
||||
void dday(machine_config &config);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
virtual void video_start() override;
|
||||
|
||||
private:
|
||||
required_shared_ptr<uint8_t> m_textvideoram;
|
||||
required_shared_ptr<uint8_t> m_fgvideoram;
|
||||
required_shared_ptr<uint8_t> m_bgvideoram;
|
||||
required_shared_ptr<uint8_t> m_colorram;
|
||||
required_region_ptr<uint8_t> m_sl_map;
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<palette_device> m_palette;
|
||||
required_device<ay8912_device> m_ay1;
|
||||
|
||||
tilemap_t *m_fg_tilemap = nullptr;
|
||||
tilemap_t *m_bg_tilemap = nullptr;
|
||||
tilemap_t *m_text_tilemap = nullptr;
|
||||
tilemap_t *m_sl_tilemap = nullptr;
|
||||
bitmap_ind16 m_main_bitmap = 0;
|
||||
uint8_t m_control = 0;
|
||||
uint8_t m_sl_image = 0;
|
||||
uint8_t m_sl_enable = 0;
|
||||
int8_t m_timer_value = 0;
|
||||
emu_timer *m_countdown_timer = nullptr;
|
||||
|
||||
uint8_t countdown_timer_r();
|
||||
void bgvideoram_w(offs_t offset, uint8_t data);
|
||||
void fgvideoram_w(offs_t offset, uint8_t data);
|
||||
void textvideoram_w(offs_t offset, uint8_t data);
|
||||
void colorram_w(offs_t offset, uint8_t data);
|
||||
uint8_t colorram_r(offs_t offset);
|
||||
void sl_control_w(uint8_t data);
|
||||
void control_w(uint8_t data);
|
||||
TILE_GET_INFO_MEMBER(get_bg_tile_info);
|
||||
TILE_GET_INFO_MEMBER(get_fg_tile_info);
|
||||
TILE_GET_INFO_MEMBER(get_text_tile_info);
|
||||
TILE_GET_INFO_MEMBER(get_sl_tile_info);
|
||||
void palette_init(palette_device &palette) const;
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
TIMER_CALLBACK_MEMBER(countdown_timer_callback);
|
||||
void start_countdown_timer();
|
||||
void program_map(address_map &map);
|
||||
};
|
||||
|
||||
|
||||
/* Note: There seems to be no way to reset this timer via hardware.
|
||||
The game uses a difference method to reset it to 99.
|
||||
|
||||
Thanks Zwaxy for the timer info. */
|
||||
|
||||
uint8_t dday_state::countdown_timer_r()
|
||||
{
|
||||
return ((m_timer_value / 10) << 4) | (m_timer_value % 10);
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(dday_state::countdown_timer_callback)
|
||||
{
|
||||
m_timer_value--;
|
||||
|
||||
if (m_timer_value < 0)
|
||||
m_timer_value = 99;
|
||||
}
|
||||
|
||||
void dday_state::start_countdown_timer()
|
||||
{
|
||||
m_timer_value = 0;
|
||||
|
||||
m_countdown_timer->adjust(attotime::from_seconds(1), 0, attotime::from_seconds(1));
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Convert the color PROMs into a more useable format.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
void dday_state::palette_init(palette_device &palette) const
|
||||
{
|
||||
uint8_t const *const color_prom = memregion("proms")->base();
|
||||
|
||||
palette.set_shadow_factor(1.0 / 8);
|
||||
|
||||
// create a lookup table for the palette
|
||||
for (int i = 0; i < 0x100; i++)
|
||||
{
|
||||
int const r = pal4bit(color_prom[i + 0x000]);
|
||||
int const g = pal4bit(color_prom[i + 0x100]);
|
||||
int const b = pal4bit(color_prom[i + 0x200]);
|
||||
|
||||
palette.set_indirect_color(i, rgb_t(r, g, b));
|
||||
}
|
||||
|
||||
for (int i = 0; i < 0x100; i++)
|
||||
palette.set_pen_indirect(i, i);
|
||||
|
||||
// HACK!!! This table is handgenerated, but it matches the screenshot. I have no clue how it really works
|
||||
palette.set_pen_indirect(0*8+0+0, 0x00);
|
||||
palette.set_pen_indirect(0*8+0+1, 0x01);
|
||||
palette.set_pen_indirect(0*8+0+2, 0x15);
|
||||
palette.set_pen_indirect(0*8+0+3, 0x02);
|
||||
palette.set_pen_indirect(0*8+4+0, 0x00);
|
||||
palette.set_pen_indirect(0*8+4+1, 0x01);
|
||||
palette.set_pen_indirect(0*8+4+2, 0x15);
|
||||
palette.set_pen_indirect(0*8+4+3, 0x02);
|
||||
|
||||
palette.set_pen_indirect(1*8+0+0, 0x04);
|
||||
palette.set_pen_indirect(1*8+0+1, 0x05);
|
||||
palette.set_pen_indirect(1*8+0+2, 0x03);
|
||||
palette.set_pen_indirect(1*8+0+3, 0x07);
|
||||
palette.set_pen_indirect(1*8+4+0, 0x04);
|
||||
palette.set_pen_indirect(1*8+4+1, 0x05);
|
||||
palette.set_pen_indirect(1*8+4+2, 0x03);
|
||||
palette.set_pen_indirect(1*8+4+3, 0x07);
|
||||
|
||||
palette.set_pen_indirect(2*8+0+0, 0x08);
|
||||
palette.set_pen_indirect(2*8+0+1, 0x15);
|
||||
palette.set_pen_indirect(2*8+0+2, 0x0a);
|
||||
palette.set_pen_indirect(2*8+0+3, 0x03);
|
||||
palette.set_pen_indirect(2*8+4+0, 0x08);
|
||||
palette.set_pen_indirect(2*8+4+1, 0x15);
|
||||
palette.set_pen_indirect(2*8+4+2, 0x0a);
|
||||
palette.set_pen_indirect(2*8+4+3, 0x03);
|
||||
|
||||
palette.set_pen_indirect(3*8+0+0, 0x08);
|
||||
palette.set_pen_indirect(3*8+0+1, 0x15);
|
||||
palette.set_pen_indirect(3*8+0+2, 0x0a);
|
||||
palette.set_pen_indirect(3*8+0+3, 0x03);
|
||||
palette.set_pen_indirect(3*8+4+0, 0x08);
|
||||
palette.set_pen_indirect(3*8+4+1, 0x15);
|
||||
palette.set_pen_indirect(3*8+4+2, 0x0a);
|
||||
palette.set_pen_indirect(3*8+4+3, 0x03);
|
||||
|
||||
palette.set_pen_indirect(4*8+0+0, 0x10);
|
||||
palette.set_pen_indirect(4*8+0+1, 0x11);
|
||||
palette.set_pen_indirect(4*8+0+2, 0x12);
|
||||
palette.set_pen_indirect(4*8+0+3, 0x07);
|
||||
palette.set_pen_indirect(4*8+4+0, 0x10);
|
||||
palette.set_pen_indirect(4*8+4+1, 0x11);
|
||||
palette.set_pen_indirect(4*8+4+2, 0x12);
|
||||
palette.set_pen_indirect(4*8+4+3, 0x07);
|
||||
|
||||
palette.set_pen_indirect(5*8+0+0, 0x1d);
|
||||
palette.set_pen_indirect(5*8+0+1, 0x15);
|
||||
palette.set_pen_indirect(5*8+0+2, 0x16);
|
||||
palette.set_pen_indirect(5*8+0+3, 0x1b);
|
||||
palette.set_pen_indirect(5*8+4+0, 0x1d);
|
||||
palette.set_pen_indirect(5*8+4+1, 0x15);
|
||||
palette.set_pen_indirect(5*8+4+2, 0x16);
|
||||
palette.set_pen_indirect(5*8+4+3, 0x1b);
|
||||
|
||||
palette.set_pen_indirect(6*8+0+0, 0x1d);
|
||||
palette.set_pen_indirect(6*8+0+1, 0x15);
|
||||
palette.set_pen_indirect(6*8+0+2, 0x1a);
|
||||
palette.set_pen_indirect(6*8+0+3, 0x1b);
|
||||
palette.set_pen_indirect(6*8+4+0, 0x1d);
|
||||
palette.set_pen_indirect(6*8+4+1, 0x15);
|
||||
palette.set_pen_indirect(6*8+4+2, 0x1a);
|
||||
palette.set_pen_indirect(6*8+4+3, 0x1b);
|
||||
|
||||
palette.set_pen_indirect(7*8+0+0, 0x1d);
|
||||
palette.set_pen_indirect(7*8+0+1, 0x02);
|
||||
palette.set_pen_indirect(7*8+0+2, 0x04);
|
||||
palette.set_pen_indirect(7*8+0+3, 0x1b);
|
||||
palette.set_pen_indirect(7*8+4+0, 0x1d);
|
||||
palette.set_pen_indirect(7*8+4+1, 0x02);
|
||||
palette.set_pen_indirect(7*8+4+2, 0x04);
|
||||
palette.set_pen_indirect(7*8+4+3, 0x1b);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Callbacks for the TileMap code
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
TILE_GET_INFO_MEMBER(dday_state::get_bg_tile_info)
|
||||
{
|
||||
int const code = m_bgvideoram[tile_index];
|
||||
tileinfo.set(0, code, code >> 5, 0);
|
||||
}
|
||||
|
||||
TILE_GET_INFO_MEMBER(dday_state::get_fg_tile_info)
|
||||
{
|
||||
int const flipx = m_colorram[tile_index & 0x03e0] & 0x01;
|
||||
int const code = m_fgvideoram[flipx ? tile_index ^ 0x1f : tile_index];
|
||||
tileinfo.set(2, code, code >> 5, flipx ? TILE_FLIPX : 0);
|
||||
}
|
||||
|
||||
TILE_GET_INFO_MEMBER(dday_state::get_text_tile_info)
|
||||
{
|
||||
int const code = m_textvideoram[tile_index];
|
||||
tileinfo.set(1, code, code >> 5, 0);
|
||||
}
|
||||
|
||||
TILE_GET_INFO_MEMBER(dday_state::get_sl_tile_info)
|
||||
{
|
||||
uint8_t *sl_map = &m_sl_map[(m_sl_image & 0x07) * 0x0200];
|
||||
|
||||
int const flipx = (tile_index >> 4) & 0x01;
|
||||
int const sl_flipx = (m_sl_image >> 3) & 0x01;
|
||||
|
||||
// bit 4 is really a flip indicator. Need to shift bits 5-9 to the right by 1
|
||||
tile_index = ((tile_index & 0x03e0) >> 1) | (tile_index & 0x0f);
|
||||
|
||||
int code = sl_map[flipx ? tile_index ^ 0x0f : tile_index];
|
||||
|
||||
if ((sl_flipx != flipx) && (code & 0x80))
|
||||
// no mirroring, draw dark spot
|
||||
code = 1;
|
||||
|
||||
tileinfo.set(3, code & 0x3f, 0, flipx ? TILE_FLIPX : 0);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Start the video hardware emulation.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
void dday_state::video_start()
|
||||
{
|
||||
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(dday_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
|
||||
m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(dday_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
|
||||
m_text_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(dday_state::get_text_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
|
||||
m_sl_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(dday_state::get_sl_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
|
||||
|
||||
m_screen->register_screen_bitmap(m_main_bitmap);
|
||||
|
||||
m_bg_tilemap->set_transmask(0, 0x00f0, 0xff0f); // pens 0-3 have priority over the foreground layer
|
||||
m_fg_tilemap->set_transparent_pen(0);
|
||||
m_text_tilemap->set_transparent_pen(0);
|
||||
|
||||
m_countdown_timer = timer_alloc(FUNC(dday_state::countdown_timer_callback), this);
|
||||
|
||||
start_countdown_timer();
|
||||
}
|
||||
|
||||
void dday_state::bgvideoram_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
m_bgvideoram[offset] = data;
|
||||
m_bg_tilemap->mark_tile_dirty(offset);
|
||||
}
|
||||
|
||||
void dday_state::fgvideoram_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
m_fgvideoram[offset] = data;
|
||||
m_fg_tilemap->mark_tile_dirty(offset);
|
||||
m_fg_tilemap->mark_tile_dirty(offset ^ 0x1f); // for flipx case
|
||||
}
|
||||
|
||||
void dday_state::textvideoram_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
m_textvideoram[offset] = data;
|
||||
m_text_tilemap->mark_tile_dirty(offset);
|
||||
}
|
||||
|
||||
void dday_state::colorram_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
offset &= 0x03e0;
|
||||
|
||||
m_colorram[offset & 0x3e0] = data;
|
||||
|
||||
for (int i = 0; i < 0x20; i++)
|
||||
m_fg_tilemap->mark_tile_dirty(offset + i);
|
||||
}
|
||||
|
||||
uint8_t dday_state::colorram_r(offs_t offset)
|
||||
{
|
||||
return m_colorram[offset & 0x03e0];
|
||||
}
|
||||
|
||||
|
||||
void dday_state::sl_control_w(uint8_t data)
|
||||
{
|
||||
if (m_sl_image != data)
|
||||
{
|
||||
m_sl_image = data;
|
||||
m_sl_tilemap->mark_all_dirty();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void dday_state::control_w(uint8_t data)
|
||||
{
|
||||
// if (data & 0xac) logerror("Control = %02X\n", data & 0xac);
|
||||
|
||||
// bit 0 is coin counter 1
|
||||
machine().bookkeeping().coin_counter_w(0, data & 0x01);
|
||||
|
||||
// bit 1 is coin counter 2
|
||||
machine().bookkeeping().coin_counter_w(1, data & 0x02);
|
||||
|
||||
// bit 4 is sound enable
|
||||
if (!(data & 0x10) && (m_control & 0x10))
|
||||
m_ay1->reset();
|
||||
|
||||
machine().sound().system_mute(!BIT(data, 4));
|
||||
|
||||
// bit 6 is search light enable
|
||||
m_sl_enable = data & 0x40;
|
||||
|
||||
m_control = data;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Display refresh
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
uint32_t dday_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
m_bg_tilemap->draw(screen, m_main_bitmap, cliprect, TILEMAP_DRAW_LAYER1, 0);
|
||||
m_fg_tilemap->draw(screen, m_main_bitmap, cliprect, 0, 0);
|
||||
m_bg_tilemap->draw(screen, m_main_bitmap, cliprect, TILEMAP_DRAW_LAYER0, 0);
|
||||
m_text_tilemap->draw(screen, m_main_bitmap, cliprect, 0, 0);
|
||||
|
||||
if (m_sl_enable)
|
||||
{
|
||||
// apply shadow
|
||||
bitmap_ind16 &sl_bitmap = m_sl_tilemap->pixmap();
|
||||
|
||||
for (int x = cliprect.min_x; x <= cliprect.max_x; x++)
|
||||
for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
|
||||
{
|
||||
uint16_t src_pixel = m_main_bitmap.pix(y, x);
|
||||
|
||||
if (sl_bitmap.pix(y, x) == 0xff)
|
||||
src_pixel += m_palette->entries();
|
||||
|
||||
bitmap.pix(y, x) = src_pixel;
|
||||
}
|
||||
}
|
||||
else
|
||||
copybitmap(bitmap, m_main_bitmap, 0, 0, 0, 0, cliprect);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void dday_state::program_map(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x3fff).rom();
|
||||
map(0x4000, 0x4000).w(FUNC(dday_state::dday_sl_control_w));
|
||||
map(0x5000, 0x53ff).ram().w(FUNC(dday_state::dday_textvideoram_w)).share("textvideoram");
|
||||
map(0x5400, 0x57ff).ram().w(FUNC(dday_state::dday_fgvideoram_w)).share("fgvideoram");
|
||||
map(0x5800, 0x5bff).ram().w(FUNC(dday_state::dday_bgvideoram_w)).share("bgvideoram");
|
||||
map(0x5c00, 0x5fff).rw(FUNC(dday_state::dday_colorram_r), FUNC(dday_state::dday_colorram_w)).share("colorram");
|
||||
map(0x4000, 0x4000).w(FUNC(dday_state::sl_control_w));
|
||||
map(0x5000, 0x53ff).ram().w(FUNC(dday_state::textvideoram_w)).share(m_textvideoram);
|
||||
map(0x5400, 0x57ff).ram().w(FUNC(dday_state::fgvideoram_w)).share(m_fgvideoram);
|
||||
map(0x5800, 0x5bff).ram().w(FUNC(dday_state::bgvideoram_w)).share(m_bgvideoram);
|
||||
map(0x5c00, 0x5fff).rw(FUNC(dday_state::colorram_r), FUNC(dday_state::colorram_w)).share(m_colorram);
|
||||
map(0x6000, 0x63ff).ram();
|
||||
map(0x6400, 0x6401).mirror(0x000e).w(m_ay1, FUNC(ay8912_device::address_data_w));
|
||||
map(0x6800, 0x6801).w("ay2", FUNC(ay8912_device::address_data_w));
|
||||
map(0x6c00, 0x6c00).portr("BUTTONS");
|
||||
map(0x7000, 0x7000).portr("DSW0");
|
||||
map(0x7400, 0x7400).portr("DSW1");
|
||||
map(0x7800, 0x7800).rw(FUNC(dday_state::dday_countdown_timer_r), FUNC(dday_state::dday_control_w));
|
||||
map(0x7800, 0x7800).rw(FUNC(dday_state::countdown_timer_r), FUNC(dday_state::control_w));
|
||||
map(0x7c00, 0x7c00).portr("PADDLE");
|
||||
}
|
||||
|
||||
@ -82,12 +455,12 @@ static INPUT_PORTS_START( dday )
|
||||
PORT_START("BUTTONS")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 )
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN2 )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON1 ) /* fire button */
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON1 ) // fire button
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START1 )
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_START2 )
|
||||
PORT_BIT( 0xc0, IP_ACTIVE_HIGH, IPT_UNKNOWN ) /* doesn't seem to be */
|
||||
/* accessed */
|
||||
PORT_BIT( 0xc0, IP_ACTIVE_HIGH, IPT_UNKNOWN ) // doesn't seem to be accessed
|
||||
|
||||
PORT_START("DSW0")
|
||||
PORT_DIPNAME( 0x03, 0x01, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW3:1,2")
|
||||
PORT_DIPSETTING( 0x00, "2" ) PORT_CONDITION("DSW0", 0x80, EQUALS, 0x80)
|
||||
@ -120,7 +493,7 @@ static INPUT_PORTS_START( dday )
|
||||
PORT_START("DSW1")
|
||||
PORT_DIPNAME( 0x0f, 0x0f, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW1:1,2,3,4")
|
||||
PORT_DIPSETTING( 0x0e, DEF_STR( 2C_1C ) )
|
||||
PORT_DIPSETTING( 0x0c, DEF_STR( 2C_2C ) ) /* Not shown in manual */
|
||||
PORT_DIPSETTING( 0x0c, DEF_STR( 2C_2C ) ) // Not shown in manual
|
||||
PORT_DIPSETTING( 0x0f, DEF_STR( 1C_1C ) )
|
||||
PORT_DIPSETTING( 0x0a, DEF_STR( 2C_3C ) )
|
||||
PORT_DIPSETTING( 0x08, DEF_STR( 2C_4C ) )
|
||||
@ -162,7 +535,7 @@ static INPUT_PORTS_START( ddayc )
|
||||
|
||||
PORT_MODIFY("BUTTONS")
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_START2 )
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON2 ) /* Distance Button */
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON2 ) // Distance Button
|
||||
|
||||
PORT_MODIFY("DSW0")
|
||||
PORT_DIPNAME( 0x0c, 0x00, "Extended Play At" ) PORT_DIPLOCATION("SW3:3,4")
|
||||
@ -198,42 +571,42 @@ INPUT_PORTS_END
|
||||
|
||||
static const gfx_layout layout_1bpp =
|
||||
{
|
||||
8,8, /* 8*8 characters */
|
||||
RGN_FRAC(1,2), /* 256 characters */
|
||||
1, /* 1 bit per pixel */
|
||||
8,8, // 8*8 characters
|
||||
RGN_FRAC(1,2), // 256 characters
|
||||
1, // 1 bit per pixel
|
||||
{ RGN_FRAC(0,1) },
|
||||
{ 7, 6, 5, 4, 3, 2, 1, 0 },
|
||||
{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
|
||||
8*8 /* every char takes 8 consecutive bytes */
|
||||
8*8 // every char takes 8 consecutive bytes
|
||||
};
|
||||
|
||||
static const gfx_layout layout_2bpp =
|
||||
{
|
||||
8,8, /* 8*8 characters */
|
||||
RGN_FRAC(1,2), /* 256 characters */
|
||||
2, /* 2 bits per pixel */
|
||||
{ RGN_FRAC(0,2), RGN_FRAC(1,2) }, /* the bitplanes are separated */
|
||||
8,8, // 8*8 characters
|
||||
RGN_FRAC(1,2), // 256 characters
|
||||
2, // 2 bits per pixel
|
||||
{ RGN_FRAC(0,2), RGN_FRAC(1,2) }, // the bitplanes are separated
|
||||
{ 7, 6, 5, 4, 3, 2, 1, 0 },
|
||||
{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
|
||||
8*8 /* every char takes 8 consecutive bytes */
|
||||
8*8 // every char takes 8 consecutive bytes
|
||||
};
|
||||
|
||||
static const gfx_layout layout_3bpp =
|
||||
{
|
||||
8,8, /* 8*8 characters */
|
||||
RGN_FRAC(1,3), /* 256 characters */
|
||||
3, /* 3 bits per pixel */
|
||||
{ RGN_FRAC(0,3), RGN_FRAC(1,3), RGN_FRAC(2,3) }, /* the bitplanes are separated */
|
||||
8,8, // 8*8 characters
|
||||
RGN_FRAC(1,3), // 256 characters
|
||||
3, // 3 bits per pixel
|
||||
{ RGN_FRAC(0,3), RGN_FRAC(1,3), RGN_FRAC(2,3) }, // the bitplanes are separated
|
||||
{ 7, 6, 5, 4, 3, 2, 1, 0 },
|
||||
{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
|
||||
8*8 /* every char takes 8 consecutive bytes */
|
||||
8*8 // every char takes 8 consecutive bytes
|
||||
};
|
||||
|
||||
static GFXDECODE_START( gfx_dday )
|
||||
GFXDECODE_ENTRY( "gfx1", 0, layout_3bpp, 0, 256/8 ) /* background */
|
||||
GFXDECODE_ENTRY( "gfx2", 0, layout_2bpp, 8*4, 8 ) /* foreground */
|
||||
GFXDECODE_ENTRY( "gfx3", 0, layout_2bpp, 8*4+8*4, 8 ) /* text */
|
||||
GFXDECODE_ENTRY( "gfx4", 0, layout_1bpp, 254, 1 ) /* searchlight */
|
||||
GFXDECODE_ENTRY( "bgtiles", 0, layout_3bpp, 0, 256/8 )
|
||||
GFXDECODE_ENTRY( "fgtiles", 0, layout_2bpp, 8*4, 8 )
|
||||
GFXDECODE_ENTRY( "chars", 0, layout_2bpp, 8*4+8*4, 8 )
|
||||
GFXDECODE_ENTRY( "searchlight", 0, layout_1bpp, 254, 1 )
|
||||
GFXDECODE_END
|
||||
|
||||
|
||||
@ -256,29 +629,29 @@ void dday_state::machine_reset()
|
||||
|
||||
void dday_state::dday(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
Z80(config, m_maincpu, 2000000); /* 2 MHz ? */
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &dday_state::dday_map);
|
||||
// basic machine hardware
|
||||
Z80(config, m_maincpu, 2'000'000); // 2 MHz ?
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &dday_state::program_map);
|
||||
|
||||
|
||||
/* video hardware */
|
||||
// video hardware
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
m_screen->set_refresh_hz(60);
|
||||
m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500) /* not accurate */);
|
||||
m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500)); // not accurate
|
||||
m_screen->set_size(32*8, 32*8);
|
||||
m_screen->set_visarea(0*8, 32*8-1, 0*8, 28*8-1);
|
||||
m_screen->set_screen_update(FUNC(dday_state::screen_update_dday));
|
||||
m_screen->set_screen_update(FUNC(dday_state::screen_update));
|
||||
m_screen->set_palette(m_palette);
|
||||
|
||||
GFXDECODE(config, m_gfxdecode, m_palette, gfx_dday);
|
||||
PALETTE(config, m_palette, FUNC(dday_state::dday_palette), 256).enable_shadows();
|
||||
PALETTE(config, m_palette, FUNC(dday_state::palette_init), 256).enable_shadows();
|
||||
m_palette->set_indirect_entries(256); // HACK!!!
|
||||
|
||||
/* sound hardware */
|
||||
// sound hardware
|
||||
SPEAKER(config, "mono").front_center();
|
||||
|
||||
AY8912(config, m_ay1, 1000000).add_route(ALL_OUTPUTS, "mono", 0.25);
|
||||
AY8912(config, "ay2", 1000000).add_route(ALL_OUTPUTS, "mono", 0.25);
|
||||
AY8912(config, m_ay1, 1'000'000).add_route(ALL_OUTPUTS, "mono", 0.25);
|
||||
AY8912(config, "ay2", 1'000'000).add_route(ALL_OUTPUTS, "mono", 0.25);
|
||||
}
|
||||
|
||||
|
||||
@ -296,29 +669,29 @@ ROM_START( dday )
|
||||
ROM_LOAD( "e6_65co.bin", 0x2000, 0x1000, CRC(fe414a83) SHA1(1ca1d30b71b62af5230dfe862a67c4cff5a71f41) )
|
||||
ROM_LOAD( "e5_66co.bin", 0x3000, 0x1000, CRC(fc9f7774) SHA1(1071d05e2f0ee8869eeeb46ad219303b417f4c90) )
|
||||
|
||||
ROM_REGION( 0x1800, "gfx1", 0 )
|
||||
ROM_REGION( 0x1800, "bgtiles", 0 )
|
||||
ROM_LOAD( "k4_73.bin", 0x0000, 0x0800, CRC(fa6237e4) SHA1(0dfe2a0079324a78b462203fe93f7fb186a42122) )
|
||||
ROM_LOAD( "k2_71.bin", 0x0800, 0x0800, CRC(f85461de) SHA1(e2ed34e993cd657681124df5531e35afd7d8c34b) )
|
||||
ROM_LOAD( "k3_72.bin", 0x1000, 0x0800, CRC(fdfe88b6) SHA1(cdc37d90500f4ce813b6efee31139e6776aa2bff) )
|
||||
|
||||
ROM_REGION( 0x1000, "gfx2", 0 )
|
||||
ROM_REGION( 0x1000, "fgtiles", 0 )
|
||||
ROM_LOAD( "j8_70co.bin", 0x0000, 0x0800, CRC(0c60e94c) SHA1(136df37b858a7fd399acc89e59917a068165d749) )
|
||||
ROM_LOAD( "j9_69co.bin", 0x0800, 0x0800, CRC(ba341c10) SHA1(c2c7350f87d5e47ac47cb19020681f0e7340e427) )
|
||||
|
||||
ROM_REGION( 0x1000, "gfx3", 0 )
|
||||
ROM_REGION( 0x1000, "chars", 0 )
|
||||
ROM_LOAD( "k6_74o.bin", 0x0000, 0x0800, CRC(66719aea) SHA1(dd29f8d079868af3c7fd16dc8c383f1eba4543d2) )
|
||||
ROM_LOAD( "k7_75o.bin", 0x0800, 0x0800, CRC(5f8772e2) SHA1(16194a02bc7d5248dea7a80bf6d6d263ec8a7fd6) )
|
||||
|
||||
ROM_REGION( 0x0800, "gfx4", 0 )
|
||||
ROM_REGION( 0x0800, "searchlight", 0 )
|
||||
ROM_LOAD( "d4_68.bin", 0x0000, 0x0800, CRC(f3649264) SHA1(5486a33fa1f7803e68d141992d6105206da1beba) )
|
||||
|
||||
ROM_REGION( 0x1000, "user1", 0 )
|
||||
ROM_LOAD( "d2_67.bin", 0x0000, 0x1000, CRC(2b693e42) SHA1(e52b987cf929ddfc7916b05456b1114076956d12) ) /* search light map */
|
||||
ROM_REGION( 0x1000, "sl_map", 0 )
|
||||
ROM_LOAD( "d2_67.bin", 0x0000, 0x1000, CRC(2b693e42) SHA1(e52b987cf929ddfc7916b05456b1114076956d12) )
|
||||
|
||||
ROM_REGION( 0x0300, "proms", 0 )
|
||||
ROM_LOAD( "dday.m11", 0x0000, 0x0100, CRC(aef6bbfc) SHA1(9e07729a4389221bc120af91d8275e1d05f3be7a) ) /* red component */
|
||||
ROM_LOAD( "dday.m8", 0x0100, 0x0100, CRC(ad3314b9) SHA1(d103f4f6103987ea85f0791ffc66a1cf9c711031) ) /* green component */
|
||||
ROM_LOAD( "dday.m3", 0x0200, 0x0100, CRC(e877ab82) SHA1(03e3905aee37f6743e7a4a87338f9504c832a55b) ) /* blue component */
|
||||
ROM_LOAD( "dday.m11", 0x0000, 0x0100, CRC(aef6bbfc) SHA1(9e07729a4389221bc120af91d8275e1d05f3be7a) ) // red component
|
||||
ROM_LOAD( "dday.m8", 0x0100, 0x0100, CRC(ad3314b9) SHA1(d103f4f6103987ea85f0791ffc66a1cf9c711031) ) // green component
|
||||
ROM_LOAD( "dday.m3", 0x0200, 0x0100, CRC(e877ab82) SHA1(03e3905aee37f6743e7a4a87338f9504c832a55b) ) // blue component
|
||||
ROM_END
|
||||
|
||||
ROM_START( ddayc )
|
||||
@ -328,31 +701,33 @@ ROM_START( ddayc )
|
||||
ROM_LOAD( "e6_65-c.bin", 0x2000, 0x1000, CRC(4c210686) SHA1(9d3110c4d1347f8a067c49b363a32d0f6a2c34c7) )
|
||||
ROM_LOAD( "e5_66-c.bin", 0x3000, 0x1000, CRC(e7e832f9) SHA1(3cbd2f9197e934ba3eae329511886a30c09a1ac7) )
|
||||
|
||||
ROM_REGION( 0x1800, "gfx1", 0 )
|
||||
ROM_REGION( 0x1800, "bgtiles", 0 )
|
||||
ROM_LOAD( "k4_73.bin", 0x0000, 0x0800, CRC(fa6237e4) SHA1(0dfe2a0079324a78b462203fe93f7fb186a42122) )
|
||||
ROM_LOAD( "k2_71.bin", 0x0800, 0x0800, CRC(f85461de) SHA1(e2ed34e993cd657681124df5531e35afd7d8c34b) )
|
||||
ROM_LOAD( "k3_72.bin", 0x1000, 0x0800, CRC(fdfe88b6) SHA1(cdc37d90500f4ce813b6efee31139e6776aa2bff) )
|
||||
|
||||
ROM_REGION( 0x1000, "gfx2", 0 )
|
||||
ROM_REGION( 0x1000, "fgtiles", 0 )
|
||||
ROM_LOAD( "j8_70-c.bin", 0x0000, 0x0800, CRC(a0c6b86b) SHA1(8b30370f2d5d7e75b8ec2a68f4e408fcb8ed2c8f) )
|
||||
ROM_LOAD( "j9_69-c.bin", 0x0800, 0x0800, CRC(d352a3d6) SHA1(4f1ba0b555f6b3dd539511bab8c55db45f719afc) )
|
||||
|
||||
ROM_REGION( 0x1000, "gfx3", 0 )
|
||||
ROM_REGION( 0x1000, "chars", 0 )
|
||||
ROM_LOAD( "k6_74.bin", 0x0000, 0x0800, CRC(d21a3e22) SHA1(9260353245f2ba2aca09fafd377c662ff508e5c0) )
|
||||
ROM_LOAD( "k7_75.bin", 0x0800, 0x0800, CRC(a5e5058c) SHA1(312dd55902c7e16eeee0dfc42c17fe1440b26e40) )
|
||||
|
||||
ROM_REGION( 0x0800, "gfx4", 0 )
|
||||
ROM_REGION( 0x0800, "searchlight", 0 )
|
||||
ROM_LOAD( "d4_68.bin", 0x0000, 0x0800, CRC(f3649264) SHA1(5486a33fa1f7803e68d141992d6105206da1beba) )
|
||||
|
||||
ROM_REGION( 0x1000, "user1", 0 )
|
||||
ROM_LOAD( "d2_67.bin", 0x0000, 0x1000, CRC(2b693e42) SHA1(e52b987cf929ddfc7916b05456b1114076956d12) ) /* search light map */
|
||||
ROM_REGION( 0x1000, "sl_map", 0 )
|
||||
ROM_LOAD( "d2_67.bin", 0x0000, 0x1000, CRC(2b693e42) SHA1(e52b987cf929ddfc7916b05456b1114076956d12) )
|
||||
|
||||
ROM_REGION( 0x0300, "proms", 0 )
|
||||
ROM_LOAD( "dday.m11", 0x0000, 0x0100, CRC(aef6bbfc) SHA1(9e07729a4389221bc120af91d8275e1d05f3be7a) ) /* red component */
|
||||
ROM_LOAD( "dday.m8", 0x0100, 0x0100, CRC(ad3314b9) SHA1(d103f4f6103987ea85f0791ffc66a1cf9c711031) ) /* green component */
|
||||
ROM_LOAD( "dday.m3", 0x0200, 0x0100, CRC(e877ab82) SHA1(03e3905aee37f6743e7a4a87338f9504c832a55b) ) /* blue component */
|
||||
ROM_LOAD( "dday.m11", 0x0000, 0x0100, CRC(aef6bbfc) SHA1(9e07729a4389221bc120af91d8275e1d05f3be7a) ) // red component
|
||||
ROM_LOAD( "dday.m8", 0x0100, 0x0100, CRC(ad3314b9) SHA1(d103f4f6103987ea85f0791ffc66a1cf9c711031) ) // green component
|
||||
ROM_LOAD( "dday.m3", 0x0200, 0x0100, CRC(e877ab82) SHA1(03e3905aee37f6743e7a4a87338f9504c832a55b) ) // blue component
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
GAME( 1982, dday, 0, dday, dday, dday_state, empty_init, ROT0, "Olympia", "D-Day", MACHINE_IMPERFECT_COLORS | MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1982, ddayc, dday, dday, ddayc, dday_state, empty_init, ROT0, "Olympia (Centuri license)", "D-Day (Centuri)", MACHINE_IMPERFECT_COLORS | MACHINE_SUPPORTS_SAVE )
|
||||
|
@ -1,87 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Zsolt Vasvari
|
||||
/*************************************************************************
|
||||
|
||||
D-Day
|
||||
|
||||
*************************************************************************/
|
||||
#ifndef MAME_OLYMPIA_DDAY_H
|
||||
#define MAME_OLYMPIA_DDAY_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "sound/ay8910.h"
|
||||
#include "tilemap.h"
|
||||
|
||||
|
||||
class dday_state : public driver_device
|
||||
{
|
||||
public:
|
||||
dday_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
driver_device(mconfig, type, tag),
|
||||
m_textvideoram(*this, "textvideoram"),
|
||||
m_fgvideoram(*this, "fgvideoram"),
|
||||
m_bgvideoram(*this, "bgvideoram"),
|
||||
m_colorram(*this, "colorram"),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_gfxdecode(*this, "gfxdecode"),
|
||||
m_screen(*this, "screen"),
|
||||
m_palette(*this, "palette"),
|
||||
m_ay1(*this, "ay1")
|
||||
{ }
|
||||
|
||||
void dday(machine_config &config);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
virtual void video_start() override;
|
||||
|
||||
private:
|
||||
/* memory pointers */
|
||||
required_shared_ptr<uint8_t> m_textvideoram;
|
||||
required_shared_ptr<uint8_t> m_fgvideoram;
|
||||
required_shared_ptr<uint8_t> m_bgvideoram;
|
||||
required_shared_ptr<uint8_t> m_colorram;
|
||||
|
||||
/* video-related */
|
||||
tilemap_t *m_fg_tilemap = nullptr;
|
||||
tilemap_t *m_bg_tilemap = nullptr;
|
||||
tilemap_t *m_text_tilemap = nullptr;
|
||||
tilemap_t *m_sl_tilemap = nullptr;
|
||||
bitmap_ind16 m_main_bitmap = 0;
|
||||
int m_control = 0;
|
||||
int m_sl_image = 0;
|
||||
int m_sl_enable = 0;
|
||||
int m_timer_value = 0;
|
||||
emu_timer *m_countdown_timer = nullptr;
|
||||
|
||||
/* devices */
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<palette_device> m_palette;
|
||||
required_device<ay8912_device> m_ay1;
|
||||
|
||||
uint8_t dday_countdown_timer_r();
|
||||
void dday_bgvideoram_w(offs_t offset, uint8_t data);
|
||||
void dday_fgvideoram_w(offs_t offset, uint8_t data);
|
||||
void dday_textvideoram_w(offs_t offset, uint8_t data);
|
||||
void dday_colorram_w(offs_t offset, uint8_t data);
|
||||
uint8_t dday_colorram_r(offs_t offset);
|
||||
void dday_sl_control_w(uint8_t data);
|
||||
void dday_control_w(uint8_t data);
|
||||
TILE_GET_INFO_MEMBER(get_bg_tile_info);
|
||||
TILE_GET_INFO_MEMBER(get_fg_tile_info);
|
||||
TILE_GET_INFO_MEMBER(get_text_tile_info);
|
||||
TILE_GET_INFO_MEMBER(get_sl_tile_info);
|
||||
void dday_palette(palette_device &palette) const;
|
||||
uint32_t screen_update_dday(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
TIMER_CALLBACK_MEMBER(countdown_timer_callback);
|
||||
void start_countdown_timer();
|
||||
void dday_map(address_map &map);
|
||||
};
|
||||
|
||||
#endif // MAME_OLYMPIA_DDAY_H
|
@ -1,322 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Zsolt Vasvari
|
||||
/***************************************************************************
|
||||
|
||||
video.c
|
||||
|
||||
Functions to emulate the video hardware of the machine.
|
||||
|
||||
Convention: "sl" stands for "searchlight"
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "sound/ay8910.h"
|
||||
#include "dday.h"
|
||||
|
||||
|
||||
/* Note: There seems to be no way to reset this timer via hardware.
|
||||
The game uses a difference method to reset it to 99.
|
||||
|
||||
Thanks Zwaxy for the timer info. */
|
||||
|
||||
uint8_t dday_state::dday_countdown_timer_r()
|
||||
{
|
||||
return ((m_timer_value / 10) << 4) | (m_timer_value % 10);
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(dday_state::countdown_timer_callback)
|
||||
{
|
||||
m_timer_value--;
|
||||
|
||||
if (m_timer_value < 0)
|
||||
m_timer_value = 99;
|
||||
}
|
||||
|
||||
void dday_state::start_countdown_timer()
|
||||
{
|
||||
m_timer_value = 0;
|
||||
|
||||
m_countdown_timer->adjust(attotime::from_seconds(1), 0, attotime::from_seconds(1));
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Convert the color PROMs into a more useable format.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
void dday_state::dday_palette(palette_device &palette) const
|
||||
{
|
||||
uint8_t const *const color_prom = memregion("proms")->base();
|
||||
|
||||
palette.set_shadow_factor(1.0 / 8);
|
||||
|
||||
// create a lookup table for the palette
|
||||
for (int i = 0; i < 0x100; i++)
|
||||
{
|
||||
int const r = pal4bit(color_prom[i + 0x000]);
|
||||
int const g = pal4bit(color_prom[i + 0x100]);
|
||||
int const b = pal4bit(color_prom[i + 0x200]);
|
||||
|
||||
palette.set_indirect_color(i, rgb_t(r, g, b));
|
||||
}
|
||||
|
||||
for (int i = 0; i < 0x100; i++)
|
||||
palette.set_pen_indirect(i, i);
|
||||
|
||||
// HACK!!! This table is handgenerated, but it matches the screenshot. I have no clue how it really works
|
||||
palette.set_pen_indirect(0*8+0+0, 0x00);
|
||||
palette.set_pen_indirect(0*8+0+1, 0x01);
|
||||
palette.set_pen_indirect(0*8+0+2, 0x15);
|
||||
palette.set_pen_indirect(0*8+0+3, 0x02);
|
||||
palette.set_pen_indirect(0*8+4+0, 0x00);
|
||||
palette.set_pen_indirect(0*8+4+1, 0x01);
|
||||
palette.set_pen_indirect(0*8+4+2, 0x15);
|
||||
palette.set_pen_indirect(0*8+4+3, 0x02);
|
||||
|
||||
palette.set_pen_indirect(1*8+0+0, 0x04);
|
||||
palette.set_pen_indirect(1*8+0+1, 0x05);
|
||||
palette.set_pen_indirect(1*8+0+2, 0x03);
|
||||
palette.set_pen_indirect(1*8+0+3, 0x07);
|
||||
palette.set_pen_indirect(1*8+4+0, 0x04);
|
||||
palette.set_pen_indirect(1*8+4+1, 0x05);
|
||||
palette.set_pen_indirect(1*8+4+2, 0x03);
|
||||
palette.set_pen_indirect(1*8+4+3, 0x07);
|
||||
|
||||
palette.set_pen_indirect(2*8+0+0, 0x08);
|
||||
palette.set_pen_indirect(2*8+0+1, 0x15);
|
||||
palette.set_pen_indirect(2*8+0+2, 0x0a);
|
||||
palette.set_pen_indirect(2*8+0+3, 0x03);
|
||||
palette.set_pen_indirect(2*8+4+0, 0x08);
|
||||
palette.set_pen_indirect(2*8+4+1, 0x15);
|
||||
palette.set_pen_indirect(2*8+4+2, 0x0a);
|
||||
palette.set_pen_indirect(2*8+4+3, 0x03);
|
||||
|
||||
palette.set_pen_indirect(3*8+0+0, 0x08);
|
||||
palette.set_pen_indirect(3*8+0+1, 0x15);
|
||||
palette.set_pen_indirect(3*8+0+2, 0x0a);
|
||||
palette.set_pen_indirect(3*8+0+3, 0x03);
|
||||
palette.set_pen_indirect(3*8+4+0, 0x08);
|
||||
palette.set_pen_indirect(3*8+4+1, 0x15);
|
||||
palette.set_pen_indirect(3*8+4+2, 0x0a);
|
||||
palette.set_pen_indirect(3*8+4+3, 0x03);
|
||||
|
||||
palette.set_pen_indirect(4*8+0+0, 0x10);
|
||||
palette.set_pen_indirect(4*8+0+1, 0x11);
|
||||
palette.set_pen_indirect(4*8+0+2, 0x12);
|
||||
palette.set_pen_indirect(4*8+0+3, 0x07);
|
||||
palette.set_pen_indirect(4*8+4+0, 0x10);
|
||||
palette.set_pen_indirect(4*8+4+1, 0x11);
|
||||
palette.set_pen_indirect(4*8+4+2, 0x12);
|
||||
palette.set_pen_indirect(4*8+4+3, 0x07);
|
||||
|
||||
palette.set_pen_indirect(5*8+0+0, 0x1d);
|
||||
palette.set_pen_indirect(5*8+0+1, 0x15);
|
||||
palette.set_pen_indirect(5*8+0+2, 0x16);
|
||||
palette.set_pen_indirect(5*8+0+3, 0x1b);
|
||||
palette.set_pen_indirect(5*8+4+0, 0x1d);
|
||||
palette.set_pen_indirect(5*8+4+1, 0x15);
|
||||
palette.set_pen_indirect(5*8+4+2, 0x16);
|
||||
palette.set_pen_indirect(5*8+4+3, 0x1b);
|
||||
|
||||
palette.set_pen_indirect(6*8+0+0, 0x1d);
|
||||
palette.set_pen_indirect(6*8+0+1, 0x15);
|
||||
palette.set_pen_indirect(6*8+0+2, 0x1a);
|
||||
palette.set_pen_indirect(6*8+0+3, 0x1b);
|
||||
palette.set_pen_indirect(6*8+4+0, 0x1d);
|
||||
palette.set_pen_indirect(6*8+4+1, 0x15);
|
||||
palette.set_pen_indirect(6*8+4+2, 0x1a);
|
||||
palette.set_pen_indirect(6*8+4+3, 0x1b);
|
||||
|
||||
palette.set_pen_indirect(7*8+0+0, 0x1d);
|
||||
palette.set_pen_indirect(7*8+0+1, 0x02);
|
||||
palette.set_pen_indirect(7*8+0+2, 0x04);
|
||||
palette.set_pen_indirect(7*8+0+3, 0x1b);
|
||||
palette.set_pen_indirect(7*8+4+0, 0x1d);
|
||||
palette.set_pen_indirect(7*8+4+1, 0x02);
|
||||
palette.set_pen_indirect(7*8+4+2, 0x04);
|
||||
palette.set_pen_indirect(7*8+4+3, 0x1b);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Callbacks for the TileMap code
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
TILE_GET_INFO_MEMBER(dday_state::get_bg_tile_info)
|
||||
{
|
||||
int code;
|
||||
|
||||
code = m_bgvideoram[tile_index];
|
||||
tileinfo.set(0, code, code >> 5, 0);
|
||||
}
|
||||
|
||||
TILE_GET_INFO_MEMBER(dday_state::get_fg_tile_info)
|
||||
{
|
||||
int code, flipx;
|
||||
|
||||
flipx = m_colorram[tile_index & 0x03e0] & 0x01;
|
||||
code = m_fgvideoram[flipx ? tile_index ^ 0x1f : tile_index];
|
||||
tileinfo.set(2, code, code >> 5, flipx ? TILE_FLIPX : 0);
|
||||
}
|
||||
|
||||
TILE_GET_INFO_MEMBER(dday_state::get_text_tile_info)
|
||||
{
|
||||
int code;
|
||||
|
||||
code = m_textvideoram[tile_index];
|
||||
tileinfo.set(1, code, code >> 5, 0);
|
||||
}
|
||||
|
||||
TILE_GET_INFO_MEMBER(dday_state::get_sl_tile_info)
|
||||
{
|
||||
int code, sl_flipx, flipx;
|
||||
uint8_t* sl_map;
|
||||
|
||||
sl_map = &memregion("user1")->base()[(m_sl_image & 0x07) * 0x0200];
|
||||
|
||||
flipx = (tile_index >> 4) & 0x01;
|
||||
sl_flipx = (m_sl_image >> 3) & 0x01;
|
||||
|
||||
/* bit 4 is really a flip indicator. Need to shift bits 5-9 to the right by 1 */
|
||||
tile_index = ((tile_index & 0x03e0) >> 1) | (tile_index & 0x0f);
|
||||
|
||||
code = sl_map[flipx ? tile_index ^ 0x0f : tile_index];
|
||||
|
||||
if ((sl_flipx != flipx) && (code & 0x80))
|
||||
/* no mirroring, draw dark spot */
|
||||
code = 1;
|
||||
|
||||
tileinfo.set(3, code & 0x3f, 0, flipx ? TILE_FLIPX : 0);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Start the video hardware emulation.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
void dday_state::video_start()
|
||||
{
|
||||
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(dday_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
|
||||
m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(dday_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
|
||||
m_text_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(dday_state::get_text_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
|
||||
m_sl_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(dday_state::get_sl_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
|
||||
|
||||
m_screen->register_screen_bitmap(m_main_bitmap);
|
||||
|
||||
m_bg_tilemap->set_transmask(0, 0x00f0, 0xff0f); /* pens 0-3 have priority over the foreground layer */
|
||||
m_fg_tilemap->set_transparent_pen(0);
|
||||
m_text_tilemap->set_transparent_pen(0);
|
||||
|
||||
m_countdown_timer = timer_alloc(FUNC(dday_state::countdown_timer_callback), this);
|
||||
|
||||
start_countdown_timer();
|
||||
}
|
||||
|
||||
void dday_state::dday_bgvideoram_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
m_bgvideoram[offset] = data;
|
||||
m_bg_tilemap->mark_tile_dirty(offset);
|
||||
}
|
||||
|
||||
void dday_state::dday_fgvideoram_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
m_fgvideoram[offset] = data;
|
||||
m_fg_tilemap->mark_tile_dirty(offset);
|
||||
m_fg_tilemap->mark_tile_dirty(offset ^ 0x1f); /* for flipx case */
|
||||
}
|
||||
|
||||
void dday_state::dday_textvideoram_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
m_textvideoram[offset] = data;
|
||||
m_text_tilemap->mark_tile_dirty(offset);
|
||||
}
|
||||
|
||||
void dday_state::dday_colorram_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
offset &= 0x03e0;
|
||||
|
||||
m_colorram[offset & 0x3e0] = data;
|
||||
|
||||
for (int i = 0; i < 0x20; i++)
|
||||
m_fg_tilemap->mark_tile_dirty(offset + i);
|
||||
}
|
||||
|
||||
uint8_t dday_state::dday_colorram_r(offs_t offset)
|
||||
{
|
||||
return m_colorram[offset & 0x03e0];
|
||||
}
|
||||
|
||||
|
||||
void dday_state::dday_sl_control_w(uint8_t data)
|
||||
{
|
||||
if (m_sl_image != data)
|
||||
{
|
||||
m_sl_image = data;
|
||||
m_sl_tilemap->mark_all_dirty();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void dday_state::dday_control_w(uint8_t data)
|
||||
{
|
||||
//if (data & 0xac) logerror("Control = %02X\n", data & 0xac);
|
||||
|
||||
/* bit 0 is coin counter 1 */
|
||||
machine().bookkeeping().coin_counter_w(0, data & 0x01);
|
||||
|
||||
/* bit 1 is coin counter 2 */
|
||||
machine().bookkeeping().coin_counter_w(1, data & 0x02);
|
||||
|
||||
/* bit 4 is sound enable */
|
||||
if (!(data & 0x10) && (m_control & 0x10))
|
||||
m_ay1->reset();
|
||||
|
||||
machine().sound().system_mute(!BIT(data, 4));
|
||||
|
||||
/* bit 6 is search light enable */
|
||||
m_sl_enable = data & 0x40;
|
||||
|
||||
m_control = data;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Display refresh
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
uint32_t dday_state::screen_update_dday(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
m_bg_tilemap->draw(screen, m_main_bitmap, cliprect, TILEMAP_DRAW_LAYER1, 0);
|
||||
m_fg_tilemap->draw(screen, m_main_bitmap, cliprect, 0, 0);
|
||||
m_bg_tilemap->draw(screen, m_main_bitmap, cliprect, TILEMAP_DRAW_LAYER0, 0);
|
||||
m_text_tilemap->draw(screen, m_main_bitmap, cliprect, 0, 0);
|
||||
|
||||
if (m_sl_enable)
|
||||
{
|
||||
/* apply shadow */
|
||||
bitmap_ind16 &sl_bitmap = m_sl_tilemap->pixmap();
|
||||
|
||||
for (int x = cliprect.min_x; x <= cliprect.max_x; x++)
|
||||
for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
|
||||
{
|
||||
uint16_t src_pixel = m_main_bitmap.pix(y, x);
|
||||
|
||||
if (sl_bitmap.pix(y, x) == 0xff)
|
||||
src_pixel += m_palette->entries();
|
||||
|
||||
bitmap.pix(y, x) = src_pixel;
|
||||
}
|
||||
}
|
||||
else
|
||||
copybitmap(bitmap, m_main_bitmap, 0, 0, 0, 0, cliprect);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Steve Ellenoff, Pierpaolo Prazzoli, Angelo Salese
|
||||
// copyright-holders: Steve Ellenoff, Pierpaolo Prazzoli, Angelo Salese
|
||||
|
||||
/**************************************************************************
|
||||
Portraits
|
||||
(c) 1983 Olympia
|
||||
@ -96,18 +97,318 @@ DM81LS95 = TriState buffer
|
||||
**************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "portrait.h"
|
||||
|
||||
#include "cpu/mcs48/mcs48.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "machine/gen_latch.h"
|
||||
#include "machine/nvram.h"
|
||||
#include "machine/pit8253.h"
|
||||
#include "sound/tms5220.h"
|
||||
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
#include "tilemap.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class portrait_state : public driver_device
|
||||
{
|
||||
public:
|
||||
portrait_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_audiocpu(*this, "audiocpu")
|
||||
, m_gfxdecode(*this, "gfxdecode")
|
||||
, m_palette(*this, "palette")
|
||||
, m_tms(*this, "tms")
|
||||
, m_bgvideoram(*this, "bgvideoram")
|
||||
, m_fgvideoram(*this, "fgvideoram")
|
||||
, m_spriteram(*this, "spriteram")
|
||||
, m_lamps(*this, "lamp%u", 0U)
|
||||
, m_photo(*this, "photo")
|
||||
{ }
|
||||
|
||||
static constexpr feature_type unemulated_features() { return feature::CAMERA; }
|
||||
|
||||
void portrait(machine_config &config);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override { m_lamps.resolve(); m_photo.resolve(); }
|
||||
virtual void video_start() override;
|
||||
|
||||
private:
|
||||
void ctrl_w(uint8_t data);
|
||||
void scroll_w(offs_t offset, uint8_t data);
|
||||
void bgvideo_write(offs_t offset, uint8_t data);
|
||||
void fgvideo_write(offs_t offset, uint8_t data);
|
||||
|
||||
TILE_GET_INFO_MEMBER(get_bg_tile_info);
|
||||
TILE_GET_INFO_MEMBER(get_fg_tile_info);
|
||||
|
||||
void palette_init(palette_device &palette) const;
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
inline void get_tile_info(tile_data &tileinfo, int tile_index, const uint8_t *source);
|
||||
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, uint8_t priority);
|
||||
void main_program_map(address_map &map);
|
||||
void audio_program_map(address_map &map);
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<i8039_device> m_audiocpu;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<palette_device> m_palette;
|
||||
required_device<tms5200_device> m_tms;
|
||||
|
||||
required_shared_ptr<uint8_t> m_bgvideoram;
|
||||
required_shared_ptr<uint8_t> m_fgvideoram;
|
||||
required_shared_ptr<uint8_t> m_spriteram;
|
||||
output_finder<2> m_lamps;
|
||||
output_finder<> m_photo;
|
||||
|
||||
uint16_t m_scroll = 0;
|
||||
tilemap_t *m_foreground = nullptr;
|
||||
tilemap_t *m_background = nullptr;
|
||||
};
|
||||
|
||||
|
||||
void portrait_state::bgvideo_write(offs_t offset, uint8_t data)
|
||||
{
|
||||
m_background->mark_tile_dirty(offset / 2);
|
||||
m_bgvideoram[offset] = data;
|
||||
}
|
||||
|
||||
void portrait_state::fgvideo_write(offs_t offset, uint8_t data)
|
||||
{
|
||||
m_foreground->mark_tile_dirty(offset / 2);
|
||||
m_fgvideoram[offset] = data;
|
||||
}
|
||||
|
||||
// NB: undisplayed areas gets filled at POST but never really used
|
||||
// $8x36-$8x3f / $8x76-$8x7f / $8xb6-$8xbf / $8xf6-$8xff
|
||||
// given that tilemap doesn't really cope well with live editing your best bet in debugging this is
|
||||
// potentially to subscribe these unused areas to a mark_all_dirty() fn.
|
||||
inline void portrait_state::get_tile_info(tile_data &tileinfo, int tile_index, const uint8_t *source)
|
||||
{
|
||||
int const attr = source[tile_index * 2 + 0];
|
||||
int tilenum = source[tile_index * 2 + 1];
|
||||
int flags = 0;
|
||||
int color = 0;
|
||||
|
||||
// TODO: always set with bit 4
|
||||
if (attr & 0x20) flags = TILE_FLIPY;
|
||||
|
||||
if (attr & 1)
|
||||
tilenum += 0x200;
|
||||
if (attr & 2)
|
||||
tilenum += 0x100;
|
||||
if (attr & 4)
|
||||
tilenum ^= 0x300;
|
||||
|
||||
// TODO: is the wild arrangement above related to how color upper banks should work?
|
||||
// cfr. trees in stage 4 leaving holes against the other layer
|
||||
|
||||
// TODO: kludgy
|
||||
// at worst this is modified at mixing time, outputting sprite color for the status bar.
|
||||
if (tilenum < 0x100)
|
||||
color = ((tilenum & 0xfe) >> 1) + 0x00;
|
||||
else
|
||||
color = ((tilenum & 0xfe) >> 1) + 0x80;
|
||||
|
||||
tileinfo.set(0, tilenum, color, flags);
|
||||
}
|
||||
|
||||
TILE_GET_INFO_MEMBER(portrait_state::get_bg_tile_info)
|
||||
{
|
||||
get_tile_info(tileinfo, tile_index, m_bgvideoram);
|
||||
}
|
||||
|
||||
TILE_GET_INFO_MEMBER(portrait_state::get_fg_tile_info)
|
||||
{
|
||||
get_tile_info(tileinfo, tile_index, m_fgvideoram);
|
||||
}
|
||||
|
||||
void portrait_state::video_start()
|
||||
{
|
||||
m_background = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(portrait_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
|
||||
m_foreground = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(portrait_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
|
||||
|
||||
m_foreground->set_transparent_pen(7);
|
||||
|
||||
save_item(NAME(m_scroll));
|
||||
}
|
||||
|
||||
/* tileattr ROM
|
||||
|
||||
this appears to be divided into 2 0x400 banks
|
||||
|
||||
0x000 - 0x3ff relates to tiles 0x000-0x0ff
|
||||
|
||||
0x400 - 0x7ff relates to tiles 0x100-0x1ff, 0x200-0x2ff, and 0x300-0x3ff
|
||||
|
||||
every 2 tiles are somehow related to 8 bytes in the data
|
||||
|
||||
so tiles 0x00 and 0x01 use bytes 0x000-0x007
|
||||
0x02 0x008
|
||||
0x04 0x010
|
||||
0x06 0x018
|
||||
0x08 0x020
|
||||
0x0a 0x028
|
||||
0x0c 0x030
|
||||
0x0e 0x038
|
||||
0x10 0x040
|
||||
.......
|
||||
0xfe and 0xff use bytes 0x3f8-0x3ff
|
||||
etc.
|
||||
|
||||
it's probably some kind of lookup table for the colours (6bpp = 8 colours, maybe every 2 tiles share the same 8 colours)
|
||||
I guess either the bank (0/1) can be selected, or bank 0 is hardcoded to tiles 0x000-0x0ff (because tilemaps can use
|
||||
these tiles too, so it's not a case of it being a sprite/tilemap lookup split)
|
||||
|
||||
anyway.. this is why the portraits logo is broken across 3 areas (0x1f2, 0x2f2, 0x3f2) so that they can share the same
|
||||
attributes from this ROM
|
||||
|
||||
*/
|
||||
void portrait_state::palette_init(palette_device &palette) const
|
||||
{
|
||||
uint8_t const *const color_prom = memregion("proms")->base();
|
||||
|
||||
for (int i = 0; i < 0x20; i++)
|
||||
{
|
||||
int const data = (color_prom[i + 0] << 0) | (color_prom[i + 0x20] << 8);
|
||||
|
||||
// TODO: experimental workbench, not using pal*bit intentionally.
|
||||
// 13 valid bits:
|
||||
// [+0x00] bit 0-3, bit 6-4
|
||||
// [+0x20] bit 0-2, bit 7-5
|
||||
// Only bit 0-3 seems to have a valid color ramp, is the rest actually bit mixed?
|
||||
|
||||
int ii = (data >> 0) & 0x0f;
|
||||
//int b = ((data >> 4) & 0x7) * ii;
|
||||
//int r = ((data >> 8) & 0x7) * ii;
|
||||
//int g = ((data >> 13) & 0x7) * ii;
|
||||
int r = ii * 0x11;
|
||||
int g = ii * 0x11;
|
||||
int b = ii * 0x11;
|
||||
|
||||
palette.set_indirect_color(i, rgb_t(r, g, b));
|
||||
|
||||
ii = (data >> 1) & 0x0f;
|
||||
r = ii * 0x11;
|
||||
g = ii * 0x11;
|
||||
b = ii * 0x11;
|
||||
|
||||
// ?? the lookup seems to reference 0x3f colours, unless 1 bit is something else (priority?)
|
||||
palette.set_indirect_color(i + 0x20, rgb_t(r, g, b));
|
||||
}
|
||||
|
||||
uint8_t const *const lookup = memregion("tileattr")->base();
|
||||
for (int i = 0; i < 0x800; i++)
|
||||
{
|
||||
uint8_t const ctabentry = lookup[i] & 0x3f;
|
||||
palette.set_pen_indirect(i, ctabentry);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* [2]
|
||||
* x--- ---- priority?
|
||||
* -x-- ---- more priority?
|
||||
* \- eagle sprite in stage 4 sets this only,
|
||||
* drawing should really go above the fg layer mountains
|
||||
* (missing tile category?)
|
||||
* --x- ---- flipy
|
||||
* ---x ---- ?
|
||||
* ---- x--- msb Y position?
|
||||
* ---- -x-- msb X position?
|
||||
*/
|
||||
void portrait_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, uint8_t priority)
|
||||
{
|
||||
uint8_t const *source = m_spriteram;
|
||||
uint8_t const *finish = source + 0x200;
|
||||
|
||||
// TODO: is anything beyond byte [3] really just work RAM buffer?
|
||||
for (; source < finish; source += 0x10)
|
||||
{
|
||||
uint8_t const attr = source[2];
|
||||
if (BIT(attr, 7) != priority)
|
||||
continue;
|
||||
uint16_t sy = source[0];
|
||||
uint16_t sx = source[1];
|
||||
uint8_t const tilenum = source[3];
|
||||
|
||||
// TODO: may be given by source[4] and/or source[5] instead
|
||||
uint8_t color = ((tilenum & 0xff) >> 1) + 0x00;
|
||||
|
||||
int const fy = BIT(attr, 5);
|
||||
|
||||
if (BIT(attr, 2)) sx |= 0x100;
|
||||
if (BIT(attr, 3)) sy |= 0x100;
|
||||
|
||||
sx += (source - m_spriteram) - 8;
|
||||
sx &= 0x1ff;
|
||||
|
||||
// TODO: confirm Y calculation
|
||||
// it expects to follow up whatever is the current scroll value (cfr. monkeys climbing trees in stage 1)
|
||||
// but then there are various misc sprites that break this rule. Examples are:
|
||||
// - player photo flash;
|
||||
// - death animation sprites;
|
||||
// - capturing photo frame in gameplay;
|
||||
// PC=0x2828 is where all of these odd sprites happen, where:
|
||||
// HL=ROM pointer for destination sprite pointer, IY=sprite pointer source
|
||||
// where they copy the origin of the given sprite, read scroll buffer $9235-36 then apply offset,
|
||||
// with [2] bits 7-6 set high and bits 5-4 copied from the source sprite.
|
||||
// Note that this will break elsewhere by logically using any of the [2] bits,
|
||||
// arguably SW does a very limited use to pinpoint what's the actual scroll disable condition,
|
||||
// it just implicitly don't setup [4] to [7] ...
|
||||
if ((source[5] & 0xf) == 0)
|
||||
sy = (511 - 16) - sy;
|
||||
else
|
||||
sy = ((511 - m_scroll) - 16) - sy;
|
||||
|
||||
sy &= 0x1ff;
|
||||
|
||||
m_gfxdecode->gfx(0)->transpen(
|
||||
bitmap, cliprect,
|
||||
tilenum, color,
|
||||
0, fy,
|
||||
sx, sy,
|
||||
7);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t portrait_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
rectangle cliprect_scroll, cliprect_no_scroll;
|
||||
|
||||
cliprect_scroll = cliprect_no_scroll = cliprect;
|
||||
|
||||
// TODO: make clipping areas more readable
|
||||
cliprect_no_scroll.min_x = cliprect_no_scroll.max_x - 111;
|
||||
cliprect_scroll.max_x = cliprect_scroll.min_x + 319;
|
||||
|
||||
// status bar
|
||||
m_background->set_scrolly(0, 0);
|
||||
m_foreground->set_scrolly(0, 0);
|
||||
m_background->draw(screen, bitmap, cliprect_no_scroll, 0, 0);
|
||||
m_foreground->draw(screen, bitmap, cliprect_no_scroll, 0, 0);
|
||||
|
||||
// playfield
|
||||
m_background->set_scrolly(0, m_scroll);
|
||||
m_foreground->set_scrolly(0, m_scroll);
|
||||
m_background->draw(screen, bitmap, cliprect_scroll, 0, 0);
|
||||
draw_sprites(bitmap, cliprect_scroll, 0);
|
||||
m_foreground->draw(screen, bitmap, cliprect_scroll, 0, 0);
|
||||
draw_sprites(bitmap, cliprect_scroll, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void portrait_state::ctrl_w(uint8_t data)
|
||||
{
|
||||
/* bits 4 and 5 are unknown */
|
||||
// bits 4 and 5 are unknown
|
||||
// TODO: condition for just displaying stored camera image
|
||||
// 0xf8 when capturing for the hi-score new pic, 0xb0 when displaying it from attract mode.
|
||||
|
||||
@ -115,11 +416,11 @@ void portrait_state::ctrl_w(uint8_t data)
|
||||
machine().bookkeeping().coin_counter_w(1, data & 0x02);
|
||||
machine().bookkeeping().coin_counter_w(2, data & 0x04);
|
||||
|
||||
/* the 2 lamps near the camera */
|
||||
// the 2 lamps near the camera
|
||||
m_lamps[0] = BIT(data, 3);
|
||||
m_lamps[1] = BIT(data, 6);
|
||||
|
||||
/* shows the black and white photo from the camera */
|
||||
// shows the black and white photo from the camera
|
||||
m_photo = BIT(data, 7);
|
||||
}
|
||||
|
||||
@ -132,16 +433,15 @@ void portrait_state::scroll_w(offs_t offset, uint8_t data)
|
||||
m_scroll += 256;
|
||||
}
|
||||
|
||||
void portrait_state::portrait_map(address_map &map)
|
||||
void portrait_state::main_program_map(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x7fff).rom();
|
||||
map(0x8000, 0x87ff).ram().w(FUNC(portrait_state::bgvideo_write)).share("bgvideoram");
|
||||
map(0x8800, 0x8fff).ram().w(FUNC(portrait_state::fgvideo_write)).share("fgvideoram");
|
||||
map(0x9000, 0x91ff).ram().share("spriteram");
|
||||
map(0x8000, 0x87ff).ram().w(FUNC(portrait_state::bgvideo_write)).share(m_bgvideoram);
|
||||
map(0x8800, 0x8fff).ram().w(FUNC(portrait_state::fgvideo_write)).share(m_fgvideoram);
|
||||
map(0x9000, 0x91ff).ram().share(m_spriteram);
|
||||
map(0x9200, 0x97ff).ram();
|
||||
map(0xa000, 0xa000).w("soundlatch", FUNC(generic_latch_8_device::write));
|
||||
map(0xa000, 0xa000).portr("DSW1").w("soundlatch", FUNC(generic_latch_8_device::write));
|
||||
map(0xa010, 0xa010).nopw(); // more sound? Follows up whatever is happening on screen
|
||||
map(0xa000, 0xa000).portr("DSW1");
|
||||
map(0xa004, 0xa004).portr("DSW2");
|
||||
map(0xa008, 0xa008).portr("SYSTEM").w(FUNC(portrait_state::ctrl_w));
|
||||
map(0xa010, 0xa010).portr("INPUTS");
|
||||
@ -153,7 +453,7 @@ void portrait_state::portrait_map(address_map &map)
|
||||
}
|
||||
|
||||
|
||||
void portrait_state::portrait_sound_map(address_map &map)
|
||||
void portrait_state::audio_program_map(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x0fff).rom();
|
||||
}
|
||||
@ -242,34 +542,36 @@ INPUT_PORTS_END
|
||||
|
||||
static const gfx_layout tile_layout =
|
||||
{
|
||||
16,16, /* tile width, height */
|
||||
1024, /* number of characters */
|
||||
3, /* bits per pixel */
|
||||
{ 0x0000*8, 0x4000*8, 0x8000*8 }, /* bitplane offsets */
|
||||
16,16, // tile width, height
|
||||
1024, // number of characters
|
||||
3, // bits per pixel
|
||||
{ 0x0000*8, 0x4000*8, 0x8000*8 }, // bitplane offsets
|
||||
{
|
||||
RGN_FRAC(1,2)+7, RGN_FRAC(1,2)+6, RGN_FRAC(1,2)+5, RGN_FRAC(1,2)+4,
|
||||
RGN_FRAC(1,2)+3, RGN_FRAC(1,2)+2, RGN_FRAC(1,2)+1, RGN_FRAC(1,2)+0,
|
||||
0, 1, 2, 3, 4, 5, 6, 7
|
||||
},
|
||||
{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 8*9, 8*10, 8*11, 8*12, 8*13, 8*14, 8*15 },
|
||||
8*16 /* character offset */
|
||||
8*16 // character offset
|
||||
};
|
||||
|
||||
static GFXDECODE_START( gfx_portrait )
|
||||
GFXDECODE_ENTRY( "gfx1", 0x00000, tile_layout, 0, 0x800/8 )
|
||||
GFXDECODE_ENTRY( "tiles", 0x00000, tile_layout, 0, 0x800/8 )
|
||||
GFXDECODE_END
|
||||
|
||||
|
||||
void portrait_state::portrait(machine_config &config)
|
||||
{
|
||||
Z80(config, m_maincpu, 4000000); /* 4 MHz ? */
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &portrait_state::portrait_map);
|
||||
Z80(config, m_maincpu, 4'000'000); // 4 MHz ?
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &portrait_state::main_program_map);
|
||||
m_maincpu->set_vblank_int("screen", FUNC(portrait_state::irq0_line_hold));
|
||||
|
||||
I8039(config, m_audiocpu, 3120000); /* ? */
|
||||
m_audiocpu->set_addrmap(AS_PROGRAM, &portrait_state::portrait_sound_map);
|
||||
I8039(config, m_audiocpu, 3'120'000); // ?
|
||||
m_audiocpu->set_addrmap(AS_PROGRAM, &portrait_state::audio_program_map);
|
||||
|
||||
// TODO: PIT8253
|
||||
PIT8253(config, "pit0", 0); // TODO
|
||||
|
||||
PIT8253(config, "pit1", 0); // TODO
|
||||
|
||||
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
|
||||
|
||||
@ -282,19 +584,19 @@ void portrait_state::portrait(machine_config &config)
|
||||
screen.set_palette(m_palette);
|
||||
|
||||
GFXDECODE(config, m_gfxdecode, m_palette, gfx_portrait);
|
||||
PALETTE(config, m_palette, FUNC(portrait_state::portrait_palette), 0x800, 0x40);
|
||||
PALETTE(config, m_palette, FUNC(portrait_state::palette_init), 0x800, 0x40);
|
||||
|
||||
/* sound hardware */
|
||||
// sound hardware
|
||||
SPEAKER(config, "mono").front_center();
|
||||
|
||||
GENERIC_LATCH_8(config, "soundlatch");
|
||||
|
||||
TMS5200(config, m_tms, 640000).add_route(ALL_OUTPUTS, "mono", 1.0);
|
||||
TMS5200(config, m_tms, 640'000).add_route(ALL_OUTPUTS, "mono", 1.0);
|
||||
}
|
||||
|
||||
|
||||
ROM_START( portrait )
|
||||
ROM_REGION( 0x10000, "maincpu", 0 ) /* 64k for the cpu */
|
||||
ROM_REGION( 0x10000, "maincpu", 0 )
|
||||
ROM_LOAD( "prt-p0.bin", 0x0000, 0x2000, CRC(a21874fa) SHA1(3db863f465a35d7d14dd71b47aa7dfe7b39fccf0) )
|
||||
ROM_LOAD( "prt-p1.bin", 0x2000, 0x2000, CRC(4d4d7793) SHA1(f828950ebbf285fc92c65f24421a20ceacef1cb9) )
|
||||
ROM_LOAD( "prt-p2.bin", 0x4000, 0x2000, CRC(83d88c9c) SHA1(c876f72b66537a49620fa27a5cb8a4aecd378f0a) )
|
||||
@ -304,7 +606,7 @@ ROM_START( portrait )
|
||||
ROM_LOAD( "port_w.bin", 0x0000, 0x0800, CRC(d3a4e950) SHA1(0a399d43c7690d568874f3b1d55135f803fc223f) )
|
||||
ROM_LOAD( "port_ma.bin", 0x0800, 0x0800, CRC(ee242e4f) SHA1(fb67e0d136927e04f4fa819f684c97b0d52ee48c) )
|
||||
|
||||
ROM_REGION( 0x20000, "gfx1", 0 )
|
||||
ROM_REGION( 0x20000, "tiles", 0 )
|
||||
ROM_LOAD( "port_00.a1", 0x00000, 0x2000, CRC(eb3e1c12) SHA1(2d38b66f52546b40553244c8a5c961279559f5b6) )
|
||||
ROM_LOAD( "port_10.b1", 0x02000, 0x2000, CRC(0f44e377) SHA1(1955f9f4deab2166f637f43c1f326bd65fc90f6a) )
|
||||
|
||||
@ -326,7 +628,7 @@ ROM_START( portrait )
|
||||
ROM_REGION( 0x0800, "user1", 0 ) // sound related?
|
||||
ROM_LOAD( "port_sa.bin", 0x0000, 0x0800, CRC(50510897) SHA1(8af0f42699602a5b33500968c958e3784e03377f) )
|
||||
|
||||
ROM_REGION( 0x800, "tileattr", 0 ) // tile attributes
|
||||
ROM_REGION( 0x800, "tileattr", 0 )
|
||||
ROM_LOAD( "93z511.bin", 0x0000, 0x0800, CRC(d66d9036) SHA1(7a25efbd8f2f94a01aad9e2be9cb18da7b9ec1d1) )
|
||||
|
||||
ROM_REGION( 0x40, "proms", 0 ) // colors
|
||||
@ -335,7 +637,7 @@ ROM_START( portrait )
|
||||
ROM_END
|
||||
|
||||
ROM_START( portraita )
|
||||
ROM_REGION( 0x10000, "maincpu", 0 ) /* 64k for the cpu */
|
||||
ROM_REGION( 0x10000, "maincpu", 0 )
|
||||
ROM_LOAD( "portp0f.m1", 0x0000, 0x2000, CRC(333eace3) SHA1(8f02df09d8b50d7e37d5abf7d539624c59a7201e) )
|
||||
ROM_LOAD( "portp0f.p1", 0x2000, 0x2000, CRC(fe258052) SHA1(f453eb05c68d61dfd644688732ff5c07366c68c0) )
|
||||
ROM_LOAD( "portp2f.r1", 0x4000, 0x2000, CRC(bc0104d5) SHA1(7707b85cde2dc9bd95391d4e1dbed219c52618cd) )
|
||||
@ -345,7 +647,7 @@ ROM_START( portraita )
|
||||
ROM_LOAD( "port_w.bin", 0x0000, 0x0800, CRC(d3a4e950) SHA1(0a399d43c7690d568874f3b1d55135f803fc223f) )
|
||||
ROM_LOAD( "port_ma.bin", 0x0800, 0x0800, CRC(ee242e4f) SHA1(fb67e0d136927e04f4fa819f684c97b0d52ee48c) )
|
||||
|
||||
ROM_REGION( 0x20000, "gfx1", 0 )
|
||||
ROM_REGION( 0x20000, "tiles", 0 )
|
||||
ROM_LOAD( "port_00.a1", 0x00000, 0x2000, CRC(eb3e1c12) SHA1(2d38b66f52546b40553244c8a5c961279559f5b6) )
|
||||
ROM_LOAD( "port_10.b1", 0x02000, 0x2000, CRC(0f44e377) SHA1(1955f9f4deab2166f637f43c1f326bd65fc90f6a) )
|
||||
ROM_LOAD( "port_02.d1", 0x04000, 0x2000, CRC(bd93a3f9) SHA1(9cb479b8840cafd6043ff0cb9d5ca031dcd332ba) )
|
||||
@ -360,7 +662,7 @@ ROM_START( portraita )
|
||||
ROM_LOAD( "port_05.g2", 0x18000, 0x2000, CRC(43ea7951) SHA1(df0ae7fa802365979514063e1d67cdd45ecada90) )
|
||||
ROM_LOAD( "port_15.h2", 0x1a000, 0x2000, CRC(ab20b438) SHA1(ea5d60f6a9f06397bd0c6ee028b463c684090c01) )
|
||||
|
||||
ROM_REGION( 0x800, "tileattr", 0 ) // tile attributes (see notes)
|
||||
ROM_REGION( 0x800, "tileattr", 0 ) // (see notes)
|
||||
ROM_LOAD( "93z511.bin", 0x0000, 0x0800, CRC(d66d9036) SHA1(7a25efbd8f2f94a01aad9e2be9cb18da7b9ec1d1) )
|
||||
|
||||
ROM_REGION( 0x40, "proms", 0 ) // colors
|
||||
@ -368,6 +670,8 @@ ROM_START( portraita )
|
||||
ROM_LOAD( "port_pr2.n4", 0x20, 0x0020, CRC(008634f3) SHA1(7cde6b09ede672d562569866d944428198f2ba9c) )
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
GAME( 1983, portrait, 0, portrait, portrait, portrait_state, empty_init, ROT270, "Olympia", "Portraits (set 1)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_WRONG_COLORS | MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1983, portraita,portrait, portrait, portrait, portrait_state, empty_init, ROT270, "Olympia", "Portraits (set 2)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_WRONG_COLORS | MACHINE_SUPPORTS_SAVE ) // harder set
|
||||
|
||||
GAME( 1983, portrait, 0, portrait, portrait, portrait_state, empty_init, ROT270, "Olympia", "Portraits (set 1)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_WRONG_COLORS | MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1983, portraita, portrait, portrait, portrait, portrait_state, empty_init, ROT270, "Olympia", "Portraits (set 2)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_WRONG_COLORS | MACHINE_SUPPORTS_SAVE ) // harder set
|
||||
|
@ -1,72 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Steve Ellenoff, Pierpaolo Prazzoli, Angelo Salese
|
||||
#ifndef MAME_OLYMPIA_PORTRAIT_H
|
||||
#define MAME_OLYMPIA_PORTRAIT_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cpu/mcs48/mcs48.h"
|
||||
#include "sound/tms5220.h"
|
||||
#include "emupal.h"
|
||||
#include "tilemap.h"
|
||||
|
||||
class portrait_state : public driver_device
|
||||
{
|
||||
public:
|
||||
portrait_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_audiocpu(*this, "audiocpu")
|
||||
, m_gfxdecode(*this, "gfxdecode")
|
||||
, m_palette(*this, "palette")
|
||||
, m_tms(*this, "tms")
|
||||
, m_bgvideoram(*this, "bgvideoram")
|
||||
, m_fgvideoram(*this, "fgvideoram")
|
||||
, m_spriteram(*this, "spriteram")
|
||||
, m_lamps(*this, "lamp%u", 0U)
|
||||
, m_photo(*this, "photo")
|
||||
{ }
|
||||
|
||||
static constexpr feature_type unemulated_features() { return feature::CAMERA; }
|
||||
|
||||
void portrait(machine_config &config);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override { m_lamps.resolve(); m_photo.resolve(); }
|
||||
virtual void video_start() override;
|
||||
|
||||
private:
|
||||
void ctrl_w(uint8_t data);
|
||||
void scroll_w(offs_t offset, uint8_t data);
|
||||
void bgvideo_write(offs_t offset, uint8_t data);
|
||||
void fgvideo_write(offs_t offset, uint8_t data);
|
||||
|
||||
TILE_GET_INFO_MEMBER(get_bg_tile_info);
|
||||
TILE_GET_INFO_MEMBER(get_fg_tile_info);
|
||||
|
||||
void portrait_palette(palette_device &palette) const;
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
inline void get_tile_info( tile_data &tileinfo, int tile_index, const uint8_t *source );
|
||||
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, u8 priority);
|
||||
void portrait_map(address_map &map);
|
||||
void portrait_sound_map(address_map &map);
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<i8039_device> m_audiocpu;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<palette_device> m_palette;
|
||||
required_device<tms5200_device> m_tms;
|
||||
|
||||
required_shared_ptr<uint8_t> m_bgvideoram;
|
||||
required_shared_ptr<uint8_t> m_fgvideoram;
|
||||
required_shared_ptr<uint8_t> m_spriteram;
|
||||
output_finder<2> m_lamps;
|
||||
output_finder<> m_photo;
|
||||
|
||||
int m_scroll = 0;
|
||||
tilemap_t *m_foreground = nullptr;
|
||||
tilemap_t *m_background = nullptr;
|
||||
};
|
||||
|
||||
#endif // MAME_OLYMPIA_PORTRAIT_H
|
@ -1,244 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Steve Ellenoff, Pierpaolo Prazzoli, Angelo Salese
|
||||
/***************************************************************************
|
||||
|
||||
Portraits
|
||||
video hardware emulation
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "portrait.h"
|
||||
|
||||
|
||||
void portrait_state::bgvideo_write(offs_t offset, uint8_t data)
|
||||
{
|
||||
m_background->mark_tile_dirty(offset/2);
|
||||
m_bgvideoram[offset] = data;
|
||||
}
|
||||
|
||||
void portrait_state::fgvideo_write(offs_t offset, uint8_t data)
|
||||
{
|
||||
m_foreground->mark_tile_dirty(offset/2);
|
||||
m_fgvideoram[offset] = data;
|
||||
}
|
||||
|
||||
// NB: undisplayed areas gets filled at POST but never really used
|
||||
// $8x36-$8x3f / $8x76-$8x7f / $8xb6-$8xbf / $8xf6-$8xff
|
||||
// given that tilemap doesn't really cope well with live editing your best bet in debugging this is
|
||||
// potentially to subscribe these unused areas to a mark_all_dirty() fn.
|
||||
inline void portrait_state::get_tile_info( tile_data &tileinfo, int tile_index, const uint8_t *source )
|
||||
{
|
||||
int attr = source[tile_index*2+0];
|
||||
int tilenum = source[tile_index*2+1];
|
||||
int flags = 0;
|
||||
int color = 0;
|
||||
|
||||
// TODO: always set with bit 4
|
||||
if( attr & 0x20 ) flags = TILE_FLIPY;
|
||||
|
||||
if (attr & 1)
|
||||
tilenum += 0x200;
|
||||
if (attr & 2)
|
||||
tilenum += 0x100;
|
||||
if (attr & 4)
|
||||
tilenum ^= 0x300;
|
||||
|
||||
// TODO: is the wild arrangement above related to how color upper banks should work?
|
||||
// cfr. trees in stage 4 leaving holes against the other layer
|
||||
|
||||
// TODO: kludgy
|
||||
// at worst this is modified at mixing time, outputting sprite color for the status bar.
|
||||
if (tilenum<0x100)
|
||||
color = ((tilenum&0xfe) >> 1) + 0x00;
|
||||
else
|
||||
color = ((tilenum&0xfe) >> 1) + 0x80;
|
||||
|
||||
tileinfo.set(0, tilenum, color, flags );
|
||||
}
|
||||
|
||||
TILE_GET_INFO_MEMBER(portrait_state::get_bg_tile_info)
|
||||
{
|
||||
get_tile_info(tileinfo, tile_index, m_bgvideoram );
|
||||
}
|
||||
|
||||
TILE_GET_INFO_MEMBER(portrait_state::get_fg_tile_info)
|
||||
{
|
||||
get_tile_info(tileinfo, tile_index, m_fgvideoram );
|
||||
}
|
||||
|
||||
void portrait_state::video_start()
|
||||
{
|
||||
m_background = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(portrait_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
|
||||
m_foreground = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(portrait_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
|
||||
|
||||
m_foreground->set_transparent_pen(7);
|
||||
|
||||
save_item(NAME(m_scroll));
|
||||
}
|
||||
|
||||
/* tileattr rom
|
||||
|
||||
this appears to be divided into 2 0x400 banks
|
||||
|
||||
0x000 - 0x3ff relates to tiles 0x000-0x0ff
|
||||
|
||||
0x400 - 0x7ff relates to tiles 0x100-0x1ff, 0x200-0x2ff, and 0x300-0x3ff
|
||||
|
||||
every 2 tiles are somehow related to 8 bytes in the data
|
||||
|
||||
so tiles 0x00 and 0x01 use bytes 0x000-0x007
|
||||
0x02 0x008
|
||||
0x04 0x010
|
||||
0x06 0x018
|
||||
0x08 0x020
|
||||
0x0a 0x028
|
||||
0x0c 0x030
|
||||
0x0e 0x038
|
||||
0x10 0x040
|
||||
.......
|
||||
0xfe and 0xff use bytes 0x3f8-0x3ff
|
||||
etc.
|
||||
|
||||
it's probably some kind of lookup table for the colours (6bpp = 8 colours, maybe every 2 tiles share the same 8 colours)
|
||||
I guess either the bank (0/1) can be selected, or bank 0 is hardcoded to tiles 0x000-0x0ff (because tilemaps can use
|
||||
these tiles too, so it's not a case of it being a sprite/tilemap lookup split)
|
||||
|
||||
anyway.. this is why the portraits logo is broken across 3 areas (0x1f2, 0x2f2, 0x3f2) so that they can share the same
|
||||
attributes from this rom
|
||||
|
||||
*/
|
||||
void portrait_state::portrait_palette(palette_device &palette) const
|
||||
{
|
||||
uint8_t const *const color_prom = memregion("proms")->base();
|
||||
|
||||
for (int i = 0; i < 0x20; i++)
|
||||
{
|
||||
int const data = (color_prom[i + 0] << 0) | (color_prom[i + 0x20] << 8);
|
||||
|
||||
// TODO: experimental workbench, not using pal*bit intentionally.
|
||||
// 13 valid bits:
|
||||
// [+0x00] bit 0-3, bit 6-4
|
||||
// [+0x20] bit 0-2, bit 7-5
|
||||
// Only bit 0-3 seems to have a valid color ramp, is the rest actually bit mixed?
|
||||
|
||||
int ii = (data >> 0) & 0x0f;
|
||||
//int b = ((data >> 4) & 0x7) * ii;
|
||||
//int r = ((data >> 8) & 0x7) * ii;
|
||||
//int g = ((data >> 13) & 0x7) * ii;
|
||||
int r = ii * 0x11;
|
||||
int g = ii * 0x11;
|
||||
int b = ii * 0x11;
|
||||
|
||||
palette.set_indirect_color(i, rgb_t(r, g, b));
|
||||
|
||||
ii = (data >> 1) & 0x0f;
|
||||
r = ii * 0x11;
|
||||
g = ii * 0x11;
|
||||
b = ii * 0x11;
|
||||
|
||||
// ?? the lookup seems to reference 0x3f colours, unless 1 bit is something else (priority?)
|
||||
palette.set_indirect_color(i + 0x20, rgb_t(r, g, b));
|
||||
}
|
||||
|
||||
uint8_t const *const lookup = memregion("tileattr")->base();
|
||||
for (int i = 0; i < 0x800; i++)
|
||||
{
|
||||
uint8_t const ctabentry = lookup[i] & 0x3f;
|
||||
palette.set_pen_indirect(i, ctabentry);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* [2]
|
||||
* x--- ---- priority?
|
||||
* -x-- ---- more priority?
|
||||
* \- eagle sprite in stage 4 sets this only,
|
||||
* drawing should really go above the fg layer mountains
|
||||
* (missing tile category?)
|
||||
* --x- ---- flipy
|
||||
* ---x ---- ?
|
||||
* ---- x--- msb Y position?
|
||||
* ---- -x-- msb X position?
|
||||
*/
|
||||
void portrait_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, u8 priority)
|
||||
{
|
||||
uint8_t *source = m_spriteram;
|
||||
uint8_t *finish = source + 0x200;
|
||||
|
||||
// TODO: is anything beyond byte [3] really just work RAM buffer?
|
||||
for( ; source < finish; source += 0x10 )
|
||||
{
|
||||
u8 attr = source[2];
|
||||
if (BIT(attr, 7) != priority)
|
||||
continue;
|
||||
u16 sy = source[0];
|
||||
u16 sx = source[1];
|
||||
u8 tilenum = source[3];
|
||||
|
||||
// TODO: may be given by source[4] and/or source[5] instead
|
||||
u8 color = ((tilenum&0xff)>>1)+0x00;
|
||||
|
||||
int fy = BIT(attr, 5);
|
||||
|
||||
if (BIT(attr, 2)) sx |= 0x100;
|
||||
if (BIT(attr, 3)) sy |= 0x100;
|
||||
|
||||
sx += (source - m_spriteram) - 8;
|
||||
sx &= 0x1ff;
|
||||
|
||||
// TODO: confirm Y calculation
|
||||
// it expects to follow up whatever is the current scroll value (cfr. monkeys climbing trees in stage 1)
|
||||
// but then there are various misc sprites that breaks this rule. Examples are:
|
||||
// - player photo flash;
|
||||
// - death animation sprites;
|
||||
// - capturing photo frame in gameplay;
|
||||
// PC=0x2828 is where all of these odd sprites happens, where:
|
||||
// HL=ROM pointer for destination sprite pointer, IY=sprite pointer source
|
||||
// where they copy the origin of the given sprite, read scroll buffer $9235-36 then apply offset,
|
||||
// with [2] bits 7-6 set high and bits 5-4 copied from the source sprite.
|
||||
// Note that this will break elsewhere by logically using any of the [2] bits,
|
||||
// arguably SW does a very limited use to pinpoint what's the actual scroll disable condition,
|
||||
// it just implicitly don't setup [4] to [7] ...
|
||||
if ((source[5] & 0xf) == 0)
|
||||
sy = (511 - 16) - sy;
|
||||
else
|
||||
sy = ((511 - m_scroll) - 16) - sy;
|
||||
|
||||
sy &= 0x1ff;
|
||||
|
||||
m_gfxdecode->gfx(0)->transpen(
|
||||
bitmap, cliprect,
|
||||
tilenum, color,
|
||||
0, fy,
|
||||
sx, sy,
|
||||
7);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t portrait_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
rectangle cliprect_scroll, cliprect_no_scroll;
|
||||
|
||||
cliprect_scroll = cliprect_no_scroll = cliprect;
|
||||
|
||||
// TODO: make clipping areas more readable
|
||||
cliprect_no_scroll.min_x = cliprect_no_scroll.max_x - 111;
|
||||
cliprect_scroll.max_x = cliprect_scroll.min_x + 319;
|
||||
|
||||
// status bar
|
||||
m_background->set_scrolly(0, 0);
|
||||
m_foreground->set_scrolly(0, 0);
|
||||
m_background->draw(screen, bitmap, cliprect_no_scroll, 0, 0);
|
||||
m_foreground->draw(screen, bitmap, cliprect_no_scroll, 0, 0);
|
||||
|
||||
// playfield
|
||||
m_background->set_scrolly(0, m_scroll);
|
||||
m_foreground->set_scrolly(0, m_scroll);
|
||||
m_background->draw(screen, bitmap, cliprect_scroll, 0, 0);
|
||||
draw_sprites(bitmap, cliprect_scroll, 0);
|
||||
m_foreground->draw(screen, bitmap, cliprect_scroll, 0, 0);
|
||||
draw_sprites(bitmap, cliprect_scroll, 1);
|
||||
|
||||
return 0;
|
||||
}
|
@ -39,7 +39,7 @@
|
||||
|_________________________________________________test_test___________________________________________|
|
||||
|
||||
-JMP3, JMP4, JMP8, JMP9, and JMP10 are for setting up the baud rate of each OKI M82C51A USART (you can
|
||||
configuse 1200, 2400, 4800, 9600, 19200 or 38400 bps.
|
||||
configure 1200, 2400, 4800, 9600, 19200 or 38400 bps.
|
||||
|
||||
****************************************************************************************/
|
||||
|
||||
|
@ -50,7 +50,9 @@ LD15 (_)
|
||||
****************************************************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "cpu/m6502/m6504.h"
|
||||
|
||||
#include "speaker.h"
|
||||
|
||||
namespace {
|
||||
@ -69,9 +71,40 @@ public:
|
||||
|
||||
private:
|
||||
required_device<cpu_device> m_maincpu;
|
||||
|
||||
INTERRUPT_GEN_MEMBER(irq_gen);
|
||||
|
||||
void program_map(address_map &map);
|
||||
};
|
||||
|
||||
INTERRUPT_GEN_MEMBER(elcirculo_state::irq_gen)
|
||||
{
|
||||
m_maincpu->set_input_line(M6504_IRQ_LINE, HOLD_LINE);
|
||||
}
|
||||
|
||||
void elcirculo_state::program_map(address_map &map)
|
||||
{
|
||||
map.global_mask(0x1fff);
|
||||
|
||||
map(0x0000, 0x01ff).ram();
|
||||
map(0x0200, 0x0200).portr("IN0");
|
||||
map(0x0201, 0x0201).portr("DSW1");
|
||||
// map(0x0400, 0x0401).w();
|
||||
// map(0x0600, 0x0601).w();
|
||||
map(0x1000, 0x17ff).mirror(0x800).rom().region("maincpu", 0);
|
||||
}
|
||||
|
||||
INPUT_PORTS_START(elcirculo)
|
||||
PORT_START("IN0")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
|
||||
PORT_START("DSW1")
|
||||
PORT_DIPUNKNOWN_DIPLOC(0x01, 0x01, "SW1:1")
|
||||
PORT_DIPUNKNOWN_DIPLOC(0x02, 0x02, "SW1:2")
|
||||
@ -86,15 +119,17 @@ INPUT_PORTS_END
|
||||
void elcirculo_state::elcirculo(machine_config &config)
|
||||
{
|
||||
M6504(config, m_maincpu, 1'000'000); // R6504P, internal clock
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &elcirculo_state::program_map);
|
||||
m_maincpu->set_periodic_int(FUNC(elcirculo_state::irq_gen), attotime::from_hz(60)); // TODO: source of this
|
||||
|
||||
SPEAKER(config, "mono").front_center();
|
||||
}
|
||||
|
||||
ROM_START(elcirculo)
|
||||
ROM_REGION(0x800, "maincpu", 0)
|
||||
ROM_LOAD("tms2716c.ic2", 0x000, 0x800, CRC(7b5ae97f) SHA1(e7276d5d97328628889d216beac0b04216bf82c7))
|
||||
ROM_START( elcirculo )
|
||||
ROM_REGION( 0x800, "maincpu", 0 )
|
||||
ROM_LOAD( "tms2716c.ic2", 0x000, 0x800, CRC(7b5ae97f) SHA1(e7276d5d97328628889d216beac0b04216bf82c7) )
|
||||
ROM_END
|
||||
|
||||
} // Anonymous namespace
|
||||
} // anonymous namespace
|
||||
|
||||
GAME(1980, elcirculo, 0, elcirculo, elcirculo, elcirculo_state, empty_init, ROT0, "Inder", "El Circulo", MACHINE_IS_SKELETON)
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
In particular
|
||||
- It uses a LSI Zevio 1020 CPU + peripherals which comprises ARM926EJ-S CPU,
|
||||
ZSP400 DPS, 3D graphics processor & 2D graphics processor
|
||||
ZSP400 DSP, 3D graphics processor & 2D graphics processor
|
||||
- The CD controller is a Sony CXD3059AR
|
||||
|
||||
****************************************************************************/
|
||||
@ -23,8 +23,8 @@
|
||||
#include "cpu/arm7/arm7.h"
|
||||
#include "imagedev/cdromimg.h"
|
||||
|
||||
#include "softlist.h"
|
||||
#include "cdrom.h"
|
||||
#include "softlist.h"
|
||||
|
||||
|
||||
namespace {
|
||||
@ -51,13 +51,13 @@ void vsmilpro_state::vsmilpro_map(address_map &map)
|
||||
}
|
||||
|
||||
|
||||
/* Input ports */
|
||||
// Input ports
|
||||
static INPUT_PORTS_START( vsmilpro )
|
||||
INPUT_PORTS_END
|
||||
|
||||
void vsmilpro_state::vsmilpro(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
// basic machine hardware
|
||||
ARM9(config, m_maincpu, 150000000);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &vsmilpro_state::vsmilpro_map);
|
||||
|
||||
@ -66,7 +66,7 @@ void vsmilpro_state::vsmilpro(machine_config &config)
|
||||
SOFTWARE_LIST(config, "cd_list").set_original("vsmile_cd");
|
||||
}
|
||||
|
||||
/* ROM definition */
|
||||
// ROM definition
|
||||
ROM_START( vsmilpro )
|
||||
ROM_REGION( 0x200000, "maincpu", 0 )
|
||||
ROM_LOAD( "70004.bin", 0x000000, 0x200000, CRC(b9161eac) SHA1(8d75fdeda8c4e228a0b1efd35011f9f667f9fb23) )
|
||||
@ -75,7 +75,7 @@ ROM_END
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
/* Driver */
|
||||
// Driver
|
||||
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
|
||||
COMP( 2007, vsmilpro, 0, 0, vsmilpro, vsmilpro, vsmilpro_state, empty_init, "VTech", "V.Smile Pro", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
|
||||
COMP( 2007, vsmilpro, 0, 0, vsmilpro, vsmilpro, vsmilpro_state, empty_init, "VTech", "V.Smile Pro", MACHINE_IS_SKELETON )
|
||||
|
Loading…
Reference in New Issue
Block a user