From 16a902fad26ea3f63550af1e4cccd2dac7d7cce3 Mon Sep 17 00:00:00 2001 From: beeanyew Date: Wed, 23 Jun 2021 04:42:58 +0200 Subject: [PATCH] Add some more Mac68k handling stuff --- Makefile | 1 + emulator.c | 9 +- m68k.h | 1 + m68kcpu.c | 34 ++++++- m68kmmu.h | 3 + mac68k.cfg | 3 +- platforms/mac68k/mac68k-platform.c | 156 +++++++++++++++++++++++++++++ platforms/platforms.c | 5 +- platforms/platforms.h | 2 + 9 files changed, 205 insertions(+), 9 deletions(-) create mode 100644 platforms/mac68k/mac68k-platform.c diff --git a/Makefile b/Makefile index 942b4a9..ed7fbf6 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,7 @@ MAINFILES = emulator.c \ platforms/amiga/amiga-autoconf.c \ platforms/amiga/amiga-platform.c \ platforms/amiga/amiga-registers.c \ + platforms/mac68k/mac68k-platform.c \ platforms/dummy/dummy-platform.c \ platforms/dummy/dummy-registers.c \ platforms/amiga/Gayle.c \ diff --git a/emulator.c b/emulator.c index 4d2fc8a..968f52e 100644 --- a/emulator.c +++ b/emulator.c @@ -629,13 +629,10 @@ switch_config: void cpu_pulse_reset(void) { m68ki_cpu_core *state = &m68ki_cpu; ps_pulse_reset(); - if (cfg->platform->handle_reset) - cfg->platform->handle_reset(cfg); - //m68k_write_memory_16(INTENA, 0x7FFF); ovl = 1; - //m68k_write_memory_8(0xbfe201, 0x0001); // AMIGA OVL - //m68k_write_memory_8(0xbfe001, 0x0001); // AMIGA OVL high (ROM@0x0) + if (cfg->platform->handle_reset) + cfg->platform->handle_reset(cfg); m68k_pulse_reset(state); } @@ -954,9 +951,11 @@ static inline int32_t platform_write_check(uint8_t type, uint32_t addr, uint32_t if (val & 0x10 && !ovl) { ovl = 1; printf("[MAC] OVL on.\n"); + handle_ovl_mappings_mac68k(cfg); } else if (ovl) { ovl = 0; printf("[MAC] OVL off.\n"); + handle_ovl_mappings_mac68k(cfg); } break; } diff --git a/m68k.h b/m68k.h index a838118..ce9e648 100644 --- a/m68k.h +++ b/m68k.h @@ -212,6 +212,7 @@ void m68k_write_memory_32(unsigned int address, unsigned int value); /* PiStorm speed hax */ void m68k_add_ram_range(uint32_t addr, uint32_t upper, unsigned char *ptr); void m68k_add_rom_range(uint32_t addr, uint32_t upper, unsigned char *ptr); +void m68k_remove_range(unsigned char *ptr); void m68k_clear_ranges(); /* Special call to simulate undocumented 68k behavior when move.l with a diff --git a/m68kcpu.c b/m68kcpu.c index 1068f26..b384e2b 100644 --- a/m68kcpu.c +++ b/m68kcpu.c @@ -1316,8 +1316,12 @@ void m68k_add_ram_range(uint32_t addr, uint32_t upper, unsigned char *ptr) return; for (int i = 0; i < m68ki_cpu.write_ranges; i++) { - if (m68ki_cpu.write_addr[i] == addr) { + if (m68ki_cpu.write_addr[i] == addr || m68ki_cpu.write_data[i] == ptr) { uint8_t changed = 0; + if (m68ki_cpu.write_addr[i] != addr) { + m68ki_cpu.write_addr[i] = addr; + changed = 1; + } if (m68ki_cpu.write_upper[i] != upper) { m68ki_cpu.write_upper[i] = upper; changed = 1; @@ -1363,8 +1367,12 @@ void m68k_add_rom_range(uint32_t addr, uint32_t upper, unsigned char *ptr) return; for (int i = 0; i < m68ki_cpu.read_ranges; i++) { - if (m68ki_cpu.read_addr[i] == addr) { + if (m68ki_cpu.read_addr[i] == addr || m68ki_cpu.read_data[i] == ptr) { uint8_t changed = 0; + if (m68ki_cpu.read_addr[i] != addr) { + m68ki_cpu.read_addr[i] = addr; + changed = 1; + } if (m68ki_cpu.read_upper[i] != upper) { m68ki_cpu.read_upper[i] = upper; changed = 1; @@ -1392,6 +1400,28 @@ void m68k_add_rom_range(uint32_t addr, uint32_t upper, unsigned char *ptr) } } +void m68k_remove_range(unsigned char *ptr) { + if (!ptr) { + return; + } + + // FIXME: Replace the 8 with a #define, such as MAX_MUSASHI_RANGES + for (int i = 0; i < 8; i++) { + if (m68ki_cpu.read_data[i] == ptr) { + m68ki_cpu.read_data[i] = NULL; + m68ki_cpu.read_addr[i] = 0; + m68ki_cpu.read_upper[i] = 0; + printf("[MUSASHI] Unmapped read range %d.\n", i); + } + if (m68ki_cpu.write_data[i] == ptr) { + m68ki_cpu.write_data[i] = NULL; + m68ki_cpu.write_addr[i] = 0; + m68ki_cpu.write_upper[i] = 0; + printf("[MUSASHI] Unmapped write range %d.\n", i); + } + } +} + void m68k_clear_ranges() { printf("[MUSASHI] Clearing all reads/write memory ranges.\n"); diff --git a/m68kmmu.h b/m68kmmu.h index 364c183..3a9c6e5 100644 --- a/m68kmmu.h +++ b/m68kmmu.h @@ -356,6 +356,9 @@ uint16 pmmu_match_tt(m68ki_cpu_core *state, uint32 addr_in, int fc, uint32 tt, u void update_descriptor(m68ki_cpu_core *state, uint32 tptr, int type, uint32 entry, int16 rw) { + // FIXME: Silence unused variable warning + if (state) {} + if (type == M68K_MMU_DF_DT_PAGE && !rw && !(entry & M68K_MMU_DF_MODIFIED) && !(entry & M68K_MMU_DF_WP)) diff --git a/mac68k.cfg b/mac68k.cfg index 7ff1c7a..f1ea160 100644 --- a/mac68k.cfg +++ b/mac68k.cfg @@ -3,8 +3,9 @@ cpu 68EC020 # Map any size ROM to a the (max) 512KB KB system ROM default address with OVL enabled. +# The id=sysrom and id=sysram for the ROM and WTC RAM are necessary in order for the 68k Mac's OVL to function properly. # (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 type=rom address=0x400000 size=512K file=system.rom 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 diff --git a/platforms/mac68k/mac68k-platform.c b/platforms/mac68k/mac68k-platform.c new file mode 100644 index 0000000..e750321 --- /dev/null +++ b/platforms/mac68k/mac68k-platform.c @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: MIT + +#include +#include +#include +#include +#include "platforms/platforms.h" +#include "platforms/shared/rtc.h" + +//#define DEBUG_MAC_PLATFORM + +#ifdef DEBUG_MAC_PLATFORM +#define DEBUG printf +#else +#define DEBUG(...) +#endif + +#define min(a, b) (a < b) ? a : b +#define max(a, b) (a > b) ? a : b + +extern void stop_cpu_emulation(uint8_t disasm_cur); + +uint8_t iscsi_enabled; + +extern int kb_hook_enabled; +extern int mouse_hook_enabled; +extern unsigned int ovl; + +void adjust_ranges_mac68k(struct emulator_config *cfg) { + cfg->mapped_high = 0; + cfg->mapped_low = 0; + cfg->custom_high = 0; + cfg->custom_low = 0; + + // Set up the min/max ranges for mapped reads/writes + for (int i = 0; i < MAX_NUM_MAPPED_ITEMS; i++) { + if (cfg->map_type[i] != MAPTYPE_NONE) { + if ((cfg->map_offset[i] != 0 && cfg->map_offset[i] < cfg->mapped_low) || cfg->mapped_low == 0) + cfg->mapped_low = cfg->map_offset[i]; + if (cfg->map_offset[i] + cfg->map_size[i] > cfg->mapped_high) + cfg->mapped_high = cfg->map_offset[i] + cfg->map_size[i]; + } + } + + printf("[MAC68K] Platform custom range: %.8X-%.8X\n", cfg->custom_low, cfg->custom_high); + printf("[MAC68K] Platform mapped range: %.8X-%.8X\n", cfg->mapped_low, cfg->mapped_high); +} + + +int setup_platform_mac68k(struct emulator_config *cfg) { + printf("Performing setup for Mac68k platform.\n"); + + if (strlen(cfg->platform->subsys)) { + printf("Sub system %sd specified, but no handler is available for this.\n", cfg->platform->subsys); + } + else + printf("No sub system specified.\n"); + + handle_ovl_mappings_mac68k(cfg); + + return 0; +} + +#define CHKVAR(a) (strcmp(var, a) == 0) + +void setvar_mac68k(struct emulator_config *cfg, char *var, char *val) { + if (!var) + return; + + // FIXME: Silence unused variable warnings. + if (var || cfg || val) {} + + if (CHKVAR("iscsi") && !iscsi_enabled) { + printf("[MAC68K] iSCSI Interface Enabled... well, not really.\n"); + iscsi_enabled = 1; + //iscsi_init(); + //adjust_ranges_mac68k(cfg); + } +} + +void handle_ovl_mappings_mac68k(struct emulator_config *cfg) { + int32_t index = -1; + + index = get_named_mapped_item(cfg, "sysrom"); + if (index != -1) { + cfg->map_offset[index] = (ovl) ? 0x0 : 0x400000; + cfg->map_high[index] = cfg->map_size[index]; + m68k_remove_range(cfg->map_data[index]); + m68k_add_rom_range((uint32_t)cfg->map_offset[index], (uint32_t)cfg->map_high[index], cfg->map_data[index]); + printf("[MAC68K] Added memory mapping for Mac68k System ROM.\n"); + } else { + printf ("[MAC68K] No sysrom mapping found. If you intended to memory map a system ROM, make sure it has the correct ID.\n"); + } + index = get_named_mapped_item(cfg, "sysram"); + if (index != -1) { + cfg->map_offset[index] = (ovl) ? 0x400000 : 0x0; + cfg->map_high[index] = cfg->map_size[index]; + m68k_remove_range(cfg->map_data[index]); + m68k_add_ram_range((uint32_t)cfg->map_offset[index], (uint32_t)cfg->map_high[index], cfg->map_data[index]); + printf("[MAC68K] Added memory mapping for Mac68k System RAM.\n"); + } else { + printf ("[MAC68K] No sysram mapping found. If you intended to memory map a system RAM, make sure it has the correct ID.\n"); + } + + adjust_ranges_mac68k(cfg); +} + +void handle_reset_mac68k(struct emulator_config *cfg) { + DEBUG("[MAC68K] Reset handler.\n"); + + if (iscsi_enabled) { + //iscsi_refresh_drives(); + } + + handle_ovl_mappings_mac68k(cfg); +} + +void shutdown_platform_mac68k(struct emulator_config *cfg) { + printf("[MAC68K] Performing Mac68k platform shutdown.\n"); + if (cfg) {} + + if (cfg->platform->subsys) { + free(cfg->platform->subsys); + cfg->platform->subsys = NULL; + } + if (iscsi_enabled) { + //iscsi_shutdown(); + iscsi_enabled = 0; + } + + mouse_hook_enabled = 0; + kb_hook_enabled = 0; + + printf("[MAC68K] Platform shutdown completed.\n"); +} + +void create_platform_mac68k(struct platform_config *cfg, char *subsys) { + cfg->register_read = NULL; + cfg->register_write = NULL; + cfg->custom_read = NULL; + cfg->custom_write = NULL; + cfg->platform_initial_setup = setup_platform_mac68k; + cfg->handle_reset = handle_reset_mac68k; + cfg->shutdown = shutdown_platform_mac68k; + + cfg->setvar = setvar_mac68k; + cfg->id = PLATFORM_MAC; + + if (subsys) { + cfg->subsys = malloc(strlen(subsys) + 1); + strcpy(cfg->subsys, subsys); + for (unsigned int i = 0; i < strlen(cfg->subsys); i++) { + cfg->subsys[i] = tolower(cfg->subsys[i]); + } + } +} diff --git a/platforms/platforms.c b/platforms/platforms.c index 4d301b4..a272de8 100644 --- a/platforms/platforms.c +++ b/platforms/platforms.c @@ -24,6 +24,7 @@ int get_platform_index(char *name) { } void create_platform_amiga(struct platform_config *cfg, char *subsys); +void create_platform_mac68k(struct platform_config *cfg, char *subsys); void create_platform_dummy(struct platform_config *cfg, char *subsys); struct platform_config *make_platform_config(char *name, char *subsys) { @@ -50,8 +51,10 @@ struct platform_config *make_platform_config(char *name, char *subsys) { case PLATFORM_AMIGA: create_platform_amiga(cfg, subsys); break; - case PLATFORM_NONE: case PLATFORM_MAC: + create_platform_mac68k(cfg, subsys); + break; + case PLATFORM_NONE: case PLATFORM_X68000: default: create_platform_dummy(cfg, subsys); diff --git a/platforms/platforms.h b/platforms/platforms.h index a88bda8..6cd93e2 100644 --- a/platforms/platforms.h +++ b/platforms/platforms.h @@ -14,3 +14,5 @@ struct platform_config *make_platform_config(char *name, char *subsys); void dump_range_to_file(uint32_t addr, uint32_t size, char *filename); uint8_t *dump_range_to_memory(uint32_t addr, uint32_t size); + +void handle_ovl_mappings_mac68k(struct emulator_config *cfg); -- 2.39.2