extern int PicoCDBuffers;\r
\r
// Pico/Pico.c\r
-extern int PicoPicoPenPos[2]; // x: 0x03c-0x17d, y: 0x200-0x2d8\r
-extern int PicoPicoPage;\r
+typedef struct\r
+{\r
+ int pen_pos[2];\r
+ int page;\r
+ // internal\r
+ int fifo_bytes;\r
+ int line_counter;\r
+} picohw_state;\r
+extern picohw_state PicoPicohw;\r
\r
// Area.c\r
typedef size_t (arearw)(void *p, size_t _size, size_t _n, void *file);\r
#include "../PicoInt.h"
+#include "../sound/sn76496.h"
#ifndef UTYPES_DEFINED
typedef unsigned char u8;
#define UTYPES_DEFINED
#endif
+
// -----------------------------------------------------------------
// Read Rom and read Ram
a&=0xffffff;
- if ((a&0xffffe0)==0xc00000) { // VDP
+ if ((a&0xfffff0)==0xc00000) { // VDP
d=PicoVideoRead(a);
if ((a&1)==0) d>>=8;
goto end;
switch (a & 0x1f)
{
case 0x03:
- d = PicoPad[0]&0x0f; // d-pad
- d |= (PicoPad[0]&0x20) >> 1; // red button -> C
- d |= (PicoPad[0]&0x40) << 1; // pen tap -> A
+ d = PicoPad[0]&0x1f; // d-pad
+ d |= (PicoPad[0]&0x20) << 2; // red button -> C
d = ~d;
break;
- case 0x05: d = (PicoPicoPenPos[0] >> 8) & 3; break; // what is MS bit for? Games read it..
- case 0x07: d = PicoPicoPenPos[0] & 0xff; break;
- case 0x09: d = (PicoPicoPenPos[1] >> 8) & 3; break;
- case 0x0b: d = PicoPicoPenPos[1] & 0xff; break;
- case 0x0d: d = (1 << (PicoPicoPage & 7)) - 1;break;
+ case 0x05: d = (PicoPicohw.pen_pos[0] >> 8) & 3; break; // what is MS bit for? Games read it..
+ case 0x07: d = PicoPicohw.pen_pos[0] & 0xff; break;
+ case 0x09: d = (PicoPicohw.pen_pos[1] >> 8) & 3; break;
+ case 0x0b: d = PicoPicohw.pen_pos[1] & 0xff; break;
+ case 0x0d: d = (1 << (PicoPicohw.page & 7)) - 1; break;
case 0x12: d = 0x80; break;
default:
elprintf(EL_UIO, "r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPc);
if (a<Pico.romsize) { d = *(u16 *)(Pico.rom+a); goto end; } // Rom
- if ((a&0xffffe0)==0xc00000) {
+ if ((a&0xfffff0)==0xc00000) {
d = PicoVideoRead(a);
goto end;
}
- if (a == 0x800010) d = 0x0f;
+ if (a == 0x800010)
+ d = (PicoPicohw.fifo_bytes > 0x3f) ? 0 : (0x3f - PicoPicohw.fifo_bytes);
elprintf(EL_UIO, "r16: %06x, %04x @%06x", a&0xffffff, d, SekPc);
if (a<Pico.romsize) { u16 *pm=(u16 *)(Pico.rom+a); d = (pm[0]<<16)|pm[1]; goto end; } // Rom
- if ((a&0xffffe0)==0xc00000) {
+ if ((a&0xfffff0)==0xc00000) {
d = (PicoVideoRead(a)<<16)|PicoVideoRead(a+2);
goto end;
}
if ((a&0xe00000)==0xe00000) { *(u8 *)(Pico.ram+((a^1)&0xffff))=d; return; } // Ram
a&=0xffffff;
- if ((a&0xffffe0)==0xc00000) { // VDP
+ if ((a&0xfffff9)==0xc00011) { if (PicoOpt&2) SN76496Write(d); return; } // PSG Sound
+
+ if ((a&0xfffff0)==0xc00000) { // VDP
d&=0xff;
PicoVideoWrite(a,(u16)(d|(d<<8))); // Byte access gets mirrored
return;
if ((a&0xe00000)==0xe00000) { *(u16 *)(Pico.ram+(a&0xfffe))=d; return; } // Ram
a&=0xfffffe;
- if ((a&0xffffe0)==0xc00000) { PicoVideoWrite(a,(u16)d); return; } // VDP
+ if ((a&0xfffff0)==0xc00000) { PicoVideoWrite(a,(u16)d); return; } // VDP
// if (a == 0x800010) dump(d);
+ if (a == 0x800010) PicoPicohw.fifo_bytes += 2;
elprintf(EL_UIO, "w16: %06x, %04x", a&0xffffff, d);
}
}
a&=0xfffffe;
- if ((a&0xffffe0)==0xc00000)
+ if ((a&0xfffff0)==0xc00000)
{
// VDP:
PicoVideoWrite(a, (u16)(d>>16));
// x: 0x03c - 0x19d
// y: 0x1fc - 0x2f7
// 0x2f8 - 0x3f3
-int PicoPicoPenPos[2] = { 0x3c, 0x200 };
-int PicoPicoPage = 0; // 0-6
+picohw_state PicoPicohw;
+
+static int prev_line_cnt_irq3 = 0, prev_line_cnt_irq5 = 0;
+
+static void PicoLineHookPico(int count)
+{
+
+ PicoPicohw.line_counter += count;
+ if ((PicoPicohw.line_counter & 0xf) == 0 || count > 10)
+ {
+ if (PicoPicohw.fifo_bytes > 0)
+ PicoPicohw.fifo_bytes--;
+ }
+
+#if 0
+ if (PicoPicohw.line_counter - prev_line_cnt_irq3 > 200) {
+ prev_line_cnt_irq3 = PicoPicohw.line_counter;
+ // just a guess/hack, allows 101 Dalmantians to boot
+ elprintf(EL_ANOMALY, "irq3");
+ SekInterrupt(3);
+ }
+#endif
+
+#if 0
+ if (PicoPicohw.line_counter - prev_line_cnt_irq5 > 512) {
+ prev_line_cnt_irq5 = PicoPicohw.line_counter;
+ elprintf(EL_ANOMALY, "irq5");
+ SekInterrupt(5);
+ }
+#endif
+}
PICO_INTERNAL int PicoInitPico(void)
{
elprintf(EL_STATUS, "Pico detected");
+ PicoLineHook = PicoLineHookPico;
+
PicoAHW = PAHW_PICO;
- PicoPicoPage = 0;
+ memset(&PicoPicohw, 0, sizeof(PicoPicohw));
+ PicoPicohw.pen_pos[0] = 0x03c + 352/2;
+ PicoPicohw.pen_pos[1] = 0x200 + 252/2;
+ prev_line_cnt_irq3 = 0, prev_line_cnt_irq5 = 0;
return 0;
}
\r
#define Pico_mcd ((mcd_state *)Pico.rom)\r
\r
+\r
// Area.c\r
PICO_INTERNAL int PicoAreaPackCpu(unsigned char *cpu, int is_sub);\r
PICO_INTERNAL int PicoAreaUnpackCpu(unsigned char *cpu, int is_sub);\r
gettimeofday(¬iceMsgTime, 0);\r
}\r
if (events & (1 << 4)) {\r
- PicoPicoPage--;\r
- if (PicoPicoPage < 0) PicoPicoPage = 0;\r
- sprintf(noticeMsg, "Page %i ", PicoPicoPage);\r
+ PicoPicohw.page--;\r
+ if (PicoPicohw.page < 0) PicoPicohw.page = 0;\r
+ sprintf(noticeMsg, "Page %i ", PicoPicohw.page);\r
gettimeofday(¬iceMsgTime, 0);\r
}\r
if (events & (1 << 5)) {\r
- PicoPicoPage++;\r
- if (PicoPicoPage > 6) PicoPicoPage = 6;\r
- sprintf(noticeMsg, "Page %i ", PicoPicoPage);\r
+ PicoPicohw.page++;\r
+ if (PicoPicohw.page > 6) PicoPicohw.page = 6;\r
+ sprintf(noticeMsg, "Page %i ", PicoPicohw.page);\r
gettimeofday(¬iceMsgTime, 0);\r
}\r
if (pico_inp_mode != 0) {\r
if (gp2x_keys & GP2X_DOWN) { pico_pen_y++; if (pico_pen_y > 251) pico_pen_y = 251; }\r
if (gp2x_keys & GP2X_LEFT) { pico_pen_x--; if (pico_pen_x < 0) pico_pen_x = 0; }\r
if (gp2x_keys & GP2X_RIGHT){ pico_pen_x++; if (pico_pen_x > 353) pico_pen_x = 353; }\r
- PicoPicoPenPos[0] = 0x03c + pico_pen_x;\r
- PicoPicoPenPos[1] = pico_inp_mode == 1 ? (0x2f8 + pico_pen_y) : (0x1fc + pico_pen_y);\r
+ PicoPicohw.pen_pos[0] = 0x03c + pico_pen_x;\r
+ PicoPicohw.pen_pos[1] = pico_inp_mode == 1 ? (0x2f8 + pico_pen_y) : (0x1fc + pico_pen_y);\r
}\r
}\r
\r