From aa872670359c1df1d5b99a39cb78ae697632775e Mon Sep 17 00:00:00 2001 From: beeanyew Date: Fri, 1 Jan 2021 01:24:04 +0100 Subject: [PATCH] Fix a bunch of stuff, add working RICOH RTC emulation. The MSM/OKI RTC emulation probably also works, but DiagROM seems to be reading it wrong. --- Gayle.c | 192 +++++++++++++++++++++++++++++- config_file/config_file.c | 3 +- emulator.c | 6 +- memory_mapped.c | 4 +- platforms/amiga/amiga-registers.h | 13 +- 5 files changed, 211 insertions(+), 7 deletions(-) diff --git a/Gayle.c b/Gayle.c index 8ed0448..f07bf2a 100644 --- a/Gayle.c +++ b/Gayle.c @@ -16,7 +16,11 @@ #include #include #include +#include +#include #include "ide.h" +#include "config_file/config_file.h" +#include "platforms/amiga/amiga-registers.h" //#define GSTATUS 0xda201c //#define GCLOW 0xda2010 @@ -45,7 +49,7 @@ #define GCS 0xDA8000 // Card Control #define GIRQ 0xDA9000 // IRQ #define GINT 0xDAA000 // Int enable -#define GCONF 0xDAB00 // Gayle Config +#define GCONF 0xDAB000 // Gayle Config /* DA8000 */ #define GAYLE_CS_IDE 0x80 /* IDE int status */ @@ -93,6 +97,8 @@ static uint8_t gayle_irq, gayle_int, gayle_cs, gayle_cs_mask, gayle_cfg; static struct ide_controller *ide0; int fd; +uint8_t rtc_type = RTC_TYPE_RICOH; + char *hdd_image_file[GAYLE_MAX_HARDFILES]; void set_hard_drive_image_file_amiga(uint8_t index, char *filename) { @@ -198,6 +204,15 @@ void writeGayleB(unsigned int address, unsigned int value) { return; } + if ((address & GAYLEMASK) == CLOCKBASE) { + if ((address & CLOCKMASK) >= 0x8000) { + printf("Byte write to CDTV SRAM?\n"); + return; + } + put_rtc_byte(address, value, rtc_type); + return; + } + printf("Write Byte to Gayle Space 0x%06x (0x%06x)\n", address, value); } @@ -207,13 +222,164 @@ void writeGayle(unsigned int address, unsigned int value) { return; } + if ((address & GAYLEMASK) == CLOCKBASE) { + if ((address & CLOCKMASK) >= 0x8000) { + printf("Word write to CDTV SRAM?\n"); + return; + } + printf("Word write to RTC.\n"); + put_rtc_byte(address, (value & 0xFF), rtc_type); + put_rtc_byte(address + 1, (value >> 8), rtc_type); + return; + } + printf("Write Word to Gayle Space 0x%06x (0x%06x)\n", address, value); } void writeGayleL(unsigned int address, unsigned int value) { + if ((address & GAYLEMASK) == CLOCKBASE) { + if ((address & CLOCKMASK) >= 0x8000) { + printf("Longword write to CDTV SRAM?\n"); + return; + } + printf("Longword write to RTC.\n"); + put_rtc_byte(address, (value & 0xFF), rtc_type); + put_rtc_byte(address + 1, ((value & 0x0000FF00) >> 8), rtc_type); + put_rtc_byte(address + 2, ((value & 0x00FF0000) >> 16), rtc_type); + put_rtc_byte(address + 3, (value >> 24), rtc_type); + return; + } + printf("Write Long to Gayle Space 0x%06x (0x%06x)\n", address, value); } +static unsigned char rtc_mystery_reg[3]; + +void put_rtc_byte(uint32_t address_, uint8_t value, uint8_t rtc_type) { + uint32_t address = address_ & 0x3F; + address >>= 2; + if (rtc_type == RTC_TYPE_MSM) { + switch(address) { + case 0x0D: + rtc_mystery_reg[address - 0x0D] = value & (0x01 | 0x08); + break; + case 0x0E: + case 0x0F: + rtc_mystery_reg[address - 0x0D] = value; + break; + default: + return; + } + } + else { + int rtc_bank = (rtc_mystery_reg[0] & 0x03); + if ((rtc_bank & 0x02) && address < 0x0D) { + // RTC memory access? + printf("Write to Ricoh RTC memory.\n"); + return; + } + else if ((rtc_bank & 0x01) && address < 0x0D) { + // RTC alarm access? + printf("Write to Ricoh RTC alarm.\n"); + return; + } + else if (address >= 0x0D) { + rtc_mystery_reg[address - 0x0D] = value; + return; + } + } +} + +uint8_t get_rtc_byte(uint32_t address_, uint8_t rtc_type) { + uint32_t address = address_; + address >>= 2; + time_t t; + time(&t); + struct tm *rtc_time = localtime(&t); + + if (rtc_type == RTC_TYPE_RICOH) { + int rtc_bank = (rtc_mystery_reg[0] & 0x03); + if ((rtc_bank & 0x02) && address < 0x0D) { + // RTC memory access? + printf("Read from Ricoh RTC memory.\n"); + return 0; + } + else if ((rtc_bank & 0x01) && address < 0x0D) { + // RTC alarm access? + printf("Read from Ricoh RTC alarm.\n"); + return 0; + } + } + + switch (address) { + case 0x00: // Seconds low? + return rtc_time->tm_sec % 10; + case 0x01: // Seconds high? + return rtc_time->tm_sec / 10; + case 0x02: // Minutes low? + return rtc_time->tm_min % 10; + case 0x03: // Minutes high? + return rtc_time->tm_min / 10; + case 0x04: // Hours low? + return rtc_time->tm_hour % 10; + case 0x05: // Hours high? + if (rtc_type == RTC_TYPE_MSM) { + if (rtc_mystery_reg[2] & 4) { + return ((rtc_time->tm_hour / 10) | (rtc_time->tm_hour > 12) ? 0x04 : 0x00); + } + else + return rtc_time->tm_hour / 10; + } + else { + break; + } + case 0x06: // Day low? + if (rtc_type == RTC_TYPE_MSM) + return rtc_time->tm_mday % 10; + else + return rtc_time->tm_wday; + case 0x07: // Day high? + if (rtc_type == RTC_TYPE_MSM) + return rtc_time->tm_mday / 10; + else + return rtc_time->tm_mday % 10; + case 0x08: // Month low? + if (rtc_type == RTC_TYPE_MSM) + return (rtc_time->tm_mon + 1) % 10; + else + return rtc_time->tm_mday / 10; + case 0x09: // Month high? + if (rtc_type == RTC_TYPE_MSM) + return (rtc_time->tm_mon + 1) / 10; + else + return (rtc_time->tm_mon + 1) % 10; + case 0x0A: // Year low? + if (rtc_type == RTC_TYPE_MSM) + return rtc_time->tm_year % 10; + else + return (rtc_time->tm_mon + 1) / 10; + case 0x0B: // Year high? + if (rtc_type == RTC_TYPE_MSM) + return rtc_time->tm_year / 10; + else + return rtc_time->tm_year % 10; + case 0x0C: // Day of week? + if (rtc_type == RTC_TYPE_MSM) + return rtc_time->tm_wday; + else + return rtc_time->tm_year / 10; + case 0x0D: // Mystery register D-F? + return rtc_mystery_reg[address - 0x0D]; + case 0x0E: + case 0x0F: + return 0; + default: + break; + } + + return 0x00; +} + uint8_t readGayleB(unsigned int address) { if (address == GERROR) { return ide_read8(ide0, ide_error_r); @@ -246,6 +412,14 @@ uint8_t readGayleB(unsigned int address) { return ide_read8(ide0, ide_altst_r); } + if ((address & GAYLEMASK) == CLOCKBASE) { + if ((address & CLOCKMASK) >= 0x8000) { + printf("Byte read from CDTV SRAM?\n"); + return 0; + } + return get_rtc_byte((address & 0x3F), rtc_type); + } + if (address == GIDENT) { uint8_t val; // printf("Read Byte from Gayle Ident 0x%06x (0x%06x)\n",address,counter); @@ -304,11 +478,27 @@ uint16_t readGayle(unsigned int address) { return value; } + if ((address & GAYLEMASK) == CLOCKBASE) { + if ((address & CLOCKMASK) >= 0x8000) { + printf("Word read from CDTV SRAM?\n"); + return 0; + } + return ((get_rtc_byte((address & 0x3F), rtc_type) << 8) | (get_rtc_byte(((address + 1) & 0x3F), rtc_type))); + } + printf("Read Word From Gayle Space 0x%06x\n", address); return 0x8000; } uint32_t readGayleL(unsigned int address) { + if ((address & GAYLEMASK) == CLOCKBASE) { + if ((address & CLOCKMASK) >= 0x8000) { + printf("Longword read from CDTV SRAM?\n"); + return 0; + } + return ((get_rtc_byte((address & 0x3F), rtc_type) << 24) | (get_rtc_byte(((address + 1) & 0x3F), rtc_type) << 16) | (get_rtc_byte(((address + 2) & 0x3F), rtc_type) << 8) | (get_rtc_byte(((address + 3) & 0x3F), rtc_type))); + } + printf("Read Long From Gayle Space 0x%06x\n", address); return 0x8000; } diff --git a/config_file/config_file.c b/config_file/config_file.c index 2ce16e1..b0b9a48 100644 --- a/config_file/config_file.c +++ b/config_file/config_file.c @@ -212,6 +212,7 @@ void add_mapping(struct emulator_config *cfg, unsigned int type, unsigned int ad file_size = (int)ftell(in); if (size == 0) { cfg->map_size[index] = file_size; + cfg->map_high[index] = addr + cfg->map_size[index]; } fseek(in, 0, SEEK_SET); cfg->map_data[index] = (unsigned char *)calloc(1, cfg->map_size[index]); @@ -230,7 +231,7 @@ void add_mapping(struct emulator_config *cfg, unsigned int type, unsigned int ad break; } - printf("[MAP %d] Added %s mapping for range %.8lX-%.8lX ID: %s\n", index, map_type_names[type], cfg->map_offset[index], cfg->map_offset[index] + cfg->map_size[index] - 1, cfg->map_id[index] ? cfg->map_id[index] : "None"); + printf("[MAP %d] Added %s mapping for range %.8lX-%.8lX ID: %s\n", index, map_type_names[type], cfg->map_offset[index], cfg->map_high[index] - 1, cfg->map_id[index] ? cfg->map_id[index] : "None"); if (cfg->map_size[index] == cfg->rom_size[index]) m68k_add_rom_range(cfg->map_offset[index], cfg->map_high[index], cfg->map_data[index]); diff --git a/emulator.c b/emulator.c index a019512..d2d3eab 100644 --- a/emulator.c +++ b/emulator.c @@ -566,8 +566,10 @@ void m68k_write_memory_8(unsigned int address, unsigned int value) { PLATFORM_CHECK_WRITE(OP_TYPE_BYTE); if (address == 0xbfe001) { - ovl = (value & (1 << 0)); - printf("OVL:%x\n", ovl); + if (ovl != (value & (1 << 0)) { + ovl = (value & (1 << 0)); + printf("OVL:%x\n", ovl); + } } // if (address < 0xffffff) { diff --git a/memory_mapped.c b/memory_mapped.c index bf42406..1e5522c 100644 --- a/memory_mapped.c +++ b/memory_mapped.c @@ -24,12 +24,12 @@ inline int handle_mapped_read(struct emulator_config *cfg, unsigned int addr, un if (cfg->map_type[i] == MAPTYPE_NONE) continue; else if (ovl && cfg->map_type[i] == MAPTYPE_ROM) { - if (cfg->map_mirror[i] != -1 && CHKRANGE_ABS(addr, cfg->map_mirror[i], cfg->map_high[i])) { + if (cfg->map_mirror[i] != -1 && CHKRANGE(addr, cfg->map_mirror[i], cfg->map_size[i])) { read_addr = cfg->map_data[i] + ((addr - cfg->map_mirror[i]) % cfg->rom_size[i]); goto read_value; } } - else if (CHKRANGE_ABS(addr, cfg->map_offset[i], cfg->map_high[i])) { + if (CHKRANGE_ABS(addr, cfg->map_offset[i], cfg->map_high[i])) { switch(cfg->map_type[i]) { case MAPTYPE_ROM: read_addr = cfg->map_data[i] + ((addr - cfg->map_offset[i]) % cfg->rom_size[i]); diff --git a/platforms/amiga/amiga-registers.h b/platforms/amiga/amiga-registers.h index 53a7b90..3e19e65 100644 --- a/platforms/amiga/amiga-registers.h +++ b/platforms/amiga/amiga-registers.h @@ -3,8 +3,19 @@ void set_hard_drive_image_file_amiga(uint8_t index, char *filename); int custom_read_amiga(struct emulator_config *cfg, unsigned int addr, unsigned int *val, unsigned char type); int custom_write_amiga(struct emulator_config *cfg, unsigned int addr, unsigned int val, unsigned char type); +void put_rtc_byte(uint32_t address_, uint8_t value, uint8_t rtc_type); +uint8_t get_rtc_byte(uint32_t address_, uint8_t rtc_type); + #define GAYLEBASE 0xD80000 -#define GAYLESIZE 0x70000 +#define GAYLESIZE 0x070000 +#define GAYLEMASK 0xDF0000 #define CLOCKBASE 0xDC0000 #define CLOCKSIZE 0x010000 +#define CLOCKMASK 0x00FFFF + +enum rtc_types { + RTC_TYPE_MSM, + RTC_TYPE_RICOH, + RTC_TYPE_NONE, +}; \ No newline at end of file -- 2.39.2