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