m72.cpp : Updates (nw) (#5283)

* m72.cpp : Updates (nw)
Use buffered_spriteram16_device for buffered spriteram, Reduce duplicates, Runtime tag lookups, Unnecessary lines, Simplify handlers, Use seperated address map related to config, Use shorter / correct type values, Correct PCM sample rates, Add notes

* m72.cpp : Rounding fixes
This commit is contained in:
cam900 2019-06-25 00:05:23 +09:00 committed by R. Belmont
parent ceb558070e
commit fc28d074da
3 changed files with 319 additions and 377 deletions

View File

@ -305,9 +305,9 @@ The protection device does
TIMER_CALLBACK_MEMBER(m72_state::delayed_ram16_w)
{
uint16_t val = param & 0xffff;
uint16_t offset = (param >> 16) & 0x07ff;
uint16_t mem_mask = (BIT(param, 28) ? 0xff00 : 0x0000) | (BIT(param, 27) ? 0x00ff : 0x0000);
const u16 val = param & 0xffff;
const u16 offset = (param >> 16) & 0x07ff;
const u16 mem_mask = (BIT(param, 28) ? 0xff00 : 0x0000) | (BIT(param, 27) ? 0x00ff : 0x0000);
logerror("MB8421/MB8431 left_w(0x%03x, 0x%04x, 0x%04x)\n", offset, val, mem_mask);
m_dpram->left_w(offset, val, mem_mask);
@ -315,8 +315,8 @@ TIMER_CALLBACK_MEMBER(m72_state::delayed_ram16_w)
TIMER_CALLBACK_MEMBER(m72_state::delayed_ram8_w)
{
uint8_t val = param & 0xff;
uint16_t offset = (param >> 9) & 0x07ff;
const u8 val = param & 0xff;
const u16 offset = (param >> 9) & 0x07ff;
if (BIT(param, 8))
m_dpram->right_w(offset, val << 8, 0xff00);
@ -325,29 +325,30 @@ TIMER_CALLBACK_MEMBER(m72_state::delayed_ram8_w)
}
WRITE16_MEMBER(m72_state::main_mcu_w)
void m72_state::main_mcu_w(offs_t offset, u16 data, u16 mem_mask)
{
machine().scheduler().synchronize(timer_expired_delegate(FUNC(m72_state::delayed_ram16_w), this), offset << 16 | data | (mem_mask & 0x0180) << 20);
}
WRITE8_MEMBER(m72_state::mcu_data_w)
void m72_state::mcu_data_w(offs_t offset, u8 data)
{
machine().scheduler().synchronize(timer_expired_delegate(FUNC(m72_state::delayed_ram8_w), this), offset << 8 | uint32_t(data));
machine().scheduler().synchronize(timer_expired_delegate(FUNC(m72_state::delayed_ram8_w), this), offset << 8 | u32(data));
}
READ8_MEMBER(m72_state::mcu_data_r)
u8 m72_state::mcu_data_r(offs_t offset)
{
return (m_dpram->right_r(offset >> 1) >> (BIT(offset, 0) ? 8 : 0)) & 0xff;
}
READ8_MEMBER(m72_state::mcu_sample_r)
u8 m72_state::mcu_sample_r()
{
uint8_t sample;
sample = memregion("samples")->base()[m_mcu_sample_addr++];
const u8 sample = m_samples_region[m_mcu_sample_addr];
if (!machine().side_effects_disabled())
m_mcu_sample_addr++;
return sample;
}
WRITE8_MEMBER(m72_state::mcu_port1_w)
void m72_state::mcu_port1_w(u8 data)
{
m_mcu_sample_latch = data;
@ -355,19 +356,19 @@ WRITE8_MEMBER(m72_state::mcu_port1_w)
m_soundcpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
}
WRITE8_MEMBER(m72_state::mcu_low_w)
void m72_state::mcu_low_w(u8 data)
{
m_mcu_sample_addr = (m_mcu_sample_addr & 0xffe000) | (data<<5);
logerror("low: %02x %02x %08x\n", offset, data, m_mcu_sample_addr);
logerror("low: %02x %08x\n", data, m_mcu_sample_addr);
}
WRITE8_MEMBER(m72_state::mcu_high_w)
void m72_state::mcu_high_w(u8 data)
{
m_mcu_sample_addr = (m_mcu_sample_addr & 0x1fff) | (data<<(8+5));
logerror("high: %02x %02x %08x\n", offset, data, m_mcu_sample_addr);
logerror("high: %02x %08x\n", data, m_mcu_sample_addr);
}
READ8_MEMBER(m72_state::snd_cpu_sample_r)
u8 m72_state::snd_cpu_sample_r()
{
return m_mcu_sample_latch;
}
@ -377,11 +378,6 @@ void m72_state::init_m72_8751()
save_item(NAME(m_mcu_sample_latch));
save_item(NAME(m_mcu_sample_addr));
/* sound cpu */
address_space &sndio = m_soundcpu->space(AS_IO);
sndio.install_write_handler(0x82, 0x82, write8_delegate(FUNC(dac_byte_interface::data_w),(dac_byte_interface *)m_dac));
sndio.install_read_handler (0x84, 0x84, read8_delegate(FUNC(m72_state::snd_cpu_sample_r),this));
/* lohtb2 */
#if 0
/* running the mcu at twice the speed, the following
@ -390,7 +386,7 @@ void m72_state::init_m72_8751()
* prefetching on the V30.
*/
{
uint8_t *rom=memregion("mcu")->base();
u8 *rom=memregion("mcu")->base();
rom[0x12d+5] += 1; printf(" 5: %d\n", rom[0x12d+5]);
rom[0x12d+8] += 5; printf(" 8: %d\n", rom[0x12d+8]);
@ -430,17 +426,16 @@ the NMI handler in the other games.
#if 0
int m72_state::find_sample(int num)
{
uint8_t *rom = memregion("samples")->base();
int len = memregion("samples")->bytes();
int len = m_samples_region.length();
int addr = 0;
while (num--)
{
/* find end of sample */
while (addr < len && rom[addr]) addr++;
while (addr < len && m_samples_region[addr]) addr++;
/* skip 0 filler between samples */
while (addr < len && !rom[addr]) addr++;
while (addr < len && !m_samples_region[addr]) addr++;
}
return addr;
@ -552,7 +547,7 @@ running, but they have not been derived from the real 8751 code.
#define CRC_LEN 18
/* Battle Chopper / Mr. Heli */
static const uint8_t bchopper_code[CODE_LEN] =
static const u8 bchopper_code[CODE_LEN] =
{
0x68,0x00,0xa0, // push 0a000h
0x1f, // pop ds
@ -572,11 +567,11 @@ static const uint8_t bchopper_code[CODE_LEN] =
0x1f, // pop ds
0xea,0x68,0x01,0x40,0x00 // jmp 0040:$0168
};
static const uint8_t bchopper_crc[CRC_LEN] = { 0x1a,0x12,0x5c,0x08, 0x84,0xb6,0x73,0xd1,
static const u8 bchopper_crc[CRC_LEN] = { 0x1a,0x12,0x5c,0x08, 0x84,0xb6,0x73,0xd1,
0x54,0x91,0x94,0xeb, 0x00,0x00 };
/* Ninja Spirit */
static const uint8_t nspirit_code[CODE_LEN] =
static const u8 nspirit_code[CODE_LEN] =
{
0x68,0x00,0xa0, // push 0a000h
0x1f, // pop ds
@ -595,10 +590,10 @@ static const uint8_t nspirit_code[CODE_LEN] =
0x1f, // pop ds
0xea,0x00,0x00,0x40,0x00 // jmp 0040:$0000
};
static const uint8_t nspirit_crc[CRC_LEN] = { 0xfe,0x94,0x6e,0x4e, 0xc8,0x33,0xa7,0x2d,
static const u8 nspirit_crc[CRC_LEN] = { 0xfe,0x94,0x6e,0x4e, 0xc8,0x33,0xa7,0x2d,
0xf2,0xa3,0xf9,0xe1, 0xa9,0x6c,0x02,0x95, 0x00,0x00 };
/* Image Fight */
static const uint8_t imgfight_code[CODE_LEN] =
static const u8 imgfight_code[CODE_LEN] =
{
0x68,0x00,0xa0, // push 0a000h
0x1f, // pop ds
@ -623,11 +618,11 @@ static const uint8_t imgfight_code[CODE_LEN] =
};
// these are for the japan set where we have the mcu anyway...
static const uint8_t imgfightj_crc[CRC_LEN] = { 0x7e,0xcc,0xec,0x03, 0x04,0x33,0xb6,0xc5,
static const u8 imgfightj_crc[CRC_LEN] = { 0x7e,0xcc,0xec,0x03, 0x04,0x33,0xb6,0xc5,
0xbf,0x37,0x92,0x94, 0x00,0x00 };
/* Legend of Hero Tonma */
static const uint8_t loht_code[CODE_LEN] =
static const u8 loht_code[CODE_LEN] =
{
0x68,0x00,0xa0, // push 0a000h
0x1f, // pop ds
@ -645,21 +640,21 @@ static const uint8_t loht_code[CODE_LEN] =
0xea,0x5d,0x01,0x40,0x00 // jmp 0040:$015d
};
static const uint8_t loht_crc[CRC_LEN] = { 0x39,0x00,0x82,0xae, 0x2c,0x9d,0x4b,0x73,
static const u8 loht_crc[CRC_LEN] = { 0x39,0x00,0x82,0xae, 0x2c,0x9d,0x4b,0x73,
0xfb,0xac,0xd4,0x6d, 0x6d,0x5b,0x77,0xc0, 0x00,0x00 };
/* Dragon Breed */
static const uint8_t dbreedm72_code[CODE_LEN] =
static const u8 dbreedm72_code[CODE_LEN] =
{
0xea,0x6c,0x00,0x00,0x00 // jmp 0000:$006c
};
static const uint8_t dbreedm72_crc[CRC_LEN] = { 0xa4,0x96,0x5f,0xc0, 0xab,0x49,0x9f,0x19,
static const u8 dbreedm72_crc[CRC_LEN] = { 0xa4,0x96,0x5f,0xc0, 0xab,0x49,0x9f,0x19,
0x84,0xe6,0xd6,0xca, 0x00,0x00 };
/* Air Duel */
static const uint8_t airduelm72_code[CODE_LEN] =
static const u8 airduelm72_code[CODE_LEN] =
{
0x68,0x00,0xd0, // push 0d000h
0x1f, // pop ds
@ -669,20 +664,20 @@ static const uint8_t airduelm72_code[CODE_LEN] =
0xc6,0x06,0xc0,0x1c,0x57, // mov [1cc0h], byte 057h
0xea,0x69,0x0b,0x00,0x00 // jmp 0000:$0b69
};
static const uint8_t airduelm72_crc[CRC_LEN] = { 0x72,0x9c,0xca,0x85, 0xc9,0x12,0xcc,0xea,
static const u8 airduelm72_crc[CRC_LEN] = { 0x72,0x9c,0xca,0x85, 0xc9,0x12,0xcc,0xea,
0x00,0x00 };
/* Daiku no Gensan */
static const uint8_t dkgenm72_code[CODE_LEN] =
static const u8 dkgenm72_code[CODE_LEN] =
{
0xea,0x3d,0x00,0x00,0x10 // jmp 1000:$003d
};
static const uint8_t dkgenm72_crc[CRC_LEN] = { 0xc8,0xb4,0xdc,0xf8, 0xd3,0xba,0x48,0xed,
static const u8 dkgenm72_crc[CRC_LEN] = { 0xc8,0xb4,0xdc,0xf8, 0xd3,0xba,0x48,0xed,
0x79,0x08,0x1c,0xb3, 0x00,0x00 };
void m72_state::copy_le(uint16_t *dest, const uint8_t *src, uint8_t bytes)
void m72_state::copy_le(u16 *dest, const u8 *src, u8 bytes)
{
int i;
@ -707,9 +702,9 @@ WRITE16_MEMBER(m72_state::protection_w)
copy_le(&m_protection_ram[0x0fe0],m_protection_crc,CRC_LEN);
}
void m72_state::install_protection_handler(const uint8_t *code,const uint8_t *crc)
void m72_state::install_protection_handler(const u8 *code,const u8 *crc)
{
m_protection_ram = std::make_unique<uint16_t[]>(0x1000/2);
m_protection_ram = std::make_unique<u16[]>(0x1000/2);
m_protection_code = code;
m_protection_crc = crc;
m_maincpu->space(AS_PROGRAM).install_read_bank(0xb0000, 0xb0fff, "bank1");
@ -746,7 +741,7 @@ void m72_state::init_loht()
m_maincpu->space(AS_IO).install_write_handler(0xc0, 0xc1, write16_delegate(FUNC(m72_state::loht_sample_trigger_w),this));
/* since we skip the startup tests, clear video RAM to prevent garbage on title screen */
memset(m_videoram2,0,0x4000);
memset(m_videoram[1],0,0x4000);
}
@ -774,28 +769,64 @@ void m72_state::init_gallop()
}
READ16_MEMBER(m72_state::soundram_r)
template<unsigned N>
u16 m72_state::palette_r(offs_t offset)
{
return m_soundram[offset * 2 + 0] | (m_soundram[offset * 2 + 1] << 8);
/* A9 isn't connected, so 0x200-0x3ff mirrors 0x000-0x1ff etc. */
offset &= ~0x100;
return m_paletteram[N][offset] | 0xffe0; /* only D0-D4 are connected */
}
WRITE16_MEMBER(m72_state::soundram_w)
inline void m72_state::changecolor(offs_t color, u8 r, u8 g, u8 b)
{
if (ACCESSING_BITS_0_7)
m_soundram[offset * 2 + 0] = data;
if (ACCESSING_BITS_8_15)
m_soundram[offset * 2 + 1] = data >> 8;
m_palette->set_pen_color(color,pal5bit(r),pal5bit(g),pal5bit(b));
}
template<unsigned N>
void m72_state::palette_w(offs_t offset, u16 data, u16 mem_mask)
{
/* A9 isn't connected, so 0x200-0x3ff mirrors 0x000-0x1ff etc. */
offset &= ~0x100;
COMBINE_DATA(&m_paletteram[N][offset]);
offset &= 0x0ff;
changecolor(offset + (N << 8),
m_paletteram[N][offset + 0x000],
m_paletteram[N][offset + 0x200],
m_paletteram[N][offset + 0x400]);
}
template<unsigned N>
void m72_state::scrollx_w(offs_t offset, u16 data, u16 mem_mask)
{
m_screen->update_partial(m_screen->vpos());
COMBINE_DATA(&m_scrollx[N]);
}
template<unsigned N>
void m72_state::scrolly_w(offs_t offset, u16 data, u16 mem_mask)
{
m_screen->update_partial(m_screen->vpos());
COMBINE_DATA(&m_scrolly[N]);
}
u8 m72_state::soundram_r(offs_t offset)
{
return m_soundram[offset];
}
void m72_state::soundram_w(offs_t offset, u8 data)
{
m_soundram[offset] = data;
}
void m72_state::m72_cpu1_common_map(address_map &map)
{
map(0xc0000, 0xc03ff).ram().share("spriteram");
map(0xc8000, 0xc8bff).rw(FUNC(m72_state::palette1_r), FUNC(m72_state::palette1_w)).share("paletteram");
map(0xcc000, 0xccbff).rw(FUNC(m72_state::palette2_r), FUNC(m72_state::palette2_w)).share("paletteram2");
map(0xc8000, 0xc8bff).rw(FUNC(m72_state::palette_r<0>), FUNC(m72_state::palette_w<0>)).share("paletteram1");
map(0xcc000, 0xccbff).rw(FUNC(m72_state::palette_r<1>), FUNC(m72_state::palette_w<1>)).share("paletteram2");
map(0xd0000, 0xd3fff).ram().w(FUNC(m72_state::videoram1_w)).share("videoram1");
map(0xd8000, 0xdbfff).ram().w(FUNC(m72_state::videoram2_w)).share("videoram2");
map(0xe0000, 0xeffff).rw(FUNC(m72_state::soundram_r), FUNC(m72_state::soundram_w));
@ -842,8 +873,8 @@ void m72_state::m81_cpu1_common_map(address_map &map)
map(0x00000, 0x7ffff).rom();
map(0xb0ffe, 0xb0fff).writeonly(); /* leftover from protection?? */
map(0xc0000, 0xc03ff).ram().share("spriteram");
map(0xc8000, 0xc8bff).rw(FUNC(m72_state::palette1_r), FUNC(m72_state::palette1_w)).share("paletteram");
map(0xcc000, 0xccbff).rw(FUNC(m72_state::palette2_r), FUNC(m72_state::palette2_w)).share("paletteram2");
map(0xc8000, 0xc8bff).rw(FUNC(m72_state::palette_r<0>), FUNC(m72_state::palette_w<0>)).share("paletteram1");
map(0xcc000, 0xccbff).rw(FUNC(m72_state::palette_r<1>), FUNC(m72_state::palette_w<1>)).share("paletteram2");
map(0xd0000, 0xd3fff).ram().w(FUNC(m72_state::videoram1_w)).share("videoram1");
map(0xd8000, 0xdbfff).ram().w(FUNC(m72_state::videoram2_w)).share("videoram2");
map(0xffff0, 0xfffff).rom();
@ -872,7 +903,7 @@ void m72_state::m84_cpu1_common_map(address_map &map)
map(0x00000, 0x7ffff).rom();
map(0xb0000, 0xb0001).w(FUNC(m72_state::irq_line_w));
map(0xb4000, 0xb4001).nopw(); /* ??? */
map(0xbc000, 0xbc001).w(FUNC(m72_state::dmaon_w));
map(0xbc000, 0xbc000).w(FUNC(m72_state::dmaon_w));
map(0xb0ffe, 0xb0fff).writeonly(); /* leftover from protection?? */
map(0xc0000, 0xc03ff).ram().share("spriteram");
map(0xe0000, 0xe3fff).ram(); /* work RAM */
@ -884,8 +915,8 @@ void m72_state::rtype2_map(address_map &map)
m84_cpu1_common_map(map);
map(0xd0000, 0xd3fff).ram().w(FUNC(m72_state::videoram1_w)).share("videoram1");
map(0xd4000, 0xd7fff).ram().w(FUNC(m72_state::videoram2_w)).share("videoram2");
map(0xc8000, 0xc8bff).rw(FUNC(m72_state::palette1_r), FUNC(m72_state::palette1_w)).share("paletteram");
map(0xd8000, 0xd8bff).rw(FUNC(m72_state::palette2_r), FUNC(m72_state::palette2_w)).share("paletteram2");
map(0xc8000, 0xc8bff).rw(FUNC(m72_state::palette_r<0>), FUNC(m72_state::palette_w<0>)).share("paletteram1");
map(0xd8000, 0xd8bff).rw(FUNC(m72_state::palette_r<1>), FUNC(m72_state::palette_w<1>)).share("paletteram2");
}
void m72_state::hharryu_map(address_map &map)
@ -893,8 +924,8 @@ void m72_state::hharryu_map(address_map &map)
m84_cpu1_common_map(map);
map(0xd0000, 0xd3fff).ram().w(FUNC(m72_state::videoram1_w)).share("videoram1");
map(0xd4000, 0xd7fff).ram().w(FUNC(m72_state::videoram2_w)).share("videoram2");
map(0xa0000, 0xa0bff).rw(FUNC(m72_state::palette1_r), FUNC(m72_state::palette1_w)).share("paletteram");
map(0xa8000, 0xa8bff).rw(FUNC(m72_state::palette2_r), FUNC(m72_state::palette2_w)).share("paletteram2");
map(0xa0000, 0xa0bff).rw(FUNC(m72_state::palette_r<0>), FUNC(m72_state::palette_w<0>)).share("paletteram1");
map(0xa8000, 0xa8bff).rw(FUNC(m72_state::palette_r<1>), FUNC(m72_state::palette_w<1>)).share("paletteram2");
}
void m72_state::kengo_map(address_map &map)
@ -902,8 +933,8 @@ void m72_state::kengo_map(address_map &map)
m84_cpu1_common_map(map);
map(0x80000, 0x83fff).ram().w(FUNC(m72_state::videoram1_w)).share("videoram1");
map(0x84000, 0x87fff).ram().w(FUNC(m72_state::videoram2_w)).share("videoram2");
map(0xa0000, 0xa0bff).rw(FUNC(m72_state::palette1_r), FUNC(m72_state::palette1_w)).share("paletteram");
map(0xa8000, 0xa8bff).rw(FUNC(m72_state::palette2_r), FUNC(m72_state::palette2_w)).share("paletteram2");
map(0xa0000, 0xa0bff).rw(FUNC(m72_state::palette_r<0>), FUNC(m72_state::palette_w<0>)).share("paletteram1");
map(0xa8000, 0xa8bff).rw(FUNC(m72_state::palette_r<1>), FUNC(m72_state::palette_w<1>)).share("paletteram2");
}
@ -911,16 +942,16 @@ void m72_state::m82_map(address_map &map)
{
map(0x00000, 0x7ffff).rom();
map(0xa0000, 0xa03ff).ram().share("majtitle_rowscr");
map(0xa4000, 0xa4bff).rw(FUNC(m72_state::palette2_r), FUNC(m72_state::palette2_w)).share("paletteram2");
map(0xa4000, 0xa4bff).rw(FUNC(m72_state::palette_r<1>), FUNC(m72_state::palette_w<1>)).share("paletteram2");
map(0xac000, 0xaffff).ram().w(FUNC(m72_state::videoram1_w)).share("videoram1");
map(0xb0000, 0xbffff).ram().w(FUNC(m72_state::videoram2_w)).share("videoram2"); /* larger than the other games */
map(0xc0000, 0xc03ff).ram().share("spriteram");
map(0xc8000, 0xc83ff).ram().share("spriteram2");
map(0xcc000, 0xccbff).rw(FUNC(m72_state::palette1_r), FUNC(m72_state::palette1_w)).share("paletteram");
map(0xcc000, 0xccbff).rw(FUNC(m72_state::palette_r<0>), FUNC(m72_state::palette_w<0>)).share("paletteram1");
map(0xd0000, 0xd3fff).ram(); /* work RAM */
map(0xe0000, 0xe0001).w(FUNC(m72_state::irq_line_w));
map(0xe4000, 0xe4001).writeonly(); /* playfield enable? 1 during screen transitions, 0 otherwise */
map(0xec000, 0xec001).w(FUNC(m72_state::dmaon_w));
map(0xec000, 0xec000).w(FUNC(m72_state::dmaon_w));
map(0xffff0, 0xfffff).rom();
}
@ -934,13 +965,13 @@ void m72_state::m72_portmap(address_map &map)
map(0x04, 0x05).portr("DSW");
map(0x00, 0x00).w("soundlatch", FUNC(generic_latch_8_device::write));
map(0x02, 0x02).w(FUNC(m72_state::port02_w)); /* coin counters, reset sound cpu, other stuff? */
map(0x04, 0x05).w(FUNC(m72_state::dmaon_w));
map(0x04, 0x04).w(FUNC(m72_state::dmaon_w));
map(0x06, 0x07).w(FUNC(m72_state::irq_line_w));
map(0x40, 0x43).rw(m_upd71059c, FUNC(pic8259_device::read), FUNC(pic8259_device::write)).umask16(0x00ff);
map(0x80, 0x81).w(FUNC(m72_state::scrolly1_w));
map(0x82, 0x83).w(FUNC(m72_state::scrollx1_w));
map(0x84, 0x85).w(FUNC(m72_state::scrolly2_w));
map(0x86, 0x87).w(FUNC(m72_state::scrollx2_w));
map(0x80, 0x81).w(FUNC(m72_state::scrolly_w<0>));
map(0x82, 0x83).w(FUNC(m72_state::scrollx_w<0>));
map(0x84, 0x85).w(FUNC(m72_state::scrolly_w<1>));
map(0x86, 0x87).w(FUNC(m72_state::scrollx_w<1>));
/* { 0xc0, 0xc0 trigger sample, filled by init_ function */
}
@ -958,10 +989,10 @@ void m72_state::m84_portmap(address_map &map)
map(0x00, 0x00).w("soundlatch", FUNC(generic_latch_8_device::write));
map(0x02, 0x02).w(FUNC(m72_state::rtype2_port02_w));
map(0x40, 0x43).rw(m_upd71059c, FUNC(pic8259_device::read), FUNC(pic8259_device::write)).umask16(0x00ff);
map(0x80, 0x81).w(FUNC(m72_state::scrolly1_w));
map(0x82, 0x83).w(FUNC(m72_state::scrollx1_w));
map(0x84, 0x85).w(FUNC(m72_state::scrolly2_w));
map(0x86, 0x87).w(FUNC(m72_state::scrollx2_w));
map(0x80, 0x81).w(FUNC(m72_state::scrolly_w<0>));
map(0x82, 0x83).w(FUNC(m72_state::scrollx_w<0>));
map(0x84, 0x85).w(FUNC(m72_state::scrolly_w<1>));
map(0x86, 0x87).w(FUNC(m72_state::scrollx_w<1>));
}
void m72_state::m84_v33_portmap(address_map &map)
@ -971,10 +1002,10 @@ void m72_state::m84_v33_portmap(address_map &map)
map(0x04, 0x05).portr("DSW");
map(0x00, 0x00).w("soundlatch", FUNC(generic_latch_8_device::write));
map(0x02, 0x02).w(FUNC(m72_state::rtype2_port02_w));
map(0x80, 0x81).w(FUNC(m72_state::scrolly1_w));
map(0x82, 0x83).w(FUNC(m72_state::scrollx1_w));
map(0x84, 0x85).w(FUNC(m72_state::scrolly2_w));
map(0x86, 0x87).w(FUNC(m72_state::scrollx2_w));
map(0x80, 0x81).w(FUNC(m72_state::scrolly_w<0>));
map(0x82, 0x83).w(FUNC(m72_state::scrollx_w<0>));
map(0x84, 0x85).w(FUNC(m72_state::scrolly_w<1>));
map(0x86, 0x87).w(FUNC(m72_state::scrollx_w<1>));
// AM_RANGE(0x8c, 0x8f) AM_WRITENOP /* ??? */
}
@ -988,10 +1019,10 @@ void m72_state::poundfor_portmap(address_map &map)
map(0x00, 0x00).w("soundlatch", FUNC(generic_latch_8_device::write));
map(0x02, 0x02).w(FUNC(m72_state::poundfor_port02_w));
map(0x40, 0x43).rw(m_upd71059c, FUNC(pic8259_device::read), FUNC(pic8259_device::write)).umask16(0x00ff);
map(0x80, 0x81).w(FUNC(m72_state::scrolly1_w));
map(0x82, 0x83).w(FUNC(m72_state::scrollx1_w));
map(0x84, 0x85).w(FUNC(m72_state::scrolly2_w));
map(0x86, 0x87).w(FUNC(m72_state::scrollx2_w));
map(0x80, 0x81).w(FUNC(m72_state::scrolly_w<0>));
map(0x82, 0x83).w(FUNC(m72_state::scrollx_w<0>));
map(0x84, 0x85).w(FUNC(m72_state::scrolly_w<1>));
map(0x86, 0x87).w(FUNC(m72_state::scrollx_w<1>));
}
void m72_state::m82_portmap(address_map &map)
@ -1002,10 +1033,10 @@ void m72_state::m82_portmap(address_map &map)
map(0x00, 0x00).w("soundlatch", FUNC(generic_latch_8_device::write));
map(0x02, 0x02).w(FUNC(m72_state::rtype2_port02_w));
map(0x40, 0x43).rw(m_upd71059c, FUNC(pic8259_device::read), FUNC(pic8259_device::write)).umask16(0x00ff);
map(0x80, 0x81).w(FUNC(m72_state::scrolly1_w));
map(0x82, 0x83).w(FUNC(m72_state::scrollx1_w));
map(0x84, 0x85).w(FUNC(m72_state::scrolly2_w));
map(0x86, 0x87).w(FUNC(m72_state::scrollx2_w));
map(0x80, 0x81).w(FUNC(m72_state::scrolly_w<0>));
map(0x82, 0x83).w(FUNC(m72_state::scrollx_w<0>));
map(0x84, 0x85).w(FUNC(m72_state::scrolly_w<1>));
map(0x86, 0x87).w(FUNC(m72_state::scrollx_w<1>));
// these ports control the tilemap sizes, rowscroll etc. that m82 has, exact bit usage not known (maybe one for each layer?)
map(0x8c, 0x8d).w(FUNC(m72_state::m82_tm_ctrl_w));
@ -1019,13 +1050,13 @@ void m72_state::m81_portmap(address_map &map)
map(0x04, 0x05).portr("DSW");
map(0x00, 0x00).w("soundlatch", FUNC(generic_latch_8_device::write));
map(0x02, 0x02).w(FUNC(m72_state::rtype2_port02_w)); /* coin counters, reset sound cpu, other stuff? */
map(0x04, 0x05).w(FUNC(m72_state::dmaon_w));
map(0x04, 0x04).w(FUNC(m72_state::dmaon_w));
map(0x06, 0x07).w(FUNC(m72_state::irq_line_w));
map(0x40, 0x43).rw(m_upd71059c, FUNC(pic8259_device::read), FUNC(pic8259_device::write)).umask16(0x00ff);
map(0x80, 0x81).w(FUNC(m72_state::scrolly1_w));
map(0x82, 0x83).w(FUNC(m72_state::scrollx1_w));
map(0x84, 0x85).w(FUNC(m72_state::scrolly2_w));
map(0x86, 0x87).w(FUNC(m72_state::scrollx2_w));
map(0x80, 0x81).w(FUNC(m72_state::scrolly_w<0>));
map(0x82, 0x83).w(FUNC(m72_state::scrollx_w<0>));
map(0x84, 0x85).w(FUNC(m72_state::scrolly_w<1>));
map(0x86, 0x87).w(FUNC(m72_state::scrollx_w<1>));
}
@ -1051,14 +1082,20 @@ void m72_state::rtype_sound_portmap(address_map &map)
void m72_state::sound_portmap(address_map &map)
{
rtype_sound_portmap(map);
map.global_mask(0xff);
map(0x00, 0x01).rw("ymsnd", FUNC(ym2151_device::read), FUNC(ym2151_device::write));
map(0x02, 0x02).r("soundlatch", FUNC(generic_latch_8_device::read));
map(0x06, 0x06).w("soundlatch", FUNC(generic_latch_8_device::acknowledge_w));
map(0x82, 0x82).w(m_audio, FUNC(m72_audio_device::sample_w));
map(0x84, 0x84).r(m_audio, FUNC(m72_audio_device::sample_r));
}
void m72_state::sound_protected_portmap(address_map &map)
{
rtype_sound_portmap(map);
map.global_mask(0xff);
map(0x82, 0x82).w(m_dac, FUNC(dac_byte_interface::data_w));
map(0x84, 0x84).r(FUNC(m72_state::snd_cpu_sample_r));
}
void m72_state::rtype2_sound_portmap(address_map &map)
{
map.global_mask(0xff);
@ -1848,6 +1885,8 @@ void m72_state::m72_base(machine_config &config)
m_upd71059c->out_int_callback().set_inputline(m_maincpu, 0);
/* video hardware */
BUFFERED_SPRITERAM16(config, m_spriteram);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_m72);
PALETTE(config, m_palette).set_entries(512);
@ -1865,7 +1904,7 @@ void m72_state::m72(machine_config &config)
{
m72_base(config);
/* Sample rate verified (Gallop : https://youtu.be/aozd0dbPzOw) */
m_soundcpu->set_periodic_int(FUNC(m72_state::fake_nmi), attotime::from_hz(32000000/8/512));
m_soundcpu->set_periodic_int(FUNC(m72_state::fake_nmi), attotime::from_hz(MASTER_CLOCK/8/512));
/* IRQs are generated by main Z80 and YM2151 */
}
@ -1875,6 +1914,8 @@ void m72_state::m72_8751(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &m72_state::m72_protected_map);
m_maincpu->set_addrmap(AS_IO, &m72_state::m72_protected_portmap);
m_soundcpu->set_addrmap(AS_IO, &m72_state::sound_protected_portmap);
MB8421_MB8431_16BIT(config, m_dpram);
//m_dpram->intl_callback().set(m_upd71059c, FUNC(pic8259_device::ir3_w)); // not actually used?
m_dpram->intr_callback().set_inputline("mcu", MCS51_INT0_LINE);
@ -1916,7 +1957,7 @@ void m72_state::m72_xmultipl(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &m72_state::xmultiplm72_map);
/* Sample rate verified (Gallop : https://youtu.be/aozd0dbPzOw) */
m_soundcpu->set_periodic_int(FUNC(m72_state::nmi_line_pulse), attotime::from_hz(32000000/8/512));
m_soundcpu->set_periodic_int(FUNC(m72_state::nmi_line_pulse), attotime::from_hz(MASTER_CLOCK/8/512));
/* IRQs are generated by main Z80 and YM2151 */
}
@ -1926,7 +1967,7 @@ void m72_state::m72_dbreed(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &m72_state::dbreedm72_map);
/* Sample rate verified (Gallop : https://youtu.be/aozd0dbPzOw) */
m_soundcpu->set_periodic_int(FUNC(m72_state::nmi_line_pulse), attotime::from_hz(32000000/8/512));
m_soundcpu->set_periodic_int(FUNC(m72_state::nmi_line_pulse), attotime::from_hz(MASTER_CLOCK/8/512));
/* IRQs are generated by main Z80 and YM2151 */
}
@ -1944,7 +1985,7 @@ void m72_state::m81_hharry(machine_config &config)
m_soundcpu->set_addrmap(AS_PROGRAM, &m72_state::sound_rom_map);
m_soundcpu->set_addrmap(AS_IO, &m72_state::rtype2_sound_portmap);
m_soundcpu->set_periodic_int(FUNC(m72_state::nmi_line_pulse), attotime::from_hz(128*55));
m_soundcpu->set_periodic_int(FUNC(m72_state::nmi_line_pulse), attotime::from_hz(MASTER_CLOCK/8/512));
MCFG_VIDEO_START_OVERRIDE(m72_state,hharry)
@ -1980,13 +2021,15 @@ void m72_state::rtype2(machine_config &config)
Z80(config, m_soundcpu, SOUND_CLOCK);
m_soundcpu->set_addrmap(AS_PROGRAM, &m72_state::sound_rom_map);
m_soundcpu->set_addrmap(AS_IO, &m72_state::rtype2_sound_portmap);
m_soundcpu->set_periodic_int(FUNC(m72_state::nmi_line_pulse), attotime::from_hz(128*55)); /* clocked by V1? (Vigilante) */
m_soundcpu->set_periodic_int(FUNC(m72_state::nmi_line_pulse), attotime::from_hz(MASTER_CLOCK/8/512)); /* verified (https://youtu.be/lUszf9Ong7U) */
/* IRQs are generated by main Z80 and YM2151 */
PIC8259(config, m_upd71059c, 0);
m_upd71059c->out_int_callback().set_inputline(m_maincpu, 0);
/* video hardware */
BUFFERED_SPRITERAM16(config, m_spriteram);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_rtype2);
PALETTE(config, m_palette).set_entries(512);
@ -2023,7 +2066,7 @@ void m72_state::cosmccop(machine_config &config)
Z80(config, m_soundcpu, SOUND_CLOCK);
m_soundcpu->set_addrmap(AS_PROGRAM, &m72_state::sound_rom_map);
m_soundcpu->set_addrmap(AS_IO, &m72_state::rtype2_sound_portmap);
m_soundcpu->set_periodic_int(FUNC(m72_state::nmi_line_pulse), attotime::from_hz(128*55)); /* clocked by V1? (Vigilante) */
m_soundcpu->set_periodic_int(FUNC(m72_state::nmi_line_pulse), attotime::from_hz(MASTER_CLOCK/8/512)); /* verified (https://youtu.be/Sol2Yq2S5hQ) */
/* IRQs are generated by main Z80 and YM2151 */
MCFG_MACHINE_START_OVERRIDE(m72_state,kengo)
@ -2032,6 +2075,8 @@ void m72_state::cosmccop(machine_config &config)
// upd71059c isn't needed because the V35 has its own IRQ controller
/* video hardware */
BUFFERED_SPRITERAM16(config, m_spriteram);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_rtype2);
PALETTE(config, m_palette).set_entries(512);
@ -2067,16 +2112,19 @@ void m72_state::m82(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &m72_state::m82_map);
m_maincpu->set_addrmap(AS_IO, &m72_state::m82_portmap);
m_maincpu->set_irq_acknowledge_callback("upd71059c", FUNC(pic8259_device::inta_cb));
Z80(config, m_soundcpu, SOUND_CLOCK);
m_soundcpu->set_addrmap(AS_PROGRAM, &m72_state::sound_rom_map);
m_soundcpu->set_addrmap(AS_IO, &m72_state::rtype2_sound_portmap);
m_soundcpu->set_periodic_int(FUNC(m72_state::nmi_line_pulse), attotime::from_hz(128*55)); /* clocked by V1? (Vigilante) */
m_soundcpu->set_periodic_int(FUNC(m72_state::nmi_line_pulse), attotime::from_hz(MASTER_CLOCK/8/512)); /* verified (https://youtu.be/lLQDPe-8Ha0) */
/* IRQs are generated by main Z80 and YM2151 */
PIC8259(config, m_upd71059c, 0);
m_upd71059c->out_int_callback().set_inputline(m_maincpu, 0);
/* video hardware */
BUFFERED_SPRITERAM16(config, m_spriteram);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_majtitle);
PALETTE(config, m_palette).set_entries(512);
@ -2106,7 +2154,7 @@ void m72_state::poundfor(machine_config &config)
Z80(config, m_soundcpu, SOUND_CLOCK);
m_soundcpu->set_addrmap(AS_PROGRAM, &m72_state::sound_rom_map);
m_soundcpu->set_addrmap(AS_IO, &m72_state::poundfor_sound_portmap);
m_soundcpu->set_periodic_int(FUNC(m72_state::fake_nmi), attotime::from_hz(128*55)); /* clocked by V1? (Vigilante) */
m_soundcpu->set_periodic_int(FUNC(m72_state::fake_nmi), attotime::from_hz(MASTER_CLOCK/8/512)); /* clocked by V1? (Vigilante) */
/* IRQs are generated by main Z80 and YM2151 */
PIC8259(config, m_upd71059c, 0);
@ -2121,6 +2169,8 @@ void m72_state::poundfor(machine_config &config)
m_upd4701[1]->set_porty_tag("TRACK1_Y");
/* video hardware */
BUFFERED_SPRITERAM16(config, m_spriteram);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_rtype2);
PALETTE(config, m_palette).set_entries(512);

View File

@ -15,6 +15,7 @@
#include "machine/mb8421.h"
#include "machine/pic8259.h"
#include "machine/upd4701.h"
#include "video/bufsprite.h"
#include "sound/dac.h"
#include "emupal.h"
#include "screen.h"
@ -46,15 +47,15 @@ public:
m_screen(*this, "screen"),
m_palette(*this, "palette"),
m_spriteram(*this, "spriteram"),
m_videoram1(*this, "videoram1"),
m_videoram2(*this, "videoram2"),
m_videoram(*this, "videoram%u", 1U),
m_m82_rowscrollram(*this, "majtitle_rowscr"),
m_spriteram2(*this, "spriteram2"),
m_soundram(*this, "soundram"),
m_generic_paletteram_16(*this, "paletteram"),
m_generic_paletteram2_16(*this, "paletteram2"),
m_paletteram(*this, "paletteram%u", 1U),
m_upd71059c(*this, "upd71059c"),
m_upd4701(*this, {"upd4701l", "upd4701h"}),
m_samples_region(*this, "samples"),
m_io_dsw(*this, "DSW"),
m_fg_source(0),
m_bg_source(0),
m_m81_b_b_j3(*this, "JumperJ3"),
@ -100,32 +101,32 @@ private:
required_device<gfxdecode_device> m_gfxdecode;
required_device<screen_device> m_screen;
required_device<palette_device> m_palette;
required_device<buffered_spriteram16_device> m_spriteram;
required_shared_ptr_array<u16, 2> m_videoram;
optional_shared_ptr<u16> m_m82_rowscrollram;
optional_shared_ptr<u16> m_spriteram2;
optional_shared_ptr<u8> m_soundram;
required_shared_ptr_array<u16, 2> m_paletteram;
required_shared_ptr<uint16_t> m_spriteram;
required_shared_ptr<uint16_t> m_videoram1;
required_shared_ptr<uint16_t> m_videoram2;
optional_shared_ptr<uint16_t> m_m82_rowscrollram;
optional_shared_ptr<uint16_t> m_spriteram2;
optional_shared_ptr<uint8_t> m_soundram;
required_shared_ptr<uint16_t> m_generic_paletteram_16;
required_shared_ptr<uint16_t> m_generic_paletteram2_16;
optional_device<pic8259_device> m_upd71059c;
optional_device_array<upd4701_device, 2> m_upd4701;
std::unique_ptr<uint16_t[]> m_protection_ram;
optional_region_ptr<u8> m_samples_region;
optional_ioport m_io_dsw;
std::unique_ptr<u16[]> m_protection_ram;
emu_timer *m_scanline_timer;
const uint8_t *m_protection_code;
const uint8_t *m_protection_crc;
uint32_t m_raster_irq_position;
std::unique_ptr<uint16_t[]> m_buffered_spriteram;
const u8 *m_protection_code;
const u8 *m_protection_crc;
u32 m_raster_irq_position;
tilemap_t *m_fg_tilemap;
tilemap_t *m_bg_tilemap;
tilemap_t *m_bg_tilemap_large;
int32_t m_scrollx1;
int32_t m_scrolly1;
int32_t m_scrollx2;
int32_t m_scrolly2;
int32_t m_video_off;
s32 m_scrollx[2];
s32 m_scrolly[2];
s32 m_video_off;
int m_fg_source;
int m_bg_source;
@ -133,39 +134,36 @@ private:
// majtitle specific
int m_m82_rowscroll;
uint16_t m_m82_tmcontrol;
u16 m_m82_tmcontrol;
// m72_i8751 specific
uint8_t m_mcu_sample_latch;
uint32_t m_mcu_sample_addr;
u8 m_mcu_sample_latch;
u32 m_mcu_sample_addr;
// common
DECLARE_READ16_MEMBER(palette1_r);
DECLARE_READ16_MEMBER(palette2_r);
DECLARE_WRITE16_MEMBER(palette1_w);
DECLARE_WRITE16_MEMBER(palette2_w);
DECLARE_WRITE16_MEMBER(videoram1_w);
DECLARE_WRITE16_MEMBER(videoram2_w);
DECLARE_READ16_MEMBER(soundram_r);
DECLARE_WRITE16_MEMBER(soundram_w);
template<unsigned N> u16 palette_r(offs_t offset);
template<unsigned N> void palette_w(offs_t offset, u16 data, u16 mem_mask);
void videoram1_w(offs_t offset, u16 data, u16 mem_mask);
void videoram2_w(offs_t offset, u16 data, u16 mem_mask);
void irq_line_w(u16 data);
template<unsigned N> void scrollx_w(offs_t offset, u16 data, u16 mem_mask);
template<unsigned N> void scrolly_w(offs_t offset, u16 data, u16 mem_mask);
void dmaon_w(u8 data);
void port02_w(u8 data);
u8 soundram_r(offs_t offset);
void soundram_w(offs_t offset, u8 data);
// m72_i8751 specific
DECLARE_WRITE16_MEMBER(main_mcu_sound_w);
DECLARE_WRITE16_MEMBER(main_mcu_w);
DECLARE_WRITE8_MEMBER(mcu_data_w);
DECLARE_READ8_MEMBER(mcu_data_r);
DECLARE_READ8_MEMBER(mcu_sample_r);
DECLARE_WRITE8_MEMBER(mcu_port1_w);
DECLARE_WRITE8_MEMBER(mcu_low_w);
DECLARE_WRITE8_MEMBER(mcu_high_w);
DECLARE_READ8_MEMBER(snd_cpu_sample_r);
DECLARE_WRITE16_MEMBER(irq_line_w);
DECLARE_WRITE16_MEMBER(scrollx1_w);
DECLARE_WRITE16_MEMBER(scrollx2_w);
DECLARE_WRITE16_MEMBER(scrolly1_w);
DECLARE_WRITE16_MEMBER(scrolly2_w);
DECLARE_WRITE16_MEMBER(dmaon_w);
DECLARE_WRITE8_MEMBER(port02_w);
void main_mcu_w(offs_t offset, u16 data, u16 mem_mask);
void mcu_data_w(offs_t offset, u8 data);
u8 mcu_data_r(offs_t offset);
u8 mcu_sample_r();
void mcu_port1_w(u8 data);
void mcu_low_w(u8 data);
void mcu_high_w(u8 data);
u8 snd_cpu_sample_r();
DECLARE_READ16_MEMBER(protection_r);
DECLARE_WRITE16_MEMBER(protection_w);
@ -178,16 +176,15 @@ private:
DECLARE_WRITE16_MEMBER(airduelm72_sample_trigger_w);
DECLARE_WRITE16_MEMBER(dkgenm72_sample_trigger_w);
DECLARE_WRITE16_MEMBER(gallop_sample_trigger_w);
DECLARE_WRITE8_MEMBER(rtype2_port02_w);
DECLARE_WRITE8_MEMBER(poundfor_port02_w);
DECLARE_WRITE16_MEMBER(m82_gfx_ctrl_w);
DECLARE_WRITE16_MEMBER(m82_tm_ctrl_w);
void rtype2_port02_w(u8 data);
void poundfor_port02_w(u8 data);
void m82_gfx_ctrl_w(offs_t offset, u16 data, u16 mem_mask);
void m82_tm_ctrl_w(offs_t offset, u16 data, u16 mem_mask);
TILE_GET_INFO_MEMBER(get_bg_tile_info);
TILE_GET_INFO_MEMBER(get_fg_tile_info);
TILE_GET_INFO_MEMBER(rtype2_get_bg_tile_info);
TILE_GET_INFO_MEMBER(rtype2_get_fg_tile_info);
template<unsigned N> TILE_GET_INFO_MEMBER(rtype2_get_tile_info);
TILEMAP_MAPPER_MEMBER(m82_scan_rows);
@ -210,17 +207,16 @@ private:
TIMER_CALLBACK_MEMBER(delayed_ram16_w);
TIMER_CALLBACK_MEMBER(delayed_ram8_w);
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
uint32_t screen_update_m81(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
uint32_t screen_update_m82(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
inline void m72_m81_get_tile_info(tile_data &tileinfo,int tile_index,const uint16_t *vram,int gfxnum);
inline void m82_m84_get_tile_info(tile_data &tileinfo,int tile_index,const uint16_t *vram,int gfxnum);
u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
u32 screen_update_m81(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
u32 screen_update_m82(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
inline void m72_m81_get_tile_info(tile_data &tileinfo,int tile_index,const u16 *vram,int gfxnum);
void register_savestate();
inline void changecolor(int color,int r,int g,int b);
inline void changecolor(offs_t color, u8 r, u8 g, u8 b);
void draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect);
void majtitle_draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect);
void copy_le(uint16_t *dest, const uint8_t *src, uint8_t bytes);
void install_protection_handler(const uint8_t *code,const uint8_t *crc);
void copy_le(u16 *dest, const u8 *src, u8 bytes);
void install_protection_handler(const u8 *code,const u8 *crc);
void dbreed_map(address_map &map);
void dbreedm72_map(address_map &map);
@ -248,6 +244,7 @@ private:
void rtype_map(address_map &map);
void rtype_sound_portmap(address_map &map);
void sound_portmap(address_map &map);
void sound_protected_portmap(address_map &map);
void sound_ram_map(address_map &map);
void sound_rom_map(address_map &map);
void xmultipl_map(address_map &map);

View File

@ -10,9 +10,9 @@
***************************************************************************/
inline void m72_state::m72_m81_get_tile_info(tile_data &tileinfo,int tile_index,const uint16_t *vram,int gfxnum)
inline void m72_state::m72_m81_get_tile_info(tile_data &tileinfo,int tile_index,const u16 *vram,int gfxnum)
{
int code,attr,color,pri;
int pri;
// word 0 word 1
// fftt tttt tttt tttt ---- ---- zz-? pppp
@ -22,75 +22,61 @@ inline void m72_state::m72_m81_get_tile_info(tile_data &tileinfo,int tile_index,
tile_index *= 2;
code = vram[tile_index] & 0xff;
attr = vram[tile_index] >> 8;
color = vram[tile_index+1] & 0xff;
const u16 code = vram[tile_index];
const u16 attr = vram[tile_index+1];
if (color & 0x80) pri = 2;
else if (color & 0x40) pri = 1;
if (attr & 0x0080) pri = 2;
else if (attr & 0x0040) pri = 1;
else pri = 0;
/* color & 0x10 is used in bchopper and hharry, more priority? */
/* attr & 0x0010 is used in bchopper and hharry, more priority? */
SET_TILE_INFO_MEMBER(gfxnum,
code + ((attr & 0x3f) << 8),
color & 0x0f,
TILE_FLIPYX((attr & 0xc0) >> 6));
tileinfo.group = pri;
}
inline void m72_state::m82_m84_get_tile_info(tile_data &tileinfo,int tile_index,const uint16_t *vram,int gfxnum)
{
int code,attr,color,pri;
// word 0 word 1
// tttt tttt tttt tttt ---- ---z zff- pppp
// f = flips, t = tilenum, z = pri, p = palette
tile_index *= 2;
code = vram[tile_index];
color = vram[tile_index+1] & 0xff;
attr = vram[tile_index+1] >> 8;
if (attr & 0x01) pri = 2;
else if (color & 0x80) pri = 1;
else pri = 0;
/* (vram[tile_index+2] & 0x10) is used by majtitle on the green, but it's not clear for what */
/* (vram[tile_index+3] & 0xfe) are used as well */
SET_TILE_INFO_MEMBER(gfxnum,
code,
color & 0x0f,
TILE_FLIPYX((color & 0x60) >> 5));
code & 0x3fff,
attr & 0x000f,
TILE_FLIPYX((code & 0xc000) >> 14));
tileinfo.group = pri;
}
TILE_GET_INFO_MEMBER(m72_state::get_bg_tile_info)
{
m72_m81_get_tile_info(tileinfo,tile_index,m_videoram2,m_bg_source);
m72_m81_get_tile_info(tileinfo,tile_index,m_videoram[1],m_bg_source);
}
TILE_GET_INFO_MEMBER(m72_state::get_fg_tile_info)
{
m72_m81_get_tile_info(tileinfo,tile_index,m_videoram1,m_fg_source);
m72_m81_get_tile_info(tileinfo,tile_index,m_videoram[0],m_fg_source);
}
TILE_GET_INFO_MEMBER(m72_state::rtype2_get_bg_tile_info)
template<unsigned N>
TILE_GET_INFO_MEMBER(m72_state::rtype2_get_tile_info)
{
m82_m84_get_tile_info(tileinfo,tile_index,m_videoram2,1);
int pri;
// word 0 word 1
// tttt tttt tttt tttt ---- ---z zff- pppp
// f = flips, t = tilenum, z = pri, p = palette
tile_index *= 2;
const u16 code = m_videoram[N][tile_index];
const u16 attr = m_videoram[N][tile_index+1];
if (attr & 0x0100) pri = 2;
else if (attr & 0x0080) pri = 1;
else pri = 0;
/* (m_videoram[N][tile_index+2] & 0x10) is used by majtitle on the green, but it's not clear for what */
/* (m_videoram[N][tile_index+3] & 0xfe) are used as well */
SET_TILE_INFO_MEMBER(1,
code,
attr & 0x000f,
TILE_FLIPYX((attr & 0x0060) >> 5));
tileinfo.group = pri;
}
TILE_GET_INFO_MEMBER(m72_state::rtype2_get_fg_tile_info)
{
m82_m84_get_tile_info(tileinfo,tile_index,m_videoram1,1);
}
/***************************************************************************
@ -102,11 +88,8 @@ void m72_state::register_savestate()
{
save_item(NAME(m_raster_irq_position));
save_item(NAME(m_video_off));
save_item(NAME(m_scrollx1));
save_item(NAME(m_scrolly1));
save_item(NAME(m_scrollx2));
save_item(NAME(m_scrolly2));
save_pointer(NAME(m_buffered_spriteram), m_spriteram.bytes()/2);
save_item(NAME(m_scrollx));
save_item(NAME(m_scrolly));
}
@ -115,8 +98,6 @@ VIDEO_START_MEMBER(m72_state,m72)
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(m72_state::get_bg_tile_info),this),TILEMAP_SCAN_ROWS,8,8,64,64);
m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(m72_state::get_fg_tile_info),this),TILEMAP_SCAN_ROWS,8,8,64,64);
m_buffered_spriteram = std::make_unique<uint16_t[]>(m_spriteram.bytes()/2);
m_fg_tilemap->set_transmask(0,0xffff,0x0001);
m_fg_tilemap->set_transmask(1,0x00ff,0xff01);
m_fg_tilemap->set_transmask(2,0x0001,0xffff);
@ -129,7 +110,7 @@ VIDEO_START_MEMBER(m72_state,m72)
//m_bg_tilemap->set_transmask(2,0x001f,0xffe0); // needed for nspiritj japan warning to look correct
// not sure what is needed to be able to see the imgfghto warning message
memset(m_buffered_spriteram.get(),0,m_spriteram.bytes());
memset(m_spriteram->buffer(),0,m_spriteram->bytes());
m_fg_tilemap->set_scrolldx(0,0);
m_fg_tilemap->set_scrolldy(-128,-128);
@ -183,11 +164,11 @@ TILEMAP_MAPPER_MEMBER(m72_state::m82_scan_rows)
VIDEO_START_MEMBER(m72_state,m82)
{
m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(m72_state::rtype2_get_fg_tile_info),this),TILEMAP_SCAN_ROWS,8,8,64,64);
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(m72_state::rtype2_get_bg_tile_info),this),TILEMAP_SCAN_ROWS,8,8,64,64);
m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(m72_state::rtype2_get_tile_info<0>),this),TILEMAP_SCAN_ROWS,8,8,64,64);
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(m72_state::rtype2_get_tile_info<1>),this),TILEMAP_SCAN_ROWS,8,8,64,64);
// The tilemap can be 256x64, but seems to be used at 128x64 (scroll wraparound).
// The layout ramains 256x64, the right half is just not displayed.
m_bg_tilemap_large = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(m72_state::rtype2_get_bg_tile_info),this),tilemap_mapper_delegate(FUNC(m72_state::m82_scan_rows),this),8,8,128,64);
m_bg_tilemap_large = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(m72_state::rtype2_get_tile_info<1>),this),tilemap_mapper_delegate(FUNC(m72_state::m82_scan_rows),this),8,8,128,64);
m_fg_tilemap->set_transmask(0,0xffff,0x0001);
m_fg_tilemap->set_transmask(1,0x00ff,0xff01);
@ -210,8 +191,7 @@ VIDEO_START_MEMBER(m72_state,m82)
m_bg_tilemap_large->set_scrolldx(4,0);
m_bg_tilemap_large->set_scrolldy(-128,-128);
m_buffered_spriteram = std::make_unique<uint16_t[]>(m_spriteram.bytes()/2);
memset(m_buffered_spriteram.get(),0,m_spriteram.bytes());
memset(m_spriteram->buffer(),0,m_spriteram->bytes());
register_savestate();
save_item(NAME(m_m82_rowscroll));
@ -222,10 +202,8 @@ VIDEO_START_MEMBER(m72_state,m82)
// M84
VIDEO_START_MEMBER(m72_state,rtype2)
{
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(m72_state::rtype2_get_bg_tile_info),this),TILEMAP_SCAN_ROWS,8,8,64,64);
m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(m72_state::rtype2_get_fg_tile_info),this),TILEMAP_SCAN_ROWS,8,8,64,64);
m_buffered_spriteram = std::make_unique<uint16_t[]>(m_spriteram.bytes()/2);
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(m72_state::rtype2_get_tile_info<1>),this),TILEMAP_SCAN_ROWS,8,8,64,64);
m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(m72_state::rtype2_get_tile_info<0>),this),TILEMAP_SCAN_ROWS,8,8,64,64);
m_fg_tilemap->set_transmask(0,0xffff,0x0001);
m_fg_tilemap->set_transmask(1,0x00ff,0xff01);
@ -235,7 +213,7 @@ VIDEO_START_MEMBER(m72_state,rtype2)
m_bg_tilemap->set_transmask(1,0x00ff,0xff00);
m_bg_tilemap->set_transmask(2,0x0001,0xfffe);
memset(m_buffered_spriteram.get(),0,m_spriteram.bytes());
memset(m_spriteram->buffer(),0,m_spriteram->bytes());
m_fg_tilemap->set_scrolldx(4,0);
m_fg_tilemap->set_scrolldy(-128,16);
@ -276,62 +254,15 @@ VIDEO_START_MEMBER(m72_state,poundfor)
***************************************************************************/
READ16_MEMBER(m72_state::palette1_r)
void m72_state::videoram1_w(offs_t offset, u16 data, u16 mem_mask)
{
/* A9 isn't connected, so 0x200-0x3ff mirrors 0x000-0x1ff etc. */
offset &= ~0x100;
return m_generic_paletteram_16[offset] | 0xffe0; /* only D0-D4 are connected */
}
READ16_MEMBER(m72_state::palette2_r)
{
/* A9 isn't connected, so 0x200-0x3ff mirrors 0x000-0x1ff etc. */
offset &= ~0x100;
return m_generic_paletteram2_16[offset] | 0xffe0; /* only D0-D4 are connected */
}
inline void m72_state::changecolor(int color,int r,int g,int b)
{
m_palette->set_pen_color(color,pal5bit(r),pal5bit(g),pal5bit(b));
}
WRITE16_MEMBER(m72_state::palette1_w)
{
/* A9 isn't connected, so 0x200-0x3ff mirrors 0x000-0x1ff etc. */
offset &= ~0x100;
COMBINE_DATA(&m_generic_paletteram_16[offset]);
offset &= 0x0ff;
changecolor(offset,
m_generic_paletteram_16[offset + 0x000],
m_generic_paletteram_16[offset + 0x200],
m_generic_paletteram_16[offset + 0x400]);
}
WRITE16_MEMBER(m72_state::palette2_w)
{
/* A9 isn't connected, so 0x200-0x3ff mirrors 0x000-0x1ff etc. */
offset &= ~0x100;
COMBINE_DATA(&m_generic_paletteram2_16[offset]);
offset &= 0x0ff;
changecolor(offset + 256,
m_generic_paletteram2_16[offset + 0x000],
m_generic_paletteram2_16[offset + 0x200],
m_generic_paletteram2_16[offset + 0x400]);
}
WRITE16_MEMBER(m72_state::videoram1_w)
{
COMBINE_DATA(&m_videoram1[offset]);
COMBINE_DATA(&m_videoram[0][offset]);
m_fg_tilemap->mark_tile_dirty(offset/2);
}
WRITE16_MEMBER(m72_state::videoram2_w)
void m72_state::videoram2_w(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_videoram2[offset]);
COMBINE_DATA(&m_videoram[1][offset]);
m_bg_tilemap->mark_tile_dirty(offset/2);
// m82 has selectable tilemap size
@ -340,7 +271,7 @@ WRITE16_MEMBER(m72_state::videoram2_w)
}
WRITE16_MEMBER(m72_state::irq_line_w)
void m72_state::irq_line_w(u16 data)
{
// KNA70H015(11): ISET
m_raster_irq_position = data & 0x1ff;
@ -353,38 +284,13 @@ WRITE16_MEMBER(m72_state::irq_line_w)
m_maincpu->set_input_line(NEC_INPUT_LINE_INTP2, CLEAR_LINE);
}
WRITE16_MEMBER(m72_state::scrollx1_w)
void m72_state::dmaon_w(u8 data)
{
m_screen->update_partial(m_screen->vpos());
COMBINE_DATA(&m_scrollx1);
}
WRITE16_MEMBER(m72_state::scrollx2_w)
{
m_screen->update_partial(m_screen->vpos());
COMBINE_DATA(&m_scrollx2);
}
WRITE16_MEMBER(m72_state::scrolly1_w)
{
m_screen->update_partial(m_screen->vpos());
COMBINE_DATA(&m_scrolly1);
}
WRITE16_MEMBER(m72_state::scrolly2_w)
{
m_screen->update_partial(m_screen->vpos());
COMBINE_DATA(&m_scrolly2);
}
WRITE16_MEMBER(m72_state::dmaon_w)
{
if (ACCESSING_BITS_0_7)
memcpy(m_buffered_spriteram.get(), m_spriteram, m_spriteram.bytes());
m_spriteram->copy();
}
WRITE8_MEMBER(m72_state::port02_w)
void m72_state::port02_w(u8 data)
{
if (data & 0xe0) logerror("write %02x to port 02\n",data);
@ -393,7 +299,7 @@ WRITE8_MEMBER(m72_state::port02_w)
machine().bookkeeping().coin_counter_w(1,data & 0x02);
/* bit 2 is flip screen (handled both by software and hardware) */
flip_screen_set(((data & 0x04) >> 2) ^ ((~ioport("DSW")->read() >> 8) & 1));
flip_screen_set(((data & 0x04) >> 2) ^ ((~m_io_dsw->read() >> 8) & 1));
/* bit 3 is display disable */
m_video_off = data & 0x08;
@ -407,7 +313,7 @@ WRITE8_MEMBER(m72_state::port02_w)
/* bit 5 = "bank"? */
}
WRITE8_MEMBER(m72_state::rtype2_port02_w)
void m72_state::rtype2_port02_w(u8 data)
{
if (data & 0xe0) logerror("write %02x to port 02\n",data);
@ -416,7 +322,7 @@ WRITE8_MEMBER(m72_state::rtype2_port02_w)
machine().bookkeeping().coin_counter_w(1,data & 0x02);
/* bit 2 is flip screen (handled both by software and hardware) */
flip_screen_set(((data & 0x04) >> 2) ^ ((~ioport("DSW")->read() >> 8) & 1));
flip_screen_set(((data & 0x04) >> 2) ^ ((~m_io_dsw->read() >> 8) & 1));
/* bit 3 is display disable */
m_video_off = data & 0x08;
@ -424,7 +330,7 @@ WRITE8_MEMBER(m72_state::rtype2_port02_w)
/* other bits unknown */
}
WRITE8_MEMBER(m72_state::poundfor_port02_w)
void m72_state::poundfor_port02_w(u8 data)
{
// bit 5 resets both uPD4701A?
m_upd4701[0]->resetx_w(BIT(data, 5));
@ -432,13 +338,13 @@ WRITE8_MEMBER(m72_state::poundfor_port02_w)
m_upd4701[1]->resetx_w(BIT(data, 5));
m_upd4701[1]->resety_w(BIT(data, 5));
rtype2_port02_w(space, 0, data & 0xbf);
rtype2_port02_w(data & 0xbf);
}
/* the following is mostly a kludge. This register seems to be used for something else */
WRITE16_MEMBER(m72_state::m82_gfx_ctrl_w)
void m72_state::m82_gfx_ctrl_w(offs_t offset, u16 data, u16 mem_mask)
{
if (ACCESSING_BITS_8_15)
{
@ -449,7 +355,7 @@ WRITE16_MEMBER(m72_state::m82_gfx_ctrl_w)
}
WRITE16_MEMBER(m72_state::m82_tm_ctrl_w)
void m72_state::m82_tm_ctrl_w(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_m82_tmcontrol);
// printf("tmcontrol %04x\n", m_m82_tmcontrol);
@ -464,24 +370,20 @@ WRITE16_MEMBER(m72_state::m82_tm_ctrl_w)
void m72_state::draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect)
{
uint16_t *spriteram = m_buffered_spriteram.get();
int offs;
u16 *spriteram = m_spriteram->buffer();
int offs = 0;
offs = 0;
while (offs < m_spriteram.bytes()/2)
while (offs < m_spriteram->bytes()/2)
{
int code,color,sx,sy,flipx,flipy,w,h,x,y;
const int code = spriteram[offs+1];
const u32 color = spriteram[offs+2] & 0x0f;
int sx = -256+(spriteram[offs+3] & 0x3ff);
int sy = 384-(spriteram[offs+0] & 0x1ff);
int flipx = spriteram[offs+2] & 0x0800;
int flipy = spriteram[offs+2] & 0x0400;
code = spriteram[offs+1];
color = spriteram[offs+2] & 0x0f;
sx = -256+(spriteram[offs+3] & 0x3ff);
sy = 384-(spriteram[offs+0] & 0x1ff);
flipx = spriteram[offs+2] & 0x0800;
flipy = spriteram[offs+2] & 0x0400;
w = 1 << ((spriteram[offs+2] & 0xc000) >> 14);
h = 1 << ((spriteram[offs+2] & 0x3000) >> 12);
const int w = 1 << ((spriteram[offs+2] & 0xc000) >> 14);
const int h = 1 << ((spriteram[offs+2] & 0x3000) >> 12);
sy -= 16 * h;
if (flip_screen())
@ -492,9 +394,9 @@ void m72_state::draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect)
flipy = !flipy;
}
for (x = 0;x < w;x++)
for (int x = 0; x < w; x++)
{
for (y = 0;y < h;y++)
for (int y = 0; y < h; y++)
{
int c = code;
@ -517,23 +419,19 @@ void m72_state::draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect)
void m72_state::majtitle_draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect)
{
uint16_t *spriteram16_2 = m_spriteram2;
int offs;
u16 *spriteram16_2 = m_spriteram2;
for (offs = 0;offs < m_spriteram.bytes();offs += 4)
for (int offs = 0; offs < m_spriteram2.bytes(); offs += 4)
{
int code,color,sx,sy,flipx,flipy,w,h,x,y;
const int code = spriteram16_2[offs+1];
const u32 color = spriteram16_2[offs+2] & 0x0f;
int sx = -256+(spriteram16_2[offs+3] & 0x3ff);
int sy = 384-(spriteram16_2[offs+0] & 0x1ff);
int flipx = spriteram16_2[offs+2] & 0x0800;
int flipy = spriteram16_2[offs+2] & 0x0400;
code = spriteram16_2[offs+1];
color = spriteram16_2[offs+2] & 0x0f;
sx = -256+(spriteram16_2[offs+3] & 0x3ff);
sy = 384-(spriteram16_2[offs+0] & 0x1ff);
flipx = spriteram16_2[offs+2] & 0x0800;
flipy = spriteram16_2[offs+2] & 0x0400;
w = 1;// << ((spriteram16_2[offs+2] & 0xc000) >> 14);
h = 1 << ((spriteram16_2[offs+2] & 0x3000) >> 12);
const int w = 1;// << ((spriteram16_2[offs+2] & 0xc000) >> 14);
const int h = 1 << ((spriteram16_2[offs+2] & 0x3000) >> 12);
sy -= 16 * h;
if (flip_screen())
@ -544,9 +442,9 @@ void m72_state::majtitle_draw_sprites(bitmap_ind16 &bitmap,const rectangle &clip
flipy = !flipy;
}
for (x = 0;x < w;x++)
for (int x = 0; x < w; x++)
{
for (y = 0;y < h;y++)
for (int y = 0; y < h; y++)
{
int c = code;
@ -565,7 +463,7 @@ void m72_state::majtitle_draw_sprites(bitmap_ind16 &bitmap,const rectangle &clip
}
}
uint32_t m72_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
u32 m72_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
if (m_video_off)
{
@ -573,11 +471,11 @@ uint32_t m72_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, c
return 0;
}
m_fg_tilemap->set_scrollx(0,m_scrollx1);
m_fg_tilemap->set_scrolly(0,m_scrolly1);
m_fg_tilemap->set_scrollx(0,m_scrollx[0]);
m_fg_tilemap->set_scrolly(0,m_scrolly[0]);
m_bg_tilemap->set_scrollx(0,m_scrollx2);
m_bg_tilemap->set_scrolly(0,m_scrolly2);
m_bg_tilemap->set_scrollx(0,m_scrollx[1]);
m_bg_tilemap->set_scrolly(0,m_scrolly[1]);
m_bg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1,0);
m_fg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1,0);
@ -587,11 +485,11 @@ uint32_t m72_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, c
return 0;
}
uint32_t m72_state::screen_update_m81(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
u32 m72_state::screen_update_m81(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
// on M81 the FG data always comes from the Ax roms
// the source of the BG data however depends on Jumper J3
int J3 = m_m81_b_b_j3->read();
const int J3 = m_m81_b_b_j3->read();
if (J3 == 0) m_bg_source = 1;
else m_bg_source = 2;
@ -599,39 +497,36 @@ uint32_t m72_state::screen_update_m81(screen_device &screen, bitmap_ind16 &bitma
}
uint32_t m72_state::screen_update_m82(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
u32 m72_state::screen_update_m82(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
int i;
tilemap_t* tm;
if (m_m82_tmcontrol & 0x40) tm = m_bg_tilemap_large;
else tm = m_bg_tilemap;
if (m_video_off)
{
bitmap.fill(m_palette->black_pen(), cliprect);
return 0;
}
m_fg_tilemap->set_scrollx(0,m_scrollx1);
m_fg_tilemap->set_scrolly(0,m_scrolly1);
m_fg_tilemap->set_scrollx(0,m_scrollx[0]);
m_fg_tilemap->set_scrolly(0,m_scrolly[0]);
if (m_m82_rowscroll)
{
tm->set_scroll_rows(512);
for (i = 0;i < 512;i++)
tm->set_scrollx((i+m_scrolly2)&0x1ff,
for (int i = 0; i < 512; i++)
tm->set_scrollx((i+m_scrolly[1])&0x1ff,
256 + m_m82_rowscrollram[i]);
}
else
{
tm->set_scroll_rows(1);
tm->set_scrollx(0,256 + m_scrollx2);
tm->set_scrollx(0,256 + m_scrollx[1]);
}
tm->set_scrolly(0,m_scrolly2);
tm->set_scrolly(0,m_scrolly[1]);
tm->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1, 0);
m_fg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1,0);
majtitle_draw_sprites(bitmap,cliprect);