jak_capb signs of life (nw) (#4569)

* spg110 data segment (nw)

* dummy (nw)

* (nw)

* notes on possible register use (nw)

* jak_capb signs of life (nw)

* better tile addressing (nw)

* (nw)

* (nw)

* yeah palette format is another strange one, not quite right, code borrowed from another driver (nw)

* some scroll (nw)

* (nw)

* seems to be step (nw)

* be more scrolly (nw)
This commit is contained in:
David Haywood 2019-01-30 01:26:55 +00:00 committed by ajrhacker
parent 7f4dc2f670
commit cb03be2109
2 changed files with 656 additions and 18 deletions

View File

@ -4,8 +4,8 @@
SunPlus SPG110-series SoC peripheral emulation
It is possible this shares some video features with spg110 and
can be made a derived device
0032xx looks like it could be the same as 003dxx on spg2xx
but the video seems quite different?
**********************************************************************/
@ -16,20 +16,124 @@ DEFINE_DEVICE_TYPE(SPG110, spg110_device, "spg110", "SPG110 System-on-a-Chip")
spg110_device::spg110_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, type, tag, owner, clock),
m_cpu(*this, finder_base::DUMMY_TAG)
device_memory_interface(mconfig, *this),
m_space_config("spg110", ENDIANNESS_BIG, 16, 32, 0, address_map_constructor(FUNC(spg110_device::map_video), this)),
m_cpu(*this, finder_base::DUMMY_TAG),
m_palette(*this, "palette"),
m_gfxdecode(*this, "gfxdecode"),
m_bg_videoram(*this, "bg_videoram"),
m_fg_videoram(*this, "fg_videoram"),
m_bg_attrram(*this, "bg_attrram"),
m_fg_attrram(*this, "fg_attrram"),
m_palram(*this, "palram")
{
}
WRITE16_MEMBER(spg110_device::bg_videoram_w)
{
COMBINE_DATA(&m_bg_videoram[offset]);
m_bg_tilemap->mark_tile_dirty(offset);
}
WRITE16_MEMBER(spg110_device::fg_videoram_w)
{
COMBINE_DATA(&m_fg_videoram[offset]);
m_fg_tilemap->mark_tile_dirty(offset);
}
WRITE16_MEMBER(spg110_device::bg_attrram_w)
{
COMBINE_DATA(&m_bg_attrram[offset]);
m_bg_tilemap->mark_tile_dirty(offset/2);
}
WRITE16_MEMBER(spg110_device::fg_attrram_w)
{
COMBINE_DATA(&m_fg_attrram[offset]);
m_fg_tilemap->mark_tile_dirty(offset/2);
}
/* correct, 4bpp gfxs */
static const gfx_layout charlayout =
{
8,8,
RGN_FRAC(1,1),
4,
{ STEP4(0,1) },
{ 0*4,1*4,2*4,3*4,4*4,5*4,6*4,7*4 },
{ STEP8(0,4*8) },
8*8*4
};
static const gfx_layout charlayout6 =
{
8,8,
RGN_FRAC(1,1),
6,
{ 0,1,2,3,4,5 },
{ STEP8(0,6) },
{ STEP8(0,6*8) },
8*8*6
};
static const gfx_layout char16layout =
{
16,16,
RGN_FRAC(1,1),
4,
{ STEP4(0,1) },
{ 0*4,1*4,2*4,3*4,4*4,5*4,6*4,7*4, 8*4,9*4,10*4,11*4,12*4,13*4,14*4,15*4 },
{ STEP16(0,4*16) },
16*16*4
};
static const gfx_layout char32layout =
{
32,32,
RGN_FRAC(1,1),
4,
{ STEP4(0,1) },
{ STEP32(0,4) },
{ STEP32(0,4*32) },
32*32*4
};
static GFXDECODE_START( gfx )
GFXDECODE_ENTRY( ":maincpu", 0, charlayout, 0, 16 )
GFXDECODE_ENTRY( ":maincpu", 0, char16layout, 0, 16 )
GFXDECODE_ENTRY( ":maincpu", 0, char32layout, 0, 16 )
GFXDECODE_ENTRY( ":maincpu", 0, charlayout6, 0, 16 ) // correct for lots of the tiles inc. startup text
GFXDECODE_END
MACHINE_CONFIG_START(spg110_device::device_add_mconfig)
// PALETTE(config, m_palette).set_format(palette_device::xRGB_555, 0x100);
// PALETTE(config, m_palette).set_format(palette_device::RGB_565, 0x100);
// PALETTE(config, m_palette).set_format(palette_device::IRGB_4444, 0x100);
// PALETTE(config, m_palette).set_format(palette_device::RGBI_4444, 0x100);
// PALETTE(config, m_palette).set_format(palette_device::xRGB_555, 0x100);
PALETTE(config, m_palette, palette_device::BLACK, 256);
GFXDECODE(config, m_gfxdecode, m_palette, gfx);
MACHINE_CONFIG_END
device_memory_interface::space_config_vector spg110_device::memory_space_config() const
{
return space_config_vector {
std::make_pair(0, &m_space_config)
};
}
spg110_device::spg110_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: spg110_device(mconfig, SPG110, tag, owner, clock)
{
}
READ16_MEMBER(spg110_device::spg110_2062_r)
{
return 0x1fff; // DMA related?
}
// irq source or similar?
READ16_MEMBER(spg110_device::spg110_2063_r)
{
@ -43,38 +147,422 @@ WRITE16_MEMBER(spg110_device::spg110_2063_w)
m_cpu->set_state_unsynced(UNSP_IRQ0_LINE, CLEAR_LINE);
}
READ16_MEMBER(spg110_device::datasegment_r)
{
uint16_t val = m_cpu->get_ds();
return val;
}
WRITE16_MEMBER(spg110_device::datasegment_w)
{
m_cpu->set_ds(data & 0x3f);
}
WRITE16_MEMBER(spg110_device::spg110_3221_w)
{
/* first write on startup? */
}
WRITE16_MEMBER(spg110_device::spg110_3223_w) { }
WRITE16_MEMBER(spg110_device::spg110_3225_w) { }
WRITE16_MEMBER(spg110_device::spg110_bg_scrollx_w) { COMBINE_DATA(&m_bg_scrollx); }
WRITE16_MEMBER(spg110_device::spg110_bg_scrolly_w) { COMBINE_DATA(&m_bg_scrolly); }
WRITE16_MEMBER(spg110_device::spg110_2012_w) { }
WRITE16_MEMBER(spg110_device::spg110_2013_w) { }
WRITE16_MEMBER(spg110_device::spg110_2014_w) { }
WRITE16_MEMBER(spg110_device::spg110_2015_w) { }
WRITE16_MEMBER(spg110_device::spg110_2016_w) { }
WRITE16_MEMBER(spg110_device::spg110_2017_w) { }
WRITE16_MEMBER(spg110_device::spg110_2018_w) { }
WRITE16_MEMBER(spg110_device::spg110_2019_w) { }
WRITE16_MEMBER(spg110_device::spg110_201a_w) { }
WRITE16_MEMBER(spg110_device::spg110_201b_w) { }
WRITE16_MEMBER(spg110_device::spg110_201c_w) { }
WRITE16_MEMBER(spg110_device::spg110_2020_w) { }
WRITE16_MEMBER(spg110_device::spg110_2042_w) { }
WRITE16_MEMBER(spg110_device::spg110_2031_w) { }
WRITE16_MEMBER(spg110_device::spg110_2032_w) { }
WRITE16_MEMBER(spg110_device::spg110_2033_w) { }
WRITE16_MEMBER(spg110_device::spg110_2034_w) { }
WRITE16_MEMBER(spg110_device::spg110_2035_w) { }
WRITE16_MEMBER(spg110_device::spg110_2036_w) { COMBINE_DATA(&m_2036_scroll); }
WRITE16_MEMBER(spg110_device::spg110_2039_w) { }
WRITE16_MEMBER(spg110_device::spg110_2037_w) { }
WRITE16_MEMBER(spg110_device::spg110_203c_w) { }
WRITE16_MEMBER(spg110_device::spg110_203d_w) { }
WRITE16_MEMBER(spg110_device::spg110_2045_w) { }
WRITE16_MEMBER(spg110_device::spg110_2028_w) { }
WRITE16_MEMBER(spg110_device::spg110_2029_w) { }
READ16_MEMBER(spg110_device::spg110_2028_r) { return 0x0000; }
READ16_MEMBER(spg110_device::spg110_2029_r) { return 0x0000; }
WRITE16_MEMBER(spg110_device::spg110_2050_w) { }
WRITE16_MEMBER(spg110_device::spg110_2051_w) { }
WRITE16_MEMBER(spg110_device::spg110_2052_w) { }
WRITE16_MEMBER(spg110_device::spg110_2053_w) { }
WRITE16_MEMBER(spg110_device::spg110_2054_w) { }
WRITE16_MEMBER(spg110_device::spg110_2055_w) { }
WRITE16_MEMBER(spg110_device::spg110_2056_w) { }
WRITE16_MEMBER(spg110_device::spg110_2057_w) { }
WRITE16_MEMBER(spg110_device::spg110_2058_w) { }
WRITE16_MEMBER(spg110_device::spg110_2059_w) { }
WRITE16_MEMBER(spg110_device::spg110_205a_w) { }
WRITE16_MEMBER(spg110_device::spg110_205b_w) { }
WRITE16_MEMBER(spg110_device::spg110_205c_w) { }
WRITE16_MEMBER(spg110_device::spg110_205d_w) { }
WRITE16_MEMBER(spg110_device::spg110_205e_w) { }
WRITE16_MEMBER(spg110_device::spg110_205f_w) { }
WRITE16_MEMBER(spg110_device::spg110_2061_w) { COMBINE_DATA(&m_2061_outer); }
WRITE16_MEMBER(spg110_device::spg110_2064_w) { COMBINE_DATA(&m_2064_outer); }
WRITE16_MEMBER(spg110_device::spg110_2067_w) { COMBINE_DATA(&m_2067_outer); }
WRITE16_MEMBER(spg110_device::spg110_2068_w) { COMBINE_DATA(&m_2068_outer); }
WRITE16_MEMBER(spg110_device::spg110_2060_w) { COMBINE_DATA(&m_2060_inner); }
WRITE16_MEMBER(spg110_device::spg110_2066_w) { COMBINE_DATA(&m_2066_inner); }
WRITE16_MEMBER(spg110_device::spg110_2062_w)
{
// int length = (data - 1) & 0xff;
int length = data & 0x1fff;
// this is presumably a counter that underflows to 0x1fff, because that's what the wait loop waits for?
logerror("%s: trigger (%04x) with values (written outer) %04x %04x %04x %04x | (written inner) %04x (ram source?) %04x\n", machine().describe_context(), data, m_2061_outer, m_2064_outer, m_2067_outer, m_2068_outer, m_2060_inner, m_2066_inner);
int source = m_2066_inner;
int dest = m_2060_inner;
// maybe
/*
if (!(m_2068_outer & 1))
{
length = length * 4;
}
*/
//logerror("[ ");
for (int i = 0; i < length; i++)
{
if (m_2068_outer & 1)
{
address_space &mem = m_cpu->space(AS_PROGRAM);
uint16_t val = mem.read_word(m_2066_inner + i);
this->space(0).write_word(dest * 2, val, 0xffff);
}
else // guess, it needs to clear layers somehow
{
// is there a fill mode to fill other values?
this->space(0).write_word(dest * 2, 0x0000, 0xffff);
}
source++;
// m_2064_outer is usually 1, but sometimes 0x20/0x40
dest+=m_2064_outer;
// logerror("%04x, ", val);
}
// logerror(" ]\n");
}
READ16_MEMBER(spg110_device::spg110_2062_r)
{
return 0x1fff; // DMA related?
}
READ16_MEMBER(spg110_device::spg110_2013_r) { return 0x0000; }
READ16_MEMBER(spg110_device::spg110_2019_r) { return 0x0000; }
READ16_MEMBER(spg110_device::spg110_2037_r) { return 0x0000; }
READ16_MEMBER(spg110_device::spg110_2042_r) { return 0x0000; }
WRITE16_MEMBER(spg110_device::spg110_3200_w) { }
WRITE16_MEMBER(spg110_device::spg110_3201_w) { }
WRITE16_MEMBER(spg110_device::spg110_3203_w) { }
WRITE16_MEMBER(spg110_device::spg110_3204_w) { }
WRITE16_MEMBER(spg110_device::spg110_3206_w) { }
WRITE16_MEMBER(spg110_device::spg110_3208_w) { }
WRITE16_MEMBER(spg110_device::spg110_3209_w) { }
READ16_MEMBER(spg110_device::spg110_3201_r) { return 0x0000; }
READ16_MEMBER(spg110_device::spg110_3225_r) { return 0x0000; }
READ16_MEMBER(spg110_device::spg110_322c_r) { return 0x0000; }
WRITE16_MEMBER(spg110_device::spg110_3100_w) { }
WRITE16_MEMBER(spg110_device::spg110_3101_w) { }
WRITE16_MEMBER(spg110_device::spg110_3102_w) { }
WRITE16_MEMBER(spg110_device::spg110_3104_w) { }
WRITE16_MEMBER(spg110_device::spg110_3105_w) { }
WRITE16_MEMBER(spg110_device::spg110_3106_w) { }
WRITE16_MEMBER(spg110_device::spg110_3107_w) { }
WRITE16_MEMBER(spg110_device::spg110_3108_w) { }
WRITE16_MEMBER(spg110_device::spg110_3109_w) { }
WRITE16_MEMBER(spg110_device::spg110_310b_w) { }
WRITE16_MEMBER(spg110_device::spg110_310c_w) { }
WRITE16_MEMBER(spg110_device::spg110_310d_w) { }
READ16_MEMBER(spg110_device::spg110_310f_r) { return 0x0000; }
void spg110_device::map(address_map &map)
{
map(0x000000, 0x000fff).ram();
// vregs are at 2000?
map(0x002060, 0x002060).nopw();
map(0x002062, 0x002062).r(FUNC(spg110_device::spg110_2062_r)).nopw();;
map(0x002063, 0x002063).rw(FUNC(spg110_device::spg110_2063_r),FUNC(spg110_device::spg110_2063_w));
map(0x002066, 0x002066).nopw();
map(0x002010, 0x002010).w(FUNC(spg110_device::spg110_bg_scrollx_w));
map(0x002011, 0x002011).w(FUNC(spg110_device::spg110_bg_scrolly_w));
map(0x002012, 0x002012).w(FUNC(spg110_device::spg110_2012_w));
map(0x002013, 0x002013).rw(FUNC(spg110_device::spg110_2013_r),FUNC(spg110_device::spg110_2013_w));
map(0x002014, 0x002014).w(FUNC(spg110_device::spg110_2014_w));
map(0x002015, 0x002015).w(FUNC(spg110_device::spg110_2015_w));
map(0x002016, 0x002016).w(FUNC(spg110_device::spg110_2016_w));
map(0x002017, 0x002017).w(FUNC(spg110_device::spg110_2017_w));
map(0x002018, 0x002018).w(FUNC(spg110_device::spg110_2018_w));
map(0x002019, 0x002019).rw(FUNC(spg110_device::spg110_2019_r), FUNC(spg110_device::spg110_2019_w));
map(0x00201a, 0x00201a).w(FUNC(spg110_device::spg110_201a_w));
map(0x00201b, 0x00201b).w(FUNC(spg110_device::spg110_201b_w));
map(0x00201c, 0x00201c).w(FUNC(spg110_device::spg110_201c_w));
map(0x002020, 0x002020).w(FUNC(spg110_device::spg110_2020_w));
map(0x002200, 0x0022ff).ram();
map(0x003000, 0x0030ff).ram();
map(0x002028, 0x002028).rw(FUNC(spg110_device::spg110_2028_r), FUNC(spg110_device::spg110_2028_w));
map(0x002029, 0x002029).rw(FUNC(spg110_device::spg110_2029_r), FUNC(spg110_device::spg110_2029_w));
map(0x002031, 0x002031).w(FUNC(spg110_device::spg110_2031_w)); // sometimes 14a?
map(0x002032, 0x002032).w(FUNC(spg110_device::spg110_2032_w)); // always 14a?
map(0x002033, 0x002033).w(FUNC(spg110_device::spg110_2033_w));
map(0x002034, 0x002034).w(FUNC(spg110_device::spg110_2034_w));
map(0x002035, 0x002035).w(FUNC(spg110_device::spg110_2035_w));
map(0x002036, 0x002036).w(FUNC(spg110_device::spg110_2036_w)); // possible scroll register?
map(0x002037, 0x002037).rw(FUNC(spg110_device::spg110_2037_r), FUNC(spg110_device::spg110_2037_w));
map(0x002039, 0x002039).w(FUNC(spg110_device::spg110_2039_w));
map(0x00203c, 0x00203c).w(FUNC(spg110_device::spg110_203c_w));
map(0x00203d, 0x00203d).w(FUNC(spg110_device::spg110_203d_w)); // possible scroll register?
map(0x002042, 0x002042).rw(FUNC(spg110_device::spg110_2042_r),FUNC(spg110_device::spg110_2042_w));
map(0x002045, 0x002045).w(FUNC(spg110_device::spg110_2045_w));
// seems to be 16 entries for.. something?
map(0x002050, 0x002050).w(FUNC(spg110_device::spg110_2050_w));
map(0x002051, 0x002051).w(FUNC(spg110_device::spg110_2051_w));
map(0x002052, 0x002052).w(FUNC(spg110_device::spg110_2052_w));
map(0x002053, 0x002053).w(FUNC(spg110_device::spg110_2053_w));
map(0x002054, 0x002054).w(FUNC(spg110_device::spg110_2054_w));
map(0x002055, 0x002055).w(FUNC(spg110_device::spg110_2055_w));
map(0x002056, 0x002056).w(FUNC(spg110_device::spg110_2056_w));
map(0x002057, 0x002057).w(FUNC(spg110_device::spg110_2057_w));
map(0x002058, 0x002058).w(FUNC(spg110_device::spg110_2058_w));
map(0x002059, 0x002059).w(FUNC(spg110_device::spg110_2059_w));
map(0x00205a, 0x00205a).w(FUNC(spg110_device::spg110_205a_w));
map(0x00205b, 0x00205b).w(FUNC(spg110_device::spg110_205b_w));
map(0x00205c, 0x00205c).w(FUNC(spg110_device::spg110_205c_w));
map(0x00205d, 0x00205d).w(FUNC(spg110_device::spg110_205d_w));
map(0x00205e, 0x00205e).w(FUNC(spg110_device::spg110_205e_w));
map(0x00205f, 0x00205f).w(FUNC(spg110_device::spg110_205f_w));
//map(0x002010, 0x00205f).ram();
// everything (dma? and interrupt flag?!)
map(0x002060, 0x002060).w(FUNC(spg110_device::spg110_2060_w));
map(0x002061, 0x002061).w(FUNC(spg110_device::spg110_2061_w));
map(0x002062, 0x002062).rw(FUNC(spg110_device::spg110_2062_r),FUNC(spg110_device::spg110_2062_w));
map(0x002063, 0x002063).rw(FUNC(spg110_device::spg110_2063_r),FUNC(spg110_device::spg110_2063_w)); // this looks like interrupt stuff and is checked in the irq like an irq source, but why in the middle of what otherwise look like some kind of DMA?
map(0x002064, 0x002064).w(FUNC(spg110_device::spg110_2064_w));
map(0x002066, 0x002066).w(FUNC(spg110_device::spg110_2066_w));
map(0x002067, 0x002067).w(FUNC(spg110_device::spg110_2067_w));
map(0x002068, 0x002068).w(FUNC(spg110_device::spg110_2068_w));
map(0x002200, 0x0022ff).ram(); // looks like per-pen brightness or similar? strange because palette isn't memory mapped here
map(0x003000, 0x00307f).ram(); // sound registers? seems to be 8 long entries, only uses up to 0x7f?
map(0x003080, 0x0030ff).ram();
map(0x003100, 0x003100).w(FUNC(spg110_device::spg110_3100_w));
map(0x003101, 0x003101).w(FUNC(spg110_device::spg110_3101_w));
map(0x003102, 0x003102).w(FUNC(spg110_device::spg110_3102_w));
map(0x003104, 0x003104).w(FUNC(spg110_device::spg110_3104_w));
map(0x003105, 0x003105).w(FUNC(spg110_device::spg110_3105_w));
map(0x003106, 0x003106).w(FUNC(spg110_device::spg110_3106_w));
map(0x003107, 0x003107).w(FUNC(spg110_device::spg110_3107_w));
map(0x003108, 0x003108).w(FUNC(spg110_device::spg110_3108_w));
map(0x003109, 0x003109).w(FUNC(spg110_device::spg110_3109_w));
map(0x00310b, 0x00310b).w(FUNC(spg110_device::spg110_310b_w));
map(0x00310c, 0x00310c).w(FUNC(spg110_device::spg110_310c_w));
map(0x00310d, 0x00310d).w(FUNC(spg110_device::spg110_310d_w));
map(0x00310f, 0x00310f).r(FUNC(spg110_device::spg110_310f_r));
// 0032xx looks like it could be the same as 003d00 on spg2xx
map(0x003200, 0x003200).w(FUNC(spg110_device::spg110_3200_w));
map(0x003201, 0x003201).rw(FUNC(spg110_device::spg110_3201_r),FUNC(spg110_device::spg110_3201_w));
map(0x003203, 0x003203).w(FUNC(spg110_device::spg110_3203_w));
map(0x003204, 0x003204).w(FUNC(spg110_device::spg110_3204_w));
map(0x003206, 0x003206).w(FUNC(spg110_device::spg110_3206_w));
map(0x003208, 0x003208).w(FUNC(spg110_device::spg110_3208_w));
map(0x003209, 0x003209).w(FUNC(spg110_device::spg110_3209_w));
map(0x003221, 0x003221).w(FUNC(spg110_device::spg110_3221_w));
map(0x003223, 0x003223).w(FUNC(spg110_device::spg110_3223_w));
map(0x003225, 0x003225).rw(FUNC(spg110_device::spg110_3225_r),FUNC(spg110_device::spg110_3225_w));
map(0x00322c, 0x00322c).r(FUNC(spg110_device::spg110_322c_r));
map(0x00322f, 0x00322f).rw(FUNC(spg110_device::datasegment_r),FUNC(spg110_device::datasegment_w));
}
// this seems to be a different, non-cpu mapped space only accessible via the DMA?
void spg110_device::map_video(address_map &map)
{
// are these addresses hardcoded, or can they move (in which case tilemap system isn't really suitable)
map(0x00000, 0x00fff).ram().w(FUNC(spg110_device::bg_videoram_w)).share("bg_videoram");
map(0x01000, 0x017ff).ram().w(FUNC(spg110_device::bg_attrram_w)).share("bg_attrram");
map(0x01800, 0x027ff).ram().w(FUNC(spg110_device::fg_videoram_w)).share("fg_videoram");
map(0x02800, 0x02fff).ram().w(FUNC(spg110_device::fg_attrram_w)).share("fg_attrram");
map(0x04000, 0x04fff).ram(); // seems to be 3 blocks, almost certainly spritelist
// map(0x08000, 0x081ff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette"); // probably? format unknown tho
map(0x08000, 0x081ff).ram().share("palram");
}
/*
TIMER_CALLBACK_MEMBER(spg110_device::test_timer)
{
//
}
*/
TILE_GET_INFO_MEMBER(spg110_device::get_bg_tile_info)
{
int tileno = m_bg_videoram[tile_index];
int attr = m_bg_attrram[tile_index/2];
if (tile_index&1) attr = (attr & 0xff00)>>8;
else attr = attr & 0x00ff;
SET_TILE_INFO_MEMBER(3, tileno, 0, 0);
tileinfo.category = (attr >> 4) & 0x0f; // very likely wrong, complete guess
}
TILE_GET_INFO_MEMBER(spg110_device::get_fg_tile_info)
{
int tileno = m_fg_videoram[tile_index];
int attr = m_fg_attrram[tile_index/2];
if (tile_index&1) attr = (attr & 0xff00)>>8;
else attr = attr & 0x00ff;
int pal = attr & 0x0f;
SET_TILE_INFO_MEMBER(0, tileno, pal, 0);
tileinfo.category = (attr >> 4) & 0x0f; // very likely wrong, complete guess
}
void spg110_device::device_start()
{
// m_test_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(spg110_device::test_timer), this));
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(spg110_device::get_bg_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 64, 32);
m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(spg110_device::get_fg_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 64, 32);
m_fg_tilemap->set_transparent_pen(0);
save_item(NAME(m_2068_outer));
save_item(NAME(m_2064_outer));
save_item(NAME(m_2061_outer));
save_item(NAME(m_2067_outer));
save_item(NAME(m_2060_inner));
save_item(NAME(m_2066_inner));
save_item(NAME(m_bg_scrollx));
save_item(NAME(m_bg_scrolly));
save_item(NAME(m_2036_scroll));
}
void spg110_device::device_reset()
{
m_2068_outer = 0;
m_2064_outer = 0;
m_2061_outer = 0;
m_2067_outer = 0;
m_2060_inner = 0;
m_2066_inner = 0;
m_bg_scrollx = 0;
m_bg_scrolly = 0;
m_2036_scroll = 0;
}
double spg110_device::hue2rgb(double p, double q, double t)
{
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1 / 6.0f) return p + (q - p) * 6 * t;
if (t < 1 / 2.0f) return q;
if (t < 2 / 3.0f) return p + (q - p) * (2 / 3.0f - t) * 6;
return p;
}
uint32_t spg110_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
// Palette, this is still wrong!
int offs = 0;
for (int index = 0;index < 256; index++)
{
uint16_t dat = m_palram[offs++];
// llll lsss sshh hhhh
int l_raw = (dat & 0xf800) >> 11;
int sl_raw = (dat & 0x07c0) >> 6;
int h_raw = (dat & 0x003f) >> 0;
double l = (double)l_raw / 31.0f;
double s = (double)sl_raw / 31.0f;
double h = (double)h_raw / 47.0f;
double r, g, b;
if (s == 0) {
r = g = b = l; // greyscale
} else {
double q = l < 0.5f ? l * (1 + s) : l + s - l * s;
double p = 2 * l - q;
r = hue2rgb(p, q, h + 1/3.0f);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3.0f);
}
int r_real = r * 255.0f;
int g_real = g * 255.0f;
int b_real = b * 255.0f;
m_palette->set_pen_color(index, r_real, g_real, b_real);
}
m_bg_tilemap->set_scrollx(0, m_bg_scrollx);
m_bg_tilemap->set_scrolly(0, m_bg_scrolly);
m_fg_tilemap->set_scrollx(0, 8); // where does this come from?
// what is 2036 used for, also looks like scrolling, maybe some sprite offset? or zoom? (reference videos suggest maybe start logo text zooms?)
for (int pri = 0; pri < 0x10; pri++) // priority is probably not correct, this is just using a random tile attribute with single use case
{
m_bg_tilemap->draw(screen, bitmap, cliprect, pri, pri, 0);
m_fg_tilemap->draw(screen, bitmap, cliprect, pri, pri, 0);
}
return 0;
}

View File

@ -8,8 +8,11 @@
//#include "spg2xx.h"
#include "cpu/unsp/unsp.h"
#include "emupal.h"
class spg110_device : public device_t, public device_memory_interface
class spg110_device : public device_t
{
public:
spg110_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
@ -23,7 +26,9 @@ public:
}
void map(address_map &map);
void map_video(address_map &map);
double hue2rgb(double p, double q, double t);
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
DECLARE_WRITE_LINE_MEMBER(vblank);
@ -31,15 +36,160 @@ protected:
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_add_mconfig(machine_config &config) override;
virtual space_config_vector memory_space_config() const override;
address_space_config m_space_config;
private:
required_device<unsp_device> m_cpu;
required_device<palette_device> m_palette;
required_device<gfxdecode_device> m_gfxdecode;
required_shared_ptr<uint16_t> m_bg_videoram;
required_shared_ptr<uint16_t> m_fg_videoram;
required_shared_ptr<uint16_t> m_bg_attrram;
required_shared_ptr<uint16_t> m_fg_attrram;
required_shared_ptr<uint16_t> m_palram;
tilemap_t *m_bg_tilemap;
tilemap_t *m_fg_tilemap;
//TIMER_CALLBACK_MEMBER(test_timer);
//emu_timer *m_test_timer;
DECLARE_WRITE16_MEMBER(bg_videoram_w);
DECLARE_WRITE16_MEMBER(bg_attrram_w);
TILE_GET_INFO_MEMBER(get_bg_tile_info);
DECLARE_WRITE16_MEMBER(fg_videoram_w);
DECLARE_WRITE16_MEMBER(fg_attrram_w);
TILE_GET_INFO_MEMBER(get_fg_tile_info);
DECLARE_READ16_MEMBER(spg110_2013_r);
DECLARE_READ16_MEMBER(spg110_2019_r);
DECLARE_WRITE16_MEMBER(spg110_bg_scrollx_w);
DECLARE_WRITE16_MEMBER(spg110_bg_scrolly_w);
DECLARE_WRITE16_MEMBER(spg110_2012_w);
DECLARE_WRITE16_MEMBER(spg110_2013_w);
DECLARE_WRITE16_MEMBER(spg110_2014_w);
DECLARE_WRITE16_MEMBER(spg110_2015_w);
DECLARE_WRITE16_MEMBER(spg110_2016_w);
DECLARE_WRITE16_MEMBER(spg110_2017_w);
DECLARE_WRITE16_MEMBER(spg110_2018_w);
DECLARE_WRITE16_MEMBER(spg110_2019_w);
DECLARE_WRITE16_MEMBER(spg110_201a_w);
DECLARE_WRITE16_MEMBER(spg110_201b_w);
DECLARE_WRITE16_MEMBER(spg110_201c_w);
DECLARE_WRITE16_MEMBER(spg110_2020_w);
DECLARE_WRITE16_MEMBER(spg110_2028_w);
DECLARE_WRITE16_MEMBER(spg110_2029_w);
DECLARE_READ16_MEMBER(spg110_2028_r);
DECLARE_READ16_MEMBER(spg110_2029_r);
DECLARE_WRITE16_MEMBER(spg110_2031_w);
DECLARE_WRITE16_MEMBER(spg110_2032_w);
DECLARE_WRITE16_MEMBER(spg110_2033_w);
DECLARE_WRITE16_MEMBER(spg110_2034_w);
DECLARE_WRITE16_MEMBER(spg110_2035_w);
DECLARE_WRITE16_MEMBER(spg110_2036_w);
DECLARE_WRITE16_MEMBER(spg110_2037_w);
DECLARE_WRITE16_MEMBER(spg110_2039_w);
DECLARE_WRITE16_MEMBER(spg110_203c_w);
DECLARE_WRITE16_MEMBER(spg110_203d_w);
DECLARE_WRITE16_MEMBER(spg110_2042_w);
DECLARE_WRITE16_MEMBER(spg110_2045_w);
DECLARE_WRITE16_MEMBER(spg110_2050_w);
DECLARE_WRITE16_MEMBER(spg110_2051_w);
DECLARE_WRITE16_MEMBER(spg110_2052_w);
DECLARE_WRITE16_MEMBER(spg110_2053_w);
DECLARE_WRITE16_MEMBER(spg110_2054_w);
DECLARE_WRITE16_MEMBER(spg110_2055_w);
DECLARE_WRITE16_MEMBER(spg110_2056_w);
DECLARE_WRITE16_MEMBER(spg110_2057_w);
DECLARE_WRITE16_MEMBER(spg110_2058_w);
DECLARE_WRITE16_MEMBER(spg110_2059_w);
DECLARE_WRITE16_MEMBER(spg110_205a_w);
DECLARE_WRITE16_MEMBER(spg110_205b_w);
DECLARE_WRITE16_MEMBER(spg110_205c_w);
DECLARE_WRITE16_MEMBER(spg110_205d_w);
DECLARE_WRITE16_MEMBER(spg110_205e_w);
DECLARE_WRITE16_MEMBER(spg110_205f_w);
DECLARE_READ16_MEMBER(spg110_2037_r);
DECLARE_READ16_MEMBER(spg110_2042_r);
DECLARE_WRITE16_MEMBER(spg110_2060_w);
DECLARE_WRITE16_MEMBER(spg110_2061_w);
DECLARE_WRITE16_MEMBER(spg110_2062_w);
DECLARE_WRITE16_MEMBER(spg110_2063_w);
DECLARE_WRITE16_MEMBER(spg110_2064_w);
DECLARE_WRITE16_MEMBER(spg110_2066_w);
DECLARE_WRITE16_MEMBER(spg110_2067_w);
DECLARE_WRITE16_MEMBER(spg110_2068_w);
DECLARE_READ16_MEMBER(spg110_2062_r);
DECLARE_READ16_MEMBER(spg110_2063_r);
DECLARE_WRITE16_MEMBER(spg110_2063_w);
};
DECLARE_WRITE16_MEMBER(spg110_3200_w);
DECLARE_WRITE16_MEMBER(spg110_3201_w);
DECLARE_WRITE16_MEMBER(spg110_3203_w);
DECLARE_WRITE16_MEMBER(spg110_3204_w);
DECLARE_WRITE16_MEMBER(spg110_3206_w);
DECLARE_WRITE16_MEMBER(spg110_3208_w);
DECLARE_WRITE16_MEMBER(spg110_3209_w);
DECLARE_READ16_MEMBER(spg110_3201_r);
DECLARE_WRITE16_MEMBER(spg110_3221_w);
DECLARE_WRITE16_MEMBER(spg110_3223_w);
DECLARE_WRITE16_MEMBER(spg110_3225_w);
DECLARE_READ16_MEMBER(spg110_3225_r);
DECLARE_READ16_MEMBER(spg110_322c_r);
READ16_MEMBER(datasegment_r);
WRITE16_MEMBER(datasegment_w);
DECLARE_WRITE16_MEMBER(spg110_3100_w);
DECLARE_WRITE16_MEMBER(spg110_3101_w);
DECLARE_WRITE16_MEMBER(spg110_3102_w);
DECLARE_WRITE16_MEMBER(spg110_3104_w);
DECLARE_WRITE16_MEMBER(spg110_3105_w);
DECLARE_WRITE16_MEMBER(spg110_3106_w);
DECLARE_WRITE16_MEMBER(spg110_3107_w);
DECLARE_WRITE16_MEMBER(spg110_3108_w);
DECLARE_WRITE16_MEMBER(spg110_3109_w);
DECLARE_WRITE16_MEMBER(spg110_310b_w);
DECLARE_WRITE16_MEMBER(spg110_310c_w);
DECLARE_WRITE16_MEMBER(spg110_310d_w);
DECLARE_READ16_MEMBER(spg110_310f_r);
uint16_t m_2068_outer;
uint16_t m_2064_outer;
uint16_t m_2061_outer;
uint16_t m_2067_outer;
uint16_t m_2060_inner;
uint16_t m_2066_inner;
uint16_t m_bg_scrollx;
uint16_t m_bg_scrolly;
uint16_t m_2036_scroll;
};
DECLARE_DEVICE_TYPE(SPG110, spg110_device)