Merge pull request #5025 from cam900/namcona1_args

namcona1.cpp : Updates
This commit is contained in:
R. Belmont 2019-05-10 11:36:00 -04:00 committed by GitHub
commit 0694e91fa2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 812 additions and 813 deletions

View File

@ -188,12 +188,11 @@ void namcona1_state::simulate_mcu()
*/
void namcona1_state::write_version_info()
{
static const uint16_t source[0x8] =
static const u16 source[0x8] =
{ /* "NSA-BIOS ver"... */
0x534e,0x2d41,0x4942,0x534f,0x7620,0x7265,0x2e31,0x3133
};
int i;
for( i=0; i<8; i++ )
for (int i = 0; i < 8; i++)
{
m_workram[0x1000 / 2 + i] = source[i];
}
@ -208,15 +207,16 @@ void namcona1_state::write_version_info()
* The secondary purpose of the custom key chip is to act as a random number
* generator in some games.
*/
READ16_MEMBER(namcona1_state::custom_key_r)
u16 namcona1_state::custom_key_r(offs_t offset)
{
const u16 old_count = m_count;
if (!machine().side_effects_disabled())
{
int old_count;
old_count = m_count;
do
{
m_count = machine().rand();
} while (old_count == m_count);
}
switch (m_gametype)
{
@ -267,14 +267,15 @@ READ16_MEMBER(namcona1_state::custom_key_r)
if (offset == 4) m_keyval = 0;
if (offset == 3)
{
uint16_t res;
res = bitswap<16>(m_keyval, 22,26,31,23,18,20,16,30,24,21,25,19,17,29,28,27);
u16 res = bitswap<16>(m_keyval, 22,26,31,23,18,20,16,30,24,21,25,19,17,29,28,27);
if (!machine().side_effects_disabled())
{
m_keyval >>= 1;
// printf("popcount(%08X) = %d\n", m_keyval & 0x58000c00, population_count_32(m_keyval & 0x58000c00));
if ((!m_keyval) || (population_count_32(m_keyval & 0x58000c00) & 1))
m_keyval ^= 0x80000000;
}
return res;
}
break;
@ -295,16 +296,15 @@ READ16_MEMBER(namcona1_state::custom_key_r)
return machine().rand()&0xffff;
} /* custom_key_r */
WRITE16_MEMBER(namcona1_state::custom_key_w)
void namcona1_state::custom_key_w(u16 data)
{
} /* custom_key_w */
/***************************************************************/
int namcona1_state::transfer_dword( uint32_t dest, uint32_t source )
int namcona1_state::transfer_dword(u32 dest, u32 source)
{
uint16_t data;
address_space &space = m_maincpu->space(AS_PROGRAM);
u16 data;
if (source >= 0x400000 && source < 0xc00000)
{
@ -325,15 +325,15 @@ int namcona1_state::transfer_dword( uint32_t dest, uint32_t source )
}
if (dest >= 0xf00000 && dest < 0xf02000)
{
paletteram_w(space, (dest-0xf00000)/2, data, 0xffff );
paletteram_w((dest - 0xf00000) / 2, data);
}
else if (dest >= 0xf40000 && dest < 0xf80000)
{
gfxram_w(space, (dest-0xf40000)/2, data, 0xffff );
gfxram_w((dest - 0xf40000) / 2, data);
}
else if (dest >= 0xff0000 && dest < 0xffc000)
{
videoram_w(space, (dest-0xff0000)/2, data, 0xffff );
videoram_w((dest - 0xff0000) / 2, data);
}
else if (dest >= 0xfff000 && dest < 0x1000000)
{
@ -342,7 +342,7 @@ int namcona1_state::transfer_dword( uint32_t dest, uint32_t source )
// xday2 writes to 0x1e01200 / 0x1e01400, assume it's just a mirror for paletteram transfer
else if (dest >= 0xf00000 * 2 && dest < 0xf02000 * 2)
{
paletteram_w(space, (dest-0xf00000*2)/2, data, 0xffff );
paletteram_w((dest - 0xf00000 * 2) / 2, data);
}
else
{
@ -364,15 +364,15 @@ void namcona1_state::blit_setup( int format, int *bytes_per_row, int *pitch, int
break;
case 0x0081:
*bytes_per_row = 4*8;
*pitch = 36*8;
*bytes_per_row = 4 << 3;
*pitch = 36 << 3;
break;
default:
// case 0x00f1:
// case 0x00f9:
// case 0x00fd:
*bytes_per_row = (64 - (format>>2))*0x08;
*bytes_per_row = (64 - (format >> 2)) << 3;
*pitch = 0x200;
break;
}
@ -407,8 +407,8 @@ void namcona1_state::blit_setup( int format, int *bytes_per_row, int *pitch, int
break;
case 0x0401: /* F/A */
*bytes_per_row = 4*0x40;
*pitch = 36*0x40;
*bytes_per_row = 4 << 6;
*pitch = 36 << 6;
break;
default:
@ -416,7 +416,7 @@ void namcona1_state::blit_setup( int format, int *bytes_per_row, int *pitch, int
// case 0x0781:
// case 0x07c1:
// case 0x07e1:
*bytes_per_row = (64 - (format>>5))*0x40;
*bytes_per_row = (64 - (format >> 5)) << 6;
*pitch = 0x1000;
break;
}
@ -436,8 +436,8 @@ void namcona1_state::blit()
int gfxbank = m_vreg[0x6];
/* dest and source are provided as dword offsets */
uint32_t src_baseaddr = 2*(0xffffff&((m_vreg[0x7]<<16)|m_vreg[0x8]));
uint32_t dst_baseaddr = 2*(0xffffff&((m_vreg[0x9]<<16)|m_vreg[0xa]));
u32 src_baseaddr = 2 * (0xffffff & ((m_vreg[0x7] << 16) | m_vreg[0x8]));
u32 dst_baseaddr = 2 * (0xffffff & ((m_vreg[0x9] << 16) | m_vreg[0xa]));
int num_bytes = m_vreg[0xb];
@ -500,9 +500,10 @@ void namcona1_state::blit()
}
} /* blit */
WRITE16_MEMBER(namcona1_state::vreg_w)
void namcona1_state::vreg_w(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA( &m_vreg[offset] );
const u16 old = m_vreg[offset];
data = COMBINE_DATA(&m_vreg[offset]);
switch (offset)
{
@ -515,6 +516,24 @@ WRITE16_MEMBER(namcona1_state::vreg_w)
m_mEnableInterrupts = 1;
/* interrupt enable mask; 0 enables INT level */
break;
case 0xb0 / 2:
case 0xb2 / 2:
case 0xb4 / 2:
case 0xb6 / 2:
m_bg_tilemap[offset - (0xb0 / 2)]->set_palette_offset((data & 0xf) << 8);
break;
case 0xba / 2:
m_bg_tilemap[4]->set_palette_offset((data & 0xf) << 8);
break;
case 0xbc / 2:
for (int i = 0; i <= 4; i++)
{
if (BIT(old ^ data, i))
m_bg_tilemap[i]->mark_all_dirty();
}
break;
}
} /* vreg_w */
@ -522,19 +541,19 @@ WRITE16_MEMBER(namcona1_state::vreg_w)
// MCU "mailslot" handler - has 8 16-bit slots mirrored
READ16_MEMBER(namcona1_state::mcu_mailbox_r)
u16 namcona1_state::mcu_mailbox_r(offs_t offset)
{
return m_mcu_mailbox[offset%8];
return m_mcu_mailbox[offset & 7];
}
WRITE16_MEMBER(namcona1_state::mcu_mailbox_w_68k)
void namcona1_state::mcu_mailbox_w_68k(offs_t offset, u16 data, u16 mem_mask)
{
// logerror("mailbox_w_68k: %x @ %x\n", data, offset);
if (offset == 4)
m_mcu->set_input_line(M37710_LINE_IRQ0, HOLD_LINE);
COMBINE_DATA(&m_mcu_mailbox[offset%8]);
COMBINE_DATA(&m_mcu_mailbox[offset & 7]);
/* FIXME: This shouldn't be necessary now that the C70 BIOS is implemented,
but for some reason the MCU never responds to the version string command */
@ -545,9 +564,9 @@ WRITE16_MEMBER(namcona1_state::mcu_mailbox_w_68k)
}
}
WRITE16_MEMBER(namcona1_state::mcu_mailbox_w_mcu)
void namcona1_state::mcu_mailbox_w_mcu(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_mcu_mailbox[offset%8]);
COMBINE_DATA(&m_mcu_mailbox[offset & 7]);
}
void namcona1_state::namcona1_main_map(address_map &map)
@ -572,14 +591,14 @@ void namcona1_state::namcona1_c140_map(address_map &map)
map(0x000000, 0x07ffff).ram().share("workram");
}
READ8_MEMBER(xday2_namcona2_state::printer_r)
u8 xday2_namcona2_state::printer_r()
{
// --xx ---- printer status related, if bit 5 held 1 long enough causes printer error
// ---- --11 battery ok, any other setting causes ng
return 3;
}
WRITE8_MEMBER(xday2_namcona2_state::printer_w)
void xday2_namcona2_state::printer_w(u8 data)
{
// ...
}
@ -600,9 +619,9 @@ void xday2_namcona2_state::xday2_main_map(address_map &map)
/* ----- NA-1 MCU handling ----------------------------------- */
READ16_MEMBER(namcona1_state::na1mcu_shared_r)
u16 namcona1_state::na1mcu_shared_r(offs_t offset)
{
uint16_t data = swapendian_int16(m_workram[offset]);
u16 data = swapendian_int16(m_workram[offset]);
#if 0
if (offset >= 0x70000 / 2)
@ -613,7 +632,7 @@ READ16_MEMBER(namcona1_state::na1mcu_shared_r)
return data;
}
WRITE16_MEMBER(namcona1_state::na1mcu_shared_w)
void namcona1_state::na1mcu_shared_w(offs_t offset, u16 data, u16 mem_mask)
{
mem_mask = swapendian_int16(mem_mask);
data = swapendian_int16(data);
@ -634,12 +653,12 @@ void namcona1_state::namcona1_mcu_map(address_map &map)
// port 4: bit 3 (0x08) enables the 68000 (see the 68k launch code at c604 in swcourt's BIOS)
READ8_MEMBER(namcona1_state::port4_r)
u8 namcona1_state::port4_r()
{
return m_mcu_port4;
}
WRITE8_MEMBER(namcona1_state::port4_w)
void namcona1_state::port4_w(u8 data)
{
if ((data & 0x08) && !(m_mcu_port4 & 0x08))
{
@ -653,12 +672,12 @@ WRITE8_MEMBER(namcona1_state::port4_w)
}
// port 5: not sure yet, but MCU code requires this interaction at least
READ8_MEMBER(namcona1_state::port5_r)
u8 namcona1_state::port5_r()
{
return m_mcu_port5;
}
WRITE8_MEMBER(namcona1_state::port5_w)
void namcona1_state::port5_w(u8 data)
{
m_mcu_port5 = data;
@ -667,17 +686,17 @@ WRITE8_MEMBER(namcona1_state::port5_w)
m_mcu_port5 |= ((m_mcu_port5 & 0x2)>>1);
}
READ8_MEMBER(namcona1_state::port6_r)
u8 namcona1_state::port6_r()
{
return 0;
}
WRITE8_MEMBER(namcona1_state::port6_w)
void namcona1_state::port6_w(u8 data)
{
m_mcu_port6 = data;
}
READ8_MEMBER(namcona1_state::port7_r)
u8 namcona1_state::port7_r()
{
if ((m_mcu_port6 & 0x80) == 0)
return m_muxed_inputs[m_mcu_port6 >> 5]->read();
@ -685,17 +704,17 @@ READ8_MEMBER(namcona1_state::port7_r)
return 0xff;
}
WRITE8_MEMBER(namcona1_state::port7_w)
void namcona1_state::port7_w(u8 data)
{
}
// port 8: bit 5 (0x20) toggles, watchdog?
READ8_MEMBER(namcona1_state::port8_r)
u8 namcona1_state::port8_r()
{
return m_mcu_port8;
}
WRITE8_MEMBER(namcona1_state::port8_w)
void namcona1_state::port8_w(u8 data)
{
m_mcu_port8 = data;
}
@ -736,7 +755,7 @@ void namcona1_state::machine_reset()
// bit 3 => port 6
// bit 7 => port 7
template <int Bit>
uint16_t namcona1_state::portana_r()
u16 namcona1_state::portana_r()
{
return BIT(m_io_p3->read(), Bit) ? 0xffff : 0x0000;
}
@ -864,7 +883,7 @@ static const gfx_layout cg_layout_8bpp =
8,8,
RGN_FRAC(1,1),
8, /* 8BPP */
{ 0,1,2,3,4,5,6,7 },
{ STEP8(0, 1) },
{ STEP8(0, 8) },
{ STEP8(0, 8*8) },
8*8*8
@ -875,7 +894,7 @@ static const gfx_layout cg_layout_4bpp =
8,8,
RGN_FRAC(1,1),
4, /* 4BPP */
{ 4,5,6,7 },
{ STEP4(4, 1) },
{ STEP8(0, 8) },
{ STEP8(0, 8*8) },
8*8*8
@ -906,7 +925,7 @@ GFXDECODE_END
void namcona1_state::scanline_interrupt(int scanline)
{
int enabled = m_mEnableInterrupts ? ~m_vreg[0x1a/2] : 0;
const u16 enabled = m_mEnableInterrupts ? ~m_vreg[0x1a / 2] : 0;
// adc (timing guessed, when does this trigger?)
if (scanline == 0)
@ -922,7 +941,7 @@ void namcona1_state::scanline_interrupt(int scanline)
}
// posirq, used with dolphin in Emeraldia's "how to play" attract mode
int posirq_scanline = m_vreg[0x8a/2] & 0xff;
const u16 posirq_scanline = m_vreg[0x8a / 2] & 0xff;
if (scanline == posirq_scanline && enabled & 4)
{
if (posirq_scanline)

View File

@ -60,32 +60,34 @@ public:
void namcona1_mcu_map(address_map &map);
protected:
DECLARE_READ16_MEMBER(custom_key_r);
DECLARE_WRITE16_MEMBER(custom_key_w);
DECLARE_WRITE16_MEMBER(vreg_w);
DECLARE_READ16_MEMBER(mcu_mailbox_r);
DECLARE_WRITE16_MEMBER(mcu_mailbox_w_68k);
DECLARE_WRITE16_MEMBER(mcu_mailbox_w_mcu);
DECLARE_READ16_MEMBER(na1mcu_shared_r);
DECLARE_WRITE16_MEMBER(na1mcu_shared_w);
DECLARE_READ8_MEMBER(port4_r);
DECLARE_WRITE8_MEMBER(port4_w);
DECLARE_READ8_MEMBER(port5_r);
DECLARE_WRITE8_MEMBER(port5_w);
DECLARE_READ8_MEMBER(port6_r);
DECLARE_WRITE8_MEMBER(port6_w);
DECLARE_READ8_MEMBER(port7_r);
DECLARE_WRITE8_MEMBER(port7_w);
DECLARE_READ8_MEMBER(port8_r);
DECLARE_WRITE8_MEMBER(port8_w);
template <int Bit> uint16_t portana_r();
DECLARE_WRITE16_MEMBER(videoram_w);
DECLARE_WRITE16_MEMBER(paletteram_w);
DECLARE_READ16_MEMBER(gfxram_r);
DECLARE_WRITE16_MEMBER(gfxram_w);
u16 custom_key_r(offs_t offset);
void custom_key_w(u16 data);
void vreg_w(offs_t offset, u16 data, u16 mem_mask = ~0);
u16 mcu_mailbox_r(offs_t offset);
void mcu_mailbox_w_68k(offs_t offset, u16 data, u16 mem_mask = ~0);
void mcu_mailbox_w_mcu(offs_t offset, u16 data, u16 mem_mask = ~0);
u16 na1mcu_shared_r(offs_t offset);
void na1mcu_shared_w(offs_t offset, u16 data, u16 mem_mask = ~0);
u8 port4_r();
void port4_w(u8 data);
u8 port5_r();
void port5_w(u8 data);
u8 port6_r();
void port6_w(u8 data);
u8 port7_r();
void port7_w(u8 data);
u8 port8_r();
void port8_w(u8 data);
template <int Bit> u16 portana_r();
void videoram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void paletteram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
u16 gfxram_r(offs_t offset);
void gfxram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
virtual void device_post_load() override;
u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void scanline_interrupt(int scanline);
@ -129,53 +131,51 @@ protected:
required_ioport_array<4> m_muxed_inputs;
required_ioport m_io_p3;
required_shared_ptr<uint16_t> m_workram;
required_shared_ptr<uint16_t> m_vreg;
required_shared_ptr<uint16_t> m_paletteram;
required_shared_ptr<uint16_t> m_cgram;
required_shared_ptr<uint16_t> m_videoram;
required_shared_ptr<uint16_t> m_scroll;
required_shared_ptr<uint16_t> m_spriteram;
required_shared_ptr<u16> m_workram;
required_shared_ptr<u16> m_vreg;
required_shared_ptr<u16> m_paletteram;
required_shared_ptr<u16> m_cgram;
required_shared_ptr<u16> m_videoram;
required_shared_ptr<u16> m_scroll;
required_shared_ptr<u16> m_spriteram;
required_region_ptr<uint16_t> m_prgrom;
required_region_ptr<uint16_t> m_maskrom;
required_region_ptr<u16> m_prgrom;
required_region_ptr<u16> m_maskrom;
emu_timer * m_scan_timer;
// this has to be uint8_t to be in the right byte order for the tilemap system
std::vector<uint8_t> m_shaperam;
// this has to be u8 to be in the right byte order for the tilemap system
std::vector<u8> m_shaperam;
int m_mEnableInterrupts;
uint16_t m_count;
uint32_t m_keyval;
uint16_t m_mcu_mailbox[8];
uint8_t m_mcu_port4;
uint8_t m_mcu_port5;
uint8_t m_mcu_port6;
uint8_t m_mcu_port8;
u16 m_count;
u32 m_keyval;
u16 m_mcu_mailbox[8];
u8 m_mcu_port4;
u8 m_mcu_port5;
u8 m_mcu_port6;
u8 m_mcu_port8;
tilemap_t *m_bg_tilemap[4+1];
int m_palette_is_dirty;
void simulate_mcu();
void write_version_info();
int transfer_dword(uint32_t dest, uint32_t source);
int transfer_dword(u32 dest, u32 source);
void blit();
void UpdatePalette(int offset);
void pdraw_tile( screen_device &screen, bitmap_ind16 &dest_bmp, const rectangle &clip, uint32_t code, int color,
int sx, int sy, int flipx, int flipy, int priority, int bShadow, int bOpaque, int gfx_region );
void pdraw_tile(screen_device &screen, bitmap_ind16 &dest_bmp, const rectangle &clip, u32 code, u32 color,
int sx, int sy, bool flipx, bool flipy, u8 priority, bool bShadow, bool bOpaque, u8 gfx_region);
void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void draw_background(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int which, int primask);
void tilemap_get_info(tile_data &tileinfo, int tile_index, const uint16_t *tilemap_videoram, bool use_4bpp_gfx);
void tilemap_get_info(tile_data &tileinfo, int tile_index, const u16 *tilemap_videoram, bool use_4bpp_gfx);
void blit_setup(int format, int *bytes_per_row, int *pitch, int mode);
void draw_pixel_line( const rectangle &cliprect, uint16_t *pDest, uint8_t *pPri, uint16_t *pSource, const pen_t *paldata );
void draw_pixel_line(const rectangle &cliprect, u16 *pDest, u8 *pPri, u16 *pSource, const pen_t *paldata);
bool screen_enabled(const rectangle &cliprect);
TILE_GET_INFO_MEMBER(tilemap_get_info0);
TILE_GET_INFO_MEMBER(tilemap_get_info1);
TILE_GET_INFO_MEMBER(tilemap_get_info2);
TILE_GET_INFO_MEMBER(tilemap_get_info3);
TILE_GET_INFO_MEMBER(roz_get_info);
void postload();
};
class namcona2_state : public namcona1_state
@ -211,8 +211,8 @@ public:
private:
required_device <msm6242_device> m_rtc;
DECLARE_READ8_MEMBER(printer_r);
DECLARE_WRITE8_MEMBER(printer_w);
u8 printer_r();
void printer_w(u8 data);
void xday2_main_map(address_map &map);
};

View File

@ -24,13 +24,13 @@ TODO:
void namcona1_state::tilemap_get_info(
tile_data &tileinfo,
int tile_index,
const uint16_t *tilemap_videoram,
const u16 *tilemap_videoram,
bool use_4bpp_gfx)
{
int data = tilemap_videoram[tile_index];
int tile = data&0xfff;
int gfx = use_4bpp_gfx ? 1 : 0;
int color = use_4bpp_gfx ? (data & 0x7000)>>12 : 0;
const u16 data = tilemap_videoram[tile_index];
const u32 tile = data & 0xfff;
const u8 gfx = use_4bpp_gfx ? 1 : 0;
const u32 color = use_4bpp_gfx ? (data & 0x7000) >> 12 : 0;
if (data & 0x8000)
{
@ -39,40 +39,40 @@ void namcona1_state::tilemap_get_info(
else
{
SET_TILE_INFO_MEMBER(gfx, tile, color, 0);
tileinfo.mask_data = &m_shaperam[tile*8];
tileinfo.mask_data = &m_shaperam[tile << 3];
}
} /* tilemap_get_info */
TILE_GET_INFO_MEMBER(namcona1_state::tilemap_get_info0)
{
tilemap_get_info(tileinfo,tile_index,0*0x1000+m_videoram,m_vreg[0xbc/2]&1);
tilemap_get_info(tileinfo, tile_index, 0 * 0x1000 + m_videoram, m_vreg[0xbc / 2] & 0x1);
}
TILE_GET_INFO_MEMBER(namcona1_state::tilemap_get_info1)
{
tilemap_get_info(tileinfo,tile_index,1*0x1000+m_videoram,m_vreg[0xbc/2]&2);
tilemap_get_info(tileinfo, tile_index, 1 * 0x1000 + m_videoram, m_vreg[0xbc / 2] & 0x2);
}
TILE_GET_INFO_MEMBER(namcona1_state::tilemap_get_info2)
{
tilemap_get_info(tileinfo,tile_index,2*0x1000+m_videoram,m_vreg[0xbc/2]&4);
tilemap_get_info(tileinfo, tile_index, 2 * 0x1000 + m_videoram, m_vreg[0xbc / 2] & 0x4);
}
TILE_GET_INFO_MEMBER(namcona1_state::tilemap_get_info3)
{
tilemap_get_info(tileinfo,tile_index,3*0x1000+m_videoram,m_vreg[0xbc/2]&8);
tilemap_get_info(tileinfo, tile_index, 3 * 0x1000 + m_videoram, m_vreg[0xbc / 2] & 0x8);
}
TILE_GET_INFO_MEMBER(namcona1_state::roz_get_info)
{
/* each logical tile is constructed from 4*4 normal tiles */
int use_4bpp_gfx = m_vreg[0xbc/2]&16; /* ? */
int c = tile_index%0x40;
int r = tile_index/0x40;
int data = m_videoram[0x8000/2+(r/4)*0x40+c/4]&0xfbf; /* mask out bit 0x40 - patch for Emeraldia Japan */
int tile = (data+(c%4)+(r%4)*0x40)&0xfff;
int gfx = use_4bpp_gfx ? 1 : 0;
int color = use_4bpp_gfx ? (data & 0x7000)>>12 : 0;
const bool use_4bpp_gfx = m_vreg[0xbc / 2] & 0x10; /* ? */
const u16 c = tile_index & 0x3f;
const u16 r = tile_index >> 6;
const u16 data = m_videoram[0x8000 / 2 + ((r >> 2) << 6) + (c >> 2)];
const u32 tile = ((data & 0xfbf) + (c & 3) + ((r & 3) << 6)) & 0xfff; /* mask out bit 0x40 - patch for Emeraldia Japan */
const u8 gfx = use_4bpp_gfx ? 1 : 0;
const u32 color = use_4bpp_gfx ? (data & 0x7000) >> 12 : 0;
if (data & 0x8000)
{
@ -81,22 +81,31 @@ TILE_GET_INFO_MEMBER(namcona1_state::roz_get_info)
else
{
SET_TILE_INFO_MEMBER(gfx, tile, color, 0);
tileinfo.mask_data = &m_shaperam[tile*8];
tileinfo.mask_data = &m_shaperam[tile << 3];
}
} /* roz_get_info */
/*************************************************************************/
WRITE16_MEMBER(namcona1_state::videoram_w)
void namcona1_state::videoram_w(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_videoram[offset]);
if (offset < 0x8000 / 2)
{
m_bg_tilemap[offset/0x1000]->mark_tile_dirty(offset&0xfff);
m_bg_tilemap[offset >> 12]->mark_tile_dirty(offset & 0xfff);
}
else if( offset<0xa000/2 )
else if (offset < 0x8800 / 2)
{
m_bg_tilemap[4]->mark_all_dirty();
if (offset & ~0x30)
{
for (int i = 0; i < 4; i++)
{
m_bg_tilemap[4]->mark_tile_dirty(((offset & 0x3cf) << 2) + i);
m_bg_tilemap[4]->mark_tile_dirty(((offset & 0x3cf) << 2) + 0x40 + i);
m_bg_tilemap[4]->mark_tile_dirty(((offset & 0x3cf) << 2) + 0x80 + i);
m_bg_tilemap[4]->mark_tile_dirty(((offset & 0x3cf) << 2) + 0xc0 + i);
}
}
}
} /* videoram_w */
@ -104,7 +113,7 @@ WRITE16_MEMBER(namcona1_state::videoram_w)
void namcona1_state::UpdatePalette(int offset)
{
uint16_t data = m_paletteram[offset]; /* -RRRRRGG GGGBBBBB */
const u16 data = m_paletteram[offset]; /* -RRRRRGG GGGBBBBB */
/**
* sprites can be configured to use an alternate interpretation of palette ram
* (used in-game in Emeraldia)
@ -119,7 +128,7 @@ void namcona1_state::UpdatePalette( int offset )
m_palette->set_pen_color(offset, pal5bit(data >> 10), pal5bit(data >> 5), pal5bit(data >> 0));
}
WRITE16_MEMBER(namcona1_state::paletteram_w)
void namcona1_state::paletteram_w(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_paletteram[offset]);
if (m_vreg[0x8e / 2])
@ -133,9 +142,9 @@ WRITE16_MEMBER(namcona1_state::paletteram_w)
}
READ16_MEMBER(namcona1_state::gfxram_r)
u16 namcona1_state::gfxram_r(offs_t offset)
{
uint16_t type = m_vreg[0x0c/2];
const u16 type = m_vreg[0x0c / 2];
if (type == 0x03)
{
if (offset < 0x4000)
@ -151,10 +160,9 @@ READ16_MEMBER(namcona1_state::gfxram_r)
return 0x0000;
} /* gfxram_r */
WRITE16_MEMBER(namcona1_state::gfxram_w)
void namcona1_state::gfxram_w(offs_t offset, u16 data, u16 mem_mask)
{
uint16_t type = m_vreg[0x0c/2];
uint16_t old_word;
const u16 type = m_vreg[0x0c / 2];
if (type == 0x03)
{
@ -165,17 +173,17 @@ WRITE16_MEMBER(namcona1_state::gfxram_w)
m_shaperam[offset] = data >> 8;
if (ACCESSING_BITS_0_7)
m_shaperam[offset + 1] = data;
m_gfxdecode->gfx(2)->mark_dirty(offset/8);
m_gfxdecode->gfx(2)->mark_dirty(offset >> 3);
}
}
else if (type == 0x02)
{
old_word = m_cgram[offset];
const u16 old_word = m_cgram[offset];
COMBINE_DATA(&m_cgram[offset]);
if (m_cgram[offset] != old_word)
{
m_gfxdecode->gfx(0)->mark_dirty(offset/0x20);
m_gfxdecode->gfx(1)->mark_dirty(offset/0x20);
m_gfxdecode->gfx(0)->mark_dirty(offset >> 5);
m_gfxdecode->gfx(1)->mark_dirty(offset >> 5);
}
}
} /* gfxram_w */
@ -197,11 +205,9 @@ void namcona1_state::video_start()
save_item(NAME(m_shaperam));
save_item(NAME(m_palette_is_dirty));
machine().save().register_postload(save_prepost_delegate(FUNC(namcona1_state::postload), this));
} /* video_start */
void namcona1_state::postload()
void namcona1_state::device_post_load()
{
for (int i = 0; i < 3; i++)
m_gfxdecode->gfx(i)->mark_all_dirty();
@ -214,55 +220,51 @@ void namcona1_state::pdraw_tile(
screen_device &screen,
bitmap_ind16 &dest_bmp,
const rectangle &clip,
uint32_t code,
int color,
u32 code,
u32 color,
int sx, int sy,
int flipx, int flipy,
int priority,
int bShadow,
int bOpaque,
int gfx_region )
bool flipx, bool flipy,
u8 priority,
bool bShadow,
bool bOpaque,
u8 gfx_region)
{
gfx_element *gfx = m_gfxdecode->gfx(gfx_region);
gfx_element *mask = m_gfxdecode->gfx(2);
int pal_base = gfx->colorbase() + gfx->granularity() * (color % gfx->colors());
const uint8_t *source_base = gfx->get_data((code % gfx->elements()));
const uint8_t *mask_base = mask->get_data((code % mask->elements()));
const u16 pal_base = gfx->colorbase() + gfx->granularity() * (color % gfx->colors());
const u8 *source_base = gfx->get_data((code % gfx->elements()));
const u8 *mask_base = mask->get_data((code % mask->elements()));
int sprite_screen_height = ((1<<16)*gfx->height()+0x8000)>>16;
int sprite_screen_width = ((1<<16)*gfx->width()+0x8000)>>16;
if (sprite_screen_width && sprite_screen_height)
{
/* compute sprite increment per screen pixel */
int dx = (gfx->width()<<16)/sprite_screen_width;
int dy = (gfx->height()<<16)/sprite_screen_height;
int dx, dy;
int ex = sx+sprite_screen_width;
int ey = sy+sprite_screen_height;
int ex = sx + gfx->width();
int ey = sy + gfx->height();
int x_index_base;
int y_index;
if (flipx)
{
x_index_base = (sprite_screen_width-1)*dx;
dx = -dx;
x_index_base = gfx->width() - 1;
dx = -1;
}
else
{
x_index_base = 0;
dx = 1;
}
if (flipy)
{
y_index = (sprite_screen_height-1)*dy;
dy = -dy;
y_index = gfx->height() - 1;
dy = -1;
}
else
{
y_index = 0;
dy = 1;
}
if (sx < clip.min_x)
@ -291,36 +293,33 @@ void namcona1_state::pdraw_tile(
if (ex > sx)
{ /* skip if inner loop doesn't draw anything */
int y;
for( y=sy; y<ey; y++ )
for (int y = sy; y < ey; y++)
{
const uint8_t *source = source_base + (y_index>>16) * gfx->rowbytes();
const uint8_t *mask_addr = mask_base + (y_index>>16) * mask->rowbytes();
uint16_t *dest = &dest_bmp.pix16(y);
uint8_t *pri = &screen.priority().pix8(y);
const u8 *source = source_base + y_index * gfx->rowbytes();
const u8 *mask_addr = mask_base + y_index * mask->rowbytes();
u16 *dest = &dest_bmp.pix16(y);
u8 *pri = &screen.priority().pix8(y);
int x, x_index = x_index_base;
for( x=sx; x<ex; x++ )
int x_index = x_index_base;
for (int x = sx; x < ex; x++)
{
if (bOpaque)
{
if (pri[x] <= priority)
{
int c = source[x_index>>16];
const u8 c = source[x_index];
dest[x] = pal_base + c;
}
pri[x] = 0xff;
}
else
{
/* sprite pixel is opaque */
if( mask_addr[x_index>>16] != 0 )
if (mask_addr[x_index] != 0)
{
if (pri[x] <= priority)
{
int c = source[x_index>>16];
const u8 c = source[x_index];
/* render a shadow only if the sprites color is $F (8bpp) or $FF (4bpp) */
if (bShadow)
@ -344,44 +343,33 @@ void namcona1_state::pdraw_tile(
pri[x] = 0xff;
}
}
x_index += dx;
}
y_index += dy;
}
}
}
} /* pdraw_tile */
void namcona1_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
int which;
const uint16_t *source = m_spriteram;
uint16_t sprite_control;
uint16_t ypos,tile,color,xpos;
int priority;
int width,height;
int flipy,flipx;
int row,col;
int sx,sy;
const u16 *source = m_spriteram;
sprite_control = m_vreg[0x22/2];
const u16 sprite_control = m_vreg[0x22 / 2];
if (sprite_control & 1) source += 0x400; /* alternate spriteram bank */
for( which=0; which<0x100; which++ )
for (int which = 0; which < 0x100; which++)
{ /* max 256 sprites */
int bpp4,palbase;
ypos = source[0]; /* FHHH---Y YYYYYYYY flipy, height, ypos */
tile = source[1]; /* O???TTTT TTTTTTTT opaque tile */
color = source[2]; /* FSWWOOOO CCCCBPPP flipx, shadow, width, color offset for 4bpp, color, 4bbp - 8bpp mode, pri*/
xpos = source[3]; /* -------X XXXXXXXX xpos */
const u16 ypos = source[0]; /* FHHH---Y YYYYYYYY flipy, height, ypos */
const u16 tile = source[1]; /* O???TTTT TTTTTTTT opaque tile */
const u16 color = source[2]; /* FSWWOOOO CCCCBPPP flipx, shadow, width, color offset for 4bpp, color, 4bbp - 8bpp mode, pri*/
const u16 xpos = source[3]; /* -------X XXXXXXXX xpos */
priority = color&0x7;
width = ((color>>12)&0x3)+1;
height = ((ypos>>12)&0x7)+1;
flipy = ypos&0x8000;
flipx = color&0x8000;
const u8 priority = color & 0x7;
const u16 width = ((color >> 12) & 0x3) + 1;
const u16 height = ((ypos >> 12) & 0x7) + 1;
bool flipy = ypos & 0x8000;
bool flipx = color & 0x8000;
if (color & 8)
{
@ -394,36 +382,36 @@ void namcona1_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, c
bpp4 = 0;
}
for( row=0; row<height; row++ )
for (int row = 0; row < height; row++)
{
sy = (ypos&0x1ff)-30+32;
int sy = (ypos & 0x1ff) - 30 + 32;
if (flipy)
{
sy += (height-1-row)*8;
sy += (height - 1 - row) << 3;
}
else
{
sy += row*8;
sy += row << 3;
}
sy = ((sy + 8) & 0x1ff) - 8;
for( col=0; col<width; col++ )
for (int col = 0; col < width; col++)
{
sx = (xpos&0x1ff)-10;
int sx = (xpos & 0x1ff) - 10;
if (flipx)
{
sx += (width-1-col)*8;
sx += (width - 1 - col) << 3;
}
else
{
sx+=col*8;
sx += col << 3;
}
sx = ((sx + 16) & 0x1ff) - 8;
pdraw_tile(screen,
bitmap,
cliprect,
(tile & 0xfff) + row*64+col,
(tile & 0xfff) + (row << 6) + col,
palbase,
sx,sy,flipx,flipy,
priority,
@ -437,12 +425,11 @@ void namcona1_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, c
}
} /* draw_sprites */
void namcona1_state::draw_pixel_line( const rectangle &cliprect, uint16_t *pDest, uint8_t *pPri, uint16_t *pSource, const pen_t *paldata )
void namcona1_state::draw_pixel_line(const rectangle &cliprect, u16 *pDest, u8 *pPri, u16 *pSource, const pen_t *paldata)
{
int x;
for( x=0; x<38*8; x+=2 )
for (int x = 0; x < 38 << 3; x += 2)
{
uint16_t data = *pSource++;
u16 data = *pSource++;
pPri[x + 0] = 0xff;
pPri[x + 1] = 0xff;
if (x >= cliprect.min_x && x <= cliprect.max_x)
@ -457,16 +444,16 @@ void namcona1_state::draw_background(screen_device &screen, bitmap_ind16 &bitmap
if (which == 4)
{
/* draw the roz tilemap all at once */
int incxx = ((int16_t)m_vreg[0xc0/2])<<8;
int incxy = ((int16_t)m_vreg[0xc2/2])<<8;
int incyx = ((int16_t)m_vreg[0xc4/2])<<8;
int incyy = ((int16_t)m_vreg[0xc6/2])<<8;
int16_t xoffset = m_vreg[0xc8/2];
int16_t yoffset = m_vreg[0xca/2];
int incxx = ((s16)m_vreg[0xc0 / 2])<<8;
int incxy = ((s16)m_vreg[0xc2 / 2])<<8;
int incyx = ((s16)m_vreg[0xc4 / 2])<<8;
int incyy = ((s16)m_vreg[0xc6 / 2])<<8;
s16 xoffset = m_vreg[0xc8 / 2];
s16 yoffset = m_vreg[0xca / 2];
int dx = 46; /* horizontal adjust */
int dy = -8; /* vertical adjust */
uint32_t startx = (xoffset<<12)+incxx*dx+incyx*dy;
uint32_t starty = (yoffset<<12)+incxy*dx+incyy*dy;
u32 startx = (xoffset<<12) + incxx * dx + incyx * dy;
u32 starty = (yoffset<<12) + incxy * dx + incyy * dy;
m_bg_tilemap[4]->draw_roz(screen, bitmap, cliprect,
startx, starty, incxx, incxy, incyx, incyy, 0, 0, primask, 0);
}
@ -479,7 +466,7 @@ void namcona1_state::draw_background(screen_device &screen, bitmap_ind16 &bitmap
* tmap2 ffe800 ffea00
* tmap3 ffec00 ffee00
*/
const uint16_t *scroll = &m_scroll[which * 0x400/2];
const u16 *scroll = &m_scroll[which * 0x400 / 2];
rectangle clip = cliprect;
int xadjust = 0x3a - which*2;
int scrollx = xadjust;
@ -553,10 +540,8 @@ bool namcona1_state::screen_enabled(const rectangle &cliprect)
return true;
}
uint32_t namcona1_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
u32 namcona1_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
int which;
int priority;
// CRTC visible area parameters
// (used mostly by Numan Athletics for global screen window effects, cfr. start of events/title screen to demo mode transitions)
rectangle display_rect;
@ -571,7 +556,7 @@ uint32_t namcona1_state::screen_update(screen_device &screen, bitmap_ind16 &bitm
// guess for X-Day 2 (flames in attract), seems wrong for Emeraldia but unsure
// bitmap.fill(0xff, cliprect); /* background color? */
bitmap.fill((m_vreg[0xba/2] & 0xf) * 256, cliprect );
bitmap.fill((m_vreg[0xba / 2] & 0xf) << 8, cliprect);
if (m_vreg[0x8e / 2] && screen_enabled(display_rect) == true)
{
@ -579,21 +564,16 @@ uint32_t namcona1_state::screen_update(screen_device &screen, bitmap_ind16 &bitm
if (m_palette_is_dirty)
{
/* palette updates are delayed when graphics are disabled */
for( which=0; which<0x1000; which++ )
for (int which = 0; which < 0x1000; which++)
{
UpdatePalette(which);
}
m_palette_is_dirty = 0;
}
for( which=0; which < 4; which++ )
m_bg_tilemap[which]->set_palette_offset((m_vreg[0xb0/2 + which] & 0xf) * 256);
m_bg_tilemap[4]->set_palette_offset((m_vreg[0xba/2] & 0xf) * 256);
for( priority = 0; priority<8; priority++ )
for (int priority = 0; priority < 8; priority++)
{
for( which=4; which>=0; which-- )
for (int which = 4; which >= 0; which--)
{
int pri;
if (which == 4)