From 038912b981e7c641e9b0c12def47b20bc07ed089 Mon Sep 17 00:00:00 2001 From: beeanyew Date: Fri, 1 Jan 2021 11:34:49 +0100 Subject: [PATCH] Clean up RTC and move it out of Gayle.c --- Gayle.c | 134 +---------------------- Makefile | 3 +- platforms/amiga/amiga-registers.h | 9 -- platforms/shared/rtc.c | 172 ++++++++++++++++++++++++++++++ platforms/shared/rtc.h | 8 ++ 5 files changed, 186 insertions(+), 140 deletions(-) create mode 100644 platforms/shared/rtc.c create mode 100644 platforms/shared/rtc.h diff --git a/Gayle.c b/Gayle.c index f07bf2a..9b21f90 100644 --- a/Gayle.c +++ b/Gayle.c @@ -21,6 +21,7 @@ #include "ide.h" #include "config_file/config_file.h" #include "platforms/amiga/amiga-registers.h" +#include "platforms/shared/rtc.h" //#define GSTATUS 0xda201c //#define GCLOW 0xda2010 @@ -253,133 +254,6 @@ void writeGayleL(unsigned int address, unsigned int value) { 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); @@ -417,7 +291,7 @@ uint8_t readGayleB(unsigned int address) { printf("Byte read from CDTV SRAM?\n"); return 0; } - return get_rtc_byte((address & 0x3F), rtc_type); + return get_rtc_byte(address, rtc_type); } if (address == GIDENT) { @@ -483,7 +357,7 @@ uint16_t readGayle(unsigned int address) { 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))); + return ((get_rtc_byte(address, rtc_type) << 8) | (get_rtc_byte(address + 1, rtc_type))); } printf("Read Word From Gayle Space 0x%06x\n", address); @@ -496,7 +370,7 @@ uint32_t readGayleL(unsigned int address) { 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))); + return ((get_rtc_byte(address, rtc_type) << 24) | (get_rtc_byte(address + 1, rtc_type) << 16) | (get_rtc_byte(address + 2, rtc_type) << 8) | (get_rtc_byte(address + 3, rtc_type))); } printf("Read Long From Gayle Space 0x%06x\n", address); diff --git a/Makefile b/Makefile index 6e7f301..c32a147 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,8 @@ MAINFILES = emulator.c \ platforms/amiga/amiga-platform.c \ platforms/amiga/amiga-registers.c \ platforms/dummy/dummy-platform.c \ - platforms/dummy/dummy-registers.c + platforms/dummy/dummy-registers.c \ + platforms/shared/rtc.c MUSASHIFILES = m68kcpu.c softfloat/softfloat.c MUSASHIGENCFILES = m68kops.c diff --git a/platforms/amiga/amiga-registers.h b/platforms/amiga/amiga-registers.h index 3e19e65..fb6e285 100644 --- a/platforms/amiga/amiga-registers.h +++ b/platforms/amiga/amiga-registers.h @@ -3,9 +3,6 @@ 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 0x070000 #define GAYLEMASK 0xDF0000 @@ -13,9 +10,3 @@ uint8_t get_rtc_byte(uint32_t address_, uint8_t rtc_type); #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 diff --git a/platforms/shared/rtc.c b/platforms/shared/rtc.c new file mode 100644 index 0000000..8b3772c --- /dev/null +++ b/platforms/shared/rtc.c @@ -0,0 +1,172 @@ +#include +#include +#include +#include "rtc.h" + +static unsigned char rtc_mystery_reg[3]; +unsigned char ricoh_memory[0x0F]; +unsigned char ricoh_alarm[0x0F]; + +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) { + if (rtc_bank & 0x01) { + // Low nibble of value -> high nibble in RTC memory + ricoh_memory[address] &= 0x0F; + ricoh_memory[address] |= ((value & 0x0F) << 4); + } + else { + // Low nibble of value -> low nibble in RTC memory + ricoh_memory[address] &= 0xF0; + ricoh_memory[address] |= (value & 0x0F); + } + return; + } + else if ((rtc_bank & 0x01) && address < 0x0D) { + // RTC alarm stuff, no idea what this is supposed to be for. + switch(address) { + case 0x00: + case 0x01: + case 0x09: + case 0x0C: + ricoh_alarm[address] = 0; + break; + case 0x03: + case 0x06: + ricoh_alarm[address] = (value & (0x08 & 0xFF)); + break; + case 0x05: + case 0x08: + case 0x0B: + ricoh_alarm[address] = (value & (0x0C & 0xFF)); + break; + case 0x0A: + ricoh_alarm[address] = (value & (0x0E & 0xFF)); + break; + default: + ricoh_alarm[address] = value; + break; + } + 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_ & 0x3F; + 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) { + // Get low/high nibble from memory (bank 2/3) + return ((ricoh_memory[address] >> (rtc_bank & 0x01) ? 4 : 0) & 0x0F); + } + else if ((rtc_bank & 0x01) && address < 0x0D) { + // Get byte from alarm + return ricoh_alarm[address]; + } + } + + 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 { + if (ricoh_alarm[10] & 0x01) { + return rtc_time->tm_hour / 10; + } + else { + return ((rtc_time->tm_hour / 10) | (rtc_time->tm_hour >= 12) ? 0x02 : 0x00); + } + 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? + case 0x0E: + case 0x0F: + if (rtc_type == RTC_TYPE_MSM) { + return rtc_mystery_reg[address - 0x0D]; + } + else { + if (address == 0x0D) return rtc_mystery_reg[address - 0x0D]; + return 0; + } + default: + break; + } + + return 0x00; +} diff --git a/platforms/shared/rtc.h b/platforms/shared/rtc.h new file mode 100644 index 0000000..107ae93 --- /dev/null +++ b/platforms/shared/rtc.h @@ -0,0 +1,8 @@ +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); + +enum rtc_types { + RTC_TYPE_MSM, + RTC_TYPE_RICOH, + RTC_TYPE_NONE, +}; \ No newline at end of file -- 2.39.2