Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
RishiRecon
GitHub Repository: RishiRecon/exploits
Path: blob/main/misc/emulator/xnes/snem/io.c
28515 views
1
#include "snes.h"
2
int slines;
3
int hblnk=0;
4
int reg4016;
5
unsigned char *ram;
6
int fastrom;
7
int irqon;
8
int padready=1;
9
unsigned char countena;
10
11
unsigned char mula,mulb,divb;
12
unsigned short mulr,divr,divc;
13
uint32 joy1=0x80000000,joy2;
14
15
16
unsigned char readio(unsigned short addr)
17
{
18
unsigned char temp;
19
if (addr==0x4017)
20
{
21
// printf("Old style read 2\n");
22
// return 0;
23
return 0xFF;
24
}
25
if (addr==0x4016)
26
{
27
return 0xFF;
28
}
29
// if (addr>0x42FF) return 0;
30
switch (addr)
31
{
32
case 0x4200:
33
return countena;
34
case 0x420C:
35
// return 0xFF;
36
return hdmaena;
37
case 0x4210: /*NMI Register*/
38
// printf("4210 read %i line %i\n",nmiocc,curline);
39
if (nmiocc)
40
{
41
nmiocc=0;
42
return 0x80;
43
}
44
return 0;
45
case 0x4211:
46
if (irqon)
47
{
48
irqon=0;
49
return 0x80;
50
}
51
return 0;
52
case 0x4212: /*Status Register*/
53
hblnk^=0x40;
54
// printf("4212 read at %02X:%04X line %i %02X\n",pbr,pc,curline,((vbl)?0x80:0)|padready|hblnk);
55
if (vbl) return 0x80|padready|hblnk;
56
return padready|hblnk;
57
case 0x4213: /*PIO port*/
58
return 0xFF;
59
case 0x4214: /*Division Result Low*/
60
return divr;
61
case 0x4215: /*Division Result High*/
62
return divr>>8;
63
case 0x4216: /*Multiplication Result Low*/
64
return mulr;
65
case 0x4217: /*Multiplication Result High*/
66
return mulr>>8;
67
case 0x4218: /*Joypad #1 low*/
68
// printf("4218 read %02X at %02X:%04X\n",joy1&0xFF,pbr,pc);
69
return native_joypad_state(0);
70
case 0x4219: /*Joypad #1 high*/
71
return native_joypad_state(0)>>8;
72
return temp;
73
case 0x421A: case 0x421B: /*All the other joypads*/
74
case 0x421C: case 0x421D:
75
case 0x421E: case 0x421F:
76
return 0;
77
78
// case 0x42FE: case 0x42FF: /*As read by Soccer Kid*/
79
// return 0xFF;
80
81
case 0x4300: case 0x4310: case 0x4320: case 0x4330:
82
case 0x4340: case 0x4350: case 0x4360: case 0x4370:
83
return dma.ctrl[(addr>>4)&7];
84
case 0x4301: case 0x4311: case 0x4321: case 0x4331:
85
case 0x4341: case 0x4351: case 0x4361: case 0x4371:
86
return dma.dest[(addr>>4)&7];
87
case 0x4302: case 0x4312: case 0x4322: case 0x4332:
88
case 0x4342: case 0x4352: case 0x4362: case 0x4372:
89
return dma.src[(addr>>4)&7]&0xFF;
90
case 0x4303: case 0x4313: case 0x4323: case 0x4333:
91
case 0x4343: case 0x4353: case 0x4363: case 0x4373:
92
return dma.src[(addr>>4)&7]>>8;
93
case 0x4304: case 0x4314: case 0x4324: case 0x4334:
94
case 0x4344: case 0x4354: case 0x4364: case 0x4374:
95
return dma.srcbank[(addr>>4)&7];
96
case 0x4305: case 0x4315: case 0x4325: case 0x4335:
97
case 0x4345: case 0x4355: case 0x4365: case 0x4375:
98
return dma.size[(addr>>4)&7]&0xFF;
99
case 0x4306: case 0x4316: case 0x4326: case 0x4336:
100
case 0x4346: case 0x4356: case 0x4366: case 0x4376:
101
return dma.size[(addr>>4)&7]&0xFF;
102
// default:
103
// printf("Bad I/O read %04X %02X:%04X %04X %02X\n",addr,pbr,pc,reg_Y.w,ram[0x287]);
104
}
105
return 0;
106
printf("Bad I/O read %04X\n",addr);
107
dumpregs();
108
exit(-1);
109
}
110
111
void writeio(unsigned short addr, unsigned char val)
112
{
113
int c;
114
int dmawsize[8]={1,2,2,4,4,0,0,0};
115
int dmadone=0;
116
unsigned short a,a2,len;
117
unsigned char temp,val2;
118
switch (addr)
119
{
120
case 0x4016: reg4016=val&1; return;
121
case 0x4200: /*Counter enable*/
122
nmiena=val&0x80;
123
countena=val;
124
vertint=val&0x20;
125
horint=val&0x10;
126
irqon=0;
127
return;
128
case 0x4202: /*Multiplicand A*/
129
mula=val;
130
mulr=mula*mulb;
131
return;
132
case 0x4203: /*Multiplier B*/
133
mulb=val;
134
mulr=mula*mulb;
135
return;
136
case 0x4204: /*Dividend C Low*/
137
divc&=0xFF00;
138
divc|=val;
139
if (divb)
140
{
141
divr=divc/divb;
142
mulr=divc%divb;
143
}
144
else
145
{
146
divr=0xFFFF;
147
mulr=divc;
148
}
149
return;
150
case 0x4205: /*Dividend C High*/
151
divc&=0xFF;
152
divc|=(val<<8);
153
if (divb)
154
{
155
divr=divc/divb;
156
mulr=divc%divb;
157
}
158
else
159
{
160
divr=0xFFFF;
161
mulr=divc;
162
}
163
return;
164
case 0x4206: /*Divisor B*/
165
divb=val;
166
if (divb)
167
{
168
divr=divc/divb;
169
mulr=divc%divb;
170
}
171
else
172
{
173
divr=0xFFFF;
174
mulr=divc;
175
}
176
return;
177
case 0x4209: /*Vertical IRQ Position Low*/
178
// printf("VIRQ low %02X %02X:%04X\n",val,pbr,pc);
179
vertline=(vertline&0x100)|val;
180
return;
181
case 0x420A: /*Vertical IRQ Position High*/
182
// printf("VIRQ high %02X %02X:%04X\n",val,pbr,pc);
183
vertline=(vertline&0xFF)|((val<<8)&0x100);
184
irqon=0;
185
return;
186
case 0x420B: /*DMA enable*/
187
// printf("DMA enable %02X\n",val);
188
temp=1;
189
for (c=0;c<8;c++)
190
{
191
if (val&temp)
192
{
193
len=dma.size[c];
194
a=dma.src[c];
195
a2=dma.dest[c]|0x2100;
196
//printf("DMA %i src %02X:%04X dest 21%02X size %04X ctrl %02X\n",c,dma.srcbank[c],dma.src[c],dma.dest[c],dma.size[c],dma.ctrl[c]);
197
do
198
{
199
if (dma.ctrl[c]&0x80)
200
{
201
if (mempointv[dma.srcbank[c]][a>>13])
202
mempoint[dma.srcbank[c]][a>>13][a&0x1FFF]=readppu(a2);
203
// printf("DMA 0x80\n");
204
// dumpregs();
205
// exit(-1);
206
// val=readppu(a2);
207
// writemem(dma.srcbank[c],a,val);
208
}
209
else
210
{
211
// if (c==0 && dma.dest[0]==4 && pc==0x8253) printf("%02X %04X %02X\n",dma.srcbank[c],a,a2);
212
if (mempointv[dma.srcbank[c]][a>>13])
213
val2=mempoint[dma.srcbank[c]][a>>13][a&0x1FFF];
214
else
215
val2=0;
216
// val2=readmem(dma.srcbank[c],a);
217
writeppu(a2,val2);
218
}
219
switch (dma.ctrl[c]&0xF)
220
{
221
case 0:
222
case 2:
223
if (dma.ctrl[c]&16) a--;
224
else a++;
225
break;
226
case 1:
227
if (a2==(dma.dest[c]|0x2100)) a2++;
228
else a2--;
229
if (dma.ctrl[c]&16) a--;
230
else a++;
231
break;
232
case 8:
233
case 0xA:
234
break;
235
case 9:
236
if (a2==(dma.dest[c]|0x2100)) a2++;
237
else a2--;
238
break;
239
default:
240
printf("Bad DMA mode %02X\n",dma.ctrl[c]);
241
dumpregs();
242
exit(-1);
243
}
244
len--;
245
/* dmadone++;
246
dmadone&=(dmawsize[dma.ctrl[c]&7]-1);
247
if (!dmadone && len<dmawsize[dma.ctrl[c]&7]) len=0;*/
248
}
249
while (len);
250
dma.src[c]=a;
251
dma.size[c]=0;
252
}
253
temp<<=1;
254
}
255
return;
256
257
case 0x420C: /*HDMA Enable*/
258
hdmaena=val;
259
// printf("HDMAENA %02X %02X:%04X\n",val,pbr,pc);
260
// if (val==0x7F && pbr==0xC2 && pc==0x841A) dumpregs();
261
return;
262
case 0x420D: /*ROM speed*/
263
fastrom=val&1;
264
return;
265
266
case 0x4300: case 0x4310: case 0x4320: case 0x4330:
267
case 0x4340: case 0x4350: case 0x4360: case 0x4370:
268
dma.ctrl[(addr>>4)&7]=val;
269
return;
270
case 0x4301: case 0x4311: case 0x4321: case 0x4331:
271
case 0x4341: case 0x4351: case 0x4361: case 0x4371:
272
dma.dest[(addr>>4)&7]=val;
273
return;
274
case 0x4302: case 0x4312: case 0x4322: case 0x4332:
275
case 0x4342: case 0x4352: case 0x4362: case 0x4372:
276
dma.src[(addr>>4)&7]&=0xFF00;
277
dma.src[(addr>>4)&7]|=val;
278
return;
279
case 0x4303: case 0x4313: case 0x4323: case 0x4333:
280
case 0x4343: case 0x4353: case 0x4363: case 0x4373:
281
dma.src[(addr>>4)&7]&=0xFF;
282
dma.src[(addr>>4)&7]|=(val<<8);
283
return;
284
case 0x4304: case 0x4314: case 0x4324: case 0x4334:
285
case 0x4344: case 0x4354: case 0x4364: case 0x4374:
286
dma.srcbank[(addr>>4)&7]=val;
287
return;
288
case 0x4305: case 0x4315: case 0x4325: case 0x4335:
289
case 0x4345: case 0x4355: case 0x4365: case 0x4375:
290
dma.size[(addr>>4)&7]&=0xFF00;
291
dma.size[(addr>>4)&7]|=val;
292
return;
293
case 0x4306: case 0x4316: case 0x4326: case 0x4336:
294
case 0x4346: case 0x4356: case 0x4366: case 0x4376:
295
dma.size[(addr>>4)&7]&=0xFF;
296
dma.size[(addr>>4)&7]|=(val<<8);
297
return;
298
case 0x4307: case 0x4317: case 0x4327: case 0x4337:
299
case 0x4347: case 0x4357: case 0x4367: case 0x4377:
300
hdma.ibank[(addr>>4)&7]=val;
301
return;
302
// default:
303
// printf("Bad I/O write %04X %02X\n",addr,val);
304
}
305
}
306
307
void dumpio()
308
{
309
printf("COUNTENA %02X\n",countena);
310
}
311
312