konami/spy.cpp: Cleaned up code: (#13311)

* Use a memory view for the RAM overlay.
* Reduced the sound CPU ROM region size to match the area mapped in the CPU address space.
* Added comments about unknown writes in address map.
This commit is contained in:
cam900 2025-02-07 00:23:49 +09:00 committed by GitHub
parent 9d21990b24
commit 13d5eed517
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -40,7 +40,7 @@
#include "speaker.h" #include "speaker.h"
#include "multibyte.h" #include "multibyte.h"
#include <algorithm>
namespace { namespace {
@ -49,61 +49,58 @@ class spy_state : public driver_device
public: public:
spy_state(const machine_config &mconfig, device_type type, const char *tag) : spy_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag), driver_device(mconfig, type, tag),
m_rombank(*this, "rombank"),
m_ram(*this, "ram"),
m_maincpu(*this, "maincpu"), m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu"), m_audiocpu(*this, "audiocpu"),
m_k007232_1(*this, "k007232_1"), m_k007232(*this, "k007232_%u", 1U),
m_k007232_2(*this, "k007232_2"),
m_k052109(*this, "k052109"), m_k052109(*this, "k052109"),
m_k051960(*this, "k051960"), m_k051960(*this, "k051960"),
m_palette(*this, "palette") m_palette(*this, "palette"),
m_pmcram(*this, "pmcram"),
m_rombank(*this, "rombank"),
m_ram_view(*this, "ram_view")
{ } { }
void spy(machine_config &config); void spy(machine_config &config);
protected:
virtual void machine_start() override ATTR_COLD;
virtual void machine_reset() override ATTR_COLD;
private: private:
/* memory pointers */
required_memory_bank m_rombank;
required_shared_ptr<uint8_t> m_ram;
uint8_t m_pmcram[0x800]{};
std::vector<uint8_t> m_paletteram{};
/* misc */
int m_rambank = 0;
int m_pmcbank = 0;
uint8_t m_pmcpc = 0;
bool m_video_enable = false;
int m_old_3f90 = 0;
/* devices */ /* devices */
required_device<cpu_device> m_maincpu; required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu; required_device<cpu_device> m_audiocpu;
required_device<k007232_device> m_k007232_1; required_device_array<k007232_device, 2> m_k007232;
required_device<k007232_device> m_k007232_2;
required_device<k052109_device> m_k052109; required_device<k052109_device> m_k052109;
required_device<k051960_device> m_k051960; required_device<k051960_device> m_k051960;
required_device<palette_device> m_palette; required_device<palette_device> m_palette;
uint8_t spy_bankedram1_r(offs_t offset); /* memory pointers */
void spy_bankedram1_w(offs_t offset, uint8_t data); required_shared_ptr<uint8_t> m_pmcram;
required_memory_bank m_rombank;
memory_view m_ram_view;
/* misc */
uint8_t m_rambank = 0;
bool m_pmcbank = false;
uint8_t m_pmcpc = 0;
bool m_video_enable = false;
int32_t m_old_3f90 = -1;
void bankswitch_w(uint8_t data); void bankswitch_w(uint8_t data);
void spy_3f90_w(uint8_t data); void spy_3f90_w(uint8_t data);
void spy_sh_irqtrigger_w(uint8_t data); void sh_irqtrigger_w(uint8_t data);
void sound_bank_w(uint8_t data); void sound_bank_w(uint8_t data);
uint8_t k052109_051960_r(offs_t offset); uint8_t k052109_051960_r(offs_t offset);
void k052109_051960_w(offs_t offset, uint8_t data); void k052109_051960_w(offs_t offset, uint8_t data);
virtual void machine_start() override ATTR_COLD;
virtual void machine_reset() override ATTR_COLD;
uint32_t screen_update_spy(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); uint32_t screen_update_spy(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void pmc_run(); void pmc_run();
void volume_callback0(uint8_t data); template <unsigned Chip> void volume_callback(uint8_t data);
void volume_callback1(uint8_t data);
K052109_CB_MEMBER(tile_callback); K052109_CB_MEMBER(tile_callback);
K051960_CB_MEMBER(sprite_callback); K051960_CB_MEMBER(sprite_callback);
void spy_map(address_map &map) ATTR_COLD; void main_map(address_map &map) ATTR_COLD;
void spy_sound_map(address_map &map) ATTR_COLD; void sound_map(address_map &map) ATTR_COLD;
}; };
@ -168,51 +165,6 @@ uint32_t spy_state::screen_update_spy(screen_device &screen, bitmap_ind16 &bitma
return 0; return 0;
} }
uint8_t spy_state::spy_bankedram1_r(offs_t offset)
{
if (m_rambank & 1)
{
return m_paletteram[offset];
}
else if (m_rambank & 2)
{
if (m_pmcbank)
{
//logerror("%04x read pmcram %04x\n",m_maincpu->pc(), offset);
return m_pmcram[offset];
}
else
{
return 0; // PMC internal RAM can't be read back
}
}
else
return m_ram[offset];
}
void spy_state::spy_bankedram1_w(offs_t offset, uint8_t data)
{
if (m_rambank & 1)
{
m_palette->write8(offset,data);
}
else if (m_rambank & 2)
{
if (m_pmcbank)
{
//logerror("%04x pmcram %04x = %02x\n", m_maincpu->pc(), offset, data);
m_pmcram[offset] = data;
}
else
{
// Set initial PMC PC
m_pmcpc = data & 0x3f;
}
}
else
m_ram[offset] = data;
}
/* /*
This is the 052591 PMC code loaded at startup, it contains both projection and collision check programs. This is the 052591 PMC code loaded at startup, it contains both projection and collision check programs.
See https://github.com/furrtek/SiliconRE/tree/master/Konami/052591 for details See https://github.com/furrtek/SiliconRE/tree/master/Konami/052591 for details
@ -292,12 +244,12 @@ Collision check routine:
void spy_state::bankswitch_w(uint8_t data) void spy_state::bankswitch_w(uint8_t data)
{ {
/* bit 0 = RAM bank */ /* bit 0 = RAM bank */
if ((data & 1) == 0) if (BIT(~data, 0))
popmessage("bankswitch RAM bank 0"); popmessage("bankswitch RAM bank 0");
/* bit 1-4 = ROM bank */ /* bit 1-4 = ROM bank */
int bank; int bank;
if (data & 0x10) if (BIT(data, 4))
bank = 8 + ((data & 0x06) >> 1); bank = 8 + ((data & 0x06) >> 1);
else else
bank = (data & 0x0e) >> 1; bank = (data & 0x0e) >> 1;
@ -314,10 +266,8 @@ void spy_state::pmc_run()
{ {
// Projection program // Projection program
// Basically divides a list of 16-bit words by a constant, results are 8.8 fixed point // Basically divides a list of 16-bit words by a constant, results are 8.8 fixed point
uint16_t loopend, nearplane; uint16_t loopend = get_u16be(&m_pmcram[0]);
uint16_t nearplane = get_u16be(&m_pmcram[2]);
loopend = get_u16be(&m_pmcram[0]);
nearplane = get_u16be(&m_pmcram[2]);
// fail safe // fail safe
if (loopend > MAX_SPRITES) if (loopend > MAX_SPRITES)
@ -430,23 +380,27 @@ void spy_state::spy_3f90_w(uint8_t data)
********************************************************************/ ********************************************************************/
/* bits 0/1 = coin counters */ /* bits 0/1 = coin counters */
machine().bookkeeping().coin_counter_w(0, data & 0x01); machine().bookkeeping().coin_counter_w(0, BIT(data, 0));
machine().bookkeeping().coin_counter_w(1, data & 0x02); machine().bookkeeping().coin_counter_w(1, BIT(data, 1));
/* bit 2 = enable char ROM reading through the video RAM */ /* bit 2 = enable char ROM reading through the video RAM */
m_k052109->set_rmrd_line((data & 0x04) ? ASSERT_LINE : CLEAR_LINE); m_k052109->set_rmrd_line(BIT(data, 2));
/* bit 3 = disable video */ /* bit 3 = disable video */
m_video_enable = !(data & 0x08); m_video_enable = BIT(~data, 3);
/* bit 4 = read RAM at 0000 (if set) else read color palette RAM */ /* bit 4 = read RAM at 0000 (if set) else read color palette RAM */
/* bit 5 = PMCBK */ /* bit 5 = PMCBK */
m_rambank = (data & 0x30) >> 4; m_rambank = (data & 0x30) >> 4;
/* bit 7 = PMC-BK */ /* bit 7 = PMC-BK */
m_pmcbank = (data & 0x80) >> 7; m_pmcbank = BIT(data, 7);
if (m_rambank == 0)
m_ram_view.disable();
else
m_ram_view.select(BIT(m_rambank, 0) ? 0 : (m_pmcbank ? 2 : 1));
/* bit 6 = PMC-START */ /* bit 6 = PMC-START */
if ((data & 0x40) && !(m_old_3f90 & 0x40)) if (BIT(data, 6) && BIT(~m_old_3f90, 6))
{ {
pmc_run(); pmc_run();
m_maincpu->set_input_line(M6809_FIRQ_LINE, HOLD_LINE); m_maincpu->set_input_line(M6809_FIRQ_LINE, HOLD_LINE);
@ -456,15 +410,15 @@ void spy_state::spy_3f90_w(uint8_t data)
} }
void spy_state::spy_sh_irqtrigger_w(uint8_t data) void spy_state::sh_irqtrigger_w(uint8_t data)
{ {
m_audiocpu->set_input_line_and_vector(0, HOLD_LINE, 0xff); // Z80 m_audiocpu->set_input_line_and_vector(0, HOLD_LINE, 0xff); // Z80
} }
void spy_state::sound_bank_w(uint8_t data) void spy_state::sound_bank_w(uint8_t data)
{ {
m_k007232_1->set_bank(BIT(data, 0, 2), BIT(data, 2, 2)); m_k007232[0]->set_bank(BIT(data, 0, 2), BIT(data, 2, 2));
m_k007232_2->set_bank(BIT(data, 4, 2), BIT(data, 6, 2)); m_k007232[1]->set_bank(BIT(data, 4, 2), BIT(data, 6, 2));
} }
@ -493,32 +447,38 @@ void spy_state::k052109_051960_w(offs_t offset, uint8_t data)
m_k051960->k051960_w(offset - 0x3c00, data); m_k051960->k051960_w(offset - 0x3c00, data);
} }
void spy_state::spy_map(address_map &map) void spy_state::main_map(address_map &map)
{ {
map(0x0000, 0x07ff).rw(FUNC(spy_state::spy_bankedram1_r), FUNC(spy_state::spy_bankedram1_w)).share("ram"); map(0x0000, 0x1aff).ram();
map(0x0800, 0x1aff).ram(); map(0x0000, 0x07ff).view(m_ram_view);
m_ram_view[0](0x0000, 0x07ff).ram().w(m_palette, FUNC(palette_device::write8)).share("palette");
// PMC internal RAM can't be read back
m_ram_view[1](0x0000, 0x07ff).lrw8(NAME([]() { return 0; }), NAME([this](uint8_t data) { m_pmcpc = data & 0x3f; }));
m_ram_view[2](0x0000, 0x07ff).ram().share(m_pmcram);
map(0x2000, 0x5fff).rw(FUNC(spy_state::k052109_051960_r), FUNC(spy_state::k052109_051960_w)); map(0x2000, 0x5fff).rw(FUNC(spy_state::k052109_051960_r), FUNC(spy_state::k052109_051960_w));
map(0x3f80, 0x3f80).w(FUNC(spy_state::bankswitch_w)); map(0x3f80, 0x3f80).w(FUNC(spy_state::bankswitch_w));
map(0x3f90, 0x3f90).w(FUNC(spy_state::spy_3f90_w)); map(0x3f90, 0x3f90).w(FUNC(spy_state::spy_3f90_w));
map(0x3fa0, 0x3fa0).w("watchdog", FUNC(watchdog_timer_device::reset_w)); map(0x3fa0, 0x3fa0).w("watchdog", FUNC(watchdog_timer_device::reset_w));
map(0x3fb0, 0x3fb0).w("soundlatch", FUNC(generic_latch_8_device::write)); map(0x3fb0, 0x3fb0).w("soundlatch", FUNC(generic_latch_8_device::write));
map(0x3fc0, 0x3fc0).w(FUNC(spy_state::spy_sh_irqtrigger_w)); map(0x3fc0, 0x3fc0).w(FUNC(spy_state::sh_irqtrigger_w));
map(0x3fd0, 0x3fd0).portr("SYSTEM"); map(0x3fd0, 0x3fd0).portr("SYSTEM");
map(0x3fd1, 0x3fd1).portr("P1"); map(0x3fd1, 0x3fd1).portr("P1");
map(0x3fd2, 0x3fd2).portr("P2"); map(0x3fd2, 0x3fd2).portr("P2");
map(0x3fd3, 0x3fd3).portr("DSW1"); map(0x3fd3, 0x3fd3).portr("DSW1");
map(0x3fe0, 0x3fe0).portr("DSW2"); map(0x3fe0, 0x3fe0).portr("DSW2");
//map(0x7c00, 0x7c00) writes 0x12, unknown usage
//map(0x7f80, 0x7f80) writes 0x01, unknown usage
map(0x6000, 0x7fff).bankr(m_rombank); map(0x6000, 0x7fff).bankr(m_rombank);
map(0x8000, 0xffff).rom(); map(0x8000, 0xffff).rom();
} }
void spy_state::spy_sound_map(address_map &map) void spy_state::sound_map(address_map &map)
{ {
map(0x0000, 0x7fff).rom(); map(0x0000, 0x7fff).rom();
map(0x8000, 0x87ff).ram(); map(0x8000, 0x87ff).ram();
map(0x9000, 0x9000).w(FUNC(spy_state::sound_bank_w)); map(0x9000, 0x9000).w(FUNC(spy_state::sound_bank_w));
map(0xa000, 0xa00d).rw(m_k007232_1, FUNC(k007232_device::read), FUNC(k007232_device::write)); map(0xa000, 0xa00d).rw(m_k007232[0], FUNC(k007232_device::read), FUNC(k007232_device::write));
map(0xb000, 0xb00d).rw(m_k007232_2, FUNC(k007232_device::read), FUNC(k007232_device::write)); map(0xb000, 0xb00d).rw(m_k007232[1], FUNC(k007232_device::read), FUNC(k007232_device::write));
map(0xc000, 0xc001).rw("ymsnd", FUNC(ym3812_device::read), FUNC(ym3812_device::write)); map(0xc000, 0xc001).rw("ymsnd", FUNC(ym3812_device::read), FUNC(ym3812_device::write));
map(0xd000, 0xd000).r("soundlatch", FUNC(generic_latch_8_device::read)); map(0xd000, 0xd000).r("soundlatch", FUNC(generic_latch_8_device::read));
} }
@ -572,17 +532,11 @@ static INPUT_PORTS_START( spy )
INPUT_PORTS_END INPUT_PORTS_END
template <unsigned Chip>
void spy_state::volume_callback0(uint8_t data) void spy_state::volume_callback(uint8_t data)
{ {
m_k007232_1->set_volume(0, (data >> 4) * 0x11, 0); m_k007232[Chip]->set_volume(0, (data >> 4) * 0x11, 0);
m_k007232_1->set_volume(1, 0, (data & 0x0f) * 0x11); m_k007232[Chip]->set_volume(1, 0, (data & 0x0f) * 0x11);
}
void spy_state::volume_callback1(uint8_t data)
{
m_k007232_2->set_volume(0, (data >> 4) * 0x11, 0);
m_k007232_2->set_volume(1, 0, (data & 0x0f) * 0x11);
} }
@ -592,37 +546,33 @@ void spy_state::machine_start()
m_rombank->configure_entries(0, 12, &ROM[0x10000], 0x2000); m_rombank->configure_entries(0, 12, &ROM[0x10000], 0x2000);
m_paletteram.resize(0x800); std::fill_n(&m_pmcram[0], m_pmcram.length(), 0);
m_palette->basemem().set(m_paletteram, ENDIANNESS_BIG, 2);
memset(m_pmcram, 0, sizeof(m_pmcram));
save_item(NAME(m_paletteram));
save_item(NAME(m_rambank)); save_item(NAME(m_rambank));
save_item(NAME(m_pmcbank)); save_item(NAME(m_pmcbank));
save_item(NAME(m_pmcpc)); save_item(NAME(m_pmcpc));
save_item(NAME(m_video_enable)); save_item(NAME(m_video_enable));
save_item(NAME(m_old_3f90)); save_item(NAME(m_old_3f90));
save_item(NAME(m_pmcram));
} }
void spy_state::machine_reset() void spy_state::machine_reset()
{ {
m_rambank = 0; m_rambank = 0;
m_pmcbank = 0; m_pmcbank = false;
m_pmcpc = 0; m_pmcpc = 0;
m_video_enable = false; m_video_enable = false;
m_old_3f90 = -1; m_old_3f90 = -1;
m_ram_view.disable();
} }
void spy_state::spy(machine_config &config) void spy_state::spy(machine_config &config)
{ {
/* basic machine hardware */ /* basic machine hardware */
MC6809E(config, m_maincpu, XTAL(24'000'000) / 8); // 3 MHz? (divided by 051961) MC6809E(config, m_maincpu, XTAL(24'000'000) / 8); // 3 MHz? (divided by 051961)
m_maincpu->set_addrmap(AS_PROGRAM, &spy_state::spy_map); m_maincpu->set_addrmap(AS_PROGRAM, &spy_state::main_map);
Z80(config, m_audiocpu, XTAL(3'579'545)); Z80(config, m_audiocpu, XTAL(3'579'545));
m_audiocpu->set_addrmap(AS_PROGRAM, &spy_state::spy_sound_map); /* nmi by the sound chip */ m_audiocpu->set_addrmap(AS_PROGRAM, &spy_state::sound_map); /* nmi by the sound chip */
WATCHDOG_TIMER(config, "watchdog"); WATCHDOG_TIMER(config, "watchdog");
@ -658,15 +608,13 @@ void spy_state::spy(machine_config &config)
ymsnd.irq_handler().set_inputline(m_audiocpu, INPUT_LINE_NMI); ymsnd.irq_handler().set_inputline(m_audiocpu, INPUT_LINE_NMI);
ymsnd.add_route(ALL_OUTPUTS, "mono", 1.0); ymsnd.add_route(ALL_OUTPUTS, "mono", 1.0);
K007232(config, m_k007232_1, 3579545); K007232(config, m_k007232[0], 3579545);
m_k007232_1->port_write().set(FUNC(spy_state::volume_callback0)); m_k007232[0]->port_write().set(FUNC(spy_state::volume_callback<0>));
m_k007232_1->add_route(0, "mono", 0.20); m_k007232[0]->add_route(ALL_OUTPUTS, "mono", 0.20);
m_k007232_1->add_route(1, "mono", 0.20);
K007232(config, m_k007232_2, 3579545); K007232(config, m_k007232[1], 3579545);
m_k007232_2->port_write().set(FUNC(spy_state::volume_callback1)); m_k007232[1]->port_write().set(FUNC(spy_state::volume_callback<1>));
m_k007232_2->add_route(0, "mono", 0.20); m_k007232[1]->add_route(ALL_OUTPUTS, "mono", 0.20);
m_k007232_2->add_route(1, "mono", 0.20);
} }
@ -677,12 +625,12 @@ void spy_state::spy(machine_config &config)
***************************************************************************/ ***************************************************************************/
ROM_START( spy ) ROM_START( spy )
ROM_REGION( 0x28000, "maincpu", 0 ) /* code + banked roms + space for banked ram */ ROM_REGION( 0x28000, "maincpu", ROMREGION_ERASE00 ) /* code + banked roms + space for banked ram */
ROM_LOAD( "857n03.bin", 0x10000, 0x10000, CRC(97993b38) SHA1(0afd561bc85fcbfe30f2d16807424ceec7188ce7) ) ROM_LOAD( "857n03.bin", 0x10000, 0x10000, CRC(97993b38) SHA1(0afd561bc85fcbfe30f2d16807424ceec7188ce7) )
ROM_LOAD( "857n02.bin", 0x20000, 0x08000, CRC(31a97efe) SHA1(6c9ec3954e4d16634bf95835b8b404d3a6ef6e24) ) ROM_LOAD( "857n02.bin", 0x20000, 0x08000, CRC(31a97efe) SHA1(6c9ec3954e4d16634bf95835b8b404d3a6ef6e24) )
ROM_CONTINUE( 0x08000, 0x08000 ) ROM_CONTINUE( 0x08000, 0x08000 )
ROM_REGION( 0x10000, "audiocpu", 0 ) /* Z80 code */ ROM_REGION( 0x8000, "audiocpu", 0 ) /* Z80 code */
ROM_LOAD( "857d01.bin", 0x0000, 0x8000, CRC(aad4210f) SHA1(bb40b8673939b5ce51012606da86b4dcbfc52a57) ) ROM_LOAD( "857d01.bin", 0x0000, 0x8000, CRC(aad4210f) SHA1(bb40b8673939b5ce51012606da86b4dcbfc52a57) )
ROM_REGION( 0x080000, "k052109", 0 ) /* tiles */ ROM_REGION( 0x080000, "k052109", 0 ) /* tiles */
@ -704,12 +652,12 @@ ROM_START( spy )
ROM_END ROM_END
ROM_START( spyu ) ROM_START( spyu )
ROM_REGION( 0x28000, "maincpu", 0 ) /* code + banked roms + space for banked ram */ ROM_REGION( 0x28000, "maincpu", ROMREGION_ERASE00 ) /* code + banked roms + space for banked ram */
ROM_LOAD( "857m03.bin", 0x10000, 0x10000, CRC(3bd87fa4) SHA1(257371ef31c8adcdc04f46e989b7a2f3531c2ab1) ) ROM_LOAD( "857m03.bin", 0x10000, 0x10000, CRC(3bd87fa4) SHA1(257371ef31c8adcdc04f46e989b7a2f3531c2ab1) )
ROM_LOAD( "857m02.bin", 0x20000, 0x08000, CRC(306cc659) SHA1(91d150b8d320bf19c12bc46103ffdffacf4387c3) ) ROM_LOAD( "857m02.bin", 0x20000, 0x08000, CRC(306cc659) SHA1(91d150b8d320bf19c12bc46103ffdffacf4387c3) )
ROM_CONTINUE( 0x08000, 0x08000 ) ROM_CONTINUE( 0x08000, 0x08000 )
ROM_REGION( 0x10000, "audiocpu", 0 ) /* Z80 code */ ROM_REGION( 0x8000, "audiocpu", 0 ) /* Z80 code */
ROM_LOAD( "857d01.bin", 0x0000, 0x8000, CRC(aad4210f) SHA1(bb40b8673939b5ce51012606da86b4dcbfc52a57) ) ROM_LOAD( "857d01.bin", 0x0000, 0x8000, CRC(aad4210f) SHA1(bb40b8673939b5ce51012606da86b4dcbfc52a57) )
ROM_REGION( 0x080000, "k052109", 0 ) /* tiles */ ROM_REGION( 0x080000, "k052109", 0 ) /* tiles */