mirror of
https://github.com/captain-amygdala/pistorm.git
synced 2026-05-01 22:06:41 +00:00
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.
This commit is contained in:
192
Gayle.c
192
Gayle.c
@@ -16,7 +16,11 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <endian.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -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]);
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
Reference in New Issue
Block a user