2 // This file is part of the PicoDrive Megadrive Emulator
\r
4 // This code is licensed under the GNU General Public License version 2.0 and the MAME License.
\r
5 // You can choose the license that has the most advantages for you.
\r
7 // SVN repository can be found at http://code.google.com/p/cyclone68000/
\r
15 int PicoPad[2]; // Joypads, format is SACB RLDU
\r
19 // Blank space for state:
\r
20 memset(&Pico,0,sizeof(Pico));
\r
21 memset(&PicoPad,0,sizeof(PicoPad));
\r
27 // Setup memory callbacks:
\r
32 YM2612Init(1,7670443,PsndRate,NULL,NULL);
\r
43 memset(&Pico,0,sizeof(Pico));
\r
48 unsigned int region=0;
\r
49 int support=0,hw=0,i=0;
\r
50 unsigned char pal=0;
\r
52 if (Pico.romsize<=0) return 1;
\r
60 // Read cartridge region data:
\r
61 region=PicoRead32(0x1f0);
\r
67 c=region>>(i<<3); c&=0xff;
\r
68 if (c<=' ') continue;
\r
70 if (c=='J') support|=1;
\r
71 else if (c=='U') support|=4;
\r
72 else if (c=='E') support|=8;
\r
78 support|=strtol(s,NULL,16);
\r
83 // Try to pick the best hardware value for English/60hz:
\r
84 if (support&4) hw=0x80; // USA
\r
85 else if (support&8) { hw=0xc0; pal=1; } // Europe
\r
86 else if (support&1) hw=0x00; // Japan NTSC
\r
87 else if (support&2) { hw=0x40; pal=1; } // Japan PAL
\r
88 else hw=0x80; // USA
\r
90 Pico.m.hardware=(unsigned char)(hw|0x20); // No disk attached
\r
96 static int CheckIdle()
\r
98 unsigned char state[0x88];
\r
100 memset(state,0,sizeof(state));
\r
102 // See if the state is the same after 2 steps:
\r
103 SekState(state); SekRun(0); SekRun(0); SekState(state+0x44);
\r
104 if (memcmp(state,state+0x44,0x44)==0) return 1;
\r
109 // Accurate but slower frame which does hints
\r
110 static int PicoFrameHints()
\r
112 struct PicoVideo *pv=&Pico.video;
\r
115 int hint=0x400; // Hint counter
\r
117 pv->status|=0x08; // Go into vblank
\r
119 for (y=-38;y<224;y++)
\r
123 hint=pv->reg[10]; // Load H-Int counter
\r
124 if (pv->reg[1]&0x40) pv->status&=~8; // Come out of vblank if display enabled
\r
130 hint=pv->reg[10]; // Reload H-Int counter
\r
131 if (pv->reg[0]&0x10) SekInterrupt(4);
\r
137 pv->status|=0x80; // V-Int happened
\r
138 if (pv->reg[1]&0x20) SekInterrupt(6);
\r
141 Pico.m.scanline=(short)y;
\r
144 aim+=489; total+=SekRun(aim-total);
\r
148 if (PicoScan && y>=0) PicoLine(y);
\r
151 SekInterrupt(0); // Cancel interrupt
\r
156 // Simple frame without H-Ints
\r
157 static int PicoFrameSimple()
\r
159 int total=0,y=0,aim=0;
\r
161 Pico.m.scanline=-64;
\r
163 // V-Blanking period:
\r
164 if (Pico.video.reg[1]&0x20) SekInterrupt(6); // Set IRQ
\r
165 Pico.video.status|=0x88; // V-Int happened / go into vblank
\r
166 total+=SekRun(18560);
\r
169 if (Pico.video.reg[1]&0x40) Pico.video.status&=~8; // Come out of vblank if display is enabled
\r
170 SekInterrupt(0); // Clear IRQ
\r
172 // Run in sections:
\r
173 for (aim=18560+6839; aim<=18560+6839*16; aim+=6839)
\r
176 if (CheckIdle()) break;
\r
177 add=SekRun(aim-total);
\r
181 if (PicoMask&0x100)
\r
185 for (y=0;y<224;y++) PicoLine(y);
\r
195 if (Pico.rom==NULL) return 1; // No Rom plugged in
\r
200 hints=Pico.video.reg[0]&0x10;
\r
202 if (hints) PicoFrameHints();
\r
203 else PicoFrameSimple();
\r
210 static int DefaultCram(int cram)
\r
213 // Convert 0000bbbb ggggrrrr
\r
214 // to rrrr1ggg g10bbbb1
\r
215 high|=(cram&0x00f)<<12; // Red
\r
216 high|=(cram&0x0f0)<< 3; // Green
\r
217 high|=(cram&0xf00)>> 7; // Blue
\r
221 // Function to convert Megadrive Cram into a native colour:
\r
222 int (*PicoCram)(int cram)=DefaultCram;
\r