changeset 2413:64cf80e683aa

Initial support for Colecovision emulation
author Michael Pavone <pavone@retrodev.com>
date Thu, 04 Jan 2024 22:56:35 -0800
parents ed7b4d869989
children dc05f1805921
files Makefile config.c debug.c default.cfg nuklear_ui/blastem_nuklear.c serialize.h system.c system.h
diffstat 8 files changed, 75 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Thu Jan 04 22:14:29 2024 -0800
+++ b/Makefile	Thu Jan 04 22:56:35 2024 -0800
@@ -234,12 +234,12 @@
 
 MAINOBJS=blastem.o system.o genesis.o debug.o gdb_remote.o vdp.o $(RENDEROBJS) io.o romdb.o hash.o menu.o xband.o \
 	realtec.o i2c.o nor.o sega_mapper.o multi_game.o megawifi.o $(NET) serialize.o $(TERMINAL) $(CONFIGOBJS) gst.o \
-	$(M68KOBJS) $(TRANSOBJS) $(AUDIOOBJS) saves.o zip.o bindings.o jcart.o gen_player.o \
+	$(M68KOBJS) $(TRANSOBJS) $(AUDIOOBJS) saves.o zip.o bindings.o jcart.o gen_player.o coleco.o \
 	segacd.o lc8951.o cdimage.o cdd_mcu.o cd_graphics.o cdd_fader.o sft_mapper.o mediaplayer.o oscilloscope.o
 
 LIBOBJS=libblastem.o system.o genesis.o vdp.o io.o romdb.o hash.o xband.o realtec.o \
 	i2c.o nor.o sega_mapper.o multi_game.o megawifi.o $(NET) serialize.o $(TERMINAL) $(CONFIGOBJS) gst.o \
-	$(M68KOBJS) $(TRANSOBJS) $(AUDIOOBJS) saves.o jcart.o rom.db.o gen_player.o $(LIBZOBJS) \
+	$(M68KOBJS) $(TRANSOBJS) $(AUDIOOBJS) saves.o jcart.o rom.db.o gen_player.o coleco.o $(LIBZOBJS) \
 	segacd.o lc8951.o cdimage.o cdd_mcu.o cd_graphics.o cdd_fader.o sft_mapper.o mediaplayer.o
 
 ifdef NONUKLEAR
--- a/config.c	Thu Jan 04 22:14:29 2024 -0800
+++ b/config.c	Thu Jan 04 22:56:35 2024 -0800
@@ -316,7 +316,7 @@
 	*pads = tern_insert_node(*pads, key, val.ptrval);
 }
 
-#define CONFIG_VERSION 8
+#define CONFIG_VERSION 9
 static tern_node *migrate_config(tern_node *config, int from_version)
 {
 	tern_node *def_config = parse_bundled_config("default.cfg");
@@ -444,6 +444,42 @@
 		free(exts[0]);//All extensions in this list share an allocation, first one is a pointer to the buffer
 		free(exts);
 	}
+	case 8: {
+		uint32_t num_exts;
+		char **exts = get_extension_list(config, &num_exts);
+		char *need_add[] = {"col"};
+		uint32_t num_need_add = sizeof(need_add)/sizeof(*need_add);
+		for (uint32_t i = 0; i < num_exts && num_need_add; i++)
+		{
+			for (uint32_t j = 0; j < num_need_add; j++)
+			{
+				if (!strcmp(exts[i], need_add[j])) {
+					num_need_add--;
+					need_add[j] = need_add[num_need_add];
+					break;
+				}
+			}
+		}
+		if (num_need_add) {
+			const char **parts = calloc(2 * (num_exts + num_need_add) - 1, sizeof(char*));
+			uint32_t dest = 0;
+			for (uint32_t i = 0; i < num_exts; i++)
+			{
+				parts[dest++] = exts[i];
+				parts[dest++] = " ";
+			}
+			for (uint32_t i = 0; i < num_need_add - 1; i++)
+			{
+				parts[dest++] = need_add[i];
+				parts[dest++] = " ";
+			}
+			parts[dest++] = need_add[num_need_add - 1];
+			config = tern_insert_path(config, "ui\0extensions\0", (tern_val){.ptrval = alloc_concat_m(dest, parts)}, TVAL_PTR);
+			free(parts);
+		}
+		free(exts[0]);//All extensions in this list share an allocation, first one is a pointer to the buffer
+		free(exts);
+	}
 	}
 	char buffer[16];
 	sprintf(buffer, "%d", CONFIG_VERSION);
--- a/debug.c	Thu Jan 04 22:14:29 2024 -0800
+++ b/debug.c	Thu Jan 04 22:56:35 2024 -0800
@@ -17,6 +17,7 @@
 #include "z80inst.h"
 #ifndef NO_Z80
 #include "sms.h"
+#include "coleco.h"
 #endif
 
 #ifdef NEW_CORE
@@ -1815,6 +1816,9 @@
 static debug_val debug_vram_get(debug_array *array, uint32_t index)
 {
 	vdp_context *vdp = array->base;
+	if (!(vdp->regs[REG_MODE_2] & BIT_MODE_5)) {
+		index = mode4_address_map[index & 0x3FFF] ^ 1;
+	}
 	return debug_int(vdp->vdpmem[index]);
 }
 
@@ -1826,6 +1830,9 @@
 		return;
 	}
 	vdp_context *vdp = array->base;
+	if (!(vdp->regs[REG_MODE_2] & BIT_MODE_5)) {
+		index = mode4_address_map[index & 0x3FFF] ^ 1;
+	}
 	vdp->vdpmem[index] = ival;
 }
 
@@ -5178,6 +5185,7 @@
 		z80_names(root);
 		genesis_context *gen;
 		sms_context *sms;
+		coleco_context *coleco;
 		debug_var *var;
 		//TODO: populate names
 		switch (current_system->type)
@@ -5199,6 +5207,11 @@
 			var->ptr = sms->vdp;
 			root->variables = tern_insert_ptr(root->variables, "frame", var);
 			break;
+		case SYSTEM_COLECOVISION:
+			coleco = context->system;
+			root->other_roots = tern_insert_ptr(root->other_roots, "vdp", find_vdp_root(coleco->vdp));
+			root->other_roots = tern_insert_ptr(root->other_roots, "psg", find_psg_root(coleco->psg));
+			break;
 		//default:
 			//root->resolve = resolve_z80;
 		}
--- a/default.cfg	Thu Jan 04 22:14:29 2024 -0800
+++ b/default.cfg	Thu Jan 04 22:56:35 2024 -0800
@@ -401,7 +401,7 @@
 	#accepts special variables $HOME, $EXEDIR, $USERDATA, $ROMNAME
 	save_path $USERDATA/blastem/$ROMNAME
 	#space delimited list of file extensions to filter against in menu
-	extensions bin gen md smd sms gg zip gz cue iso vgm vgz flac wav
+	extensions bin gen md smd sms gg zip gz cue iso vgm vgz flac wav col
 	#specifies the preferred save-state format, set to gst for Genecyst compatible states
 	state_format native
 	#set to on to use the native file picker on your OS instead of the builtin one
@@ -437,4 +437,4 @@
 }
 
 #Don't manually edit `version`, it's used for automatic config migration
-version 8
+version 9
--- a/nuklear_ui/blastem_nuklear.c	Thu Jan 04 22:14:29 2024 -0800
+++ b/nuklear_ui/blastem_nuklear.c	Thu Jan 04 22:56:35 2024 -0800
@@ -2370,6 +2370,8 @@
 		settings_path(context, "US CD BIOS", "system\0scd_bios_us\0", "cdbios.md", exts, 3);
 		settings_path(context, "JP CD BIOS", "system\0scd_bios_jp\0", "cdbios.md", exts, 3);
 		settings_path(context, "EU CD BIOS", "system\0scd_bios_eu\0", "cdbios.md", exts, 3);
+		static const char* coleco_exts[] = {"col", "bin", "rom"};
+		settings_path(context, "Colecovision BIOS", "system\0coleco_bios_path\0", "colecovision_bios.col", coleco_exts, 3);
 		if (nk_button_label(context, "Back")) {
 			pop_view();
 		}
--- a/serialize.h	Thu Jan 04 22:14:29 2024 -0800
+++ b/serialize.h	Thu Jan 04 22:56:35 2024 -0800
@@ -50,7 +50,8 @@
 	SECTION_LC8951,
 	SECTION_RF5C164,
 	SECTION_CDD_FADER,
-	SECTION_CDROM
+	SECTION_CDROM,
+	SECTION_COLECO_IO
 };
 
 void init_serialize(serialize_buffer *buf);
--- a/system.c	Thu Jan 04 22:14:29 2024 -0800
+++ b/system.c	Thu Jan 04 22:56:35 2024 -0800
@@ -4,6 +4,7 @@
 #include "gen_player.h"
 #include "sms.h"
 #include "mediaplayer.h"
+#include "coleco.h"
 
 uint8_t safe_cmp(char *str, long offset, uint8_t *buffer, long filesize)
 {
@@ -39,6 +40,15 @@
 		|| safe_cmp("fLaC", 0, media->buffer, media->size)) {
 		return SYSTEM_MEDIA_PLAYER;
 	}
+	if (
+		(safe_cmp("\xAA\x55", 0, media->buffer, media->size)
+		|| safe_cmp("\x55\xAA", 0, media->buffer, media->size))
+		&& media->size > 0xB) {
+		uint8_t *buffer = media->buffer;
+		if (((buffer[0xB] << 8) | buffer[0xA]) > 0x8000) {
+			return SYSTEM_COLECOVISION;
+		}
+	}
 
 
 	//TODO: Detect Jaguar ROMs here
@@ -54,6 +64,9 @@
 		if (!strcmp("j64", media->extension)) {
 			return SYSTEM_JAGUAR;
 		}
+		if (!strcmp("col", media->extension)) {
+			return SYSTEM_COLECOVISION;
+		}
 	}
 
 	//More certain checks failed, look for a valid 68K reset vector
@@ -87,6 +100,8 @@
 #ifndef NO_Z80
 	case SYSTEM_SMS:
 		return &(alloc_configure_sms(media, opts, force_region))->header;
+	case SYSTEM_COLECOVISION:
+		return &(alloc_configure_coleco(media))->header;
 #endif
 	case SYSTEM_MEDIA_PLAYER:
 		return &(alloc_media_player(media, opts))->header;
--- a/system.h	Thu Jan 04 22:14:29 2024 -0800
+++ b/system.h	Thu Jan 04 22:56:35 2024 -0800
@@ -16,7 +16,8 @@
 	SYSTEM_SMS,
 	SYSTEM_SMS_PLAYER,
 	SYSTEM_JAGUAR,
-	SYSTEM_MEDIA_PLAYER
+	SYSTEM_MEDIA_PLAYER,
+	SYSTEM_COLECOVISION
 } system_type;
 
 typedef enum {