#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
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);
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) {
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);
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);
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
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
#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
--- /dev/null
+#include <time.h>
+#include <stdio.h>
+#include <stdint.h>
+#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;
+}
--- /dev/null
+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