X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Feeprom.cpp;h=4258a4e661fc5d8d4b37504ad05eb388057e69a2;hb=725caa0f8bb826a73edef366906ccb41a3197819;hp=705014631b98dcc0808be1cc184128455389bb1d;hpb=53fb0ca4ce174b7f36d39404cfb907ae3deaf55d;p=virtualjaguar diff --git a/src/eeprom.cpp b/src/eeprom.cpp index 7050146..4258a4e 100644 --- a/src/eeprom.cpp +++ b/src/eeprom.cpp @@ -1,146 +1,206 @@ // -// EEPROM handler +// Jaguar EEPROM handler // -// by cal2 +// by Cal2 // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS) -// Cleanups by James L. Hammons +// Cleanups/enhancements by James Hammons +// (C) 2010 Underground Software +// +// JLH = James Hammons +// +// Who When What +// --- ---------- ------------------------------------------------------------- +// JLH 01/16/2010 Created this log ;-) // #include "eeprom.h" -#define eeprom_LOG +#include +#include // For memset +#include "jaguar.h" +#include "log.h" +#include "settings.h" + +//#define eeprom_LOG -static uint16 eeprom_ram[64]; +static uint16_t eeprom_ram[64]; +static uint16_t cdromEEPROM[64]; // // Private function prototypes // -void eeprom_set_di(uint32 state); -void eeprom_set_cs(uint32 state); -uint32 eeprom_get_do(void); - -#define EE_STATE_START 1 -#define EE_STATE_OP_A 2 -#define EE_STATE_OP_B 3 -#define EE_STATE_0 4 -#define EE_STATE_1 5 -#define EE_STATE_2 6 -#define EE_STATE_3 7 -#define EE_STATE_0_0 8 -#define EE_READ_ADDRESS 9 -#define EE_STATE_0_0_0 10 -#define EE_STATE_0_0_1 11 -#define EE_STATE_0_0_2 12 -#define EE_STATE_0_0_3 13 -#define EE_STATE_0_0_1_0 14 -#define EE_READ_DATA 15 -#define EE_STATE_BUSY 16 -#define EE_STATE_1_0 17 -#define EE_STATE_1_1 18 -#define EE_STATE_2_0 19 -#define EE_STATE_3_0 20 - -uint16 jerry_ee_state = EE_STATE_START; -uint16 jerry_ee_op = 0; -uint16 jerry_ee_rstate = 0; -uint16 jerry_ee_address_data = 0; -uint16 jerry_ee_address_cnt = 6; -uint16 jerry_ee_data = 0; -uint16 jerry_ee_data_cnt = 16; -uint16 jerry_writes_enabled = 0; -uint16 jerry_ee_direct_jump = 0; -FILE * jerry_ee_fp; -extern char jaguar_boot_dir[1024]; - - -void eeprom_init(void) +static void EEPROMSave(void); +static void eeprom_set_di(uint32_t state); +static void eeprom_set_cs(uint32_t state); +static uint32_t eeprom_get_do(void); + +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, + EE_STATE_0_0_1, EE_STATE_0_0_2, EE_STATE_0_0_3, EE_STATE_0_0_1_0, EE_READ_DATA, + EE_STATE_BUSY, EE_STATE_1_0, EE_STATE_1_1, EE_STATE_2_0, EE_STATE_3_0 }; + +// Local global variables + +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 char cdromEEPROMFilename[MAX_PATH]; +static bool haveEEPROM = false; +static bool haveCDROMEEPROM = false; + + +void EepromInit(void) { - static char eeprom_filename[1024]; + // Handle regular cartridge EEPROM + sprintf(eeprom_filename, "%s%08X.eep", vjs.EEPROMPath, (unsigned int)jaguarMainROMCRC32); + sprintf(cdromEEPROMFilename, "%scdrom.eeprom", vjs.EEPROMPath); + FILE * fp = fopen(eeprom_filename, "rb"); - sprintf(eeprom_filename, "%s/%s%08X.eep", jaguar_boot_dir, jaguar_eeproms_path, (unsigned int)jaguar_mainRom_crc32); - jerry_ee_fp = fopen(eeprom_filename, "rb"); - if (jerry_ee_fp) + if (fp) { - fread(eeprom_ram, 1, 128, jerry_ee_fp); - fclose(jerry_ee_fp); - fprintf(log_get(), "eeprom: loaded from %s\n", eeprom_filename); - jerry_ee_fp = fopen(eeprom_filename, "wrb"); + fread(eeprom_ram, 1, 128, fp); + fclose(fp); + WriteLog("EEPROM: Loaded from %s\n", eeprom_filename); + haveEEPROM = true; } else + WriteLog("EEPROM: Could not open file \"%s\"!\n", eeprom_filename); + + // Handle JagCD EEPROM + fp = fopen(cdromEEPROMFilename, "rb"); + + if (fp) { - fprintf(log_get(), "eeprom: creating %s\n", eeprom_filename); - jerry_ee_fp = fopen(eeprom_filename, "wb"); - if (jerry_ee_fp == NULL) - fprintf(log_get(), "EEPROM: Could not open/create %s\n", eeprom_filename); + fread(cdromEEPROM, 1, 128, fp); + fclose(fp); + WriteLog("EEPROM: Loaded from cdrom.eeprom\n"); + haveCDROMEEPROM = true; } + else + WriteLog("EEPROM: Could not open file \"%s\"!\n", cdromEEPROMFilename); } -void eeprom_reset(void) + +void EepromReset(void) { - if (jerry_ee_fp == NULL) - 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 eeprom_done(void) + +void EepromDone(void) { - if (jerry_ee_fp) + WriteLog("EEPROM: Done.\n"); +} + + +static void EEPROMSave(void) +{ + // Write out regular cartridge EEPROM data + FILE * fp = fopen(eeprom_filename, "wb"); + + if (fp) + { + fwrite(eeprom_ram, 1, 128, fp); + fclose(fp); + } + else + WriteLog("EEPROM: Could not create file \"%s!\"\n", eeprom_filename); + + // Write out JagCD EEPROM data + fp = fopen(cdromEEPROMFilename, "wb"); + + if (fp) { - fwrite(eeprom_ram, 1, 128, jerry_ee_fp); - fclose(jerry_ee_fp); + fwrite(cdromEEPROM, 1, 128, fp); + fclose(fp); } else - fprintf(log_get(),"eeprom: not saved\n"); + WriteLog("EEPROM: Could not create file \"%s!\"\n", cdromEEPROMFilename); } -void eeprom_byte_write(uint32 offset, uint8 data) + +uint8_t EepromReadByte(uint32_t offset) { switch (offset) { case 0xF14001: - break; + return eeprom_get_do(); case 0xF14801: - eeprom_set_di(data & 0x01); break; case 0xF15001: eeprom_set_cs(1); break; -// default: fprintf(log_get(),"eeprom: unmapped 0x%.8x\n",offset); break; +// default: WriteLog("EEPROM: unmapped 0x%.8x\n", offset); break; } + + return 0x00; } -void eeprom_word_write(uint32 offset, uint16 data) + +uint16_t EepromReadWord(uint32_t offset) { - eeprom_byte_write(offset+0, (data >> 8) & 0xFF); - eeprom_byte_write(offset+1, data & 0xFF); + return ((uint16_t)EepromReadByte(offset + 0) << 8) | EepromReadByte(offset + 1); } -uint8 eeprom_byte_read(uint32 offset) + +void EepromWriteByte(uint32_t offset, uint8_t data) { switch (offset) { case 0xF14001: - return eeprom_get_do(); + break; case 0xF14801: + eeprom_set_di(data & 0x01); break; case 0xF15001: eeprom_set_cs(1); break; -// default: fprintf(log_get(),"eeprom: unmapped 0x%.8x\n",offset); break; +// default: WriteLog("eeprom: unmapped 0x%.8x\n",offset); break; } - - return 0x00; } -uint16 eeprom_word_read(uint32 offset) + +void EepromWriteWord(uint32_t offset, uint16_t data) { - return ((uint16)eeprom_byte_read(offset+0) << 8) | eeprom_byte_read(offset+1); + EepromWriteByte(offset + 0, (data >> 8) & 0xFF); + EepromWriteByte(offset + 1, data & 0xFF); } -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) { -// fprintf(log_get(),"eeprom: di=%i\n",data); -// fprintf(log_get(),"eeprom: state %i\n",jerry_ee_state); +// WriteLog("eeprom: di=%i\n",data); +// WriteLog("eeprom: state %i\n",jerry_ee_state); switch (jerry_ee_state) { case EE_STATE_START: @@ -153,14 +213,20 @@ void eeprom_set_di(uint32 data) case EE_STATE_OP_B: jerry_ee_op |= data; jerry_ee_direct_jump = 0; -// fprintf(log_get(),"eeprom: opcode %i\n",jerry_ee_op); +// 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: @@ -173,16 +239,21 @@ 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: // writes disable - // fprintf(log_get(),"eeprom: read only\n"); + // WriteLog("eeprom: read only\n"); jerry_writes_enabled = 0; jerry_ee_state = EE_STATE_START; break; @@ -195,26 +266,31 @@ void eeprom_set_di(uint32 data) jerry_ee_direct_jump = 1; break; case EE_STATE_0_0_1_0: - // fprintf(log_get(),"eeprom: filling eeprom with 0x%.4x\n",data); + // 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; - //else - // fprintf(log_get(),"eeprom: not writing because read only\n"); + + EEPROMSave(); // Save it NOW! + } + + //else + // WriteLog("eeprom: not writing because read only\n"); jerry_ee_state = EE_STATE_BUSY; break; case EE_STATE_0_0_2: // erase all - //fprintf(log_get(),"eeprom: erasing eeprom\n"); + //WriteLog("eeprom: erasing eeprom\n"); if (jerry_writes_enabled) for(int i=0; i<64; i++) eeprom_ram[i] = 0xFFFF; - jerry_ee_state=EE_STATE_BUSY; + jerry_ee_state = EE_STATE_BUSY; break; case EE_STATE_0_0_3: // writes enable - //fprintf(log_get(),"eeprom: read/write\n"); + //WriteLog("eeprom: read/write\n"); jerry_writes_enabled = 1; jerry_ee_state = EE_STATE_START; break; @@ -233,9 +309,13 @@ void eeprom_set_di(uint32 data) jerry_ee_direct_jump = 1; break; case EE_STATE_1_1: - //fprintf(log_get(),"eeprom: writing 0x%.4x at 0x%.2x\n",jerry_ee_data,jerry_ee_address_data); + //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! + } + jerry_ee_state = EE_STATE_BUSY; break; case EE_STATE_2: @@ -254,44 +334,52 @@ void eeprom_set_di(uint32 data) jerry_ee_direct_jump = 1; break; case EE_STATE_3_0: - //fprintf(log_get(),"eeprom: erasing 0x%.2x\n",jerry_ee_address_data); + //WriteLog("eeprom: erasing 0x%.2x\n",jerry_ee_address_data); if (jerry_writes_enabled) eeprom_ram[jerry_ee_address_data] = 0xFFFF; + jerry_ee_state = EE_STATE_BUSY; break; - case EE_READ_DATA: - //fprintf(log_get(),"eeprom:\t\t\t%i bit %i\n",data,jerry_ee_data_cnt-1); + case EE_READ_DATA: + //WriteLog("eeprom:\t\t\t%i bit %i\n",data,jerry_ee_data_cnt-1); jerry_ee_data <<= 1; jerry_ee_data |= data; jerry_ee_data_cnt--; + if (!jerry_ee_data_cnt) { jerry_ee_state = jerry_ee_rstate; + if (jerry_ee_direct_jump) eeprom_set_di(data); } + break; - case EE_READ_ADDRESS: + case EE_READ_ADDRESS: jerry_ee_address_data <<= 1; jerry_ee_address_data |= data; jerry_ee_address_cnt--; -// fprintf(log_get(),"eeprom:\t%i bits remaining\n",jerry_ee_address_cnt); +// WriteLog("eeprom:\t%i bits remaining\n",jerry_ee_address_cnt); + if (!jerry_ee_address_cnt) { jerry_ee_state = jerry_ee_rstate; - //fprintf(log_get(),"eeprom:\t\tread address 0x%.2x\n",jerry_ee_address_data); + //WriteLog("eeprom:\t\tread address 0x%.2x\n",jerry_ee_address_data); + if (jerry_ee_direct_jump) eeprom_set_di(data); } + break; default: - jerry_ee_state = EE_STATE_OP_A; + jerry_ee_state = EE_STATE_OP_A; } } -void eeprom_set_cs(uint32 state) + +static void eeprom_set_cs(uint32_t /*state*/) { -// fprintf(log_get(),"eeprom: cs=%i\n",state); +// WriteLog("eeprom: cs=%i\n",state); jerry_ee_state = EE_STATE_START; jerry_ee_op = 0; jerry_ee_rstate = 0; @@ -302,9 +390,10 @@ void eeprom_set_cs(uint32 state) jerry_writes_enabled = 1; } -uint32 eeprom_get_do(void) + +static uint32_t eeprom_get_do(void) { - uint16 data = 1; + uint16_t data = 1; switch (jerry_ee_state) { @@ -317,15 +406,21 @@ uint32 eeprom_get_do(void) break; case EE_STATE_2_0: jerry_ee_data_cnt--; +#if 0 data = (eeprom_ram[jerry_ee_address_data] & (1 << jerry_ee_data_cnt)) >> jerry_ee_data_cnt; +#else + data = (eeprom_ram[jerry_ee_address_data] >> jerry_ee_data_cnt) & 0x01; +#endif + if (!jerry_ee_data_cnt) { - //fprintf(log_get(),"eeprom: read 0x%.4x at 0x%.2x cpu %i pc=0x%.8x\n",eeprom_ram[jerry_ee_address_data],jerry_ee_address_data,jaguar_cpu_in_exec,s68000readPC()); + //WriteLog("eeprom: read 0x%.4x at 0x%.2x cpu %i pc=0x%.8x\n",eeprom_ram[jerry_ee_address_data],jerry_ee_address_data,jaguar_cpu_in_exec,s68000readPC()); jerry_ee_state = EE_STATE_START; } break; } -// fprintf(log_get(),"eeprom: do=%i\n",data); +// WriteLog("eeprom: do=%i\n",data); return data; } +