Create a directory for EEPROMs if it doesn't already exist
authorJean-Paul Mari <djipi.mari@gmail.com>
Thu, 12 Oct 2017 00:00:52 +0000 (20:00 -0400)
committerJean-Paul Mari <djipi.mari@gmail.com>
Thu, 12 Oct 2017 00:00:52 +0000 (20:00 -0400)
docs/TODO
docs/vj_ReleaseNotes.txt
src/eeprom.cpp
src/eeprom.h

index c86f39d..d15efa1 100644 (file)
--- a/docs/TODO
+++ b/docs/TODO
@@ -1,75 +1,75 @@
-Stuff to add/fix for the next release of Virtual Jaguar
--------------------------------------------------------
-
-- Fix VC behavior to match what a real Jaguar does. Still not sure just what
-  the heck is going on there. [Shamus]
-- Create an EEPROMs directory (or whatever is in EEPROMPath[]) if it doesn't
-  already exist. [Shamus]
-- It would be nice to have the emulator pick up where you last left off, or at
-  least give you the option of continuing from your last session. This would
-  require save states, 'natch. ;-) [Shamus]
-- It would be nice to have "save states" for instant save/load capability.
-  [Shamus]
-- Cycle accuracy for GPU/DSP/OP/Blitter. [Shamus]
-- Need to propagate blitter fixes in the A1 <- A2 direction to the A1 -> A2
-  direction and the GPU fixes to various instructions to the DSP. [Shamus]
-- Blitter needs fixing. [Shamus]
-- In emulator screenshots. [Shamus]
-- Audio/video dumping. [Shamus]
-- Need to emulate bus contention. [Shamus]
-- Need to fix timing in the OP. As it is now, it gives a false impression of
-  how much it's capable of. [Shamus]
-- Fix coming out of fullscreen on Win32. As of now, it doesn't restore the
-  window position correctly [CJ]
-- Fix the Tripper Getem ROM so that it works. It has some tight coupling
-  between the M68K and the DSP that causes the DSP to starve itself; fixing
-  this will probably fix a bunch of other timing related issues as well.
-  [Shamus]
-
-
-Stuff that was added/fixed
---------------------------
-
-- Controller handling. [Shamus] [DONE--Shamus]
-- Full screen option. [Shamus] [DONE--Shamus]
-- Command line switches for frontends. [Shamus] [DONE-Shamus]
-- Fix DSP code so that it doesn't hang in a spinlock waiting for the sound
-  buffer to empty. Probably a CS lock contention issue. [Shamus] [DONE-Shamus]
-- Need to fix PAL mode to work with the virtual screen code. [DONE--Shamus]
-- There are a few ROMs that use some "quasi-illegal" 68K instructions. Need
-  to patch the 68K core to deal with these in a better way than they are
-  now. [DONE--Shamus]
-  NOTE: This behavior was verified on Rayman, the problem was due to attempting
-        to press both left & right at the same time!
-- We need a comprehensive way of determining what gets written where and
-  by whom (i.e., blitter wrote to range $F03000-$F03230) in order to figure
-  out the remaining problems with various ROMs. [DONE--Shamus]
-- Would also be nice to be able to dynamically change the keybindings for
-  the various keys on the emulated Jaguar controller while inside the emulator.
-  [DONE--Shamus]
-- Make sure that VJ doesn't crash if the useJaguarBIOS key is set to 1 and the
-  BIOS file isn't available. [DONE--Shamus]
-- There is a bug either with the GPU or the blitter (most likely the latter)
-  which causes the spinning "A"s in the BIOS startup code to be corrupted
-  when they are showing their backsides. [Shamus] [DONE--Shamus]
-  NOTE: This behavior has been verified on a real Jaguar and as such is not
-        an emulator bug. A Jaguar boot ROM bug, yes, but not ours. ;-)
-- Make it possible to completely disable the GUI (using a switch like -nogui
-  or the like) for people running VJ in a cabinet. [Shamus] [DONE--Shamus]
-- Code to stretch the display in a generic way would be nice. [Shamus]
-  [DONE for OpenGL--nwagenaar]
-- Would be nice to have a GUI for things that are set on the command line or
-  in the config file. [Shamus] [DONE--Shamus]
-- DSP code needs to be rewritten. [Shamus] [DONE but still work to be done--Shamus]
-- We need to have an external configuration file for remembering a user's
-  preferences, such as key bindings, etc. [Shamus] [DONE--Shamus]
-- We need to come up with a way to fix the aspect ratio for pixel modes that
-  aren't square (PWIDTH != 4). [Shamus] [DONE for OpenGL--Shamus]
-- GUI for ROM selection [Shamus] [DONE--Shamus]
-- Need to rewrite the main Jaguar execution loop to increment the VC by one
-  instead of by two, which is how the real Jaguar works. [Shamus] [DONE--Shamus]
-- Sound needs a rewrite. With SDL, this shouldn't be much of a problem.
-  Of course, whoever does this should realize that the PCM outs are probably
-  not being used for a majority of the ROMs out there--according to the JTRM,
-  you're supposed to use the I2S interface to output sound since the PCM outs
-  aren't even physically hooked up in the console! [Shamus] [DONE--Shamus]
+Stuff to add/fix for the next release of Virtual Jaguar\r
+-------------------------------------------------------\r
+\r
+- Fix VC behavior to match what a real Jaguar does. Still not sure just what\r
+  the heck is going on there. [Shamus]\r
+- It would be nice to have the emulator pick up where you last left off, or at\r
+  least give you the option of continuing from your last session. This would\r
+  require save states, 'natch. ;-) [Shamus]\r
+- It would be nice to have "save states" for instant save/load capability.\r
+  [Shamus]\r
+- Cycle accuracy for GPU/DSP/OP/Blitter. [Shamus]\r
+- Need to propagate blitter fixes in the A1 <- A2 direction to the A1 -> A2\r
+  direction and the GPU fixes to various instructions to the DSP. [Shamus]\r
+- Blitter needs fixing. [Shamus]\r
+- In emulator screenshots. [Shamus]\r
+- Audio/video dumping. [Shamus]\r
+- Need to emulate bus contention. [Shamus]\r
+- Need to fix timing in the OP. As it is now, it gives a false impression of\r
+  how much it's capable of. [Shamus]\r
+- Fix coming out of fullscreen on Win32. As of now, it doesn't restore the\r
+  window position correctly [CJ]\r
+- Fix the Tripper Getem ROM so that it works. It has some tight coupling\r
+  between the M68K and the DSP that causes the DSP to starve itself; fixing\r
+  this will probably fix a bunch of other timing related issues as well.\r
+  [Shamus]\r
+\r
+\r
+Stuff that was added/fixed\r
+--------------------------\r
+\r
+- Create an EEPROMs directory (or whatever is in EEPROMPath[]) if it doesn't\r
+  already exist. [Shamus] [DONE--Flynn]\r
+- Controller handling. [Shamus] [DONE--Shamus]\r
+- Full screen option. [Shamus] [DONE--Shamus]\r
+- Command line switches for frontends. [Shamus] [DONE-Shamus]\r
+- Fix DSP code so that it doesn't hang in a spinlock waiting for the sound\r
+  buffer to empty. Probably a CS lock contention issue. [Shamus] [DONE-Shamus]\r
+- Need to fix PAL mode to work with the virtual screen code. [DONE--Shamus]\r
+- There are a few ROMs that use some "quasi-illegal" 68K instructions. Need\r
+  to patch the 68K core to deal with these in a better way than they are\r
+  now. [DONE--Shamus]\r
+  NOTE: This behavior was verified on Rayman, the problem was due to attempting\r
+        to press both left & right at the same time!\r
+- We need a comprehensive way of determining what gets written where and\r
+  by whom (i.e., blitter wrote to range $F03000-$F03230) in order to figure\r
+  out the remaining problems with various ROMs. [DONE--Shamus]\r
+- Would also be nice to be able to dynamically change the keybindings for\r
+  the various keys on the emulated Jaguar controller while inside the emulator.\r
+  [DONE--Shamus]\r
+- Make sure that VJ doesn't crash if the useJaguarBIOS key is set to 1 and the\r
+  BIOS file isn't available. [DONE--Shamus]\r
+- There is a bug either with the GPU or the blitter (most likely the latter)\r
+  which causes the spinning "A"s in the BIOS startup code to be corrupted\r
+  when they are showing their backsides. [Shamus] [DONE--Shamus]\r
+  NOTE: This behavior has been verified on a real Jaguar and as such is not\r
+        an emulator bug. A Jaguar boot ROM bug, yes, but not ours. ;-)\r
+- Make it possible to completely disable the GUI (using a switch like -nogui\r
+  or the like) for people running VJ in a cabinet. [Shamus] [DONE--Shamus]\r
+- Code to stretch the display in a generic way would be nice. [Shamus]\r
+  [DONE for OpenGL--nwagenaar]\r
+- Would be nice to have a GUI for things that are set on the command line or\r
+  in the config file. [Shamus] [DONE--Shamus]\r
+- DSP code needs to be rewritten. [Shamus] [DONE but still work to be done--Shamus]\r
+- We need to have an external configuration file for remembering a user's\r
+  preferences, such as key bindings, etc. [Shamus] [DONE--Shamus]\r
+- We need to come up with a way to fix the aspect ratio for pixel modes that\r
+  aren't square (PWIDTH != 4). [Shamus] [DONE for OpenGL--Shamus]\r
+- GUI for ROM selection [Shamus] [DONE--Shamus]\r
+- Need to rewrite the main Jaguar execution loop to increment the VC by one\r
+  instead of by two, which is how the real Jaguar works. [Shamus] [DONE--Shamus]\r
+- Sound needs a rewrite. With SDL, this shouldn't be much of a problem.\r
+  Of course, whoever does this should realize that the PCM outs are probably\r
+  not being used for a majority of the ROMs out there--according to the JTRM,\r
+  you're supposed to use the I2S interface to output sound since the PCM outs\r
+  aren't even physically hooked up in the console! [Shamus] [DONE--Shamus]\r
index 73f84e8..361dd1b 100644 (file)
@@ -15,6 +15,7 @@ Release 3 (WiP)
 10) Solved an interference between the HW labels setting and the one used by the debugger\r
 -- The setting is now only the reference used\r
 11) Fixed the SP (Stack) window UI potential missing data\r
+12) Create a directory for EEPROMs (based on the EEPROMs setting) if it doesn't already exist\r
 \r
 Release 2 (3rd September 2017)\r
 ------------------------------\r
index 66c4a4c..9062c2c 100644 (file)
-//
-// Jaguar EEPROM handler
-//
-// by Cal2
-// GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS)
-// Cleanups/enhancements by James Hammons
-// (C) 2010 Underground Software
-//
-// JLH = James Hammons <jlhamm@acm.org>
-//
-// Who  When        What
-// ---  ----------  ------------------------------------------------------------
-// JLH  01/16/2010  Created this log ;-)
-//
-
-#include "eeprom.h"
-
-#include <stdlib.h>
-#include <string.h>                                                            // For memset
-#include "jaguar.h"
-#include "log.h"
-#include "settings.h"
-
-//#define eeprom_LOG
-
-static uint16_t eeprom_ram[64];
-static uint16_t cdromEEPROM[64];
-
-//
-// Private function prototypes
-//
-
-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);
-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,
-       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)
-{
-       // No need for EEPROM for the Memory Track device :-P
-       if (jaguarMainROMCRC32 == 0xFDF37F47)
-       {
-               WriteLog("EEPROM: Memory Track device detected...\n");
-               return;
-       }
-
-       // 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)
-       {
-               ReadEEPROMFromFile(fp, eeprom_ram);
-               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)
-       {
-               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 (!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)
-       {
-               WriteEEPROMToFile(fp, eeprom_ram);
-               fclose(fp);
-       }
-       else
-               WriteLog("EEPROM: Could not create file \"%s!\"\n", eeprom_filename);
-
-       // 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];
-       size_t ignored = 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(buffer, 1, 128, file);
-}
-
-
-uint8_t EepromReadByte(uint32_t offset)
-{
-       switch (offset)
-       {
-       case 0xF14001:
-               return eeprom_get_do();
-       case 0xF14801:
-               break;
-       case 0xF15001:
-               eeprom_set_cs(1);
-               break;
-//     default: WriteLog("EEPROM: unmapped 0x%.8x\n", offset); break;
-       }
-
-       return 0x00;
-}
-
-
-uint16_t EepromReadWord(uint32_t offset)
-{
-       return ((uint16_t)EepromReadByte(offset + 0) << 8) | EepromReadByte(offset + 1);
-}
-
-
-void EepromWriteByte(uint32_t offset, uint8_t data)
-{
-       switch (offset)
-       {
-       case 0xF14001:
-               break;
-       case 0xF14801:
-               eeprom_set_di(data & 0x01);
-               break;
-       case 0xF15001:
-               eeprom_set_cs(1);
-               break;
-//     default: WriteLog("eeprom: unmapped 0x%.8x\n",offset); break;
-       }
-}
-
-
-void EepromWriteWord(uint32_t offset, uint16_t data)
-{
-       EepromWriteByte(offset + 0, (data >> 8) & 0xFF);
-       EepromWriteByte(offset + 1, data & 0xFF);
-}
-
-
-/*
-;
-;   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);
-       switch (jerry_ee_state)
-       {
-       case EE_STATE_START:
-               jerry_ee_state = EE_STATE_OP_A;
-               break;
-       case EE_STATE_OP_A:
-               jerry_ee_op = (data << 1);
-               jerry_ee_state = EE_STATE_OP_B;
-               break;
-       case EE_STATE_OP_B:
-               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:
-               jerry_ee_rstate = EE_STATE_0_0;
-               jerry_ee_state = EE_READ_ADDRESS;
-               jerry_ee_direct_jump = 1;
-               jerry_ee_address_cnt = 6;
-               jerry_ee_address_data = 0;
-               break;
-       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
-               // WriteLog("eeprom: read only\n");
-               jerry_writes_enabled = 0;
-               jerry_ee_state = EE_STATE_START;
-               break;
-       case EE_STATE_0_0_1:
-               // writes all
-               jerry_ee_rstate = EE_STATE_0_0_1_0;
-               jerry_ee_state = EE_READ_DATA;
-               jerry_ee_data_cnt = 16;
-               jerry_ee_data = 0;
-               jerry_ee_direct_jump = 1;
-               break;
-       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!
-               }
-
-               //else
-               //      WriteLog("eeprom: not writing because read only\n");
-               jerry_ee_state = EE_STATE_BUSY;
-               break;
-       case EE_STATE_0_0_2:
-               // erase all
-               //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;
-               break;
-       case EE_STATE_0_0_3:
-               // writes enable
-               //WriteLog("eeprom: read/write\n");
-               jerry_writes_enabled = 1;
-               jerry_ee_state = EE_STATE_START;
-               break;
-       case EE_STATE_1:
-               jerry_ee_rstate = EE_STATE_1_0;
-               jerry_ee_state = EE_READ_ADDRESS;
-               jerry_ee_address_cnt = 6;
-               jerry_ee_address_data = 0;
-               jerry_ee_direct_jump = 1;
-               break;
-       case EE_STATE_1_0:
-               jerry_ee_rstate = EE_STATE_1_1;
-               jerry_ee_state = EE_READ_DATA;
-               jerry_ee_data_cnt = 16;
-               jerry_ee_data = 0;
-               jerry_ee_direct_jump = 1;
-               break;
-       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!
-               }
-
-               jerry_ee_state = EE_STATE_BUSY;
-               break;
-       case EE_STATE_2:
-               jerry_ee_rstate = EE_STATE_2_0;
-               jerry_ee_state = EE_READ_ADDRESS;
-               jerry_ee_address_cnt = 6;
-               jerry_ee_address_data = 0;
-               jerry_ee_data_cnt = 16;
-               jerry_ee_data = 0;
-               break;
-       case EE_STATE_3:
-               jerry_ee_rstate = EE_STATE_3_0;
-               jerry_ee_state = EE_READ_ADDRESS;
-               jerry_ee_address_cnt = 6;
-               jerry_ee_address_data = 0;
-               jerry_ee_direct_jump = 1;
-               break;
-       case EE_STATE_3_0:
-               //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:
-               //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:
-               jerry_ee_address_data <<= 1;
-               jerry_ee_address_data |= data;
-               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;
-                       //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;
-       }
-}
-
-
-static void eeprom_set_cs(uint32_t /*state*/)
-{
-//     WriteLog("eeprom: cs=%i\n",state);
-       jerry_ee_state = EE_STATE_START;
-       jerry_ee_op = 0;
-       jerry_ee_rstate = 0;
-       jerry_ee_address_data = 0;
-       jerry_ee_address_cnt = 6;
-       jerry_ee_data = 0;
-       jerry_ee_data_cnt = 16;
-       jerry_writes_enabled = 1;
-}
-
-
-static uint32_t eeprom_get_do(void)
-{
-       uint16_t data = 1;
-
-       switch (jerry_ee_state)
-       {
-       case EE_STATE_START:
-               data = 1;
-               break;
-       case EE_STATE_BUSY:
-               jerry_ee_state = EE_STATE_START;
-               data = 0;
-               break;
-       case EE_STATE_2_0:
-               jerry_ee_data_cnt--;
-               data = (eeprom_ram[jerry_ee_address_data] >> jerry_ee_data_cnt) & 0x01;
-
-               if (!jerry_ee_data_cnt)
-               {
-                       //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;
-       }
-
-//     WriteLog("eeprom: do=%i\n",data);
-       return data;
-}
-
+//\r
+// Jaguar EEPROM handler\r
+//\r
+// by Cal2\r
+// GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS)\r
+// Cleanups/enhancements by James Hammons\r
+// (C) 2010 Underground Software\r
+//\r
+// JLH = James Hammons <jlhamm@acm.org>\r
+// JPM = Jean-Paul Mari <djipi.mari@gmail.com>\r
+//\r
+// Who  When        What\r
+// ---  ----------  ------------------------------------------------------------\r
+// JLH  01/16/2010  Created this log ;-)\r
+// JPM  10/11/2017  Directory detection and creation if missing\r
+//\r
+\r
+#include "eeprom.h"\r
+#include <direct.h>\r
+#include <stdlib.h>\r
+#include <string.h>                                                            // For memset\r
+#include "jaguar.h"\r
+#include "log.h"\r
+#include "settings.h"\r
+\r
+#define eeprom_LOG\r
+\r
+static uint16_t eeprom_ram[64];\r
+static uint16_t cdromEEPROM[64];\r
+\r
+//\r
+// Private function prototypes\r
+//\r
+\r
+static void EEPROMSave(void);\r
+static void eeprom_set_di(uint32_t state);\r
+static void eeprom_set_cs(uint32_t state);\r
+static uint32_t eeprom_get_do(void);\r
+void ReadEEPROMFromFile(FILE * file, uint16_t * ram);\r
+void WriteEEPROMToFile(FILE * file, uint16_t * ram);\r
+\r
+\r
+enum { EE_STATE_START = 1, EE_STATE_OP_A, EE_STATE_OP_B, EE_STATE_0, EE_STATE_1,\r
+       EE_STATE_2, EE_STATE_3, EE_STATE_0_0, EE_READ_ADDRESS, EE_STATE_0_0_0,\r
+       EE_STATE_0_0_1, EE_STATE_0_0_2, EE_STATE_0_0_3, EE_STATE_0_0_1_0, EE_READ_DATA,\r
+       EE_STATE_BUSY, EE_STATE_1_0, EE_STATE_1_1, EE_STATE_2_0, EE_STATE_3_0 };\r
+\r
+// Local global variables\r
+\r
+static uint16_t jerry_ee_state = EE_STATE_START;\r
+static uint16_t jerry_ee_op = 0;\r
+static uint16_t jerry_ee_rstate = 0;\r
+static uint16_t jerry_ee_address_data = 0;\r
+static uint16_t jerry_ee_address_cnt = 6;\r
+static uint16_t jerry_ee_data = 0;\r
+static uint16_t jerry_ee_data_cnt = 16;\r
+static uint16_t jerry_writes_enabled = 0;\r
+static uint16_t jerry_ee_direct_jump = 0;\r
+\r
+static char eeprom_filename[MAX_PATH];\r
+static char cdromEEPROMFilename[MAX_PATH];\r
+static bool haveEEPROM = false;\r
+static bool haveCDROMEEPROM = false;\r
+\r
+\r
+// EEPROM initialisations\r
+void EepromInit(void)\r
+{\r
+       FILE * fp;\r
+\r
+       // No need for EEPROM for the Memory Track device :-P\r
+       if (jaguarMainROMCRC32 == 0xFDF37F47)\r
+       {\r
+               WriteLog("EEPROM: Memory Track device detected...\n");\r
+       }\r
+       else\r
+       {\r
+               // Handle regular cartridge EEPROM\r
+               sprintf(eeprom_filename, "%s%08X.eeprom", vjs.EEPROMPath, (unsigned int)jaguarMainROMCRC32);\r
+               fp = fopen(eeprom_filename, "rb");\r
+\r
+               if (fp)\r
+               {\r
+                       ReadEEPROMFromFile(fp, eeprom_ram);\r
+                       fclose(fp);\r
+                       WriteLog("EEPROM: Loaded from %s\n", eeprom_filename);\r
+                       haveEEPROM = true;\r
+               }\r
+               else\r
+               {\r
+                       WriteLog("EEPROM: Could not open file \"%s\"!\n", eeprom_filename);\r
+               }\r
+\r
+               // Handle JagCD EEPROM\r
+               sprintf(cdromEEPROMFilename, "%scdrom.eeprom", vjs.EEPROMPath);\r
+               fp = fopen(cdromEEPROMFilename, "rb");\r
+\r
+               if (fp)\r
+               {\r
+                       ReadEEPROMFromFile(fp, cdromEEPROM);\r
+                       fclose(fp);\r
+                       WriteLog("EEPROM: Loaded from cdrom.eeprom\n");\r
+                       haveCDROMEEPROM = true;\r
+               }\r
+               else\r
+               {\r
+                       WriteLog("EEPROM: Could not open file \"%s\"!\n", cdromEEPROMFilename);\r
+               }\r
+       }\r
+}\r
+\r
+\r
+// EEPROM reset\r
+void EepromReset(void)\r
+{\r
+       if (!haveEEPROM)\r
+               memset(eeprom_ram, 0xFF, 64 * sizeof(uint16_t));\r
+\r
+       if (!haveCDROMEEPROM)\r
+               memset(cdromEEPROM, 0xFF, 64 * sizeof(uint16_t));\r
+}\r
+\r
+\r
+//\r
+void EepromDone(void)\r
+{\r
+       WriteLog("EEPROM: Done.\n");\r
+}\r
+\r
+\r
+// EEPROM save\r
+static void EEPROMSave(void)\r
+{\r
+       FILE * fp;\r
+\r
+       // Check if EEPROM directory exists and try to create it if not\r
+       if (_mkdir(vjs.EEPROMPath))\r
+       {\r
+               WriteLog("EEPROM: Could not create directory \"%s!\"\n", vjs.EEPROMPath);\r
+       }\r
+\r
+       // Write out regular cartridge EEPROM data\r
+       fp = fopen(eeprom_filename, "wb");\r
+       if (fp)\r
+       {\r
+               WriteEEPROMToFile(fp, eeprom_ram);\r
+               fclose(fp);\r
+       }\r
+       else\r
+       {\r
+               WriteLog("EEPROM: Could not create file \"%s!\"\n", eeprom_filename);\r
+       }\r
+\r
+       // Write out JagCD EEPROM data\r
+       fp = fopen(cdromEEPROMFilename, "wb");\r
+       if (fp)\r
+       {\r
+               WriteEEPROMToFile(fp, cdromEEPROM);\r
+               fclose(fp);\r
+       }\r
+       else\r
+       {\r
+               WriteLog("EEPROM: Could not create file \"%s!\"\n", cdromEEPROMFilename);\r
+       }\r
+}\r
+\r
+\r
+//\r
+// Read/write EEPROM files to disk in an endian safe manner\r
+//\r
+void ReadEEPROMFromFile(FILE * file, uint16_t * ram)\r
+{\r
+       uint8_t buffer[128];\r
+       size_t ignored = fread(buffer, 1, 128, file);\r
+\r
+       for(int i=0; i<64; i++)\r
+               ram[i] = (buffer[(i * 2) + 0] << 8) | buffer[(i * 2) + 1];\r
+}\r
+\r
+\r
+void WriteEEPROMToFile(FILE * file, uint16_t * ram)\r
+{\r
+       uint8_t buffer[128];\r
+\r
+       for(int i=0; i<64; i++)\r
+       {\r
+               buffer[(i * 2) + 0] = ram[i] >> 8;\r
+               buffer[(i * 2) + 1] = ram[i] & 0xFF;\r
+       }\r
+\r
+       fwrite(buffer, 1, 128, file);\r
+}\r
+\r
+\r
+uint8_t EepromReadByte(uint32_t offset)\r
+{\r
+       switch (offset)\r
+       {\r
+       case 0xF14001:\r
+               return eeprom_get_do();\r
+       case 0xF14801:\r
+               break;\r
+       case 0xF15001:\r
+               eeprom_set_cs(1);\r
+               break;\r
+       default:\r
+#ifdef eeprom_LOG\r
+               WriteLog("EEPROM: unmapped 0x%.8x\n", offset);\r
+#endif\r
+               break;\r
+       }\r
+\r
+       return 0x00;\r
+}\r
+\r
+\r
+uint16_t EepromReadWord(uint32_t offset)\r
+{\r
+       return ((uint16_t)EepromReadByte(offset + 0) << 8) | EepromReadByte(offset + 1);\r
+}\r
+\r
+\r
+void EepromWriteByte(uint32_t offset, uint8_t data)\r
+{\r
+       switch (offset)\r
+       {\r
+       case 0xF14001:\r
+               break;\r
+       case 0xF14801:\r
+               eeprom_set_di(data & 0x01);\r
+               break;\r
+       case 0xF15001:\r
+               eeprom_set_cs(1);\r
+               break;\r
+       default:\r
+#ifdef eeprom_LOG\r
+               WriteLog("eeprom: unmapped 0x%.8x\n",offset);\r
+#endif\r
+               break;\r
+       }\r
+}\r
+\r
+\r
+void EepromWriteWord(uint32_t offset, uint16_t data)\r
+{\r
+       EepromWriteByte(offset + 0, (data >> 8) & 0xFF);\r
+       EepromWriteByte(offset + 1, data & 0xFF);\r
+}\r
+\r
+\r
+/*\r
+;\r
+;   Commands specific to the National Semiconductor NM93C14\r
+;\r
+;\r
+;  9-bit commands..\r
+;                       876543210\r
+eEWDS  equ     %100000000              ;Erase/Write disable (default)\r
+eWRAL  equ     %100010000              ;Writes all registers\r
+eERAL  equ     %100100000              ;Erase all registers\r
+eEWEN  equ     %100110000              ;Erase/write Enable\r
+eWRITE equ     %101000000              ;Write selected register\r
+eREAD  equ     %110000000              ;read from EEPROM\r
+eERASE equ     %111000000              ;Erase selected register\r
+*/\r
+\r
+\r
+static void eeprom_set_di(uint32_t data)\r
+{\r
+#ifdef eeprom_LOG\r
+       WriteLog("eeprom: di=%i\n",data);\r
+       WriteLog("eeprom: state %i\n",jerry_ee_state);\r
+#endif\r
+\r
+       switch (jerry_ee_state)\r
+       {\r
+       case EE_STATE_START:\r
+               jerry_ee_state = EE_STATE_OP_A;\r
+               break;\r
+       case EE_STATE_OP_A:\r
+               jerry_ee_op = (data << 1);\r
+               jerry_ee_state = EE_STATE_OP_B;\r
+               break;\r
+       case EE_STATE_OP_B:\r
+               jerry_ee_op |= data;\r
+               jerry_ee_direct_jump = 0;\r
+#ifdef eeprom_LOG\r
+               WriteLog("eeprom: opcode %i\n",jerry_ee_op);\r
+#endif\r
+\r
+               switch (jerry_ee_op)\r
+               {\r
+               // Opcode 00: eEWEN, eERAL, eWRAL, eEWNDS\r
+               case 0: jerry_ee_state = EE_STATE_0; break;\r
+               // Opcode 01: eWRITE (Write selected register)\r
+               case 1: jerry_ee_state = EE_STATE_1; break;\r
+               // Opcode 10: eREAD (Read from EEPROM)\r
+               case 2: jerry_ee_state = EE_STATE_2; break;\r
+               // Opcode 11: eERASE (Erase selected register)\r
+               case 3: jerry_ee_state = EE_STATE_3; break;\r
+               }\r
+\r
+               eeprom_set_di(data);\r
+               break;\r
+       case EE_STATE_0:\r
+               jerry_ee_rstate = EE_STATE_0_0;\r
+               jerry_ee_state = EE_READ_ADDRESS;\r
+               jerry_ee_direct_jump = 1;\r
+               jerry_ee_address_cnt = 6;\r
+               jerry_ee_address_data = 0;\r
+               break;\r
+       case EE_STATE_0_0:\r
+               switch ((jerry_ee_address_data >> 4) & 0x03)\r
+               {\r
+               // Opcode 00 00: eEWDS (Erase/Write disable)\r
+               case 0: jerry_ee_state=EE_STATE_0_0_0; break;\r
+               // Opcode 00 01: eWRAL (Write all registers)\r
+               case 1: jerry_ee_state=EE_STATE_0_0_1; break;\r
+               // Opcode 00 10: eERAL (Erase all registers)\r
+               case 2: jerry_ee_state=EE_STATE_0_0_2; break;\r
+               // Opcode 00 11: eEWEN (Erase/Write enable)\r
+               case 3: jerry_ee_state=EE_STATE_0_0_3; break;\r
+               }\r
+\r
+               eeprom_set_di(data);\r
+               break;\r
+       case EE_STATE_0_0_0:\r
+               // writes disable\r
+#ifdef eeprom_LOG\r
+               WriteLog("eeprom: read only\n");\r
+#endif\r
+               jerry_writes_enabled = 0;\r
+               jerry_ee_state = EE_STATE_START;\r
+               break;\r
+       case EE_STATE_0_0_1:\r
+               // writes all\r
+               jerry_ee_rstate = EE_STATE_0_0_1_0;\r
+               jerry_ee_state = EE_READ_DATA;\r
+               jerry_ee_data_cnt = 16;\r
+               jerry_ee_data = 0;\r
+               jerry_ee_direct_jump = 1;\r
+               break;\r
+       case EE_STATE_0_0_1_0:\r
+#ifdef eeprom_LOG\r
+               WriteLog("eeprom: filling eeprom with 0x%.4x\n",data);\r
+#endif\r
+               if (jerry_writes_enabled)\r
+               {\r
+                       for(int i=0; i<64; i++)\r
+                               eeprom_ram[i] = jerry_ee_data;\r
+\r
+                       EEPROMSave();                                           // Save it NOW!\r
+               }\r
+\r
+               //else\r
+#ifdef eeprom_LOG\r
+               WriteLog("eeprom: not writing because read only\n");\r
+#endif\r
+               jerry_ee_state = EE_STATE_BUSY;\r
+               break;\r
+       case EE_STATE_0_0_2:\r
+               // erase all\r
+#ifdef eeprom_LOG\r
+               WriteLog("eeprom: erasing eeprom\n");\r
+#endif\r
+               if (jerry_writes_enabled)\r
+                       for(int i=0; i<64; i++)\r
+                               eeprom_ram[i] = 0xFFFF;\r
+\r
+               jerry_ee_state = EE_STATE_BUSY;\r
+               break;\r
+       case EE_STATE_0_0_3:\r
+               // writes enable\r
+#ifdef eeprom_LOG\r
+               WriteLog("eeprom: read/write\n");\r
+#endif\r
+               jerry_writes_enabled = 1;\r
+               jerry_ee_state = EE_STATE_START;\r
+               break;\r
+       case EE_STATE_1:\r
+               jerry_ee_rstate = EE_STATE_1_0;\r
+               jerry_ee_state = EE_READ_ADDRESS;\r
+               jerry_ee_address_cnt = 6;\r
+               jerry_ee_address_data = 0;\r
+               jerry_ee_direct_jump = 1;\r
+               break;\r
+       case EE_STATE_1_0:\r
+               jerry_ee_rstate = EE_STATE_1_1;\r
+               jerry_ee_state = EE_READ_DATA;\r
+               jerry_ee_data_cnt = 16;\r
+               jerry_ee_data = 0;\r
+               jerry_ee_direct_jump = 1;\r
+               break;\r
+       case EE_STATE_1_1:\r
+#ifdef eeprom_LOG\r
+               WriteLog("eeprom: writing 0x%.4x at 0x%.2x\n",jerry_ee_data,jerry_ee_address_data);\r
+#endif\r
+               if (jerry_writes_enabled)\r
+               {\r
+                       eeprom_ram[jerry_ee_address_data] = jerry_ee_data;\r
+                       EEPROMSave();                                           // Save it NOW!\r
+               }\r
+\r
+               jerry_ee_state = EE_STATE_BUSY;\r
+               break;\r
+       case EE_STATE_2:\r
+               jerry_ee_rstate = EE_STATE_2_0;\r
+               jerry_ee_state = EE_READ_ADDRESS;\r
+               jerry_ee_address_cnt = 6;\r
+               jerry_ee_address_data = 0;\r
+               jerry_ee_data_cnt = 16;\r
+               jerry_ee_data = 0;\r
+               break;\r
+       case EE_STATE_3:\r
+               jerry_ee_rstate = EE_STATE_3_0;\r
+               jerry_ee_state = EE_READ_ADDRESS;\r
+               jerry_ee_address_cnt = 6;\r
+               jerry_ee_address_data = 0;\r
+               jerry_ee_direct_jump = 1;\r
+               break;\r
+       case EE_STATE_3_0:\r
+#ifdef eeprom_LOG\r
+               WriteLog("eeprom: erasing 0x%.2x\n",jerry_ee_address_data);\r
+#endif\r
+               if (jerry_writes_enabled)\r
+                       eeprom_ram[jerry_ee_address_data] = 0xFFFF;\r
+\r
+               jerry_ee_state = EE_STATE_BUSY;\r
+               break;\r
+       case EE_READ_DATA:\r
+#ifdef eeprom_LOG\r
+               WriteLog("eeprom:\t\t\t%i bit %i\n",data,jerry_ee_data_cnt-1);\r
+#endif\r
+               jerry_ee_data <<= 1;\r
+               jerry_ee_data |= data;\r
+               jerry_ee_data_cnt--;\r
+\r
+               if (!jerry_ee_data_cnt)\r
+               {\r
+                       jerry_ee_state = jerry_ee_rstate;\r
+\r
+                       if (jerry_ee_direct_jump)\r
+                               eeprom_set_di(data);\r
+               }\r
+\r
+               break;\r
+       case EE_READ_ADDRESS:\r
+               jerry_ee_address_data <<= 1;\r
+               jerry_ee_address_data |= data;\r
+               jerry_ee_address_cnt--;\r
+#ifdef eeprom_LOG\r
+               WriteLog("eeprom:\t%i bits remaining\n",jerry_ee_address_cnt);\r
+#endif\r
+\r
+               if (!jerry_ee_address_cnt)\r
+               {\r
+                       jerry_ee_state = jerry_ee_rstate;\r
+#ifdef eeprom_LOG\r
+                       WriteLog("eeprom:\t\tread address 0x%.2x\n",jerry_ee_address_data);\r
+#endif\r
+\r
+                       if (jerry_ee_direct_jump)\r
+                               eeprom_set_di(data);\r
+               }\r
+\r
+               break;\r
+       default:\r
+               jerry_ee_state = EE_STATE_OP_A;\r
+       }\r
+}\r
+\r
+\r
+static void eeprom_set_cs(uint32_t state)\r
+{\r
+#ifdef eeprom_LOG\r
+       WriteLog("eeprom: cs=%i\n",state);\r
+#endif\r
+       jerry_ee_state = EE_STATE_START;\r
+       jerry_ee_op = 0;\r
+       jerry_ee_rstate = 0;\r
+       jerry_ee_address_data = 0;\r
+       jerry_ee_address_cnt = 6;\r
+       jerry_ee_data = 0;\r
+       jerry_ee_data_cnt = 16;\r
+       jerry_writes_enabled = 1;\r
+}\r
+\r
+\r
+static uint32_t eeprom_get_do(void)\r
+{\r
+       uint16_t data = 1;\r
+\r
+       switch (jerry_ee_state)\r
+       {\r
+       case EE_STATE_START:\r
+               data = 1;\r
+               break;\r
+       case EE_STATE_BUSY:\r
+               jerry_ee_state = EE_STATE_START;\r
+               data = 0;\r
+               break;\r
+       case EE_STATE_2_0:\r
+               jerry_ee_data_cnt--;\r
+               data = (eeprom_ram[jerry_ee_address_data] >> jerry_ee_data_cnt) & 0x01;\r
+\r
+               if (!jerry_ee_data_cnt)\r
+               {\r
+#ifdef eeprom_LOG\r
+                       //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());\r
+#endif\r
+                       jerry_ee_state = EE_STATE_START;\r
+               }\r
+               break;\r
+       }\r
+\r
+#ifdef eeprom_LOG\r
+       WriteLog("eeprom: do=%i\n",data);\r
+#endif\r
+       return data;\r
+}\r
+\r
dissimilarity index 68%
index 0f89ade..b98c189 100644 (file)
@@ -1,19 +1,19 @@
-//
-// EEPROM.H: Header file
-//
-
-#ifndef __EEPROM_H__
-#define __EEPROM_H__
-
-#include <stdint.h>
-
-void EepromInit(void);
-void EepromReset(void);
-void EepromDone(void);
-
-uint8_t EepromReadByte(uint32_t offset);
-uint16_t EepromReadWord(uint32_t offset);
-void EepromWriteByte(uint32_t offset, uint8_t data);
-void EepromWriteWord(uint32_t offset, uint16_t data);
-
-#endif // __EEPROM_H__
+//
+// EEPROM.H: Header file
+//
+
+#ifndef __EEPROM_H__
+#define __EEPROM_H__
+
+#include <stdint.h>
+
+extern void EepromInit(void);
+extern void EepromReset(void);
+extern void EepromDone(void);
+
+extern uint8_t EepromReadByte(uint32_t offset);
+extern uint16_t EepromReadWord(uint32_t offset);
+extern void EepromWriteByte(uint32_t offset, uint8_t data);
+extern void EepromWriteWord(uint32_t offset, uint16_t data);
+
+#endif // __EEPROM_H__