]> Shamusworld >> Repos - virtualjaguar/blob - src/eeprom.cpp
Changed functioning to save EEPROM contents on write instead of waiting until the...
[virtualjaguar] / src / eeprom.cpp
1 //
2 // EEPROM handler
3 //
4 // by Cal2
5 // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS)
6 // Cleanups by James L. Hammons
7 //
8
9 #include "eeprom.h"
10
11 #define eeprom_LOG
12
13 static uint16 eeprom_ram[64];
14
15 //
16 // Private function prototypes
17 //
18
19 void EEPROMSave(void);
20 void eeprom_set_di(uint32 state); 
21 void eeprom_set_cs(uint32 state);
22 uint32 eeprom_get_do(void);
23
24 #define EE_STATE_START                  1
25 #define EE_STATE_OP_A                   2
26 #define EE_STATE_OP_B                   3
27 #define EE_STATE_0                              4
28 #define EE_STATE_1                              5
29 #define EE_STATE_2                              6
30 #define EE_STATE_3                              7
31 #define EE_STATE_0_0                    8
32 #define EE_READ_ADDRESS                 9
33 #define EE_STATE_0_0_0                  10
34 #define EE_STATE_0_0_1                  11
35 #define EE_STATE_0_0_2                  12
36 #define EE_STATE_0_0_3                  13
37 #define EE_STATE_0_0_1_0                14
38 #define EE_READ_DATA                    15
39 #define EE_STATE_BUSY                   16
40 #define EE_STATE_1_0                    17
41 #define EE_STATE_1_1                    18
42 #define EE_STATE_2_0                    19
43 #define EE_STATE_3_0                    20
44
45 // External global variables
46
47 extern char jaguar_boot_dir[1024];
48
49 // Local global variables
50
51 uint16 jerry_ee_state = EE_STATE_START;
52 uint16 jerry_ee_op = 0;
53 uint16 jerry_ee_rstate = 0;
54 uint16 jerry_ee_address_data = 0;
55 uint16 jerry_ee_address_cnt = 6;
56 uint16 jerry_ee_data = 0;
57 uint16 jerry_ee_data_cnt = 16;
58 uint16 jerry_writes_enabled = 0;
59 uint16 jerry_ee_direct_jump = 0;
60 FILE * jerry_ee_fp;
61 static char eeprom_filename[1024];
62 static bool foundEEPROM = false;
63
64 void eeprom_init(void)
65 {
66         sprintf(eeprom_filename, "%s/%s%08X.eep", jaguar_boot_dir, jaguar_eeproms_path, (unsigned int)jaguar_mainRom_crc32);
67         jerry_ee_fp = fopen(eeprom_filename, "rb");
68         if (jerry_ee_fp)
69         {
70                 fread(eeprom_ram, 1, 128, jerry_ee_fp);
71                 fclose(jerry_ee_fp);
72                 WriteLog("EEPROM: Loaded from %s\n", eeprom_filename);
73                 foundEEPROM = true;
74         }
75         else
76         {
77                 WriteLog("EEPROM: Creating %s\n", eeprom_filename);
78                 jerry_ee_fp = fopen(eeprom_filename, "wb");
79                 if (jerry_ee_fp == NULL)
80                         WriteLog("EEPROM: Could not open/create %s\n", eeprom_filename);
81         }
82 }
83
84 void eeprom_reset(void)
85 {
86         if (!foundEEPROM)
87                 memset(eeprom_ram, 0xFF, 64 * sizeof(uint16));
88 }
89
90 void eeprom_done(void)
91 {
92 //Actually, is this necessary now that we write the file immediately?
93         EEPROMSave();
94 }
95
96 void EEPROMSave(void)
97 {
98         jerry_ee_fp = fopen(eeprom_filename, "wb");
99         fwrite(eeprom_ram, 1, 128, jerry_ee_fp);
100         fclose(jerry_ee_fp);
101 }
102
103 uint8 eeprom_byte_read(uint32 offset)
104 {
105         switch (offset)
106         {
107         case 0xF14001:
108                 return eeprom_get_do();
109         case 0xF14801:
110                 break;
111         case 0xF15001:
112                 eeprom_set_cs(1);
113                 break;
114 //      default: WriteLog("eeprom: unmapped 0x%.8x\n",offset); break;
115         }
116
117         return 0x00;
118 }
119
120 uint16 eeprom_word_read(uint32 offset)
121 {
122         return ((uint16)eeprom_byte_read(offset+0) << 8) | eeprom_byte_read(offset+1);
123 }
124
125 void eeprom_byte_write(uint32 offset, uint8 data)
126 {
127         switch (offset)
128         {
129         case 0xF14001:
130                 break;
131         case 0xF14801:
132                 eeprom_set_di(data & 0x01);
133                 break;
134         case 0xF15001:
135                 eeprom_set_cs(1);
136                 break;
137 //      default: WriteLog("eeprom: unmapped 0x%.8x\n",offset); break;
138         }
139 }
140
141 void eeprom_word_write(uint32 offset, uint16 data)
142 {
143         eeprom_byte_write(offset+0, (data >> 8) & 0xFF);
144         eeprom_byte_write(offset+1, data & 0xFF);
145 }
146
147 void eeprom_set_di(uint32 data)
148 {
149 //      WriteLog("eeprom: di=%i\n",data);
150 //      WriteLog("eeprom: state %i\n",jerry_ee_state);
151         switch (jerry_ee_state)
152         {
153         case EE_STATE_START:
154                 jerry_ee_state = EE_STATE_OP_A;
155                 break;
156         case EE_STATE_OP_A:
157                 jerry_ee_op = (data << 1);
158                 jerry_ee_state = EE_STATE_OP_B;
159                 break;
160         case EE_STATE_OP_B:
161                 jerry_ee_op |= data;
162                 jerry_ee_direct_jump = 0;
163 //              WriteLog("eeprom: opcode %i\n",jerry_ee_op);
164                 switch (jerry_ee_op)
165                 {
166                 case 0: jerry_ee_state = EE_STATE_0; break;
167                 case 1: jerry_ee_state = EE_STATE_1; break;
168                 case 2: jerry_ee_state = EE_STATE_2; break;
169                 case 3: jerry_ee_state = EE_STATE_3; break;
170                 }
171                 eeprom_set_di(data);
172                 break;
173         case EE_STATE_0:
174                 jerry_ee_rstate = EE_STATE_0_0;
175                 jerry_ee_state = EE_READ_ADDRESS;
176                 jerry_ee_direct_jump = 1;
177                 jerry_ee_address_cnt = 6;
178                 jerry_ee_address_data = 0;
179                 break;
180         case EE_STATE_0_0:
181                 switch ((jerry_ee_address_data >> 4) & 0x03)
182                 {
183                 case 0: jerry_ee_state=EE_STATE_0_0_0; break;
184                 case 1: jerry_ee_state=EE_STATE_0_0_1; break;
185                 case 2: jerry_ee_state=EE_STATE_0_0_2; break;
186                 case 3: jerry_ee_state=EE_STATE_0_0_3; break;
187                 }
188                 eeprom_set_di(data);
189                 break;
190         case EE_STATE_0_0_0:
191                 // writes disable
192                 // WriteLog("eeprom: read only\n");
193                 jerry_writes_enabled = 0;
194                 jerry_ee_state = EE_STATE_START;
195                 break;
196         case EE_STATE_0_0_1:
197                 // writes all
198                 jerry_ee_rstate = EE_STATE_0_0_1_0;
199                 jerry_ee_state = EE_READ_DATA;
200                 jerry_ee_data_cnt = 16;
201                 jerry_ee_data = 0;
202                 jerry_ee_direct_jump = 1;
203                 break;
204         case EE_STATE_0_0_1_0:
205                 // WriteLog("eeprom: filling eeprom with 0x%.4x\n",data);
206                 if (jerry_writes_enabled)
207                         for(int i=0; i<64; i++)
208                                 eeprom_ram[i] = jerry_ee_data;
209                 EEPROMSave();   // Save it NOW!
210                 //else 
211                 //      WriteLog("eeprom: not writing because read only\n");
212                 jerry_ee_state = EE_STATE_BUSY;
213                 break;
214         case EE_STATE_0_0_2:
215                 // erase all
216                 //WriteLog("eeprom: erasing eeprom\n");
217                 if (jerry_writes_enabled)
218                         for(int i=0; i<64; i++)
219                                 eeprom_ram[i] = 0xFFFF;
220
221                 jerry_ee_state=EE_STATE_BUSY;
222                 break;
223         case EE_STATE_0_0_3:
224                 // writes enable
225                 //WriteLog("eeprom: read/write\n");
226                 jerry_writes_enabled = 1;
227                 jerry_ee_state = EE_STATE_START;
228                 break;
229         case EE_STATE_1:
230                 jerry_ee_rstate = EE_STATE_1_0;
231                 jerry_ee_state = EE_READ_ADDRESS;
232                 jerry_ee_address_cnt = 6;
233                 jerry_ee_address_data = 0;
234                 jerry_ee_direct_jump = 1;
235                 break;
236         case EE_STATE_1_0:
237                 jerry_ee_rstate = EE_STATE_1_1;
238                 jerry_ee_state = EE_READ_DATA;
239                 jerry_ee_data_cnt = 16;
240                 jerry_ee_data = 0;
241                 jerry_ee_direct_jump = 1;
242                 break;
243         case EE_STATE_1_1:
244                 //WriteLog("eeprom: writing 0x%.4x at 0x%.2x\n",jerry_ee_data,jerry_ee_address_data);
245                 if (jerry_writes_enabled)
246                         eeprom_ram[jerry_ee_address_data] = jerry_ee_data;
247                 EEPROMSave();   // Save it NOW!
248                 jerry_ee_state = EE_STATE_BUSY;
249                 break;
250         case EE_STATE_2:
251                 jerry_ee_rstate = EE_STATE_2_0;
252                 jerry_ee_state = EE_READ_ADDRESS;
253                 jerry_ee_address_cnt = 6;
254                 jerry_ee_address_data = 0;
255                 jerry_ee_data_cnt = 16;
256                 jerry_ee_data = 0;
257                 break;
258         case EE_STATE_3:
259                 jerry_ee_rstate = EE_STATE_3_0;
260                 jerry_ee_state = EE_READ_ADDRESS;
261                 jerry_ee_address_cnt = 6;
262                 jerry_ee_address_data = 0;
263                 jerry_ee_direct_jump = 1;
264                 break;
265         case EE_STATE_3_0:
266                 //WriteLog("eeprom: erasing 0x%.2x\n",jerry_ee_address_data);
267                 if (jerry_writes_enabled)
268                         eeprom_ram[jerry_ee_address_data] = 0xFFFF;
269                 jerry_ee_state = EE_STATE_BUSY;
270                 break;
271         case EE_READ_DATA: 
272                 //WriteLog("eeprom:\t\t\t%i bit %i\n",data,jerry_ee_data_cnt-1);
273                 jerry_ee_data <<= 1;
274                 jerry_ee_data |= data;
275                 jerry_ee_data_cnt--;
276                 if (!jerry_ee_data_cnt)
277                 {
278                         jerry_ee_state = jerry_ee_rstate;
279                         if (jerry_ee_direct_jump)
280                                 eeprom_set_di(data);
281                 }
282                 break;
283         case EE_READ_ADDRESS: 
284                 jerry_ee_address_data <<= 1;
285                 jerry_ee_address_data |= data;
286                 jerry_ee_address_cnt--;
287 //              WriteLog("eeprom:\t%i bits remaining\n",jerry_ee_address_cnt);
288                 if (!jerry_ee_address_cnt)
289                 {
290                         jerry_ee_state = jerry_ee_rstate;
291                         //WriteLog("eeprom:\t\tread address 0x%.2x\n",jerry_ee_address_data);
292                         if (jerry_ee_direct_jump)
293                                 eeprom_set_di(data);
294                 }
295                 break;
296         default:
297                 jerry_ee_state = EE_STATE_OP_A; 
298         }
299 }
300
301 void eeprom_set_cs(uint32 state)
302 {
303 //      WriteLog("eeprom: cs=%i\n",state);
304         jerry_ee_state = EE_STATE_START;
305         jerry_ee_op = 0;
306         jerry_ee_rstate = 0;
307         jerry_ee_address_data = 0;
308         jerry_ee_address_cnt = 6;
309         jerry_ee_data = 0;
310         jerry_ee_data_cnt = 16;
311         jerry_writes_enabled = 1;
312 }
313
314 uint32 eeprom_get_do(void)
315 {
316         uint16 data = 1;
317
318         switch (jerry_ee_state)
319         {
320         case EE_STATE_START:
321                 data = 1;
322                 break;
323         case EE_STATE_BUSY:
324                 jerry_ee_state = EE_STATE_START;
325                 data = 0;
326                 break;
327         case EE_STATE_2_0:
328                 jerry_ee_data_cnt--;
329                 data = (eeprom_ram[jerry_ee_address_data] & (1 << jerry_ee_data_cnt)) >> jerry_ee_data_cnt;
330                 if (!jerry_ee_data_cnt)
331                 {
332                         //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());
333                         jerry_ee_state = EE_STATE_START;
334                 }
335                 break;
336         }
337
338 //      WriteLog("eeprom: do=%i\n",data);
339         return data;
340 }