summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author npwoods <npwoods@mess.org>2021-10-22 22:54:26 -0400
committer GitHub <noreply@github.com>2021-10-22 22:54:26 -0400
commit84970b9090f99ca6a06cb0133b108aabf3caf533 (patch)
treea568a7b44d74d25a0f1798540b97d51fff7337ee
parent559ba3124366b7af42b16c244f772470f02e3290 (diff)
Initial RPK support for CoCo (#8541)
-rw-r--r--src/devices/bus/coco/cococart.cpp109
1 files changed, 103 insertions, 6 deletions
diff --git a/src/devices/bus/coco/cococart.cpp b/src/devices/bus/coco/cococart.cpp
index 5f6e543725a..04b22d1471c 100644
--- a/src/devices/bus/coco/cococart.cpp
+++ b/src/devices/bus/coco/cococart.cpp
@@ -39,6 +39,7 @@
#include "emu.h"
#include "cococart.h"
+#include "formats/rpk.h"
#include "coco_dcmodem.h"
#include "coco_fdc.h"
@@ -96,6 +97,23 @@ enum
};
+// definitions of RPK PCBs in layout.xml
+static const char *coco_rpk_pcbdefs[] =
+{
+ "standard",
+ "paged16k",
+ nullptr
+};
+
+
+// ...and their mappings to "default card slots"
+static const char *coco_rpk_cardslottypes[] =
+{
+ "pak",
+ "banked_16k"
+};
+
+
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
@@ -475,6 +493,63 @@ void cococart_slot_device::set_cart_base_update(cococart_base_update_delegate up
//-------------------------------------------------
+// read_coco_rpk
+//-------------------------------------------------
+
+static std::error_condition read_coco_rpk(std::unique_ptr<util::random_read> &&stream, rpk_file::ptr &result)
+{
+ // sanity checks
+ static_assert(std::size(coco_rpk_pcbdefs) - 1 == std::size(coco_rpk_cardslottypes));
+
+ // set up the RPK reader
+ rpk_reader reader(coco_rpk_pcbdefs, false);
+
+ // and read the RPK file
+ return reader.read(std::move(stream), result);
+}
+
+
+//-------------------------------------------------
+// read_coco_rpk
+//-------------------------------------------------
+
+static std::error_condition read_coco_rpk(std::unique_ptr<util::random_read> &&stream, u8 *mem, offs_t cart_length, offs_t &actual_length)
+{
+ actual_length = 0;
+
+ // open the RPK
+ rpk_file::ptr file;
+ std::error_condition err = read_coco_rpk(std::move(stream), file);
+ if (err)
+ return err;
+
+ // for now, we are just going to load all sockets into the contiguous block of memory
+ // that cartridges use
+ offs_t pos = 0;
+ for (const rpk_socket &socket : file->sockets())
+ {
+ // only ROM supported for now; if we see anything else it should have been caught in the RPK code
+ assert(socket.type() == rpk_socket::socket_type::ROM);
+
+ // read all bytes
+ std::vector<uint8_t> contents;
+ err = socket.read_file(contents);
+ if (err)
+ return err;
+
+ // copy the bytes
+ offs_t size = (offs_t) std::min(contents.size(), (size_t)cart_length - pos);
+ memcpy(&mem[pos], &contents[0], size);
+ pos += size;
+ }
+
+ // we're done!
+ actual_length = pos;
+ return std::error_condition();
+}
+
+
+//-------------------------------------------------
// call_load
//-------------------------------------------------
@@ -486,14 +561,23 @@ image_init_result cococart_slot_device::call_load()
u8 *base = cart_mem->base();
offs_t read_length, cart_length = cart_mem->bytes();
- if (!loaded_through_softlist())
+ if (loaded_through_softlist())
{
- read_length = fread(base, cart_length);
+ // loaded through softlist
+ read_length = get_software_region_length("rom");
+ memcpy(base, get_software_region("rom"), read_length);
+ }
+ else if (is_filetype("rpk"))
+ {
+ // RPK file
+ std::error_condition err = read_coco_rpk(util::core_file_read(image_core_file()), base, cart_length, read_length);
+ if (err)
+ return image_init_result::FAIL;
}
else
{
- read_length = get_software_region_length("rom");
- memcpy(base, get_software_region("rom"), read_length);
+ // conventional ROM image
+ read_length = fread(base, cart_length);
}
while (read_length < cart_length)
@@ -513,9 +597,22 @@ image_init_result cococart_slot_device::call_load()
std::string cococart_slot_device::get_default_card_software(get_default_card_software_hook &hook) const
{
- return software_get_default_slot("pak");
-}
+ // this is the default for anything not in an RPK file
+ int pcb_type = 0;
+ // is this an RPK?
+ if (hook.is_filetype("rpk"))
+ {
+ // RPK file
+ rpk_file::ptr file;
+ std::error_condition err = read_coco_rpk(util::core_file_read(*hook.image_file()), file);
+ if (!err)
+ pcb_type = file->pcb_type();
+ }
+
+ // lookup the default slot
+ return software_get_default_slot(coco_rpk_cardslottypes[pcb_type]);
+}
//**************************************************************************