jak_gtg / jak_car2 - show all startup screens, respond to inputs etc. (#6107)

* begin refactor (nw)

* internal mapping (nw)

* more mapping changes (nw)

* continued refactor (nw)

* this was meant to have vanished when the set was moved, not sure how/when it got restored (nw)

* (nw)

* (nw)

* (nw)

* (nw)

* (nw)

* (nw)

* (nw)

* (nw)

* tidy (nw)

* move logic (nw)

* refactor (nw)

* param not needed (nw)

* tidy (nw)

* this is the banked area.. (nw)

* tv logo displays (nw)

* less printf, disable hack for now to show all logos (nw)

* unrelated note change (nw)

* more likely bootstrap actually changes the registers (nw)
This commit is contained in:
David Haywood 2019-12-28 20:31:23 +00:00 committed by R. Belmont
parent 7e680c0052
commit b459e55a0f
6 changed files with 581 additions and 466 deletions

View File

@ -33,6 +33,10 @@ generalplus_gpac800_device::generalplus_gpac800_device(const machine_config &mco
{
}
void sunplus_gcm394_base_device::default_cs_callback(uint16_t cs0, uint16_t cs1, uint16_t cs2, uint16_t cs3, uint16_t cs4)
{
logerror("callback not hooked\n");
}
// **************************************** SYSTEM DMA device *************************************************
@ -91,7 +95,7 @@ void sunplus_gcm394_base_device::trigger_systemm_dma(address_space &space, int c
uint32_t dest = m_dma_params[2][channel] | (m_dma_params[5][channel] << 16) ;
uint32_t length = m_dma_params[3][channel] | (m_dma_params[6][channel] << 16);
LOGMASKED(LOG_GCM394_SYSDMA, "%s:possible DMA operation (7abf) (trigger %04x) with params mode:%04x source:%08x (word offset) dest:%08x (word offset) length:%08x (words)\n", machine().describe_context(), data, mode, source, dest, length );
LOGMASKED(LOG_GCM394_SYSDMA, "%s:possible DMA operation (7abf) (trigger %04x) with params mode:%04x source:%08x (word offset) dest:%08x (word offset) length:%08x (words) while csbank is %02x\n", machine().describe_context().c_str(), data, mode, source, dest, length, m_membankswitch_7810 );
if ((source&0x0fffffff) >= 0x20000)
LOGMASKED(LOG_GCM394_SYSDMA, " likely transfer from ROM %08x - %08x\n", (source - 0x20000) * 2, (source - 0x20000) * 2 + (length * 2)- 1);
@ -109,14 +113,14 @@ void sunplus_gcm394_base_device::trigger_systemm_dma(address_space &space, int c
for (int i = 0; i < length/2; i++)
{
uint16_t val1 = mem.read_word(source);
uint16_t val2 = mem.read_word(source);
uint16_t val1 = read_space(source);
uint16_t val2 = read_space(source);
//printf("val1 %04x val2 %04x\n", val1, val2);
//logerror("val1 %04x val2 %04x\n", val1, val2);
uint16_t val = (val2 << 8) | val1;
m_space_write_cb(space, dest, val);
write_space(dest, val);
dest += 1;
}
@ -126,45 +130,26 @@ void sunplus_gcm394_base_device::trigger_systemm_dma(address_space &space, int c
if (mem.read_word(0x3f368) == 0x4840)
mem.write_word(0x3f368, 0x4841); // cars 2 IRQ? wait hack
if (mem.read_word(0x4368c) == 0x4846)
mem.write_word(0x4368c, 0x4840); // cars 2 force service mode
//if (mem.read_word(0x4368c) == 0x4846)
// mem.write_word(0x4368c, 0x4840); // cars 2 force service mode
if (mem.read_word(0x4d8d4) == 0x4840)
mem.write_word(0x4d8d4, 0x4841); // golden tee IRQ? wait hack
if (mem.read_word(0x34410) == 0x4846)
mem.write_word(0x34410, 0x4840); // golden tee force service mode
//if (mem.read_word(0x34410) == 0x4846)
// mem.write_word(0x34410, 0x4840); // golden tee force service mode
}
else if ((mode == 0x0089) || (mode == 0x0009) || (mode == 0x4009))
{
for (int i = 0; i < length; i++)
{
uint16_t val = 0x0000;
address_space& mem = this->space(AS_PROGRAM);
if (source < 0x20000)
{
val = mem.read_word(source);
}
else
{
// maybe the -0x20000 here should be handled in external space handlers instead
val = m_space_read_cb(space, source - 0x20000);
}
if (dest < 0x20000)
{
mem.write_word(dest, val);
}
else
{
// maybe the -0x20000 here should be handled in external space handlers instead
m_space_write_cb(space, dest - 0x20000, val);
}
uint16_t val = read_space(source);
write_space(dest , val);
dest += 1;
if ((mode&0x3fff) == 0x0009)
source += 1;
}
@ -237,7 +222,8 @@ WRITE16_MEMBER(sunplus_gcm394_base_device::membankswitch_7810_w)
// if (m_membankswitch_7810 != data)
// LOGMASKED(LOG_GCM394,"%s:sunplus_gcm394_base_device::membankswitch_7810_w %04x\n", machine().describe_context(), data);
popmessage("bankswitch %04x -> %04x", m_membankswitch_7810, data);
if (m_membankswitch_7810 != data)
popmessage("bankswitch %04x -> %04x", m_membankswitch_7810, data);
m_membankswitch_7810 = data;
}
@ -253,7 +239,7 @@ WRITE16_MEMBER(sunplus_gcm394_base_device::chipselect_csx_memory_device_control_
if (offset == 0)
m_mapping_write_cb(data);
static const char* const md[] =
{
@ -270,6 +256,9 @@ WRITE16_MEMBER(sunplus_gcm394_base_device::chipselect_csx_memory_device_control_
logerror("CS%d set to size: %02x (%08x words) md: %01x %s warat: %01x wait: %01x\n", offset, cs_size, (cs_size+1)*0x10000, cs_md, md[cs_md], cs_warat, cs_wait);
m_cs_callback(m_782x[0], m_782x[1], m_782x[2], m_782x[3], m_782x[4]);
}
@ -435,7 +424,7 @@ WRITE16_MEMBER(sunplus_gcm394_base_device::unk_w)
}
}
void sunplus_gcm394_base_device::gcm394_internal_map(address_map &map)
void sunplus_gcm394_base_device::base_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
@ -662,6 +651,77 @@ void sunplus_gcm394_base_device::gcm394_internal_map(address_map &map)
map(0x007b80, 0x007bbf).rw(m_spg_audio, FUNC(sunplus_gcm394_audio_device::control_r), FUNC(sunplus_gcm394_audio_device::control_w));
map(0x007c00, 0x007dff).rw(m_spg_audio, FUNC(sunplus_gcm394_audio_device::audio_r), FUNC(sunplus_gcm394_audio_device::audio_w));
map(0x007e00, 0x007fff).rw(m_spg_audio, FUNC(sunplus_gcm394_audio_device::audio_phase_r), FUNC(sunplus_gcm394_audio_device::audio_phase_w));
}
void sunplus_gcm394_base_device::gcm394_internal_map(address_map& map)
{
sunplus_gcm394_base_device::base_internal_map(map);
// no internal ROM on this model?
map(0x08000, 0x0ffff).r(FUNC(sunplus_gcm394_base_device::internalrom_lower32_r)).nopw();
map(0x020000, 0x1fffff).rw(FUNC(sunplus_gcm394_base_device::cs_space_r), FUNC(sunplus_gcm394_base_device::cs_space_w));
map(0x200000, 0x3fffff).rw(FUNC(sunplus_gcm394_base_device::cs_bank_space_r), FUNC(sunplus_gcm394_base_device::cs_bank_space_w));
}
READ16_MEMBER(sunplus_gcm394_base_device::cs_space_r)
{
return m_cs_space->read_word(offset);
}
WRITE16_MEMBER(sunplus_gcm394_base_device::cs_space_w)
{
m_cs_space->write_word(offset, data);
}
READ16_MEMBER(sunplus_gcm394_base_device::cs_bank_space_r)
{
int bank = m_membankswitch_7810 & 0x3f;
int realoffset = offset + (bank * 0x200000) - m_csbase;
if (realoffset < 0)
{
logerror("read real offset < 0\n");
return 0;
}
//return m_cs_space->read_word(offset + (0x200000 - m_csbase));
return m_cs_space->read_word(realoffset);
}
WRITE16_MEMBER(sunplus_gcm394_base_device::cs_bank_space_w)
{
int bank = m_membankswitch_7810 & 0x3f;
int realoffset = offset + (bank * 0x200000) - m_csbase;
if (realoffset < 0)
{
logerror("write real offset < 0\n");
return;
}
m_cs_space->write_word(realoffset, data);
}
READ16_MEMBER(sunplus_gcm394_base_device::internalrom_lower32_r)
{
if (m_boot_mode == 0)
{
uint16_t* introm = (uint16_t*)m_internalrom->base();
return introm[offset];
}
else
{
if (!m_cs_space)
return 0x0000;
uint16_t val = m_cs_space->read_word(offset+0x8000);
return val;
}
}
READ16_MEMBER(generalplus_gpac800_device::unkarea_7850_r)
@ -691,7 +751,7 @@ READ16_MEMBER(generalplus_gpac800_device::unkarea_7854_r)
uint32_t nandaddress = (m_flash_addr_high << 16) | m_flash_addr_low;
uint8_t data = m_nand_read_cb((nandaddress * 2) + m_curblockaddr);
//printf("reading nand byte %02x\n", data);
//logerror("reading nand byte %02x\n", data);
m_curblockaddr++;
@ -738,31 +798,40 @@ WRITE16_MEMBER(generalplus_gpac800_device::flash_addr_high_w)
// so it's likely this is built on top of that just with NAND support
void generalplus_gpac800_device::gpac800_internal_map(address_map& map)
{
sunplus_gcm394_base_device::gcm394_internal_map(map);
sunplus_gcm394_base_device::base_internal_map(map);
// there is an extra command-based device at 785x, what it returns is important to code flow
// code is littered with NOPs so clearly the device can't accept commands too quickly and doesn't return data immediately
//
// this should be the NAND device, as the games attempt to do a DMA operation with '7854' as the source, and the target
// as the RAM location where code needs to end up before jumping to it
// 785x = NAND device
map(0x007850, 0x007850).r(FUNC(generalplus_gpac800_device::unkarea_7850_r)); // NAND Control Reg
map(0x007851, 0x007851).w(FUNC(generalplus_gpac800_device::nand_command_w)); // NAND Command Reg
map(0x007852, 0x007852).w(FUNC(generalplus_gpac800_device::flash_addr_low_w)); // NAND Low Address Reg
map(0x007853, 0x007853).w(FUNC(generalplus_gpac800_device::flash_addr_high_w)); // NAND High Address Reg
map(0x007854, 0x007854).r(FUNC(generalplus_gpac800_device::unkarea_7854_r)); // NAND Data Reg
// map(0x007855, 0x007855).w(FUNC(generalplus_gpac800_device::nand_dma_ctrl_w)); // NAND DMA / INT Control
// 128kwords internal ROM
//map(0x08000, 0x0ffff).rom().region("internal", 0); // lower 32kwords of internal ROM is visible / shadowed depending on boot pins and register
map(0x08000, 0x0ffff).r(FUNC(generalplus_gpac800_device::internalrom_lower32_r)).nopw();
map(0x10000, 0x27fff).rom().region("internal", 0x10000); // upper 96kwords of internal ROM is always visible
map(0x28000, 0x2ffff).noprw(); // reserved
// 0x30000+ is CS access
map(0x030000, 0x1fffff).rw(FUNC(generalplus_gpac800_device::cs_space_r), FUNC(generalplus_gpac800_device::cs_space_w));
map(0x200000, 0x3fffff).rw(FUNC(generalplus_gpac800_device::cs_bank_space_r), FUNC(generalplus_gpac800_device::cs_bank_space_w));
}
void sunplus_gcm394_base_device::device_start()
{
unsp_20_device::device_start();
m_cs_callback.resolve();
m_porta_in.resolve_safe(0);
m_portb_in.resolve_safe(0);
m_porta_out.resolve();
m_space_read_cb.resolve_safe(0);
m_space_write_cb.resolve();
m_mapping_write_cb.resolve();
@ -792,7 +861,7 @@ void sunplus_gcm394_base_device::device_reset()
m_7807 = 0x0000;
m_membankswitch_7810 = 0x0000;
m_membankswitch_7810 = 0x0001;
m_7816 = 0x0000;
m_7817 = 0x0000;
@ -850,10 +919,6 @@ void sunplus_gcm394_base_device::device_reset()
m_unk_timer->adjust(attotime::from_hz(60), 0, attotime::from_hz(60));
m_gfxregion = memregion(":maincpu")->base();
m_gfxregionsize = memregion(":maincpu")->bytes();
}
void generalplus_gpac800_device::device_reset()
@ -942,13 +1007,34 @@ WRITE_LINE_MEMBER(sunplus_gcm394_base_device::videoirq_w)
uint16_t sunplus_gcm394_base_device::read_space(uint32_t offset)
{
// uint16_t b = m_gfxregion[(offset * 2) & (m_gfxregionsize - 1)] | (m_gfxregion[(offset * 2 + 1) & (m_gfxregionsize - 1)] << 8);
// return b;
address_space& mem = this->space(AS_PROGRAM);
uint16_t retdata = mem.read_word(offset);
return retdata;
address_space& space = this->space(AS_PROGRAM);
uint16_t val;
if (offset < m_csbase)
{
val = space.read_word(offset);
}
else
{
val = m_cs_space->read_word(offset-m_csbase);
}
return val;
}
void sunplus_gcm394_base_device::write_space(uint32_t offset, uint16_t data)
{
address_space& space = this->space(AS_PROGRAM);
if (offset < m_csbase)
{
space.write_word(offset, data);
}
else
{
m_cs_space->write_word(offset-m_csbase, data);
}
}
void sunplus_gcm394_base_device::device_add_mconfig(machine_config &config)
{

View File

@ -17,6 +17,7 @@
#include "sunplus_gcm394_video.h"
#include "spg2xx_audio.h"
typedef device_delegate<void (uint16_t, uint16_t, uint16_t, uint16_t, uint16_t)> sunplus_gcm394_cs_callback_device;
class sunplus_gcm394_base_device : public unsp_20_device, public device_mixer_interface
{
@ -32,13 +33,17 @@ public:
m_screen(*this, finder_base::DUMMY_TAG),
m_spg_video(*this, "spgvideo"),
m_spg_audio(*this, "spgaudio"),
m_internalrom(*this, "internal"),
m_porta_in(*this),
m_portb_in(*this),
m_porta_out(*this),
m_nand_read_cb(*this),
m_csbase(0x20000),
m_space_read_cb(*this),
m_space_write_cb(*this),
m_mapping_write_cb(*this)
m_mapping_write_cb(*this),
m_boot_mode(0),
m_cs_callback(*this, DEVICE_SELF, FUNC(sunplus_gcm394_base_device::default_cs_callback))
{
}
@ -59,7 +64,13 @@ public:
virtual void device_add_mconfig(machine_config& config) override;
void set_bootmode(int mode) { m_boot_mode = mode; }
IRQ_CALLBACK_MEMBER(irq_vector_cb);
template <typename... T> void set_cs_config_callback(T &&... args) { m_cs_callback.set(std::forward<T>(args)...); }
void default_cs_callback(uint16_t cs0, uint16_t cs1, uint16_t cs2, uint16_t cs3, uint16_t cs4 );
void set_cs_space(address_space* csspace) { m_cs_space = csspace; }
protected:
@ -67,10 +78,12 @@ protected:
virtual void device_reset() override;
void gcm394_internal_map(address_map &map);
void base_internal_map(address_map &map);
required_device<screen_device> m_screen;
required_device<gcm394_video_device> m_spg_video;
required_device<sunplus_gcm394_audio_device> m_spg_audio;
optional_memory_region m_internalrom;
devcb_read16 m_porta_in;
devcb_read16 m_portb_in;
@ -142,6 +155,16 @@ protected:
uint16_t m_7961;
devcb_read16 m_nand_read_cb;
int m_csbase;
DECLARE_READ16_MEMBER(internalrom_lower32_r);
address_space* m_cs_space;
DECLARE_READ16_MEMBER(cs_space_r);
DECLARE_WRITE16_MEMBER(cs_space_w);
DECLARE_READ16_MEMBER(cs_bank_space_r);
DECLARE_WRITE16_MEMBER(cs_bank_space_w);
private:
devcb_read16 m_space_read_cb;
@ -263,9 +286,12 @@ private:
emu_timer *m_unk_timer;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
uint8_t* m_gfxregion;
uint32_t m_gfxregionsize;
uint16_t read_space(uint32_t offset);
inline uint16_t read_space(uint32_t offset);
inline void write_space(uint32_t offset, uint16_t data);
// config registers (external pins)
int m_boot_mode; // 2 pins determine boot mode, likely only read at power-on
sunplus_gcm394_cs_callback_device m_cs_callback;
};
@ -294,6 +320,7 @@ public:
{
m_screen.set_tag(std::forward<T>(screen_tag));
m_testval = 0;
m_csbase = 0x30000;
}
generalplus_gpac800_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

View File

@ -207,7 +207,9 @@ void gcm394_base_video_device::device_start()
m_maxgfxelement = 0;
decodegfx(":maincpu");
// debug helper only
if (memregion(":maincpu"))
decodegfx(":maincpu");
save_item(NAME(m_spriteextra));
save_item(NAME(m_spriteram));

View File

@ -2359,6 +2359,8 @@ CONS( 200?, lxcmcysw, 0, 0, nes_vt_cy, nes_vt, nes_vt_cy_state, empty_init, "
// Lexibook Compact Cyber Arcade - Paw Patrol
// Lexibook Compact Cyber Arcade - Barbie
// Lexibook Compact Cyber Arcade - Finding Dory
// Lexibook Compact Cyber Arcade - Marvel Ultimate Spiderman
// Lexibook Compact Cyber Arcade - PJ Masks
// more?

View File

@ -50,6 +50,89 @@
#include "speaker.h"
class full_memory_device :
public device_t,
public device_memory_interface
{
public:
// construction/destruction
full_memory_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
// configuration helpers
template <typename... T> full_memory_device& set_map(T &&... args) { set_addrmap(0, std::forward<T>(args)...); return *this; }
template <typename... T> full_memory_device& map(T &&... args) { set_addrmap(0, std::forward<T>(args)...); return *this; }
address_space* get_program() { return m_program; }
protected:
virtual void device_start() override;
virtual void device_config_complete() override;
// device_memory_interface overrides
virtual space_config_vector memory_space_config() const override;
private:
// internal state
address_space_config m_program_config;
address_space *m_program;
int m_shift;
};
// device type definition
DECLARE_DEVICE_TYPE(FULL_MEMORY, full_memory_device)
// device type definition
DEFINE_DEVICE_TYPE(FULL_MEMORY, full_memory_device, "full_memory", "SunPlus Full CS Memory Map")
full_memory_device::full_memory_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
device_t(mconfig, FULL_MEMORY, tag, owner, clock),
device_memory_interface(mconfig, *this),
m_program(nullptr)
{
}
device_memory_interface::space_config_vector full_memory_device::memory_space_config() const
{
return space_config_vector {
std::make_pair(AS_PROGRAM, &m_program_config)
};
}
/*
':maincpu' (00F87F):possible DMA operation (7abf) (trigger 0001) with params mode:4009 source:00040000 (word offset) dest:00830000 (word offset) length:00007800 (words)
':maincpu' (002384):possible DMA operation (7abf) (trigger 0001) with params mode:0009 source:00180000 (word offset) dest:00840000 (word offset) length:00160000 (words)
':maincpu' (05048D):possible DMA operation (7abf) (trigger 0001) with params mode:0089 source:00006fa3 (word offset) dest:000025bc (word offset) length:000001e0 (words)
':maincpu' (05048D):possible DMA operation (7abf) (trigger 0001) with params mode:0089 source:00006fa3 (word offset) dest:000024cc (word offset) length:000000f0 (words)
':maincpu' (05048D):possible DMA operation (7abf) (trigger 0001) with params mode:0089 source:00006fa3 (word offset) dest:00000002 (word offset) length:00000400 (words)
':maincpu' (05048D):possible DMA operation (7abf) (trigger 0001) with params mode:0089 source:00006fa3 (word offset) dest:00000402 (word offset) length:00000400 (words)
':maincpu' (05048D):possible DMA operation (7abf) (trigger 0001) with params mode:0089 source:00006fa3 (word offset) dest:00000802 (word offset) length:00000400 (words)
gtg
':maincpu' (005ACE):possible DMA operation (7abf) (trigger 0001) with params mode:1089 source:30007854 (word offset) dest:00030000 (word offset) length:00000200 (words)
':maincpu' (005ACE):possible DMA operation (7abf) (trigger 0001) with params mode:1089 source:30007854 (word offset) dest:00030100 (word offset) length:00000200 (words)
':maincpu' (005ACE):possible DMA operation (7abf) (trigger 0001) with params mode:1089 source:30007854 (word offset) dest:00030200 (word offset) length:00000200 (words)
':maincpu' (005ACE):possible DMA operation (7abf) (trigger 0001) with params mode:1089 source:30007854 (word offset) dest:00030300 (word offset) length:00000200 (words)
':maincpu' (005ACE):possible DMA operation (7abf) (trigger 0001) with params mode:1089 source:30007854 (word offset) dest:00030400 (word offset) length:00000200 (words)
*/
void full_memory_device::device_config_complete()
{
m_program_config = address_space_config( "program", ENDIANNESS_BIG, 16, 32, -1 );
}
void full_memory_device::device_start()
{
m_program = &space(AS_PROGRAM);
}
class gcm394_game_state : public driver_device
{
public:
@ -57,33 +140,45 @@ public:
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_screen(*this, "screen"),
m_bank(*this, "cartbank"),
m_io_p1(*this, "P1"),
m_io_p2(*this, "P2"),
m_romregion(*this, "maincpu")
m_romregion(*this, "maincpu"),
m_memory(*this, "memory")
{
}
void base(machine_config &config);
void cs_map_base(address_map &map);
virtual DECLARE_READ16_MEMBER(cs0_r);
virtual DECLARE_WRITE16_MEMBER(cs0_w);
virtual DECLARE_READ16_MEMBER(cs1_r);
virtual DECLARE_WRITE16_MEMBER(cs1_w);
virtual DECLARE_READ16_MEMBER(cs2_r);
virtual DECLARE_WRITE16_MEMBER(cs2_w);
virtual DECLARE_READ16_MEMBER(cs3_r);
virtual DECLARE_WRITE16_MEMBER(cs3_w);
virtual DECLARE_READ16_MEMBER(cs4_r);
virtual DECLARE_WRITE16_MEMBER(cs4_w);
void cs_callback(uint16_t cs0, uint16_t cs1, uint16_t cs2, uint16_t cs3, uint16_t cs4);
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
void switch_bank(uint32_t bank);
required_device<sunplus_gcm394_base_device> m_maincpu;
required_device<screen_device> m_screen;
optional_memory_bank m_bank;
required_ioport m_io_p1;
required_ioport m_io_p2;
virtual void mem_map_4m(address_map &map);
required_region_ptr<uint16_t> m_romregion;
optional_region_ptr<uint16_t> m_romregion;
required_device<full_memory_device> m_memory;
DECLARE_READ16_MEMBER(porta_r);
DECLARE_READ16_MEMBER(portb_r);
@ -95,42 +190,47 @@ protected:
virtual DECLARE_WRITE16_MEMBER(write_external_space);
private:
uint32_t m_current_bank;
int m_numbanks;
};
class wrlshunt_game_state : public gcm394_game_state
READ16_MEMBER(gcm394_game_state::cs0_r)
{
public:
wrlshunt_game_state(const machine_config& mconfig, device_type type, const char* tag) :
gcm394_game_state(mconfig, type, tag),
m_mapping(0),
m_mainram(*this, "mainram")
{
}
return m_romregion[offset & 0x3fffff];
}
void wrlshunt(machine_config &config);
WRITE16_MEMBER(gcm394_game_state::cs0_w)
{
logerror("cs0_w %04x %04x (to ROM!)\n", offset, data);
}
protected:
//virtual void machine_start() override;
//virtual void machine_reset() override;
READ16_MEMBER(gcm394_game_state::cs1_r) { logerror("cs1_r %06n", offset); return 0x0000; }
WRITE16_MEMBER(gcm394_game_state::cs1_w) { logerror("cs1_w %06x %04x\n", offset, data); }
READ16_MEMBER(gcm394_game_state::cs2_r) { logerror("cs2_r %06n", offset); return 0x0000; }
WRITE16_MEMBER(gcm394_game_state::cs2_w) { logerror("cs2_w %06x %04x\n", offset, data); }
READ16_MEMBER(gcm394_game_state::cs3_r) { logerror("cs3_r %06n", offset); return 0x0000; }
WRITE16_MEMBER(gcm394_game_state::cs3_w) { logerror("cs3_w %06x %04x\n", offset, data); }
READ16_MEMBER(gcm394_game_state::cs4_r) { logerror("cs4_r %06n", offset); return 0x0000; }
WRITE16_MEMBER(gcm394_game_state::cs4_w) { logerror("cs4_w %06x %04x\n", offset, data); }
void wrlshunt_map(address_map &map);
private:
/*
map info (NAND type)
DECLARE_READ16_MEMBER(hunt_porta_r);
DECLARE_WRITE16_MEMBER(hunt_porta_w);
map(0x000000, 0x006fff) internal RAM
map(0x007000, 0x007fff) internal peripherals
map(0x008000, 0x00ffff) internal ROM (lower 32kwords) - can also be configured to mirror CS0 308000 area with external pin for boot from external ROM
map(0x010000, 0x027fff) internal ROM (upper 96kwords) - can't be switched
map(0x028000, 0x02ffff) reserved
virtual DECLARE_WRITE16_MEMBER(mapping_w) override;
uint16_t m_mapping;
map(0x030000, 0x0.....) view into external spaces (CS0 area starts here. followed by CS1 area, CS2 area etc.)
map(0x200000, 0x3fffff) continued view into external spaces, but this area is banked with m_membankswitch_7810 (valid bank values 0x00-0x3f)
*/
required_shared_ptr<u16> m_mainram;
virtual DECLARE_READ16_MEMBER(read_external_space) override;
virtual DECLARE_WRITE16_MEMBER(write_external_space) override;
};
void gcm394_game_state::cs_map_base(address_map& map)
{
}
class generalplus_gpac800_game_state : public gcm394_game_state
@ -138,7 +238,7 @@ class generalplus_gpac800_game_state : public gcm394_game_state
public:
generalplus_gpac800_game_state(const machine_config& mconfig, device_type type, const char* tag) :
gcm394_game_state(mconfig, type, tag),
m_mainram(*this, "mainram"),
m_has_nand(false),
m_initial_copy_words(0x2000),
m_nandreadbase(0)
{
@ -155,106 +255,132 @@ public:
protected:
virtual void machine_reset() override;
void generalplus_gpac800_map(address_map &map);
DECLARE_READ8_MEMBER(read_nand);
std::vector<uint16_t> m_sdram;
std::vector<uint16_t> m_sdram2;
virtual DECLARE_READ16_MEMBER(cs0_r) override;
virtual DECLARE_WRITE16_MEMBER(cs0_w) override;
virtual DECLARE_READ16_MEMBER(cs1_r) override;
virtual DECLARE_WRITE16_MEMBER(cs1_w) override;
bool m_has_nand;
private:
void nand_init(int blocksize, int blocksize_stripped);
required_shared_ptr<u16> m_mainram;
std::vector<uint8_t> m_strippedrom;
int m_strippedsize;
int m_initial_copy_words;
int m_nandreadbase;
virtual DECLARE_WRITE16_MEMBER(write_external_space) override;
};
class wrlshunt_game_state : public gcm394_game_state
{
public:
wrlshunt_game_state(const machine_config& mconfig, device_type type, const char* tag) :
gcm394_game_state(mconfig, type, tag)
{
}
void wrlshunt(machine_config &config);
void init_wrlshunt();
protected:
//virtual void machine_start() override;
virtual void machine_reset() override;
std::vector<uint16_t> m_sdram;
private:
DECLARE_READ16_MEMBER(hunt_porta_r);
DECLARE_WRITE16_MEMBER(hunt_porta_w);
//required_shared_ptr<u16> m_mainram;
virtual DECLARE_READ16_MEMBER(cs0_r) override;
virtual DECLARE_WRITE16_MEMBER(cs0_w) override;
virtual DECLARE_READ16_MEMBER(cs1_r) override;
virtual DECLARE_WRITE16_MEMBER(cs1_w) override;
};
READ16_MEMBER(wrlshunt_game_state::cs0_r)
{
return m_romregion[offset & 0x3ffffff];
}
WRITE16_MEMBER(wrlshunt_game_state::cs0_w)
{
logerror("cs0_w write to ROM?\n");
//m_romregion[offset & 0x3ffffff] = data;
}
READ16_MEMBER(wrlshunt_game_state::cs1_r)
{
return m_sdram[offset & 0x3fffff];
}
WRITE16_MEMBER(wrlshunt_game_state::cs1_w)
{
m_sdram[offset & 0x3fffff] = data;
}
void wrlshunt_game_state::machine_reset()
{
cs_callback(0x00, 0x00, 0x00, 0x00, 0x00);
m_maincpu->set_cs_space(m_memory->get_program());
m_maincpu->reset(); // reset CPU so vector gets read etc.
}
void wrlshunt_game_state::init_wrlshunt()
{
m_sdram.resize(0x400000); // 0x400000 bytes, 0x800000 words
}
READ16_MEMBER(generalplus_gpac800_game_state::cs0_r)
{
return m_sdram2[offset & 0xffff];
}
WRITE16_MEMBER(generalplus_gpac800_game_state::cs0_w)
{
m_sdram2[offset & 0xffff] = data;
}
READ16_MEMBER(generalplus_gpac800_game_state::cs1_r)
{
return m_sdram[offset & 0x3fffff];
}
WRITE16_MEMBER(generalplus_gpac800_game_state::cs1_w)
{
m_sdram[offset & 0x3fffff] = data;
}
READ8_MEMBER(generalplus_gpac800_game_state::read_nand)
{
if (!m_has_nand)
return 0x0000;
return m_strippedrom[(offset + m_nandreadbase) & (m_strippedsize - 1)];
}
WRITE16_MEMBER(generalplus_gpac800_game_state::write_external_space)
{
if (offset < 0x0400000)
{
m_mainram[offset] = data;
// logerror("DMA writing to external space (RAM?) %08x %04x\n", offset, data);
}
}
READ16_MEMBER(gcm394_game_state::read_external_space)
{
//logerror("reading offset %04x\n", offset * 2);
return m_romregion[offset];
return m_memory->get_program()->read_word(offset);
}
WRITE16_MEMBER(gcm394_game_state::write_external_space)
{
logerror("DMA writing to external space (RAM?) %08x %04x\n", offset, data);
m_memory->get_program()->write_word(offset, data);
}
WRITE16_MEMBER(wrlshunt_game_state::mapping_w)
{
m_mapping = data;
logerror("change mapping %04x\n", data);
}
READ16_MEMBER(wrlshunt_game_state::read_external_space)
{
if (m_mapping == 0x7f8a)
{
//logerror("reading offset %04x\n", offset * 2);
return m_romregion[offset];
}
else if (m_mapping == 0x008a)
{
address_space& mem = m_maincpu->space(AS_PROGRAM);
uint16_t retdata = mem.read_word(offset + 0x20000);
logerror("reading from RAM instead offset %08x returning %04x\n", offset * 2, retdata);
return retdata;
}
else
{
uint16_t retdata = 0x0000;
logerror("reading from unknown source instead offset %08x returning %04x\n", offset * 2, retdata);
return retdata;
}
}
WRITE16_MEMBER(wrlshunt_game_state::write_external_space)
{
// logerror("DMA writing to external space (RAM?) %08x %04x\n", offset, data);
if (offset & 0x0800000)
{
offset &= 0x03fffff;
if (offset < 0x03d0000)
{
m_mainram[offset] = data;
//logerror("DMA writing to external space (RAM?) %08x %04x\n", offset, data);
}
else
{
logerror("DMA writing to external space (RAM?) (out of bounds) %08x %04x\n", offset, data);
}
}
else
{
logerror("DMA writing to external space (RAM?) (unknown handling) %08x %04x\n", offset, data);
}
}
READ16_MEMBER(gcm394_game_state::porta_r)
{
uint16_t data = m_io_p1->read();
@ -278,7 +404,6 @@ WRITE16_MEMBER(gcm394_game_state::porta_w)
void gcm394_game_state::base(machine_config &config)
{
GCM394(config, m_maincpu, XTAL(27'000'000), m_screen);
m_maincpu->set_addrmap(AS_PROGRAM, &gcm394_game_state::mem_map_4m);
m_maincpu->porta_in().set(FUNC(gcm394_game_state::porta_r));
m_maincpu->portb_in().set(FUNC(gcm394_game_state::portb_r));
m_maincpu->porta_out().set(FUNC(gcm394_game_state::porta_w));
@ -288,6 +413,10 @@ void gcm394_game_state::base(machine_config &config)
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);
m_maincpu->set_bootmode(1); // boot from external ROM / CS mirror
m_maincpu->set_cs_config_callback(FUNC(gcm394_game_state::cs_callback));
FULL_MEMORY(config, m_memory).set_map(&gcm394_game_state::cs_map_base);
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_refresh_hz(60);
@ -300,6 +429,19 @@ void gcm394_game_state::base(machine_config &config)
SPEAKER(config, "rspeaker").front_right();
}
void wrlshunt_game_state::wrlshunt(machine_config &config)
{
gcm394_game_state::base(config);
m_maincpu->porta_in().set(FUNC(wrlshunt_game_state::hunt_porta_r));
m_maincpu->porta_out().set(FUNC(wrlshunt_game_state::hunt_porta_w));
m_maincpu->set_bootmode(1); // boot from external ROM / CS mirror
m_screen->set_size(320*2, 262*2);
m_screen->set_visarea(0, (320*2)-1, 0, (240*2)-1);
}
READ16_MEMBER(wrlshunt_game_state::hunt_porta_r)
{
uint16_t data = m_io_p1->read();
@ -311,30 +453,17 @@ WRITE16_MEMBER(wrlshunt_game_state::hunt_porta_w)
{
logerror("%s: Port A:WRITE %04x\n", machine().describe_context(), data);
// skip check (EEPROM?)
if (m_mainram[0x5b354 - 0x30000] == 0xafd0)
m_mainram[0x5b354 - 0x30000] = 0xB403;
// HACK
address_space& mem = m_maincpu->space(AS_PROGRAM);
if (mem.read_word(0x5b354) == 0xafd0) // wrlshubt - skip check (EEPROM?)
mem.write_word(0x5b354, 0xB403);
}
void wrlshunt_game_state::wrlshunt(machine_config &config)
{
gcm394_game_state::base(config);
m_maincpu->set_addrmap(AS_PROGRAM, &wrlshunt_game_state::wrlshunt_map);
m_maincpu->porta_in().set(FUNC(wrlshunt_game_state::hunt_porta_r));
m_maincpu->porta_out().set(FUNC(wrlshunt_game_state::hunt_porta_w));
m_screen->set_size(320*2, 262*2);
m_screen->set_visarea(0, (320*2)-1, 0, (240*2)-1);
}
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);
GPAC800(config, m_maincpu, XTAL(27'000'000), m_screen);
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));
@ -344,88 +473,80 @@ void generalplus_gpac800_game_state::generalplus_gpac800(machine_config &config)
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);
m_maincpu->set_bootmode(0); // boot from internal ROM (NAND bootstrap)
m_maincpu->set_cs_config_callback(FUNC(gcm394_game_state::cs_callback));
m_maincpu->nand_read_callback().set(FUNC(generalplus_gpac800_game_state::read_nand));
FULL_MEMORY(config, m_memory).set_map(&generalplus_gpac800_game_state::cs_map_base);
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_refresh_hz(60);
m_screen->set_size(320*2, 262*2);
m_screen->set_visarea(0, (320*2)-1, 0, (240*2)-1);
m_screen->set_screen_update("maincpu", FUNC(sunplus_gcm394_device::screen_update));
m_screen->screen_vblank().set(m_maincpu, FUNC(sunplus_gcm394_device::vblank));
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
}
void gcm394_game_state::switch_bank(uint32_t bank)
{
if (!m_bank)
return;
if (bank != m_current_bank)
{
m_current_bank = bank;
m_bank->set_entry(bank);
m_maincpu->invalidate_cache();
}
}
void gcm394_game_state::machine_start()
{
if (m_bank)
{
int i;
for (i = 0; i < (m_romregion.bytes() / 0x800000); i++)
{
m_bank->configure_entry(i, &m_romregion[i * 0x800000]);
}
m_numbanks = i;
m_bank->set_entry(0);
}
else
{
m_numbanks = 0;
}
save_item(NAME(m_current_bank));
}
void gcm394_game_state::machine_reset()
{
m_current_bank = 0;
cs_callback(0x00, 0x00, 0x00, 0x00, 0x00);
m_maincpu->set_cs_space(m_memory->get_program());
m_maincpu->reset(); // reset CPU so vector gets read etc.
}
/*
map info
void gcm394_game_state::cs_callback(uint16_t cs0, uint16_t cs1, uint16_t cs2, uint16_t cs3, uint16_t cs4)
{
// wipe existing mappings;
m_memory->get_program()->unmap_readwrite(0, (0x8000000*5)-1);
map(0x000000, 0x006fff) internal RAM
map(0x007000, 0x007fff) internal peripherals
map(0x008000, 0x00ffff) internal ROM (lower 32kwords) - can also be configured to mirror CS0 308000 area with external pin for boot from external ROM
map(0x010000, 0x027fff) internal ROM (upper 96kwords) - can't be switched
map(0x028000, 0x02ffff) reserved
int start_address = 0;
int end_address;
map(0x030000, 0x0.....) view into external spaces (CS0 area starts here. followed by CS1 area, CS2 area etc.)
int size; // cs region sizes in kwords
map(0x200000, 0x3fffff) continued view into external spaces, but this area is banked with m_membankswitch_7810 (valid bank values 0x00-0x3f)
*/
size = (((cs0 & 0xff00) >> 8) + 1) * 0x10000;
end_address = start_address + (size - 1);
logerror("installing cs0 handler start_address %08x end_address %08x\n", start_address, end_address);
m_memory->get_program()->install_readwrite_handler( start_address, end_address, read16_delegate(*this, FUNC(gcm394_game_state::cs0_r)), write16_delegate(*this, FUNC(gcm394_game_state::cs0_w)));
start_address += size;
void gcm394_game_state::mem_map_4m(address_map &map)
{
map(0x000000, 0x00ffff).rom().region("maincpu", 0); // non-banked area on this SoC?
size = (((cs1 & 0xff00) >> 8) + 1) * 0x10000;
end_address = start_address + (size - 1);
logerror("installing cs1 handler start_address %08x end_address %08x\n", start_address, end_address);
m_memory->get_program()->install_readwrite_handler( start_address, end_address, read16_delegate(*this, FUNC(gcm394_game_state::cs1_r)), write16_delegate(*this, FUNC(gcm394_game_state::cs1_w)));
start_address += size;
// smartfp really expects the ROM at 0 to map here, so maybe this is how the newer SoC works
map(0x020000, 0x3fffff).bankr("cartbank");
size = (((cs2 & 0xff00) >> 8) + 1) * 0x10000;
end_address = start_address + (size - 1);
logerror("installing cs2 handler start_address %08x end_address %08x\n", start_address, end_address);
m_memory->get_program()->install_readwrite_handler( start_address, end_address, read16_delegate(*this, FUNC(gcm394_game_state::cs2_r)), write16_delegate(*this, FUNC(gcm394_game_state::cs2_w)));
start_address += size;
size = (((cs3 & 0xff00) >> 8) + 1) * 0x10000;
end_address = start_address + (size - 1);
logerror("installing cs3 handler start_address %08x end_address %08x\n", start_address, end_address);
m_memory->get_program()->install_readwrite_handler( start_address, end_address, read16_delegate(*this, FUNC(gcm394_game_state::cs3_r)), write16_delegate(*this, FUNC(gcm394_game_state::cs3_w)));
start_address += size;
size = (((cs4 & 0xff00) >> 8) + 1) * 0x10000;
end_address = start_address + (size - 1);
logerror("installing cs4 handler start_address %08x end_address %08x\n", start_address, end_address);
m_memory->get_program()->install_readwrite_handler( start_address, end_address, read16_delegate(*this, FUNC(gcm394_game_state::cs4_r)), write16_delegate(*this, FUNC(gcm394_game_state::cs4_w)));
//start_address += size;
}
void wrlshunt_game_state::wrlshunt_map(address_map &map)
{
map(0x000000, 0x00ffff).rom().region("maincpu", 0); // non-banked area on this SoC?
map(0x030000, 0x3fffff).ram().share("mainram");
}
void generalplus_gpac800_game_state::generalplus_gpac800_map(address_map &map)
{
map(0x000000, 0x3fffff).ram().share("mainram");
}
static INPUT_PORTS_START( gcm394 )
@ -686,6 +807,24 @@ static INPUT_PORTS_START( jak_gtg )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
INPUT_PORTS_END
ROM_START(smartfp)
//ROM_REGION16_BE( 0x40000, "maincpu:internal", ROMREGION_ERASE00 ) // not on this model? (or at least not this size, as CS base is different)
//ROM_LOAD16_WORD_SWAP( "intenral.rom", 0x00000, 0x40000, NO_DUMP )
ROM_REGION(0x800000, "maincpu", ROMREGION_ERASE00)
ROM_LOAD16_WORD_SWAP("smartfitpark.bin", 0x000000, 0x800000, CRC(ada84507) SHA1(a3a80bf71fae62ebcbf939166a51d29c24504428))
ROM_END
ROM_START(wrlshunt)
//ROM_REGION16_BE( 0x40000, "maincpu:internal", ROMREGION_ERASE00 ) // not on this model? (or at least not this size, as CS base is different)
//ROM_LOAD16_WORD_SWAP( "intenral.rom", 0x00000, 0x40000, NO_DUMP )
ROM_REGION(0x8000000, "maincpu", ROMREGION_ERASE00)
ROM_LOAD16_WORD_SWAP("wireless.bin", 0x0000, 0x8000000, CRC(a6ecc20e) SHA1(3645f23ba2bb218e92d4560a8ae29dddbaabf796))
ROM_END
/*
Wireless Hunting Video Game System
(info provided with dump)
@ -762,16 +901,6 @@ which is also found in the Wireless Air 60 ROM.
*/
ROM_START(wrlshunt)
ROM_REGION(0x8000000, "maincpu", ROMREGION_ERASE00)
ROM_LOAD16_WORD_SWAP("wireless.bin", 0x0000, 0x8000000, CRC(a6ecc20e) SHA1(3645f23ba2bb218e92d4560a8ae29dddbaabf796))
ROM_END
ROM_START(smartfp)
ROM_REGION(0x800000, "maincpu", ROMREGION_ERASE00)
ROM_LOAD16_WORD_SWAP("smartfitpark.bin", 0x000000, 0x800000, CRC(ada84507) SHA1(a3a80bf71fae62ebcbf939166a51d29c24504428))
ROM_END
/*
Wireless Air 60
@ -797,88 +926,134 @@ https://web.archive.org/web/20180106005235/http://www.lcis.com.tw/paper_store/pa
*/
ROM_START( wlsair60 )
ROM_REGION( 0x8400000, "maincpu", ROMREGION_ERASE00 )
ROM_REGION16_BE( 0x40000, "maincpu:internal", ROMREGION_ERASE00 )
ROM_LOAD16_WORD_SWAP( "intenral.rom", 0x00000, 0x40000, NO_DUMP ) // used as bootstrap only
ROM_REGION16_BE( 0x8400000, "nandrom", ROMREGION_ERASE00 )
ROM_LOAD16_WORD_SWAP( "wlsair60.nand", 0x0000, 0x8400000, CRC(eec23b97) SHA1(1bb88290cf54579a5bb51c08a02d793cd4d79f7a) )
ROM_END
ROM_START( jak_gtg )
ROM_REGION( 0x4200000, "maincpu", ROMREGION_ERASE00 )
ROM_REGION16_BE( 0x40000, "maincpu:internal", ROMREGION_ERASE00 )
ROM_LOAD16_WORD_SWAP( "intenral.rom", 0x00000, 0x40000, NO_DUMP ) // used as bootstrap only
ROM_REGION16_BE( 0x4200000, "nandrom", ROMREGION_ERASE00 )
ROM_LOAD16_WORD_SWAP( "goldentee.bin", 0x0000, 0x4200000, CRC(87d5e815) SHA1(5dc46cd753b791449cc41d5eff4928c0dcaf35c0) )
ROM_END
ROM_START( jak_car2 )
ROM_REGION( 0x4200000, "maincpu", ROMREGION_ERASE00 )
ROM_REGION16_BE( 0x40000, "maincpu:internal", ROMREGION_ERASE00 )
ROM_LOAD16_WORD_SWAP( "intenral.rom", 0x00000, 0x40000, NO_DUMP ) // used as bootstrap only
ROM_REGION16_BE( 0x4200000, "nandrom", ROMREGION_ERASE00 )
ROM_LOAD16_WORD_SWAP( "cars2.bin", 0x0000, 0x4200000, CRC(4d610e09) SHA1(bc59f5f7f676a8f2a78dfda7fb62c804bbf850b6) )
ROM_END
ROM_START( jak_tsm )
ROM_REGION( 0x4200000, "maincpu", ROMREGION_ERASE00 )
ROM_REGION16_BE( 0x40000, "maincpu:internal", ROMREGION_ERASE00 )
ROM_LOAD16_WORD_SWAP( "intenral.rom", 0x00000, 0x40000, NO_DUMP ) // used as bootstrap only
ROM_REGION16_BE( 0x4200000, "nandrom", ROMREGION_ERASE00 )
ROM_LOAD16_WORD_SWAP( "toystorymania.bin", 0x0000, 0x4200000, CRC(183b20a5) SHA1(eb4fa5ee9dfac58f5244d00d4e833b1e461cc52c) )
ROM_END
ROM_START( vbaby )
ROM_REGION( 0x8400000, "maincpu", ROMREGION_ERASE00 )
ROM_REGION16_BE( 0x40000, "maincpu:internal", ROMREGION_ERASE00 )
ROM_LOAD16_WORD_SWAP( "intenral.rom", 0x00000, 0x40000, NO_DUMP ) // used as bootstrap only
ROM_REGION16_BE( 0x8400000, "nandrom", ROMREGION_ERASE00 )
ROM_LOAD16_WORD_SWAP( "vbaby.bin", 0x0000, 0x8400000, CRC(d904441b) SHA1(3742bc4e1e403f061ce2813ecfafc6f30a44d287) )
ROM_END
ROM_START( beambox )
ROM_REGION( 0x4200000, "maincpu", ROMREGION_ERASE00 )
ROM_REGION16_BE( 0x40000, "maincpu:internal", ROMREGION_ERASE00 )
ROM_LOAD16_WORD_SWAP( "intenral.rom", 0x00000, 0x40000, NO_DUMP ) // used as bootstrap only
ROM_REGION16_BE( 0x4200000, "nandrom", ROMREGION_ERASE00 )
ROM_LOAD16_WORD_SWAP( "beambox.bin", 0x0000, 0x4200000, CRC(a486f04e) SHA1(73c7d99d8922eba58d94e955e254b9c3baa4443e) )
ROM_END
// the JAKKS ones of these seem to be known as 'Generalplus GPAC500' hardware?
CONS(2011, wrlshunt, 0, 0, wrlshunt, wrlshunt, wrlshunt_game_state, empty_init, "Hamy / Kids Station Toys Inc", "Wireless Hunting Video Game System", MACHINE_NO_SOUND | MACHINE_NOT_WORKING)
CONS(2009, smartfp, 0, 0, base, gcm394, gcm394_game_state, empty_init, "Fisher-Price", "Fun 2 Learn Smart Fit Park (Spain)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND)
// Fun 2 Learn 3-in-1 SMART SPORTS ?
CONS(2011, wrlshunt, 0, 0, wrlshunt, wrlshunt, wrlshunt_game_state, init_wrlshunt, "Hamy / Kids Station Toys Inc", "Wireless Hunting Video Game System", MACHINE_NO_SOUND | MACHINE_NOT_WORKING)
void generalplus_gpac800_game_state::machine_reset()
{
// configure CS defaults
address_space& mem = m_maincpu->space(AS_PROGRAM);
mem.write_word(0x007820, 0x0047);
mem.write_word(0x007821, 0xff47);
mem.write_word(0x007822, 0x00c7);
mem.write_word(0x007823, 0x0047);
mem.write_word(0x007824, 0x0047);
/* 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
m_maincpu->set_cs_space(m_memory->get_program());
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 < m_initial_copy_words; i++)
if (m_has_nand)
{
uint16_t word = m_strippedrom[(i * 2) + 0] | (m_strippedrom[(i * 2) + 1] << 8);
// up to 256 pages (16384kw) for each space
mem.write_word(dest+i, word);
// (size of cs0 + cs1 + cs2 + cs3 + cs4) <= 81920kwords
// simulate bootstrap / internal ROM
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 < m_initial_copy_words; i++)
{
uint16_t word = m_strippedrom[(i * 2) + 0] | (m_strippedrom[(i * 2) + 1] << 8);
mem.write_word(dest + i, word);
}
// these vectors must either directly point to RAM, or at least redirect there after some code
uint16_t* internal = (uint16_t*)memregion("maincpu:internal")->base();
internal[0x7ff5] = 0x6fea;
internal[0x7ff6] = 0x6fec;
internal[0x7ff7] = dest + 0x20; // point boot vector at code in RAM (probably in reality points to internal code that copies the first block)
internal[0x7ff8] = 0x6ff0;
internal[0x7ff9] = 0x6ff2;
internal[0x7ffa] = 0x6ff4;
internal[0x7ffb] = 0x6ff6;
internal[0x7ffc] = 0x6ff8;
internal[0x7ffd] = 0x6ffa;
internal[0x7ffe] = 0x6ffc;
internal[0x7fff] = 0x6ffe;
internal[0x8000] = 0xb00b;
}
mem.write_word(0xfff5, 0x6fea);
mem.write_word(0xfff6, 0x6fec);
mem.write_word(0xfff7, dest+0x20); // point boot vector at code in RAM
mem.write_word(0xfff8, 0x6ff0);
mem.write_word(0xfff9, 0x6ff2);
mem.write_word(0xfffa, 0x6ff4);
mem.write_word(0xfffb, 0x6ff6);
mem.write_word(0xfffc, 0x6ff8);
mem.write_word(0xfffd, 0x6ffa);
mem.write_word(0xfffe, 0x6ffc);
mem.write_word(0xffff, 0x6ffe);
m_maincpu->reset(); // reset CPU so vector gets read etc.
}
void generalplus_gpac800_game_state::nand_init(int blocksize, int blocksize_stripped)
{
uint8_t* rom = memregion("maincpu")->base();
int size = memregion("maincpu")->bytes();
m_sdram.resize(0x400000); // 0x400000 bytes, 0x800000 words
m_sdram2.resize(0x10000);
uint8_t* rom = memregion("nandrom")->base();
int size = memregion("nandrom")->bytes();
int numblocks = size / blocksize;
m_strippedsize = numblocks * blocksize_stripped;
@ -908,6 +1083,8 @@ void generalplus_gpac800_game_state::nand_init(int blocksize, int blocksize_stri
fclose(fp);
}
}
m_has_nand = true;
}
void generalplus_gpac800_game_state::nand_init210()

View File

@ -1,179 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
/******************************************************************************
Wireless Hunting Video Game System skeleton driver
System: Wireless Hunting Video Game System
Publisher: Hamy / Kids Station Toys Inc
Year: 2011
ROM: FDI MSP55LV100G
RAM: Micron Technology 48LC8M16A2
Games:
Secret Mission
Predator
Delta Force
Toy Land
Dream Forest
Trophy Season
Freedom Force
Be Careful
Net Power
Open Training
Super Archer
Ultimate Frisbee
UFO Shooting
Happy Darts
Balloon Shoot
Avatair
Angry Pirate
Penguin War
Ghost Shooter
Duck Hunt
ROM Board:
Package: SO44
Spacing: 1.27 mm
Width: 16.14 mm
Length: 27.78 mm
Voltage: 3V
Pinout:
A25 A24
| |
+--------------------------+
A21 --|== # # `.__.' ==|-- A20
A18 --|== ==|-- A19
A17 --|== ==|-- A8
A7 --|== ==|-- A9
A6 --|== o ==|-- A10
A5 --|== +----------------+ ==|-- A11
A4 --|== | | ==|-- A12
A3 --|== | MSP55LV100G | ==|-- A13
A2 --|== | 0834 M02H | ==|-- A14
A1 --|== | JAPAN | ==|-- A15
A0 --|== | | ==|-- A16
#CE --|== | | ==|-- A23
GND --|== | | ==|-- A22
#OE --|== | | ==|-- Q15
Q0 --|== | | ==|-- Q7
Q8 --|== | | ==|-- Q14
Q1 --|== +----------------+ ==|-- Q6
Q9 --|== ==|-- Q13
Q2 --|== M55L100G ==|-- Q5
Q10 --|== ==|-- Q12
Q3 --|== ==|-- Q4
Q11 --|== ==|-- VCC
+--------------------------+
The only interesting string in this ROM is SPF2ALP,
which is also found in the Wireless Air 60 ROM.
*******************************************************************************/
#include "emu.h"
#include "cpu/unsp/unsp.h"
#include "machine/spg2xx.h"
#include "screen.h"
#include "speaker.h"
class wrlshunt_state : public driver_device
{
public:
wrlshunt_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_screen(*this, "screen")
, m_spg(*this, "spg")
{ }
void wrlshunt(machine_config &config);
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
void mem_map(address_map &map);
required_device<unsp12_device> m_maincpu;
required_device<screen_device> m_screen;
required_device<spg2xx_device> m_spg;
};
/************************************
*
* Machine Hardware
*
************************************/
void wrlshunt_state::machine_start()
{
}
void wrlshunt_state::machine_reset()
{
}
void wrlshunt_state::mem_map(address_map &map)
{
map(0x008000, 0x00ffff).rom().region("maincpu", 0x10000);
map(0x000000, 0x007fff).m(m_spg, FUNC(spg_wh_device::map));
map(0x040000, 0x07ffff).rom().region("maincpu", 0x106f000);
}
/************************************
*
* Inputs
*
************************************/
static INPUT_PORTS_START( wrlshunt )
INPUT_PORTS_END
/************************************
*
* Machine Configs
*
************************************/
void wrlshunt_state::wrlshunt(machine_config &config)
{
UNSP12(config, m_maincpu, XTAL(27'000'000));
m_maincpu->set_addrmap(AS_PROGRAM, &wrlshunt_state::mem_map);
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_refresh_hz(60);
m_screen->set_size(320, 262);
m_screen->set_visarea(0, 320-1, 0, 240-1);
m_screen->set_screen_update("spg", FUNC(spg_wh_device::screen_update));
m_screen->screen_vblank().set(m_spg, FUNC(spg_wh_device::vblank));
SPG_WH(config, m_spg, XTAL(27'000'000), m_maincpu, m_screen);
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
m_spg->add_route(ALL_OUTPUTS, "lspeaker", 0.5);
m_spg->add_route(ALL_OUTPUTS, "rspeaker", 0.5);
}
/************************************
*
* ROM Loading
*
************************************/
ROM_START( wrlshunt )
ROM_REGION( 0x8000000, "maincpu", ROMREGION_ERASE00 )
ROM_LOAD16_WORD_SWAP( "wireless.bin", 0x0000, 0x8000000, CRC(a6ecc20e) SHA1(3645f23ba2bb218e92d4560a8ae29dddbaabf796) )
ROM_END
// valid looking code, but extended periperhal area (twice the size?)
CONS( 2011, wrlshunt, 0, 0, wrlshunt, wrlshunt, wrlshunt_state, empty_init, "Hamy / Kids Station Toys Inc", "Wireless Hunting Video Game System", MACHINE_NO_SOUND | MACHINE_NOT_WORKING )