+++ /dev/null
-\r
-// This file is part of the PicoDrive Megadrive Emulator\r
-\r
-// Copyright (c) 2011 FinalDave (emudave (at) gmail.com)\r
-\r
-// This code is licensed under the GNU General Public License version 2.0 and the MAME License.\r
-// You can choose the license that has the most advantages for you.\r
-\r
-// SVN repository can be found at http://code.google.com/p/cyclone68000/\r
-\r
-#include "PicoInt.h"\r
-\r
-int PicoVer=0x0030;\r
-struct Pico Pico;\r
-int PicoOpt=0;\r
-\r
-int PicoPad[2]; // Joypads, format is SACB RLDU\r
-\r
-int PicoInit()\r
-{\r
- // Blank space for state:\r
- memset(&Pico,0,sizeof(Pico));\r
- memset(&PicoPad,0,sizeof(PicoPad));\r
- Pico.m.dirtyPal=1;\r
-\r
- // Init CPU:\r
- SekInit();\r
-\r
- // Setup memory callbacks:\r
- PicoMemInit();\r
- PsndReset();\r
-\r
-#ifdef MSOUND\r
- YM2612Init(1,7670443,PsndRate,NULL,NULL);\r
-#endif\r
- return 0;\r
-}\r
-\r
-void PicoExit()\r
-{\r
-#ifdef MSOUND\r
- YM2612Shutdown();\r
-#endif\r
-\r
- memset(&Pico,0,sizeof(Pico));\r
-}\r
-\r
-int PicoReset()\r
-{\r
- unsigned int region=0;\r
- int support=0,hw=0,i=0;\r
- unsigned char pal=0;\r
-\r
- if (Pico.romsize<=0) return 1;\r
-\r
- SekReset();\r
- PsndReset();\r
-#ifdef MSOUND\r
- YM2612ResetChip(0);\r
-#endif\r
-\r
- // Read cartridge region data:\r
- region=PicoRead32(0x1f0);\r
-\r
- for (i=0;i<4;i++)\r
- {\r
- int c=0;\r
- \r
- c=region>>(i<<3); c&=0xff;\r
- if (c<=' ') continue;\r
-\r
- if (c=='J') support|=1;\r
- else if (c=='U') support|=4;\r
- else if (c=='E') support|=8;\r
- else\r
- {\r
- // New style code:\r
- char s[2]={0,0};\r
- s[0]=(char)c;\r
- support|=strtol(s,NULL,16);\r
- }\r
-\r
- }\r
-\r
- // Try to pick the best hardware value for English/60hz:\r
- if (support&4) hw=0x80; // USA\r
- else if (support&8) { hw=0xc0; pal=1; } // Europe\r
- else if (support&1) hw=0x00; // Japan NTSC\r
- else if (support&2) { hw=0x40; pal=1; } // Japan PAL\r
- else hw=0x80; // USA\r
-\r
- Pico.m.hardware=(unsigned char)(hw|0x20); // No disk attached\r
- Pico.m.pal=pal;\r
-\r
- return 0;\r
-}\r
-\r
-static int CheckIdle()\r
-{\r
- unsigned char state[0x88];\r
-\r
- memset(state,0,sizeof(state));\r
-\r
- // See if the state is the same after 2 steps:\r
- SekState(state); SekRun(0); SekRun(0); SekState(state+0x44);\r
- if (memcmp(state,state+0x44,0x44)==0) return 1;\r
-\r
- return 0;\r
-}\r
-\r
-// Accurate but slower frame which does hints\r
-static int PicoFrameHints()\r
-{\r
- struct PicoVideo *pv=&Pico.video;\r
- int total=0,aim=0;\r
- int y=0;\r
- int hint=0x400; // Hint counter\r
-\r
- pv->status|=0x08; // Go into vblank\r
-\r
- for (y=-38;y<224;y++)\r
- {\r
- if (y==0)\r
- {\r
- hint=pv->reg[10]; // Load H-Int counter\r
- if (pv->reg[1]&0x40) pv->status&=~8; // Come out of vblank if display enabled\r
- }\r
-\r
- // H-Interrupts:\r
- if (hint<0)\r
- {\r
- hint=pv->reg[10]; // Reload H-Int counter\r
- if (pv->reg[0]&0x10) SekInterrupt(4);\r
- }\r
-\r
- // V-Interrupt:\r
- if (y==-37)\r
- {\r
- pv->status|=0x80; // V-Int happened\r
- if (pv->reg[1]&0x20) SekInterrupt(6);\r
- }\r
-\r
- Pico.m.scanline=(short)y;\r
-\r
- // Run scanline:\r
- aim+=489; total+=SekRun(aim-total);\r
-\r
- hint--;\r
-\r
- if (PicoScan && y>=0) PicoLine(y);\r
- }\r
-\r
- SekInterrupt(0); // Cancel interrupt\r
-\r
- return 0;\r
-}\r
-\r
-// Simple frame without H-Ints\r
-static int PicoFrameSimple()\r
-{\r
- int total=0,y=0,aim=0;\r
- \r
- Pico.m.scanline=-64;\r
-\r
- // V-Blanking period:\r
- if (Pico.video.reg[1]&0x20) SekInterrupt(6); // Set IRQ\r
- Pico.video.status|=0x88; // V-Int happened / go into vblank\r
- total+=SekRun(18560);\r
-\r
- // Active Scan:\r
- if (Pico.video.reg[1]&0x40) Pico.video.status&=~8; // Come out of vblank if display is enabled\r
- SekInterrupt(0); // Clear IRQ\r
-\r
- // Run in sections:\r
- for (aim=18560+6839; aim<=18560+6839*16; aim+=6839)\r
- {\r
- int add=0;\r
- if (CheckIdle()) break;\r
- add=SekRun(aim-total);\r
- total+=add;\r
- }\r
-\r
- if (PicoMask&0x100)\r
- if (PicoScan)\r
- {\r
- // Draw the screen\r
- for (y=0;y<224;y++) PicoLine(y);\r
- }\r
-\r
- return 0;\r
-}\r
-\r
-int PicoFrame()\r
-{\r
- int hints=0;\r
-\r
- if (Pico.rom==NULL) return 1; // No Rom plugged in\r
-\r
-\r
- PmovUpdate();\r
-\r
- hints=Pico.video.reg[0]&0x10;\r
-\r
- if (hints) PicoFrameHints();\r
- else PicoFrameSimple();\r
-\r
- PsndRender();\r
-\r
- return 0;\r
-}\r
-\r
-static int DefaultCram(int cram)\r
-{\r
- int high=0x0841;\r
- // Convert 0000bbbb ggggrrrr\r
- // to rrrr1ggg g10bbbb1\r
- high|=(cram&0x00f)<<12; // Red\r
- high|=(cram&0x0f0)<< 3; // Green\r
- high|=(cram&0xf00)>> 7; // Blue\r
- return high;\r
-}\r
-\r
-// Function to convert Megadrive Cram into a native colour:\r
-int (*PicoCram)(int cram)=DefaultCram;\r