mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 07:17:45 -04:00
adjustments for MAME
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@164 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
parent
e362c57310
commit
a67855765d
9 changed files with 245 additions and 216 deletions
|
@ -382,17 +382,23 @@ int MemHandler(int type,int size)
|
|||
int func=0;
|
||||
func=0x68+type*0xc+(size<<2); // Find correct offset
|
||||
|
||||
#if MEMHANDLERS_NEED_PC
|
||||
ot(" str r4,[r7,#0x40] ;@ Save PC\n");
|
||||
#endif
|
||||
#if MEMHANDLERS_NEED_FLAGS
|
||||
ot(" mov r3,r9,lsr #28\n");
|
||||
ot(" strb r3,[r7,#0x46] ;@ Save Flags (NZCV)\n");
|
||||
#endif
|
||||
#if MEMHANDLERS_NEED_CYCLES
|
||||
ot(" str r5,[r7,#0x5c] ;@ Save Cycles\n");
|
||||
#endif
|
||||
|
||||
#if (MEMHANDLERS_ADDR_MASK & 0xff000000)
|
||||
ot(" bic r0,r0,#0x%08x\n", MEMHANDLERS_ADDR_MASK & 0xff000000);
|
||||
#endif
|
||||
#if (MEMHANDLERS_ADDR_MASK & 0x00ff0000)
|
||||
ot(" bic r0,r0,#0x%08x\n", MEMHANDLERS_ADDR_MASK & 0x00ff0000);
|
||||
#endif
|
||||
#if (MEMHANDLERS_ADDR_MASK & 0x0000ff00)
|
||||
ot(" bic r0,r0,#0x%08x\n", MEMHANDLERS_ADDR_MASK & 0x0000ff00);
|
||||
#endif
|
||||
#if (MEMHANDLERS_ADDR_MASK & 0x000000ff)
|
||||
ot(" bic r0,r0,#0x%08x\n", MEMHANDLERS_ADDR_MASK & 0x000000ff);
|
||||
#endif
|
||||
ot(" mov lr,pc\n");
|
||||
ot(" ldr pc,[r7,#0x%x] ;@ Call ",func);
|
||||
|
||||
|
|
|
@ -25,11 +25,23 @@ void OpUse(int op,int use)
|
|||
ot(";@ ---------- [%.4x] %s uses Op%.4x ----------\n",op,text,use);
|
||||
}
|
||||
|
||||
void OpStart(int op)
|
||||
void OpStart(int op, int ea)
|
||||
{
|
||||
Cycles=0;
|
||||
OpUse(op,op); // This opcode obviously uses this handler
|
||||
ot("Op%.4x%s\n", op, ms?"":":");
|
||||
#if (MEMHANDLERS_NEED_PC || MEMHANDLERS_NEED_CYCLES)
|
||||
if (ea >= 0x10) {
|
||||
#if MEMHANDLERS_NEED_PC
|
||||
ot(" sub r0,r4,#2\n");
|
||||
ot(" str r0,[r7,#0x40] ;@ Save PC\n");
|
||||
#endif
|
||||
#if MEMHANDLERS_NEED_CYCLES
|
||||
ot(" str r5,[r7,#0x5c] ;@ Save Cycles\n");
|
||||
#endif
|
||||
ot("\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void OpEnd()
|
||||
|
|
|
@ -22,7 +22,7 @@ int OpArith(int op)
|
|||
use=OpBase(op);
|
||||
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler
|
||||
|
||||
OpStart(op); Cycles=4;
|
||||
OpStart(op, sea|tea); Cycles=4;
|
||||
|
||||
EaCalc(10,0x0000, sea,size,1);
|
||||
EaRead(10, 10, sea,size,0,1);
|
||||
|
@ -94,7 +94,7 @@ int OpAddq(int op)
|
|||
if (num!=8) use|=0x0e00; // If num is not 8, use same handler
|
||||
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler
|
||||
|
||||
OpStart(op);
|
||||
OpStart(op,ea);
|
||||
Cycles=ea<8?4:8;
|
||||
if(type==0&&size==1) Cycles=ea<0x10?4:8;
|
||||
if(size>=2) Cycles=ea<0x10?8:12;
|
||||
|
@ -157,7 +157,7 @@ int OpArithReg(int op)
|
|||
use&=~0x0e00; // Use same opcode for Dn
|
||||
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler
|
||||
|
||||
OpStart(op); Cycles=4;
|
||||
OpStart(op,ea); Cycles=4;
|
||||
|
||||
ot(";@ Get r10=EA r11=EA value\n");
|
||||
EaCalc(10,0x003f, ea,size,1);
|
||||
|
@ -219,7 +219,7 @@ int OpMul(int op)
|
|||
use&=~0x0e00; // Use same for all registers
|
||||
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler
|
||||
|
||||
OpStart(op);
|
||||
OpStart(op,ea);
|
||||
if(type) Cycles=54;
|
||||
else Cycles=sign?158:140;
|
||||
|
||||
|
@ -370,7 +370,7 @@ int OpAbcd(int op)
|
|||
if (sea==0x27||dea==0x27) use=op; // ..except -(a7)
|
||||
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler
|
||||
|
||||
OpStart(op); Cycles=6;
|
||||
OpStart(op,sea|dea); Cycles=6;
|
||||
|
||||
EaCalc( 0,0x0007, sea,0,1);
|
||||
EaRead( 0, 10, sea,0,0x0007,1);
|
||||
|
@ -456,7 +456,7 @@ int OpNbcd(int op)
|
|||
use=OpBase(op);
|
||||
if(op!=use) { OpUse(op,use); return 0; } // Use existing handler
|
||||
|
||||
OpStart(op); Cycles=6;
|
||||
OpStart(op,ea); Cycles=6;
|
||||
if(ea >= 8) Cycles+=2;
|
||||
|
||||
EaCalc(10,0x3f, ea,0,1);
|
||||
|
@ -519,7 +519,7 @@ int OpAritha(int op)
|
|||
use&=~0x0e00; // Use same opcode for An
|
||||
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler
|
||||
|
||||
OpStart(op); Cycles=(size==2)?6:8;
|
||||
OpStart(op,sea); Cycles=(size==2)?6:8;
|
||||
if(size==2&&(sea<0x10||sea==0x3c)) Cycles+=2;
|
||||
if(type==1) Cycles=6;
|
||||
|
||||
|
@ -566,7 +566,7 @@ int OpAddx(int op)
|
|||
if (size==0&&(sea==0x27||dea==0x27)) use=op; // ___x.b -(a7)
|
||||
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler
|
||||
|
||||
OpStart(op); Cycles=4;
|
||||
OpStart(op,sea|dea); Cycles=4;
|
||||
if(size>=2) Cycles+=4;
|
||||
if(sea>=0x10) Cycles+=2;
|
||||
|
||||
|
@ -631,7 +631,7 @@ int OpCmpEor(int op)
|
|||
use&=~0x0e00; // Use 1 handler for register d0-7
|
||||
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler
|
||||
|
||||
OpStart(op); Cycles=4;
|
||||
OpStart(op,ea); Cycles=4;
|
||||
if(eor) {
|
||||
if(ea>8) Cycles+=4;
|
||||
if(size>=2) Cycles+=4;
|
||||
|
@ -678,7 +678,7 @@ int OpCmpm(int op)
|
|||
if (size==0&&(sea==0x1f||dea==0x1f)) use=op; // ..except (a7)+
|
||||
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler
|
||||
|
||||
OpStart(op); Cycles=4;
|
||||
OpStart(op,sea); Cycles=4;
|
||||
|
||||
ot(";@ Get src operand into r10:\n");
|
||||
EaCalc (0,0x000f, sea,size,1);
|
||||
|
@ -719,7 +719,7 @@ int OpChk(int op)
|
|||
use&=~0x0e00; // Use 1 handler for register d0-7
|
||||
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler
|
||||
|
||||
OpStart(op); Cycles=10;
|
||||
OpStart(op,ea); Cycles=10;
|
||||
|
||||
ot(";@ Get EA into r10 and value into r0:\n");
|
||||
EaCalc (10,0x003f, ea,size,1);
|
||||
|
|
|
@ -58,7 +58,9 @@ static void PopPc()
|
|||
MemHandler(0,2);
|
||||
ot(" add r4,r0,r10 ;@ r4=Memory Base+PC\n");
|
||||
ot("\n");
|
||||
#if USE_CHECKPC_CALLBACK
|
||||
CheckPc();
|
||||
#endif
|
||||
}
|
||||
|
||||
int OpTrap(int op)
|
||||
|
@ -68,7 +70,7 @@ int OpTrap(int op)
|
|||
use=op&~0xf;
|
||||
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler
|
||||
|
||||
OpStart(op);
|
||||
OpStart(op,0x10);
|
||||
ot(" and r0,r8,#0xf ;@ Get trap number\n");
|
||||
ot(" orr r0,r0,#0x20\n");
|
||||
ot(" mov r0,r0,asl #2\n");
|
||||
|
@ -90,7 +92,7 @@ int OpLink(int op)
|
|||
if (reg==7) use=op;
|
||||
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler
|
||||
|
||||
OpStart(op);
|
||||
OpStart(op,0x10);
|
||||
|
||||
if(reg!=7) {
|
||||
ot(";@ Get An\n");
|
||||
|
@ -132,7 +134,7 @@ int OpUnlk(int op)
|
|||
use=op&~7;
|
||||
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler
|
||||
|
||||
OpStart(op);
|
||||
OpStart(op,0x10);
|
||||
|
||||
ot(";@ Get An\n");
|
||||
EaCalc(10, 7, 8, 2, 1);
|
||||
|
@ -169,7 +171,7 @@ int Op4E70(int op)
|
|||
return 0;
|
||||
|
||||
case 3: // rte
|
||||
OpStart(op); Cycles=20;
|
||||
OpStart(op,0x10); Cycles=20;
|
||||
SuperCheck(op);
|
||||
PopSr(1);
|
||||
ot(" ldr r10,[r7,#0x60] ;@ Get Memory base\n");
|
||||
|
@ -181,14 +183,14 @@ int Op4E70(int op)
|
|||
return 0;
|
||||
|
||||
case 5: // rts
|
||||
OpStart(op); Cycles=16;
|
||||
OpStart(op,0x10); Cycles=16;
|
||||
ot(" ldr r10,[r7,#0x60] ;@ Get Memory base\n");
|
||||
PopPc();
|
||||
OpEnd();
|
||||
return 0;
|
||||
|
||||
case 6: // trapv
|
||||
OpStart(op); Cycles=4;
|
||||
OpStart(op,0x10); Cycles=4;
|
||||
ot(" tst r9,#0x10000000\n");
|
||||
ot(" subne r5,r5,#%i\n",30);
|
||||
ot(" movne r0,#0x1c ;@ TRAPV exception\n");
|
||||
|
@ -197,7 +199,7 @@ int Op4E70(int op)
|
|||
return 0;
|
||||
|
||||
case 7: // rtr
|
||||
OpStart(op); Cycles=20;
|
||||
OpStart(op,0x10); Cycles=20;
|
||||
PopSr(0);
|
||||
ot(" ldr r10,[r7,#0x60] ;@ Get Memory base\n");
|
||||
PopPc();
|
||||
|
@ -224,7 +226,7 @@ int OpJsr(int op)
|
|||
use=OpBase(op);
|
||||
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler
|
||||
|
||||
OpStart(op);
|
||||
OpStart(op,0x10);
|
||||
|
||||
ot(" ldr r10,[r7,#0x60] ;@ Get Memory base\n");
|
||||
ot("\n");
|
||||
|
@ -352,7 +354,7 @@ int OpBranch(int op)
|
|||
else use=(op&0xff00)+1; // Use same opcode for all 8-bit branches
|
||||
|
||||
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler
|
||||
OpStart(op);
|
||||
OpStart(op,size?0x10:0);
|
||||
|
||||
ot(";@ Get Branch offset:\n");
|
||||
if (size)
|
||||
|
|
|
@ -27,7 +27,7 @@ int OpBtstReg(int op)
|
|||
use&=~0x0e00; // Use same handler for all registers
|
||||
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler
|
||||
|
||||
OpStart(op);
|
||||
OpStart(op,tea);
|
||||
|
||||
if(type==1||type==3) {
|
||||
Cycles=8;
|
||||
|
@ -88,7 +88,7 @@ int OpBtstImm(int op)
|
|||
use=OpBase(op);
|
||||
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler
|
||||
|
||||
OpStart(op);
|
||||
OpStart(op,sea|tea);
|
||||
|
||||
ot(" mov r10,#1\n");
|
||||
ot("\n");
|
||||
|
@ -145,7 +145,7 @@ int OpNeg(int op)
|
|||
use=OpBase(op);
|
||||
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler
|
||||
|
||||
OpStart(op); Cycles=size<2?4:6;
|
||||
OpStart(op,ea); Cycles=size<2?4:6;
|
||||
if(ea >= 0x10) {
|
||||
Cycles*=2;
|
||||
#ifdef CYCLONE_FOR_GENESIS
|
||||
|
@ -254,7 +254,7 @@ int OpTst(int op)
|
|||
use=OpBase(op);
|
||||
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler
|
||||
|
||||
OpStart(op); Cycles=4;
|
||||
OpStart(op,sea); Cycles=4;
|
||||
|
||||
EaCalc ( 0,0x003f,sea,size,1);
|
||||
EaRead ( 0, 0,sea,size,0x003f,1);
|
||||
|
@ -322,7 +322,7 @@ int OpSet(int op)
|
|||
use=OpBase(op);
|
||||
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler
|
||||
|
||||
OpStart(op); Cycles=8;
|
||||
OpStart(op,ea); Cycles=8;
|
||||
if (ea<8) Cycles=4;
|
||||
|
||||
ot(" mov r1,#0\n");
|
||||
|
@ -619,7 +619,7 @@ int OpAsrEa(int op)
|
|||
use=OpBase(op);
|
||||
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler
|
||||
|
||||
OpStart(op); Cycles=6; // EmitAsr() will add 2
|
||||
OpStart(op,ea); Cycles=6; // EmitAsr() will add 2
|
||||
|
||||
EaCalc (10,0x003f,ea,size,1);
|
||||
EaRead (10, 0,ea,size,0x003f,1);
|
||||
|
@ -645,7 +645,7 @@ int OpTas(int op, int gen_special)
|
|||
use=OpBase(op);
|
||||
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler
|
||||
|
||||
if (!gen_special) OpStart(op);
|
||||
if (!gen_special) OpStart(op,ea);
|
||||
else
|
||||
ot("Op%.4x_%s\n", op, ms?"":":");
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@ int OpMove(int op)
|
|||
|
||||
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler
|
||||
|
||||
OpStart(op); Cycles=4;
|
||||
OpStart(op,sea|tea); Cycles=4;
|
||||
|
||||
EaCalc(0,0x003f,sea,size);
|
||||
EaRead(0, 1,sea,size,0x003f);
|
||||
|
@ -173,7 +173,7 @@ int OpLea(int op)
|
|||
use&=~0x0e00; // Also use 1 handler for target ?0-7
|
||||
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler
|
||||
|
||||
OpStart(op);
|
||||
OpStart(op,sea|tea);
|
||||
|
||||
EaCalc (1,0x003f,sea,0); // Lea
|
||||
EaCalc (0,0x0e00,tea,2,1);
|
||||
|
@ -215,7 +215,7 @@ int OpMoveSr(int op)
|
|||
use=OpBase(op);
|
||||
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler
|
||||
|
||||
OpStart(op);
|
||||
OpStart(op,ea);
|
||||
Cycles=12;
|
||||
if (type==0) Cycles=(ea>=8)?8:6;
|
||||
|
||||
|
@ -260,7 +260,7 @@ int OpArithSr(int op)
|
|||
use=OpBase(op);
|
||||
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler
|
||||
|
||||
OpStart(op); Cycles=16;
|
||||
OpStart(op,ea); Cycles=16;
|
||||
|
||||
if (size) SuperCheck(op);
|
||||
|
||||
|
@ -296,7 +296,7 @@ int OpPea(int op)
|
|||
use=OpBase(op);
|
||||
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler
|
||||
|
||||
OpStart(op);
|
||||
OpStart(op,ea);
|
||||
|
||||
ot(" ldr r10,[r7,#0x3c]\n");
|
||||
EaCalc (1,0x003f, ea,0);
|
||||
|
@ -339,7 +339,7 @@ int OpMovem(int op)
|
|||
use=OpBase(op);
|
||||
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler
|
||||
|
||||
OpStart(op);
|
||||
OpStart(op,ea);
|
||||
|
||||
ot(" stmdb sp!,{r9} ;@ Push r9\n"); // can't just use r12 or lr here, because memhandlers touch them
|
||||
ot(" ldrh r11,[r4],#2 ;@ r11=register mask\n");
|
||||
|
@ -519,7 +519,7 @@ int OpMovep(int op)
|
|||
// Find size extension
|
||||
if(op&0x0040) size=2;
|
||||
|
||||
OpStart(op);
|
||||
OpStart(op,ea);
|
||||
|
||||
if(dir) { // reg to mem
|
||||
EaCalc(11,0x0e00,0,size); // reg number -> r11
|
||||
|
|
|
@ -37,7 +37,7 @@ int MemHandler(int type,int size);
|
|||
// OpAny.cpp
|
||||
int OpGetFlags(int subtract,int xbit,int sprecialz=0);
|
||||
void OpUse(int op,int use);
|
||||
void OpStart(int op);
|
||||
void OpStart(int op,int ea=0);
|
||||
void OpEnd();
|
||||
int OpBase(int op,int sepa=0);
|
||||
void OpAny(int op);
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* Enable this option if you are going to use Cyclone to emulate Genesis /
|
||||
* Mega Drive system. As VDP chip in these systems had control of the bus,
|
||||
* several instructions were acting differently, for example TAS did'n have
|
||||
* the write-back phase. That will be emulated, if this option is enebled.
|
||||
* the write-back phase. That will be emulated, if this option is enabled.
|
||||
* This option also alters timing slightly.
|
||||
*/
|
||||
#define CYCLONE_FOR_GENESIS 1
|
||||
|
@ -29,14 +29,23 @@
|
|||
*/
|
||||
#define COMPRESS_JUMPTABLE 1
|
||||
|
||||
/*
|
||||
* Address mask for memory hadlers. The bits set will be masked out of address
|
||||
* parameter, which is passed to r/w memory handlers.
|
||||
* Using 0xff000000 means that only 24 least significant bits should be used.
|
||||
* Set to 0 if you want to mask unused address bits in the memory handlers yourself.
|
||||
*/
|
||||
#define MEMHANDLERS_ADDR_MASK 0xff000000
|
||||
|
||||
/*
|
||||
* Cyclone keeps the 4 least significant bits of SR, PC+membase and it's cycle
|
||||
* count in ARM registers instead of the context for performance reasons. If you for
|
||||
* any reason need to access them in your memory handlers, enable the options below,
|
||||
* otherwise disable them to improve performance.
|
||||
* Warning: the PC value will not point to start of instruction (it will be middle or
|
||||
* end), also updating PC is dangerous, as Cyclone may internally increment the PC
|
||||
* before fetching the next instruction and continue executing at wrong location.
|
||||
* PC value will point to start of instruction currently executed.
|
||||
* Warning: updating PC in memhandlers is dangerous, as Cyclone may internally
|
||||
* increment the PC before fetching the next instruction and continue executing
|
||||
* at wrong location.
|
||||
*/
|
||||
#define MEMHANDLERS_NEED_PC 0
|
||||
#define MEMHANDLERS_NEED_FLAGS 0
|
||||
|
@ -70,7 +79,7 @@
|
|||
* If enabled, UnrecognizedCallback is called if an invalid opcode is
|
||||
* encountered. All context members are valid and can be changed. The handler
|
||||
* should return zero if you want Cyclone to gererate "Illegal Instruction"
|
||||
* exception after this, or nonzero if not. In the later case you shuold change
|
||||
* exception after this, or nonzero if not. In the later case you should change
|
||||
* the PC by yourself, or else Cyclone will keep executing that opcode all over
|
||||
* again.
|
||||
* If disabled, "Illegal Instruction" exception is generated and execution is
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue