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