// add nonstandard EA\r
int Ea_add_ns(int *tab, int ea)\r
{\r
- if(ea<0x10) return 0;\r
- if((ea&0x38)==0x10) return tab[0]; // (An) (ai)\r
- if(ea<0x28) return 0;\r
- if(ea<0x30) return tab[1]; // ($nn,An) (di)\r
- if(ea<0x38) return tab[2]; // ($nn,An,Rn) (ix)\r
- if(ea==0x38) return tab[3]; // (aw)\r
- if(ea==0x39) return tab[4]; // (al)\r
- if(ea==0x3a) return tab[5]; // ($nn,PC) (pcdi)\r
- if(ea==0x3b) return tab[6]; // ($nn,pc,Rn) (pcix)\r
- if(ea==0x3c) return tab[7]; // #$nnnn (i)\r
- return 0;\r
+ if(ea<0x10) return 0;\r
+ if((ea&0x38)==0x10) return tab[0]; // (An) (ai)\r
+ if(ea<0x28) return 0;\r
+ if(ea<0x30) return tab[1]; // ($nn,An) (di)\r
+ if(ea<0x38) return tab[2]; // ($nn,An,Rn) (ix)\r
+ if(ea==0x38) return tab[3]; // (aw)\r
+ if(ea==0x39) return tab[4]; // (al)\r
+ if(ea==0x3a) return tab[5]; // ($nn,PC) (pcdi)\r
+ if(ea==0x3b) return tab[6]; // ($nn,pc,Rn) (pcix)\r
+ if(ea==0x3c) return tab[7]; // #$nnnn (i)\r
+ return 0;\r
}\r
\r
\r
if (ea<0x28)\r
{\r
int step=1<<size, strr=a;\r
- int low=0,lsl,i;\r
+ int low=0,lsl,i;\r
\r
if ((ea&7)==7 && step<2) step=2; // move.b (a7)+ or -(a7) steps by 2 not 1\r
\r
EaCalcReg(2,ea,mask,0,0,1);\r
- if(mask)\r
+ if(mask)\r
for (i=mask|0x8000; (i&1)==0; i>>=1) low++; // Find out how high up the EA mask is\r
- lsl=2-low; // Having a lsl #x here saves one opcode\r
+ lsl=2-low; // Having a lsl #x here saves one opcode\r
if (lsl>=0) ot(" ldr r%d,[r7,r2,lsl #%i]\n",a,lsl);\r
else if (lsl<0) ot(" ldr r%d,[r7,r2,lsr #%i]\n",a,-lsl);\r
\r
if ((ea&0x38)==0x18) // (An)+\r
- {\r
+ {\r
ot(" add r3,r%d,#%d ;@ Post-increment An\n",a,step);\r
- strr=3;\r
- }\r
+ strr=3;\r
+ }\r
\r
if ((ea&0x38)==0x20) // -(An)\r
ot(" sub r%d,r%d,#%d ;@ Pre-decrement An\n",a,a,step);\r
\r
if ((ea&0x38)==0x18||(ea&0x38)==0x20)\r
- {\r
+ {\r
if (lsl>=0) ot(" str r%d,[r7,r2,lsl #%i]\n",strr,lsl);\r
else if (lsl<0) ot(" str r%d,[r7,r2,lsr #%i]\n",strr,-lsl);\r
}\r
{\r
int lsl=0,low=0,i;\r
if (size>=2||(size==0&&top)) {\r
- if(mask)\r
+ if(mask)\r
for (i=mask|0x8000; (i&1)==0; i>>=1) low++; // Find out how high up the EA mask is\r
- lsl=2-low; // Having a lsl #2 here saves one opcode\r
- }\r
+ lsl=2-low; // Having a lsl #2 here saves one opcode\r
+ }\r
\r
ot(";@ EaRead : Read register[r%d] into r%d:\n",a,v);\r
\r
{\r
int lsl=0,low=0,i;\r
if (size>=2||(size==0&&top)) {\r
- if(mask)\r
+ if(mask)\r
for (i=mask|0x8000; (i&1)==0; i>>=1) low++; // Find out how high up the EA mask is\r
- lsl=2-low; // Having a lsl #x here saves one opcode\r
- }\r
+ lsl=2-low; // Having a lsl #x here saves one opcode\r
+ }\r
\r
ot(";@ EaWrite: r%d into register[r%d]:\n",v,a);\r
if (shift) ot(" mov r%d,r%d,asr #%d\n",v,v,shift);\r
ot(" ldr r1,[r0,#-4]\n");\r
ot(" tst r1,r1\n");\r
ot(" movne pc,lr ;@ already uncompressed\n");\r
- ot(" add r3,r12,#0xa000*4 ;@ handler table pointer, r12=dest\n");\r
+ ot(" add r3,r12,#0xa000*4 ;@ handler table pointer, r12=dest\n");\r
ot("unc_loop%s\n", ms?"":":");\r
ot(" ldrh r1,[r0],#2\n");\r
ot(" and r2,r1,#0xf\n");\r
int func=0;\r
func=0x68+type*0xc+(size<<2); // Find correct offset\r
\r
-#if MEMHANDLERS_NEED_PC\r
- ot(" str r4,[r7,#0x40] ;@ Save PC\n");\r
-#endif\r
#if MEMHANDLERS_NEED_FLAGS\r
ot(" mov r3,r9,lsr #28\n");\r
ot(" strb r3,[r7,#0x46] ;@ Save Flags (NZCV)\n");\r
#endif\r
-#if MEMHANDLERS_NEED_CYCLES\r
- ot(" str r5,[r7,#0x5c] ;@ Save Cycles\n");\r
-#endif\r
\r
+#if (MEMHANDLERS_ADDR_MASK & 0xff000000)\r
+ ot(" bic r0,r0,#0x%08x\n", MEMHANDLERS_ADDR_MASK & 0xff000000);\r
+#endif\r
+#if (MEMHANDLERS_ADDR_MASK & 0x00ff0000)\r
+ ot(" bic r0,r0,#0x%08x\n", MEMHANDLERS_ADDR_MASK & 0x00ff0000);\r
+#endif\r
+#if (MEMHANDLERS_ADDR_MASK & 0x0000ff00)\r
+ ot(" bic r0,r0,#0x%08x\n", MEMHANDLERS_ADDR_MASK & 0x0000ff00);\r
+#endif\r
+#if (MEMHANDLERS_ADDR_MASK & 0x000000ff)\r
+ ot(" bic r0,r0,#0x%08x\n", MEMHANDLERS_ADDR_MASK & 0x000000ff);\r
+#endif\r
ot(" mov lr,pc\n");\r
ot(" ldr pc,[r7,#0x%x] ;@ Call ",func);\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
- indexes=(int *)malloc(0x10000*4);\r
- if(!indexes) { printf("ERROR: out of memory\n"); exit(1); }\r
- len=0x10000;\r
+ indexes=(int *)malloc(0x10000*4);\r
+ if(!indexes) { printf("ERROR: out of memory\n"); exit(1); }\r
+ len=0x10000;\r
\r
- ot("CycloneJumpTab%s\n", ms?"":":");\r
- if(ms) {\r
- for(i = 0; i < 0xa000/8; i++)\r
- ot(" dcd 0,0,0,0,0,0,0,0\n");\r
- } else\r
- ot(" .rept 0x%x\n .long 0,0,0,0,0,0,0,0\n .endr\n", 0xa000/8);\r
+ ot("CycloneJumpTab%s\n", ms?"":":");\r
+ if(ms) {\r
+ for(i = 0; i < 0xa000/8; i++)\r
+ ot(" dcd 0,0,0,0,0,0,0,0\n");\r
+ } else\r
+ ot(" .rept 0x%x\n .long 0,0,0,0,0,0,0,0\n .endr\n", 0xa000/8);\r
\r
// hanlers live in "a-line" part of the table\r
- // first output nop,a-line,f-line handlers\r
- ot(ms?" dcd Op____,Op__al,Op__fl,":" .long Op____,Op__al,Op__fl,");\r
- handlers=3;\r
+ // first output nop,a-line,f-line handlers\r
+ ot(ms?" dcd Op____,Op__al,Op__fl,":" .long Op____,Op__al,Op__fl,");\r
+ handlers=3;\r
\r
- for(i=0;i<len;i++)\r
+ for(i=0;i<len;i++)\r
{\r
op=CyJump[i];\r
\r
- for(u=i-1; u>=0; u--) if(op == CyJump[u]) break; // already done with this op?\r
- if(u==-1 && op >= 0) {\r
- ott("Op%.4x",op," ;@ %.4x\n",i,handlers,2);\r
- indexes[op] = handlers;\r
- handlers++;\r
+ for(u=i-1; u>=0; u--) if(op == CyJump[u]) break; // already done with this op?\r
+ if(u==-1 && op >= 0) {\r
+ ott("Op%.4x",op," ;@ %.4x\n",i,handlers,2);\r
+ indexes[op] = handlers;\r
+ handlers++;\r
}\r
- }\r
- if(handlers&7) {\r
- fseek(AsmFile, -1, SEEK_CUR); // remove last comma\r
- for(i = 8-(handlers&7); i > 0; i--)\r
- ot(",000000");\r
- ot("\n");\r
- }\r
- if(ms) {\r
- for(i = (0x4000-handlers)/8; i > 0; i--)\r
- ot(" dcd 0,0,0,0,0,0,0,0\n");\r
- } else {\r
- ot(ms?"":" .rept 0x%x\n .long 0,0,0,0,0,0,0,0\n .endr\n", (0x4000-handlers)/8);\r
- }\r
+ }\r
+ if(handlers&7) {\r
+ fseek(AsmFile, -1, SEEK_CUR); // remove last comma\r
+ for(i = 8-(handlers&7); i > 0; i--)\r
+ ot(",000000");\r
+ ot("\n");\r
+ }\r
+ if(ms) {\r
+ for(i = (0x4000-handlers)/8; i > 0; i--)\r
+ ot(" dcd 0,0,0,0,0,0,0,0\n");\r
+ } else {\r
+ ot(ms?"":" .rept 0x%x\n .long 0,0,0,0,0,0,0,0\n .endr\n", (0x4000-handlers)/8);\r
+ }\r
printf("total distinct hanlers: %i\n",handlers);\r
- // output data\r
- for(i=0,ip=0; i < 0xf000; i++, ip++) {\r
+ // output data\r
+ for(i=0,ip=0; i < 0xf000; i++, ip++) {\r
op=CyJump[i];\r
- if(op == -2) {\r
- // it must skip a-line area, because we keep our data there\r
- ott("0x%.4x", handlers<<4, "\n",0,ip++,1);\r
- ott("0x%.4x", 0x1000, "\n",0,ip,1);\r
- i+=0xfff;\r
- continue;\r
- }\r
- for(reps=1; i < 0xf000; i++, reps++) if(op != CyJump[i+1]) break;\r
- if(op>=0) out=indexes[op]<<4; else out=0; // unrecognised\r
- if(reps <= 0xe || reps==0x10) {\r
- if(reps!=0x10) out|=reps; else out|=0xf; // 0xf means 0x10 (0xf appeared to be unused anyway)\r
- ott("0x%.4x", out, "\n",0,ip,1);\r
+ if(op == -2) {\r
+ // it must skip a-line area, because we keep our data there\r
+ ott("0x%.4x", handlers<<4, "\n",0,ip++,1);\r
+ ott("0x%.4x", 0x1000, "\n",0,ip,1);\r
+ i+=0xfff;\r
+ continue;\r
+ }\r
+ for(reps=1; i < 0xf000; i++, reps++) if(op != CyJump[i+1]) break;\r
+ if(op>=0) out=indexes[op]<<4; else out=0; // unrecognised\r
+ if(reps <= 0xe || reps==0x10) {\r
+ if(reps!=0x10) out|=reps; else out|=0xf; // 0xf means 0x10 (0xf appeared to be unused anyway)\r
+ ott("0x%.4x", out, "\n",0,ip,1);\r
} else {\r
- ott("0x%.4x", out, "\n",0,ip++,1);\r
- ott("0x%.4x", reps,"\n",0,ip,1);\r
- }\r
+ ott("0x%.4x", out, "\n",0,ip++,1);\r
+ ott("0x%.4x", reps,"\n",0,ip,1);\r
+ }\r
}\r
- if(ip&1) ott("0x%.4x", 0, "\n",0,ip++,1);\r
- if(ip&7) fseek(AsmFile, -1, SEEK_CUR); // remove last comma\r
- ot("\n");\r
- if(ip&7) {\r
- for(i = 8-(ip&7); i > 0; i--)\r
- ot(",0x0000");\r
- ot("\n");\r
- }\r
- if(ms) {\r
- for(i = (0x2000-ip/2)/8+1; i > 0; i--)\r
- ot(" dcd 0,0,0,0,0,0,0,0\n");\r
- } else {\r
- ot(" .rept 0x%x\n .long 0,0,0,0,0,0,0,0\n .endr\n", (0x2000-ip/2)/8+1);\r
- }\r
- ot("\n");\r
- free(indexes);\r
+ if(ip&1) ott("0x%.4x", 0, "\n",0,ip++,1);\r
+ if(ip&7) fseek(AsmFile, -1, SEEK_CUR); // remove last comma\r
+ ot("\n");\r
+ if(ip&7) {\r
+ for(i = 8-(ip&7); i > 0; i--)\r
+ ot(",0x0000");\r
+ ot("\n");\r
+ }\r
+ if(ms) {\r
+ for(i = (0x2000-ip/2)/8+1; i > 0; i--)\r
+ ot(" dcd 0,0,0,0,0,0,0,0\n");\r
+ } else {\r
+ ot(" .rept 0x%x\n .long 0,0,0,0,0,0,0,0\n .endr\n", (0x2000-ip/2)/8+1);\r
+ }\r
+ ot("\n");\r
+ free(indexes);\r
#else\r
- ot("CycloneJumpTab%s\n", ms?"":":");\r
+ ot("CycloneJumpTab%s\n", ms?"":":");\r
len=0xfffe; // Hmmm, armasm 2.50.8684 messes up with a 0x10000 long jump table\r
// notaz: same thing with GNU as 2.9-psion-98r2 (reloc overflow)\r
// this is due to COFF objects using only 2 bytes for reloc count\r
else if(op==-3) ott("Op__fl",0, " ;@ %.4x\n",i-7,i,2);\r
else ott("Op____",0, " ;@ %.4x\n",i-7,i,2);\r
}\r
- if(i&7) fseek(AsmFile, -1, SEEK_CUR); // remove last comma\r
+ if(i&7) fseek(AsmFile, -1, SEEK_CUR); // remove last comma\r
\r
ot("\n");\r
ot(";@ notaz: we don't want to crash if we run into those 2 missing opcodes\n");\r
ot(";@ ---------- [%.4x] %s uses Op%.4x ----------\n",op,text,use);\r
}\r
\r
-void OpStart(int op)\r
+void OpStart(int op, int ea)\r
{\r
Cycles=0;\r
OpUse(op,op); // This opcode obviously uses this handler\r
ot("Op%.4x%s\n", op, ms?"":":");\r
+#if (MEMHANDLERS_NEED_PC || MEMHANDLERS_NEED_CYCLES)\r
+ if (ea >= 0x10) {\r
+#if MEMHANDLERS_NEED_PC\r
+ ot(" sub r0,r4,#2\n");\r
+ ot(" str r0,[r7,#0x40] ;@ Save PC\n");\r
+#endif\r
+#if MEMHANDLERS_NEED_CYCLES\r
+ ot(" str r5,[r7,#0x5c] ;@ Save Cycles\n");\r
+#endif\r
+ ot("\n");\r
+ }\r
+#endif\r
}\r
\r
void OpEnd()\r
use=OpBase(op);\r
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
\r
- OpStart(op); Cycles=4;\r
+ OpStart(op, sea|tea); Cycles=4;\r
\r
EaCalc(10,0x0000, sea,size,1);\r
EaRead(10, 10, sea,size,0,1);\r
if (num!=8) use|=0x0e00; // If num is not 8, use same handler\r
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
\r
- OpStart(op);\r
+ OpStart(op,ea);\r
Cycles=ea<8?4:8;\r
if(type==0&&size==1) Cycles=ea<0x10?4:8;\r
if(size>=2) Cycles=ea<0x10?8:12;\r
use&=~0x0e00; // Use same opcode for Dn\r
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
\r
- OpStart(op); Cycles=4;\r
+ OpStart(op,ea); Cycles=4;\r
\r
ot(";@ Get r10=EA r11=EA value\n");\r
EaCalc(10,0x003f, ea,size,1);\r
if(size>=2) Cycles+=4;\r
} else {\r
if(size>=2) {\r
- Cycles+=2;\r
- if(ea<0x10||ea==0x3c) Cycles+=2;\r
- }\r
+ Cycles+=2;\r
+ if(ea<0x10||ea==0x3c) Cycles+=2;\r
+ }\r
}\r
\r
OpEnd();\r
use&=~0x0e00; // Use same for all registers\r
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
\r
- OpStart(op);\r
+ OpStart(op,ea);\r
if(type) Cycles=54;\r
else Cycles=sign?158:140;\r
\r
ot("\n");\r
}\r
else\r
- {\r
+ {\r
ot(" mov r10,r10,lsl #16 ;@ use only 16 bits of divisor\n");\r
ot(" mov r10,r10,lsr #16\n");\r
- }\r
+ }\r
\r
ot(";@ Divide r2 by r10\n");\r
ot(" mov r3,#0\n");\r
\r
if (sign)\r
{\r
- // sign correction\r
+ // sign correction\r
ot(" and r1,r11,#1\n");\r
ot(" teq r1,r11,lsr #1\n");\r
ot(" rsbne r3,r3,#0 ;@ negate if quotient is negative\n");\r
ot(" rsbne r2,r2,#0 ;@ negate the remainder if divident was negative\n");\r
ot("\n");\r
\r
- // signed overflow check\r
- ot(" mov r1,r3,asl #16\n");\r
- ot(" cmp r3,r1,asr #16 ;@ signed overflow?\n");\r
+ // signed overflow check\r
+ ot(" mov r1,r3,asl #16\n");\r
+ ot(" cmp r3,r1,asr #16 ;@ signed overflow?\n");\r
ot(" orrne r9,r9,#0x10000000 ;@ set overflow flag\n");\r
ot(" bne endofop%.4x ;@ overflow!\n",op);\r
}\r
- else\r
- {\r
- // overflow check\r
- ot(" movs r1,r3,lsr #16 ;@ check for overflow condition\n");\r
+ else\r
+ {\r
+ // overflow check\r
+ ot(" movs r1,r3,lsr #16 ;@ check for overflow condition\n");\r
ot(" orrne r9,r9,#0x10000000 ;@ set overflow flag\n");\r
ot(" bne endofop%.4x ;@ overflow!\n",op);\r
- }\r
+ }\r
\r
ot(" mov r1,r3,lsl #16 ;@ Clip to 16-bits\n");\r
ot(" adds r1,r1,#0 ;@ Defines NZ, clears CV\n");\r
if (sea==0x27||dea==0x27) use=op; // ..except -(a7)\r
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
\r
- OpStart(op); Cycles=6;\r
+ OpStart(op,sea|dea); Cycles=6;\r
\r
EaCalc( 0,0x0007, sea,0,1);\r
EaRead( 0, 10, sea,0,0x0007,1);\r
ot(" ldrb r0,[r7,#0x45] ;@ Get X bit\n");\r
ot(" mov r3,#0x00f00000\n");\r
ot(" and r2,r3,r1,lsr #4\n");\r
- ot(" tst r0,#2\n");\r
+ ot(" tst r0,#2\n");\r
ot(" and r0,r3,r10,lsr #4\n");\r
ot(" add r0,r0,r2\n");\r
ot(" addne r0,r0,#0x00100000\n");\r
ot(" mov r2,r10,lsr #28\n");\r
ot(" add r0,r0,r2,lsl #24\n");\r
ot(" cmp r0,#0x09900000\n");\r
- ot(" orrhi r9,r9,#0x20000000 ;@ C\n");\r
- ot(" subhi r0,r0,#0x0a000000\n");\r
-// ot(" and r3,r9,r0,lsr #3 ;@ Undefined V behavior part II\n");\r
-// ot(" orr r9,r9,r3,lsl #4 ;@ V\n");\r
+ ot(" orrhi r9,r9,#0x20000000 ;@ C\n");\r
+ ot(" subhi r0,r0,#0x0a000000\n");\r
+// ot(" and r3,r9,r0,lsr #3 ;@ Undefined V behavior part II\n");\r
+// ot(" orr r9,r9,r3,lsl #4 ;@ V\n");\r
ot(" movs r0,r0,lsl #4\n");\r
- ot(" orrmi r9,r9,#0x90000000 ;@ Undefined N+V behavior\n"); // this is what Musashi really does\r
- ot(" bicne r9,r9,#0x40000000 ;@ Z flag\n");\r
+ ot(" orrmi r9,r9,#0x90000000 ;@ Undefined N+V behavior\n"); // this is what Musashi really does\r
+ ot(" bicne r9,r9,#0x40000000 ;@ Z flag\n");\r
}\r
else\r
{\r
ot(" ldrb r0,[r7,#0x45] ;@ Get X bit\n");\r
ot(" mov r3,#0x00f00000\n");\r
ot(" and r2,r3,r10,lsr #4\n");\r
- ot(" tst r0,#2\n");\r
+ ot(" tst r0,#2\n");\r
ot(" and r0,r3,r1,lsr #4\n");\r
ot(" sub r0,r0,r2\n");\r
ot(" subne r0,r0,#0x00100000\n");\r
ot(" mov r2,r10,lsr #28\n");\r
ot(" sub r0,r0,r2,lsl #24\n");\r
ot(" cmp r0,#0x09900000\n");\r
- ot(" orrhi r9,r9,#0xa0000000 ;@ N and C\n");\r
- ot(" addhi r0,r0,#0x0a000000\n");\r
-// ot(" and r3,r9,r0,lsr #3 ;@ Undefined V behavior part II\n");\r
-// ot(" orr r9,r9,r3,lsl #4 ;@ V\n");\r
+ ot(" orrhi r9,r9,#0xa0000000 ;@ N and C\n");\r
+ ot(" addhi r0,r0,#0x0a000000\n");\r
+// ot(" and r3,r9,r0,lsr #3 ;@ Undefined V behavior part II\n");\r
+// ot(" orr r9,r9,r3,lsl #4 ;@ V\n");\r
ot(" movs r0,r0,lsl #4\n");\r
-// ot(" orrmi r9,r9,#0x80000000 ;@ Undefined N behavior\n");\r
- ot(" bicne r9,r9,#0x40000000 ;@ Z flag\n");\r
+// ot(" orrmi r9,r9,#0x80000000 ;@ Undefined N behavior\n");\r
+ ot(" bicne r9,r9,#0x40000000 ;@ Z flag\n");\r
}\r
\r
ot(" mov r2,r9,lsr #28\n");\r
use=OpBase(op);\r
if(op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
\r
- OpStart(op); Cycles=6;\r
+ OpStart(op,ea); Cycles=6;\r
if(ea >= 8) Cycles+=2;\r
\r
EaCalc(10,0x3f, ea,0,1);\r
use&=~0x0e00; // Use same opcode for An\r
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
\r
- OpStart(op); Cycles=(size==2)?6:8;\r
+ OpStart(op,sea); Cycles=(size==2)?6:8;\r
if(size==2&&(sea<0x10||sea==0x3c)) Cycles+=2;\r
if(type==1) Cycles=6;\r
\r
if (size==0&&(sea==0x27||dea==0x27)) use=op; // ___x.b -(a7)\r
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
\r
- OpStart(op); Cycles=4;\r
+ OpStart(op,sea|dea); Cycles=4;\r
if(size>=2) Cycles+=4;\r
if(sea>=0x10) Cycles+=2;\r
\r
if (type==5 && size<2)\r
{\r
ot(";@ Make sure the carry bit will tip the balance:\n");\r
- ot(" mvn r2,#0\n");\r
+ ot(" mvn r2,#0\n");\r
ot(" orr r11,r11,r2,lsr #%i\n",(size==0)?8:16);\r
ot("\n");\r
}\r
use&=~0x0e00; // Use 1 handler for register d0-7\r
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
\r
- OpStart(op); Cycles=4;\r
+ OpStart(op,ea); Cycles=4;\r
if(eor) {\r
if(ea>8) Cycles+=4;\r
if(size>=2) Cycles+=4;\r
if (size==0&&(sea==0x1f||dea==0x1f)) use=op; // ..except (a7)+\r
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
\r
- OpStart(op); Cycles=4;\r
+ OpStart(op,sea); Cycles=4;\r
\r
ot(";@ Get src operand into r10:\n");\r
EaCalc (0,0x000f, sea,size,1);\r
use&=~0x0e00; // Use 1 handler for register d0-7\r
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
\r
- OpStart(op); Cycles=10;\r
+ OpStart(op,ea); Cycles=10;\r
\r
ot(";@ Get EA into r10 and value into r0:\n");\r
EaCalc (10,0x003f, ea,size,1);\r
MemHandler(0,2);\r
ot(" add r4,r0,r10 ;@ r4=Memory Base+PC\n");\r
ot("\n");\r
+#if USE_CHECKPC_CALLBACK\r
CheckPc();\r
+#endif\r
}\r
\r
int OpTrap(int op)\r
use=op&~0xf;\r
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
\r
- OpStart(op);\r
+ OpStart(op,0x10);\r
ot(" and r0,r8,#0xf ;@ Get trap number\n");\r
ot(" orr r0,r0,#0x20\n");\r
ot(" mov r0,r0,asl #2\n");\r
if (reg==7) use=op;\r
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
\r
- OpStart(op);\r
+ OpStart(op,0x10);\r
\r
if(reg!=7) {\r
ot(";@ Get An\n");\r
use=op&~7;\r
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
\r
- OpStart(op);\r
+ OpStart(op,0x10);\r
\r
ot(";@ Get An\n");\r
EaCalc(10, 7, 8, 2, 1);\r
OpEnd();\r
return 0;\r
\r
- case 3: // rte\r
- OpStart(op); Cycles=20;\r
- SuperCheck(op);\r
+ case 3: // rte\r
+ OpStart(op,0x10); Cycles=20;\r
+ SuperCheck(op);\r
PopSr(1);\r
ot(" ldr r10,[r7,#0x60] ;@ Get Memory base\n");\r
PopPc();\r
- SuperChange(op);\r
+ SuperChange(op);\r
CheckInterrupt(op);\r
OpEnd();\r
- SuperEnd(op);\r
+ SuperEnd(op);\r
return 0;\r
\r
case 5: // rts\r
- OpStart(op); Cycles=16;\r
+ OpStart(op,0x10); Cycles=16;\r
ot(" ldr r10,[r7,#0x60] ;@ Get Memory base\n");\r
PopPc();\r
OpEnd();\r
return 0;\r
\r
case 6: // trapv\r
- OpStart(op); Cycles=4;\r
+ OpStart(op,0x10); Cycles=4;\r
ot(" tst r9,#0x10000000\n");\r
ot(" subne r5,r5,#%i\n",30);\r
ot(" movne r0,#0x1c ;@ TRAPV exception\n");\r
return 0;\r
\r
case 7: // rtr\r
- OpStart(op); Cycles=20;\r
+ OpStart(op,0x10); Cycles=20;\r
PopSr(0);\r
ot(" ldr r10,[r7,#0x60] ;@ Get Memory base\n");\r
PopPc();\r
use=OpBase(op);\r
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
\r
- OpStart(op);\r
+ OpStart(op,0x10);\r
\r
ot(" ldr r10,[r7,#0x60] ;@ Get Memory base\n");\r
ot("\n");\r
else use=(op&0xff00)+1; // Use same opcode for all 8-bit branches\r
\r
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
- OpStart(op);\r
+ OpStart(op,size?0x10:0);\r
\r
ot(";@ Get Branch offset:\n");\r
if (size) \r
use&=~0x0e00; // Use same handler for all registers\r
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
\r
- OpStart(op);\r
+ OpStart(op,tea);\r
\r
if(type==1||type==3) {\r
Cycles=8;\r
use=OpBase(op);\r
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
\r
- OpStart(op);\r
+ OpStart(op,sea|tea);\r
\r
ot(" mov r10,#1\n");\r
ot("\n");\r
use=OpBase(op);\r
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
\r
- OpStart(op); Cycles=size<2?4:6;\r
+ OpStart(op,ea); Cycles=size<2?4:6;\r
if(ea >= 0x10) {\r
Cycles*=2;\r
#ifdef CYCLONE_FOR_GENESIS\r
ot(" orr r3,r9,#0xb0000000 ;@ for old Z\n");\r
OpGetFlags(1,1,0);\r
if(size!=2) {\r
- ot(" movs r1,r1,asr #%i\n",size?16:24);\r
+ ot(" movs r1,r1,asr #%i\n",size?16:24);\r
ot(" orreq r9,r9,#0x40000000 ;@ possily missed Z\n");\r
- }\r
- ot(" andeq r9,r9,r3 ;@ fix Z\n");\r
+ }\r
+ ot(" andeq r9,r9,r3 ;@ fix Z\n");\r
ot("\n");\r
}\r
\r
use=OpBase(op);\r
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
\r
- OpStart(op); Cycles=4;\r
+ OpStart(op,sea); Cycles=4;\r
\r
EaCalc ( 0,0x003f,sea,size,1);\r
EaRead ( 0, 0,sea,size,0x003f,1);\r
use=OpBase(op);\r
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
\r
- OpStart(op); Cycles=8;\r
+ OpStart(op,ea); Cycles=8;\r
if (ea<8) Cycles=4;\r
\r
ot(" mov r1,#0\n");\r
if(count == 1) {\r
if(dir==0) {\r
if(size!=2) {\r
- ot(" orr r0,r0,r0,lsr #%i\n", size?16:24);\r
- ot(" bic r0,r0,#0x%x\n", 1<<(32-wide));\r
- }\r
+ ot(" orr r0,r0,r0,lsr #%i\n", size?16:24);\r
+ ot(" bic r0,r0,#0x%x\n", 1<<(32-wide));\r
+ }\r
GetXBit(0);\r
ot(" movs r0,r0,rrx\n");\r
OpGetFlags(0,1);\r
use=OpBase(op);\r
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
\r
- OpStart(op); Cycles=6; // EmitAsr() will add 2\r
+ OpStart(op,ea); Cycles=6; // EmitAsr() will add 2\r
\r
EaCalc (10,0x003f,ea,size,1);\r
EaRead (10, 0,ea,size,0x003f,1);\r
use=OpBase(op);\r
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
\r
- if (!gen_special) OpStart(op);\r
+ if (!gen_special) OpStart(op,ea);\r
else\r
ot("Op%.4x_%s\n", op, ms?"":":");\r
\r
\r
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
\r
- OpStart(op); Cycles=4;\r
+ OpStart(op,sea|tea); Cycles=4;\r
\r
EaCalc(0,0x003f,sea,size);\r
EaRead(0, 1,sea,size,0x003f);\r
use&=~0x0e00; // Also use 1 handler for target ?0-7\r
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
\r
- OpStart(op);\r
+ OpStart(op,sea|tea);\r
\r
EaCalc (1,0x003f,sea,0); // Lea\r
EaCalc (0,0x0e00,tea,2,1);\r
case 1:\r
return 1; // no such op in 68000\r
\r
- case 2: case 3:\r
+ case 2: case 3:\r
if (EaCanRead(ea,size)==0) return 1; // See if we can do this opcode:\r
break;\r
}\r
use=OpBase(op);\r
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
\r
- OpStart(op);\r
+ OpStart(op,ea);\r
Cycles=12;\r
if (type==0) Cycles=(ea>=8)?8:6;\r
\r
EaRead(0, 0,ea,size,0x003f);\r
OpRegToFlags(type==3);\r
if (type==3) {\r
- SuperChange(op);\r
- CheckInterrupt(op);\r
- }\r
+ SuperChange(op);\r
+ CheckInterrupt(op);\r
+ }\r
}\r
\r
OpEnd();\r
use=OpBase(op);\r
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
\r
- OpStart(op); Cycles=16;\r
+ OpStart(op,ea); Cycles=16;\r
\r
if (size) SuperCheck(op);\r
\r
if (type==5) ot(" eor r0,r1,r10\n");\r
OpRegToFlags(size);\r
if (size) {\r
- SuperChange(op);\r
+ SuperChange(op);\r
CheckInterrupt(op);\r
}\r
\r
use=OpBase(op);\r
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
\r
- OpStart(op);\r
+ OpStart(op,ea);\r
\r
ot(" ldr r10,[r7,#0x3c]\n");\r
EaCalc (1,0x003f, ea,0);\r
use=OpBase(op);\r
if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
\r
- OpStart(op);\r
+ OpStart(op,ea);\r
\r
ot(" stmdb sp!,{r9} ;@ Push r9\n"); // can't just use r12 or lr here, because memhandlers touch them\r
ot(" ldrh r11,[r4],#2 ;@ r11=register mask\n");\r
if(dir) { // er\r
if (ea==0x3a) Cycles=16; // ($nn,PC)\r
else if (ea==0x3b) Cycles=18; // ($nn,pc,Rn)\r
- else Cycles=12;\r
+ else Cycles=12;\r
} else {\r
Cycles=8;\r
}\r
// Find size extension\r
if(op&0x0040) size=2;\r
\r
- OpStart(op);\r
+ OpStart(op,ea);\r
\r
if(dir) { // reg to mem\r
EaCalc(11,0x0e00,0,size); // reg number -> r11\r
EaRead(11,11,0,size,0x0e00); // regval -> r11\r
EaCalc(10,0x0007,ea,size);\r
- if(size==2) { // if operand is long\r
- ot(" mov r1,r11,lsr #24 ;@ first byte\n");\r
- EaWrite(10,1,ea,0,0x0007); // store first byte\r
- ot(" add r10,r10,#2\n");\r
- ot(" mov r1,r11,lsr #16 ;@ second byte\n");\r
- EaWrite(10,1,ea,0,0x0007); // store second byte\r
- ot(" add r10,r10,#2\n");\r
- }\r
- ot(" mov r1,r11,lsr #8 ;@ first or third byte\n");\r
- EaWrite(10,1,ea,0,0x0007);\r
- ot(" add r10,r10,#2\n");\r
- ot(" and r1,r11,#0xff\n");\r
- EaWrite(10,1,ea,0,0x0007);\r
+ if(size==2) { // if operand is long\r
+ ot(" mov r1,r11,lsr #24 ;@ first byte\n");\r
+ EaWrite(10,1,ea,0,0x0007); // store first byte\r
+ ot(" add r10,r10,#2\n");\r
+ ot(" mov r1,r11,lsr #16 ;@ second byte\n");\r
+ EaWrite(10,1,ea,0,0x0007); // store second byte\r
+ ot(" add r10,r10,#2\n");\r
+ }\r
+ ot(" mov r1,r11,lsr #8 ;@ first or third byte\n");\r
+ EaWrite(10,1,ea,0,0x0007);\r
+ ot(" add r10,r10,#2\n");\r
+ ot(" and r1,r11,#0xff\n");\r
+ EaWrite(10,1,ea,0,0x0007);\r
} else { // mem to reg\r
EaCalc(10,0x0007,ea,size,1);\r
EaRead(10,11,ea,0,0x0007,1); // read first byte\r
- ot(" add r10,r10,#2\n");\r
+ ot(" add r10,r10,#2\n");\r
EaRead(10,1,ea,0,0x0007,1); // read second byte\r
- if(size==2) { // if operand is long\r
+ if(size==2) { // if operand is long\r
ot(" orr r11,r11,r1,lsr #8 ;@ second byte\n");\r
- ot(" add r10,r10,#2\n");\r
- EaRead(10,1,ea,0,0x0007,1);\r
+ ot(" add r10,r10,#2\n");\r
+ EaRead(10,1,ea,0,0x0007,1);\r
ot(" orr r11,r11,r1,lsr #16 ;@ third byte\n");\r
- ot(" add r10,r10,#2\n");\r
- EaRead(10,1,ea,0,0x0007,1);\r
+ ot(" add r10,r10,#2\n");\r
+ EaRead(10,1,ea,0,0x0007,1);\r
ot(" orr r0,r11,r1,lsr #24 ;@ fourth byte\n");\r
- } else {\r
+ } else {\r
ot(" orr r0,r11,r1,lsr #8 ;@ second byte\n");\r
- }\r
- // store the result\r
+ }\r
+ // store the result\r
EaCalc(11,0x0e00,0,size,1); // reg number -> r11\r
- EaWrite(11,0,0,size,0x0e00,1);\r
+ EaWrite(11,0,0,size,0x0e00,1);\r
}\r
\r
Cycles=(size==2)?24:16;\r
SuperChange(op);\r
OpRegToFlags(1);\r
\r
- ot("\n");\r
+ ot("\n");\r
\r
- ot(" mov r0,#1\n");\r
- ot(" str r0,[r7,#0x58] ;@ stopped\n");\r
- ot("\n");\r
+ ot(" mov r0,#1\n");\r
+ ot(" str r0,[r7,#0x58] ;@ stopped\n");\r
+ ot("\n");\r
\r
- ot(" mov r5,#0 ;@ eat cycles\n");\r
+ ot(" mov r5,#0 ;@ eat cycles\n");\r
Cycles = 4;\r
- ot("\n");\r
+ ot("\n");\r
}\r
else\r
{\r
// OpAny.cpp\r
int OpGetFlags(int subtract,int xbit,int sprecialz=0);\r
void OpUse(int op,int use);\r
-void OpStart(int op);\r
+void OpStart(int op,int ea=0);\r
void OpEnd();\r
int OpBase(int op,int sepa=0);\r
void OpAny(int op);\r
* Enable this option if you are going to use Cyclone to emulate Genesis /\r
* Mega Drive system. As VDP chip in these systems had control of the bus,\r
* several instructions were acting differently, for example TAS did'n have\r
- * the write-back phase. That will be emulated, if this option is enebled.\r
+ * the write-back phase. That will be emulated, if this option is enabled.\r
* This option also alters timing slightly.\r
*/\r
-#define CYCLONE_FOR_GENESIS 1\r
+#define CYCLONE_FOR_GENESIS 1\r
\r
/*\r
* This option compresses Cyclone's jumptable. Because of this the executable\r
*/\r
#define COMPRESS_JUMPTABLE 1\r
\r
+/*\r
+ * Address mask for memory hadlers. The bits set will be masked out of address\r
+ * parameter, which is passed to r/w memory handlers.\r
+ * Using 0xff000000 means that only 24 least significant bits should be used.\r
+ * Set to 0 if you want to mask unused address bits in the memory handlers yourself.\r
+ */\r
+#define MEMHANDLERS_ADDR_MASK 0xff000000\r
+\r
/*\r
* Cyclone keeps the 4 least significant bits of SR, PC+membase and it's cycle\r
* count in ARM registers instead of the context for performance reasons. If you for\r
* any reason need to access them in your memory handlers, enable the options below,\r
* otherwise disable them to improve performance.\r
- * Warning: the PC value will not point to start of instruction (it will be middle or\r
- * end), also updating PC is dangerous, as Cyclone may internally increment the PC\r
- * before fetching the next instruction and continue executing at wrong location.\r
+ * PC value will point to start of instruction currently executed.\r
+ * Warning: updating PC in memhandlers is dangerous, as Cyclone may internally\r
+ * increment the PC before fetching the next instruction and continue executing\r
+ * at wrong location.\r
*/\r
#define MEMHANDLERS_NEED_PC 0\r
#define MEMHANDLERS_NEED_FLAGS 0\r
* If enabled, UnrecognizedCallback is called if an invalid opcode is\r
* encountered. All context members are valid and can be changed. The handler\r
* should return zero if you want Cyclone to gererate "Illegal Instruction"\r
- * exception after this, or nonzero if not. In the later case you shuold change\r
+ * exception after this, or nonzero if not. In the later case you should change\r
* the PC by yourself, or else Cyclone will keep executing that opcode all over\r
* again.\r
* If disabled, "Illegal Instruction" exception is generated and execution is\r