2 // Jaguar EEPROM handler
5 // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS)
6 // Cleanups/enhancements by James L. Hammons
12 #include <string.h> // For memset
19 static uint16 eeprom_ram[64];
22 // Private function prototypes
25 static void EEPROMSave(void);
26 static void eeprom_set_di(uint32 state);
27 static void eeprom_set_cs(uint32 state);
28 static uint32 eeprom_get_do(void);
30 enum { EE_STATE_START = 1, EE_STATE_OP_A, EE_STATE_OP_B, EE_STATE_0, EE_STATE_1,
31 EE_STATE_2, EE_STATE_3, EE_STATE_0_0, EE_READ_ADDRESS, EE_STATE_0_0_0,
32 EE_STATE_0_0_1, EE_STATE_0_0_2, EE_STATE_0_0_3, EE_STATE_0_0_1_0, EE_READ_DATA,
33 EE_STATE_BUSY, EE_STATE_1_0, EE_STATE_1_1, EE_STATE_2_0, EE_STATE_3_0 };
35 // Local global variables
37 static uint16 jerry_ee_state = EE_STATE_START;
38 static uint16 jerry_ee_op = 0;
39 static uint16 jerry_ee_rstate = 0;
40 static uint16 jerry_ee_address_data = 0;
41 static uint16 jerry_ee_address_cnt = 6;
42 static uint16 jerry_ee_data = 0;
43 static uint16 jerry_ee_data_cnt = 16;
44 static uint16 jerry_writes_enabled = 0;
45 static uint16 jerry_ee_direct_jump = 0;
46 static char eeprom_filename[MAX_PATH];
47 static bool foundEEPROM = false;
51 sprintf(eeprom_filename, "%s%08X.eep", vjs.EEPROMPath, (unsigned int)jaguarMainROMCRC32);
52 FILE * fp = fopen(eeprom_filename, "rb");
56 fread(eeprom_ram, 1, 128, fp);
58 WriteLog("EEPROM: Loaded from %s\n", eeprom_filename);
62 WriteLog("EEPROM: Could not open file \"%s\"!\n", eeprom_filename);
65 void EepromReset(void)
68 memset(eeprom_ram, 0xFF, 64 * sizeof(uint16));
73 WriteLog("EEPROM: Done.\n");
76 static void EEPROMSave(void)
78 FILE * fp = fopen(eeprom_filename, "wb");
82 WriteLog("EEPROM: Could not create file \"%s!\"\n", eeprom_filename);
86 fwrite(eeprom_ram, 1, 128, fp);
90 uint8 EepromReadByte(uint32 offset)
95 return eeprom_get_do();
101 // default: WriteLog("EEPROM: unmapped 0x%.8x\n", offset); break;
107 uint16 EepromReadWord(uint32 offset)
109 return ((uint16)EepromReadByte(offset + 0) << 8) | EepromReadByte(offset + 1);
112 void EepromWriteByte(uint32 offset, uint8 data)
119 eeprom_set_di(data & 0x01);
124 // default: WriteLog("eeprom: unmapped 0x%.8x\n",offset); break;
128 void EepromWriteWord(uint32 offset, uint16 data)
130 EepromWriteByte(offset + 0, (data >> 8) & 0xFF);
131 EepromWriteByte(offset + 1, data & 0xFF);
134 static void eeprom_set_di(uint32 data)
136 // WriteLog("eeprom: di=%i\n",data);
137 // WriteLog("eeprom: state %i\n",jerry_ee_state);
138 switch (jerry_ee_state)
141 jerry_ee_state = EE_STATE_OP_A;
144 jerry_ee_op = (data << 1);
145 jerry_ee_state = EE_STATE_OP_B;
149 jerry_ee_direct_jump = 0;
150 // WriteLog("eeprom: opcode %i\n",jerry_ee_op);
153 case 0: jerry_ee_state = EE_STATE_0; break;
154 case 1: jerry_ee_state = EE_STATE_1; break;
155 case 2: jerry_ee_state = EE_STATE_2; break;
156 case 3: jerry_ee_state = EE_STATE_3; break;
161 jerry_ee_rstate = EE_STATE_0_0;
162 jerry_ee_state = EE_READ_ADDRESS;
163 jerry_ee_direct_jump = 1;
164 jerry_ee_address_cnt = 6;
165 jerry_ee_address_data = 0;
168 switch ((jerry_ee_address_data >> 4) & 0x03)
170 case 0: jerry_ee_state=EE_STATE_0_0_0; break;
171 case 1: jerry_ee_state=EE_STATE_0_0_1; break;
172 case 2: jerry_ee_state=EE_STATE_0_0_2; break;
173 case 3: jerry_ee_state=EE_STATE_0_0_3; break;
179 // WriteLog("eeprom: read only\n");
180 jerry_writes_enabled = 0;
181 jerry_ee_state = EE_STATE_START;
185 jerry_ee_rstate = EE_STATE_0_0_1_0;
186 jerry_ee_state = EE_READ_DATA;
187 jerry_ee_data_cnt = 16;
189 jerry_ee_direct_jump = 1;
191 case EE_STATE_0_0_1_0:
192 // WriteLog("eeprom: filling eeprom with 0x%.4x\n",data);
193 if (jerry_writes_enabled)
194 for(int i=0; i<64; i++)
195 eeprom_ram[i] = jerry_ee_data;
196 EEPROMSave(); // Save it NOW!
198 // WriteLog("eeprom: not writing because read only\n");
199 jerry_ee_state = EE_STATE_BUSY;
203 //WriteLog("eeprom: erasing eeprom\n");
204 if (jerry_writes_enabled)
205 for(int i=0; i<64; i++)
206 eeprom_ram[i] = 0xFFFF;
208 jerry_ee_state = EE_STATE_BUSY;
212 //WriteLog("eeprom: read/write\n");
213 jerry_writes_enabled = 1;
214 jerry_ee_state = EE_STATE_START;
217 jerry_ee_rstate = EE_STATE_1_0;
218 jerry_ee_state = EE_READ_ADDRESS;
219 jerry_ee_address_cnt = 6;
220 jerry_ee_address_data = 0;
221 jerry_ee_direct_jump = 1;
224 jerry_ee_rstate = EE_STATE_1_1;
225 jerry_ee_state = EE_READ_DATA;
226 jerry_ee_data_cnt = 16;
228 jerry_ee_direct_jump = 1;
231 //WriteLog("eeprom: writing 0x%.4x at 0x%.2x\n",jerry_ee_data,jerry_ee_address_data);
232 if (jerry_writes_enabled)
233 eeprom_ram[jerry_ee_address_data] = jerry_ee_data;
234 EEPROMSave(); // Save it NOW!
235 jerry_ee_state = EE_STATE_BUSY;
238 jerry_ee_rstate = EE_STATE_2_0;
239 jerry_ee_state = EE_READ_ADDRESS;
240 jerry_ee_address_cnt = 6;
241 jerry_ee_address_data = 0;
242 jerry_ee_data_cnt = 16;
246 jerry_ee_rstate = EE_STATE_3_0;
247 jerry_ee_state = EE_READ_ADDRESS;
248 jerry_ee_address_cnt = 6;
249 jerry_ee_address_data = 0;
250 jerry_ee_direct_jump = 1;
253 //WriteLog("eeprom: erasing 0x%.2x\n",jerry_ee_address_data);
254 if (jerry_writes_enabled)
255 eeprom_ram[jerry_ee_address_data] = 0xFFFF;
256 jerry_ee_state = EE_STATE_BUSY;
259 //WriteLog("eeprom:\t\t\t%i bit %i\n",data,jerry_ee_data_cnt-1);
261 jerry_ee_data |= data;
263 if (!jerry_ee_data_cnt)
265 jerry_ee_state = jerry_ee_rstate;
266 if (jerry_ee_direct_jump)
270 case EE_READ_ADDRESS:
271 jerry_ee_address_data <<= 1;
272 jerry_ee_address_data |= data;
273 jerry_ee_address_cnt--;
274 // WriteLog("eeprom:\t%i bits remaining\n",jerry_ee_address_cnt);
275 if (!jerry_ee_address_cnt)
277 jerry_ee_state = jerry_ee_rstate;
278 //WriteLog("eeprom:\t\tread address 0x%.2x\n",jerry_ee_address_data);
279 if (jerry_ee_direct_jump)
284 jerry_ee_state = EE_STATE_OP_A;
288 static void eeprom_set_cs(uint32 state)
290 // WriteLog("eeprom: cs=%i\n",state);
291 jerry_ee_state = EE_STATE_START;
294 jerry_ee_address_data = 0;
295 jerry_ee_address_cnt = 6;
297 jerry_ee_data_cnt = 16;
298 jerry_writes_enabled = 1;
301 static uint32 eeprom_get_do(void)
305 switch (jerry_ee_state)
311 jerry_ee_state = EE_STATE_START;
316 data = (eeprom_ram[jerry_ee_address_data] & (1 << jerry_ee_data_cnt)) >> jerry_ee_data_cnt;
317 if (!jerry_ee_data_cnt)
319 //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());
320 jerry_ee_state = EE_STATE_START;
325 // WriteLog("eeprom: do=%i\n",data);