]> Shamusworld >> Repos - virtualjaguar/blob - src/eeprom.cpp
We can now compile, but still doesn't work at this point... Lots of cleanup
[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 L. Hammons
7 //
8
9 #include "eeprom.h"
10
11 #include <stdlib.h>
12 #include <string.h>                                                             // For memset
13 #include "jaguar.h"
14 #include "log.h"
15 #include "settings.h"
16
17 #define eeprom_LOG
18
19 static uint16 eeprom_ram[64];
20
21 //
22 // Private function prototypes
23 //
24
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);
29
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 };
34
35 // Local global variables
36
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;
48
49 void EepromInit(void)
50 {
51         sprintf(eeprom_filename, "%s%08X.eep", vjs.EEPROMPath, (unsigned int)jaguarMainROMCRC32);
52         FILE * fp = fopen(eeprom_filename, "rb");
53
54         if (fp)
55         {
56                 fread(eeprom_ram, 1, 128, fp);
57                 fclose(fp);
58                 WriteLog("EEPROM: Loaded from %s\n", eeprom_filename);
59                 foundEEPROM = true;
60         }
61         else
62                 WriteLog("EEPROM: Could not open file \"%s\"!\n", eeprom_filename);
63 }
64
65 void EepromReset(void)
66 {
67         if (!foundEEPROM)
68                 memset(eeprom_ram, 0xFF, 64 * sizeof(uint16));
69 }
70
71 void EepromDone(void)
72 {
73         WriteLog("EEPROM: Done.\n");
74 }
75
76 static void EEPROMSave(void)
77 {
78         FILE * fp = fopen(eeprom_filename, "wb");
79
80         if (fp == NULL)
81         {
82                 WriteLog("EEPROM: Could not create file \"%s!\"\n", eeprom_filename);
83                 return;
84         }
85
86         fwrite(eeprom_ram, 1, 128, fp);
87         fclose(fp);
88 }
89
90 uint8 EepromReadByte(uint32 offset)
91 {
92         switch (offset)
93         {
94         case 0xF14001:
95                 return eeprom_get_do();
96         case 0xF14801:
97                 break;
98         case 0xF15001:
99                 eeprom_set_cs(1);
100                 break;
101 //      default: WriteLog("EEPROM: unmapped 0x%.8x\n", offset); break;
102         }
103
104         return 0x00;
105 }
106
107 uint16 EepromReadWord(uint32 offset)
108 {
109         return ((uint16)EepromReadByte(offset + 0) << 8) | EepromReadByte(offset + 1);
110 }
111
112 void EepromWriteByte(uint32 offset, uint8 data)
113 {
114         switch (offset)
115         {
116         case 0xF14001:
117                 break;
118         case 0xF14801:
119                 eeprom_set_di(data & 0x01);
120                 break;
121         case 0xF15001:
122                 eeprom_set_cs(1);
123                 break;
124 //      default: WriteLog("eeprom: unmapped 0x%.8x\n",offset); break;
125         }
126 }
127
128 void EepromWriteWord(uint32 offset, uint16 data)
129 {
130         EepromWriteByte(offset + 0, (data >> 8) & 0xFF);
131         EepromWriteByte(offset + 1, data & 0xFF);
132 }
133
134 static void eeprom_set_di(uint32 data)
135 {
136 //      WriteLog("eeprom: di=%i\n",data);
137 //      WriteLog("eeprom: state %i\n",jerry_ee_state);
138         switch (jerry_ee_state)
139         {
140         case EE_STATE_START:
141                 jerry_ee_state = EE_STATE_OP_A;
142                 break;
143         case EE_STATE_OP_A:
144                 jerry_ee_op = (data << 1);
145                 jerry_ee_state = EE_STATE_OP_B;
146                 break;
147         case EE_STATE_OP_B:
148                 jerry_ee_op |= data;
149                 jerry_ee_direct_jump = 0;
150 //              WriteLog("eeprom: opcode %i\n",jerry_ee_op);
151                 switch (jerry_ee_op)
152                 {
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;
157                 }
158                 eeprom_set_di(data);
159                 break;
160         case EE_STATE_0:
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;
166                 break;
167         case EE_STATE_0_0:
168                 switch ((jerry_ee_address_data >> 4) & 0x03)
169                 {
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;
174                 }
175                 eeprom_set_di(data);
176                 break;
177         case EE_STATE_0_0_0:
178                 // writes disable
179                 // WriteLog("eeprom: read only\n");
180                 jerry_writes_enabled = 0;
181                 jerry_ee_state = EE_STATE_START;
182                 break;
183         case EE_STATE_0_0_1:
184                 // writes all
185                 jerry_ee_rstate = EE_STATE_0_0_1_0;
186                 jerry_ee_state = EE_READ_DATA;
187                 jerry_ee_data_cnt = 16;
188                 jerry_ee_data = 0;
189                 jerry_ee_direct_jump = 1;
190                 break;
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!
197                 //else
198                 //      WriteLog("eeprom: not writing because read only\n");
199                 jerry_ee_state = EE_STATE_BUSY;
200                 break;
201         case EE_STATE_0_0_2:
202                 // erase all
203                 //WriteLog("eeprom: erasing eeprom\n");
204                 if (jerry_writes_enabled)
205                         for(int i=0; i<64; i++)
206                                 eeprom_ram[i] = 0xFFFF;
207
208                 jerry_ee_state = EE_STATE_BUSY;
209                 break;
210         case EE_STATE_0_0_3:
211                 // writes enable
212                 //WriteLog("eeprom: read/write\n");
213                 jerry_writes_enabled = 1;
214                 jerry_ee_state = EE_STATE_START;
215                 break;
216         case EE_STATE_1:
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;
222                 break;
223         case EE_STATE_1_0:
224                 jerry_ee_rstate = EE_STATE_1_1;
225                 jerry_ee_state = EE_READ_DATA;
226                 jerry_ee_data_cnt = 16;
227                 jerry_ee_data = 0;
228                 jerry_ee_direct_jump = 1;
229                 break;
230         case EE_STATE_1_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;
236                 break;
237         case EE_STATE_2:
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;
243                 jerry_ee_data = 0;
244                 break;
245         case EE_STATE_3:
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;
251                 break;
252         case EE_STATE_3_0:
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;
257                 break;
258         case EE_READ_DATA:
259                 //WriteLog("eeprom:\t\t\t%i bit %i\n",data,jerry_ee_data_cnt-1);
260                 jerry_ee_data <<= 1;
261                 jerry_ee_data |= data;
262                 jerry_ee_data_cnt--;
263                 if (!jerry_ee_data_cnt)
264                 {
265                         jerry_ee_state = jerry_ee_rstate;
266                         if (jerry_ee_direct_jump)
267                                 eeprom_set_di(data);
268                 }
269                 break;
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)
276                 {
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)
280                                 eeprom_set_di(data);
281                 }
282                 break;
283         default:
284                 jerry_ee_state = EE_STATE_OP_A;
285         }
286 }
287
288 static void eeprom_set_cs(uint32 state)
289 {
290 //      WriteLog("eeprom: cs=%i\n",state);
291         jerry_ee_state = EE_STATE_START;
292         jerry_ee_op = 0;
293         jerry_ee_rstate = 0;
294         jerry_ee_address_data = 0;
295         jerry_ee_address_cnt = 6;
296         jerry_ee_data = 0;
297         jerry_ee_data_cnt = 16;
298         jerry_writes_enabled = 1;
299 }
300
301 static uint32 eeprom_get_do(void)
302 {
303         uint16 data = 1;
304
305         switch (jerry_ee_state)
306         {
307         case EE_STATE_START:
308                 data = 1;
309                 break;
310         case EE_STATE_BUSY:
311                 jerry_ee_state = EE_STATE_START;
312                 data = 0;
313                 break;
314         case EE_STATE_2_0:
315                 jerry_ee_data_cnt--;
316                 data = (eeprom_ram[jerry_ee_address_data] & (1 << jerry_ee_data_cnt)) >> jerry_ee_data_cnt;
317                 if (!jerry_ee_data_cnt)
318                 {
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;
321                 }
322                 break;
323         }
324
325 //      WriteLog("eeprom: do=%i\n",data);
326         return data;
327 }