diff options
Diffstat (limited to 'target-m68k/helper.c')
-rw-r--r-- | target-m68k/helper.c | 138 |
1 files changed, 49 insertions, 89 deletions
diff --git a/target-m68k/helper.c b/target-m68k/helper.c index e850d53..f428375 100644 --- a/target-m68k/helper.c +++ b/target-m68k/helper.c @@ -25,35 +25,50 @@ #define SIGNBIT (1u << 31) -enum m68k_cpuid { - M68K_CPUID_M5206, - M68K_CPUID_M5208, - M68K_CPUID_CFV4E, - M68K_CPUID_ANY, -}; - -typedef struct m68k_def_t m68k_def_t; - -struct m68k_def_t { - const char * name; - enum m68k_cpuid id; -}; - -static m68k_def_t m68k_cpu_defs[] = { - {"m5206", M68K_CPUID_M5206}, - {"m5208", M68K_CPUID_M5208}, - {"cfv4e", M68K_CPUID_CFV4E}, - {"any", M68K_CPUID_ANY}, - {NULL, 0}, -}; +typedef struct M68kCPUListState { + fprintf_function cpu_fprintf; + FILE *file; +} M68kCPUListState; + +/* Sort alphabetically, except for "any". */ +static gint m68k_cpu_list_compare(gconstpointer a, gconstpointer b) +{ + ObjectClass *class_a = (ObjectClass *)a; + ObjectClass *class_b = (ObjectClass *)b; + const char *name_a, *name_b; + + name_a = object_class_get_name(class_a); + name_b = object_class_get_name(class_b); + if (strcmp(name_a, "any") == 0) { + return 1; + } else if (strcmp(name_b, "any") == 0) { + return -1; + } else { + return strcasecmp(name_a, name_b); + } +} + +static void m68k_cpu_list_entry(gpointer data, gpointer user_data) +{ + ObjectClass *c = data; + M68kCPUListState *s = user_data; + + (*s->cpu_fprintf)(s->file, "%s\n", + object_class_get_name(c)); +} void m68k_cpu_list(FILE *f, fprintf_function cpu_fprintf) { - unsigned int i; + M68kCPUListState s = { + .file = f, + .cpu_fprintf = cpu_fprintf, + }; + GSList *list; - for (i = 0; m68k_cpu_defs[i].name; i++) { - (*cpu_fprintf)(f, "%s\n", m68k_cpu_defs[i].name); - } + list = object_class_get_list(TYPE_M68K_CPU, false); + list = g_slist_sort(list, m68k_cpu_list_compare); + g_slist_foreach(list, m68k_cpu_list_entry, &s); + g_slist_free(list); } static int fpu_gdb_get_reg(CPUM68KState *env, uint8_t *mem_buf, int n) @@ -83,66 +98,6 @@ static int fpu_gdb_set_reg(CPUM68KState *env, uint8_t *mem_buf, int n) return 0; } -static void m68k_set_feature(CPUM68KState *env, int feature) -{ - env->features |= (1u << feature); -} - -static int cpu_m68k_set_model(CPUM68KState *env, const char *name) -{ - m68k_def_t *def; - - for (def = m68k_cpu_defs; def->name; def++) { - if (strcmp(def->name, name) == 0) - break; - } - if (!def->name) - return -1; - - switch (def->id) { - case M68K_CPUID_M5206: - m68k_set_feature(env, M68K_FEATURE_CF_ISA_A); - break; - case M68K_CPUID_M5208: - m68k_set_feature(env, M68K_FEATURE_CF_ISA_A); - m68k_set_feature(env, M68K_FEATURE_CF_ISA_APLUSC); - m68k_set_feature(env, M68K_FEATURE_BRAL); - m68k_set_feature(env, M68K_FEATURE_CF_EMAC); - m68k_set_feature(env, M68K_FEATURE_USP); - break; - case M68K_CPUID_CFV4E: - m68k_set_feature(env, M68K_FEATURE_CF_ISA_A); - m68k_set_feature(env, M68K_FEATURE_CF_ISA_B); - m68k_set_feature(env, M68K_FEATURE_BRAL); - m68k_set_feature(env, M68K_FEATURE_CF_FPU); - m68k_set_feature(env, M68K_FEATURE_CF_EMAC); - m68k_set_feature(env, M68K_FEATURE_USP); - break; - case M68K_CPUID_ANY: - m68k_set_feature(env, M68K_FEATURE_CF_ISA_A); - m68k_set_feature(env, M68K_FEATURE_CF_ISA_B); - m68k_set_feature(env, M68K_FEATURE_CF_ISA_APLUSC); - m68k_set_feature(env, M68K_FEATURE_BRAL); - m68k_set_feature(env, M68K_FEATURE_CF_FPU); - /* MAC and EMAC are mututally exclusive, so pick EMAC. - It's mostly backwards compatible. */ - m68k_set_feature(env, M68K_FEATURE_CF_EMAC); - m68k_set_feature(env, M68K_FEATURE_CF_EMAC_B); - m68k_set_feature(env, M68K_FEATURE_USP); - m68k_set_feature(env, M68K_FEATURE_EXT_FULL); - m68k_set_feature(env, M68K_FEATURE_WORD_INDEX); - break; - } - - register_m68k_insns(env); - if (m68k_feature (env, M68K_FEATURE_CF_FPU)) { - gdb_register_coprocessor(env, fpu_gdb_get_reg, fpu_gdb_set_reg, - 11, "cf-fp.xml", 18); - } - /* TODO: Add [E]MAC registers. */ - return 0; -} - void cpu_state_reset(CPUM68KState *env) { cpu_reset(ENV_GET_CPU(env)); @@ -154,7 +109,10 @@ CPUM68KState *cpu_m68k_init(const char *cpu_model) CPUM68KState *env; static int inited; - cpu = M68K_CPU(object_new(TYPE_M68K_CPU)); + if (object_class_by_name(cpu_model) == NULL) { + return NULL; + } + cpu = M68K_CPU(object_new(cpu_model)); env = &cpu->env; if (!inited) { @@ -164,10 +122,12 @@ CPUM68KState *cpu_m68k_init(const char *cpu_model) env->cpu_model_str = cpu_model; - if (cpu_m68k_set_model(env, cpu_model) < 0) { - object_delete(OBJECT(cpu)); - return NULL; + register_m68k_insns(env); + if (m68k_feature(env, M68K_FEATURE_CF_FPU)) { + gdb_register_coprocessor(env, fpu_gdb_get_reg, fpu_gdb_set_reg, + 11, "cf-fp.xml", 18); } + /* TODO: Add [E]MAC registers. */ cpu_reset(ENV_GET_CPU(env)); qemu_init_vcpu(env); |