From ce1c064e71706992b3de778af96aa9321575b114 Mon Sep 17 00:00:00 2001 From: beeanyew Date: Tue, 22 Jun 2021 13:13:13 +0200 Subject: [PATCH] Add write-through cached RAM for Mac experiments --- config_file/config_file.c | 15 ++++++++++++- config_file/config_file.h | 1 + default.cfg | 11 +++++++++- mac68k.cfg | 45 +++++++++++++++++++++++++++++++++++++++ memory_mapped.c | 25 +++++++++++++++------- 5 files changed, 87 insertions(+), 10 deletions(-) create mode 100644 mac68k.cfg diff --git a/config_file/config_file.c b/config_file/config_file.c index 12ba4b4..f848ba5 100644 --- a/config_file/config_file.c +++ b/config_file/config_file.c @@ -27,7 +27,8 @@ const char *map_type_names[MAPTYPE_NUM] = { "rom", "ram", "register", - "ram (no alloc)", + "ram_noalloc", + "wtcram", }; const char *config_item_names[CONFITEM_NUM] = { @@ -213,6 +214,9 @@ void add_mapping(struct emulator_config *cfg, unsigned int type, unsigned int ad cfg->map_high[index] = addr + size; cfg->map_mirror[index] = mirr_addr; if (strlen(map_id)) { + if (cfg->map_id[index]) { + free(cfg->map_id[index]); + } cfg->map_id[index] = (char *)malloc(strlen(map_id) + 1); strcpy(cfg->map_id[index], map_id); } @@ -222,14 +226,23 @@ void add_mapping(struct emulator_config *cfg, unsigned int type, unsigned int ad printf("[CFG] Adding %d byte (%d MB) RAM mapping %s...\n", size, size / 1024 / 1024, map_id); cfg->map_data[index] = (unsigned char *)filename; break; + case MAPTYPE_RAM_WTC: + printf("[CFG] Allocating %d bytes for Write-Through Cached RAM mapping (%.1f MB)...\n", size, (float)size / 1024.0f / 1024.0f); + goto alloc_mapram; + break; case MAPTYPE_RAM: printf("[CFG] Allocating %d bytes for RAM mapping (%d MB)...\n", size, size / 1024 / 1024); +alloc_mapram: cfg->map_data[index] = (unsigned char *)malloc(size); if (!cfg->map_data[index]) { printf("[CFG] ERROR: Unable to allocate memory for mapped RAM!\n"); goto mapping_failed; } memset(cfg->map_data[index], 0x00, size); + if (type == MAPTYPE_RAM_WTC) { + // This may look a bit weird, but it adds a read range for the WTC RAM. Writes still go through to the mapped read/write functions. + m68k_add_rom_range(cfg->map_offset[index], cfg->map_high[index], cfg->map_data[index]); + } break; case MAPTYPE_ROM: in = fopen(filename, "rb"); diff --git a/config_file/config_file.h b/config_file/config_file.h index 841f802..cb82603 100644 --- a/config_file/config_file.h +++ b/config_file/config_file.h @@ -18,6 +18,7 @@ typedef enum { MAPTYPE_RAM, MAPTYPE_REGISTER, MAPTYPE_RAM_NOALLOC, + MAPTYPE_RAM_WTC, MAPTYPE_NUM, } map_types; diff --git a/default.cfg b/default.cfg index 2716c3e..e34ba30 100644 --- a/default.cfg +++ b/default.cfg @@ -33,7 +33,11 @@ map type=register address=0xDC0000 size=0x10000 loopcycles 300 # Set the platform to Amiga to enable all the registers and stuff. platform amiga -# Uncomment to let reads/writes through from/to the RTC memory range +# Uncommenting the below this long comment DISABLES RTC emulation, letting reads/writes through to the RTC memory range. +# There is no need to uncomment it unless you are either using a CDTV, you want to use a physical RTC source present +# inside the computer, such as on a trapdoor memory expansion board, or if you have a physical A314 intalled, since the +# A314 uses the RTC address range to communicate with the Amiga, and enabling RTC emulation # blocks this communication completely. +# DO NOT UNCOMMENT THE LINE BELOW UNLESS YOU'VE READ AND UNDERSTOOD THE FIVE LINES ABOVE THIS ONE. #setvar enable_rtc_emulation 0 # Uncomment to enable RTG #setvar rtg @@ -55,6 +59,11 @@ setvar piscsi6 platforms/amiga/pistorm.hdf # Uncomment to enable A314 emulation #setvar a314 +# Please take note: +# At the time of writing this (22 Jun 2021), the mouse and keyboard forwarding (for Amiga only) is by no means perfect. +# It works properly in Workbench, and in a number of games and applications, but it does not work for everything. +# Do not rely on the mouse and keyboard forwarding as your only means of input for the host computer. + # Forward keyboard events to host system, defaults to off unless toggle key is pressed, toggled off using F12. # Syntax: keyboard [grab key] [grab|nograb] [autoconnect|noautoconnect] # "grab" steals the keyboard from the Pi so Amiga/etc. input is not sent to the Pi diff --git a/mac68k.cfg b/mac68k.cfg new file mode 100644 index 0000000..7ff1c7a --- /dev/null +++ b/mac68k.cfg @@ -0,0 +1,45 @@ +# CPU type is by default 68EC020, try 68000 or 68010 if EC020 doesn't work with the ROM. +# (CPU support on classic Macs seem to be severely limited by the system ROM used, and later ROMs are needed for any 32-bit CPU.) +cpu 68EC020 + +# Map any size ROM to a the (max) 512KB KB system ROM default address with OVL enabled. +# (From what I could tell, the ROM was mirrored across this entire 512KB space regardless of physical capacity.) +map type=rom address=0x400000 size=512K file=system.rom ovl=0 id=sysrom + +# Map X KB/MB of RAM starting at $0. The type of this RAM map is "wtcram", which is short for Write Through Cache RAM. +# It appears that the Mac Classic sound/video chips can't write to RAM, only read from it, so this should be sufficient +# unless there's something I've missed. Only uncomment one of these lines at any time, depending on how much physical RAM is installed. +#map type=wtcram address=0x0 size=128K id=sysram +#map type=wtcram address=0x0 size=256K id=sysram +#map type=wtcram address=0x0 size=512K id=sysram +#map type=wtcram address=0x0 size=1M id=sysram +#map type=wtcram address=0x0 size=2M id=sysram +#map type=wtcram address=0x0 size=2560K id=sysram +#map type=wtcram address=0x0 size=4M id=sysram + +# Number of instructions to run every main loop. +loopcycles 300 +# Set the platform to Mac68k to enable all the registers and stuff. +platform mac68k + +#setvar iscsi +# ... Just kidding! +#setvar iscsi0 system.hdf +#setvar iscsi1 simcity2000.hdf + +# No keyboard/mouse forwarding is available for Mac68k, and uncommenting any of these lines won't do anything. +# Forward keyboard events to host system, defaults to off unless toggle key is pressed, toggled off using F12. +# Syntax: keyboard [grab key] [grab|nograb] [autoconnect|noautoconnect] +# "grab" steals the keyboard from the Pi so Amiga/etc. input is not sent to the Pi +# (also helps prevent sending any ctrl-alt-del to the Amiga from resetting the Pi) +# +# "autoconnect" connects the keyboard to the Amiga/etc. on startup +#keyboard k nograb noautoconnect +# Select a specific filename for the keyboard event source. +# This is typically /dev/input/event1 or event0, but it may be event3 with for instance a wireless keyboard. +# Use ls /dev/input/event* to check which event files are available and try until you find the one that works. +#kbfile /dev/input/event1 +# Forward mouse events to host system, defaults to off unless toggle key is pressed on the Pi. +# Syntax is mouse [device] [toggle key] [autoconnect|noautoconnect] +# (see "keyboard" above for autoconnect description) +#mouse /dev/input/mice m noautoconnect diff --git a/memory_mapped.c b/memory_mapped.c index c3a02be..372485d 100644 --- a/memory_mapped.c +++ b/memory_mapped.c @@ -38,6 +38,8 @@ inline int handle_mapped_read(struct emulator_config *cfg, unsigned int addr, un goto read_value; break; case MAPTYPE_RAM: + case MAPTYPE_RAM_WTC: + case MAPTYPE_RAM_NOALLOC: read_addr = cfg->map_data[i] + (addr - cfg->map_offset[i]); goto read_value; break; @@ -57,7 +59,6 @@ inline int handle_mapped_read(struct emulator_config *cfg, unsigned int addr, un return -1; read_value:; - //printf("Read value from %.8X\n", addr); switch(type) { case OP_TYPE_BYTE: *val = read_addr[0]; @@ -80,6 +81,7 @@ read_value:; } inline int handle_mapped_write(struct emulator_config *cfg, unsigned int addr, unsigned int value, unsigned char type) { + int res = -1; unsigned char *write_addr = NULL; for (int i = 0; i < MAX_NUM_MAPPED_ITEMS; i++) { @@ -88,10 +90,17 @@ inline int handle_mapped_write(struct emulator_config *cfg, unsigned int addr, u else if (CHKRANGE_ABS(addr, cfg->map_offset[i], cfg->map_high[i])) { switch(cfg->map_type[i]) { case MAPTYPE_ROM: - return 1; + res = 1; break; case MAPTYPE_RAM: + case MAPTYPE_RAM_NOALLOC: write_addr = cfg->map_data[i] + (addr - cfg->map_offset[i]); + res = 1; + goto write_value; + break; + case MAPTYPE_RAM_WTC: + write_addr = cfg->map_data[i] + (addr - cfg->map_offset[i]); + res = -1; goto write_value; break; case MAPTYPE_REGISTER: @@ -103,27 +112,27 @@ inline int handle_mapped_write(struct emulator_config *cfg, unsigned int addr, u } } - return -1; + return res; write_value:; - //printf("Write value to %.8X\n", addr); switch(type) { case OP_TYPE_BYTE: write_addr[0] = (unsigned char)value; - return 1; + return res; break; case OP_TYPE_WORD: ((short *)write_addr)[0] = htobe16(value); - return 1; + return res; break; case OP_TYPE_LONGWORD: ((int *)write_addr)[0] = htobe32(value); - return 1; + return res; break; case OP_TYPE_MEM: return -1; break; } - return 1; + // This should never actually happen. + return res; } -- 2.39.2