coco3: Make banked cartridges actually work

This commit is contained in:
AJR 2017-09-28 14:42:00 -04:00
parent 957e1a02b5
commit 35526fa556
7 changed files with 101 additions and 33 deletions

View File

@ -937,6 +937,7 @@ Compiled by K1W1 and Cowering (from GoodCoCo)
<info name="developer" value="Epyx" /> <info name="developer" value="Epyx" />
<info name="serial" value="26-3100" /> <info name="serial" value="26-3100" />
<part name="cart" interface="coco_cart"> <part name="cart" interface="coco_cart">
<feature name="slot" value="banked_16k" />
<dataarea name="rom" size="32768"> <dataarea name="rom" size="32768">
<rom name="mind-roll (1988)(26-3100)(epyx)[!].rom" size="32768" crc="83bd6056" sha1="f7b505383ca5739a98a5130549d534c38cb1bd2f" offset="0" /> <rom name="mind-roll (1988)(26-3100)(epyx)[!].rom" size="32768" crc="83bd6056" sha1="f7b505383ca5739a98a5130549d534c38cb1bd2f" offset="0" />
</dataarea> </dataarea>
@ -1076,6 +1077,7 @@ Compiled by K1W1 and Cowering (from GoodCoCo)
<info name="developer" value="Activision" /> <info name="developer" value="Activision" />
<info name="serial" value="26-3165" /> <info name="serial" value="26-3165" />
<part name="cart" interface="coco_cart"> <part name="cart" interface="coco_cart">
<feature name="slot" value="banked_16k" />
<dataarea name="rom" size="65536"> <dataarea name="rom" size="65536">
<rom name="predator (1989) (26-3165) (activision).rom" size="65536" crc="a9680ede" sha1="551d8d95fd310b2d72b1e22028a517c325fe9ab4" offset="0" /> <rom name="predator (1989) (26-3165) (activision).rom" size="65536" crc="a9680ede" sha1="551d8d95fd310b2d72b1e22028a517c325fe9ab4" offset="0" />
</dataarea> </dataarea>
@ -1160,6 +1162,7 @@ Compiled by K1W1 and Cowering (from GoodCoCo)
<info name="serial" value="26-3164" /> <info name="serial" value="26-3164" />
<sharedfeat name="compatibility" value="COCO3" /> <sharedfeat name="compatibility" value="COCO3" />
<part name="cart" interface="coco_cart"> <part name="cart" interface="coco_cart">
<feature name="slot" value="banked_16k" />
<dataarea name="rom" size="131072"> <dataarea name="rom" size="131072">
<rom name="robocop (1988)(26-3164)(data east).rom" size="131072" crc="dd94dd06" sha1="82ad8a207a446d99455926bd27d4490578de2b41" offset="0" /> <rom name="robocop (1988)(26-3164)(data east).rom" size="131072" crc="dd94dd06" sha1="82ad8a207a446d99455926bd27d4490578de2b41" offset="0" />
</dataarea> </dataarea>

View File

@ -24,6 +24,11 @@ ROM_START( coco_pak )
// this region is filled by cococart_slot_device::call_load() // this region is filled by cococart_slot_device::call_load()
ROM_END ROM_END
ROM_START( coco_pak_banked )
ROM_REGION(0x20000, CARTSLOT_TAG, ROMREGION_ERASE00)
// this region is filled by cococart_slot_device::call_load()
ROM_END
//------------------------------------------------- //-------------------------------------------------
// INPUT_PORTS( coco_cart_autostart ) // INPUT_PORTS( coco_cart_autostart )
@ -136,6 +141,7 @@ DEFINE_DEVICE_TYPE(COCO_PAK_BANKED, coco_pak_banked_device, "cocopak_banked", "C
coco_pak_banked_device::coco_pak_banked_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) coco_pak_banked_device::coco_pak_banked_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: coco_pak_device(mconfig, type, tag, owner, clock) : coco_pak_device(mconfig, type, tag, owner, clock)
, m_pos(0)
{ {
} }
coco_pak_banked_device::coco_pak_banked_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) coco_pak_banked_device::coco_pak_banked_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
@ -143,39 +149,58 @@ coco_pak_banked_device::coco_pak_banked_device(const machine_config &mconfig, co
{ {
} }
/*------------------------------------------------- //-------------------------------------------------
device_reset - device-specific startup // rom_region - device-specific ROM region
-------------------------------------------------*/ //-------------------------------------------------
const tiny_rom_entry *coco_pak_banked_device::device_rom_region() const
{
return ROM_NAME( coco_pak_banked );
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void coco_pak_banked_device::device_start()
{
coco_pak_device::device_start();
save_item(NAME(m_pos));
}
//-------------------------------------------------
// device_reset - device-specific startup
//-------------------------------------------------
void coco_pak_banked_device::device_reset() void coco_pak_banked_device::device_reset()
{ {
coco_pak_device::device_reset(); coco_pak_device::device_reset();
banked_pak_set_bank(0); m_pos = 0;
cart_base_changed();
} }
/*------------------------------------------------- //-------------------------------------------------
banked_pak_set_bank - function to set the bank // get_cart_base
-------------------------------------------------*/ //-------------------------------------------------
void coco_pak_banked_device::banked_pak_set_bank(uint32_t bank) uint8_t *coco_pak_banked_device::get_cart_base()
{ {
uint64_t pos;
uint32_t i;
uint8_t *rom = memregion(CARTSLOT_TAG)->base(); uint8_t *rom = memregion(CARTSLOT_TAG)->base();
uint32_t rom_length = memregion(CARTSLOT_TAG)->bytes(); uint32_t rom_length = memregion(CARTSLOT_TAG)->bytes();
if (m_cart->exists()) { return &rom[(m_pos * 0x4000) % rom_length];
pos = (bank * 0x4000) % m_cart->length();
for (i = 0; i < rom_length / 0x4000; i++)
{
m_cart->fseek(pos, SEEK_SET);
m_cart->fread(&rom[i * 0x4000], 0x4000);
}
}
} }
//-------------------------------------------------
// get_cart_size
//-------------------------------------------------
uint32_t coco_pak_banked_device::get_cart_size()
{
return 0x4000;
}
//------------------------------------------------- //-------------------------------------------------
// scs_write // scs_write
@ -187,7 +212,11 @@ WRITE8_MEMBER(coco_pak_banked_device::scs_write)
{ {
case 0: case 0:
// set the bank // set the bank
banked_pak_set_bank(data); if (m_pos != data)
{
m_pos = data;
cart_base_changed();
}
break; break;
} }
} }

View File

@ -53,11 +53,15 @@ protected:
coco_pak_banked_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); coco_pak_banked_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
// device-level overrides // device-level overrides
virtual const tiny_rom_entry *device_rom_region() const override;
virtual void device_start() override;
virtual void device_reset() override; virtual void device_reset() override;
virtual uint8_t *get_cart_base() override;
virtual uint32_t get_cart_size() override;
virtual DECLARE_WRITE8_MEMBER(scs_write) override; virtual DECLARE_WRITE8_MEMBER(scs_write) override;
private: private:
void banked_pak_set_bank(uint32_t bank); uint8_t m_pos;
}; };
#endif // MAME_BUS_COCO_COCO_PAK_H #endif // MAME_BUS_COCO_COCO_PAK_H

View File

@ -379,6 +379,18 @@ uint8_t* cococart_slot_device::get_cart_base()
} }
//-------------------------------------------------
// get_cart_size
//-------------------------------------------------
uint32_t cococart_slot_device::get_cart_size()
{
if (m_cart != nullptr)
return m_cart->get_cart_size();
return 0;
}
//------------------------------------------------- //-------------------------------------------------
// set_cart_base_update // set_cart_base_update
//------------------------------------------------- //-------------------------------------------------
@ -401,16 +413,16 @@ image_init_result cococart_slot_device::call_load()
offs_t read_length; offs_t read_length;
if (!loaded_through_softlist()) if (!loaded_through_softlist())
{ {
read_length = fread(m_cart->get_cart_base(), 0x8000); read_length = fread(m_cart->get_cart_base(), m_cart->get_cart_size());
} }
else else
{ {
read_length = get_software_region_length("rom"); read_length = get_software_region_length("rom");
memcpy(m_cart->get_cart_base(), get_software_region("rom"), read_length); memcpy(m_cart->get_cart_base(), get_software_region("rom"), read_length);
} }
while(read_length < 0x8000) while(read_length < m_cart->get_cart_size())
{ {
offs_t len = std::min(read_length, 0x8000 - read_length); offs_t len = std::min(read_length, m_cart->get_cart_size() - read_length);
memcpy(m_cart->get_cart_base() + read_length, m_cart->get_cart_base(), len); memcpy(m_cart->get_cart_base() + read_length, m_cart->get_cart_base(), len);
read_length += len; read_length += len;
} }
@ -522,6 +534,16 @@ uint8_t* device_cococart_interface::get_cart_base()
} }
//-------------------------------------------------
// get_cart_size
//-------------------------------------------------
uint32_t device_cococart_interface::get_cart_size()
{
return 0x8000;
}
//------------------------------------------------- //-------------------------------------------------
// set_cart_base_update // set_cart_base_update
//------------------------------------------------- //-------------------------------------------------

View File

@ -119,7 +119,8 @@ public:
void twiddle_q_lines(); void twiddle_q_lines();
// cart base // cart base
uint8_t* get_cart_base(); uint8_t *get_cart_base();
uint32_t get_cart_size();
void set_cart_base_update(cococart_base_update_delegate update); void set_cart_base_update(cococart_base_update_delegate update);
private: private:
@ -184,6 +185,7 @@ public:
virtual void set_sound_enable(bool sound_enable); virtual void set_sound_enable(bool sound_enable);
virtual uint8_t* get_cart_base(); virtual uint8_t* get_cart_base();
virtual uint32_t get_cart_size();
void set_cart_base_update(cococart_base_update_delegate update); void set_cart_base_update(cococart_base_update_delegate update);
virtual void interface_config_complete() override; virtual void interface_config_complete() override;

View File

@ -173,6 +173,7 @@ void gime_device::device_start(void)
// set up ROM/RAM pointers // set up ROM/RAM pointers
m_rom = machine().root_device().memregion(m_maincpu_tag)->base(); m_rom = machine().root_device().memregion(m_maincpu_tag)->base();
m_cart_rom = m_cart_device->get_cart_base(); m_cart_rom = m_cart_device->get_cart_base();
m_cart_size = m_cart_device->get_cart_size();
// populate palettes // populate palettes
m_composite_phase_invert = false; m_composite_phase_invert = false;
@ -348,6 +349,7 @@ void gime_device::device_pre_save()
void gime_device::device_post_load() void gime_device::device_post_load()
{ {
super::device_post_load(); super::device_post_load();
update_cart_rom();
update_memory(); update_memory();
update_cpu_clock(); update_cpu_clock();
@ -566,11 +568,15 @@ void gime_device::update_memory(int bank)
block = rom_map[m_gime_registers[0] & 3][(block & 0x3F) - 0x3C]; block = rom_map[m_gime_registers[0] & 3][(block & 0x3F) - 0x3C];
// are we in onboard ROM or cart ROM? // are we in onboard ROM or cart ROM?
uint8_t *rom_ptr = (block & 4) ? m_cart_rom : m_rom; if (BIT(block, 2) && m_cart_rom != nullptr)
// TODO: make this unmapped {
if (rom_ptr==nullptr) rom_ptr = m_rom; // perform the look up
// perform the look up memory = &m_cart_rom[((block & 3) * 0x2000) % m_cart_size];
memory = &rom_ptr[(block & 3) * 0x2000]; }
else
{
memory = &m_rom[(block & 3) * 0x2000];
}
is_read_only = true; is_read_only = true;
} }
else else
@ -608,6 +614,7 @@ uint8_t *gime_device::memory_pointer(uint32_t address)
void gime_device::update_cart_rom(void) void gime_device::update_cart_rom(void)
{ {
m_cart_rom = m_cart_device->get_cart_base(); m_cart_rom = m_cart_device->get_cart_base();
m_cart_size = m_cart_device->get_cart_size();
update_memory(); update_memory();
} }

View File

@ -196,12 +196,13 @@ private:
cococart_slot_device * m_cart_device; cococart_slot_device * m_cart_device;
memory_bank * m_read_banks[9]; memory_bank * m_read_banks[9];
memory_bank * m_write_banks[9]; memory_bank * m_write_banks[9];
uint8_t * m_rom; uint8_t * m_rom;
uint8_t * m_cart_rom; uint8_t * m_cart_rom;
uint32_t m_cart_size;
pixel_t m_composite_palette[64]; pixel_t m_composite_palette[64];
pixel_t m_composite_bw_palette[64]; pixel_t m_composite_bw_palette[64];
pixel_t m_rgb_palette[64]; pixel_t m_rgb_palette[64];
uint8_t m_dummy_bank[0x2000]; uint8_t m_dummy_bank[0x2000];
const char *m_maincpu_tag; /* tag of main CPU */ const char *m_maincpu_tag; /* tag of main CPU */
const char *m_ram_tag; /* tag of RAM device */ const char *m_ram_tag; /* tag of RAM device */