#include "log.h"
#include "settings.h"
-#define eeprom_LOG
+//#define eeprom_LOG
-static uint16 eeprom_ram[64];
+static uint16_t eeprom_ram[64];
+static uint16_t cdromEEPROM[64];
//
// Private function prototypes
//
static void EEPROMSave(void);
-static void eeprom_set_di(uint32 state);
-static void eeprom_set_cs(uint32 state);
-static uint32 eeprom_get_do(void);
+static void eeprom_set_di(uint32_t state);
+static void eeprom_set_cs(uint32_t state);
+static uint32_t eeprom_get_do(void);
+void ReadEEPROMFromFile(FILE * file, uint16_t * ram);
+void WriteEEPROMToFile(FILE * file, uint16_t * ram);
+
enum { EE_STATE_START = 1, EE_STATE_OP_A, EE_STATE_OP_B, EE_STATE_0, EE_STATE_1,
EE_STATE_2, EE_STATE_3, EE_STATE_0_0, EE_READ_ADDRESS, EE_STATE_0_0_0,
// Local global variables
-static uint16 jerry_ee_state = EE_STATE_START;
-static uint16 jerry_ee_op = 0;
-static uint16 jerry_ee_rstate = 0;
-static uint16 jerry_ee_address_data = 0;
-static uint16 jerry_ee_address_cnt = 6;
-static uint16 jerry_ee_data = 0;
-static uint16 jerry_ee_data_cnt = 16;
-static uint16 jerry_writes_enabled = 0;
-static uint16 jerry_ee_direct_jump = 0;
+static uint16_t jerry_ee_state = EE_STATE_START;
+static uint16_t jerry_ee_op = 0;
+static uint16_t jerry_ee_rstate = 0;
+static uint16_t jerry_ee_address_data = 0;
+static uint16_t jerry_ee_address_cnt = 6;
+static uint16_t jerry_ee_data = 0;
+static uint16_t jerry_ee_data_cnt = 16;
+static uint16_t jerry_writes_enabled = 0;
+static uint16_t jerry_ee_direct_jump = 0;
+
static char eeprom_filename[MAX_PATH];
-static bool foundEEPROM = false;
+static char cdromEEPROMFilename[MAX_PATH];
+static bool haveEEPROM = false;
+static bool haveCDROMEEPROM = false;
+
void EepromInit(void)
{
- sprintf(eeprom_filename, "%s%08X.eep", vjs.EEPROMPath, (unsigned int)jaguarMainROMCRC32);
+ // Handle regular cartridge EEPROM
+ sprintf(eeprom_filename, "%s%08X.eeprom", vjs.EEPROMPath, (unsigned int)jaguarMainROMCRC32);
+ sprintf(cdromEEPROMFilename, "%scdrom.eeprom", vjs.EEPROMPath);
FILE * fp = fopen(eeprom_filename, "rb");
if (fp)
{
- fread(eeprom_ram, 1, 128, fp);
+ ReadEEPROMFromFile(fp, eeprom_ram);
fclose(fp);
WriteLog("EEPROM: Loaded from %s\n", eeprom_filename);
- foundEEPROM = true;
+ haveEEPROM = true;
}
else
WriteLog("EEPROM: Could not open file \"%s\"!\n", eeprom_filename);
+
+ // Handle JagCD EEPROM
+ fp = fopen(cdromEEPROMFilename, "rb");
+
+ if (fp)
+ {
+ ReadEEPROMFromFile(fp, cdromEEPROM);
+ fclose(fp);
+ WriteLog("EEPROM: Loaded from cdrom.eeprom\n");
+ haveCDROMEEPROM = true;
+ }
+ else
+ WriteLog("EEPROM: Could not open file \"%s\"!\n", cdromEEPROMFilename);
}
+
void EepromReset(void)
{
- if (!foundEEPROM)
- memset(eeprom_ram, 0xFF, 64 * sizeof(uint16));
+ if (!haveEEPROM)
+ memset(eeprom_ram, 0xFF, 64 * sizeof(uint16_t));
+
+ if (!haveCDROMEEPROM)
+ memset(cdromEEPROM, 0xFF, 64 * sizeof(uint16_t));
}
+
void EepromDone(void)
{
WriteLog("EEPROM: Done.\n");
}
+
static void EEPROMSave(void)
{
+ // Write out regular cartridge EEPROM data
FILE * fp = fopen(eeprom_filename, "wb");
- if (fp == NULL)
+ if (fp)
{
+ WriteEEPROMToFile(fp, eeprom_ram);
+ fclose(fp);
+ }
+ else
WriteLog("EEPROM: Could not create file \"%s!\"\n", eeprom_filename);
- return;
+
+ // Write out JagCD EEPROM data
+ fp = fopen(cdromEEPROMFilename, "wb");
+
+ if (fp)
+ {
+ WriteEEPROMToFile(fp, cdromEEPROM);
+ fclose(fp);
+ }
+ else
+ WriteLog("EEPROM: Could not create file \"%s!\"\n", cdromEEPROMFilename);
+}
+
+
+//
+// Read/write EEPROM files to disk in an endian safe manner
+//
+void ReadEEPROMFromFile(FILE * file, uint16_t * ram)
+{
+ uint8_t buffer[128];
+ fread(buffer, 1, 128, file);
+
+ for(int i=0; i<64; i++)
+ ram[i] = (buffer[(i * 2) + 0] << 8) | buffer[(i * 2) + 1];
+}
+
+
+void WriteEEPROMToFile(FILE * file, uint16_t * ram)
+{
+ uint8_t buffer[128];
+
+ for(int i=0; i<64; i++)
+ {
+ buffer[(i * 2) + 0] = ram[i] >> 8;
+ buffer[(i * 2) + 1] = ram[i] & 0xFF;
}
- fwrite(eeprom_ram, 1, 128, fp);
- fclose(fp);
+ fwrite(buffer, 1, 128, file);
}
-uint8 EepromReadByte(uint32 offset)
+
+uint8_t EepromReadByte(uint32_t offset)
{
switch (offset)
{
return 0x00;
}
-uint16 EepromReadWord(uint32 offset)
+
+uint16_t EepromReadWord(uint32_t offset)
{
- return ((uint16)EepromReadByte(offset + 0) << 8) | EepromReadByte(offset + 1);
+ return ((uint16_t)EepromReadByte(offset + 0) << 8) | EepromReadByte(offset + 1);
}
-void EepromWriteByte(uint32 offset, uint8 data)
+
+void EepromWriteByte(uint32_t offset, uint8_t data)
{
switch (offset)
{
}
}
-void EepromWriteWord(uint32 offset, uint16 data)
+
+void EepromWriteWord(uint32_t offset, uint16_t data)
{
EepromWriteByte(offset + 0, (data >> 8) & 0xFF);
EepromWriteByte(offset + 1, data & 0xFF);
}
-static void eeprom_set_di(uint32 data)
+
+/*
+;
+; Commands specific to the National Semiconductor NM93C14
+;
+;
+; 9-bit commands..
+; 876543210
+eEWDS equ %100000000 ;Erase/Write disable (default)
+eWRAL equ %100010000 ;Writes all registers
+eERAL equ %100100000 ;Erase all registers
+eEWEN equ %100110000 ;Erase/write Enable
+eWRITE equ %101000000 ;Write selected register
+eREAD equ %110000000 ;read from EEPROM
+eERASE equ %111000000 ;Erase selected register
+*/
+
+
+static void eeprom_set_di(uint32_t data)
{
// WriteLog("eeprom: di=%i\n",data);
// WriteLog("eeprom: state %i\n",jerry_ee_state);
jerry_ee_op |= data;
jerry_ee_direct_jump = 0;
// WriteLog("eeprom: opcode %i\n",jerry_ee_op);
+
switch (jerry_ee_op)
{
+ // Opcode 00: eEWEN, eERAL, eWRAL, eEWNDS
case 0: jerry_ee_state = EE_STATE_0; break;
+ // Opcode 01: eWRITE (Write selected register)
case 1: jerry_ee_state = EE_STATE_1; break;
+ // Opcode 10: eREAD (Read from EEPROM)
case 2: jerry_ee_state = EE_STATE_2; break;
+ // Opcode 11: eERASE (Erase selected register)
case 3: jerry_ee_state = EE_STATE_3; break;
}
+
eeprom_set_di(data);
break;
case EE_STATE_0:
case EE_STATE_0_0:
switch ((jerry_ee_address_data >> 4) & 0x03)
{
+ // Opcode 00 00: eEWDS (Erase/Write disable)
case 0: jerry_ee_state=EE_STATE_0_0_0; break;
+ // Opcode 00 01: eWRAL (Write all registers)
case 1: jerry_ee_state=EE_STATE_0_0_1; break;
+ // Opcode 00 10: eERAL (Erase all registers)
case 2: jerry_ee_state=EE_STATE_0_0_2; break;
+ // Opcode 00 11: eEWEN (Erase/Write enable)
case 3: jerry_ee_state=EE_STATE_0_0_3; break;
}
+
eeprom_set_di(data);
break;
case EE_STATE_0_0_0:
case EE_STATE_0_0_1_0:
// WriteLog("eeprom: filling eeprom with 0x%.4x\n",data);
if (jerry_writes_enabled)
+ {
for(int i=0; i<64; i++)
eeprom_ram[i] = jerry_ee_data;
- EEPROMSave(); // Save it NOW!
+ EEPROMSave(); // Save it NOW!
+ }
+
//else
// WriteLog("eeprom: not writing because read only\n");
jerry_ee_state = EE_STATE_BUSY;
case EE_STATE_1_1:
//WriteLog("eeprom: writing 0x%.4x at 0x%.2x\n",jerry_ee_data,jerry_ee_address_data);
if (jerry_writes_enabled)
+ {
eeprom_ram[jerry_ee_address_data] = jerry_ee_data;
+ EEPROMSave(); // Save it NOW!
+ }
- EEPROMSave(); // Save it NOW!
jerry_ee_state = EE_STATE_BUSY;
break;
case EE_STATE_2:
if (jerry_ee_direct_jump)
eeprom_set_di(data);
}
+
break;
case EE_READ_ADDRESS:
jerry_ee_address_data <<= 1;
if (jerry_ee_direct_jump)
eeprom_set_di(data);
}
+
break;
default:
jerry_ee_state = EE_STATE_OP_A;
}
}
-static void eeprom_set_cs(uint32 state)
+
+static void eeprom_set_cs(uint32_t /*state*/)
{
// WriteLog("eeprom: cs=%i\n",state);
jerry_ee_state = EE_STATE_START;
jerry_writes_enabled = 1;
}
-static uint32 eeprom_get_do(void)
+
+static uint32_t eeprom_get_do(void)
{
- uint16 data = 1;
+ uint16_t data = 1;
switch (jerry_ee_state)
{
break;
case EE_STATE_2_0:
jerry_ee_data_cnt--;
- data = (eeprom_ram[jerry_ee_address_data] & (1 << jerry_ee_data_cnt)) >> jerry_ee_data_cnt;
+ data = (eeprom_ram[jerry_ee_address_data] >> jerry_ee_data_cnt) & 0x01;
if (!jerry_ee_data_cnt)
{
// WriteLog("eeprom: do=%i\n",data);
return data;
}
+