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

View File

@ -24,6 +24,11 @@ ROM_START( coco_pak )
// this region is filled by cococart_slot_device::call_load()
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 )
@ -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_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)
@ -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()
{
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();
uint32_t rom_length = memregion(CARTSLOT_TAG)->bytes();
if (m_cart->exists()) {
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);
}
}
return &rom[(m_pos * 0x4000) % rom_length];
}
//-------------------------------------------------
// get_cart_size
//-------------------------------------------------
uint32_t coco_pak_banked_device::get_cart_size()
{
return 0x4000;
}
//-------------------------------------------------
// scs_write
@ -187,7 +212,11 @@ WRITE8_MEMBER(coco_pak_banked_device::scs_write)
{
case 0:
// set the bank
banked_pak_set_bank(data);
if (m_pos != data)
{
m_pos = data;
cart_base_changed();
}
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);
// device-level overrides
virtual const tiny_rom_entry *device_rom_region() const override;
virtual void device_start() 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;
private:
void banked_pak_set_bank(uint32_t bank);
uint8_t m_pos;
};
#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
//-------------------------------------------------
@ -401,16 +413,16 @@ image_init_result cococart_slot_device::call_load()
offs_t read_length;
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
{
read_length = get_software_region_length("rom");
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);
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
//-------------------------------------------------

View File

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

View File

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

View File

@ -196,12 +196,13 @@ private:
cococart_slot_device * m_cart_device;
memory_bank * m_read_banks[9];
memory_bank * m_write_banks[9];
uint8_t * m_rom;
uint8_t * m_cart_rom;
uint8_t * m_rom;
uint8_t * m_cart_rom;
uint32_t m_cart_size;
pixel_t m_composite_palette[64];
pixel_t m_composite_bw_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_ram_tag; /* tag of RAM device */