else PicoMemSetup();\r
PicoMemReset();\r
SekReset();\r
+ // s68k doesn't have the TAS quirk, so we just globally set normal TAS handler in MCD mode (used by Batman games).\r
+ CycloneSetRealTAS(PicoMCD & 1);\r
SekCycleCntT=0;\r
z80_reset();\r
\r
goto end;\r
case 2:\r
d = (Pico_mcd->s68k_regs[a]<<8) | (Pico_mcd->s68k_regs[a+1]&0xc7);\r
- dprintf("m68k_regs r3: %02x @%06x", (u8)d, SekPc);\r
+ // the DMNA delay must only be visible on s68k side (Lunar2, Silpheed)\r
+ if (Pico_mcd->m.state_flags&2) { d &= ~1; d |= 2; }\r
+ //printf("m68k_regs r3: %02x @%06x\n", (u8)d, SekPc);\r
goto end;\r
case 4:\r
d = Pico_mcd->s68k_regs[4]<<8;\r
return;\r
case 3: {\r
u32 dold = Pico_mcd->s68k_regs[3]&0x1f;\r
- dprintf("m68k_regs w3: %02x @%06x", (u8)d, SekPc);\r
+ //printf("m68k_regs w3: %02x @%06x\n", (u8)d, SekPc);\r
d &= 0xc2;\r
if ((dold>>6) != ((d>>6)&3))\r
dprintf("m68k: prg bank: %i -> %i", (Pico_mcd->s68k_regs[a]>>6), ((d>>6)&3));\r
return ((Pico_mcd->s68k_regs[0]&3)<<8) | 1; // ver = 0, not in reset state\r
case 2:\r
d = (Pico_mcd->s68k_regs[a]<<8) | (Pico_mcd->s68k_regs[a+1]&0x1f);\r
- dprintf("s68k_regs r3: %02x @%06x", (u8)d, SekPcS68k);\r
+ //printf("s68k_regs r3: %02x @%06x\n", (u8)d, SekPcS68k);\r
goto poll_detect;\r
case 6:\r
return CDC_Read_Reg();\r
return; // only m68k can change WP\r
case 3: {\r
int dold = Pico_mcd->s68k_regs[3];\r
- dprintf("s68k_regs w3: %02x @%06x", (u8)d, SekPcS68k);\r
+ //printf("s68k_regs w3: %02x @%06x\n", (u8)d, SekPcS68k);\r
d &= 0x1d;\r
d |= dold&0xc2;\r
if (d&4) {\r
// prg RAM\r
if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&2)) {\r
u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
+ wrdprintf("m68k_prgram r16: [%i,%06x] @%06x", Pico_mcd->s68k_regs[3]>>6, a, SekPc);\r
d = *(u16 *)(prg_bank+(a&0x1fffe));\r
+ wrdprintf("ret = %04x", d);\r
goto end;\r
}\r
\r
// prg RAM\r
if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&2)) {\r
u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
+ wrdprintf("m68k_prgram w16: [%i,%06x] %04x @%06x", Pico_mcd->s68k_regs[3]>>6, a, d, SekPc);\r
*(u16 *)(prg_bank+(a&0x1fffe))=d;\r
return;\r
}\r
\r
// prg RAM\r
if (a < 0x80000) {\r
+ wrdprintf("s68k_prgram r16: [%06x] @%06x", a, SekPcS68k);\r
d = *(u16 *)(Pico_mcd->prg_ram+a);\r
+ wrdprintf("ret = %04x", d);\r
goto end;\r
}\r
\r
d = Pico_mcd->word_ram1M[bank][((a+0)^1)&0x1ffff] << 16;\r
d |= Pico_mcd->word_ram1M[bank][((a+1)^1)&0x1ffff];\r
d |= d << 4; d &= 0x0f0f0f0f;\r
- dprintf("FIXME: decode");\r
} else {\r
// allow access in any mode, like Gens does\r
u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); d = (pm[0]<<16)|pm[1];\r
d &= 0x0f;\r
if (!(a&1)) d <<= 4;\r
\r
- //dprintf("FIXME: decode, r3 = %02x", r3);\r
-\r
if (r3 == 8) {\r
if ((!(*pd & (~oldmask))) && d) goto do_it;\r
} else if (r3 > 8) {\r
} else {\r
*pd = d;\r
}\r
-\r
- //dprintf("FIXME: decode");\r
}\r
#endif\r
\r
// -----------------------------------------------------------------\r
\r
-//void PicoWriteS68k8_(u32 a,u8 d);\r
-//void PicoWriteS68k8__(u32 a,u8 d);\r
#ifdef _ASM_CD_MEMORY_C\r
void PicoWriteS68k8(u32 a,u8 d);\r
#else\r
#endif\r
\r
a&=0xffffff;\r
-#if 0\r
- PicoWriteS68k8_(a, d);\r
-/* if ((a&0xfc0000)!=0x080000) {\r
- PicoWriteS68k8_(a, d);\r
- return;\r
- }\r
- printf("r3: %02x\n", Pico_mcd->s68k_regs[3]);\r
- PicoWriteS68k8__(a,d);*/\r
- return;\r
-#endif\r
\r
// prg RAM\r
if (a < 0x80000) {\r
\r
// prg RAM\r
if (a < 0x80000) {\r
+ wrdprintf("s68k_prgram w16: [%06x] %04x @%06x", a, d, SekPcS68k);\r
*(u16 *)(Pico_mcd->prg_ram+a)=d;\r
return;\r
}\r
m_m68k_read8_r03:
add r1, r1, #0x110000
ldrb r0, [r1, #3]
+ add r1, r1, #0x002200
+ ldr r1, [r1, #4]
and r0, r0, #0xc7
+ tst r1, #2 @ DMNA pending?
+ bxeq lr
+ bic r0, r0, #1
+ orr r0, r0, #2
bx lr
m_m68k_read8_r04:
add r1, r1, #0x110000
m_m68k_read16_r02:
add r1, r1, #0x110000
ldrb r0, [r1, #2]
- ldrb r1, [r1, #3]
- and r1, r1, #0xc7
- orr r0, r1, r0, lsl #8
+ ldrb r2, [r1, #3]
+ add r1, r1, #0x002200
+ ldr r1, [r1, #4]
+ and r2, r2, #0xc7
+ orr r0, r2, r0, lsl #8
+ tst r1, #2 @ DMNA pending?
+ bxeq lr
+ bic r0, r0, #1
+ orr r0, r0, #2
bx lr
m_m68k_read16_r04:
add r1, r1, #0x110000
memset(&Pico_mcd->m, 0, sizeof(Pico_mcd->m));
*(unsigned int *)(Pico_mcd->bios + 0x70) = 0xffffffff; // reset hint vector (simplest way to implement reg6)
- Pico_mcd->m.state_flags |= 2; // s68k reset pending
+ Pico_mcd->m.state_flags |= 1; // s68k reset pending
Pico_mcd->s68k_regs[3] = 1; // 2M word RAM mode with m68k access after reset
Reset_CD();
{
int upd_len;
- dprintf("gfx_cd_start()");
-
// rot_comp.XD_Mul = ((rot_comp.Reg_5C & 0x1f) + 1) * 4; // unused
rot_comp.Function = (rot_comp.Reg_58 & 7) | (Pico_mcd->s68k_regs[3] & 0x18); // Jmp_Adr
// rot_comp.Buffer_Adr = (rot_comp.Reg_5E & 0xfff8) << 2; // unused?
break;
}
+ dprintf("gfx_cd_start, stamp_map_addr=%06x", rot_comp.Stamp_Map_Adr);
+
gfx_cd_update();
}
// MAKE_IMAGE_LINE
while (H_Dot)
{
+ // MAKE_IMAGE_PIXEL
+ if (!(func & 1)) // NOT TILED
+ {
+ int mask = (func & 4) ? 0x00800000 : 0x00f80000;
+ if ((ecx | edx) & mask)
+ {
+ if (func & 0x18) goto Next_Pixel;
+ pixel = 0;
+ goto Pixel_Out;
+ }
+ }
+
if (func & 2) // mode 32x32 dot
{
if (func & 4) // 16x16 screen
}
}
- // MAKE_IMAGE_PIXEL
- if (!(func & 1)) // NOT TILED
- {
- int mask = (func & 4) ? 0x00800000 : 0x00f80000;
- if ((ecx | edx) & mask)
- {
- if (func & 0x18) goto Next_Pixel;
- pixel = 0;
- goto Pixel_Out;
- }
- }
-
- edi = stamp_base[ebx];// | (stamp_base[ebx+1] << 16);
+ edi = stamp_base[ebx];
esi = (edi & 0x7ff) << 7;
if (!esi) { pixel = 0; goto Pixel_Out; }
edi >>= (11+1);
void CycloneSetSr(struct Cyclone *pcy, unsigned int sr); // auto-swaps a7<->osp if detects supervisor change\r
unsigned int CycloneGetSr(struct Cyclone *pcy);\r
\r
+// genesis: if 1, switch to normal TAS handlers\r
+void CycloneSetRealTAS(int use_real);\r
+\r
#ifdef __cplusplus\r
} // End of extern "C"\r
#endif\r
else ot(" .ltorg\n");\r
}\r
\r
+#if CYCLONE_FOR_GENESIS\r
+// r12=ptr to tas in table, trashes r0,r1\r
+static void ChangeTAS(int norm)\r
+{\r
+ ot(" ldr r0,=Op4ad0%s\n",norm?"_":"");\r
+ ot(" mov r1,#8\n");\r
+ ot("setrtas_loop%i0%s ;@ 4ad0-4ad7\n",norm,ms?"":":");\r
+ ot(" subs r1,r1,#1\n");\r
+ ot(" str r0,[r12],#4\n");\r
+ ot(" bne setrtas_loop%i0\n",norm);\r
+ ot(" ldr r0,=Op4ad8%s\n",norm?"_":"");\r
+ ot(" mov r1,#7\n");\r
+ ot("setrtas_loop%i1%s ;@ 4ad8-4ade\n",norm,ms?"":":");\r
+ ot(" subs r1,r1,#1\n");\r
+ ot(" str r0,[r12],#4\n");\r
+ ot(" bne setrtas_loop%i1\n",norm);\r
+ ot(" ldr r0,=Op4adf%s\n",norm?"_":"");\r
+ ot(" str r0,[r12],#4\n");\r
+ ot(" ldr r0,=Op4ae0%s\n",norm?"_":"");\r
+ ot(" mov r1,#7\n");\r
+ ot("setrtas_loop%i2%s ;@ 4ae0-4ae6\n",norm,ms?"":":");\r
+ ot(" subs r1,r1,#1\n");\r
+ ot(" str r0,[r12],#4\n");\r
+ ot(" bne setrtas_loop%i2\n",norm);\r
+ ot(" ldr r0,=Op4ae7%s\n",norm?"_":"");\r
+ ot(" str r0,[r12],#4\n");\r
+ ot(" ldr r0,=Op4ae8%s\n",norm?"_":"");\r
+ ot(" mov r1,#8\n");\r
+ ot("setrtas_loop%i3%s ;@ 4ae8-4aef\n",norm,ms?"":":");\r
+ ot(" subs r1,r1,#1\n");\r
+ ot(" str r0,[r12],#4\n");\r
+ ot(" bne setrtas_loop%i3\n",norm);\r
+ ot(" ldr r0,=Op4af0%s\n",norm?"_":"");\r
+ ot(" mov r1,#8\n");\r
+ ot("setrtas_loop%i4%s ;@ 4af0-4af7\n",norm,ms?"":":");\r
+ ot(" subs r1,r1,#1\n");\r
+ ot(" str r0,[r12],#4\n");\r
+ ot(" bne setrtas_loop%i4\n",norm);\r
+ ot(" ldr r0,=Op4af8%s\n",norm?"_":"");\r
+ ot(" str r0,[r12],#4\n");\r
+ ot(" ldr r0,=Op4af9%s\n",norm?"_":"");\r
+ ot(" str r0,[r12],#4\n");\r
+}\r
+#endif\r
+\r
// trashes all temp regs\r
static void PrintException(int ints)\r
{\r
ot(" bx lr\n");\r
ot("\n");\r
\r
+ if (ms) ot("CycloneSetRealTAS\n");\r
+ else ot("CycloneSetRealTAS:\n");\r
+#if CYCLONE_FOR_GENESIS\r
+ ot(" ldr r12,=CycloneJumpTab\n");\r
+ ot(" tst r0,r0\n");\r
+ ot(" add r12,r12,#0x4a00*4\n");\r
+ ot(" add r12,r12,#0x00d0*4\n");\r
+ ot(" beq setrtas_off\n");\r
+ ChangeTAS(1);\r
+ ot(" bx lr\n");\r
+ ot("setrtas_off%s\n",ms?"":":");\r
+ ChangeTAS(0);\r
+ ot(" bx lr\n");\r
+ ltorg();\r
+ ot("\n");\r
+#else\r
+ ot(" bx lr\n");\r
+ ot("\n");\r
+#endif\r
+\r
ot(";@ DoInterrupt - r0=IRQ number\n");\r
ot("CycloneDoInterrupt%s\n", ms?"":":");\r
ot(" stmdb sp!,{lr} ;@ Push ARM return address\n");\r
\r
ot(";@ -------------------------- Jump Table --------------------------\n");\r
\r
+ // space for decompressed table\r
+ ot(ms?" area |.data|, data\n":" .data\n .align 4\n\n");\r
+\r
#if COMPRESS_JUMPTABLE\r
int handlers=0,reps=0,*indexes,ip,u,out;\r
// use some weird compression on the jump table\r
if(!indexes) { printf("ERROR: out of memory\n"); exit(1); }\r
len=0x10000;\r
\r
- // space for decompressed table\r
- ot(ms?" area |.data|, data\n":" .data\n .align 4\n\n");\r
-\r
ot("CycloneJumpTab%s\n", ms?"":":");\r
if(ms) {\r
for(i = 0; i < 0xa000/8; i++)\r
ot(" export CycloneRun\n");\r
ot(" export CycloneSetSr\n");\r
ot(" export CycloneGetSr\n");\r
+ ot(" export CycloneSetRealTAS\n");\r
ot(" export CycloneVer\n");\r
ot("\n");\r
ot("CycloneVer dcd 0x%.4x\n",CycloneVer);\r
ot(" .global CycloneRun\n");\r
ot(" .global CycloneSetSr\n");\r
ot(" .global CycloneGetSr\n");\r
+ ot(" .global CycloneSetRealTAS\n");\r
ot(" .global CycloneVer\n");\r
#ifdef CYCLONE_FOR_PICODRIVE\r
ot(" .global CycloneDoInterrupt\n");\r
return 0;\r
}\r
\r
-int OpTas(int op)\r
+int OpTas(int op, int gen_special)\r
{\r
int ea=0;\r
int use=0;\r
use=OpBase(op);\r
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
\r
- OpStart(op); Cycles=4;\r
+ if (!gen_special) OpStart(op);\r
+ else\r
+ ot("Op%.4x_%s\n", op, ms?"":":");\r
+\r
+ Cycles=4;\r
if(ea>=8) Cycles+=10;\r
\r
EaCalc (10,0x003f,ea,0,1);\r
\r
#if CYCLONE_FOR_GENESIS\r
// the original Sega hardware ignores write-back phase (to memory only)\r
- if (ea < 0x10) {\r
+ if (ea < 0x10 || gen_special) {\r
#endif\r
ot(" orr r1,r1,#0x80000000 ;@ set bit7\n");\r
\r
#endif\r
\r
OpEnd();\r
+\r
+#if CYCLONE_FOR_GENESIS\r
+ if (!gen_special && ea >= 0x10) {\r
+ OpTas(op, 1);\r
+ }\r
+#endif\r
+\r
return 0;\r
}\r
\r
int OpSet(int op);\r
int OpAsr(int op);\r
int OpAsrEa(int op);\r
-int OpTas(int op);\r
+int OpTas(int op, int gen_special=0);\r
\r
// OpMove.cpp\r
int OpMove(int op);\r
return alphasort(d1, d2);\r
}\r
\r
+static char *filter_exts[] = { ".mp3", ".MP3", ".srm", ".brm", "s.gz", ".mds", "bcfg", ".txt", ".htm", "html", ".gpe" };\r
+\r
+static int scandir_filter(const struct dirent *ent)\r
+{\r
+ const char *p;\r
+ int i;\r
+\r
+ if (ent == NULL || ent->d_name == NULL) return 0;\r
+ if (strlen(ent->d_name) < 5) return 1;\r
+\r
+ p = ent->d_name + strlen(ent->d_name) - 4;\r
+\r
+ for (i = 0; i < sizeof(filter_exts)/sizeof(filter_exts[0]); i++)\r
+ {\r
+ if (strcmp(p, filter_exts[i]) == 0) return 0;\r
+ }\r
+\r
+ return 1;\r
+}\r
\r
static char *romsel_loop(char *curr_path)\r
{\r
fname = p+1;\r
}\r
\r
- n = scandir(curr_path, &namelist, 0, scandir_cmp);\r
+ n = scandir(curr_path, &namelist, scandir_filter, scandir_cmp);\r
if (n < 0) {\r
// try root\r
- n = scandir(curr_path, &namelist, 0, scandir_cmp);\r
+ n = scandir("/", &namelist, scandir_filter, scandir_cmp);\r
if (n < 0) {\r
// oops, we failed\r
printf("dir: "); printf(curr_path); printf("\n");\r
-#define VERSION "1.30"\r
+#define VERSION "1.31"\r
\r
\r
Changelog\r
---------\r
+1.31\r
+ * Changed the way memory mode register is read (fixes Lunar 2, broken in 1.30).\r
+ * Fixed TAS opcode on sub-68k side (fixes Batman games).\r
+ * File browser now filters out mp3s, saves and some other files, which are not ROMS.\r
+\r
1.30\r
+ ISO files now can be zipped. Note that this causes VERY long loading times.\r
+ Added data pre-buffering support, this allows to reduce frequency of short pauses\r