Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/genplus-gx32/core/cart_hw/eeprom_93c.c
2 views
1
/****************************************************************************
2
* Genesis Plus
3
* Microwire Serial EEPROM (93C46 only) support
4
*
5
* Copyright (C) 2011 Eke-Eke (Genesis Plus GX)
6
*
7
* Redistribution and use of this code or any derivative works are permitted
8
* provided that the following conditions are met:
9
*
10
* - Redistributions may not be sold, nor may they be used in a commercial
11
* product or activity.
12
*
13
* - Redistributions that are modified from the original source must include the
14
* complete source code, including the source code for all components used by a
15
* binary built from the modified sources. However, as a special exception, the
16
* source code distributed need not include anything that is normally distributed
17
* (in either source or binary form) with the major components (compiler, kernel,
18
* and so on) of the operating system on which the executable runs, unless that
19
* component itself accompanies the executable.
20
*
21
* - Redistributions must reproduce the above copyright notice, this list of
22
* conditions and the following disclaimer in the documentation and/or other
23
* materials provided with the distribution.
24
*
25
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35
* POSSIBILITY OF SUCH DAMAGE.
36
*
37
****************************************************************************************/
38
39
#include "shared.h"
40
#include "eeprom_93c.h"
41
42
/* fixed board implementation */
43
#define BIT_DATA (0)
44
#define BIT_CLK (1)
45
#define BIT_CS (2)
46
47
48
T_EEPROM_93C eeprom_93c;
49
50
void eeprom_93c_init()
51
{
52
/* default eeprom state */
53
memset(&eeprom_93c, 0, sizeof(T_EEPROM_93C));
54
eeprom_93c.data = 1;
55
eeprom_93c.state = WAIT_START93;
56
sram.custom = 3;
57
}
58
59
void eeprom_93c_write(unsigned char data)
60
{
61
/* Make sure CS is HIGH */
62
if (data & (1 << BIT_CS))
63
{
64
/* Data latched on CLK postive edge */
65
if ((data & (1 << BIT_CLK)) && !eeprom_93c.clk)
66
{
67
/* Current EEPROM state */
68
switch (eeprom_93c.state)
69
{
70
case WAIT_START93:
71
{
72
/* Wait for START bit */
73
if (data & (1 << BIT_DATA))
74
{
75
eeprom_93c.opcode = 0;
76
eeprom_93c.cycles = 0;
77
eeprom_93c.state = GET_OPCODE93;
78
}
79
break;
80
}
81
82
case GET_OPCODE93:
83
{
84
/* 8-bit buffer (opcode + address) */
85
eeprom_93c.opcode |= ((data >> BIT_DATA) & 1) << (7 - eeprom_93c.cycles);
86
eeprom_93c.cycles++;
87
88
if (eeprom_93c.cycles == 8)
89
{
90
/* Decode instruction */
91
switch ((eeprom_93c.opcode >> 6) & 3)
92
{
93
case 1:
94
{
95
/* WRITE */
96
eeprom_93c.buffer = 0;
97
eeprom_93c.cycles = 0;
98
eeprom_93c.state = WRITE_WORD93;
99
break;
100
}
101
102
case 2:
103
{
104
/* READ */
105
eeprom_93c.buffer = *(uint16 *)(sram.sram + ((eeprom_93c.opcode & 0x3F) << 1));
106
eeprom_93c.cycles = 0;
107
eeprom_93c.state = READ_WORD93;
108
109
/* Force DATA OUT */
110
eeprom_93c.data = 0;
111
break;
112
}
113
114
case 3:
115
{
116
/* ERASE */
117
if (eeprom_93c.we)
118
{
119
*(uint16 *)(sram.sram + ((eeprom_93c.opcode & 0x3F) << 1)) = 0xFFFF;
120
}
121
122
/* wait for next command */
123
eeprom_93c.state = WAIT_STANDBY93;
124
break;
125
}
126
127
default:
128
{
129
/* special command */
130
switch ((eeprom_93c.opcode >> 4) & 3)
131
{
132
case 1:
133
{
134
/* WRITE ALL */
135
eeprom_93c.buffer = 0;
136
eeprom_93c.cycles = 0;
137
eeprom_93c.state = WRITE_WORD93;
138
break;
139
}
140
141
case 2:
142
{
143
/* ERASE ALL */
144
if (eeprom_93c.we)
145
{
146
memset(sram.sram, 0xFF, 128);
147
}
148
149
/* wait for next command */
150
eeprom_93c.state = WAIT_STANDBY93;
151
break;
152
}
153
154
default:
155
{
156
/* WRITE ENABLE/DISABLE */
157
eeprom_93c.we = (eeprom_93c.opcode >> 4) & 1;
158
159
/* wait for next command */
160
eeprom_93c.state = WAIT_STANDBY93;
161
break;
162
}
163
}
164
break;
165
}
166
}
167
}
168
break;
169
}
170
171
case WRITE_WORD93:
172
{
173
/* 16-bit data buffer */
174
eeprom_93c.buffer |= ((data >> BIT_DATA) & 1) << (15 - eeprom_93c.cycles);
175
eeprom_93c.cycles++;
176
177
if (eeprom_93c.cycles == 16)
178
{
179
/* check EEPROM write protection */
180
if (eeprom_93c.we)
181
{
182
if (eeprom_93c.opcode & 0x40)
183
{
184
/* write one word */
185
*(uint16 *)(sram.sram + ((eeprom_93c.opcode & 0x3F) << 1)) = eeprom_93c.buffer;
186
}
187
else
188
{
189
/* write 64 words */
190
int i;
191
for (i=0; i<64; i++)
192
{
193
*(uint16 *)(sram.sram + (i << 1)) = eeprom_93c.buffer;
194
195
}
196
}
197
}
198
199
/* wait for next command */
200
eeprom_93c.state = WAIT_STANDBY93;
201
}
202
break;
203
}
204
205
case READ_WORD93:
206
{
207
/* set DATA OUT */
208
eeprom_93c.data = ((eeprom_93c.buffer >> (15 - eeprom_93c.cycles)) & 1);
209
eeprom_93c.cycles++;
210
211
if (eeprom_93c.cycles == 16)
212
{
213
/* read next word (93C46B) */
214
eeprom_93c.opcode++;
215
eeprom_93c.cycles = 0;
216
eeprom_93c.buffer = *(uint16 *)(sram.sram + ((eeprom_93c.opcode & 0x3F) << 1));
217
}
218
break;
219
}
220
221
default:
222
{
223
/* wait for STANDBY mode */
224
break;
225
}
226
}
227
}
228
}
229
else
230
{
231
/* CS HIGH->LOW transition */
232
if (eeprom_93c.cs)
233
{
234
/* standby mode */
235
eeprom_93c.data = 1;
236
eeprom_93c.state = WAIT_START93;
237
}
238
}
239
240
/* Update input lines */
241
eeprom_93c.cs = (data >> BIT_CS) & 1;
242
eeprom_93c.clk = (data >> BIT_CLK) & 1;
243
}
244
245
unsigned char eeprom_93c_read(void)
246
{
247
return ((eeprom_93c.cs << BIT_CS) | (eeprom_93c.data << BIT_DATA) | (1 << BIT_CLK));
248
}
249
250
251