summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/machine/ram.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/machine/ram.c')
-rw-r--r--trunk/src/emu/machine/ram.c268
1 files changed, 268 insertions, 0 deletions
diff --git a/trunk/src/emu/machine/ram.c b/trunk/src/emu/machine/ram.c
new file mode 100644
index 00000000000..7e7aa69196c
--- /dev/null
+++ b/trunk/src/emu/machine/ram.c
@@ -0,0 +1,268 @@
+/*************************************************************************
+
+ RAM device
+
+ Provides a configurable amount of RAM to drivers
+
+**************************************************************************/
+
+#include <stdio.h>
+#include <ctype.h>
+
+#include "emu.h"
+#include "emuopts.h"
+#include "ram.h"
+
+
+/***************************************************************************
+ CONSTANTS
+***************************************************************************/
+
+#define RAM_STRING_BUFLEN 16
+#define MAX_RAM_OPTIONS 16
+
+
+/***************************************************************************
+ TYPE DEFINITIONS
+***************************************************************************/
+
+typedef struct _ram_state ram_state;
+struct _ram_state
+{
+ UINT32 size; /* total amount of ram configured */
+ UINT8 *ram; /* pointer to the start of ram */
+};
+
+
+/*****************************************************************************
+ INLINE FUNCTIONS
+*****************************************************************************/
+
+INLINE ram_state *get_safe_token(device_t *device)
+{
+ assert(device != NULL);
+ assert(device->type() == RAM);
+
+ return (ram_state *)downcast<legacy_device_base *>(device)->token();
+}
+
+
+/*****************************************************************************
+ HELPER FUNCTIONS
+*****************************************************************************/
+
+/*-------------------------------------------------
+ ram_parse_string - convert a ram string to an
+ integer value
+-------------------------------------------------*/
+
+UINT32 ram_parse_string(const char *s)
+{
+ UINT32 ram;
+ char suffix = '\0';
+
+ s += sscanf(s, "%u%c", &ram, &suffix);
+
+ switch(tolower(suffix))
+ {
+ case 'k':
+ /* kilobytes */
+ ram *= 1024;
+ break;
+
+ case 'm':
+ /* megabytes */
+ ram *= 1024*1024;
+ break;
+
+ case '\0':
+ /* no suffix */
+ break;
+
+ default:
+ /* parse failure */
+ ram = 0;
+ break;
+ }
+
+ return ram;
+}
+
+/*****************************************************************************
+ DEVICE INTERFACE
+*****************************************************************************/
+
+static DEVICE_START( ram )
+{
+ ram_state *ram = get_safe_token(device);
+ ram_config *config = (ram_config *)downcast<const legacy_device_base *>(device)->inline_config();
+
+ /* the device named 'ram' can get ram options from command line */
+ if (strcmp(device->tag(), RAM_TAG) == 0)
+ {
+ const char *ramsize_string = device->machine().options().ram_size();
+
+ if ((ramsize_string != NULL) && (ramsize_string[0] != '\0'))
+ ram->size = ram_parse_string(ramsize_string);
+ }
+
+ /* if we didn't get a size yet, use the default */
+ if (ram->size == 0)
+ ram->size = ram_parse_string(config->default_size);
+
+ /* allocate space for the ram */
+ ram->ram = auto_alloc_array(device->machine(), UINT8, ram->size);
+
+ /* reset ram to the default value */
+ memset(ram->ram, config->default_value, ram->size);
+
+ /* register for state saving */
+ device->save_item(NAME(ram->size));
+ device->save_pointer(NAME(ram->ram), ram->size);
+}
+
+static DEVICE_VALIDITY_CHECK( ram )
+{
+ ram_config *config = (ram_config *)downcast<const legacy_device_base *>(device)->inline_config();
+ const char *ramsize_string = NULL;
+ int is_valid = FALSE;
+ UINT32 specified_ram = 0;
+ int error = FALSE;
+ const char *gamename_option = NULL;
+
+ /* verify default ram value */
+ if (config!=NULL && ram_parse_string(config->default_size) == 0)
+ {
+ mame_printf_error("%s: '%s' has an invalid default RAM option: %s\n", driver->source_file, driver->name, config->default_size);
+ error = TRUE;
+ }
+
+ /* command line options are only parsed for the device named RAM_TAG */
+ if (device->tag()!=NULL && strcmp(device->tag(), RAM_TAG) == 0)
+ {
+ /* verify command line ram option */
+ ramsize_string = options.ram_size();
+ gamename_option = options.system_name();
+
+ if ((ramsize_string != NULL) && (ramsize_string[0] != '\0'))
+ {
+ specified_ram = ram_parse_string(ramsize_string);
+
+ if (specified_ram == 0)
+ {
+ mame_printf_error("%s: '%s' cannot recognize the RAM option %s\n", driver->source_file, driver->name, ramsize_string);
+ error = TRUE;
+ }
+ if (gamename_option != NULL && *gamename_option != 0 && strcmp(gamename_option, driver->name) == 0)
+ {
+ /* compare command line option to default value */
+ if (ram_parse_string(config->default_size) == specified_ram)
+ is_valid = TRUE;
+
+ /* verify extra ram options */
+ if (config->extra_options != NULL)
+ {
+ int j;
+ int size = strlen(config->extra_options);
+ char * const s = mame_strdup(config->extra_options);
+ char * const e = s + size;
+ char *p = s;
+ for (j=0;j<size;j++) {
+ if (p[j]==',') p[j]=0;
+ }
+
+ /* try to parse each option */
+ while(p <= e)
+ {
+ UINT32 option_ram_size = ram_parse_string(p);
+
+ if (option_ram_size == 0)
+ {
+ mame_printf_error("%s: '%s' has an invalid RAM option: %s\n", driver->source_file, driver->name, p);
+ error = TRUE;
+ }
+
+ if (option_ram_size == specified_ram)
+ is_valid = TRUE;
+
+ p += strlen(p);
+ if (p == e)
+ break;
+ p += 1;
+ }
+
+ osd_free(s);
+ }
+
+ } else {
+ /* if not for this driver then return ok */
+ is_valid = TRUE;
+ }
+ }
+ else
+ {
+ /* not specifying the ramsize on the command line is valid as well */
+ is_valid = TRUE;
+ }
+ }
+ else
+ is_valid = TRUE;
+
+ if (!is_valid)
+ {
+ mame_printf_error("%s: '%s' cannot recognize the RAM option %s", driver->source_file, driver->name, ramsize_string);
+ mame_printf_error(" (valid options are %s", config->default_size);
+
+ if (config->extra_options != NULL)
+ mame_printf_error(",%s).\n", config->extra_options);
+ else
+ mame_printf_error(").\n");
+
+ error = TRUE;
+ }
+
+ return error;
+
+}
+
+
+DEVICE_GET_INFO( ram )
+{
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(ram_state); break;
+ case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = sizeof(ram_config); break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(ram); break;
+ case DEVINFO_FCT_STOP: /* Nothing */ break;
+ case DEVINFO_FCT_RESET: /* Nothing */ break;
+ case DEVINFO_FCT_VALIDITY_CHECK: info->p = (void*)DEVICE_VALIDITY_CHECK_NAME(ram); break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "RAM"); break;
+ case DEVINFO_STR_FAMILY: strcpy(info->s, "RAM"); break;
+ case DEVINFO_STR_VERSION: strcpy(info->s, "1.00"); break;
+ case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
+ case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright MESS Team"); break;
+ }
+}
+
+/***************************************************************************
+ IMPLEMENTATION
+***************************************************************************/
+
+UINT32 ram_get_size(device_t *device)
+{
+ ram_state *ram = get_safe_token(device);
+ return ram->size;
+}
+
+UINT8 *ram_get_ptr(device_t *device)
+{
+ ram_state *ram = get_safe_token(device);
+ return ram->ram;
+}
+
+DEFINE_LEGACY_DEVICE(RAM, ram);