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