#include "snes.h"
int slines;
int hblnk=0;
int reg4016;
unsigned char *ram;
int fastrom;
int irqon;
int padready=1;
unsigned char countena;
unsigned char mula,mulb,divb;
unsigned short mulr,divr,divc;
uint32 joy1=0x80000000,joy2;
unsigned char readio(unsigned short addr)
{
unsigned char temp;
if (addr==0x4017)
{
return 0xFF;
}
if (addr==0x4016)
{
return 0xFF;
}
switch (addr)
{
case 0x4200:
return countena;
case 0x420C:
return hdmaena;
case 0x4210:
if (nmiocc)
{
nmiocc=0;
return 0x80;
}
return 0;
case 0x4211:
if (irqon)
{
irqon=0;
return 0x80;
}
return 0;
case 0x4212:
hblnk^=0x40;
if (vbl) return 0x80|padready|hblnk;
return padready|hblnk;
case 0x4213:
return 0xFF;
case 0x4214:
return divr;
case 0x4215:
return divr>>8;
case 0x4216:
return mulr;
case 0x4217:
return mulr>>8;
case 0x4218:
return native_joypad_state(0);
case 0x4219:
return native_joypad_state(0)>>8;
return temp;
case 0x421A: case 0x421B:
case 0x421C: case 0x421D:
case 0x421E: case 0x421F:
return 0;
case 0x4300: case 0x4310: case 0x4320: case 0x4330:
case 0x4340: case 0x4350: case 0x4360: case 0x4370:
return dma.ctrl[(addr>>4)&7];
case 0x4301: case 0x4311: case 0x4321: case 0x4331:
case 0x4341: case 0x4351: case 0x4361: case 0x4371:
return dma.dest[(addr>>4)&7];
case 0x4302: case 0x4312: case 0x4322: case 0x4332:
case 0x4342: case 0x4352: case 0x4362: case 0x4372:
return dma.src[(addr>>4)&7]&0xFF;
case 0x4303: case 0x4313: case 0x4323: case 0x4333:
case 0x4343: case 0x4353: case 0x4363: case 0x4373:
return dma.src[(addr>>4)&7]>>8;
case 0x4304: case 0x4314: case 0x4324: case 0x4334:
case 0x4344: case 0x4354: case 0x4364: case 0x4374:
return dma.srcbank[(addr>>4)&7];
case 0x4305: case 0x4315: case 0x4325: case 0x4335:
case 0x4345: case 0x4355: case 0x4365: case 0x4375:
return dma.size[(addr>>4)&7]&0xFF;
case 0x4306: case 0x4316: case 0x4326: case 0x4336:
case 0x4346: case 0x4356: case 0x4366: case 0x4376:
return dma.size[(addr>>4)&7]&0xFF;
}
return 0;
printf("Bad I/O read %04X\n",addr);
dumpregs();
exit(-1);
}
void writeio(unsigned short addr, unsigned char val)
{
int c;
int dmawsize[8]={1,2,2,4,4,0,0,0};
int dmadone=0;
unsigned short a,a2,len;
unsigned char temp,val2;
switch (addr)
{
case 0x4016: reg4016=val&1; return;
case 0x4200:
nmiena=val&0x80;
countena=val;
vertint=val&0x20;
horint=val&0x10;
irqon=0;
return;
case 0x4202:
mula=val;
mulr=mula*mulb;
return;
case 0x4203:
mulb=val;
mulr=mula*mulb;
return;
case 0x4204:
divc&=0xFF00;
divc|=val;
if (divb)
{
divr=divc/divb;
mulr=divc%divb;
}
else
{
divr=0xFFFF;
mulr=divc;
}
return;
case 0x4205:
divc&=0xFF;
divc|=(val<<8);
if (divb)
{
divr=divc/divb;
mulr=divc%divb;
}
else
{
divr=0xFFFF;
mulr=divc;
}
return;
case 0x4206:
divb=val;
if (divb)
{
divr=divc/divb;
mulr=divc%divb;
}
else
{
divr=0xFFFF;
mulr=divc;
}
return;
case 0x4209:
vertline=(vertline&0x100)|val;
return;
case 0x420A:
vertline=(vertline&0xFF)|((val<<8)&0x100);
irqon=0;
return;
case 0x420B:
temp=1;
for (c=0;c<8;c++)
{
if (val&temp)
{
len=dma.size[c];
a=dma.src[c];
a2=dma.dest[c]|0x2100;
do
{
if (dma.ctrl[c]&0x80)
{
if (mempointv[dma.srcbank[c]][a>>13])
mempoint[dma.srcbank[c]][a>>13][a&0x1FFF]=readppu(a2);
}
else
{
if (mempointv[dma.srcbank[c]][a>>13])
val2=mempoint[dma.srcbank[c]][a>>13][a&0x1FFF];
else
val2=0;
writeppu(a2,val2);
}
switch (dma.ctrl[c]&0xF)
{
case 0:
case 2:
if (dma.ctrl[c]&16) a--;
else a++;
break;
case 1:
if (a2==(dma.dest[c]|0x2100)) a2++;
else a2--;
if (dma.ctrl[c]&16) a--;
else a++;
break;
case 8:
case 0xA:
break;
case 9:
if (a2==(dma.dest[c]|0x2100)) a2++;
else a2--;
break;
default:
printf("Bad DMA mode %02X\n",dma.ctrl[c]);
dumpregs();
exit(-1);
}
len--;
}
while (len);
dma.src[c]=a;
dma.size[c]=0;
}
temp<<=1;
}
return;
case 0x420C:
hdmaena=val;
return;
case 0x420D:
fastrom=val&1;
return;
case 0x4300: case 0x4310: case 0x4320: case 0x4330:
case 0x4340: case 0x4350: case 0x4360: case 0x4370:
dma.ctrl[(addr>>4)&7]=val;
return;
case 0x4301: case 0x4311: case 0x4321: case 0x4331:
case 0x4341: case 0x4351: case 0x4361: case 0x4371:
dma.dest[(addr>>4)&7]=val;
return;
case 0x4302: case 0x4312: case 0x4322: case 0x4332:
case 0x4342: case 0x4352: case 0x4362: case 0x4372:
dma.src[(addr>>4)&7]&=0xFF00;
dma.src[(addr>>4)&7]|=val;
return;
case 0x4303: case 0x4313: case 0x4323: case 0x4333:
case 0x4343: case 0x4353: case 0x4363: case 0x4373:
dma.src[(addr>>4)&7]&=0xFF;
dma.src[(addr>>4)&7]|=(val<<8);
return;
case 0x4304: case 0x4314: case 0x4324: case 0x4334:
case 0x4344: case 0x4354: case 0x4364: case 0x4374:
dma.srcbank[(addr>>4)&7]=val;
return;
case 0x4305: case 0x4315: case 0x4325: case 0x4335:
case 0x4345: case 0x4355: case 0x4365: case 0x4375:
dma.size[(addr>>4)&7]&=0xFF00;
dma.size[(addr>>4)&7]|=val;
return;
case 0x4306: case 0x4316: case 0x4326: case 0x4336:
case 0x4346: case 0x4356: case 0x4366: case 0x4376:
dma.size[(addr>>4)&7]&=0xFF;
dma.size[(addr>>4)&7]|=(val<<8);
return;
case 0x4307: case 0x4317: case 0x4327: case 0x4337:
case 0x4347: case 0x4357: case 0x4367: case 0x4377:
hdma.ibank[(addr>>4)&7]=val;
return;
}
}
void dumpio()
{
printf("COUNTENA %02X\n",countena);
}