X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Feeprom.cpp;h=2fb896e44b6d229e4745ff6fa272544fcca89276;hb=32f569e1bd09f5d7f07005d119f6408805106381;hp=bba94afd3d4cb5f283b79cc30a08aaa53d04a5c0;hpb=f30bf746981a99079e766b0d4e9de5391a4175ff;p=virtualjaguar diff --git a/src/eeprom.cpp b/src/eeprom.cpp index bba94af..2fb896e 100644 --- a/src/eeprom.cpp +++ b/src/eeprom.cpp @@ -21,18 +21,22 @@ #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, @@ -41,60 +45,124 @@ enum { EE_STATE_START = 1, EE_STATE_OP_A, EE_STATE_OP_B, EE_STATE_0, EE_STATE_1, // 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) { @@ -111,12 +179,14 @@ uint8 EepromReadByte(uint32 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) { @@ -132,13 +202,32 @@ void EepromWriteByte(uint32 offset, uint8 data) } } -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); @@ -155,13 +244,19 @@ static void eeprom_set_di(uint32 data) 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: @@ -174,11 +269,16 @@ static void eeprom_set_di(uint32 data) 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: @@ -198,10 +298,13 @@ static void eeprom_set_di(uint32 data) 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; @@ -238,9 +341,11 @@ static void eeprom_set_di(uint32 data) 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: @@ -278,6 +383,7 @@ static void eeprom_set_di(uint32 data) if (jerry_ee_direct_jump) eeprom_set_di(data); } + break; case EE_READ_ADDRESS: jerry_ee_address_data <<= 1; @@ -293,13 +399,15 @@ static void eeprom_set_di(uint32 data) 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; @@ -312,9 +420,10 @@ static void eeprom_set_cs(uint32 state) 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) { @@ -327,7 +436,7 @@ static uint32 eeprom_get_do(void) 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) { @@ -340,3 +449,4 @@ static uint32 eeprom_get_do(void) // WriteLog("eeprom: do=%i\n",data); return data; } +