8 int PicoPad[2]; // Joypads, format is SACB RLDU
\r
12 // Blank space for state:
\r
13 memset(&Pico,0,sizeof(Pico));
\r
14 memset(&PicoPad,0,sizeof(PicoPad));
\r
20 // Setup memory callbacks:
\r
25 YM2612Init(1,7670443,PsndRate,NULL,NULL);
\r
36 memset(&Pico,0,sizeof(Pico));
\r
41 unsigned int region=0;
\r
42 int support=0,hw=0,i=0;
\r
43 unsigned char pal=0;
\r
45 if (Pico.romsize<=0) return 1;
\r
53 // Read cartridge region data:
\r
54 region=PicoRead32(0x1f0);
\r
60 c=region>>(i<<3); c&=0xff;
\r
61 if (c<=' ') continue;
\r
63 if (c=='J') support|=1;
\r
64 else if (c=='U') support|=4;
\r
65 else if (c=='E') support|=8;
\r
71 support|=strtol(s,NULL,16);
\r
76 // Try to pick the best hardware value for English/60hz:
\r
77 if (support&4) hw=0x80; // USA
\r
78 else if (support&8) { hw=0xc0; pal=1; } // Europe
\r
79 else if (support&1) hw=0x00; // Japan NTSC
\r
80 else if (support&2) { hw=0x40; pal=1; } // Japan PAL
\r
81 else hw=0x80; // USA
\r
83 Pico.m.hardware=(unsigned char)(hw|0x20); // No disk attached
\r
89 static int CheckIdle()
\r
91 unsigned char state[0x88];
\r
93 memset(state,0,sizeof(state));
\r
95 // See if the state is the same after 2 steps:
\r
96 SekState(state); SekRun(0); SekRun(0); SekState(state+0x44);
\r
97 if (memcmp(state,state+0x44,0x44)==0) return 1;
\r
102 // Accurate but slower frame which does hints
\r
103 static int PicoFrameHints()
\r
105 struct PicoVideo *pv=&Pico.video;
\r
108 int hint=0x400; // Hint counter
\r
110 pv->status|=0x08; // Go into vblank
\r
112 for (y=-38;y<224;y++)
\r
116 hint=pv->reg[10]; // Load H-Int counter
\r
117 if (pv->reg[1]&0x40) pv->status&=~8; // Come out of vblank if display enabled
\r
123 hint=pv->reg[10]; // Reload H-Int counter
\r
124 if (pv->reg[0]&0x10) SekInterrupt(4);
\r
130 pv->status|=0x80; // V-Int happened
\r
131 if (pv->reg[1]&0x20) SekInterrupt(6);
\r
134 Pico.m.scanline=(short)y;
\r
137 aim+=489; total+=SekRun(aim-total);
\r
141 if (PicoScan && y>=0) PicoLine(y);
\r
144 SekInterrupt(0); // Cancel interrupt
\r
149 // Simple frame without H-Ints
\r
150 static int PicoFrameSimple()
\r
152 int total=0,y=0,aim=0;
\r
154 Pico.m.scanline=-64;
\r
156 // V-Blanking period:
\r
157 if (Pico.video.reg[1]&0x20) SekInterrupt(6); // Set IRQ
\r
158 Pico.video.status|=0x88; // V-Int happened / go into vblank
\r
159 total+=SekRun(18560);
\r
162 if (Pico.video.reg[1]&0x40) Pico.video.status&=~8; // Come out of vblank if display is enabled
\r
163 SekInterrupt(0); // Clear IRQ
\r
165 // Run in sections:
\r
166 for (aim=18560+6839; aim<=18560+6839*16; aim+=6839)
\r
169 if (CheckIdle()) break;
\r
170 add=SekRun(aim-total);
\r
174 if (PicoMask&0x100)
\r
178 for (y=0;y<224;y++) PicoLine(y);
\r
188 if (Pico.rom==NULL) return 1; // No Rom plugged in
\r
193 hints=Pico.video.reg[0]&0x10;
\r
195 if (hints) PicoFrameHints();
\r
196 else PicoFrameSimple();
\r
203 static int DefaultCram(int cram)
\r
206 // Convert 0000bbbb ggggrrrr
\r
207 // to rrrr1ggg g10bbbb1
\r
208 high|=(cram&0x00f)<<12; // Red
\r
209 high|=(cram&0x0f0)<< 3; // Green
\r
210 high|=(cram&0xf00)>> 7; // Blue
\r
214 // Function to convert Megadrive Cram into a native colour:
\r
215 int (*PicoCram)(int cram)=DefaultCram;
\r