Skip to content

Commit

Permalink
MEGA65: the start of cartridge support #380
Browse files Browse the repository at this point in the history
  • Loading branch information
lgblgblgb committed Jul 28, 2023
1 parent ef5dc3f commit 7c927cb
Show file tree
Hide file tree
Showing 8 changed files with 171 additions and 4 deletions.
4 changes: 2 additions & 2 deletions targets/mega65/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## A work-in-progess MEGA65 (Commodore-65 clone origins) emulator
## Part of the Xemu project, please visit: https://github.com/lgblgblgb/xemu
## Copyright (C)2016-2022 LGB (Gábor Lénárt) <[email protected]>
## Copyright (C)2016-2023 LGB (Gábor Lénárt) <[email protected]>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand All @@ -20,7 +20,7 @@ TARGET = mega65
PRG_TARGET = xmega65
EMU_DESCRIPTION = MEGA65

SRCS_TARGET_xmega65 = configdb.c mega65.c sdcard.c uart_monitor.c hypervisor.c m65_snapshot.c memory_mapper.c io_mapper.c vic4.c vic4_palette.c ethernet65.c input_devices.c memcontent.c ui.c fat32.c sdcontent.c audio65.c inject.c dma65.c rom.c hdos.c matrix_mode.c
SRCS_TARGET_xmega65 = configdb.c mega65.c sdcard.c uart_monitor.c hypervisor.c m65_snapshot.c memory_mapper.c io_mapper.c vic4.c vic4_palette.c ethernet65.c input_devices.c memcontent.c ui.c fat32.c sdcontent.c audio65.c inject.c dma65.c rom.c hdos.c matrix_mode.c cart.c
SRCS_COMMON_xmega65 = emutools.c cpu65.c cia6526.c emutools_hid.c sid.c f011_core.c c64_kbd_mapping.c emutools_config.c emutools_snapshot.c emutools_files.c emutools_umon.c emutools_socketapi.c ethertap.c d81access.c emutools_gui.c basic_text.c opl3.c lodepng.c
CFLAGS_TARGET_xmega65 = $(SDL2_CFLAGS) $(MATH_CFLAGS) $(SOCKET_CFLAGS) $(XEMUGUI_CFLAGS)
LDFLAGS_TARGET_xmega65 = $(SDL2_LIBS) $(MATH_LIBS) $(SOCKET_LIBS) $(XEMUGUI_LIBS)
Expand Down
84 changes: 84 additions & 0 deletions targets/mega65/cart.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/* A work-in-progess MEGA65 (Commodore 65 clone origins) emulator
Part of the Xemu project, please visit: https://github.com/lgblgblgb/xemu
Copyright (C)2016-2023 LGB (Gábor Lénárt) <[email protected]>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */

#include "xemu/emutools.h"
#include "cart.h"
#include "xemu/emutools_files.h"

static Uint8 cart_mem[0x10000];
static int loaded = 0;


void cart_init ( void )
{
memset(cart_mem, 0xFF, sizeof cart_mem);
}


Uint8 cart_read_byte ( unsigned int addr )
{
Uint8 data = 0xFF;
if (addr < sizeof(cart_mem))
data = cart_mem[addr];
DEBUGPRINT("CART: reading byte ($%02X) at $%X" NL, data, addr + 0x4000000);
return data;
}


void cart_write_byte ( unsigned int addr, Uint8 data )
{
DEBUGPRINT("CART: writing byte ($%02X) at $%X" NL, data, addr + 0x4000000);
}


int cart_load_bin ( const char *fn, const unsigned int addr, const char *cry )
{
if (!fn || !*fn)
return 0;
loaded = 0;
if (addr >= sizeof(cart_mem)) {
if (cry)
ERROR_WINDOW("%s\nOutside of 64K range\n%s", cry, fn);
return -1;
}
const int ret = xemu_load_file(fn, cart_mem + addr, 1, sizeof(cart_mem) - addr, cry);
if (ret <= 0)
return -1;
DEBUGPRINT("CART: %d byte(s) loaded at offset $%04X from file %s" NL, ret, addr, fn);
loaded = 1;
return 0;
}


int cart_detect_id ( void )
{
static const Uint8 cart_id[] = {'M', '6', '5'};
return memcmp(cart_mem + 0x8007, cart_id, sizeof cart_id);
}


int cart_is_loaded ( void )
{
return loaded;
}


void cart_copy_from ( const Uint16 cart_addr, Uint8 *target, const Uint16 size )
{
memcpy(target, cart_mem + cart_addr, size);
}
30 changes: 30 additions & 0 deletions targets/mega65/cart.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/* A work-in-progess MEGA65 (Commodore 65 clone origins) emulator
Part of the Xemu project, please visit: https://github.com/lgblgblgb/xemu
Copyright (C)2016-2023 LGB (Gábor Lénárt) <[email protected]>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */

#ifndef XEMU_MEGA65_CART_H_INCLUDED
#define XEMU_MEGA65_CART_H_INCLUDED

extern void cart_init ( void );
extern Uint8 cart_read_byte ( unsigned int addr );
extern void cart_write_byte ( unsigned int addr, Uint8 data );
extern int cart_load_bin ( const char *fn, const unsigned int addr, const char *cry );
extern void cart_copy_from ( const Uint16 cart_addr, Uint8 *target, const Uint16 size );
extern int cart_detect_id ( void );
extern int cart_is_loaded ( void );

#endif
2 changes: 2 additions & 0 deletions targets/mega65/configdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ static const struct xemutools_configdef_str_st str_options[] = {
#endif
{ "gui", NULL, "Select GUI type for usage. Specify some insane str to get a list", &configdb.selectedgui },
{ "importbas", NULL, "Import and RUN BASIC65 program from TEXT file", &configdb.importbas },
{ "cartbin8000",NULL, "Load binary cartridge image from $8000", &configdb.cartbin8000 },
{ NULL }
};

Expand Down Expand Up @@ -151,6 +152,7 @@ static const void *do_not_save_opts[] = {
&emu_is_sleepless, &emu_is_headless, &configdb.testing,
&configdb.dumpmem, &configdb.dumpscreen, &configdb.screenshot_and_exit,
&configdb.testing, &configdb.hyperdebug, &configdb.hyperdebugfreezer, &configdb.usestubrom, &configdb.useinitrom, &configdb.useutilmenu,
&configdb.cartbin8000,
NULL
};

Expand Down
1 change: 1 addition & 0 deletions targets/mega65/configdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ struct configdb_st {
// $60/$61/$62 = qmtecha100t/qmtecha200t/qmtecha325t, $21/$22=megaphoner1/megaphoner4
int mega65_model;
int colour_effect;
char *cartbin8000;
int hicked;
int prgmode;
int rtc_hour_offset;
Expand Down
2 changes: 2 additions & 0 deletions targets/mega65/mega65.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "configdb.h"
#include "xemu/emutools_socketapi.h"
#include "rom.h"
#include "cart.h"

// "Typical" size in default settings (video standard is PAL, default border settings).
// See also vic4.h
Expand Down Expand Up @@ -355,6 +356,7 @@ static void mega65_init ( void )
} while (0);
// *** Initializes memory subsystem of MEGA65 emulation itself
memory_init();
cart_load_bin(configdb.cartbin8000, 0x8000, "Cannot load binary cartridge image from $8000");
// Load contents of NVRAM.
// Also store as "nvram_original" so we can sense on shutdown of the emu, if we need to up-date the on-disk version
// If we fail to load it (does not exist?) it will be written out anyway on exit.
Expand Down
12 changes: 11 additions & 1 deletion targets/mega65/memory_mapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "ethernet65.h"
#include "audio65.h"
#include "sdcard.h"
#include "cart.h"
#include <string.h>

#define ALLOW_CPU_CUSTOM_FUNCTIONS_INCLUDE
Expand Down Expand Up @@ -338,6 +339,14 @@ DEFINE_WRITER(i2c_io_writer) {
break;
}
}
// "Slow device" ~ cardridge space
DEFINE_READER(slowdev_reader) {
return cart_read_byte(GET_READER_OFFSET());
}
DEFINE_WRITER(slowdev_writer) {
cart_write_byte(GET_WRITER_OFFSET(), data);
}

// Not implemented yet, just here, since freezer accesses this memory area, and without **some** dummy
// support, it would cause "unhandled memory access" warning in Xemu.
DEFINE_READER(mem1541_reader) {
Expand Down Expand Up @@ -372,7 +381,7 @@ static const struct m65_memory_map_st m65_memory_map[] = {
{ 0xFFD7000, 0xFFD7FFF, i2c_io_reader, i2c_io_writer }, // I2C devices
{ 0x8000000, 0x8000000 + SLOW_RAM_SIZE - 1, slow_ram_reader, slow_ram_writer }, // "slow RAM" also called "hyper RAM" (not to be confused with hypervisor RAM!)
{ 0x8000000 + SLOW_RAM_SIZE, 0xFDFFFFF, dummy_reader, dummy_writer }, // ununsed big part of the "slow RAM" or so ...
{ 0x4000000, 0x7FFFFFF, dummy_reader, dummy_writer }, // slow RAM memory area, not exactly known what it's for, let's define as "dummy"
{ 0x4000000, 0x7FFFFFF, slowdev_reader, slowdev_writer }, // slow RAM memory area ~ cartridge
{ 0xFE00000, 0xFE000FF, opl3_reader, opl3_writer },
{ 0x60000, 0xFFFFF, dummy_reader, dummy_writer }, // upper "unused" area of C65 (!) memory map. It seems C65 ROMs want it (Expansion RAM?) so we define as unused.
{ 0xFFDB000, 0xFFDFFFF, mem1541_reader, mem1541_writer }, // 1541's 16K ROM + 4K RAM, not so much used currently, but freezer seems to access it, for example ...
Expand Down Expand Up @@ -498,6 +507,7 @@ void memory_init ( void )
memset(D6XX_registers, 0, sizeof D6XX_registers);
memset(D7XX, 0xFF, sizeof D7XX);
memset(i2c_regs, 0, sizeof i2c_regs);
cart_init();
rom_protect = 0;
in_hypervisor = 0;
for (a = 0; a < MEM_SLOTS; a++) {
Expand Down
40 changes: 39 additions & 1 deletion targets/mega65/ui.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "hypervisor.h"
#include "xemu/cpu65.h"
#include "xemu/emutools_config.h"
#include "cart.h"


// Used by UI CBs to maintain configDB persistence
Expand Down Expand Up @@ -653,10 +654,46 @@ static void ui_cb_colour_effect ( const struct menu_st *m, int *query )
vic4_set_emulation_colour_effect(VOIDPTR_TO_INT(m->user_data));
}

static void ui_cb_load_bin_cart ( const struct menu_st *m, int *query )
{
char fnbuf[PATH_MAX + 1];
static char dir[PATH_MAX + 1] = "";
_check_file_selection_default_override(dir);
if (!xemugui_file_selector(
XEMUGUI_FSEL_OPEN | XEMUGUI_FSEL_FLAG_STORE_DIR,
"Select binary cartridge",
dir,
fnbuf,
sizeof fnbuf
)) {
if (!cart_load_bin(fnbuf, VOIDPTR_TO_INT(m->user_data), "Cannot load binary cartridge"))
xemucfg_set_str(&configdb.cartbin8000, fnbuf);
} else
DEBUGPRINT("UI: file selection for PRG injection was cancelled." NL);
}

static void ui_start_cartridge ( void )
{
if (!cart_is_loaded()) {
ERROR_WINDOW("No cartridge is loaded yet.");
return;
}
if (cart_detect_id()) {
INFO_WINDOW("Cartridge signature M65 not detected. Start with your own risk.");
}
cart_copy_from(0x8000, main_ram + 0x8000, 0x2000);
INFO_WINDOW("Copied. Type BANK0:SYS$8000 to start");
}


/**** MENU SYSTEM ****/


static const struct menu_st menu_cartridge[] = {
{ "Load BIN cartridge to $8000",XEMUGUI_MENUID_CALLABLE, ui_cb_load_bin_cart, (void*)0x8000 },
{ "Start cartridge", XEMUGUI_MENUID_CALLABLE, xemugui_cb_call_user_data, ui_start_cartridge },
{ NULL }
};
static const struct menu_st menu_colour_effects[] = {
{ "Normal colours", XEMUGUI_MENUID_CALLABLE | XEMUGUI_MENUFLAG_QUERYBACK, ui_cb_colour_effect, (void*)0 },
{ "Grayscale", XEMUGUI_MENUID_CALLABLE | XEMUGUI_MENUFLAG_QUERYBACK, ui_cb_colour_effect, (void*)1 },
Expand Down Expand Up @@ -857,6 +894,7 @@ static const struct menu_st menu_disks[] = {
{ "Drive-8", XEMUGUI_MENUID_SUBMENU, NULL, menu_drv8 },
{ "Drive-9", XEMUGUI_MENUID_SUBMENU, NULL, menu_drv9 },
{ "SD-card", XEMUGUI_MENUID_SUBMENU, NULL, menu_sdcard },
{ "Cartridge", XEMUGUI_MENUID_SUBMENU, NULL, menu_cartridge },
{ NULL }
};
static const struct menu_st menu_audio_stereo[] = {
Expand Down Expand Up @@ -942,7 +980,7 @@ static const struct menu_st menu_main[] = {
{ "Display", XEMUGUI_MENUID_SUBMENU, NULL, menu_display },
{ "Input devices", XEMUGUI_MENUID_SUBMENU, NULL, menu_inputdevices },
{ "Audio", XEMUGUI_MENUID_SUBMENU, NULL, menu_audio },
{ "Disks", XEMUGUI_MENUID_SUBMENU, NULL, menu_disks },
{ "Disks / Cart", XEMUGUI_MENUID_SUBMENU, NULL, menu_disks },
{ "Reset / ROM switching", XEMUGUI_MENUID_SUBMENU, NULL, menu_reset },
{ "Debug / Advanced", XEMUGUI_MENUID_SUBMENU, NULL, menu_debug },
{ "Configuration", XEMUGUI_MENUID_SUBMENU, NULL, menu_config },
Expand Down

0 comments on commit 7c927cb

Please sign in to comment.