\r
\r
#include "PicoInt.h"\r
+#include "cd/gfx_cd.h"\r
\r
extern const unsigned char hcounts_32[];\r
extern const unsigned char hcounts_40[];\r
extern const unsigned short vcounts[];\r
extern int rendstatus;\r
\r
+typedef unsigned char u8;\r
typedef unsigned short u16;\r
\r
\r
\r
if(Pico.m.scanline != -1) {\r
Pico.m.dma_bytes += len;\r
- SekSetCyclesLeft(SekCyclesLeft - CheckDMA());\r
+ if ((PicoMCD&1) && (PicoOpt & 0x2000)) SekCycleCnt+=CheckDMA();\r
+ else SekSetCyclesLeftNoMCD(SekCyclesLeftNoMCD - CheckDMA());\r
} else {\r
// be approximate in non-accurate mode\r
SekSetCyclesLeft(SekCyclesLeft - (len*(((488<<8)/167))>>8));\r
}\r
\r
- if ((source&0xe00000)==0xe00000) { pd=(u16 *)(Pico.ram+(source&0xfffe)); pdend=(u16 *)(Pico.ram+0x10000); } // Ram\r
- else if(PicoMCD & 1) {\r
- if(source<0x20000) { pd=(u16 *)(Pico_mcd->bios+(source&~1)); pdend=(u16 *)(Pico_mcd->bios+0x20000); } // Bios area\r
- else { dprintf("unsupported src"); return; } // Invalid source address\r
+ if ((source&0xe00000)==0xe00000) { // Ram\r
+ pd=(u16 *)(Pico.ram+(source&0xfffe));\r
+ pdend=(u16 *)(Pico.ram+0x10000);\r
+ } else if(PicoMCD & 1) {\r
+ dprintf("DmaSlow CD, r3=%02x", Pico_mcd->s68k_regs[3]);\r
+ if(source<0x20000) { // Bios area\r
+ pd=(u16 *)(Pico_mcd->bios+(source&~1));\r
+ pdend=(u16 *)(Pico_mcd->bios+0x20000);\r
+ } else if ((source&0xfc0000)==0x200000) { // Word Ram\r
+ source -= 2;\r
+ if (!(Pico_mcd->s68k_regs[3]&4)) { // 2M mode\r
+ pd=(u16 *)(Pico_mcd->word_ram2M+(source&0x3fffe));\r
+ pdend=(u16 *)(Pico_mcd->word_ram2M+0x40000);\r
+ } else {\r
+ if (source < 0x220000) { // 1M mode\r
+ int bank = Pico_mcd->s68k_regs[3]&1;\r
+ pd=(u16 *)(Pico_mcd->word_ram1M[bank]+(source&0x1fffe));\r
+ pdend=(u16 *)(Pico_mcd->word_ram1M[bank]+0x20000);\r
+ } else {\r
+ DmaSlowCell(source, a, len, inc);\r
+ return;\r
+ }\r
+ }\r
+ } else if ((source&0xfe0000)==0x020000) { // Prg Ram\r
+ u8 *prg_ram = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
+ pd=(u16 *)(prg_ram+(source&0x1fffe));\r
+ pdend=(u16 *)(prg_ram+0x20000);\r
+ } else {\r
+ dprintf("DmaSlow FIXME: unsupported src");\r
+ return;\r
+ }\r
} else {\r
- if(source<Pico.romsize) { pd=(u16 *)(Pico.rom+(source&~1)); pdend=(u16 *)(Pico.rom+Pico.romsize); } // Rom\r
- else { dprintf("invalid dma src"); return; } // Invalid source address\r
+ if(source<Pico.romsize) { // Rom\r
+ pd=(u16 *)(Pico.rom+(source&~1));\r
+ pdend=(u16 *)(Pico.rom+Pico.romsize);\r
+ } else {\r
+ dprintf("DmaSlow: invalid dma src");\r
+ return;\r
+ }\r
+ }\r
+\r
+ // overflow protection, might break something..\r
+ if (len > pdend - pd) {\r
+ len = pdend - pd;\r
+ dprintf("DmaSlow overflow");\r
}\r
\r
switch (Pico.video.type)\r
{\r
case 1: // vram\r
r = Pico.vram;\r
- for(; len; len--)\r
+ if (inc == 2 && !(a&1) && a+len*2 < 0x10000)\r
{\r
- d=*pd++;\r
- if(a&1) d=(d<<8)|(d>>8);\r
- r[a>>1] = (u16)d; // will drop the upper bits\r
- // AutoIncrement\r
- a=(u16)(a+inc);\r
- // didn't src overlap?\r
- if(pd >= pdend) pd-=0x8000; // should be good for RAM, bad for ROM\r
+ // most used DMA mode\r
+ memcpy16(r + (a>>1), pd, len);\r
+ a += len*2;\r
+ }\r
+ else\r
+ {\r
+ for(; len; len--)\r
+ {\r
+ d=*pd++;\r
+ if(a&1) d=(d<<8)|(d>>8);\r
+ r[a>>1] = (u16)d; // will drop the upper bits\r
+ // AutoIncrement\r
+ a=(u16)(a+inc);\r
+ // didn't src overlap?\r
+ //if(pd >= pdend) pd-=0x8000; // should be good for RAM, bad for ROM\r
+ }\r
}\r
rendstatus|=0x10;\r
break;\r
r = Pico.cram;\r
for(a2=a&0x7f; len; len--)\r
{\r
- r[a2>>1] = (u16)*pd++;; // bit 0 is ignored\r
+ r[a2>>1] = (u16)*pd++; // bit 0 is ignored\r
// AutoIncrement\r
a2+=inc;\r
// didn't src overlap?\r
- if(pd >= pdend) pd-=0x8000;\r
+ //if(pd >= pdend) pd-=0x8000;\r
// good dest?\r
if(a2 >= 0x80) break; // Todds Adventures in Slime World / Andre Agassi tennis\r
}\r
// AutoIncrement\r
a2+=inc;\r
// didn't src overlap?\r
- if(pd >= pdend) pd-=0x8000;\r
+ //if(pd >= pdend) pd-=0x8000;\r
// good dest?\r
if(a2 >= 0x80) break;\r
}\r