srmp6.cpp : Updates

Use buffered_spriteram16 for sprite ram, Use shorter type values, Fix namings, Add notes, Fix color fading, Minor corrections, Add save states, Reduce runtime tag lookups, Minor code style fixes, Simplified gfxdecode
This commit is contained in:
cam900 2019-01-06 14:35:35 +09:00 committed by Vas Crabb
parent ace20271b3
commit ea91b15e36

View File

@ -70,6 +70,7 @@ Dumped 06/15/2000
#include "emu.h"
#include "cpu/m68000/m68000.h"
#include "video/bufsprite.h"
#include "sound/nile.h"
#include "emupal.h"
#include "screen.h"
@ -81,51 +82,54 @@ class srmp6_state : public driver_device
public:
srmp6_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_sprram(*this, "sprram"),
m_chrram(*this, "chrram"),
m_dmaram(*this, "dmaram"),
m_video_regs(*this, "video_regs"),
m_nile_region(*this, "nile"),
m_nile_bank(*this, "nile_bank"),
m_key_io(*this, "KEY%u", 0U),
m_maincpu(*this, "maincpu"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette")
m_palette(*this, "palette"),
m_sprram(*this, "sprram")
{ }
void srmp6(machine_config &config);
private:
std::unique_ptr<uint16_t[]> m_tileram;
required_shared_ptr<uint16_t> m_sprram;
required_shared_ptr<uint16_t> m_chrram;
optional_shared_ptr<uint16_t> m_dmaram;
required_shared_ptr<uint16_t> m_video_regs;
std::unique_ptr<u16[]> m_tileram;
required_shared_ptr<u16> m_chrram;
optional_shared_ptr<u16> m_dmaram;
required_shared_ptr<u16> m_video_regs;
required_region_ptr<u8> m_nile_region;
std::unique_ptr<uint16_t[]> m_sprram_old;
required_memory_bank m_nile_bank;
required_ioport_array<4> m_key_io;
int m_brightness;
uint16_t m_input_select;
u16 m_input_select;
unsigned short m_lastb;
unsigned short m_lastb2;
u16 m_lastb;
u16 m_lastb2;
int m_destl;
void init_INIT();
DECLARE_WRITE16_MEMBER(srmp6_input_select_w);
DECLARE_READ16_MEMBER(srmp6_inputs_r);
DECLARE_WRITE16_MEMBER(input_select_w);
DECLARE_READ16_MEMBER(inputs_r);
DECLARE_WRITE16_MEMBER(video_regs_w);
DECLARE_READ16_MEMBER(video_regs_r);
DECLARE_WRITE16_MEMBER(srmp6_dma_w);
DECLARE_WRITE16_MEMBER(dma_w);
DECLARE_READ16_MEMBER(tileram_r);
DECLARE_WRITE16_MEMBER(tileram_w);
DECLARE_WRITE16_MEMBER(paletteram_w);
DECLARE_READ16_MEMBER(srmp6_irq_ack_r);
DECLARE_READ16_MEMBER(irq_ack_r);
virtual void machine_start() override;
virtual void video_start() override;
uint32_t screen_update_srmp6(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
void update_palette();
uint32_t process(uint8_t b,uint32_t dst_offset);
u32 process(u8 b,u32 dst_offset);
required_device<cpu_device> m_maincpu;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_device<buffered_spriteram16_device> m_sprram;
void srmp6_map(address_map &map);
};
@ -137,105 +141,109 @@ static const gfx_layout tiles8x8_layout =
8,8,
(0x100000*16)/0x40,
8,
{ 0,1,2,3,4,5,6,7 },
{ 0*8,1*8,2*8,3*8,4*8,5*8,6*8,7*8 },
{ 0*64,1*64,2*64,3*64,4*64,5*64,6*64,7*64 },
{ STEP8(0,1) },
{ STEP8(0,8) },
{ STEP8(0,8*8) },
8*64
};
static inline u8 get_fade(int c, int f) // same as CPS3?
{
// bit 7 unknown
// bit 6 fade enable / disable
// bit 5 fade mode
// bit 4-0 fade value
if (f & 0x40) // Fading enable / disable
{
f &= 0x3f;
c = (f & 0x20) ? (c + (((0x1f - c) * (f & 0x1f)) / 0x1f)) : ((c * f) / 0x1f);
c = std::max(0, std::min(0x1f, c));
}
return c;
}
void srmp6_state::update_palette()
{
int8_t r, g ,b;
int brg = m_brightness - 0x60;
int i;
int brg = m_brightness & 0x7f;
for(i = 0; i < 0x800; i++)
for (int i = 0; i < m_palette->entries(); i++)
{
r = m_palette->basemem().read16(i) >> 0 & 0x1F;
g = m_palette->basemem().read16(i) >> 5 & 0x1F;
b = m_palette->basemem().read16(i) >> 10 & 0x1F;
u8 r = m_palette->basemem().read16(i) >> 0 & 0x1F;
u8 g = m_palette->basemem().read16(i) >> 5 & 0x1F;
u8 b = m_palette->basemem().read16(i) >> 10 & 0x1F;
if(brg < 0) {
r += (r * brg) >> 5;
if(r < 0) r = 0;
g += (g * brg) >> 5;
if(g < 0) g = 0;
b += (b * brg) >> 5;
if(b < 0) b = 0;
if (brg & 0x40)
{
r = get_fade(r, brg);
g = get_fade(g, brg);
b = get_fade(b, brg);
}
else if(brg > 0) {
r += ((0x1F - r) * brg) >> 5;
if(r > 0x1F) r = 0x1F;
g += ((0x1F - g) * brg) >> 5;
if(g > 0x1F) g = 0x1F;
b += ((0x1F - b) * brg) >> 5;
if(b > 0x1F) b = 0x1F;
}
m_palette->set_pen_color(i, rgb_t(r << 3, g << 3, b << 3));
m_palette->set_pen_color(i, pal5bit(r), pal5bit(g), pal5bit(b));
}
}
void srmp6_state::video_start()
{
m_tileram = make_unique_clear<uint16_t[]>(0x100000*16/2);
m_tileram = make_unique_clear<u16[]>(0x100000*16/2);
m_dmaram.allocate(0x100/2);
m_sprram_old = make_unique_clear<uint16_t[]>(0x80000/2);
/* create the char set (gfx will then be updated dynamically from RAM) */
m_gfxdecode->set_gfx(0, std::make_unique<gfx_element>(m_palette, tiles8x8_layout, (uint8_t*)m_tileram.get(), 0, m_palette->entries() / 256, 0));
m_gfxdecode->set_gfx(0, std::make_unique<gfx_element>(m_palette, tiles8x8_layout, (u8*)m_tileram.get(), 0, m_palette->entries() / 256, 0));
m_gfxdecode->gfx(0)->set_granularity(256);
m_brightness = 0x60;
m_brightness = 0;
save_pointer(NAME(m_tileram), 0x100000*16/2);
save_item(NAME(m_brightness));
}
#if 0
static int xixi=0;
static int xixi = 0;
#endif
uint32_t srmp6_state::screen_update_srmp6(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
u32 srmp6_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
int alpha;
int x,y,tileno,height,width,xw,yw,sprite,xb,yb;
uint16_t *sprite_list = m_sprram_old.get();
uint16_t mainlist_offset = 0;
u16 *sprite_list = m_sprram->buffer();
u16 mainlist_offset = 0;
union
{
int16_t a;
uint16_t b;
s16 a;
u16 b;
} temp;
bitmap.fill(0, cliprect);
#if 0
/* debug */
if(machine().input().code_pressed_once(KEYCODE_Q))
if (machine().input().code_pressed_once(KEYCODE_Q))
{
++xixi;
printf("%x\n",xixi);
logerror("%x\n",xixi);
}
if(machine().input().code_pressed_once(KEYCODE_W))
if (machine().input().code_pressed_once(KEYCODE_W))
{
--xixi;
printf("%x\n",xixi);
logerror("%x\n",xixi);
}
#endif
/* Main spritelist is 0x0000 - 0x1fff in spriteram, sublists follow */
while (mainlist_offset<0x2000/2)
{
uint16_t *sprite_sublist = &m_sprram_old[sprite_list[mainlist_offset+1]<<3];
uint16_t sublist_length=sprite_list[mainlist_offset+0]&0x7fff; //+1 ?
int16_t global_x,global_y, flip_x, flip_y;
uint16_t global_pal;
u16 *sprite_sublist = &sprite_list[sprite_list[mainlist_offset+1]<<3];
u16 sublist_length=sprite_list[mainlist_offset+0] & 0x7fff; //+1 ?
s16 global_x,global_y, flip_x, flip_y;
u16 global_pal;
/* end of list marker */
if (sprite_list[mainlist_offset+0] == 0x8000)
break;
if(sprite_list[mainlist_offset+0]!=0)
if (sprite_list[mainlist_offset+0] != 0)
{
temp.b=sprite_list[mainlist_offset+2];
global_x=temp.a;
@ -244,19 +252,19 @@ uint32_t srmp6_state::screen_update_srmp6(screen_device &screen, bitmap_rgb32 &b
global_pal = sprite_list[mainlist_offset+4] & 0x7;
if((sprite_list[mainlist_offset+5] & 0x700) == 0x700)
if ((sprite_list[mainlist_offset+5] & 0x700) == 0x700)
{
alpha = (sprite_list[mainlist_offset+5] & 0x1F) << 3;
alpha = pal5bit(sprite_list[mainlist_offset+5] & 0x1F);
}
else
{
alpha = 255;
}
// printf("%x %x \n",sprite_list[mainlist_offset+1],sublist_length);
// logerror("%x %x \n",sprite_list[mainlist_offset+1],sublist_length);
while(sublist_length)
while (sublist_length)
{
sprite=sprite_sublist[0]&0x7fff;
sprite=sprite_sublist[0] & 0x7fff;
flip_x=sprite_sublist[1]>>8&1;
flip_y=sprite_sublist[1]>>9&1;
temp.b=sprite_sublist[2];
@ -266,26 +274,26 @@ uint32_t srmp6_state::screen_update_srmp6(screen_device &screen, bitmap_rgb32 &b
//x+=global_x;
//y+=global_y;
width=((sprite_sublist[1])&0x3);
height=((sprite_sublist[1]>>2)&0x3);
width=((sprite_sublist[1]) & 0x3);
height=((sprite_sublist[1]>>2) & 0x3);
height = 1 << height;
width = 1 << width;
y-=height*8;
tileno = sprite;
//tileno += (sprite_list[4]&0xf)*0x4000; // this makes things worse in places (title screen for example)
//tileno += (sprite_list[4] & 0xf)*0x4000; // this makes things worse in places (title screen for example)
for(xw=0;xw<width;xw++)
for (xw = 0; xw < width; xw++)
{
for(yw=0;yw<height;yw++)
for (yw = 0; yw < height; yw++)
{
if(!flip_x)
if (!flip_x)
xb=x+xw*8+global_x;
else
xb=x+(width-xw-1)*8+global_x;
if(!flip_y)
if (!flip_y)
yb=y+yw*8+global_y;
else
yb=y+(height-yw-1)*8+global_y;
@ -294,7 +302,6 @@ uint32_t srmp6_state::screen_update_srmp6(screen_device &screen, bitmap_rgb32 &b
tileno++;
}
}
sprite_sublist+=8;
--sublist_length;
}
@ -302,9 +309,9 @@ uint32_t srmp6_state::screen_update_srmp6(screen_device &screen, bitmap_rgb32 &b
mainlist_offset+=8;
}
memcpy(m_sprram_old.get(), m_sprram, 0x80000);
m_sprram->copy();
if(machine().input().code_pressed_once(KEYCODE_Q))
if (machine().input().code_pressed_once(KEYCODE_Q))
{
FILE *p=fopen("tileram.bin","wb");
fwrite(m_tileram.get(), 1, 0x100000*16, p);
@ -321,25 +328,23 @@ uint32_t srmp6_state::screen_update_srmp6(screen_device &screen, bitmap_rgb32 &b
void srmp6_state::machine_start()
{
membank("bank1")->configure_entries(0, 16, memregion("nile")->base(), 0x200000);
m_nile_bank->configure_entries(0, 16, memregion("nile")->base(), 0x200000);
save_item(NAME(m_input_select));
}
WRITE16_MEMBER(srmp6_state::srmp6_input_select_w)
WRITE16_MEMBER(srmp6_state::input_select_w)
{
m_input_select = data & 0x0f;
}
READ16_MEMBER(srmp6_state::srmp6_inputs_r)
READ16_MEMBER(srmp6_state::inputs_r)
{
if (offset == 0) // DSW
return ioport("DSW")->read();
switch (m_input_select) // inputs
{
case 1<<0: return ioport("KEY0")->read();
case 1<<1: return ioport("KEY1")->read();
case 1<<2: return ioport("KEY2")->read();
case 1<<3: return ioport("KEY3")->read();
case 1<<0: return m_key_io[0]->read();
case 1<<1: return m_key_io[1]->read();
case 1<<2: return m_key_io[2]->read();
case 1<<3: return m_key_io[3]->read();
}
return 0;
@ -348,20 +353,20 @@ READ16_MEMBER(srmp6_state::srmp6_inputs_r)
WRITE16_MEMBER(srmp6_state::video_regs_w)
{
switch(offset)
switch (offset)
{
case 0x5e/2: // bank switch, used by ROM check
{
LOG(("%x\n",data));
membank("bank1")->set_entry(data & 0x0f);
m_nile_bank->set_entry(data & 0x0f);
break;
}
// set by IT4
case 0x5c/2: // either 0x40 explicitely in many places, or according $2083b0 (IT4)
//Fade in/out (0x40(dark)-0x60(normal)-0x7e?(bright) reset by 0x00?
data = (!data)?0x60:(data == 0x5e)?0x60:data;
if (m_brightness != data) {
if (m_brightness != data)
{
m_brightness = data;
update_palette();
}
@ -392,18 +397,17 @@ READ16_MEMBER(srmp6_state::video_regs_r)
/* DMA RLE stuff - the same as CPS3 */
uint32_t srmp6_state::process(uint8_t b,uint32_t dst_offset)
u32 srmp6_state::process(u8 b,u32 dst_offset)
{
int l=0;
int l = 0;
uint8_t *tram=(uint8_t*)m_tileram.get();
u8 *tram=(u8*)m_tileram.get();
if (m_lastb == m_lastb2) //rle
{
int i;
int rle=(b+1)&0xff;
int rle=(b+1) & 0xff;
for(i=0;i<rle;++i)
for (int i = 0; i <rle; ++i)
{
tram[dst_offset + m_destl] = m_lastb;
m_gfxdecode->gfx(0)->mark_dirty((dst_offset + m_destl)/0x40);
@ -427,18 +431,17 @@ uint32_t srmp6_state::process(uint8_t b,uint32_t dst_offset)
}
WRITE16_MEMBER(srmp6_state::srmp6_dma_w)
WRITE16_MEMBER(srmp6_state::dma_w)
{
uint16_t* dmaram = m_dmaram;
u16* dmaram = m_dmaram;
COMBINE_DATA(&dmaram[offset]);
if (offset==13 && dmaram[offset]==0x40)
{
const uint8_t *rom = memregion("nile")->base();
uint32_t srctab=2*((((uint32_t)dmaram[5])<<16)|dmaram[4]);
uint32_t srcdata=2*((((uint32_t)dmaram[11])<<16)|dmaram[10]);
uint32_t len=4*(((((uint32_t)dmaram[7]&3)<<16)|dmaram[6])+1); //??? WRONG!
int tempidx=0;
u32 srctab=2*((((u32)dmaram[5])<<16)|dmaram[4]);
u32 srcdata=2*((((u32)dmaram[11])<<16)|dmaram[10]);
u32 len=4*(((((u32)dmaram[7]&3)<<16)|dmaram[6])+1); //??? WRONG!
int tempidx = 0;
/* show params */
LOG(("DMA! %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x\n",
@ -462,22 +465,21 @@ WRITE16_MEMBER(srmp6_state::srmp6_dma_w)
m_lastb = 0xfffe;
m_lastb2 = 0xffff;
while(1)
while (1)
{
int i;
uint8_t ctrl=rom[srcdata];
u8 ctrl=m_nile_region[srcdata];
++srcdata;
for(i=0;i<8;++i)
for (int i = 0; i < 8; ++i)
{
uint8_t p=rom[srcdata];
u8 p=m_nile_region[srcdata];
if(ctrl&0x80)
if (ctrl & 0x80)
{
uint8_t real_byte;
real_byte = rom[srctab+p*2];
u8 real_byte;
real_byte = m_nile_region[srctab+p*2];
tempidx+=process(real_byte,tempidx);
real_byte = rom[srctab+p*2+1];//px[DMA_XOR((current_table_address+p*2+1))];
real_byte = m_nile_region[srctab+p*2+1];//px[DMA_XOR((current_table_address+p*2+1))];
tempidx+=process(real_byte,tempidx);
}
else
@ -488,8 +490,7 @@ WRITE16_MEMBER(srmp6_state::srmp6_dma_w)
ctrl<<=1;
++srcdata;
if(tempidx>=len)
if (tempidx >= len)
{
LOG(("%x\n",srcdata));
return;
@ -507,52 +508,38 @@ READ16_MEMBER(srmp6_state::tileram_r)
WRITE16_MEMBER(srmp6_state::tileram_w)
{
//uint16_t tmp;
//u16 tmp;
COMBINE_DATA(&m_chrram[offset]);
/* are the DMA registers enabled some other way, or always mapped here, over RAM? */
if (offset >= 0xfff00/2 && offset <= 0xfff1a/2 )
{
offset &=0x1f;
srmp6_dma_w(space,offset,data,mem_mask);
dma_w(space,offset,data,mem_mask);
}
}
WRITE16_MEMBER(srmp6_state::paletteram_w)
{
int8_t r, g, b;
int brg = m_brightness - 0x60;
int brg = m_brightness & 0x7f;
m_palette->write16(space, offset, data, mem_mask);
if(brg)
if (brg & 0x40)
{
r = data >> 0 & 0x1F;
g = data >> 5 & 0x1F;
b = data >> 10 & 0x1F;
u8 r = m_palette->basemem().read16(offset) >> 0 & 0x1F;
u8 g = m_palette->basemem().read16(offset) >> 5 & 0x1F;
u8 b = m_palette->basemem().read16(offset) >> 10 & 0x1F;
if(brg < 0) {
r += (r * brg) >> 5;
if(r < 0) r = 0;
g += (g * brg) >> 5;
if(g < 0) g = 0;
b += (b * brg) >> 5;
if(b < 0) b = 0;
}
else if(brg > 0) {
r += ((0x1F - r) * brg) >> 5;
if(r > 0x1F) r = 0x1F;
g += ((0x1F - g) * brg) >> 5;
if(g > 0x1F) g = 0x1F;
b += ((0x1F - b) * brg) >> 5;
if(b > 0x1F) b = 0x1F;
}
r = get_fade(r, brg);
g = get_fade(g, brg);
b = get_fade(b, brg);
m_palette->set_pen_color(offset, rgb_t(r << 3, g << 3, b << 3));
m_palette->set_pen_color(offset, pal5bit(r), pal5bit(g), pal5bit(b));
}
}
READ16_MEMBER(srmp6_state::srmp6_irq_ack_r)
READ16_MEMBER(srmp6_state::irq_ack_r)
{
m_maincpu->set_input_line(4, CLEAR_LINE);
return 0; // value read doesn't matter
@ -562,26 +549,29 @@ void srmp6_state::srmp6_map(address_map &map)
{
map(0x000000, 0x0fffff).rom();
map(0x200000, 0x23ffff).ram(); // work RAM
map(0x600000, 0x7fffff).bankr("bank1"); // banked ROM (used by ROM check)
map(0x800000, 0x9fffff).rom().region("user1", 0);
map(0x300000, 0x300005).rw(FUNC(srmp6_state::srmp6_inputs_r), FUNC(srmp6_state::srmp6_input_select_w)); // inputs
map(0x480000, 0x480fff).ram().w(FUNC(srmp6_state::paletteram_w)).share("palette");
map(0x4d0000, 0x4d0001).r(FUNC(srmp6_state::srmp6_irq_ack_r));
map(0x300000, 0x300005).w(FUNC(srmp6_state::input_select_w)); // inputs
map(0x300000, 0x300001).portr("DSW");
map(0x300002, 0x300005).r(FUNC(srmp6_state::inputs_r)); // inputs
// OBJ RAM: checked [$400000-$47dfff]
map(0x400000, 0x47ffff).ram().share("sprram");
// CHR RAM: checked [$500000-$5fffff]
map(0x500000, 0x5fffff).rw(FUNC(srmp6_state::tileram_r), FUNC(srmp6_state::tileram_w)).share("chrram");
//AM_RANGE(0x5fff00, 0x5fffff) AM_WRITE(dma_w) AM_SHARE("dmaram")
map(0x480000, 0x480fff).ram().w(FUNC(srmp6_state::paletteram_w)).share("palette");
map(0x4c0000, 0x4c006f).rw(FUNC(srmp6_state::video_regs_r), FUNC(srmp6_state::video_regs_w)).share("video_regs"); // ? gfx regs ST-0026 NiLe
map(0x4d0000, 0x4d0001).r(FUNC(srmp6_state::irq_ack_r));
map(0x4e0000, 0x4e00ff).rw("nile", FUNC(nile_device::nile_snd_r), FUNC(nile_device::nile_snd_w));
map(0x4e0100, 0x4e0101).rw("nile", FUNC(nile_device::nile_sndctrl_r), FUNC(nile_device::nile_sndctrl_w));
//AM_RANGE(0x4e0110, 0x4e0111) AM_NOP // ? accessed once ($268dc, written $b.w)
//AM_RANGE(0x5fff00, 0x5fff1f) AM_RAM // ? see routine $5ca8, video_regs related ???
// CHR RAM: checked [$500000-$5fffff]
map(0x500000, 0x5fffff).rw(FUNC(srmp6_state::tileram_r), FUNC(srmp6_state::tileram_w)).share("chrram");
//AM_RANGE(0x5fff00, 0x5fff1f) AM_RAM // ? see routine $5ca8, video_regs related ???
//AM_RANGE(0x5fff00, 0x5fffff) AM_WRITE(dma_w) AM_SHARE("dmaram")
map(0x600000, 0x7fffff).bankr("nile_bank"); // banked ROM (used by ROM check)
map(0x800000, 0x9fffff).rom().region("user1", 0);
//AM_RANGE(0xf00004, 0xf00005) AM_RAM // ?
//AM_RANGE(0xf00006, 0xf00007) AM_RAM // ?
@ -695,12 +685,14 @@ void srmp6_state::srmp6(machine_config &config)
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
screen.set_size(64*8, 64*8);
screen.set_visarea(0*8, 42*8-1, 0*8, 30*8-1);
screen.set_screen_update(FUNC(srmp6_state::screen_update_srmp6));
screen.set_screen_update(FUNC(srmp6_state::screen_update));
PALETTE(config, m_palette).set_format(palette_device::xBGR_555, 0x800);
GFXDECODE(config, m_gfxdecode, m_palette, gfxdecode_device::empty);
BUFFERED_SPRITERAM16(config, m_sprram);
/* sound hardware */
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();