2 // This file is part of the PicoDrive Megadrive Emulator
\r
4 // Copyright (c) 2011 FinalDave (emudave (at) gmail.com)
\r
6 // This code is licensed under the GNU General Public License version 2.0 and the MAME License.
\r
7 // You can choose the license that has the most advantages for you.
\r
9 // SVN repository can be found at http://code.google.com/p/cyclone68000/
\r
11 #include "PicoInt.h"
\r
17 int PicoPad[2]; // Joypads, format is SACB RLDU
\r
21 // Blank space for state:
\r
22 memset(&Pico,0,sizeof(Pico));
\r
23 memset(&PicoPad,0,sizeof(PicoPad));
\r
29 // Setup memory callbacks:
\r
34 YM2612Init(1,7670443,PsndRate,NULL,NULL);
\r
45 memset(&Pico,0,sizeof(Pico));
\r
50 unsigned int region=0;
\r
51 int support=0,hw=0,i=0;
\r
52 unsigned char pal=0;
\r
54 if (Pico.romsize<=0) return 1;
\r
62 // Read cartridge region data:
\r
63 region=PicoRead32(0x1f0);
\r
69 c=region>>(i<<3); c&=0xff;
\r
70 if (c<=' ') continue;
\r
72 if (c=='J') support|=1;
\r
73 else if (c=='U') support|=4;
\r
74 else if (c=='E') support|=8;
\r
80 support|=strtol(s,NULL,16);
\r
85 // Try to pick the best hardware value for English/60hz:
\r
86 if (support&4) hw=0x80; // USA
\r
87 else if (support&8) { hw=0xc0; pal=1; } // Europe
\r
88 else if (support&1) hw=0x00; // Japan NTSC
\r
89 else if (support&2) { hw=0x40; pal=1; } // Japan PAL
\r
90 else hw=0x80; // USA
\r
92 Pico.m.hardware=(unsigned char)(hw|0x20); // No disk attached
\r
98 static int CheckIdle()
\r
100 unsigned char state[0x88];
\r
102 memset(state,0,sizeof(state));
\r
104 // See if the state is the same after 2 steps:
\r
105 SekState(state); SekRun(0); SekRun(0); SekState(state+0x44);
\r
106 if (memcmp(state,state+0x44,0x44)==0) return 1;
\r
111 // Accurate but slower frame which does hints
\r
112 static int PicoFrameHints()
\r
114 struct PicoVideo *pv=&Pico.video;
\r
117 int hint=0x400; // Hint counter
\r
119 pv->status|=0x08; // Go into vblank
\r
121 for (y=-38;y<224;y++)
\r
125 hint=pv->reg[10]; // Load H-Int counter
\r
126 if (pv->reg[1]&0x40) pv->status&=~8; // Come out of vblank if display enabled
\r
132 hint=pv->reg[10]; // Reload H-Int counter
\r
133 if (pv->reg[0]&0x10) SekInterrupt(4);
\r
139 pv->status|=0x80; // V-Int happened
\r
140 if (pv->reg[1]&0x20) SekInterrupt(6);
\r
143 Pico.m.scanline=(short)y;
\r
146 aim+=489; total+=SekRun(aim-total);
\r
150 if (PicoScan && y>=0) PicoLine(y);
\r
153 SekInterrupt(0); // Cancel interrupt
\r
158 // Simple frame without H-Ints
\r
159 static int PicoFrameSimple()
\r
161 int total=0,y=0,aim=0;
\r
163 Pico.m.scanline=-64;
\r
165 // V-Blanking period:
\r
166 if (Pico.video.reg[1]&0x20) SekInterrupt(6); // Set IRQ
\r
167 Pico.video.status|=0x88; // V-Int happened / go into vblank
\r
168 total+=SekRun(18560);
\r
171 if (Pico.video.reg[1]&0x40) Pico.video.status&=~8; // Come out of vblank if display is enabled
\r
172 SekInterrupt(0); // Clear IRQ
\r
174 // Run in sections:
\r
175 for (aim=18560+6839; aim<=18560+6839*16; aim+=6839)
\r
178 if (CheckIdle()) break;
\r
179 add=SekRun(aim-total);
\r
183 if (PicoMask&0x100)
\r
187 for (y=0;y<224;y++) PicoLine(y);
\r
197 if (Pico.rom==NULL) return 1; // No Rom plugged in
\r
202 hints=Pico.video.reg[0]&0x10;
\r
204 if (hints) PicoFrameHints();
\r
205 else PicoFrameSimple();
\r
212 static int DefaultCram(int cram)
\r
215 // Convert 0000bbbb ggggrrrr
\r
216 // to rrrr1ggg g10bbbb1
\r
217 high|=(cram&0x00f)<<12; // Red
\r
218 high|=(cram&0x0f0)<< 3; // Green
\r
219 high|=(cram&0xf00)>> 7; // Blue
\r
223 // Function to convert Megadrive Cram into a native colour:
\r
224 int (*PicoCram)(int cram)=DefaultCram;
\r