]> Shamusworld >> Repos - virtualjaguar/blob - src/eeprom.cpp
First stab at adding translations. Translators needed! :-)
[virtualjaguar] / src / eeprom.cpp
1 //
2 // Jaguar EEPROM handler
3 //
4 // by Cal2
5 // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS)
6 // Cleanups/enhancements by James Hammons
7 // (C) 2010 Underground Software
8 //
9 // JLH = James Hammons <jlhamm@acm.org>
10 //
11 // Who  When        What
12 // ---  ----------  -------------------------------------------------------------
13 // JLH  01/16/2010  Created this log ;-)
14 //
15
16 #include "eeprom.h"
17
18 #include <stdlib.h>
19 #include <string.h>                                                             // For memset
20 #include "jaguar.h"
21 #include "log.h"
22 #include "settings.h"
23
24 //#define eeprom_LOG
25
26 static uint16_t eeprom_ram[64];
27 static uint16_t cdromEEPROM[64];
28
29 //
30 // Private function prototypes
31 //
32
33 static void EEPROMSave(void);
34 static void eeprom_set_di(uint32_t state);
35 static void eeprom_set_cs(uint32_t state);
36 static uint32_t eeprom_get_do(void);
37
38 enum { EE_STATE_START = 1, EE_STATE_OP_A, EE_STATE_OP_B, EE_STATE_0, EE_STATE_1,
39         EE_STATE_2, EE_STATE_3, EE_STATE_0_0, EE_READ_ADDRESS, EE_STATE_0_0_0,
40         EE_STATE_0_0_1, EE_STATE_0_0_2, EE_STATE_0_0_3, EE_STATE_0_0_1_0, EE_READ_DATA,
41         EE_STATE_BUSY, EE_STATE_1_0, EE_STATE_1_1, EE_STATE_2_0, EE_STATE_3_0 };
42
43 // Local global variables
44
45 static uint16_t jerry_ee_state = EE_STATE_START;
46 static uint16_t jerry_ee_op = 0;
47 static uint16_t jerry_ee_rstate = 0;
48 static uint16_t jerry_ee_address_data = 0;
49 static uint16_t jerry_ee_address_cnt = 6;
50 static uint16_t jerry_ee_data = 0;
51 static uint16_t jerry_ee_data_cnt = 16;
52 static uint16_t jerry_writes_enabled = 0;
53 static uint16_t jerry_ee_direct_jump = 0;
54
55 static char eeprom_filename[MAX_PATH];
56 static char cdromEEPROMFilename[MAX_PATH];
57 static bool haveEEPROM = false;
58 static bool haveCDROMEEPROM = false;
59
60
61 void EepromInit(void)
62 {
63         // Handle regular cartridge EEPROM
64         sprintf(eeprom_filename, "%s%08X.eep", vjs.EEPROMPath, (unsigned int)jaguarMainROMCRC32);
65         sprintf(cdromEEPROMFilename, "%scdrom.eeprom", vjs.EEPROMPath);
66         FILE * fp = fopen(eeprom_filename, "rb");
67
68         if (fp)
69         {
70                 fread(eeprom_ram, 1, 128, fp);
71                 fclose(fp);
72                 WriteLog("EEPROM: Loaded from %s\n", eeprom_filename);
73                 haveEEPROM = true;
74         }
75         else
76                 WriteLog("EEPROM: Could not open file \"%s\"!\n", eeprom_filename);
77
78         // Handle JagCD EEPROM
79         fp = fopen(cdromEEPROMFilename, "rb");
80
81         if (fp)
82         {
83                 fread(cdromEEPROM, 1, 128, fp);
84                 fclose(fp);
85                 WriteLog("EEPROM: Loaded from cdrom.eeprom\n");
86                 haveCDROMEEPROM = true;
87         }
88         else
89                 WriteLog("EEPROM: Could not open file \"%s\"!\n", cdromEEPROMFilename);
90 }
91
92
93 void EepromReset(void)
94 {
95         if (!haveEEPROM)
96                 memset(eeprom_ram, 0xFF, 64 * sizeof(uint16_t));
97
98         if (!haveCDROMEEPROM)
99                 memset(cdromEEPROM, 0xFF, 64 * sizeof(uint16_t));
100 }
101
102
103 void EepromDone(void)
104 {
105         WriteLog("EEPROM: Done.\n");
106 }
107
108
109 static void EEPROMSave(void)
110 {
111         // Write out regular cartridge EEPROM data
112         FILE * fp = fopen(eeprom_filename, "wb");
113
114         if (fp)
115         {
116                 fwrite(eeprom_ram, 1, 128, fp);
117                 fclose(fp);
118         }
119         else
120                 WriteLog("EEPROM: Could not create file \"%s!\"\n", eeprom_filename);
121
122         // Write out JagCD EEPROM data
123         fp = fopen(cdromEEPROMFilename, "wb");
124
125         if (fp)
126         {
127                 fwrite(cdromEEPROM, 1, 128, fp);
128                 fclose(fp);
129         }
130         else
131                 WriteLog("EEPROM: Could not create file \"%s!\"\n", cdromEEPROMFilename);
132 }
133
134
135 uint8_t EepromReadByte(uint32_t offset)
136 {
137         switch (offset)
138         {
139         case 0xF14001:
140                 return eeprom_get_do();
141         case 0xF14801:
142                 break;
143         case 0xF15001:
144                 eeprom_set_cs(1);
145                 break;
146 //      default: WriteLog("EEPROM: unmapped 0x%.8x\n", offset); break;
147         }
148
149         return 0x00;
150 }
151
152
153 uint16_t EepromReadWord(uint32_t offset)
154 {
155         return ((uint16_t)EepromReadByte(offset + 0) << 8) | EepromReadByte(offset + 1);
156 }
157
158
159 void EepromWriteByte(uint32_t offset, uint8_t data)
160 {
161         switch (offset)
162         {
163         case 0xF14001:
164                 break;
165         case 0xF14801:
166                 eeprom_set_di(data & 0x01);
167                 break;
168         case 0xF15001:
169                 eeprom_set_cs(1);
170                 break;
171 //      default: WriteLog("eeprom: unmapped 0x%.8x\n",offset); break;
172         }
173 }
174
175
176 void EepromWriteWord(uint32_t offset, uint16_t data)
177 {
178         EepromWriteByte(offset + 0, (data >> 8) & 0xFF);
179         EepromWriteByte(offset + 1, data & 0xFF);
180 }
181
182
183 /*
184 ;
185 ;   Commands specific to the National Semiconductor NM93C14
186 ;
187 ;
188 ;  9-bit commands..
189 ;                        876543210
190 eEWDS   equ     %100000000              ;Erase/Write disable (default)
191 eWRAL   equ     %100010000              ;Writes all registers
192 eERAL   equ     %100100000              ;Erase all registers
193 eEWEN   equ     %100110000              ;Erase/write Enable
194 eWRITE  equ     %101000000              ;Write selected register
195 eREAD   equ     %110000000              ;read from EEPROM
196 eERASE  equ     %111000000              ;Erase selected register
197 */
198
199
200 static void eeprom_set_di(uint32_t data)
201 {
202 //      WriteLog("eeprom: di=%i\n",data);
203 //      WriteLog("eeprom: state %i\n",jerry_ee_state);
204         switch (jerry_ee_state)
205         {
206         case EE_STATE_START:
207                 jerry_ee_state = EE_STATE_OP_A;
208                 break;
209         case EE_STATE_OP_A:
210                 jerry_ee_op = (data << 1);
211                 jerry_ee_state = EE_STATE_OP_B;
212                 break;
213         case EE_STATE_OP_B:
214                 jerry_ee_op |= data;
215                 jerry_ee_direct_jump = 0;
216 //              WriteLog("eeprom: opcode %i\n",jerry_ee_op);
217
218                 switch (jerry_ee_op)
219                 {
220                 // Opcode 00: eEWEN, eERAL, eWRAL, eEWNDS
221                 case 0: jerry_ee_state = EE_STATE_0; break;
222                 // Opcode 01: eWRITE (Write selected register)
223                 case 1: jerry_ee_state = EE_STATE_1; break;
224                 // Opcode 10: eREAD (Read from EEPROM)
225                 case 2: jerry_ee_state = EE_STATE_2; break;
226                 // Opcode 11: eERASE (Erase selected register)
227                 case 3: jerry_ee_state = EE_STATE_3; break;
228                 }
229
230                 eeprom_set_di(data);
231                 break;
232         case EE_STATE_0:
233                 jerry_ee_rstate = EE_STATE_0_0;
234                 jerry_ee_state = EE_READ_ADDRESS;
235                 jerry_ee_direct_jump = 1;
236                 jerry_ee_address_cnt = 6;
237                 jerry_ee_address_data = 0;
238                 break;
239         case EE_STATE_0_0:
240                 switch ((jerry_ee_address_data >> 4) & 0x03)
241                 {
242                 // Opcode 00 00: eEWDS (Erase/Write disable)
243                 case 0: jerry_ee_state=EE_STATE_0_0_0; break;
244                 // Opcode 00 01: eWRAL (Write all registers)
245                 case 1: jerry_ee_state=EE_STATE_0_0_1; break;
246                 // Opcode 00 10: eERAL (Erase all registers)
247                 case 2: jerry_ee_state=EE_STATE_0_0_2; break;
248                 // Opcode 00 11: eEWEN (Erase/Write enable)
249                 case 3: jerry_ee_state=EE_STATE_0_0_3; break;
250                 }
251
252                 eeprom_set_di(data);
253                 break;
254         case EE_STATE_0_0_0:
255                 // writes disable
256                 // WriteLog("eeprom: read only\n");
257                 jerry_writes_enabled = 0;
258                 jerry_ee_state = EE_STATE_START;
259                 break;
260         case EE_STATE_0_0_1:
261                 // writes all
262                 jerry_ee_rstate = EE_STATE_0_0_1_0;
263                 jerry_ee_state = EE_READ_DATA;
264                 jerry_ee_data_cnt = 16;
265                 jerry_ee_data = 0;
266                 jerry_ee_direct_jump = 1;
267                 break;
268         case EE_STATE_0_0_1_0:
269                 // WriteLog("eeprom: filling eeprom with 0x%.4x\n",data);
270                 if (jerry_writes_enabled)
271                 {
272                         for(int i=0; i<64; i++)
273                                 eeprom_ram[i] = jerry_ee_data;
274
275                         EEPROMSave();                                           // Save it NOW!
276                 }
277
278                 //else
279                 //      WriteLog("eeprom: not writing because read only\n");
280                 jerry_ee_state = EE_STATE_BUSY;
281                 break;
282         case EE_STATE_0_0_2:
283                 // erase all
284                 //WriteLog("eeprom: erasing eeprom\n");
285                 if (jerry_writes_enabled)
286                         for(int i=0; i<64; i++)
287                                 eeprom_ram[i] = 0xFFFF;
288
289                 jerry_ee_state = EE_STATE_BUSY;
290                 break;
291         case EE_STATE_0_0_3:
292                 // writes enable
293                 //WriteLog("eeprom: read/write\n");
294                 jerry_writes_enabled = 1;
295                 jerry_ee_state = EE_STATE_START;
296                 break;
297         case EE_STATE_1:
298                 jerry_ee_rstate = EE_STATE_1_0;
299                 jerry_ee_state = EE_READ_ADDRESS;
300                 jerry_ee_address_cnt = 6;
301                 jerry_ee_address_data = 0;
302                 jerry_ee_direct_jump = 1;
303                 break;
304         case EE_STATE_1_0:
305                 jerry_ee_rstate = EE_STATE_1_1;
306                 jerry_ee_state = EE_READ_DATA;
307                 jerry_ee_data_cnt = 16;
308                 jerry_ee_data = 0;
309                 jerry_ee_direct_jump = 1;
310                 break;
311         case EE_STATE_1_1:
312                 //WriteLog("eeprom: writing 0x%.4x at 0x%.2x\n",jerry_ee_data,jerry_ee_address_data);
313                 if (jerry_writes_enabled)
314                 {
315                         eeprom_ram[jerry_ee_address_data] = jerry_ee_data;
316                         EEPROMSave();                                           // Save it NOW!
317                 }
318
319                 jerry_ee_state = EE_STATE_BUSY;
320                 break;
321         case EE_STATE_2:
322                 jerry_ee_rstate = EE_STATE_2_0;
323                 jerry_ee_state = EE_READ_ADDRESS;
324                 jerry_ee_address_cnt = 6;
325                 jerry_ee_address_data = 0;
326                 jerry_ee_data_cnt = 16;
327                 jerry_ee_data = 0;
328                 break;
329         case EE_STATE_3:
330                 jerry_ee_rstate = EE_STATE_3_0;
331                 jerry_ee_state = EE_READ_ADDRESS;
332                 jerry_ee_address_cnt = 6;
333                 jerry_ee_address_data = 0;
334                 jerry_ee_direct_jump = 1;
335                 break;
336         case EE_STATE_3_0:
337                 //WriteLog("eeprom: erasing 0x%.2x\n",jerry_ee_address_data);
338                 if (jerry_writes_enabled)
339                         eeprom_ram[jerry_ee_address_data] = 0xFFFF;
340
341                 jerry_ee_state = EE_STATE_BUSY;
342                 break;
343         case EE_READ_DATA:
344                 //WriteLog("eeprom:\t\t\t%i bit %i\n",data,jerry_ee_data_cnt-1);
345                 jerry_ee_data <<= 1;
346                 jerry_ee_data |= data;
347                 jerry_ee_data_cnt--;
348
349                 if (!jerry_ee_data_cnt)
350                 {
351                         jerry_ee_state = jerry_ee_rstate;
352
353                         if (jerry_ee_direct_jump)
354                                 eeprom_set_di(data);
355                 }
356
357                 break;
358         case EE_READ_ADDRESS:
359                 jerry_ee_address_data <<= 1;
360                 jerry_ee_address_data |= data;
361                 jerry_ee_address_cnt--;
362 //              WriteLog("eeprom:\t%i bits remaining\n",jerry_ee_address_cnt);
363
364                 if (!jerry_ee_address_cnt)
365                 {
366                         jerry_ee_state = jerry_ee_rstate;
367                         //WriteLog("eeprom:\t\tread address 0x%.2x\n",jerry_ee_address_data);
368
369                         if (jerry_ee_direct_jump)
370                                 eeprom_set_di(data);
371                 }
372
373                 break;
374         default:
375                 jerry_ee_state = EE_STATE_OP_A;
376         }
377 }
378
379
380 static void eeprom_set_cs(uint32_t /*state*/)
381 {
382 //      WriteLog("eeprom: cs=%i\n",state);
383         jerry_ee_state = EE_STATE_START;
384         jerry_ee_op = 0;
385         jerry_ee_rstate = 0;
386         jerry_ee_address_data = 0;
387         jerry_ee_address_cnt = 6;
388         jerry_ee_data = 0;
389         jerry_ee_data_cnt = 16;
390         jerry_writes_enabled = 1;
391 }
392
393
394 static uint32_t eeprom_get_do(void)
395 {
396         uint16_t data = 1;
397
398         switch (jerry_ee_state)
399         {
400         case EE_STATE_START:
401                 data = 1;
402                 break;
403         case EE_STATE_BUSY:
404                 jerry_ee_state = EE_STATE_START;
405                 data = 0;
406                 break;
407         case EE_STATE_2_0:
408                 jerry_ee_data_cnt--;
409 #if 0
410                 data = (eeprom_ram[jerry_ee_address_data] & (1 << jerry_ee_data_cnt)) >> jerry_ee_data_cnt;
411 #else
412                 data = (eeprom_ram[jerry_ee_address_data] >> jerry_ee_data_cnt) & 0x01;
413 #endif
414
415                 if (!jerry_ee_data_cnt)
416                 {
417                         //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());
418                         jerry_ee_state = EE_STATE_START;
419                 }
420                 break;
421         }
422
423 //      WriteLog("eeprom: do=%i\n",data);
424         return data;
425 }
426