sub-class generalplus gpac800, better simulate bootstrap by copying initial code to location in rom header (#6040)

* subclassing CPU SoC type (nw)

* push along so they fail somewhere else (nw)

* fix logging, improve stability (nw)

* disable helper (nw)

* fix CRC on conyping (nw)
This commit is contained in:
David Haywood 2019-12-11 14:07:07 +00:00 committed by ajrhacker
parent 935431ab00
commit 22f745e0d5
5 changed files with 94 additions and 20 deletions

View File

@ -246,12 +246,14 @@ void unsp_12_device::execute_fxxx_101_group(uint16_t op)
return;
case 0xf144: case 0xf344: case 0xf544: case 0xf744: case 0xf944: case 0xfb44: case 0xfd44: case 0xff44:
logerror("fir_mov on\n");
unimplemented_opcode(op);
logerror("unimplemented: fir_mov on\n");
m_core->m_icount -= 1;
//unimplemented_opcode(op); // generalplus_gpac800 games do this on startup
return;
case 0xf145: case 0xf345: case 0xf545: case 0xf745: case 0xf945: case 0xfb45: case 0xfd45: case 0xff45:
logerror("unimplemented: fir_mov off\n");
m_core->m_icount -= 1;
//unimplemented_opcode(op); // generalplus_gpac800 games do this on startup
return;

View File

@ -26,6 +26,12 @@ sunplus_gcm394_device::sunplus_gcm394_device(const machine_config &mconfig, cons
{
}
DEFINE_DEVICE_TYPE(GPAC800, generalplus_gpac800_device, "gpac800", "GeneralPlus GPAC800 System-on-a-Chip")
generalplus_gpac800_device::generalplus_gpac800_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: sunplus_gcm394_base_device(mconfig, GCM394, tag, owner, clock, address_map_constructor(FUNC(generalplus_gpac800_device::gpac800_internal_map), this))
{
}
@ -146,7 +152,7 @@ READ16_MEMBER(sunplus_gcm394_base_device::unkarea_7810_r)
WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7810_w)
{
printf( "%s:sunplus_gcm394_base_device::unkarea_7810_w %04x\n", machine().describe_context().c_str(), data);
LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7810_w %04x\n", machine().describe_context(), data);
m_7810 = data;
}
@ -327,7 +333,7 @@ WRITE16_MEMBER(sunplus_gcm394_base_device::unk_w)
}
}
void sunplus_gcm394_base_device::internal_map(address_map &map)
void sunplus_gcm394_base_device::gcm394_internal_map(address_map &map)
{
map(0x000000, 0x006fff).ram();
map(0x007000, 0x007fff).rw(FUNC(sunplus_gcm394_base_device::unk_r), FUNC(sunplus_gcm394_base_device::unk_w)); // catch unhandled
@ -498,6 +504,18 @@ void sunplus_gcm394_base_device::internal_map(address_map &map)
map(0x007e00, 0x007fff).rw(m_spg_audio, FUNC(sunplus_gcm394_audio_device::audio_phase_r), FUNC(sunplus_gcm394_audio_device::audio_phase_w));
}
READ16_MEMBER(generalplus_gpac800_device::unkarea_7850_r)
{
return machine().rand();
}
void generalplus_gpac800_device::gpac800_internal_map(address_map& map)
{
sunplus_gcm394_base_device::gcm394_internal_map(map);
map(0x007850, 0x007850).r(FUNC(generalplus_gpac800_device::unkarea_7850_r));
}
void sunplus_gcm394_base_device::device_start()
{
unsp_20_device::device_start();

View File

@ -22,7 +22,12 @@ class sunplus_gcm394_base_device : public unsp_20_device, public device_mixer_in
{
public:
sunplus_gcm394_base_device(const machine_config& mconfig, device_type type, const char* tag, device_t* owner, uint32_t clock) :
unsp_20_device(mconfig, type, tag, owner, clock, address_map_constructor(FUNC(sunplus_gcm394_base_device::internal_map), this)),
sunplus_gcm394_base_device(mconfig, type, tag, owner, clock, address_map_constructor(FUNC(sunplus_gcm394_base_device::gcm394_internal_map), this))
{
}
sunplus_gcm394_base_device(const machine_config& mconfig, device_type type, const char* tag, device_t* owner, uint32_t clock, address_map_constructor internal) :
unsp_20_device(mconfig, type, tag, owner, clock, internal),
device_mixer_interface(mconfig, *this, 2),
m_screen(*this, finder_base::DUMMY_TAG),
m_spg_video(*this, "spgvideo"),
@ -59,7 +64,7 @@ protected:
virtual void device_start() override;
virtual void device_reset() override;
void internal_map(address_map &map);
void gcm394_internal_map(address_map &map);
required_device<screen_device> m_screen;
required_device<gcm394_video_device> m_spg_video;
@ -260,8 +265,8 @@ class sunplus_gcm394_device : public sunplus_gcm394_base_device
{
public:
template <typename T>
sunplus_gcm394_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&screen_tag)
: sunplus_gcm394_device(mconfig, tag, owner, clock)
sunplus_gcm394_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&screen_tag) :
sunplus_gcm394_device(mconfig, tag, owner, clock)
{
m_screen.set_tag(std::forward<T>(screen_tag));
}
@ -270,6 +275,28 @@ public:
};
class generalplus_gpac800_device : public sunplus_gcm394_base_device
{
public:
template <typename T>
generalplus_gpac800_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&screen_tag) :
generalplus_gpac800_device(mconfig, tag, owner, clock)
{
m_screen.set_tag(std::forward<T>(screen_tag));
}
generalplus_gpac800_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
void gpac800_internal_map(address_map &map);
private:
DECLARE_READ16_MEMBER(unkarea_7850_r);
};
DECLARE_DEVICE_TYPE(GCM394, sunplus_gcm394_device)
DECLARE_DEVICE_TYPE(GPAC800, generalplus_gpac800_device)
#endif // MAME_MACHINE_SUNPLUS_GCM394_H

View File

@ -527,7 +527,7 @@ ROM_END
ROM_START( conyping )
ROM_REGION( 0x800000, "maincpu", ROMREGION_ERASE00 )
ROM_LOAD16_WORD_SWAP( "tvvirtualpingpong.bin", 0x000000, 0x200000, CRC(11050f17) SHA1(929f0d8599b7380b5994684424bb91063c4f6569) )
ROM_LOAD16_WORD_SWAP( "tvvirtualpingpong.bin", 0x000000, 0x200000, CRC(6f5bf22e) SHA1(005e1580c4ab66db38682e797faebe8776eb58f7) )
// MCU (I/O?) read protected TODO: add NO_DUMP
ROM_END

View File

@ -34,7 +34,7 @@ public:
m_romregion(*this, "maincpu")
{
}
void base(machine_config &config);
@ -44,7 +44,7 @@ protected:
void switch_bank(uint32_t bank);
required_device<sunplus_gcm394_device> m_maincpu;
required_device<sunplus_gcm394_base_device> m_maincpu;
required_device<screen_device> m_screen;
optional_memory_bank m_bank;
@ -55,10 +55,6 @@ protected:
virtual void mem_map_4m(address_map &map);
required_region_ptr<uint16_t> m_romregion;
private:
uint32_t m_current_bank;
int m_numbanks;
DECLARE_READ16_MEMBER(porta_r);
DECLARE_READ16_MEMBER(portb_r);
@ -68,6 +64,12 @@ private:
virtual DECLARE_READ16_MEMBER(read_external_space);
virtual DECLARE_WRITE16_MEMBER(write_external_space);
private:
uint32_t m_current_bank;
int m_numbanks;
};
class wrlshunt_game_state : public gcm394_game_state
@ -229,6 +231,8 @@ void gcm394_game_state::base(machine_config &config)
m_maincpu->space_write_callback().set(FUNC(gcm394_game_state::write_external_space));
m_maincpu->set_irq_acknowledge_callback(m_maincpu, FUNC(sunplus_gcm394_base_device::irq_vector_cb));
m_maincpu->mapping_write_callback().set(FUNC(gcm394_game_state::mapping_w));
m_maincpu->add_route(ALL_OUTPUTS, "lspeaker", 0.5);
m_maincpu->add_route(ALL_OUTPUTS, "rspeaker", 0.5);
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_refresh_hz(60);
@ -239,9 +243,6 @@ void gcm394_game_state::base(machine_config &config)
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
m_maincpu->add_route(ALL_OUTPUTS, "lspeaker", 0.5);
m_maincpu->add_route(ALL_OUTPUTS, "rspeaker", 0.5);
}
READ16_MEMBER(wrlshunt_game_state::hunt_porta_r)
@ -276,7 +277,19 @@ void wrlshunt_game_state::wrlshunt(machine_config &config)
void generalplus_gpac800_game_state::generalplus_gpac800(machine_config &config)
{
gcm394_game_state::base(config);
GPAC800(config.replace(), m_maincpu, XTAL(27'000'000), m_screen);
m_maincpu->set_addrmap(AS_PROGRAM, &generalplus_gpac800_game_state::generalplus_gpac800_map);
m_maincpu->porta_in().set(FUNC(generalplus_gpac800_game_state::porta_r));
m_maincpu->portb_in().set(FUNC(generalplus_gpac800_game_state::portb_r));
m_maincpu->porta_out().set(FUNC(generalplus_gpac800_game_state::porta_w));
m_maincpu->space_read_callback().set(FUNC(generalplus_gpac800_game_state::read_external_space));
m_maincpu->space_write_callback().set(FUNC(generalplus_gpac800_game_state::write_external_space));
m_maincpu->set_irq_acknowledge_callback(m_maincpu, FUNC(sunplus_gcm394_base_device::irq_vector_cb));
m_maincpu->mapping_write_callback().set(FUNC(generalplus_gpac800_game_state::mapping_w));
m_maincpu->add_route(ALL_OUTPUTS, "lspeaker", 0.5);
m_maincpu->add_route(ALL_OUTPUTS, "rspeaker", 0.5);
}
@ -567,15 +580,29 @@ void generalplus_gpac800_game_state::machine_reset()
{
address_space& mem = m_maincpu->space(AS_PROGRAM);
/* Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000000 (50 47 61 6E 64 6E 61 6E 64 6E)-- -- -- -- -- -- PGandnandn------
00000010 -- -- -- -- -- bb -- -- -- -- -- -- -- -- -- -- ----------------
bb = where to copy first block
The header is GPnandnand (byteswapped) then some params
one of the params appears to be for the initial code copy operation done
by the bootstrap
*/
// probably more bytes are used
int dest = m_strippedrom[0x15] << 8;
// copy a block of code from the NAND to RAM
for (int i = 0; i < 0x2000; i++)
{
uint16_t word = m_strippedrom[(i * 2) + 0] | (m_strippedrom[(i * 2) + 1] << 8);
mem.write_word(0x4000+i, word);
mem.write_word(dest+i, word);
}
mem.write_word(0xfff7, 0x4020); // point boot vector at code in RAM
mem.write_word(0xfff7, dest+0x20); // point boot vector at code in RAM
m_maincpu->reset(); // reset CPU so vector gets read etc.
}