mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
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:
parent
935431ab00
commit
22f745e0d5
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user