fixed mp3 buffer overlapping of GP2X sound buffer
[picodrive.git] / cpu / Cyclone / OpMove.cpp
CommitLineData
cc68a136 1\r
2#include "app.h"\r
3\r
4\r
5// Pack our flags into r1, in SR/CCR register format\r
6// trashes r0,r2\r
7void OpFlagsToReg(int high)\r
8{\r
9 ot(" ldrb r0,[r7,#0x45] ;@ X bit\n");\r
10 ot(" mov r1,r9,lsr #28 ;@ ____NZCV\n");\r
11 ot(" eor r2,r1,r1,ror #1 ;@ Bit 0=C^V\n");\r
12 ot(" tst r2,#1 ;@ 1 if C!=V\n");\r
13 ot(" eorne r1,r1,#3 ;@ ____NZVC\n");\r
14 ot("\n");\r
15 if (high) ot(" ldrb r2,[r7,#0x44] ;@ Include SR high\n");\r
16 ot(" and r0,r0,#0x02\n");\r
17 ot(" orr r1,r1,r0,lsl #3 ;@ ___XNZVC\n");\r
18 if (high) ot(" orr r1,r1,r2,lsl #8\n");\r
19 ot("\n");\r
20}\r
21\r
22// Convert SR/CRR register in r0 to our flags\r
23// trashes r0,r1\r
24void OpRegToFlags(int high)\r
25{\r
26 ot(" eor r1,r0,r0,ror #1 ;@ Bit 0=C^V\n");\r
27 ot(" mov r2,r0,lsr #3 ;@ r2=___XN\n");\r
28 ot(" tst r1,#1 ;@ 1 if C!=V\n");\r
29 ot(" eorne r0,r0,#3 ;@ ___XNZCV\n");\r
30 ot(" strb r2,[r7,#0x45] ;@ Store X bit\n");\r
31 ot(" mov r9,r0,lsl #28 ;@ r9=NZCV...\n");\r
32\r
33 if (high)\r
34 {\r
35 ot(" mov r0,r0,ror #8\n");\r
36 ot(" and r0,r0,#0xa7 ;@ only take defined bits\n");\r
37 ot(" strb r0,[r7,#0x44] ;@ Store SR high\n");\r
38 }\r
39 ot("\n");\r
40}\r
41\r
42// checks for supervisor bit, if not set, jumps to SuperEnd()\r
43// also sets r11 to SR high value, SuperChange() uses this\r
44void SuperCheck(int op)\r
45{\r
46 ot(" ldr r11,[r7,#0x44] ;@ Get SR high\n");\r
47 ot(" tst r11,#0x20 ;@ Check we are in supervisor mode\n");\r
48 ot(" beq WrongMode%.4x ;@ No\n",op);\r
49 ot("\n");\r
50}\r
51\r
52void SuperEnd(int op)\r
53{\r
54 ot("WrongMode%.4x%s\n",op,ms?"":":");\r
55 ot(" sub r4,r4,#2 ;@ this opcode wasn't executed - go back\n");\r
56 ot(" mov r0,#0x20 ;@ privilege violation\n");\r
57 ot(" bl Exception\n");\r
58 Cycles=34;\r
59 OpEnd();\r
60}\r
61\r
62// does OSP and A7 swapping if needed\r
63// new or old SR (not the one already in [r7,#0x44]) should be passed in r11\r
64// trashes r1,r11\r
65void SuperChange(int op)\r
66{\r
67 ot(";@ A7 <-> OSP?\n");\r
68 ot(" ldr r1,[r7,#0x44] ;@ Get other SR high\n");\r
69 ot(" and r11,r11,#0x20\n");\r
70 ot(" and r1,r1,#0x20\n");\r
71 ot(" teq r11,r1 ;@ r11 xor r1\n");\r
72 ot(" beq no_sp_swap%.4x\n",op);\r
73 ot(" ;@ swap OSP and A7:\n");\r
74 ot(" ldr r11,[r7,#0x3C] ;@ Get A7\n");\r
75 ot(" ldr r1, [r7,#0x48] ;@ Get OSP\n");\r
76 ot(" str r11,[r7,#0x48]\n");\r
77 ot(" str r1, [r7,#0x3C]\n");\r
78 ot("no_sp_swap%.4x%s\n", op, ms?"":":");\r
79}\r
80\r
81\r
82\r
83// --------------------- Opcodes 0x1000+ ---------------------\r
84// Emit a Move opcode, 00xxdddd ddssssss\r
85int OpMove(int op)\r
86{\r
87 int sea=0,tea=0;\r
88 int size=0,use=0;\r
89 int movea=0;\r
90\r
91 // Get source and target EA\r
92 sea = op&0x003f;\r
93 tea =(op&0x01c0)>>3;\r
94 tea|=(op&0x0e00)>>9;\r
95\r
96 if (tea>=8 && tea<0x10) movea=1;\r
97\r
98 // Find size extension\r
99 switch (op&0x3000)\r
100 {\r
101 default: return 1;\r
102 case 0x1000: size=0; break;\r
103 case 0x3000: size=1; break;\r
104 case 0x2000: size=2; break;\r
105 }\r
106\r
107 if (size<1 && (movea || EaAn(sea))) return 1; // move.b An,* and movea.b * are invalid\r
108\r
109 // See if we can do this opcode:\r
110 if (EaCanRead (sea,size)==0) return 1;\r
111 if (EaCanWrite(tea )==0) return 1;\r
112\r
113 use=OpBase(op);\r
114 if (tea<0x38) use&=~0x0e00; // Use same handler for register ?0-7\r
115 \r
116 if (tea>=0x18 && tea<0x28 && (tea&7)==7) use|=0x0e00; // Specific handler for (a7)+ and -(a7)\r
117\r
118 if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
119\r
120 OpStart(op); Cycles=4;\r
121\r
122 EaCalc(0,0x003f,sea,size);\r
123 EaRead(0, 1,sea,size,0x003f);\r
124\r
125 if (movea==0) {\r
126 ot(" adds r1,r1,#0 ;@ Defines NZ, clears CV\n");\r
127 ot(" mrs r9,cpsr ;@ r9=NZCV flags\n");\r
128 ot("\n");\r
129 }\r
130\r
131 if (movea) size=2; // movea always expands to 32-bits\r
132\r
133 EaCalc (0,0x0e00,tea,size);\r
134#if SPLIT_MOVEL_PD\r
135 if ((tea&0x38)==0x20 && size==2) { // -(An)\r
136 ot(" mov r10,r0\n");\r
137 ot(" mov r11,r1\n");\r
138 ot(" add r0,r0,#2\n");\r
139 EaWrite(0, 1,tea,1,0x0e00);\r
140 EaWrite(10, 11,tea,1,0x0e00,1);\r
141 } else {\r
142 EaWrite(0, 1,tea,size,0x0e00);\r
143 }\r
144#else\r
145 EaWrite(0, 1,tea,size,0x0e00);\r
146#endif\r
147\r
148#if CYCLONE_FOR_GENESIS && !MEMHANDLERS_CHANGE_CYCLES\r
149 // this is a bit hacky\r
150 if ((tea==0x39||(tea&0x38)==0x10)&&size>=1)\r
151 ot(" ldr r5,[r7,#0x5c] ;@ Load Cycles\n");\r
152#endif\r
153\r
154 if((tea&0x38)==0x20) Cycles-=2; // less cycles when dest is -(An)\r
155\r
156 OpEnd();\r
157 return 0;\r
158}\r
159\r
160// --------------------- Opcodes 0x41c0+ ---------------------\r
161// Emit an Lea opcode, 0100nnn1 11aaaaaa\r
162int OpLea(int op)\r
163{\r
164 int use=0;\r
165 int sea=0,tea=0;\r
166\r
167 sea= op&0x003f;\r
168 tea=(op&0x0e00)>>9; tea|=8;\r
169\r
170 if (EaCanRead(sea,-1)==0) return 1; // See if we can do this opcode\r
171\r
172 use=OpBase(op);\r
173 use&=~0x0e00; // Also use 1 handler for target ?0-7\r
174 if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
175\r
176 OpStart(op);\r
177\r
178 EaCalc (1,0x003f,sea,0); // Lea\r
179 EaCalc (0,0x0e00,tea,2,1);\r
180 EaWrite(0, 1,tea,2,0x0e00,1);\r
181\r
182 Cycles=Ea_add_ns(g_lea_cycle_table,sea);\r
183\r
184 OpEnd();\r
185\r
186 return 0;\r
187}\r
188\r
189// --------------------- Opcodes 0x40c0+ ---------------------\r
190// Move SR opcode, 01000tt0 11aaaaaa move SR\r
191int OpMoveSr(int op)\r
192{\r
193 int type=0,ea=0;\r
194 int use=0,size=1;\r
195\r
196 type=(op>>9)&3; // from SR, from CCR, to CCR, to SR\r
197 ea=op&0x3f;\r
198\r
199 if(EaAn(ea)) return 1; // can't use An regs\r
200\r
201 switch(type)\r
202 {\r
203 case 0:\r
204 if (EaCanWrite(ea)==0) return 1; // See if we can do this opcode:\r
205 break;\r
206\r
207 case 1:\r
208 return 1; // no such op in 68000\r
209\r
210 case 2: case 3:\r
211 if (EaCanRead(ea,size)==0) return 1; // See if we can do this opcode:\r
212 break;\r
213 }\r
214\r
215 use=OpBase(op);\r
216 if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
217\r
218 OpStart(op);\r
219 Cycles=12;\r
220 if (type==0) Cycles=(ea>=8)?8:6;\r
221\r
222 if (type==3) SuperCheck(op); // 68000 model allows reading whole SR in user mode (but newer models don't)\r
223\r
224 if (type==0 || type==1)\r
225 {\r
226 OpFlagsToReg(type==0);\r
227 EaCalc (0,0x003f,ea,size);\r
228 EaWrite(0, 1,ea,size,0x003f);\r
229 }\r
230\r
231 if (type==2 || type==3)\r
232 {\r
233 EaCalc(0,0x003f,ea,size);\r
234 EaRead(0, 0,ea,size,0x003f);\r
235 OpRegToFlags(type==3);\r
236 if (type==3) {\r
237 SuperChange(op);\r
238 CheckInterrupt(op);\r
239 }\r
240 }\r
241\r
242 OpEnd();\r
243\r
244 if (type==3) SuperEnd(op);\r
245\r
246 return 0;\r
247}\r
248\r
249\r
250// Ori/Andi/Eori $nnnn,sr 0000t0t0 01111100\r
251int OpArithSr(int op)\r
252{\r
253 int type=0,ea=0;\r
254 int use=0,size=0;\r
255\r
256 type=(op>>9)&5; if (type==4) return 1;\r
257 size=(op>>6)&1; // ccr or sr?\r
258 ea=0x3c;\r
259\r
260 use=OpBase(op);\r
261 if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
262\r
263 OpStart(op); Cycles=16;\r
264\r
265 if (size) SuperCheck(op);\r
266\r
267 EaCalc(0,0x003f,ea,size);\r
268 EaRead(0, 10,ea,size,0x003f);\r
269\r
270 OpFlagsToReg(size);\r
271 if (type==0) ot(" orr r0,r1,r10\n");\r
272 if (type==1) ot(" and r0,r1,r10\n");\r
273 if (type==5) ot(" eor r0,r1,r10\n");\r
274 OpRegToFlags(size);\r
275 if (size) {\r
276 SuperChange(op);\r
277 CheckInterrupt(op);\r
278 }\r
279\r
280 OpEnd();\r
281 if (size) SuperEnd(op);\r
282\r
283 return 0;\r
284}\r
285\r
286// --------------------- Opcodes 0x4850+ ---------------------\r
287// Emit an Pea opcode, 01001000 01aaaaaa\r
288int OpPea(int op)\r
289{\r
290 int use=0;\r
291 int ea=0;\r
292\r
293 ea=op&0x003f; if (ea<0x10) return 1; // Swap opcode\r
294 if (EaCanRead(ea,-1)==0) return 1; // See if we can do this opcode:\r
295\r
296 use=OpBase(op);\r
297 if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
298\r
299 OpStart(op);\r
300\r
301 ot(" ldr r10,[r7,#0x3c]\n");\r
302 EaCalc (1,0x003f, ea,0);\r
303 ot("\n");\r
304 ot(" sub r0,r10,#4 ;@ Predecrement A7\n");\r
305 ot(" str r0,[r7,#0x3c] ;@ Save A7\n");\r
306 ot("\n");\r
307 MemHandler(1,2); // Write 32-bit\r
308 ot("\n");\r
309\r
310 Cycles=6+Ea_add_ns(g_pea_cycle_table,ea);\r
311\r
312 OpEnd();\r
313\r
314 return 0;\r
315}\r
316\r
317// --------------------- Opcodes 0x4880+ ---------------------\r
318// Emit a Movem opcode, 01001d00 1xeeeeee regmask\r
319int OpMovem(int op)\r
320{\r
321 int size=0,ea=0,cea=0,dir=0;\r
322 int use=0,decr=0,change=0;\r
323\r
324 size=((op>>6)&1)+1; // word, long\r
325 ea=op&0x003f;\r
326 dir=(op>>10)&1; // Direction (1==ea2reg)\r
327\r
328 if (dir) {\r
329 if (ea<0x10 || ea>0x3b || (ea&0x38)==0x20) return 1; // Invalid EA\r
330 } else {\r
331 if (ea<0x10 || ea>0x39 || (ea&0x38)==0x18) return 1;\r
332 }\r
333\r
334 if ((ea&0x38)==0x18 || (ea&0x38)==0x20) change=1;\r
335 if ((ea&0x38)==0x20) decr=1; // -(An), bitfield is decr\r
336\r
337 cea=ea; if (change) cea=0x10;\r
338\r
339 use=OpBase(op);\r
340 if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
341\r
342 OpStart(op);\r
343\r
344 ot(" stmdb sp!,{r9} ;@ Push r9\n"); // can't just use r12 or lr here, because memhandlers touch them\r
345 ot(" ldrh r11,[r4],#2 ;@ r11=register mask\n");\r
346\r
347 ot("\n");\r
348 ot(";@ Get the address into r9:\n");\r
349 EaCalc(9,0x003f,cea,size);\r
350\r
351 ot(";@ r10=Register Index*4:\n");\r
352 if (decr) ot(" mov r10,#0x3c ;@ order reversed for -(An)\n");\r
353 else ot(" mov r10,#0\n");\r
354 \r
355 ot("\n");\r
356 ot("MoreReg%.4x%s\n",op, ms?"":":");\r
357\r
358 ot(" tst r11,#1\n");\r
359 ot(" beq SkipReg%.4x\n",op);\r
360 ot("\n");\r
361\r
362 if (decr) ot(" sub r9,r9,#%d ;@ Pre-decrement address\n",1<<size);\r
363\r
364 if (dir)\r
365 {\r
366 ot(" ;@ Copy memory to register:\n",1<<size);\r
367 EaRead (9,0,ea,size,0x003f);\r
368 ot(" str r0,[r7,r10] ;@ Save value into Dn/An\n");\r
369 }\r
370 else\r
371 {\r
372 ot(" ;@ Copy register to memory:\n",1<<size);\r
373 ot(" ldr r1,[r7,r10] ;@ Load value from Dn/An\n");\r
374 EaWrite(9,1,ea,size,0x003f);\r
375 }\r
376\r
377 if (decr==0) ot(" add r9,r9,#%d ;@ Post-increment address\n",1<<size);\r
378\r
379 ot(" sub r5,r5,#%d ;@ Take some cycles\n",2<<size);\r
380 ot("\n");\r
381 ot("SkipReg%.4x%s\n",op, ms?"":":");\r
382 ot(" movs r11,r11,lsr #1;@ Shift mask:\n");\r
383 ot(" add r10,r10,#%d ;@ r10=Next Register\n",decr?-4:4);\r
384 ot(" bne MoreReg%.4x\n",op);\r
385 ot("\n");\r
386\r
387 if (change)\r
388 {\r
389 ot(";@ Write back address:\n");\r
390 EaCalc (0,0x0007,8|(ea&7),2);\r
391 EaWrite(0, 9,8|(ea&7),2,0x0007);\r
392 }\r
393\r
394 ot(" ldmia sp!,{r9} ;@ Pop r9\n");\r
395 ot("\n");\r
396\r
397 if(dir) { // er\r
398 if (ea==0x3a) Cycles=16; // ($nn,PC)\r
399 else if (ea==0x3b) Cycles=18; // ($nn,pc,Rn)\r
400 else Cycles=12;\r
401 } else {\r
402 Cycles=8;\r
403 }\r
404\r
405 Cycles+=Ea_add_ns(g_movem_cycle_table,ea);\r
406\r
407 OpEnd();\r
408\r
409 return 0;\r
410}\r
411\r
412// --------------------- Opcodes 0x4e60+ ---------------------\r
413// Emit a Move USP opcode, 01001110 0110dnnn move An to/from USP\r
414int OpMoveUsp(int op)\r
415{\r
416 int use=0,dir=0;\r
417\r
418 dir=(op>>3)&1; // Direction\r
419 use=op&~0x0007; // Use same opcode for all An\r
420\r
421 if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
422\r
423 OpStart(op); Cycles=4;\r
424\r
425 SuperCheck(op);\r
426\r
427 if (dir)\r
428 {\r
429 ot(" ldr r1,[r7,#0x48] ;@ Get from USP\n\n");\r
430 EaCalc (0,0x0007,8,2,1);\r
431 EaWrite(0, 1,8,2,0x0007,1);\r
432 }\r
433 else\r
434 {\r
435 EaCalc (0,0x0007,8,2,1);\r
436 EaRead (0, 0,8,2,0x0007,1);\r
437 ot(" str r0,[r7,#0x48] ;@ Put in USP\n\n");\r
438 }\r
439 \r
440 OpEnd();\r
441\r
442 SuperEnd(op);\r
443\r
444 return 0;\r
445}\r
446\r
447// --------------------- Opcodes 0x7000+ ---------------------\r
448// Emit a Move Quick opcode, 0111nnn0 dddddddd moveq #dd,Dn\r
449int OpMoveq(int op)\r
450{\r
451 int use=0;\r
452\r
453 use=op&0xf100; // Use same opcode for all values\r
454 if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
455\r
456 OpStart(op); Cycles=4;\r
457\r
458 ot(" movs r0,r8,asl #24\n");\r
459 ot(" and r1,r8,#0x0e00\n");\r
460 ot(" mov r0,r0,asr #24 ;@ Sign extended Quick value\n");\r
461 ot(" mrs r9,cpsr ;@ r9=NZ flags\n");\r
462 ot(" str r0,[r7,r1,lsr #7] ;@ Store into Dn\n");\r
463 ot("\n");\r
464\r
465 OpEnd();\r
466\r
467 return 0;\r
468}\r
469\r
470// --------------------- Opcodes 0xc140+ ---------------------\r
471// Emit a Exchange opcode:\r
472// 1100ttt1 01000sss exg ds,dt\r
473// 1100ttt1 01001sss exg as,at\r
474// 1100ttt1 10001sss exg as,dt\r
475int OpExg(int op)\r
476{\r
477 int use=0,type=0;\r
478\r
479 type=op&0xf8;\r
480\r
481 if (type!=0x40 && type!=0x48 && type!=0x88) return 1; // Not an exg opcode\r
482\r
483 use=op&0xf1f8; // Use same opcode for all values\r
484 if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
485\r
486 OpStart(op); Cycles=6;\r
487\r
488 ot(" and r10,r8,#0x0e00 ;@ Find T register\n");\r
489 ot(" and r11,r8,#0x000f ;@ Find S register\n");\r
490 if (type==0x48) ot(" orr r10,r10,#0x1000 ;@ T is an address register\n");\r
491 ot("\n");\r
492 ot(" ldr r0,[r7,r10,lsr #7] ;@ Get T\n");\r
493 ot(" ldr r1,[r7,r11,lsl #2] ;@ Get S\n");\r
494 ot("\n");\r
495 ot(" str r0,[r7,r11,lsl #2] ;@ T->S\n");\r
496 ot(" str r1,[r7,r10,lsr #7] ;@ S->T\n"); \r
497 ot("\n");\r
498\r
499 OpEnd();\r
500 \r
501 return 0;\r
502}\r
503\r
504// ------------------------- movep -------------------------------\r
505// 0000ddd1 0z001sss\r
506// 0000sss1 1z001ddd (to mem)\r
507int OpMovep(int op)\r
508{\r
509 int ea=0;\r
510 int size=1,use=0,dir;\r
511\r
512 use=op&0xf1f8;\r
513 if (op!=use) { OpUse(op,use); return 0; } // Use existing handler (for all dests, srcs)\r
514\r
515 // Get EA\r
516 ea = (op&0x0007)|0x28;\r
517 dir = (op>>7)&1;\r
518\r
519 // Find size extension\r
520 if(op&0x0040) size=2;\r
521\r
522 OpStart(op);\r
523 \r
524 if(dir) { // reg to mem\r
525 EaCalc(11,0x0e00,0,size); // reg number -> r11\r
526 EaRead(11,11,0,size,0x0e00); // regval -> r11\r
527 EaCalc(10,0x0007,ea,size);\r
528 if(size==2) { // if operand is long\r
529 ot(" mov r1,r11,lsr #24 ;@ first byte\n");\r
530 EaWrite(10,1,ea,0,0x0007); // store first byte\r
531 ot(" add r10,r10,#2\n");\r
532 ot(" mov r1,r11,lsr #16 ;@ second byte\n");\r
533 EaWrite(10,1,ea,0,0x0007); // store second byte\r
534 ot(" add r10,r10,#2\n");\r
535 }\r
536 ot(" mov r1,r11,lsr #8 ;@ first or third byte\n");\r
537 EaWrite(10,1,ea,0,0x0007);\r
538 ot(" add r10,r10,#2\n");\r
539 ot(" and r1,r11,#0xff\n");\r
540 EaWrite(10,1,ea,0,0x0007);\r
541 } else { // mem to reg\r
542 EaCalc(10,0x0007,ea,size,1);\r
543 EaRead(10,11,ea,0,0x0007,1); // read first byte\r
544 ot(" add r10,r10,#2\n");\r
545 EaRead(10,1,ea,0,0x0007,1); // read second byte\r
546 if(size==2) { // if operand is long\r
547 ot(" orr r11,r11,r1,lsr #8 ;@ second byte\n");\r
548 ot(" add r10,r10,#2\n");\r
549 EaRead(10,1,ea,0,0x0007,1);\r
550 ot(" orr r11,r11,r1,lsr #16 ;@ third byte\n");\r
551 ot(" add r10,r10,#2\n");\r
552 EaRead(10,1,ea,0,0x0007,1);\r
553 ot(" orr r0,r11,r1,lsr #24 ;@ fourth byte\n");\r
554 } else {\r
555 ot(" orr r0,r11,r1,lsr #8 ;@ second byte\n");\r
556 }\r
557 // store the result\r
558 EaCalc(11,0x0e00,0,size,1); // reg number -> r11\r
559 EaWrite(11,0,0,size,0x0e00,1);\r
560 }\r
561\r
562 Cycles=(size==2)?24:16;\r
563 OpEnd();\r
564\r
565 return 0;\r
566}\r
567\r
568// Emit a Stop/Reset opcodes, 01001110 011100t0 imm\r
569int OpStopReset(int op)\r
570{\r
571 int type=(op>>1)&1; // reset/stop\r
572\r
573 OpStart(op);\r
574\r
575 SuperCheck(op);\r
576\r
577 if(type) {\r
578 // copy immediate to SR, stop the CPU and eat all remaining cycles.\r
579 ot(" ldrh r0,[r4],#2 ;@ Fetch the immediate\n");\r
580 SuperChange(op);\r
581 OpRegToFlags(1);\r
582\r
583 ot("\n");\r
584\r
585 ot(" mov r0,#1\n");\r
586 ot(" str r0,[r7,#0x58] ;@ stopped\n");\r
587 ot("\n");\r
588\r
589 ot(" mov r5,#0 ;@ eat cycles\n");\r
590 Cycles = 4;\r
591 ot("\n");\r
592 }\r
593 else\r
594 {\r
595 Cycles = 132;\r
596#if USE_RESET_CALLBACK\r
597 ot(" str r4,[r7,#0x40] ;@ Save PC\n");\r
598 ot(" mov r1,r9,lsr #28\n");\r
599 ot(" strb r1,[r7,#0x46] ;@ Save Flags (NZCV)\n");\r
600 ot(" str r5,[r7,#0x5c] ;@ Save Cycles\n");\r
601 ot(" ldr r11,[r7,#0x90] ;@ ResetCallback\n");\r
602 ot(" tst r11,r11\n");\r
603 ot(" movne lr,pc\n");\r
604 ot(" movne pc,r11 ;@ call ResetCallback if it is defined\n");\r
605 ot(" ldrb r9,[r7,#0x46] ;@ r9 = Load Flags (NZCV)\n");\r
606 ot(" ldr r5,[r7,#0x5c] ;@ Load Cycles\n");\r
607 ot(" ldr r4,[r7,#0x40] ;@ Load PC\n");\r
608 ot(" mov r9,r9,lsl #28\n");\r
609#endif\r
610 }\r
611\r
612 OpEnd();\r
613 SuperEnd(op);\r
614\r
615 return 0;\r
616}\r