From a67855765d6106f3fd8737ec35c2165460d2705f Mon Sep 17 00:00:00 2001 From: notaz Date: Sun, 17 Jun 2007 12:24:13 +0000 Subject: [PATCH] adjustments for MAME git-svn-id: file:///home/notaz/opt/svn/PicoDrive@164 be3aeb3a-fb24-0410-a615-afba39da0efa --- cpu/Cyclone/Ea.cpp | 48 ++++++------- cpu/Cyclone/Main.cpp | 152 ++++++++++++++++++++------------------- cpu/Cyclone/OpAny.cpp | 14 +++- cpu/Cyclone/OpArith.cpp | 80 ++++++++++----------- cpu/Cyclone/OpBranch.cpp | 28 ++++---- cpu/Cyclone/OpLogic.cpp | 26 +++---- cpu/Cyclone/OpMove.cpp | 84 +++++++++++----------- cpu/Cyclone/app.h | 2 +- cpu/Cyclone/config.h | 21 ++++-- 9 files changed, 242 insertions(+), 213 deletions(-) diff --git a/cpu/Cyclone/Ea.cpp b/cpu/Cyclone/Ea.cpp index 32a8cf78..58faa469 100644 --- a/cpu/Cyclone/Ea.cpp +++ b/cpu/Cyclone/Ea.cpp @@ -72,17 +72,17 @@ int g_movem_cycle_table[8] = // add nonstandard EA int Ea_add_ns(int *tab, int ea) { - if(ea<0x10) return 0; - if((ea&0x38)==0x10) return tab[0]; // (An) (ai) - if(ea<0x28) return 0; - if(ea<0x30) return tab[1]; // ($nn,An) (di) - if(ea<0x38) return tab[2]; // ($nn,An,Rn) (ix) - if(ea==0x38) return tab[3]; // (aw) - if(ea==0x39) return tab[4]; // (al) - if(ea==0x3a) return tab[5]; // ($nn,PC) (pcdi) - if(ea==0x3b) return tab[6]; // ($nn,pc,Rn) (pcix) - if(ea==0x3c) return tab[7]; // #$nnnn (i) - return 0; + if(ea<0x10) return 0; + if((ea&0x38)==0x10) return tab[0]; // (An) (ai) + if(ea<0x28) return 0; + if(ea<0x30) return tab[1]; // ($nn,An) (di) + if(ea<0x38) return tab[2]; // ($nn,An,Rn) (ix) + if(ea==0x38) return tab[3]; // (aw) + if(ea==0x39) return tab[4]; // (al) + if(ea==0x3a) return tab[5]; // ($nn,PC) (pcdi) + if(ea==0x3b) return tab[6]; // ($nn,pc,Rn) (pcix) + if(ea==0x3c) return tab[7]; // #$nnnn (i) + return 0; } @@ -147,28 +147,28 @@ int EaCalc(int a,int mask,int ea,int size,int top) if (ea<0x28) { int step=1<>=1) low++; // Find out how high up the EA mask is - lsl=2-low; // Having a lsl #x here saves one opcode + lsl=2-low; // Having a lsl #x here saves one opcode if (lsl>=0) ot(" ldr r%d,[r7,r2,lsl #%i]\n",a,lsl); else if (lsl<0) ot(" ldr r%d,[r7,r2,lsr #%i]\n",a,-lsl); if ((ea&0x38)==0x18) // (An)+ - { + { ot(" add r3,r%d,#%d ;@ Post-increment An\n",a,step); - strr=3; - } + strr=3; + } if ((ea&0x38)==0x20) // -(An) ot(" sub r%d,r%d,#%d ;@ Pre-decrement An\n",a,a,step); if ((ea&0x38)==0x18||(ea&0x38)==0x20) - { + { if (lsl>=0) ot(" str r%d,[r7,r2,lsl #%i]\n",strr,lsl); else if (lsl<0) ot(" str r%d,[r7,r2,lsr #%i]\n",strr,-lsl); } @@ -292,10 +292,10 @@ int EaRead(int a,int v,int ea,int size,int mask,int top) { int lsl=0,low=0,i; if (size>=2||(size==0&&top)) { - if(mask) + if(mask) for (i=mask|0x8000; (i&1)==0; i>>=1) low++; // Find out how high up the EA mask is - lsl=2-low; // Having a lsl #2 here saves one opcode - } + lsl=2-low; // Having a lsl #2 here saves one opcode + } ot(";@ EaRead : Read register[r%d] into r%d:\n",a,v); @@ -369,10 +369,10 @@ int EaWrite(int a,int v,int ea,int size,int mask,int top) { int lsl=0,low=0,i; if (size>=2||(size==0&&top)) { - if(mask) + if(mask) for (i=mask|0x8000; (i&1)==0; i>>=1) low++; // Find out how high up the EA mask is - lsl=2-low; // Having a lsl #x here saves one opcode - } + lsl=2-low; // Having a lsl #x here saves one opcode + } ot(";@ EaWrite: r%d into register[r%d]:\n",v,a); if (shift) ot(" mov r%d,r%d,asr #%d\n",v,v,shift); diff --git a/cpu/Cyclone/Main.cpp b/cpu/Cyclone/Main.cpp index a85aebce..1d0318ca 100644 --- a/cpu/Cyclone/Main.cpp +++ b/cpu/Cyclone/Main.cpp @@ -216,7 +216,7 @@ static void PrintFramework() ot(" ldr r1,[r0,#-4]\n"); ot(" tst r1,r1\n"); ot(" movne pc,lr ;@ already uncompressed\n"); - ot(" add r3,r12,#0xa000*4 ;@ handler table pointer, r12=dest\n"); + ot(" add r3,r12,#0xa000*4 ;@ handler table pointer, r12=dest\n"); ot("unc_loop%s\n", ms?"":":"); ot(" ldrh r1,[r0],#2\n"); ot(" and r2,r1,#0xf\n"); @@ -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); @@ -541,84 +547,84 @@ static void PrintJumpTable() #if COMPRESS_JUMPTABLE int handlers=0,reps=0,*indexes,ip,u,out; // use some weird compression on the jump table - indexes=(int *)malloc(0x10000*4); - if(!indexes) { printf("ERROR: out of memory\n"); exit(1); } - len=0x10000; + indexes=(int *)malloc(0x10000*4); + if(!indexes) { printf("ERROR: out of memory\n"); exit(1); } + len=0x10000; - ot("CycloneJumpTab%s\n", ms?"":":"); - if(ms) { - for(i = 0; i < 0xa000/8; i++) - ot(" dcd 0,0,0,0,0,0,0,0\n"); - } else - ot(" .rept 0x%x\n .long 0,0,0,0,0,0,0,0\n .endr\n", 0xa000/8); + ot("CycloneJumpTab%s\n", ms?"":":"); + if(ms) { + for(i = 0; i < 0xa000/8; i++) + ot(" dcd 0,0,0,0,0,0,0,0\n"); + } else + ot(" .rept 0x%x\n .long 0,0,0,0,0,0,0,0\n .endr\n", 0xa000/8); // hanlers live in "a-line" part of the table - // first output nop,a-line,f-line handlers - ot(ms?" dcd Op____,Op__al,Op__fl,":" .long Op____,Op__al,Op__fl,"); - handlers=3; + // first output nop,a-line,f-line handlers + ot(ms?" dcd Op____,Op__al,Op__fl,":" .long Op____,Op__al,Op__fl,"); + handlers=3; - for(i=0;i=0; u--) if(op == CyJump[u]) break; // already done with this op? - if(u==-1 && op >= 0) { - ott("Op%.4x",op," ;@ %.4x\n",i,handlers,2); - indexes[op] = handlers; - handlers++; + for(u=i-1; u>=0; u--) if(op == CyJump[u]) break; // already done with this op? + if(u==-1 && op >= 0) { + ott("Op%.4x",op," ;@ %.4x\n",i,handlers,2); + indexes[op] = handlers; + handlers++; } - } - if(handlers&7) { - fseek(AsmFile, -1, SEEK_CUR); // remove last comma - for(i = 8-(handlers&7); i > 0; i--) - ot(",000000"); - ot("\n"); - } - if(ms) { - for(i = (0x4000-handlers)/8; i > 0; i--) - ot(" dcd 0,0,0,0,0,0,0,0\n"); - } else { - ot(ms?"":" .rept 0x%x\n .long 0,0,0,0,0,0,0,0\n .endr\n", (0x4000-handlers)/8); - } + } + if(handlers&7) { + fseek(AsmFile, -1, SEEK_CUR); // remove last comma + for(i = 8-(handlers&7); i > 0; i--) + ot(",000000"); + ot("\n"); + } + if(ms) { + for(i = (0x4000-handlers)/8; i > 0; i--) + ot(" dcd 0,0,0,0,0,0,0,0\n"); + } else { + ot(ms?"":" .rept 0x%x\n .long 0,0,0,0,0,0,0,0\n .endr\n", (0x4000-handlers)/8); + } printf("total distinct hanlers: %i\n",handlers); - // output data - for(i=0,ip=0; i < 0xf000; i++, ip++) { + // output data + for(i=0,ip=0; i < 0xf000; i++, ip++) { op=CyJump[i]; - if(op == -2) { - // it must skip a-line area, because we keep our data there - ott("0x%.4x", handlers<<4, "\n",0,ip++,1); - ott("0x%.4x", 0x1000, "\n",0,ip,1); - i+=0xfff; - continue; - } - for(reps=1; i < 0xf000; i++, reps++) if(op != CyJump[i+1]) break; - if(op>=0) out=indexes[op]<<4; else out=0; // unrecognised - if(reps <= 0xe || reps==0x10) { - if(reps!=0x10) out|=reps; else out|=0xf; // 0xf means 0x10 (0xf appeared to be unused anyway) - ott("0x%.4x", out, "\n",0,ip,1); + if(op == -2) { + // it must skip a-line area, because we keep our data there + ott("0x%.4x", handlers<<4, "\n",0,ip++,1); + ott("0x%.4x", 0x1000, "\n",0,ip,1); + i+=0xfff; + continue; + } + for(reps=1; i < 0xf000; i++, reps++) if(op != CyJump[i+1]) break; + if(op>=0) out=indexes[op]<<4; else out=0; // unrecognised + if(reps <= 0xe || reps==0x10) { + if(reps!=0x10) out|=reps; else out|=0xf; // 0xf means 0x10 (0xf appeared to be unused anyway) + ott("0x%.4x", out, "\n",0,ip,1); } else { - ott("0x%.4x", out, "\n",0,ip++,1); - ott("0x%.4x", reps,"\n",0,ip,1); - } + ott("0x%.4x", out, "\n",0,ip++,1); + ott("0x%.4x", reps,"\n",0,ip,1); + } } - if(ip&1) ott("0x%.4x", 0, "\n",0,ip++,1); - if(ip&7) fseek(AsmFile, -1, SEEK_CUR); // remove last comma - ot("\n"); - if(ip&7) { - for(i = 8-(ip&7); i > 0; i--) - ot(",0x0000"); - ot("\n"); - } - if(ms) { - for(i = (0x2000-ip/2)/8+1; i > 0; i--) - ot(" dcd 0,0,0,0,0,0,0,0\n"); - } else { - ot(" .rept 0x%x\n .long 0,0,0,0,0,0,0,0\n .endr\n", (0x2000-ip/2)/8+1); - } - ot("\n"); - free(indexes); + if(ip&1) ott("0x%.4x", 0, "\n",0,ip++,1); + if(ip&7) fseek(AsmFile, -1, SEEK_CUR); // remove last comma + ot("\n"); + if(ip&7) { + for(i = 8-(ip&7); i > 0; i--) + ot(",0x0000"); + ot("\n"); + } + if(ms) { + for(i = (0x2000-ip/2)/8+1; i > 0; i--) + ot(" dcd 0,0,0,0,0,0,0,0\n"); + } else { + ot(" .rept 0x%x\n .long 0,0,0,0,0,0,0,0\n .endr\n", (0x2000-ip/2)/8+1); + } + ot("\n"); + free(indexes); #else - ot("CycloneJumpTab%s\n", ms?"":":"); + ot("CycloneJumpTab%s\n", ms?"":":"); len=0xfffe; // Hmmm, armasm 2.50.8684 messes up with a 0x10000 long jump table // notaz: same thing with GNU as 2.9-psion-98r2 (reloc overflow) // this is due to COFF objects using only 2 bytes for reloc count @@ -632,7 +638,7 @@ static void PrintJumpTable() else if(op==-3) ott("Op__fl",0, " ;@ %.4x\n",i-7,i,2); else ott("Op____",0, " ;@ %.4x\n",i-7,i,2); } - if(i&7) fseek(AsmFile, -1, SEEK_CUR); // remove last comma + if(i&7) fseek(AsmFile, -1, SEEK_CUR); // remove last comma ot("\n"); ot(";@ notaz: we don't want to crash if we run into those 2 missing opcodes\n"); diff --git a/cpu/Cyclone/OpAny.cpp b/cpu/Cyclone/OpAny.cpp index 946ecba8..222db2bc 100644 --- a/cpu/Cyclone/OpAny.cpp +++ b/cpu/Cyclone/OpAny.cpp @@ -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() diff --git a/cpu/Cyclone/OpArith.cpp b/cpu/Cyclone/OpArith.cpp index 33cdf870..29b6cdf2 100644 --- a/cpu/Cyclone/OpArith.cpp +++ b/cpu/Cyclone/OpArith.cpp @@ -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); @@ -190,9 +190,9 @@ int OpArithReg(int op) if(size>=2) Cycles+=4; } else { if(size>=2) { - Cycles+=2; - if(ea<0x10||ea==0x3c) Cycles+=2; - } + Cycles+=2; + if(ea<0x10||ea==0x3c) Cycles+=2; + } } OpEnd(); @@ -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; @@ -249,10 +249,10 @@ int OpMul(int op) ot("\n"); } else - { + { ot(" mov r10,r10,lsl #16 ;@ use only 16 bits of divisor\n"); ot(" mov r10,r10,lsr #16\n"); - } + } ot(";@ Divide r2 by r10\n"); ot(" mov r3,#0\n"); @@ -277,7 +277,7 @@ int OpMul(int op) if (sign) { - // sign correction + // sign correction ot(" and r1,r11,#1\n"); ot(" teq r1,r11,lsr #1\n"); ot(" rsbne r3,r3,#0 ;@ negate if quotient is negative\n"); @@ -285,19 +285,19 @@ int OpMul(int op) ot(" rsbne r2,r2,#0 ;@ negate the remainder if divident was negative\n"); ot("\n"); - // signed overflow check - ot(" mov r1,r3,asl #16\n"); - ot(" cmp r3,r1,asr #16 ;@ signed overflow?\n"); + // signed overflow check + ot(" mov r1,r3,asl #16\n"); + ot(" cmp r3,r1,asr #16 ;@ signed overflow?\n"); ot(" orrne r9,r9,#0x10000000 ;@ set overflow flag\n"); ot(" bne endofop%.4x ;@ overflow!\n",op); } - else - { - // overflow check - ot(" movs r1,r3,lsr #16 ;@ check for overflow condition\n"); + else + { + // overflow check + ot(" movs r1,r3,lsr #16 ;@ check for overflow condition\n"); ot(" orrne r9,r9,#0x10000000 ;@ set overflow flag\n"); ot(" bne endofop%.4x ;@ overflow!\n",op); - } + } ot(" mov r1,r3,lsl #16 ;@ Clip to 16-bits\n"); ot(" adds r1,r1,#0 ;@ Defines NZ, clears CV\n"); @@ -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); @@ -384,7 +384,7 @@ int OpAbcd(int op) ot(" ldrb r0,[r7,#0x45] ;@ Get X bit\n"); ot(" mov r3,#0x00f00000\n"); ot(" and r2,r3,r1,lsr #4\n"); - ot(" tst r0,#2\n"); + ot(" tst r0,#2\n"); ot(" and r0,r3,r10,lsr #4\n"); ot(" add r0,r0,r2\n"); ot(" addne r0,r0,#0x00100000\n"); @@ -398,20 +398,20 @@ int OpAbcd(int op) ot(" mov r2,r10,lsr #28\n"); ot(" add r0,r0,r2,lsl #24\n"); ot(" cmp r0,#0x09900000\n"); - ot(" orrhi r9,r9,#0x20000000 ;@ C\n"); - ot(" subhi r0,r0,#0x0a000000\n"); -// ot(" and r3,r9,r0,lsr #3 ;@ Undefined V behavior part II\n"); -// ot(" orr r9,r9,r3,lsl #4 ;@ V\n"); + ot(" orrhi r9,r9,#0x20000000 ;@ C\n"); + ot(" subhi r0,r0,#0x0a000000\n"); +// ot(" and r3,r9,r0,lsr #3 ;@ Undefined V behavior part II\n"); +// ot(" orr r9,r9,r3,lsl #4 ;@ V\n"); ot(" movs r0,r0,lsl #4\n"); - ot(" orrmi r9,r9,#0x90000000 ;@ Undefined N+V behavior\n"); // this is what Musashi really does - ot(" bicne r9,r9,#0x40000000 ;@ Z flag\n"); + ot(" orrmi r9,r9,#0x90000000 ;@ Undefined N+V behavior\n"); // this is what Musashi really does + ot(" bicne r9,r9,#0x40000000 ;@ Z flag\n"); } else { ot(" ldrb r0,[r7,#0x45] ;@ Get X bit\n"); ot(" mov r3,#0x00f00000\n"); ot(" and r2,r3,r10,lsr #4\n"); - ot(" tst r0,#2\n"); + ot(" tst r0,#2\n"); ot(" and r0,r3,r1,lsr #4\n"); ot(" sub r0,r0,r2\n"); ot(" subne r0,r0,#0x00100000\n"); @@ -425,13 +425,13 @@ int OpAbcd(int op) ot(" mov r2,r10,lsr #28\n"); ot(" sub r0,r0,r2,lsl #24\n"); ot(" cmp r0,#0x09900000\n"); - ot(" orrhi r9,r9,#0xa0000000 ;@ N and C\n"); - ot(" addhi r0,r0,#0x0a000000\n"); -// ot(" and r3,r9,r0,lsr #3 ;@ Undefined V behavior part II\n"); -// ot(" orr r9,r9,r3,lsl #4 ;@ V\n"); + ot(" orrhi r9,r9,#0xa0000000 ;@ N and C\n"); + ot(" addhi r0,r0,#0x0a000000\n"); +// ot(" and r3,r9,r0,lsr #3 ;@ Undefined V behavior part II\n"); +// ot(" orr r9,r9,r3,lsl #4 ;@ V\n"); ot(" movs r0,r0,lsl #4\n"); -// ot(" orrmi r9,r9,#0x80000000 ;@ Undefined N behavior\n"); - ot(" bicne r9,r9,#0x40000000 ;@ Z flag\n"); +// ot(" orrmi r9,r9,#0x80000000 ;@ Undefined N behavior\n"); + ot(" bicne r9,r9,#0x40000000 ;@ Z flag\n"); } ot(" mov r2,r9,lsr #28\n"); @@ -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; @@ -583,7 +583,7 @@ int OpAddx(int op) if (type==5 && size<2) { ot(";@ Make sure the carry bit will tip the balance:\n"); - ot(" mvn r2,#0\n"); + ot(" mvn r2,#0\n"); ot(" orr r11,r11,r2,lsr #%i\n",(size==0)?8:16); ot("\n"); } @@ -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); diff --git a/cpu/Cyclone/OpBranch.cpp b/cpu/Cyclone/OpBranch.cpp index 71f97858..9cc57e93 100644 --- a/cpu/Cyclone/OpBranch.cpp +++ b/cpu/Cyclone/OpBranch.cpp @@ -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); @@ -168,27 +170,27 @@ int Op4E70(int op) OpEnd(); return 0; - case 3: // rte - OpStart(op); Cycles=20; - SuperCheck(op); + case 3: // rte + OpStart(op,0x10); Cycles=20; + SuperCheck(op); PopSr(1); ot(" ldr r10,[r7,#0x60] ;@ Get Memory base\n"); PopPc(); - SuperChange(op); + SuperChange(op); CheckInterrupt(op); OpEnd(); - SuperEnd(op); + SuperEnd(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) diff --git a/cpu/Cyclone/OpLogic.cpp b/cpu/Cyclone/OpLogic.cpp index d0eafecf..2a0c8195 100644 --- a/cpu/Cyclone/OpLogic.cpp +++ b/cpu/Cyclone/OpLogic.cpp @@ -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 @@ -170,10 +170,10 @@ int OpNeg(int op) ot(" orr r3,r9,#0xb0000000 ;@ for old Z\n"); OpGetFlags(1,1,0); if(size!=2) { - ot(" movs r1,r1,asr #%i\n",size?16:24); + ot(" movs r1,r1,asr #%i\n",size?16:24); ot(" orreq r9,r9,#0x40000000 ;@ possily missed Z\n"); - } - ot(" andeq r9,r9,r3 ;@ fix Z\n"); + } + ot(" andeq r9,r9,r3 ;@ fix Z\n"); ot("\n"); } @@ -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"); @@ -429,9 +429,9 @@ static int EmitAsr(int op,int type,int dir,int count,int size,int usereg) if(count == 1) { if(dir==0) { if(size!=2) { - ot(" orr r0,r0,r0,lsr #%i\n", size?16:24); - ot(" bic r0,r0,#0x%x\n", 1<<(32-wide)); - } + ot(" orr r0,r0,r0,lsr #%i\n", size?16:24); + ot(" bic r0,r0,#0x%x\n", 1<<(32-wide)); + } GetXBit(0); ot(" movs r0,r0,rrx\n"); OpGetFlags(0,1); @@ -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?"":":"); diff --git a/cpu/Cyclone/OpMove.cpp b/cpu/Cyclone/OpMove.cpp index 5d3459b9..33332871 100644 --- a/cpu/Cyclone/OpMove.cpp +++ b/cpu/Cyclone/OpMove.cpp @@ -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); @@ -207,7 +207,7 @@ int OpMoveSr(int op) case 1: return 1; // no such op in 68000 - case 2: case 3: + case 2: case 3: if (EaCanRead(ea,size)==0) return 1; // See if we can do this opcode: break; } @@ -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; @@ -234,9 +234,9 @@ int OpMoveSr(int op) EaRead(0, 0,ea,size,0x003f); OpRegToFlags(type==3); if (type==3) { - SuperChange(op); - CheckInterrupt(op); - } + SuperChange(op); + CheckInterrupt(op); + } } OpEnd(); @@ -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); @@ -273,7 +273,7 @@ int OpArithSr(int op) if (type==5) ot(" eor r0,r1,r10\n"); OpRegToFlags(size); if (size) { - SuperChange(op); + SuperChange(op); CheckInterrupt(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"); @@ -397,7 +397,7 @@ int OpMovem(int op) if(dir) { // er if (ea==0x3a) Cycles=16; // ($nn,PC) else if (ea==0x3b) Cycles=18; // ($nn,pc,Rn) - else Cycles=12; + else Cycles=12; } else { Cycles=8; } @@ -519,44 +519,44 @@ 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 EaRead(11,11,0,size,0x0e00); // regval -> r11 EaCalc(10,0x0007,ea,size); - if(size==2) { // if operand is long - ot(" mov r1,r11,lsr #24 ;@ first byte\n"); - EaWrite(10,1,ea,0,0x0007); // store first byte - ot(" add r10,r10,#2\n"); - ot(" mov r1,r11,lsr #16 ;@ second byte\n"); - EaWrite(10,1,ea,0,0x0007); // store second byte - ot(" add r10,r10,#2\n"); - } - ot(" mov r1,r11,lsr #8 ;@ first or third byte\n"); - EaWrite(10,1,ea,0,0x0007); - ot(" add r10,r10,#2\n"); - ot(" and r1,r11,#0xff\n"); - EaWrite(10,1,ea,0,0x0007); + if(size==2) { // if operand is long + ot(" mov r1,r11,lsr #24 ;@ first byte\n"); + EaWrite(10,1,ea,0,0x0007); // store first byte + ot(" add r10,r10,#2\n"); + ot(" mov r1,r11,lsr #16 ;@ second byte\n"); + EaWrite(10,1,ea,0,0x0007); // store second byte + ot(" add r10,r10,#2\n"); + } + ot(" mov r1,r11,lsr #8 ;@ first or third byte\n"); + EaWrite(10,1,ea,0,0x0007); + ot(" add r10,r10,#2\n"); + ot(" and r1,r11,#0xff\n"); + EaWrite(10,1,ea,0,0x0007); } else { // mem to reg EaCalc(10,0x0007,ea,size,1); EaRead(10,11,ea,0,0x0007,1); // read first byte - ot(" add r10,r10,#2\n"); + ot(" add r10,r10,#2\n"); EaRead(10,1,ea,0,0x0007,1); // read second byte - if(size==2) { // if operand is long + if(size==2) { // if operand is long ot(" orr r11,r11,r1,lsr #8 ;@ second byte\n"); - ot(" add r10,r10,#2\n"); - EaRead(10,1,ea,0,0x0007,1); + ot(" add r10,r10,#2\n"); + EaRead(10,1,ea,0,0x0007,1); ot(" orr r11,r11,r1,lsr #16 ;@ third byte\n"); - ot(" add r10,r10,#2\n"); - EaRead(10,1,ea,0,0x0007,1); + ot(" add r10,r10,#2\n"); + EaRead(10,1,ea,0,0x0007,1); ot(" orr r0,r11,r1,lsr #24 ;@ fourth byte\n"); - } else { + } else { ot(" orr r0,r11,r1,lsr #8 ;@ second byte\n"); - } - // store the result + } + // store the result EaCalc(11,0x0e00,0,size,1); // reg number -> r11 - EaWrite(11,0,0,size,0x0e00,1); + EaWrite(11,0,0,size,0x0e00,1); } Cycles=(size==2)?24:16; @@ -580,15 +580,15 @@ int OpStopReset(int op) SuperChange(op); OpRegToFlags(1); - ot("\n"); + ot("\n"); - ot(" mov r0,#1\n"); - ot(" str r0,[r7,#0x58] ;@ stopped\n"); - ot("\n"); + ot(" mov r0,#1\n"); + ot(" str r0,[r7,#0x58] ;@ stopped\n"); + ot("\n"); - ot(" mov r5,#0 ;@ eat cycles\n"); + ot(" mov r5,#0 ;@ eat cycles\n"); Cycles = 4; - ot("\n"); + ot("\n"); } else { diff --git a/cpu/Cyclone/app.h b/cpu/Cyclone/app.h index e8fb2128..589131f1 100644 --- a/cpu/Cyclone/app.h +++ b/cpu/Cyclone/app.h @@ -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); diff --git a/cpu/Cyclone/config.h b/cpu/Cyclone/config.h index bcea68d2..ded00b1e 100644 --- a/cpu/Cyclone/config.h +++ b/cpu/Cyclone/config.h @@ -15,10 +15,10 @@ * 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 +#define CYCLONE_FOR_GENESIS 1 /* * This option compresses Cyclone's jumptable. Because of this the executable @@ -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 -- 2.39.5