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
 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
 \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__