Previous 199869 Revisions Next

r20718 Monday 4th February, 2013 at 00:59:54 UTC by Ryan Holtz
checkpoint (nw)
[src/emu/cpu/arm7]arm7.c arm7.h arm7core.c arm7core.h arm7drc.c* arm7help.h arm7ops.c arm7ops.h arm7thmb.c arm7thmb.h

trunk/src/emu/cpu/arm7/arm7thmb.c
r20717r20718
4242
4343   /* Shift operations */
4444
45const void tg00_0(arm_state *cpustate, UINT32 pc, UINT32 insn) /* Shift left */
45const void tg00_0(arm_state *arm, UINT32 pc, UINT32 insn) /* Shift left */
4646{
4747   UINT32 rs, rd, rrs;
4848   INT32 offs;
r20717r20718
5151
5252   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
5353   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
54   rrs = GET_REGISTER(cpustate, rs);
54   rrs = GET_REGISTER(arm, rs);
5555   offs = (insn & THUMB_SHIFT_AMT) >> THUMB_SHIFT_AMT_SHIFT;
5656   if (offs != 0)
5757   {
58      SET_REGISTER(cpustate, rd, rrs << offs);
58      SET_REGISTER(arm, rd, rrs << offs);
5959      if (rrs & (1 << (31 - (offs - 1))))
6060      {
6161         SET_CPSR(GET_CPSR | C_MASK);
r20717r20718
6767   }
6868   else
6969   {
70      SET_REGISTER(cpustate, rd, rrs);
70      SET_REGISTER(arm, rd, rrs);
7171   }
7272   SET_CPSR(GET_CPSR & ~(Z_MASK | N_MASK));
73   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(cpustate, rd)));
73   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(arm, rd)));
7474   R15 += 2;
7575}
7676
77const void tg00_1(arm_state *cpustate, UINT32 pc, UINT32 insn) /* Shift right */
77const void tg00_1(arm_state *arm, UINT32 pc, UINT32 insn) /* Shift right */
7878{
7979   UINT32 rs, rd, rrs;
8080   INT32 offs;
r20717r20718
8383
8484   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
8585   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
86   rrs = GET_REGISTER(cpustate, rs);
86   rrs = GET_REGISTER(arm, rs);
8787   offs = (insn & THUMB_SHIFT_AMT) >> THUMB_SHIFT_AMT_SHIFT;
8888   if (offs != 0)
8989   {
90      SET_REGISTER(cpustate, rd, rrs >> offs);
90      SET_REGISTER(arm, rd, rrs >> offs);
9191      if (rrs & (1 << (offs - 1)))
9292      {
9393         SET_CPSR(GET_CPSR | C_MASK);
r20717r20718
9999   }
100100   else
101101   {
102      SET_REGISTER(cpustate, rd, 0);
102      SET_REGISTER(arm, rd, 0);
103103      if (rrs & 0x80000000)
104104      {
105105         SET_CPSR(GET_CPSR | C_MASK);
r20717r20718
110110      }
111111   }
112112   SET_CPSR(GET_CPSR & ~(Z_MASK | N_MASK));
113   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(cpustate, rd)));
113   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(arm, rd)));
114114   R15 += 2;
115115}
116116
117117/* Arithmetic */
118118
119const void tg01_0(arm_state *cpustate, UINT32 pc, UINT32 insn)
119const void tg01_0(arm_state *arm, UINT32 pc, UINT32 insn)
120120{
121121   UINT32 rs, rd, rrs;
122122   INT32 offs;
r20717r20718
125125   {
126126      rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
127127      rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
128      rrs = GET_REGISTER(cpustate, rs);
128      rrs = GET_REGISTER(arm, rs);
129129      offs = (insn & THUMB_SHIFT_AMT) >> THUMB_SHIFT_AMT_SHIFT;
130130      if (offs == 0)
131131      {
r20717r20718
141141         {
142142            SET_CPSR(GET_CPSR & ~C_MASK);
143143         }
144         SET_REGISTER(cpustate, rd, (rrs & 0x80000000) ? 0xFFFFFFFF : 0x00000000);
144         SET_REGISTER(arm, rd, (rrs & 0x80000000) ? 0xFFFFFFFF : 0x00000000);
145145      }
146146      else
147147      {
r20717r20718
153153         {
154154            SET_CPSR(GET_CPSR & ~C_MASK);
155155         }
156         SET_REGISTER(cpustate, rd,
156         SET_REGISTER(arm, rd,
157157                     (rrs & 0x80000000)
158158                     ? ((0xFFFFFFFF << (32 - offs)) | (rrs >> offs))
159159                     : (rrs >> offs));
160160      }
161161      SET_CPSR(GET_CPSR & ~(N_MASK | Z_MASK));
162      SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(cpustate, rd)));
162      SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(arm, rd)));
163163      R15 += 2;
164164   }
165165}
166166
167const void tg01_10(arm_state *cpustate, UINT32 pc, UINT32 insn)  /* ADD Rd, Rs, Rn */
167const void tg01_10(arm_state *arm, UINT32 pc, UINT32 insn)  /* ADD Rd, Rs, Rn */
168168{
169169   UINT32 rn, rs, rd;
170170
171171
172   rn = GET_REGISTER(cpustate, (insn & THUMB_ADDSUB_RNIMM) >> THUMB_ADDSUB_RNIMM_SHIFT);
173   rs = GET_REGISTER(cpustate, (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT);
172   rn = GET_REGISTER(arm, (insn & THUMB_ADDSUB_RNIMM) >> THUMB_ADDSUB_RNIMM_SHIFT);
173   rs = GET_REGISTER(arm, (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT);
174174   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
175   SET_REGISTER(cpustate, rd, rs + rn);
176   HandleThumbALUAddFlags(GET_REGISTER(cpustate, rd), rs, rn);
175   SET_REGISTER(arm, rd, rs + rn);
176   HandleThumbALUAddFlags(GET_REGISTER(arm, rd), rs, rn);
177177
178178}
179179
180const void tg01_11(arm_state *cpustate, UINT32 pc, UINT32 insn) /* SUB Rd, Rs, Rn */
180const void tg01_11(arm_state *arm, UINT32 pc, UINT32 insn) /* SUB Rd, Rs, Rn */
181181{
182182   UINT32 rn, rs, rd;
183183
184   rn = GET_REGISTER(cpustate, (insn & THUMB_ADDSUB_RNIMM) >> THUMB_ADDSUB_RNIMM_SHIFT);
185   rs = GET_REGISTER(cpustate, (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT);
184   rn = GET_REGISTER(arm, (insn & THUMB_ADDSUB_RNIMM) >> THUMB_ADDSUB_RNIMM_SHIFT);
185   rs = GET_REGISTER(arm, (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT);
186186   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
187   SET_REGISTER(cpustate, rd, rs - rn);
188   HandleThumbALUSubFlags(GET_REGISTER(cpustate, rd), rs, rn);
187   SET_REGISTER(arm, rd, rs - rn);
188   HandleThumbALUSubFlags(GET_REGISTER(arm, rd), rs, rn);
189189
190190}
191191
192const void tg01_12(arm_state *cpustate, UINT32 pc, UINT32 insn) /* ADD Rd, Rs, #imm */
192const void tg01_12(arm_state *arm, UINT32 pc, UINT32 insn) /* ADD Rd, Rs, #imm */
193193{
194194   UINT32 rs, rd, imm;
195195
196196   imm = (insn & THUMB_ADDSUB_RNIMM) >> THUMB_ADDSUB_RNIMM_SHIFT;
197   rs = GET_REGISTER(cpustate, (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT);
197   rs = GET_REGISTER(arm, (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT);
198198   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
199   SET_REGISTER(cpustate, rd, rs + imm);
200   HandleThumbALUAddFlags(GET_REGISTER(cpustate, rd), rs, imm);
199   SET_REGISTER(arm, rd, rs + imm);
200   HandleThumbALUAddFlags(GET_REGISTER(arm, rd), rs, imm);
201201
202202}
203203
204const void tg01_13(arm_state *cpustate, UINT32 pc, UINT32 insn) /* SUB Rd, Rs, #imm */
204const void tg01_13(arm_state *arm, UINT32 pc, UINT32 insn) /* SUB Rd, Rs, #imm */
205205{
206206   UINT32 rs, rd, imm;
207207
208208   imm = (insn & THUMB_ADDSUB_RNIMM) >> THUMB_ADDSUB_RNIMM_SHIFT;
209   rs = GET_REGISTER(cpustate, (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT);
209   rs = GET_REGISTER(arm, (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT);
210210   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
211   SET_REGISTER(cpustate, rd, rs - imm);
212   HandleThumbALUSubFlags(GET_REGISTER(cpustate, rd), rs,imm);
211   SET_REGISTER(arm, rd, rs - imm);
212   HandleThumbALUSubFlags(GET_REGISTER(arm, rd), rs,imm);
213213
214214}
215215
216216/* CMP / MOV */
217217
218const void tg02_0(arm_state *cpustate, UINT32 pc, UINT32 insn)
218const void tg02_0(arm_state *arm, UINT32 pc, UINT32 insn)
219219{
220220   UINT32 rd, op2;
221221
222222   rd = (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT;
223223   op2 = (insn & THUMB_INSN_IMM);
224   SET_REGISTER(cpustate, rd, op2);
224   SET_REGISTER(arm, rd, op2);
225225   SET_CPSR(GET_CPSR & ~(Z_MASK | N_MASK));
226   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(cpustate, rd)));
226   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(arm, rd)));
227227   R15 += 2;
228228}
229229
230const void tg02_1(arm_state *cpustate, UINT32 pc, UINT32 insn)
230const void tg02_1(arm_state *arm, UINT32 pc, UINT32 insn)
231231{
232232   UINT32 rn, rd, op2;
233233
234   rn = GET_REGISTER(cpustate, (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT);
234   rn = GET_REGISTER(arm, (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT);
235235   op2 = insn & THUMB_INSN_IMM;
236236   rd = rn - op2;
237237   HandleThumbALUSubFlags(rd, rn, op2);
238   //mame_printf_debug("%08x: xxx Thumb instruction: CMP R%d (%08x), %02x (N=%d, Z=%d, C=%d, V=%d)\n", pc, (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT, GET_REGISTER(cpustate, (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT), op2, N_IS_SET(GET_CPSR) ? 1 : 0, Z_IS_SET(GET_CPSR) ? 1 : 0, C_IS_SET(GET_CPSR) ? 1 : 0, V_IS_SET(GET_CPSR) ? 1 : 0);
238   //mame_printf_debug("%08x: xxx Thumb instruction: CMP R%d (%08x), %02x (N=%d, Z=%d, C=%d, V=%d)\n", pc, (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT, GET_REGISTER(arm, (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT), op2, N_IS_SET(GET_CPSR) ? 1 : 0, Z_IS_SET(GET_CPSR) ? 1 : 0, C_IS_SET(GET_CPSR) ? 1 : 0, V_IS_SET(GET_CPSR) ? 1 : 0);
239239}
240240
241241
242242
243243/* ADD/SUB immediate */
244244
245const void tg03_0(arm_state *cpustate, UINT32 pc, UINT32 insn) /* ADD Rd, #Offset8 */
245const void tg03_0(arm_state *arm, UINT32 pc, UINT32 insn) /* ADD Rd, #Offset8 */
246246{
247247   UINT32 rn, rd, op2;
248248
249   rn = GET_REGISTER(cpustate, (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT);
249   rn = GET_REGISTER(arm, (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT);
250250   op2 = insn & THUMB_INSN_IMM;
251251   rd = rn + op2;
252252   //mame_printf_debug("%08x:  Thumb instruction: ADD R%d, %02x\n", pc, (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT, op2);
253   SET_REGISTER(cpustate, (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT, rd);
253   SET_REGISTER(arm, (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT, rd);
254254   HandleThumbALUAddFlags(rd, rn, op2);
255255}
256256
257const void tg03_1(arm_state *cpustate, UINT32 pc, UINT32 insn) /* SUB Rd, #Offset8 */
257const void tg03_1(arm_state *arm, UINT32 pc, UINT32 insn) /* SUB Rd, #Offset8 */
258258{
259259   UINT32 rn, rd, op2;
260260
261   rn = GET_REGISTER(cpustate, (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT);
261   rn = GET_REGISTER(arm, (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT);
262262   op2 = insn & THUMB_INSN_IMM;
263263   //mame_printf_debug("%08x:  Thumb instruction: SUB R%d, %02x\n", pc, (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT, op2);
264264   rd = rn - op2;
265   SET_REGISTER(cpustate, (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT, rd);
265   SET_REGISTER(arm, (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT, rd);
266266   HandleThumbALUSubFlags(rd, rn, op2);
267267}
268268
r20717r20718
270270
271271/* Rd & Rm instructions */
272272
273const void tg04_00_00(arm_state *cpustate, UINT32 pc, UINT32 insn) /* AND Rd, Rs */
273const void tg04_00_00(arm_state *arm, UINT32 pc, UINT32 insn) /* AND Rd, Rs */
274274{
275275   UINT32 rs, rd;
276276
277277   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
278278   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
279   SET_REGISTER(cpustate, rd, GET_REGISTER(cpustate, rd) & GET_REGISTER(cpustate, rs));
279   SET_REGISTER(arm, rd, GET_REGISTER(arm, rd) & GET_REGISTER(arm, rs));
280280   SET_CPSR(GET_CPSR & ~(Z_MASK | N_MASK));
281   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(cpustate, rd)));
281   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(arm, rd)));
282282   R15 += 2;
283283
284284}
285285
286const void tg04_00_01(arm_state *cpustate, UINT32 pc, UINT32 insn) /* EOR Rd, Rs */
286const void tg04_00_01(arm_state *arm, UINT32 pc, UINT32 insn) /* EOR Rd, Rs */
287287{
288288   UINT32 rs, rd;
289289
290290   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
291291   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
292   SET_REGISTER(cpustate, rd, GET_REGISTER(cpustate, rd) ^ GET_REGISTER(cpustate, rs));
292   SET_REGISTER(arm, rd, GET_REGISTER(arm, rd) ^ GET_REGISTER(arm, rs));
293293   SET_CPSR(GET_CPSR & ~(Z_MASK | N_MASK));
294   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(cpustate, rd)));
294   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(arm, rd)));
295295   R15 += 2;
296296
297297}
298298
299const void tg04_00_02(arm_state *cpustate, UINT32 pc, UINT32 insn) /* LSL Rd, Rs */
299const void tg04_00_02(arm_state *arm, UINT32 pc, UINT32 insn) /* LSL Rd, Rs */
300300{
301301   UINT32 rs, rd, rrd;
302302   INT32 offs;
303303
304304   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
305305   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
306   rrd = GET_REGISTER(cpustate, rd);
307   offs = GET_REGISTER(cpustate, rs) & 0x000000ff;
306   rrd = GET_REGISTER(arm, rd);
307   offs = GET_REGISTER(arm, rs) & 0x000000ff;
308308   if (offs > 0)
309309   {
310310      if (offs < 32)
311311      {
312         SET_REGISTER(cpustate, rd, rrd << offs);
312         SET_REGISTER(arm, rd, rrd << offs);
313313         if (rrd & (1 << (31 - (offs - 1))))
314314         {
315315            SET_CPSR(GET_CPSR | C_MASK);
r20717r20718
321321      }
322322      else if (offs == 32)
323323      {
324         SET_REGISTER(cpustate, rd, 0);
324         SET_REGISTER(arm, rd, 0);
325325         if (rrd & 1)
326326         {
327327            SET_CPSR(GET_CPSR | C_MASK);
r20717r20718
333333      }
334334      else
335335      {
336         SET_REGISTER(cpustate, rd, 0);
336         SET_REGISTER(arm, rd, 0);
337337         SET_CPSR(GET_CPSR & ~C_MASK);
338338      }
339339   }
340340   SET_CPSR(GET_CPSR & ~(Z_MASK | N_MASK));
341   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(cpustate, rd)));
341   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(arm, rd)));
342342   R15 += 2;
343343
344344}
345345
346const void tg04_00_03(arm_state *cpustate, UINT32 pc, UINT32 insn) /* LSR Rd, Rs */
346const void tg04_00_03(arm_state *arm, UINT32 pc, UINT32 insn) /* LSR Rd, Rs */
347347{
348348   UINT32 rs, rd, rrd;
349349   INT32 offs;
350350
351351   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
352352   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
353   rrd = GET_REGISTER(cpustate, rd);
354   offs = GET_REGISTER(cpustate, rs) & 0x000000ff;
353   rrd = GET_REGISTER(arm, rd);
354   offs = GET_REGISTER(arm, rs) & 0x000000ff;
355355   if (offs >  0)
356356   {
357357      if (offs < 32)
358358      {
359         SET_REGISTER(cpustate, rd, rrd >> offs);
359         SET_REGISTER(arm, rd, rrd >> offs);
360360         if (rrd & (1 << (offs - 1)))
361361         {
362362            SET_CPSR(GET_CPSR | C_MASK);
r20717r20718
368368      }
369369      else if (offs == 32)
370370      {
371         SET_REGISTER(cpustate, rd, 0);
371         SET_REGISTER(arm, rd, 0);
372372         if (rrd & 0x80000000)
373373         {
374374            SET_CPSR(GET_CPSR | C_MASK);
r20717r20718
380380      }
381381      else
382382      {
383         SET_REGISTER(cpustate, rd, 0);
383         SET_REGISTER(arm, rd, 0);
384384         SET_CPSR(GET_CPSR & ~C_MASK);
385385      }
386386   }
387387   SET_CPSR(GET_CPSR & ~(Z_MASK | N_MASK));
388   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(cpustate, rd)));
388   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(arm, rd)));
389389   R15 += 2;
390390
391391}
392392
393const void tg04_00_04(arm_state *cpustate, UINT32 pc, UINT32 insn) /* ASR Rd, Rs */
393const void tg04_00_04(arm_state *arm, UINT32 pc, UINT32 insn) /* ASR Rd, Rs */
394394{
395395   UINT32 rs, rd, rrs, rrd;
396396
397397   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
398398   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
399   rrs = GET_REGISTER(cpustate, rs)&0xff;
400   rrd = GET_REGISTER(cpustate, rd);
399   rrs = GET_REGISTER(arm, rs)&0xff;
400   rrd = GET_REGISTER(arm, rd);
401401   if (rrs != 0)
402402   {
403403      if (rrs >= 32)
r20717r20718
410410         {
411411            SET_CPSR(GET_CPSR & ~C_MASK);
412412         }
413         SET_REGISTER(cpustate, rd, (GET_REGISTER(cpustate, rd) & 0x80000000) ? 0xFFFFFFFF : 0x00000000);
413         SET_REGISTER(arm, rd, (GET_REGISTER(arm, rd) & 0x80000000) ? 0xFFFFFFFF : 0x00000000);
414414      }
415415      else
416416      {
r20717r20718
422422         {
423423            SET_CPSR(GET_CPSR & ~C_MASK);
424424         }
425         SET_REGISTER(cpustate, rd, (rrd & 0x80000000)
425         SET_REGISTER(arm, rd, (rrd & 0x80000000)
426426                     ? ((0xFFFFFFFF << (32 - rrs)) | (rrd >> rrs))
427427                     : (rrd >> rrs));
428428      }
429429   }
430430   SET_CPSR(GET_CPSR & ~(N_MASK | Z_MASK));
431   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(cpustate, rd)));
431   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(arm, rd)));
432432   R15 += 2;
433433
434434}
435435
436const void tg04_00_05(arm_state *cpustate, UINT32 pc, UINT32 insn) /* ADC Rd, Rs */
436const void tg04_00_05(arm_state *arm, UINT32 pc, UINT32 insn) /* ADC Rd, Rs */
437437{
438438   UINT32 rn, rs, rd, op2;
439439
440440   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
441441   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
442442   op2=(GET_CPSR & C_MASK) ? 1 : 0;
443   rn=GET_REGISTER(cpustate, rd) + GET_REGISTER(cpustate, rs) + op2;
444   HandleThumbALUAddFlags(rn, GET_REGISTER(cpustate, rd), (GET_REGISTER(cpustate, rs))); // ?
445   SET_REGISTER(cpustate, rd, rn);
443   rn=GET_REGISTER(arm, rd) + GET_REGISTER(arm, rs) + op2;
444   HandleThumbALUAddFlags(rn, GET_REGISTER(arm, rd), (GET_REGISTER(arm, rs))); // ?
445   SET_REGISTER(arm, rd, rn);
446446
447447}
448448
449const void tg04_00_06(arm_state *cpustate, UINT32 pc, UINT32 insn)  /* SBC Rd, Rs */
449const void tg04_00_06(arm_state *arm, UINT32 pc, UINT32 insn)  /* SBC Rd, Rs */
450450{
451451   UINT32 rn, rs, rd, op2;
452452
453453   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
454454   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
455455   op2=(GET_CPSR & C_MASK) ? 0 : 1;
456   rn=GET_REGISTER(cpustate, rd) - GET_REGISTER(cpustate, rs) - op2;
457   HandleThumbALUSubFlags(rn, GET_REGISTER(cpustate, rd), (GET_REGISTER(cpustate, rs))); //?
458   SET_REGISTER(cpustate, rd, rn);
456   rn=GET_REGISTER(arm, rd) - GET_REGISTER(arm, rs) - op2;
457   HandleThumbALUSubFlags(rn, GET_REGISTER(arm, rd), (GET_REGISTER(arm, rs))); //?
458   SET_REGISTER(arm, rd, rn);
459459
460460}
461461
462const void tg04_00_07(arm_state *cpustate, UINT32 pc, UINT32 insn) /* ROR Rd, Rs */
462const void tg04_00_07(arm_state *arm, UINT32 pc, UINT32 insn) /* ROR Rd, Rs */
463463{
464464   UINT32 rs, rd, imm, rrd;
465465
466466   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
467467   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
468   rrd = GET_REGISTER(cpustate, rd);
469   imm = GET_REGISTER(cpustate, rs) & 0x0000001f;
470   SET_REGISTER(cpustate, rd, (rrd >> imm) | (rrd << (32 - imm)));
468   rrd = GET_REGISTER(arm, rd);
469   imm = GET_REGISTER(arm, rs) & 0x0000001f;
470   SET_REGISTER(arm, rd, (rrd >> imm) | (rrd << (32 - imm)));
471471   if (rrd & (1 << (imm - 1)))
472472   {
473473      SET_CPSR(GET_CPSR | C_MASK);
r20717r20718
477477      SET_CPSR(GET_CPSR & ~C_MASK);
478478   }
479479   SET_CPSR(GET_CPSR & ~(Z_MASK | N_MASK));
480   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(cpustate, rd)));
480   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(arm, rd)));
481481   R15 += 2;
482482
483483}
484484
485const void tg04_00_08(arm_state *cpustate, UINT32 pc, UINT32 insn) /* TST Rd, Rs */
485const void tg04_00_08(arm_state *arm, UINT32 pc, UINT32 insn) /* TST Rd, Rs */
486486{
487487   UINT32 rs, rd;
488488
489489   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
490490   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
491491   SET_CPSR(GET_CPSR & ~(Z_MASK | N_MASK));
492   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(cpustate, rd) & GET_REGISTER(cpustate, rs)));
492   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(arm, rd) & GET_REGISTER(arm, rs)));
493493   R15 += 2;
494494
495495}
496496
497const void tg04_00_09(arm_state *cpustate, UINT32 pc, UINT32 insn) /* NEG Rd, Rs */
497const void tg04_00_09(arm_state *arm, UINT32 pc, UINT32 insn) /* NEG Rd, Rs */
498498{
499499   UINT32 rn, rs, rd, rrs;
500500
501501   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
502502   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
503   rrs = GET_REGISTER(cpustate, rs);
503   rrs = GET_REGISTER(arm, rs);
504504   rn = 0 - rrs;
505   SET_REGISTER(cpustate, rd, rn);
506   HandleThumbALUSubFlags(GET_REGISTER(cpustate, rd), 0, rrs);
505   SET_REGISTER(arm, rd, rn);
506   HandleThumbALUSubFlags(GET_REGISTER(arm, rd), 0, rrs);
507507
508508}
509509
510const void tg04_00_0a(arm_state *cpustate, UINT32 pc, UINT32 insn) /* CMP Rd, Rs */
510const void tg04_00_0a(arm_state *arm, UINT32 pc, UINT32 insn) /* CMP Rd, Rs */
511511{
512512   UINT32 rn, rs, rd;
513513
514514   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
515515   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
516   rn = GET_REGISTER(cpustate, rd) - GET_REGISTER(cpustate, rs);
517   HandleThumbALUSubFlags(rn, GET_REGISTER(cpustate, rd), GET_REGISTER(cpustate, rs));
516   rn = GET_REGISTER(arm, rd) - GET_REGISTER(arm, rs);
517   HandleThumbALUSubFlags(rn, GET_REGISTER(arm, rd), GET_REGISTER(arm, rs));
518518
519519}
520520
521521
522const void tg04_00_0b(arm_state *cpustate, UINT32 pc, UINT32 insn) /* CMN Rd, Rs - check flags, add dasm */
522const void tg04_00_0b(arm_state *arm, UINT32 pc, UINT32 insn) /* CMN Rd, Rs - check flags, add dasm */
523523{
524524   UINT32 rn, rs, rd;
525525
526526   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
527527   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
528   rn = GET_REGISTER(cpustate, rd) + GET_REGISTER(cpustate, rs);
529   HandleThumbALUAddFlags(rn, GET_REGISTER(cpustate, rd), GET_REGISTER(cpustate, rs));
528   rn = GET_REGISTER(arm, rd) + GET_REGISTER(arm, rs);
529   HandleThumbALUAddFlags(rn, GET_REGISTER(arm, rd), GET_REGISTER(arm, rs));
530530
531531}
532532
533const void tg04_00_0c(arm_state *cpustate, UINT32 pc, UINT32 insn) /* ORR Rd, Rs */
533const void tg04_00_0c(arm_state *arm, UINT32 pc, UINT32 insn) /* ORR Rd, Rs */
534534{
535535   UINT32 rs, rd;
536536
537537   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
538538   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
539   SET_REGISTER(cpustate, rd, GET_REGISTER(cpustate, rd) | GET_REGISTER(cpustate, rs));
539   SET_REGISTER(arm, rd, GET_REGISTER(arm, rd) | GET_REGISTER(arm, rs));
540540   SET_CPSR(GET_CPSR & ~(Z_MASK | N_MASK));
541   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(cpustate, rd)));
541   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(arm, rd)));
542542   R15 += 2;
543543
544544}
545545
546const void tg04_00_0d(arm_state *cpustate, UINT32 pc, UINT32 insn) /* MUL Rd, Rs */
546const void tg04_00_0d(arm_state *arm, UINT32 pc, UINT32 insn) /* MUL Rd, Rs */
547547{
548548   UINT32 rn, rs, rd;
549549
550550   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
551551   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
552   rn = GET_REGISTER(cpustate, rd) * GET_REGISTER(cpustate, rs);
552   rn = GET_REGISTER(arm, rd) * GET_REGISTER(arm, rs);
553553   SET_CPSR(GET_CPSR & ~(Z_MASK | N_MASK));
554   SET_REGISTER(cpustate, rd, rn);
554   SET_REGISTER(arm, rd, rn);
555555   SET_CPSR(GET_CPSR | HandleALUNZFlags(rn));
556556   R15 += 2;
557557
558558}
559559
560const void tg04_00_0e(arm_state *cpustate, UINT32 pc, UINT32 insn) /* BIC Rd, Rs */
560const void tg04_00_0e(arm_state *arm, UINT32 pc, UINT32 insn) /* BIC Rd, Rs */
561561{
562562   UINT32 rs, rd;
563563
564564   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
565565   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
566   SET_REGISTER(cpustate, rd, GET_REGISTER(cpustate, rd) & (~GET_REGISTER(cpustate, rs)));
566   SET_REGISTER(arm, rd, GET_REGISTER(arm, rd) & (~GET_REGISTER(arm, rs)));
567567   SET_CPSR(GET_CPSR & ~(Z_MASK | N_MASK));
568   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(cpustate, rd)));
568   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(arm, rd)));
569569   R15 += 2;
570570
571571}
572const void tg04_00_0f(arm_state *cpustate, UINT32 pc, UINT32 insn) /* MVN Rd, Rs */
572const void tg04_00_0f(arm_state *arm, UINT32 pc, UINT32 insn) /* MVN Rd, Rs */
573573{
574574   UINT32 rs, rd, op2;
575575
576576   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
577577   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
578   op2 = GET_REGISTER(cpustate, rs);
579   SET_REGISTER(cpustate, rd, ~op2);
578   op2 = GET_REGISTER(arm, rs);
579   SET_REGISTER(arm, rd, ~op2);
580580   SET_CPSR(GET_CPSR & ~(Z_MASK | N_MASK));
581   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(cpustate, rd)));
581   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(arm, rd)));
582582   R15 += 2;
583583
584584}
585585
586586/* ADD Rd, Rs group */
587587
588const void tg04_01_00(arm_state *cpustate, UINT32 pc, UINT32 insn)
588const void tg04_01_00(arm_state *arm, UINT32 pc, UINT32 insn)
589589{
590590//  UINT32 rs, rd;
591591//  rs = (insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
r20717r20718
598598
599599}
600600
601const void tg04_01_01(arm_state *cpustate, UINT32 pc, UINT32 insn) /* ADD Rd, HRs */
601const void tg04_01_01(arm_state *arm, UINT32 pc, UINT32 insn) /* ADD Rd, HRs */
602602{
603603   UINT32 rs, rd;
604604   rs = (insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
605605   rd = insn & THUMB_HIREG_RD;
606606
607607
608   SET_REGISTER(cpustate, rd, GET_REGISTER(cpustate, rd) + GET_REGISTER(cpustate, rs+8));
608   SET_REGISTER(arm, rd, GET_REGISTER(arm, rd) + GET_REGISTER(arm, rs+8));
609609   // emulate the effects of pre-fetch
610610   if (rs == 7)
611611   {
612      SET_REGISTER(cpustate, rd, GET_REGISTER(cpustate, rd) + 4);
612      SET_REGISTER(arm, rd, GET_REGISTER(arm, rd) + 4);
613613   }
614614
615615   R15 += 2;
616616}
617617
618const void tg04_01_02(arm_state *cpustate, UINT32 pc, UINT32 insn) /* ADD HRd, Rs */
618const void tg04_01_02(arm_state *arm, UINT32 pc, UINT32 insn) /* ADD HRd, Rs */
619619{
620620   UINT32 rs, rd;
621621   rs = (insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
622622   rd = insn & THUMB_HIREG_RD;
623623
624624
625   SET_REGISTER(cpustate, rd+8, GET_REGISTER(cpustate, rd+8) + GET_REGISTER(cpustate, rs));
625   SET_REGISTER(arm, rd+8, GET_REGISTER(arm, rd+8) + GET_REGISTER(arm, rs));
626626   if (rd == 7)
627627   {
628628      R15 += 2;
r20717r20718
631631   R15 += 2;
632632}
633633
634const void tg04_01_03(arm_state *cpustate, UINT32 pc, UINT32 insn) /* Add HRd, HRs */
634const void tg04_01_03(arm_state *arm, UINT32 pc, UINT32 insn) /* Add HRd, HRs */
635635{
636636   UINT32 rs, rd;
637637   rs = (insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
638638   rd = insn & THUMB_HIREG_RD;
639639
640640
641   SET_REGISTER(cpustate, rd+8, GET_REGISTER(cpustate, rd+8) + GET_REGISTER(cpustate, rs+8));
641   SET_REGISTER(arm, rd+8, GET_REGISTER(arm, rd+8) + GET_REGISTER(arm, rs+8));
642642   // emulate the effects of pre-fetch
643643   if (rs == 7)
644644   {
645      SET_REGISTER(cpustate, rd+8, GET_REGISTER(cpustate, rd+8) + 4);
645      SET_REGISTER(arm, rd+8, GET_REGISTER(arm, rd+8) + 4);
646646   }
647647   if (rd == 7)
648648   {
r20717r20718
653653}
654654
655655
656const void tg04_01_10(arm_state *cpustate, UINT32 pc, UINT32 insn)  /* CMP Rd, Rs */
656const void tg04_01_10(arm_state *arm, UINT32 pc, UINT32 insn)  /* CMP Rd, Rs */
657657{
658658   UINT32 rn, rs, rd;
659659
660   rs = GET_REGISTER(cpustate, ((insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT));
661   rd = GET_REGISTER(cpustate, insn & THUMB_HIREG_RD);
660   rs = GET_REGISTER(arm, ((insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT));
661   rd = GET_REGISTER(arm, insn & THUMB_HIREG_RD);
662662   rn = rd - rs;
663663   HandleThumbALUSubFlags(rn, rd, rs);
664664
665665}
666666
667const void tg04_01_11(arm_state *cpustate, UINT32 pc, UINT32 insn) /* CMP Rd, Hs */
667const void tg04_01_11(arm_state *arm, UINT32 pc, UINT32 insn) /* CMP Rd, Hs */
668668{
669669   UINT32 rn, rs, rd;
670670
671   rs = GET_REGISTER(cpustate, ((insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT) + 8);
672   rd = GET_REGISTER(cpustate, insn & THUMB_HIREG_RD);
671   rs = GET_REGISTER(arm, ((insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT) + 8);
672   rd = GET_REGISTER(arm, insn & THUMB_HIREG_RD);
673673   rn = rd - rs;
674674   HandleThumbALUSubFlags(rn, rd, rs);
675675
676676}
677677
678const void tg04_01_12(arm_state *cpustate, UINT32 pc, UINT32 insn) /* CMP Hd, Rs */
678const void tg04_01_12(arm_state *arm, UINT32 pc, UINT32 insn) /* CMP Hd, Rs */
679679{
680680   UINT32 rn, rs, rd;
681681
682   rs = GET_REGISTER(cpustate, ((insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT));
683   rd = GET_REGISTER(cpustate, (insn & THUMB_HIREG_RD) + 8);
682   rs = GET_REGISTER(arm, ((insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT));
683   rd = GET_REGISTER(arm, (insn & THUMB_HIREG_RD) + 8);
684684   rn = rd - rs;
685685   HandleThumbALUSubFlags(rn, rd, rs);
686686
687687}
688688
689const void tg04_01_13(arm_state *cpustate, UINT32 pc, UINT32 insn) /* CMP Hd, Hs */
689const void tg04_01_13(arm_state *arm, UINT32 pc, UINT32 insn) /* CMP Hd, Hs */
690690{
691691   UINT32 rn, rs, rd;
692692
693   rs = GET_REGISTER(cpustate, ((insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT) + 8);
694   rd = GET_REGISTER(cpustate, (insn & THUMB_HIREG_RD) + 8);
693   rs = GET_REGISTER(arm, ((insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT) + 8);
694   rd = GET_REGISTER(arm, (insn & THUMB_HIREG_RD) + 8);
695695   rn = rd - rs;
696696   HandleThumbALUSubFlags(rn, rd, rs);
697697
r20717r20718
700700   /* MOV group */
701701
702702// "The action of H1 = 0, H2 = 0 for Op = 00 (ADD), Op = 01 (CMP) and Op = 10 (MOV) is undefined, and should not be used."
703const void tg04_01_20(arm_state *cpustate, UINT32 pc, UINT32 insn) /* MOV Rd, Rs (undefined) */
703const void tg04_01_20(arm_state *arm, UINT32 pc, UINT32 insn) /* MOV Rd, Rs (undefined) */
704704{
705705   UINT32 rs, rd;
706706
707707
708708   rs = (insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
709709   rd = insn & THUMB_HIREG_RD;
710   SET_REGISTER(cpustate, rd, GET_REGISTER(cpustate, rs));
710   SET_REGISTER(arm, rd, GET_REGISTER(arm, rs));
711711   R15 += 2;
712712
713713}
714714
715const void tg04_01_21(arm_state *cpustate, UINT32 pc, UINT32 insn) /* MOV Rd, Hs */
715const void tg04_01_21(arm_state *arm, UINT32 pc, UINT32 insn) /* MOV Rd, Hs */
716716{
717717   UINT32 rs, rd;
718718
r20717r20718
720720   rd = insn & THUMB_HIREG_RD;
721721   if (rs == 7)
722722   {
723      SET_REGISTER(cpustate, rd, GET_REGISTER(cpustate, rs + 8) + 4);
723      SET_REGISTER(arm, rd, GET_REGISTER(arm, rs + 8) + 4);
724724   }
725725   else
726726   {
727      SET_REGISTER(cpustate, rd, GET_REGISTER(cpustate, rs + 8));
727      SET_REGISTER(arm, rd, GET_REGISTER(arm, rs + 8));
728728   }
729729   R15 += 2;
730730
731731}
732732
733const void tg04_01_22(arm_state *cpustate, UINT32 pc, UINT32 insn) /* MOV Hd, Rs */
733const void tg04_01_22(arm_state *arm, UINT32 pc, UINT32 insn) /* MOV Hd, Rs */
734734{
735735   UINT32 rs, rd;
736736
737737   rs = (insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
738738   rd = insn & THUMB_HIREG_RD;
739   SET_REGISTER(cpustate, rd + 8, GET_REGISTER(cpustate, rs));
739   SET_REGISTER(arm, rd + 8, GET_REGISTER(arm, rs));
740740   if (rd != 7)
741741   {
742742      R15 += 2;
r20717r20718
748748
749749}
750750
751const void tg04_01_23(arm_state *cpustate, UINT32 pc, UINT32 insn) /* MOV Hd, Hs */
751const void tg04_01_23(arm_state *arm, UINT32 pc, UINT32 insn) /* MOV Hd, Hs */
752752{
753753   UINT32 rs, rd;
754754
r20717r20718
756756   rd = insn & THUMB_HIREG_RD;
757757   if (rs == 7)
758758   {
759      SET_REGISTER(cpustate, rd + 8, GET_REGISTER(cpustate, rs+8)+4);
759      SET_REGISTER(arm, rd + 8, GET_REGISTER(arm, rs+8)+4);
760760   }
761761   else
762762   {
763      SET_REGISTER(cpustate, rd + 8, GET_REGISTER(cpustate, rs+8));
763      SET_REGISTER(arm, rd + 8, GET_REGISTER(arm, rs+8));
764764   }
765765   if (rd != 7)
766766   {
r20717r20718
774774}
775775
776776
777const void tg04_01_30(arm_state *cpustate, UINT32 pc, UINT32 insn)
777const void tg04_01_30(arm_state *arm, UINT32 pc, UINT32 insn)
778778{
779779   UINT32 addr;
780780   UINT32 rd;
781781
782782
783783   rd = (insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
784   addr = GET_REGISTER(cpustate, rd);
784   addr = GET_REGISTER(arm, rd);
785785   if (addr & 1)
786786   {
787787      addr &= ~1;
r20717r20718
798798
799799}
800800
801const void tg04_01_31(arm_state *cpustate, UINT32 pc, UINT32 insn)
801const void tg04_01_31(arm_state *arm, UINT32 pc, UINT32 insn)
802802{
803803   UINT32 addr;
804804
805805
806   addr = GET_REGISTER(cpustate, ((insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT) + 8);
806   addr = GET_REGISTER(arm, ((insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT) + 8);
807807   if ((((insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT) + 8) == 15)
808808   {
809809      addr += 2;
r20717r20718
824824
825825}
826826
827const void tg04_01_32(arm_state *cpustate, UINT32 pc, UINT32 insn)
827const void tg04_01_32(arm_state *arm, UINT32 pc, UINT32 insn)
828828{
829829//  UINT32 addr;
830830//  UINT32 rd;
r20717r20718
835835
836836}
837837
838const void tg04_01_33(arm_state *cpustate, UINT32 pc, UINT32 insn)
838const void tg04_01_33(arm_state *arm, UINT32 pc, UINT32 insn)
839839{
840840//  UINT32 addr;
841841//  UINT32 rd;
r20717r20718
851851
852852
853853
854const void tg04_0203(arm_state *cpustate, UINT32 pc, UINT32 insn)
854const void tg04_0203(arm_state *arm, UINT32 pc, UINT32 insn)
855855{
856856   UINT32 readword;
857857
858858   readword = READ32((R15 & ~2) + 4 + ((insn & THUMB_INSN_IMM) << 2));
859   SET_REGISTER(cpustate, (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT, readword);
859   SET_REGISTER(arm, (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT, readword);
860860   R15 += 2;
861861}
862862
863863/* LDR* STR* group */
864864
865const void tg05_0(arm_state *cpustate, UINT32 pc, UINT32 insn)  /* STR Rd, [Rn, Rm] */
865const void tg05_0(arm_state *arm, UINT32 pc, UINT32 insn)  /* STR Rd, [Rn, Rm] */
866866{
867867   UINT32 addr;
868868   UINT32 rm, rn, rd;
r20717r20718
870870   rm = (insn & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
871871   rn = (insn & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
872872   rd = (insn & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
873   addr = GET_REGISTER(cpustate, rn) + GET_REGISTER(cpustate, rm);
874   WRITE32(addr, GET_REGISTER(cpustate, rd));
873   addr = GET_REGISTER(arm, rn) + GET_REGISTER(arm, rm);
874   WRITE32(addr, GET_REGISTER(arm, rd));
875875   R15 += 2;
876876
877877}
878878
879const void tg05_1(arm_state *cpustate, UINT32 pc, UINT32 insn)  /* STRH Rd, [Rn, Rm] */
879const void tg05_1(arm_state *arm, UINT32 pc, UINT32 insn)  /* STRH Rd, [Rn, Rm] */
880880{
881881   UINT32 addr;
882882   UINT32 rm, rn, rd;
r20717r20718
884884   rm = (insn & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
885885   rn = (insn & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
886886   rd = (insn & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
887   addr = GET_REGISTER(cpustate, rn) + GET_REGISTER(cpustate, rm);
888   WRITE16(addr, GET_REGISTER(cpustate, rd));
887   addr = GET_REGISTER(arm, rn) + GET_REGISTER(arm, rm);
888   WRITE16(addr, GET_REGISTER(arm, rd));
889889   R15 += 2;
890890
891891}
892892
893const void tg05_2(arm_state *cpustate, UINT32 pc, UINT32 insn)  /* STRB Rd, [Rn, Rm] */
893const void tg05_2(arm_state *arm, UINT32 pc, UINT32 insn)  /* STRB Rd, [Rn, Rm] */
894894{
895895   UINT32 addr;
896896   UINT32 rm, rn, rd;
r20717r20718
898898   rm = (insn & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
899899   rn = (insn & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
900900   rd = (insn & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
901   addr = GET_REGISTER(cpustate, rn) + GET_REGISTER(cpustate, rm);
902   WRITE8(addr, GET_REGISTER(cpustate, rd));
901   addr = GET_REGISTER(arm, rn) + GET_REGISTER(arm, rm);
902   WRITE8(addr, GET_REGISTER(arm, rd));
903903   R15 += 2;
904904
905905}
906906
907const void tg05_3(arm_state *cpustate, UINT32 pc, UINT32 insn)  /* LDSB Rd, [Rn, Rm] todo, add dasm */
907const void tg05_3(arm_state *arm, UINT32 pc, UINT32 insn)  /* LDSB Rd, [Rn, Rm] todo, add dasm */
908908{
909909   UINT32 addr;
910910   UINT32 rm, rn, rd, op2;
r20717r20718
912912   rm = (insn & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
913913   rn = (insn & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
914914   rd = (insn & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
915   addr = GET_REGISTER(cpustate, rn) + GET_REGISTER(cpustate, rm);
915   addr = GET_REGISTER(arm, rn) + GET_REGISTER(arm, rm);
916916   op2 = READ8(addr);
917917   if (op2 & 0x00000080)
918918   {
919919      op2 |= 0xffffff00;
920920   }
921   SET_REGISTER(cpustate, rd, op2);
921   SET_REGISTER(arm, rd, op2);
922922   R15 += 2;
923923
924924}
925925
926const void tg05_4(arm_state *cpustate, UINT32 pc, UINT32 insn)  /* LDR Rd, [Rn, Rm] */
926const void tg05_4(arm_state *arm, UINT32 pc, UINT32 insn)  /* LDR Rd, [Rn, Rm] */
927927{
928928   UINT32 addr;
929929   UINT32 rm, rn, rd, op2;
r20717r20718
931931   rm = (insn & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
932932   rn = (insn & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
933933   rd = (insn & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
934   addr = GET_REGISTER(cpustate, rn) + GET_REGISTER(cpustate, rm);
934   addr = GET_REGISTER(arm, rn) + GET_REGISTER(arm, rm);
935935   op2 = READ32(addr);
936   SET_REGISTER(cpustate, rd, op2);
936   SET_REGISTER(arm, rd, op2);
937937   R15 += 2;
938938
939939}
940940
941const void tg05_5(arm_state *cpustate, UINT32 pc, UINT32 insn)  /* LDRH Rd, [Rn, Rm] */
941const void tg05_5(arm_state *arm, UINT32 pc, UINT32 insn)  /* LDRH Rd, [Rn, Rm] */
942942{
943943   UINT32 addr;
944944   UINT32 rm, rn, rd, op2;
r20717r20718
946946   rm = (insn & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
947947   rn = (insn & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
948948   rd = (insn & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
949   addr = GET_REGISTER(cpustate, rn) + GET_REGISTER(cpustate, rm);
949   addr = GET_REGISTER(arm, rn) + GET_REGISTER(arm, rm);
950950   op2 = READ16(addr);
951   SET_REGISTER(cpustate, rd, op2);
951   SET_REGISTER(arm, rd, op2);
952952   R15 += 2;
953953
954954}
955955
956const void tg05_6(arm_state *cpustate, UINT32 pc, UINT32 insn)  /* LDRB Rd, [Rn, Rm] */
956const void tg05_6(arm_state *arm, UINT32 pc, UINT32 insn)  /* LDRB Rd, [Rn, Rm] */
957957{
958958   UINT32 addr;
959959   UINT32 rm, rn, rd, op2;
r20717r20718
961961   rm = (insn & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
962962   rn = (insn & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
963963   rd = (insn & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
964   addr = GET_REGISTER(cpustate, rn) + GET_REGISTER(cpustate, rm);
964   addr = GET_REGISTER(arm, rn) + GET_REGISTER(arm, rm);
965965   op2 = READ8(addr);
966   SET_REGISTER(cpustate, rd, op2);
966   SET_REGISTER(arm, rd, op2);
967967   R15 += 2;
968968
969969}
970970
971const void tg05_7(arm_state *cpustate, UINT32 pc, UINT32 insn)  /* LDSH Rd, [Rn, Rm] */
971const void tg05_7(arm_state *arm, UINT32 pc, UINT32 insn)  /* LDSH Rd, [Rn, Rm] */
972972{
973973   UINT32 addr;
974974   UINT32 rm, rn, rd, op2;
r20717r20718
976976   rm = (insn & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
977977   rn = (insn & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
978978   rd = (insn & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
979   addr = GET_REGISTER(cpustate, rn) + GET_REGISTER(cpustate, rm);
979   addr = GET_REGISTER(arm, rn) + GET_REGISTER(arm, rm);
980980   op2 = READ16(addr);
981981   if (op2 & 0x00008000)
982982   {
983983      op2 |= 0xffff0000;
984984   }
985   SET_REGISTER(cpustate, rd, op2);
985   SET_REGISTER(arm, rd, op2);
986986   R15 += 2;
987987
988988}
989989
990990   /* Word Store w/ Immediate Offset */
991991
992const void tg06_0(arm_state *cpustate, UINT32 pc, UINT32 insn) /* Store */
992const void tg06_0(arm_state *arm, UINT32 pc, UINT32 insn) /* Store */
993993{
994994   UINT32 rn, rd;
995995   INT32 offs;
r20717r20718
997997   rn = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
998998   rd = insn & THUMB_ADDSUB_RD;
999999   offs = ((insn & THUMB_LSOP_OFFS) >> THUMB_LSOP_OFFS_SHIFT) << 2;
1000   WRITE32(GET_REGISTER(cpustate, rn) + offs, GET_REGISTER(cpustate, rd));
1000   WRITE32(GET_REGISTER(arm, rn) + offs, GET_REGISTER(arm, rd));
10011001   R15 += 2;
10021002}
10031003
1004const void tg06_1(arm_state *cpustate, UINT32 pc, UINT32 insn) /* Load */
1004const void tg06_1(arm_state *arm, UINT32 pc, UINT32 insn) /* Load */
10051005{
10061006   UINT32 rn, rd;
10071007   INT32 offs;
r20717r20718
10091009   rn = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
10101010   rd = insn & THUMB_ADDSUB_RD;
10111011   offs = ((insn & THUMB_LSOP_OFFS) >> THUMB_LSOP_OFFS_SHIFT) << 2;
1012   SET_REGISTER(cpustate, rd, READ32(GET_REGISTER(cpustate, rn) + offs)); // fix
1012   SET_REGISTER(arm, rd, READ32(GET_REGISTER(arm, rn) + offs)); // fix
10131013   R15 += 2;
10141014}
10151015
10161016/* Byte Store w/ Immeidate Offset */
10171017
1018const void tg07_0(arm_state *cpustate, UINT32 pc, UINT32 insn) /* Store */
1018const void tg07_0(arm_state *arm, UINT32 pc, UINT32 insn) /* Store */
10191019{
10201020   UINT32 rn, rd;
10211021   INT32 offs;
r20717r20718
10231023   rn = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
10241024   rd = insn & THUMB_ADDSUB_RD;
10251025   offs = (insn & THUMB_LSOP_OFFS) >> THUMB_LSOP_OFFS_SHIFT;
1026   WRITE8(GET_REGISTER(cpustate, rn) + offs, GET_REGISTER(cpustate, rd));
1026   WRITE8(GET_REGISTER(arm, rn) + offs, GET_REGISTER(arm, rd));
10271027   R15 += 2;
10281028}
10291029
1030const void tg07_1(arm_state *cpustate, UINT32 pc, UINT32 insn)  /* Load */
1030const void tg07_1(arm_state *arm, UINT32 pc, UINT32 insn)  /* Load */
10311031{
10321032   UINT32 rn, rd;
10331033   INT32 offs;
r20717r20718
10351035   rn = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
10361036   rd = insn & THUMB_ADDSUB_RD;
10371037   offs = (insn & THUMB_LSOP_OFFS) >> THUMB_LSOP_OFFS_SHIFT;
1038   SET_REGISTER(cpustate, rd, READ8(GET_REGISTER(cpustate, rn) + offs));
1038   SET_REGISTER(arm, rd, READ8(GET_REGISTER(arm, rn) + offs));
10391039   R15 += 2;
10401040}
10411041
10421042/* Load/Store Halfword */
10431043
1044const void tg08_0(arm_state *cpustate, UINT32 pc, UINT32 insn) /* Store */
1044const void tg08_0(arm_state *arm, UINT32 pc, UINT32 insn) /* Store */
10451045{
10461046   UINT32 rs, rd, imm;
10471047
10481048   imm = (insn & THUMB_HALFOP_OFFS) >> THUMB_HALFOP_OFFS_SHIFT;
10491049   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
10501050   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
1051   WRITE16(GET_REGISTER(cpustate, rs) + (imm << 1), GET_REGISTER(cpustate, rd));
1051   WRITE16(GET_REGISTER(arm, rs) + (imm << 1), GET_REGISTER(arm, rd));
10521052   R15 += 2;
10531053}
10541054
1055const void tg08_1(arm_state *cpustate, UINT32 pc, UINT32 insn) /* Load */
1055const void tg08_1(arm_state *arm, UINT32 pc, UINT32 insn) /* Load */
10561056{
10571057   UINT32 rs, rd, imm;
10581058
10591059   imm = (insn & THUMB_HALFOP_OFFS) >> THUMB_HALFOP_OFFS_SHIFT;
10601060   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
10611061   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
1062   SET_REGISTER(cpustate, rd, READ16(GET_REGISTER(cpustate, rs) + (imm << 1)));
1062   SET_REGISTER(arm, rd, READ16(GET_REGISTER(arm, rs) + (imm << 1)));
10631063   R15 += 2;
10641064}
10651065
10661066   /* Stack-Relative Load/Store */
10671067
1068const void tg09_0(arm_state *cpustate, UINT32 pc, UINT32 insn) /* Store */
1068const void tg09_0(arm_state *arm, UINT32 pc, UINT32 insn) /* Store */
10691069{
10701070   UINT32 rd;
10711071   INT32 offs;
10721072
10731073   rd = (insn & THUMB_STACKOP_RD) >> THUMB_STACKOP_RD_SHIFT;
10741074   offs = (UINT8)(insn & THUMB_INSN_IMM);
1075   WRITE32(GET_REGISTER(cpustate, 13) + ((UINT32)offs << 2), GET_REGISTER(cpustate, rd));
1075   WRITE32(GET_REGISTER(arm, 13) + ((UINT32)offs << 2), GET_REGISTER(arm, rd));
10761076   R15 += 2;
10771077}
10781078
1079const void tg09_1(arm_state *cpustate, UINT32 pc, UINT32 insn) /* Load */
1079const void tg09_1(arm_state *arm, UINT32 pc, UINT32 insn) /* Load */
10801080{
10811081   UINT32 readword;
10821082   UINT32 rd;
r20717r20718
10841084
10851085   rd = (insn & THUMB_STACKOP_RD) >> THUMB_STACKOP_RD_SHIFT;
10861086   offs = (UINT8)(insn & THUMB_INSN_IMM);
1087   readword = READ32(GET_REGISTER(cpustate, 13) + ((UINT32)offs << 2));
1088   SET_REGISTER(cpustate, rd, readword);
1087   readword = READ32(GET_REGISTER(arm, 13) + ((UINT32)offs << 2));
1088   SET_REGISTER(arm, rd, readword);
10891089   R15 += 2;
10901090}
10911091
10921092   /* Get relative address */
10931093
1094const void tg0a_0(arm_state *cpustate, UINT32 pc, UINT32 insn)  /* ADD Rd, PC, #nn */
1094const void tg0a_0(arm_state *arm, UINT32 pc, UINT32 insn)  /* ADD Rd, PC, #nn */
10951095{
10961096   UINT32 rd;
10971097   INT32 offs;
10981098
10991099   rd = (insn & THUMB_RELADDR_RD) >> THUMB_RELADDR_RD_SHIFT;
11001100   offs = (UINT8)(insn & THUMB_INSN_IMM) << 2;
1101   SET_REGISTER(cpustate, rd, ((R15 + 4) & ~2) + offs);
1101   SET_REGISTER(arm, rd, ((R15 + 4) & ~2) + offs);
11021102   R15 += 2;
11031103}
11041104
1105const void tg0a_1(arm_state *cpustate, UINT32 pc, UINT32 insn) /* ADD Rd, SP, #nn */
1105const void tg0a_1(arm_state *arm, UINT32 pc, UINT32 insn) /* ADD Rd, SP, #nn */
11061106{
11071107   UINT32 rd;
11081108   INT32 offs;
11091109
11101110   rd = (insn & THUMB_RELADDR_RD) >> THUMB_RELADDR_RD_SHIFT;
11111111   offs = (UINT8)(insn & THUMB_INSN_IMM) << 2;
1112   SET_REGISTER(cpustate, rd, GET_REGISTER(cpustate, 13) + offs);
1112   SET_REGISTER(arm, rd, GET_REGISTER(arm, 13) + offs);
11131113   R15 += 2;
11141114}
11151115
11161116   /* Stack-Related Opcodes */
11171117
1118const void tg0b_0(arm_state *cpustate, UINT32 pc, UINT32 insn) /* ADD SP, #imm */
1118const void tg0b_0(arm_state *arm, UINT32 pc, UINT32 insn) /* ADD SP, #imm */
11191119{
11201120   UINT32 addr;
11211121
11221122
11231123   addr = (insn & THUMB_INSN_IMM);
11241124   addr &= ~THUMB_INSN_IMM_S;
1125   SET_REGISTER(cpustate, 13, GET_REGISTER(cpustate, 13) + ((insn & THUMB_INSN_IMM_S) ? -(addr << 2) : (addr << 2)));
1125   SET_REGISTER(arm, 13, GET_REGISTER(arm, 13) + ((insn & THUMB_INSN_IMM_S) ? -(addr << 2) : (addr << 2)));
11261126   R15 += 2;
11271127
11281128}
11291129
1130const void tg0b_1(arm_state *cpustate, UINT32 pc, UINT32 insn)
1130const void tg0b_1(arm_state *arm, UINT32 pc, UINT32 insn)
11311131{
11321132//  UINT32 addr;
11331133//  INT32 offs;
r20717r20718
11371137
11381138}
11391139
1140const void tg0b_2(arm_state *cpustate, UINT32 pc, UINT32 insn)
1140const void tg0b_2(arm_state *arm, UINT32 pc, UINT32 insn)
11411141{
11421142//  UINT32 addr;
11431143//  INT32 offs;
r20717r20718
11471147
11481148}
11491149
1150const void tg0b_3(arm_state *cpustate, UINT32 pc, UINT32 insn)
1150const void tg0b_3(arm_state *arm, UINT32 pc, UINT32 insn)
11511151{
11521152//  UINT32 addr;
11531153//  INT32 offs;
r20717r20718
11571157
11581158}
11591159
1160const void tg0b_4(arm_state *cpustate, UINT32 pc, UINT32 insn) /* PUSH {Rlist} */
1160const void tg0b_4(arm_state *arm, UINT32 pc, UINT32 insn) /* PUSH {Rlist} */
11611161{
11621162   INT32 offs;
11631163
r20717r20718
11651165   {
11661166      if (insn & (1 << offs))
11671167      {
1168         SET_REGISTER(cpustate, 13, GET_REGISTER(cpustate, 13) - 4);
1169         WRITE32(GET_REGISTER(cpustate, 13), GET_REGISTER(cpustate, offs));
1168         SET_REGISTER(arm, 13, GET_REGISTER(arm, 13) - 4);
1169         WRITE32(GET_REGISTER(arm, 13), GET_REGISTER(arm, offs));
11701170      }
11711171   }
11721172   R15 += 2;
11731173
11741174}
11751175
1176const void tg0b_5(arm_state *cpustate, UINT32 pc, UINT32 insn) /* PUSH {Rlist}{LR} */
1176const void tg0b_5(arm_state *arm, UINT32 pc, UINT32 insn) /* PUSH {Rlist}{LR} */
11771177{
11781178   INT32 offs;
11791179
1180   SET_REGISTER(cpustate, 13, GET_REGISTER(cpustate, 13) - 4);
1181   WRITE32(GET_REGISTER(cpustate, 13), GET_REGISTER(cpustate, 14));
1180   SET_REGISTER(arm, 13, GET_REGISTER(arm, 13) - 4);
1181   WRITE32(GET_REGISTER(arm, 13), GET_REGISTER(arm, 14));
11821182   for (offs = 7; offs >= 0; offs--)
11831183   {
11841184      if (insn & (1 << offs))
11851185      {
1186         SET_REGISTER(cpustate, 13, GET_REGISTER(cpustate, 13) - 4);
1187         WRITE32(GET_REGISTER(cpustate, 13), GET_REGISTER(cpustate, offs));
1186         SET_REGISTER(arm, 13, GET_REGISTER(arm, 13) - 4);
1187         WRITE32(GET_REGISTER(arm, 13), GET_REGISTER(arm, offs));
11881188      }
11891189   }
11901190   R15 += 2;
11911191
11921192}
11931193
1194const void tg0b_6(arm_state *cpustate, UINT32 pc, UINT32 insn)
1194const void tg0b_6(arm_state *arm, UINT32 pc, UINT32 insn)
11951195{
11961196//  UINT32 addr;
11971197//  INT32 offs;
r20717r20718
12011201
12021202}
12031203
1204const void tg0b_7(arm_state *cpustate, UINT32 pc, UINT32 insn)
1204const void tg0b_7(arm_state *arm, UINT32 pc, UINT32 insn)
12051205{
12061206//  UINT32 addr;
12071207//  INT32 offs;
r20717r20718
12111211
12121212}
12131213
1214const void tg0b_8(arm_state *cpustate, UINT32 pc, UINT32 insn)
1214const void tg0b_8(arm_state *arm, UINT32 pc, UINT32 insn)
12151215{
12161216//  UINT32 addr;
12171217//  INT32 offs;
r20717r20718
12211221
12221222}
12231223
1224const void tg0b_9(arm_state *cpustate, UINT32 pc, UINT32 insn)
1224const void tg0b_9(arm_state *arm, UINT32 pc, UINT32 insn)
12251225{
12261226//  UINT32 addr;
12271227//  INT32 offs;
r20717r20718
12311231
12321232}
12331233
1234const void tg0b_a(arm_state *cpustate, UINT32 pc, UINT32 insn)
1234const void tg0b_a(arm_state *arm, UINT32 pc, UINT32 insn)
12351235{
12361236//  UINT32 addr;
12371237//  INT32 offs;
r20717r20718
12411241
12421242}
12431243
1244const void tg0b_b(arm_state *cpustate, UINT32 pc, UINT32 insn)
1244const void tg0b_b(arm_state *arm, UINT32 pc, UINT32 insn)
12451245{
12461246//  UINT32 addr;
12471247//  INT32 offs;
r20717r20718
12511251
12521252}
12531253
1254const void tg0b_c(arm_state *cpustate, UINT32 pc, UINT32 insn) /* POP {Rlist} */
1254const void tg0b_c(arm_state *arm, UINT32 pc, UINT32 insn) /* POP {Rlist} */
12551255{
12561256   INT32 offs;
12571257
r20717r20718
12591259   {
12601260      if (insn & (1 << offs))
12611261      {
1262         SET_REGISTER(cpustate, offs, READ32(GET_REGISTER(cpustate, 13)));
1263         SET_REGISTER(cpustate, 13, GET_REGISTER(cpustate, 13) + 4);
1262         SET_REGISTER(arm, offs, READ32(GET_REGISTER(arm, 13)));
1263         SET_REGISTER(arm, 13, GET_REGISTER(arm, 13) + 4);
12641264      }
12651265   }
12661266   R15 += 2;
12671267
12681268}
12691269
1270const void tg0b_d(arm_state *cpustate, UINT32 pc, UINT32 insn) /* POP {Rlist}{PC} */
1270const void tg0b_d(arm_state *arm, UINT32 pc, UINT32 insn) /* POP {Rlist}{PC} */
12711271{
12721272   INT32 offs;
12731273
r20717r20718
12751275   {
12761276      if (insn & (1 << offs))
12771277      {
1278         SET_REGISTER(cpustate, offs, READ32(GET_REGISTER(cpustate, 13)));
1279         SET_REGISTER(cpustate, 13, GET_REGISTER(cpustate, 13) + 4);
1278         SET_REGISTER(arm, offs, READ32(GET_REGISTER(arm, 13)));
1279         SET_REGISTER(arm, 13, GET_REGISTER(arm, 13) + 4);
12801280      }
12811281   }
1282   UINT32 addr = READ32(GET_REGISTER(cpustate, 13));
1282   UINT32 addr = READ32(GET_REGISTER(arm, 13));
12831283   // in v4T, bit 0 is ignored.  v5 and later, it's an ARM/Thumb flag like the BX instruction
1284   if (cpustate->archRev < 5)
1284   if (arm->archRev < 5)
12851285   {
12861286      R15 = addr & ~1;
12871287   }
r20717r20718
13021302
13031303      R15 = addr;
13041304   }
1305   SET_REGISTER(cpustate, 13, GET_REGISTER(cpustate, 13) + 4);
1305   SET_REGISTER(arm, 13, GET_REGISTER(arm, 13) + 4);
13061306
13071307}
13081308
1309const void tg0b_e(arm_state *cpustate, UINT32 pc, UINT32 insn)
1309const void tg0b_e(arm_state *arm, UINT32 pc, UINT32 insn)
13101310{
13111311//  UINT32 addr;
13121312//  INT32 offs;
r20717r20718
13161316
13171317}
13181318
1319const void tg0b_f(arm_state *cpustate, UINT32 pc, UINT32 insn)
1319const void tg0b_f(arm_state *arm, UINT32 pc, UINT32 insn)
13201320{
13211321//  UINT32 addr;
13221322//  INT32 offs;
r20717r20718
13341334// GBA "BB Ball" performs an unaligned read with A[1:0] = 2 and expects A[1] not to be ignored [BP 800B90A,(R4&3)!=0]
13351335// GBA "Gadget Racers" performs an unaligned read with A[1:0] = 1 and expects A[0] to be ignored [BP B72,(R0&3)!=0]
13361336
1337const void tg0c_0(arm_state *cpustate, UINT32 pc, UINT32 insn) /* Store */
1337const void tg0c_0(arm_state *arm, UINT32 pc, UINT32 insn) /* Store */
13381338{
13391339   UINT32 rd;
13401340   INT32 offs;
r20717r20718
13441344   rd = (insn & THUMB_MULTLS_BASE) >> THUMB_MULTLS_BASE_SHIFT;
13451345
13461346
1347   ld_st_address = GET_REGISTER(cpustate, rd);
1347   ld_st_address = GET_REGISTER(arm, rd);
13481348
13491349   for (offs = 0; offs < 8; offs++)
13501350   {
13511351      if (insn & (1 << offs))
13521352      {
1353         WRITE32(ld_st_address & ~3, GET_REGISTER(cpustate, offs));
1353         WRITE32(ld_st_address & ~3, GET_REGISTER(arm, offs));
13541354         ld_st_address += 4;
13551355      }
13561356   }
1357   SET_REGISTER(cpustate, rd, ld_st_address);
1357   SET_REGISTER(arm, rd, ld_st_address);
13581358   R15 += 2;
13591359}
13601360
13611361
1362const void tg0c_1(arm_state *cpustate, UINT32 pc, UINT32 insn) /* Load */
1362const void tg0c_1(arm_state *arm, UINT32 pc, UINT32 insn) /* Load */
13631363{
13641364   UINT32 rd;
13651365   INT32 offs;
r20717r20718
13691369   rd = (insn & THUMB_MULTLS_BASE) >> THUMB_MULTLS_BASE_SHIFT;
13701370
13711371
1372   ld_st_address = GET_REGISTER(cpustate, rd);
1372   ld_st_address = GET_REGISTER(arm, rd);
13731373
13741374
13751375   int rd_in_list;
r20717r20718
13791379   {
13801380      if (insn & (1 << offs))
13811381      {
1382         SET_REGISTER(cpustate, offs, READ32(ld_st_address & ~1));
1382         SET_REGISTER(arm, offs, READ32(ld_st_address & ~1));
13831383         ld_st_address += 4;
13841384      }
13851385   }
13861386
13871387   if (!rd_in_list)
1388      SET_REGISTER(cpustate, rd, ld_st_address);
1388      SET_REGISTER(arm, rd, ld_st_address);
13891389
13901390   R15 += 2;
13911391}
13921392
13931393/* Conditional Branch */
13941394
1395const void tg0d_0(arm_state *cpustate, UINT32 pc, UINT32 insn) // COND_EQ:
1395const void tg0d_0(arm_state *arm, UINT32 pc, UINT32 insn) // COND_EQ:
13961396{
13971397   INT32 offs;
13981398
r20717r20718
14091409
14101410}
14111411
1412const void tg0d_1(arm_state *cpustate, UINT32 pc, UINT32 insn) // COND_NE:
1412const void tg0d_1(arm_state *arm, UINT32 pc, UINT32 insn) // COND_NE:
14131413{
14141414   INT32 offs;
14151415
r20717r20718
14261426
14271427}
14281428
1429const void tg0d_2(arm_state *cpustate, UINT32 pc, UINT32 insn) // COND_CS:
1429const void tg0d_2(arm_state *arm, UINT32 pc, UINT32 insn) // COND_CS:
14301430{
14311431   INT32 offs;
14321432
r20717r20718
14431443
14441444}
14451445
1446const void tg0d_3(arm_state *cpustate, UINT32 pc, UINT32 insn) // COND_CC:
1446const void tg0d_3(arm_state *arm, UINT32 pc, UINT32 insn) // COND_CC:
14471447{
14481448   INT32 offs;
14491449
r20717r20718
14601460
14611461}
14621462
1463const void tg0d_4(arm_state *cpustate, UINT32 pc, UINT32 insn) // COND_MI:
1463const void tg0d_4(arm_state *arm, UINT32 pc, UINT32 insn) // COND_MI:
14641464{
14651465   INT32 offs;
14661466
r20717r20718
14771477
14781478}
14791479
1480const void tg0d_5(arm_state *cpustate, UINT32 pc, UINT32 insn) // COND_PL:
1480const void tg0d_5(arm_state *arm, UINT32 pc, UINT32 insn) // COND_PL:
14811481{
14821482   INT32 offs;
14831483
r20717r20718
14941494
14951495}
14961496
1497const void tg0d_6(arm_state *cpustate, UINT32 pc, UINT32 insn) // COND_VS:
1497const void tg0d_6(arm_state *arm, UINT32 pc, UINT32 insn) // COND_VS:
14981498{
14991499   INT32 offs;
15001500
r20717r20718
15111511
15121512}
15131513
1514const void tg0d_7(arm_state *cpustate, UINT32 pc, UINT32 insn) // COND_VC:
1514const void tg0d_7(arm_state *arm, UINT32 pc, UINT32 insn) // COND_VC:
15151515{
15161516   INT32 offs;
15171517
r20717r20718
15281528
15291529}
15301530
1531const void tg0d_8(arm_state *cpustate, UINT32 pc, UINT32 insn) // COND_HI:
1531const void tg0d_8(arm_state *arm, UINT32 pc, UINT32 insn) // COND_HI:
15321532{
15331533   INT32 offs;
15341534
r20717r20718
15451545
15461546}
15471547
1548const void tg0d_9(arm_state *cpustate, UINT32 pc, UINT32 insn) // COND_LS:
1548const void tg0d_9(arm_state *arm, UINT32 pc, UINT32 insn) // COND_LS:
15491549{
15501550   INT32 offs;
15511551
r20717r20718
15621562
15631563}
15641564
1565const void tg0d_a(arm_state *cpustate, UINT32 pc, UINT32 insn) // COND_GE:
1565const void tg0d_a(arm_state *arm, UINT32 pc, UINT32 insn) // COND_GE:
15661566{
15671567   INT32 offs;
15681568
r20717r20718
15791579
15801580}
15811581
1582const void tg0d_b(arm_state *cpustate, UINT32 pc, UINT32 insn) // COND_LT:
1582const void tg0d_b(arm_state *arm, UINT32 pc, UINT32 insn) // COND_LT:
15831583{
15841584   INT32 offs;
15851585
r20717r20718
15961596
15971597}
15981598
1599const void tg0d_c(arm_state *cpustate, UINT32 pc, UINT32 insn) // COND_GT:
1599const void tg0d_c(arm_state *arm, UINT32 pc, UINT32 insn) // COND_GT:
16001600{
16011601   INT32 offs;
16021602
r20717r20718
16131613
16141614}
16151615
1616const void tg0d_d(arm_state *cpustate, UINT32 pc, UINT32 insn) // COND_LE:
1616const void tg0d_d(arm_state *arm, UINT32 pc, UINT32 insn) // COND_LE:
16171617{
16181618   INT32 offs;
16191619
r20717r20718
16301630
16311631}
16321632
1633const void tg0d_e(arm_state *cpustate, UINT32 pc, UINT32 insn) // COND_AL:
1633const void tg0d_e(arm_state *arm, UINT32 pc, UINT32 insn) // COND_AL:
16341634{
16351635//  INT32 offs;
16361636
r20717r20718
16411641
16421642}
16431643
1644const void tg0d_f(arm_state *cpustate, UINT32 pc, UINT32 insn) // COND_NV:   // SWI (this is sort of a "hole" in the opcode encoding)
1644const void tg0d_f(arm_state *arm, UINT32 pc, UINT32 insn) // COND_NV:   // SWI (this is sort of a "hole" in the opcode encoding)
16451645{
16461646//  INT32 offs;
16471647
16481648//    offs = (INT8)(insn & THUMB_INSN_IMM);
16491649
16501650//case
1651   cpustate->pendingSwi = 1;
1651   arm->pendingSwi = 1;
16521652   ARM7_CHECKIRQ;
16531653
16541654}
16551655
16561656   /* B #offs */
16571657
1658const void tg0e_0(arm_state *cpustate, UINT32 pc, UINT32 insn)
1658const void tg0e_0(arm_state *arm, UINT32 pc, UINT32 insn)
16591659{
16601660   INT32 offs;
16611661
r20717r20718
16681668}
16691669
16701670
1671const void tg0e_1(arm_state *cpustate, UINT32 pc, UINT32 insn)
1671const void tg0e_1(arm_state *arm, UINT32 pc, UINT32 insn)
16721672{
16731673   UINT32 addr;
16741674
1675   addr = GET_REGISTER(cpustate, 14);
1675   addr = GET_REGISTER(arm, 14);
16761676   addr += (insn & THUMB_BLOP_OFFS) << 1;
16771677   addr &= 0xfffffffc;
1678   SET_REGISTER(cpustate, 14, (R15 + 4) | 1);
1678   SET_REGISTER(arm, 14, (R15 + 4) | 1);
16791679   R15 = addr;
16801680}
16811681
16821682   /* BL */
16831683
1684const void tg0f_0(arm_state *cpustate, UINT32 pc, UINT32 insn)
1684const void tg0f_0(arm_state *arm, UINT32 pc, UINT32 insn)
16851685{
16861686   UINT32 addr;
16871687
r20717r20718
16911691      addr |= 0xff800000;
16921692   }
16931693   addr += R15 + 4;
1694   SET_REGISTER(cpustate, 14, addr);
1694   SET_REGISTER(arm, 14, addr);
16951695   R15 += 2;
16961696}
16971697
16981698
1699const void tg0f_1(arm_state *cpustate, UINT32 pc, UINT32 insn) /* BL */
1699const void tg0f_1(arm_state *arm, UINT32 pc, UINT32 insn) /* BL */
17001700{
17011701   UINT32 addr;
17021702
1703   addr = GET_REGISTER(cpustate, 14) & ~1;
1703   addr = GET_REGISTER(arm, 14) & ~1;
17041704   addr += (insn & THUMB_BLOP_OFFS) << 1;
1705   SET_REGISTER(cpustate, 14, (R15 + 2) | 1);
1705   SET_REGISTER(arm, 14, (R15 + 2) | 1);
17061706   R15 = addr;
17071707   //R15 += 2;
17081708}
trunk/src/emu/cpu/arm7/arm7help.h
r20717r20718
11/* ARM7 core helper Macros / Functions */
22
33/* Macros that need to be defined according to the cpu implementation specific need */
4#define ARM7REG(reg)        cpustate->sArmRegister[reg]
5#define ARM7_ICOUNT         cpustate->iCount
4#define ARM7REG(reg)        arm->r[reg]
5#define ARM7_ICOUNT         arm->icount
66
77
8extern void SwitchMode(arm_state *cpustate, int cpsr_mode_val);
8extern void SwitchMode(arm_state *arm, int cpsr_mode_val);
99
1010#if 0
1111#define LOG(x) mame_printf_debug x
r20717r20718
7676            | (((sc) != 0) << C_BIT)));              \
7777   R15 += 4;
7878
79void set_cpsr( arm_state *cpustate, UINT32 val);
79void set_cpsr( arm_state *arm, UINT32 val);
8080
8181// used to be functions, but no longer a need, so we'll use define for better speed.
82#define GetRegister(cpustate, rIndex)        ARM7REG(sRegisterTable[GET_MODE][rIndex])
83#define SetRegister(cpustate, rIndex, value) ARM7REG(sRegisterTable[GET_MODE][rIndex]) = value
82#define GetRegister(arm, rIndex)        ARM7REG(sRegisterTable[GET_MODE][rIndex])
83#define SetRegister(arm, rIndex, value) ARM7REG(sRegisterTable[GET_MODE][rIndex]) = value
8484
85#define GetModeRegister(cpustate, mode, rIndex)        ARM7REG(sRegisterTable[mode][rIndex])
86#define SetModeRegister(cpustate, mode, rIndex, value) ARM7REG(sRegisterTable[mode][rIndex]) = value
85#define GetModeRegister(arm, mode, rIndex)        ARM7REG(sRegisterTable[mode][rIndex])
86#define SetModeRegister(arm, mode, rIndex, value) ARM7REG(sRegisterTable[mode][rIndex]) = value
8787
88int arm7_tlb_translate(arm_state *cpustate, UINT32 *addr, int flags);
89void arm7_check_irq_state(arm_state *cpustate);
88int arm7_tlb_translate(arm_state *arm, UINT32 *addr, int flags);
89void arm7_check_irq_state(arm_state *arm);
9090
9191typedef const void (*arm7thumb_ophandler)(arm_state*, UINT32, UINT32);
9292
r20717r20718
9696
9797extern arm7ops_ophandler ops_handler[0x10];
9898
99extern void (*arm7_coproc_dt_r_callback)(arm_state *cpustate, UINT32 insn, UINT32 *prn, UINT32 (*read32)(arm_state *cpustate, UINT32 addr));
100extern void (*arm7_coproc_dt_w_callback)(arm_state *cpustate, UINT32 insn, UINT32 *prn, void (*write32)(arm_state *cpustate, UINT32 addr, UINT32 data));
99extern void (*arm7_coproc_dt_r_callback)(arm_state *arm, UINT32 insn, UINT32 *prn, UINT32 (*read32)(arm_state *arm, UINT32 addr));
100extern void (*arm7_coproc_dt_w_callback)(arm_state *arm, UINT32 insn, UINT32 *prn, void (*write32)(arm_state *arm, UINT32 addr, UINT32 data));
101101
102102
103103/***************************************************************************
104104 * Default Memory Handlers
105105 ***************************************************************************/
106INLINE void arm7_cpu_write32(arm_state *cpustate, UINT32 addr, UINT32 data)
106INLINE void arm7_cpu_write32(arm_state *arm, UINT32 addr, UINT32 data)
107107{
108108   if( COPRO_CTRL & COPRO_CTRL_MMU_EN )
109109   {
110      if (!arm7_tlb_translate( cpustate, &addr, ARM7_TLB_ABORT_D | ARM7_TLB_WRITE ))
110      if (!arm7_tlb_translate( arm, &addr, ARM7_TLB_ABORT_D | ARM7_TLB_WRITE ))
111111      {
112112         return;
113113      }
114114   }
115115
116116   addr &= ~3;
117   if ( cpustate->endian == ENDIANNESS_BIG )
118      cpustate->program->write_dword(addr, data);
117   if ( arm->endian == ENDIANNESS_BIG )
118      arm->program->write_dword(addr, data);
119119   else
120      cpustate->program->write_dword(addr, data);
120      arm->program->write_dword(addr, data);
121121}
122122
123123
124INLINE void arm7_cpu_write16(arm_state *cpustate, UINT32 addr, UINT16 data)
124INLINE void arm7_cpu_write16(arm_state *arm, UINT32 addr, UINT16 data)
125125{
126126   if( COPRO_CTRL & COPRO_CTRL_MMU_EN )
127127   {
128      if (!arm7_tlb_translate( cpustate, &addr, ARM7_TLB_ABORT_D | ARM7_TLB_WRITE ))
128      if (!arm7_tlb_translate( arm, &addr, ARM7_TLB_ABORT_D | ARM7_TLB_WRITE ))
129129      {
130130         return;
131131      }
132132   }
133133
134134   addr &= ~1;
135   if ( cpustate->endian == ENDIANNESS_BIG )
136      cpustate->program->write_word(addr, data);
135   if ( arm->endian == ENDIANNESS_BIG )
136      arm->program->write_word(addr, data);
137137   else
138      cpustate->program->write_word(addr, data);
138      arm->program->write_word(addr, data);
139139}
140140
141INLINE void arm7_cpu_write8(arm_state *cpustate, UINT32 addr, UINT8 data)
141INLINE void arm7_cpu_write8(arm_state *arm, UINT32 addr, UINT8 data)
142142{
143143   if( COPRO_CTRL & COPRO_CTRL_MMU_EN )
144144   {
145      if (!arm7_tlb_translate( cpustate, &addr, ARM7_TLB_ABORT_D | ARM7_TLB_WRITE ))
145      if (!arm7_tlb_translate( arm, &addr, ARM7_TLB_ABORT_D | ARM7_TLB_WRITE ))
146146      {
147147         return;
148148      }
149149   }
150150
151   if ( cpustate->endian == ENDIANNESS_BIG )
152      cpustate->program->write_byte(addr, data);
151   if ( arm->endian == ENDIANNESS_BIG )
152      arm->program->write_byte(addr, data);
153153   else
154      cpustate->program->write_byte(addr, data);
154      arm->program->write_byte(addr, data);
155155}
156156
157INLINE UINT32 arm7_cpu_read32(arm_state *cpustate, UINT32 addr)
157INLINE UINT32 arm7_cpu_read32(arm_state *arm, UINT32 addr)
158158{
159159   UINT32 result;
160160
161161   if( COPRO_CTRL & COPRO_CTRL_MMU_EN )
162162   {
163      if (!arm7_tlb_translate( cpustate, &addr, ARM7_TLB_ABORT_D | ARM7_TLB_READ ))
163      if (!arm7_tlb_translate( arm, &addr, ARM7_TLB_ABORT_D | ARM7_TLB_READ ))
164164      {
165165         return 0;
166166      }
r20717r20718
168168
169169   if (addr & 3)
170170   {
171      if ( cpustate->endian == ENDIANNESS_BIG )
172         result = cpustate->program->read_dword(addr & ~3);
171      if ( arm->endian == ENDIANNESS_BIG )
172         result = arm->program->read_dword(addr & ~3);
173173      else
174         result = cpustate->program->read_dword(addr & ~3);
174         result = arm->program->read_dword(addr & ~3);
175175      result = (result >> (8 * (addr & 3))) | (result << (32 - (8 * (addr & 3))));
176176   }
177177   else
178178   {
179      if ( cpustate->endian == ENDIANNESS_BIG )
180         result = cpustate->program->read_dword(addr);
179      if ( arm->endian == ENDIANNESS_BIG )
180         result = arm->program->read_dword(addr);
181181      else
182         result = cpustate->program->read_dword(addr);
182         result = arm->program->read_dword(addr);
183183   }
184184
185185   return result;
186186}
187187
188INLINE UINT16 arm7_cpu_read16(arm_state *cpustate, UINT32 addr)
188INLINE UINT16 arm7_cpu_read16(arm_state *arm, UINT32 addr)
189189{
190190   UINT16 result;
191191
192192   if( COPRO_CTRL & COPRO_CTRL_MMU_EN )
193193   {
194      if (!arm7_tlb_translate( cpustate, &addr, ARM7_TLB_ABORT_D | ARM7_TLB_READ ))
194      if (!arm7_tlb_translate( arm, &addr, ARM7_TLB_ABORT_D | ARM7_TLB_READ ))
195195      {
196196         return 0;
197197      }
198198   }
199199
200   if ( cpustate->endian == ENDIANNESS_BIG )
201      result = cpustate->program->read_word(addr & ~1);
200   if ( arm->endian == ENDIANNESS_BIG )
201      result = arm->program->read_word(addr & ~1);
202202   else
203      result = cpustate->program->read_word(addr & ~1);
203      result = arm->program->read_word(addr & ~1);
204204
205205   if (addr & 1)
206206   {
r20717r20718
210210   return result;
211211}
212212
213INLINE UINT8 arm7_cpu_read8(arm_state *cpustate, UINT32 addr)
213INLINE UINT8 arm7_cpu_read8(arm_state *arm, UINT32 addr)
214214{
215215   if( COPRO_CTRL & COPRO_CTRL_MMU_EN )
216216   {
217      if (!arm7_tlb_translate( cpustate, &addr, ARM7_TLB_ABORT_D | ARM7_TLB_READ ))
217      if (!arm7_tlb_translate( arm, &addr, ARM7_TLB_ABORT_D | ARM7_TLB_READ ))
218218      {
219219         return 0;
220220      }
221221   }
222222
223223   // Handle through normal 8 bit handler (for 32 bit cpu)
224   if ( cpustate->endian == ENDIANNESS_BIG )
225      return cpustate->program->read_byte(addr);
224   if ( arm->endian == ENDIANNESS_BIG )
225      return arm->program->read_byte(addr);
226226   else
227      return cpustate->program->read_byte(addr);
227      return arm->program->read_byte(addr);
228228}
229229
230230
231231/* Macros that can be re-defined for custom cpu implementations - The core expects these to be defined */
232232/* In this case, we are using the default arm7 handlers (supplied by the core)
233233   - but simply changes these and define your own if needed for cpu implementation specific needs */
234#define READ8(addr)         arm7_cpu_read8(cpustate, addr)
235#define WRITE8(addr,data)   arm7_cpu_write8(cpustate, addr,data)
236#define READ16(addr)        arm7_cpu_read16(cpustate, addr)
237#define WRITE16(addr,data)  arm7_cpu_write16(cpustate, addr,data)
238#define READ32(addr)        arm7_cpu_read32(cpustate, addr)
239#define WRITE32(addr,data)  arm7_cpu_write32(cpustate, addr,data)
234#define READ8(addr)         arm7_cpu_read8(arm, addr)
235#define WRITE8(addr,data)   arm7_cpu_write8(arm, addr,data)
236#define READ16(addr)        arm7_cpu_read16(arm, addr)
237#define WRITE16(addr,data)  arm7_cpu_write16(arm, addr,data)
238#define READ32(addr)        arm7_cpu_read32(arm, addr)
239#define WRITE32(addr,data)  arm7_cpu_write32(arm, addr,data)
240240#define PTR_READ32          &arm7_cpu_read32
241241#define PTR_WRITE32         &arm7_cpu_write32
trunk/src/emu/cpu/arm7/arm7core.h
r20717r20718
8989   /* Undefined Mode - Bank switched registers */
9090   eR13_UND, eR14_UND, eSPSR_UND,
9191
92   kNumRegisters
92   NUM_REGS
9393};
9494
9595/* Coprocessor-related macros */
96#define COPRO_TLB_BASE          cpustate->tlbBase
96#define COPRO_TLB_BASE                   arm->tlbBase
9797#define COPRO_TLB_BASE_MASK                 0xffffc000
9898#define COPRO_TLB_VADDR_FLTI_MASK           0xfff00000
9999#define COPRO_TLB_VADDR_FLTI_MASK_SHIFT     18
r20717r20718
115115#define COPRO_TLB_SECTION_TABLE             2
116116#define COPRO_TLB_FINE_TABLE                3
117117
118#define COPRO_CTRL            cpustate->control
118#define COPRO_CTRL                        arm->control
119119#define COPRO_CTRL_MMU_EN                   0x00000001
120120#define COPRO_CTRL_ADDRFAULT_EN             0x00000002
121121#define COPRO_CTRL_DCACHE_EN                0x00000004
r20717r20718
139139#define COPRO_CTRL_INTVEC_F                 1
140140#define COPRO_CTRL_MASK                     0x0000338f
141141
142#define COPRO_DOMAIN_ACCESS_CONTROL         cpustate->domainAccessControl
142#define COPRO_DOMAIN_ACCESS_CONTROL         arm->domainAccessControl
143143
144#define COPRO_FAULT_STATUS_D        cpustate->faultStatus[0]
145#define COPRO_FAULT_STATUS_P        cpustate->faultStatus[1]
144#define COPRO_FAULT_STATUS_D              arm->faultStatus[0]
145#define COPRO_FAULT_STATUS_P              arm->faultStatus[1]
146146
147#define COPRO_FAULT_ADDRESS         cpustate->faultAddress
147#define COPRO_FAULT_ADDRESS               arm->faultAddress
148148
149#define COPRO_FCSE_PID          cpustate->fcsePID
149#define COPRO_FCSE_PID                   arm->fcsePID
150150
151151/* Coprocessor Registers */
152152#define ARM7COPRO_REGS \
r20717r20718
169169};
170170
171171#define ARM7CORE_REGS                   \
172   UINT32 sArmRegister[kNumRegisters]; \
173   UINT8 pendingIrq;                   \
174   UINT8 pendingFiq;                   \
175   UINT8 pendingAbtD;                  \
176   UINT8 pendingAbtP;                  \
177   UINT8 pendingUnd;                   \
178   UINT8 pendingSwi;                   \
179   INT32 iCount;           \
172   UINT32 r[NUM_REGS]; \
173   UINT32 pendingIrq;                   \
174   UINT32 pendingFiq;                   \
175   UINT32 pendingAbtD;                  \
176   UINT32 pendingAbtP;                  \
177   UINT32 pendingUnd;                   \
178   UINT32 pendingSwi;                   \
179   int icount;           \
180180   endianness_t endian;                \
181181   device_irq_acknowledge_callback irq_callback;       \
182182   legacy_cpu_device *device;      \
183183   address_space *program;         \
184184   direct_read_data *direct;
185185
186//#define ARM7_USE_DRC
186187
188/* forward declaration of implementation-specific state */
189#ifndef ARM7_USE_DRC
190struct arm7imp_state {};
191#else
192struct arm7imp_state;
193#endif
194
187195/* CPU state struct */
188196struct arm_state
189197{
r20717r20718
196204#if ARM7_MMU_ENABLE_HACK
197205   UINT32 mmu_enable_addr; // workaround for "MMU is enabled when PA != VA" problem
198206#endif
207   arm7imp_state impstate;
199208};
200209
201210/****************************************************************************************************
r20717r20718
493502#define R15                     ARM7REG(eR15)
494503#define SPSR                    17                     // SPSR is always the 18th register in our 0 based array sRegisterTable[][18]
495504#define GET_CPSR                ARM7REG(eCPSR)
496#define SET_CPSR(v)             set_cpsr(cpustate,v)
505#define SET_CPSR(v)             set_cpsr(arm,v)
497506#define MODE_FLAG               0xF                    // Mode bits are 4:0 of CPSR, but we ignore bit 4.
498507#define GET_MODE                (GET_CPSR & MODE_FLAG)
499508#define SIGN_BIT                ((UINT32)(1 << 31))
r20717r20718
502511#define THUMB_SIGN_BIT               ((UINT32)(1 << 31))
503512#define THUMB_SIGN_BITS_DIFFER(a, b) (((a)^(b)) >> 31)
504513
505#define MODE32                  (GET_CPSR & 0x10)
506#define MODE26                  (!(GET_CPSR & 0x10))
514#define SR_MODE32               0x10
515
516#define MODE32                  (GET_CPSR & SR_MODE32)
517#define MODE26                  (!(GET_CPSR & SR_MODE32))
507518#define GET_PC                  (MODE32 ? R15 : R15 & 0x03FFFFFC)
508519
509520#define ARM7_TLB_ABORT_D (1 << 0)
r20717r20718
516527#define SET_REGISTER(state, reg, val)  SetRegister(state, reg, val)
517528#define GET_MODE_REGISTER(state, mode, reg)       GetModeRegister(state, mode, reg)
518529#define SET_MODE_REGISTER(state, mode, reg, val)  SetModeRegister(state, mode, reg, val)
519#define ARM7_CHECKIRQ           arm7_check_irq_state(cpustate)
530#define ARM7_CHECKIRQ           arm7_check_irq_state(arm)
520531
521532extern write32_device_func arm7_coproc_do_callback;
522533extern read32_device_func arm7_coproc_rt_r_callback;
523534extern write32_device_func arm7_coproc_rt_w_callback;
524extern void arm7_dt_r_callback(arm_state *cpustate, UINT32 insn, UINT32 *prn, UINT32 (*read32)(arm_state *cpustate, UINT32 addr));
525extern void arm7_dt_w_callback(arm_state *cpustate, UINT32 insn, UINT32 *prn, void (*write32)(arm_state *cpustate, UINT32 addr, UINT32 data));
535extern void arm7_dt_r_callback(arm_state *arm, UINT32 insn, UINT32 *prn, UINT32 (*read32)(arm_state *arm, UINT32 addr));
536extern void arm7_dt_w_callback(arm_state *arm, UINT32 insn, UINT32 *prn, void (*write32)(arm_state *arm, UINT32 addr, UINT32 data));
526537
527538#ifdef UNUSED_DEFINITION
528extern char *(*arm7_dasm_cop_dt_callback)(arm_state *cpustate, char *pBuf, UINT32 opcode, char *pConditionCode, char *pBuf0);
529extern char *(*arm7_dasm_cop_rt_callback)(arm_state *cpustate, char *pBuf, UINT32 opcode, char *pConditionCode, char *pBuf0);
530extern char *(*arm7_dasm_cop_do_callback)(arm_state *cpustate, char *pBuf, UINT32 opcode, char *pConditionCode, char *pBuf0);
539extern char *(*arm7_dasm_cop_dt_callback)(arm_state *arm, char *pBuf, UINT32 opcode, char *pConditionCode, char *pBuf0);
540extern char *(*arm7_dasm_cop_rt_callback)(arm_state *arm, char *pBuf, UINT32 opcode, char *pConditionCode, char *pBuf0);
541extern char *(*arm7_dasm_cop_do_callback)(arm_state *arm, char *pBuf, UINT32 opcode, char *pConditionCode, char *pBuf0);
531542#endif
532543
544/* ARM flavors */
545enum arm_flavor
546{
547   /* ARM7 variants */
548   ARM_TYPE_ARM7,
549   ARM_TYPE_ARM7BE,
550   ARM_TYPE_ARM7500,
551   ARM_TYPE_PXA255,
552   ARM_TYPE_SA1110,
553
554   /* ARM9 variants */
555   ARM_TYPE_ARM9,
556   ARM_TYPE_ARM920T
557};
558
533559#endif /* __ARM7CORE_H__ */
trunk/src/emu/cpu/arm7/arm7thmb.h
r20717r20718
11
22
33
4const void tg00_0(arm_state *cpustate, UINT32 pc, UINT32 insn);
5const void tg00_1(arm_state *cpustate, UINT32 pc, UINT32 insn);
6const void tg01_0(arm_state *cpustate, UINT32 pc, UINT32 insn);
7const void tg01_10(arm_state *cpustate, UINT32 pc, UINT32 insn);
8const void tg01_11(arm_state *cpustate, UINT32 pc, UINT32 insn);
9const void tg01_12(arm_state *cpustate, UINT32 pc, UINT32 insn);
10const void tg01_13(arm_state *cpustate, UINT32 pc, UINT32 insn);
11const void tg02_0(arm_state *cpustate, UINT32 pc, UINT32 insn);
12const void tg02_1(arm_state *cpustate, UINT32 pc, UINT32 insn);
13const void tg03_0(arm_state *cpustate, UINT32 pc, UINT32 insn);
14const void tg03_1(arm_state *cpustate, UINT32 pc, UINT32 insn);
15const void tg04_00_00(arm_state *cpustate, UINT32 pc, UINT32 insn);
16const void tg04_00_01(arm_state *cpustate, UINT32 pc, UINT32 insn);
17const void tg04_00_02(arm_state *cpustate, UINT32 pc, UINT32 insn);
18const void tg04_00_03(arm_state *cpustate, UINT32 pc, UINT32 insn);
19const void tg04_00_04(arm_state *cpustate, UINT32 pc, UINT32 insn);
20const void tg04_00_05(arm_state *cpustate, UINT32 pc, UINT32 insn);
21const void tg04_00_06(arm_state *cpustate, UINT32 pc, UINT32 insn);
22const void tg04_00_07(arm_state *cpustate, UINT32 pc, UINT32 insn);
23const void tg04_00_08(arm_state *cpustate, UINT32 pc, UINT32 insn);
24const void tg04_00_09(arm_state *cpustate, UINT32 pc, UINT32 insn);
25const void tg04_00_0a(arm_state *cpustate, UINT32 pc, UINT32 insn);
26const void tg04_00_0b(arm_state *cpustate, UINT32 pc, UINT32 insn);
27const void tg04_00_0c(arm_state *cpustate, UINT32 pc, UINT32 insn);
28const void tg04_00_0d(arm_state *cpustate, UINT32 pc, UINT32 insn);
29const void tg04_00_0e(arm_state *cpustate, UINT32 pc, UINT32 insn);
30const void tg04_00_0f(arm_state *cpustate, UINT32 pc, UINT32 insn);
31const void tg04_01_00(arm_state *cpustate, UINT32 pc, UINT32 insn);
32const void tg04_01_01(arm_state *cpustate, UINT32 pc, UINT32 insn);
33const void tg04_01_02(arm_state *cpustate, UINT32 pc, UINT32 insn);
34const void tg04_01_03(arm_state *cpustate, UINT32 pc, UINT32 insn);
35const void tg04_01_10(arm_state *cpustate, UINT32 pc, UINT32 insn);
36const void tg04_01_11(arm_state *cpustate, UINT32 pc, UINT32 insn);
37const void tg04_01_12(arm_state *cpustate, UINT32 pc, UINT32 insn);
38const void tg04_01_13(arm_state *cpustate, UINT32 pc, UINT32 insn);
39const void tg04_01_20(arm_state *cpustate, UINT32 pc, UINT32 insn);
40const void tg04_01_21(arm_state *cpustate, UINT32 pc, UINT32 insn);
41const void tg04_01_22(arm_state *cpustate, UINT32 pc, UINT32 insn);
42const void tg04_01_23(arm_state *cpustate, UINT32 pc, UINT32 insn);
43const void tg04_01_30(arm_state *cpustate, UINT32 pc, UINT32 insn);
44const void tg04_01_31(arm_state *cpustate, UINT32 pc, UINT32 insn);
45const void tg04_01_32(arm_state *cpustate, UINT32 pc, UINT32 insn);
46const void tg04_01_33(arm_state *cpustate, UINT32 pc, UINT32 insn);
47const void tg04_0203(arm_state *cpustate, UINT32 pc, UINT32 insn);
48const void tg05_0(arm_state *cpustate, UINT32 pc, UINT32 insn);
49const void tg05_1(arm_state *cpustate, UINT32 pc, UINT32 insn);
50const void tg05_2(arm_state *cpustate, UINT32 pc, UINT32 insn);
51const void tg05_3(arm_state *cpustate, UINT32 pc, UINT32 insn);
52const void tg05_4(arm_state *cpustate, UINT32 pc, UINT32 insn);
53const void tg05_5(arm_state *cpustate, UINT32 pc, UINT32 insn);
54const void tg05_6(arm_state *cpustate, UINT32 pc, UINT32 insn);
55const void tg05_7(arm_state *cpustate, UINT32 pc, UINT32 insn);
56const void tg06_0(arm_state *cpustate, UINT32 pc, UINT32 insn);
57const void tg06_1(arm_state *cpustate, UINT32 pc, UINT32 insn);
58const void tg07_0(arm_state *cpustate, UINT32 pc, UINT32 insn);
59const void tg07_1(arm_state *cpustate, UINT32 pc, UINT32 insn);
60const void tg08_0(arm_state *cpustate, UINT32 pc, UINT32 insn);
61const void tg08_1(arm_state *cpustate, UINT32 pc, UINT32 insn);
62const void tg09_0(arm_state *cpustate, UINT32 pc, UINT32 insn);
63const void tg09_1(arm_state *cpustate, UINT32 pc, UINT32 insn);
64const void tg0a_0(arm_state *cpustate, UINT32 pc, UINT32 insn);
65const void tg0a_1(arm_state *cpustate, UINT32 pc, UINT32 insn);
66const void tg0b_0(arm_state *cpustate, UINT32 pc, UINT32 insn);
67const void tg0b_1(arm_state *cpustate, UINT32 pc, UINT32 insn);
68const void tg0b_2(arm_state *cpustate, UINT32 pc, UINT32 insn);
69const void tg0b_3(arm_state *cpustate, UINT32 pc, UINT32 insn);
70const void tg0b_4(arm_state *cpustate, UINT32 pc, UINT32 insn);
71const void tg0b_5(arm_state *cpustate, UINT32 pc, UINT32 insn);
72const void tg0b_6(arm_state *cpustate, UINT32 pc, UINT32 insn);
73const void tg0b_7(arm_state *cpustate, UINT32 pc, UINT32 insn);
74const void tg0b_8(arm_state *cpustate, UINT32 pc, UINT32 insn);
75const void tg0b_9(arm_state *cpustate, UINT32 pc, UINT32 insn);
76const void tg0b_a(arm_state *cpustate, UINT32 pc, UINT32 insn);
77const void tg0b_b(arm_state *cpustate, UINT32 pc, UINT32 insn);
78const void tg0b_c(arm_state *cpustate, UINT32 pc, UINT32 insn);
79const void tg0b_d(arm_state *cpustate, UINT32 pc, UINT32 insn);
80const void tg0b_e(arm_state *cpustate, UINT32 pc, UINT32 insn);
81const void tg0b_f(arm_state *cpustate, UINT32 pc, UINT32 insn);
82const void tg0c_0(arm_state *cpustate, UINT32 pc, UINT32 insn);
83const void tg0c_1(arm_state *cpustate, UINT32 pc, UINT32 insn);
84const void tg0d_0(arm_state *cpustate, UINT32 pc, UINT32 insn);
85const void tg0d_1(arm_state *cpustate, UINT32 pc, UINT32 insn);
86const void tg0d_2(arm_state *cpustate, UINT32 pc, UINT32 insn);
87const void tg0d_3(arm_state *cpustate, UINT32 pc, UINT32 insn);
88const void tg0d_4(arm_state *cpustate, UINT32 pc, UINT32 insn);
89const void tg0d_5(arm_state *cpustate, UINT32 pc, UINT32 insn);
90const void tg0d_6(arm_state *cpustate, UINT32 pc, UINT32 insn);
91const void tg0d_7(arm_state *cpustate, UINT32 pc, UINT32 insn);
92const void tg0d_8(arm_state *cpustate, UINT32 pc, UINT32 insn);
93const void tg0d_9(arm_state *cpustate, UINT32 pc, UINT32 insn);
94const void tg0d_a(arm_state *cpustate, UINT32 pc, UINT32 insn);
95const void tg0d_b(arm_state *cpustate, UINT32 pc, UINT32 insn);
96const void tg0d_c(arm_state *cpustate, UINT32 pc, UINT32 insn);
97const void tg0d_d(arm_state *cpustate, UINT32 pc, UINT32 insn);
98const void tg0d_e(arm_state *cpustate, UINT32 pc, UINT32 insn);
99const void tg0d_f(arm_state *cpustate, UINT32 pc, UINT32 insn);
100const void tg0e_0(arm_state *cpustate, UINT32 pc, UINT32 insn);
101const void tg0e_1(arm_state *cpustate, UINT32 pc, UINT32 insn);
102const void tg0f_0(arm_state *cpustate, UINT32 pc, UINT32 insn);
103const void tg0f_1(arm_state *cpustate, UINT32 pc, UINT32 insn);
4const void tg00_0(arm_state *arm, UINT32 pc, UINT32 insn);
5const void tg00_1(arm_state *arm, UINT32 pc, UINT32 insn);
6const void tg01_0(arm_state *arm, UINT32 pc, UINT32 insn);
7const void tg01_10(arm_state *arm, UINT32 pc, UINT32 insn);
8const void tg01_11(arm_state *arm, UINT32 pc, UINT32 insn);
9const void tg01_12(arm_state *arm, UINT32 pc, UINT32 insn);
10const void tg01_13(arm_state *arm, UINT32 pc, UINT32 insn);
11const void tg02_0(arm_state *arm, UINT32 pc, UINT32 insn);
12const void tg02_1(arm_state *arm, UINT32 pc, UINT32 insn);
13const void tg03_0(arm_state *arm, UINT32 pc, UINT32 insn);
14const void tg03_1(arm_state *arm, UINT32 pc, UINT32 insn);
15const void tg04_00_00(arm_state *arm, UINT32 pc, UINT32 insn);
16const void tg04_00_01(arm_state *arm, UINT32 pc, UINT32 insn);
17const void tg04_00_02(arm_state *arm, UINT32 pc, UINT32 insn);
18const void tg04_00_03(arm_state *arm, UINT32 pc, UINT32 insn);
19const void tg04_00_04(arm_state *arm, UINT32 pc, UINT32 insn);
20const void tg04_00_05(arm_state *arm, UINT32 pc, UINT32 insn);
21const void tg04_00_06(arm_state *arm, UINT32 pc, UINT32 insn);
22const void tg04_00_07(arm_state *arm, UINT32 pc, UINT32 insn);
23const void tg04_00_08(arm_state *arm, UINT32 pc, UINT32 insn);
24const void tg04_00_09(arm_state *arm, UINT32 pc, UINT32 insn);
25const void tg04_00_0a(arm_state *arm, UINT32 pc, UINT32 insn);
26const void tg04_00_0b(arm_state *arm, UINT32 pc, UINT32 insn);
27const void tg04_00_0c(arm_state *arm, UINT32 pc, UINT32 insn);
28const void tg04_00_0d(arm_state *arm, UINT32 pc, UINT32 insn);
29const void tg04_00_0e(arm_state *arm, UINT32 pc, UINT32 insn);
30const void tg04_00_0f(arm_state *arm, UINT32 pc, UINT32 insn);
31const void tg04_01_00(arm_state *arm, UINT32 pc, UINT32 insn);
32const void tg04_01_01(arm_state *arm, UINT32 pc, UINT32 insn);
33const void tg04_01_02(arm_state *arm, UINT32 pc, UINT32 insn);
34const void tg04_01_03(arm_state *arm, UINT32 pc, UINT32 insn);
35const void tg04_01_10(arm_state *arm, UINT32 pc, UINT32 insn);
36const void tg04_01_11(arm_state *arm, UINT32 pc, UINT32 insn);
37const void tg04_01_12(arm_state *arm, UINT32 pc, UINT32 insn);
38const void tg04_01_13(arm_state *arm, UINT32 pc, UINT32 insn);
39const void tg04_01_20(arm_state *arm, UINT32 pc, UINT32 insn);
40const void tg04_01_21(arm_state *arm, UINT32 pc, UINT32 insn);
41const void tg04_01_22(arm_state *arm, UINT32 pc, UINT32 insn);
42const void tg04_01_23(arm_state *arm, UINT32 pc, UINT32 insn);
43const void tg04_01_30(arm_state *arm, UINT32 pc, UINT32 insn);
44const void tg04_01_31(arm_state *arm, UINT32 pc, UINT32 insn);
45const void tg04_01_32(arm_state *arm, UINT32 pc, UINT32 insn);
46const void tg04_01_33(arm_state *arm, UINT32 pc, UINT32 insn);
47const void tg04_0203(arm_state *arm, UINT32 pc, UINT32 insn);
48const void tg05_0(arm_state *arm, UINT32 pc, UINT32 insn);
49const void tg05_1(arm_state *arm, UINT32 pc, UINT32 insn);
50const void tg05_2(arm_state *arm, UINT32 pc, UINT32 insn);
51const void tg05_3(arm_state *arm, UINT32 pc, UINT32 insn);
52const void tg05_4(arm_state *arm, UINT32 pc, UINT32 insn);
53const void tg05_5(arm_state *arm, UINT32 pc, UINT32 insn);
54const void tg05_6(arm_state *arm, UINT32 pc, UINT32 insn);
55const void tg05_7(arm_state *arm, UINT32 pc, UINT32 insn);
56const void tg06_0(arm_state *arm, UINT32 pc, UINT32 insn);
57const void tg06_1(arm_state *arm, UINT32 pc, UINT32 insn);
58const void tg07_0(arm_state *arm, UINT32 pc, UINT32 insn);
59const void tg07_1(arm_state *arm, UINT32 pc, UINT32 insn);
60const void tg08_0(arm_state *arm, UINT32 pc, UINT32 insn);
61const void tg08_1(arm_state *arm, UINT32 pc, UINT32 insn);
62const void tg09_0(arm_state *arm, UINT32 pc, UINT32 insn);
63const void tg09_1(arm_state *arm, UINT32 pc, UINT32 insn);
64const void tg0a_0(arm_state *arm, UINT32 pc, UINT32 insn);
65const void tg0a_1(arm_state *arm, UINT32 pc, UINT32 insn);
66const void tg0b_0(arm_state *arm, UINT32 pc, UINT32 insn);
67const void tg0b_1(arm_state *arm, UINT32 pc, UINT32 insn);
68const void tg0b_2(arm_state *arm, UINT32 pc, UINT32 insn);
69const void tg0b_3(arm_state *arm, UINT32 pc, UINT32 insn);
70const void tg0b_4(arm_state *arm, UINT32 pc, UINT32 insn);
71const void tg0b_5(arm_state *arm, UINT32 pc, UINT32 insn);
72const void tg0b_6(arm_state *arm, UINT32 pc, UINT32 insn);
73const void tg0b_7(arm_state *arm, UINT32 pc, UINT32 insn);
74const void tg0b_8(arm_state *arm, UINT32 pc, UINT32 insn);
75const void tg0b_9(arm_state *arm, UINT32 pc, UINT32 insn);
76const void tg0b_a(arm_state *arm, UINT32 pc, UINT32 insn);
77const void tg0b_b(arm_state *arm, UINT32 pc, UINT32 insn);
78const void tg0b_c(arm_state *arm, UINT32 pc, UINT32 insn);
79const void tg0b_d(arm_state *arm, UINT32 pc, UINT32 insn);
80const void tg0b_e(arm_state *arm, UINT32 pc, UINT32 insn);
81const void tg0b_f(arm_state *arm, UINT32 pc, UINT32 insn);
82const void tg0c_0(arm_state *arm, UINT32 pc, UINT32 insn);
83const void tg0c_1(arm_state *arm, UINT32 pc, UINT32 insn);
84const void tg0d_0(arm_state *arm, UINT32 pc, UINT32 insn);
85const void tg0d_1(arm_state *arm, UINT32 pc, UINT32 insn);
86const void tg0d_2(arm_state *arm, UINT32 pc, UINT32 insn);
87const void tg0d_3(arm_state *arm, UINT32 pc, UINT32 insn);
88const void tg0d_4(arm_state *arm, UINT32 pc, UINT32 insn);
89const void tg0d_5(arm_state *arm, UINT32 pc, UINT32 insn);
90const void tg0d_6(arm_state *arm, UINT32 pc, UINT32 insn);
91const void tg0d_7(arm_state *arm, UINT32 pc, UINT32 insn);
92const void tg0d_8(arm_state *arm, UINT32 pc, UINT32 insn);
93const void tg0d_9(arm_state *arm, UINT32 pc, UINT32 insn);
94const void tg0d_a(arm_state *arm, UINT32 pc, UINT32 insn);
95const void tg0d_b(arm_state *arm, UINT32 pc, UINT32 insn);
96const void tg0d_c(arm_state *arm, UINT32 pc, UINT32 insn);
97const void tg0d_d(arm_state *arm, UINT32 pc, UINT32 insn);
98const void tg0d_e(arm_state *arm, UINT32 pc, UINT32 insn);
99const void tg0d_f(arm_state *arm, UINT32 pc, UINT32 insn);
100const void tg0e_0(arm_state *arm, UINT32 pc, UINT32 insn);
101const void tg0e_1(arm_state *arm, UINT32 pc, UINT32 insn);
102const void tg0f_0(arm_state *arm, UINT32 pc, UINT32 insn);
103const void tg0f_1(arm_state *arm, UINT32 pc, UINT32 insn);
trunk/src/emu/cpu/arm7/arm7.c
r20717r20718
4646static DECLARE_WRITE32_DEVICE_HANDLER(arm7_do_callback);
4747static DECLARE_READ32_DEVICE_HANDLER(arm7_rt_r_callback);
4848static DECLARE_WRITE32_DEVICE_HANDLER(arm7_rt_w_callback);
49void arm7_dt_r_callback(arm_state *cpustate, UINT32 insn, UINT32 *prn, UINT32 (*read32)(arm_state *cpustate, UINT32 addr));
50void arm7_dt_w_callback(arm_state *cpustate, UINT32 insn, UINT32 *prn, void (*write32)(arm_state *cpustate, UINT32 addr, UINT32 data));
49void arm7_dt_r_callback(arm_state *arm, UINT32 insn, UINT32 *prn, UINT32 (*read32)(arm_state *arm, UINT32 addr));
50void arm7_dt_w_callback(arm_state *arm, UINT32 insn, UINT32 *prn, void (*write32)(arm_state *arm, UINT32 addr, UINT32 data));
5151
5252// holder for the co processor Data Transfer Read & Write Callback funcs
53void (*arm7_coproc_dt_r_callback)(arm_state *cpustate, UINT32 insn, UINT32 *prn, UINT32 (*read32)(arm_state *cpustate, UINT32 addr));
54void (*arm7_coproc_dt_w_callback)(arm_state *cpustate, UINT32 insn, UINT32 *prn, void (*write32)(arm_state *cpustate, UINT32 addr, UINT32 data));
53void (*arm7_coproc_dt_r_callback)(arm_state *arm, UINT32 insn, UINT32 *prn, UINT32 (*read32)(arm_state *arm, UINT32 addr));
54void (*arm7_coproc_dt_w_callback)(arm_state *arm, UINT32 insn, UINT32 *prn, void (*write32)(arm_state *arm, UINT32 addr, UINT32 data));
5555
5656
5757INLINE arm_state *get_safe_token(device_t *device)
r20717r20718
6161   return (arm_state *)downcast<legacy_cpu_device *>(device)->token();
6262}
6363
64void set_cpsr( arm_state *cpustate, UINT32 val)
64void set_cpsr( arm_state *arm, UINT32 val)
6565{
66   if (cpustate->archFlags & eARM_ARCHFLAGS_MODE26)
66   if (arm->archFlags & eARM_ARCHFLAGS_MODE26)
6767   {
6868      if ((val & 0x10) != (ARM7REG(eCPSR) & 0x10))
6969      {
r20717r20718
113113   FAULT_PERMISSION,
114114};
115115
116INLINE UINT32 arm7_tlb_get_first_level_descriptor( arm_state *cpustate, UINT32 vaddr )
116INLINE UINT32 arm7_tlb_get_first_level_descriptor( arm_state *arm, UINT32 vaddr )
117117{
118118   UINT32 entry_paddr = ( COPRO_TLB_BASE & COPRO_TLB_BASE_MASK ) | ( ( vaddr & COPRO_TLB_VADDR_FLTI_MASK ) >> COPRO_TLB_VADDR_FLTI_MASK_SHIFT );
119   return cpustate->program->read_dword( entry_paddr );
119   return arm->program->read_dword( entry_paddr );
120120}
121121
122INLINE UINT32 arm7_tlb_get_second_level_descriptor( arm_state *cpustate, UINT32 granularity, UINT32 first_desc, UINT32 vaddr )
122// COARSE, desc_level1, vaddr
123INLINE UINT32 arm7_tlb_get_second_level_descriptor( arm_state *arm, UINT32 granularity, UINT32 first_desc, UINT32 vaddr )
123124{
124125   UINT32 desc_lvl2 = vaddr;
125126
r20717r20718
137138         break;
138139   }
139140
140   return cpustate->program->read_dword( desc_lvl2 );
141   return arm->program->read_dword( desc_lvl2 );
141142}
142143
143INLINE int detect_fault( arm_state *cpustate, int permission, int ap, int flags)
144INLINE int detect_fault( arm_state *arm, int permission, int ap, int flags)
144145{
145146   switch (permission)
146147   {
r20717r20718
225226   return FAULT_NONE;
226227}
227228
228int arm7_tlb_translate(arm_state *cpustate, UINT32 *addr, int flags)
229int arm7_tlb_translate(arm_state *arm, UINT32 *addr, int flags)
229230{
230231   UINT32 desc_lvl1;
231232   UINT32 desc_lvl2 = 0;
r20717r20718
242243      }
243244   }
244245
245   desc_lvl1 = arm7_tlb_get_first_level_descriptor( cpustate, vaddr );
246   desc_lvl1 = arm7_tlb_get_first_level_descriptor( arm, vaddr );
246247
247248   paddr = vaddr;
248249
249250#if ARM7_MMU_ENABLE_HACK
250   if ((R15 == (cpustate->mmu_enable_addr + 4)) || (R15 == (cpustate->mmu_enable_addr + 8)))
251   if ((R15 == (arm->mmu_enable_addr + 4)) || (R15 == (arm->mmu_enable_addr + 8)))
251252   {
252253      LOG( ( "ARM7: fetch flat, PC = %08x, vaddr = %08x\n", R15, vaddr ) );
253254      *addr = vaddr;
r20717r20718
255256   }
256257   else
257258   {
258      cpustate->mmu_enable_addr = 1;
259      arm->mmu_enable_addr = 1;
259260   }
260261#endif
261262
r20717r20718
271272            LOG( ( "ARM7: Translation fault on unmapped virtual address, PC = %08x, vaddr = %08x\n", R15, vaddr ) );
272273            COPRO_FAULT_STATUS_D = (5 << 0); // 5 = section translation fault
273274            COPRO_FAULT_ADDRESS = vaddr;
274            cpustate->pendingAbtD = 1;
275            arm->pendingAbtD = 1;
275276         }
276277         else if (flags & ARM7_TLB_ABORT_P)
277278         {
278279            LOG( ( "ARM7: Translation fault on unmapped virtual address, PC = %08x, vaddr = %08x\n", R15, vaddr ) );
279            cpustate->pendingAbtP = 1;
280            arm->pendingAbtP = 1;
280281         }
281282         return FALSE;
282283      case COPRO_TLB_COARSE_TABLE:
283284         // Entry is the physical address of a coarse second-level table
284285         if ((permission == 1) || (permission == 3))
285286         {
286            desc_lvl2 = arm7_tlb_get_second_level_descriptor( cpustate, TLB_COARSE, desc_lvl1, vaddr );
287            desc_lvl2 = arm7_tlb_get_second_level_descriptor( arm, TLB_COARSE, desc_lvl1, vaddr );
287288         }
288289         else
289290         {
r20717r20718
292293         break;
293294      case COPRO_TLB_SECTION_TABLE:
294295         {
295         // Entry is a section
296         UINT8 ap = (desc_lvl1 >> 10) & 3;
297         int fault = detect_fault( cpustate, permission, ap, flags);
298         if (fault == FAULT_NONE)
299         {
300            paddr = ( desc_lvl1 & COPRO_TLB_SECTION_PAGE_MASK ) | ( vaddr & ~COPRO_TLB_SECTION_PAGE_MASK );
301         }
302         else
303         {
304            if (flags & ARM7_TLB_ABORT_D)
296            // Entry is a section
297            UINT8 ap = (desc_lvl1 >> 10) & 3;
298            int fault = detect_fault( arm, permission, ap, flags);
299            if (fault == FAULT_NONE)
305300            {
306               LOG( ( "ARM7: Section Table, Section %s fault on virtual address, vaddr = %08x, PC = %08x\n", (fault == FAULT_DOMAIN) ? "domain" : "permission", vaddr, R15 ) );
307               COPRO_FAULT_STATUS_D = ((fault == FAULT_DOMAIN) ? (9 << 0) : (13 << 0)) | (domain << 4); // 9 = section domain fault, 13 = section permission fault
308               COPRO_FAULT_ADDRESS = vaddr;
309               cpustate->pendingAbtD = 1;
310               LOG( ( "vaddr %08X desc_lvl1 %08X domain %d permission %d ap %d s %d r %d mode %d read %d write %d\n",
311                  vaddr, desc_lvl1, domain, permission, ap, (COPRO_CTRL & COPRO_CTRL_SYSTEM) ? 1 : 0, (COPRO_CTRL & COPRO_CTRL_ROM) ? 1 : 0,
312                  GET_MODE, flags & ARM7_TLB_READ ? 1 : 0,  flags & ARM7_TLB_WRITE ? 1 : 0) );
301               paddr = ( desc_lvl1 & COPRO_TLB_SECTION_PAGE_MASK ) | ( vaddr & ~COPRO_TLB_SECTION_PAGE_MASK );
313302            }
314            else if (flags & ARM7_TLB_ABORT_P)
303            else
315304            {
316               LOG( ( "ARM7: Section Table, Section %s fault on virtual address, vaddr = %08x, PC = %08x\n", (fault == FAULT_DOMAIN) ? "domain" : "permission", vaddr, R15 ) );
317               cpustate->pendingAbtP = 1;
305               if (flags & ARM7_TLB_ABORT_D)
306               {
307                  LOG( ( "ARM7: Section Table, Section %s fault on virtual address, vaddr = %08x, PC = %08x\n", (fault == FAULT_DOMAIN) ? "domain" : "permission", vaddr, R15 ) );
308                  COPRO_FAULT_STATUS_D = ((fault == FAULT_DOMAIN) ? (9 << 0) : (13 << 0)) | (domain << 4); // 9 = section domain fault, 13 = section permission fault
309                  COPRO_FAULT_ADDRESS = vaddr;
310                  arm->pendingAbtD = 1;
311                  LOG( ( "vaddr %08X desc_lvl1 %08X domain %d permission %d ap %d s %d r %d mode %d read %d write %d\n",
312                     vaddr, desc_lvl1, domain, permission, ap, (COPRO_CTRL & COPRO_CTRL_SYSTEM) ? 1 : 0, (COPRO_CTRL & COPRO_CTRL_ROM) ? 1 : 0,
313                     GET_MODE, flags & ARM7_TLB_READ ? 1 : 0,  flags & ARM7_TLB_WRITE ? 1 : 0) );
314               }
315               else if (flags & ARM7_TLB_ABORT_P)
316               {
317                  LOG( ( "ARM7: Section Table, Section %s fault on virtual address, vaddr = %08x, PC = %08x\n", (fault == FAULT_DOMAIN) ? "domain" : "permission", vaddr, R15 ) );
318                  arm->pendingAbtP = 1;
319               }
320               return FALSE;
318321            }
319            return FALSE;
320322         }
321         }
322323         break;
323324      case COPRO_TLB_FINE_TABLE:
324325         // Entry is the physical address of a fine second-level table
r20717r20718
340341               LOG( ( "ARM7: Translation fault on unmapped virtual address, vaddr = %08x, PC %08X\n", vaddr, R15 ) );
341342               COPRO_FAULT_STATUS_D = (7 << 0) | (domain << 4); // 7 = page translation fault
342343               COPRO_FAULT_ADDRESS = vaddr;
343               cpustate->pendingAbtD = 1;
344               arm->pendingAbtD = 1;
344345            }
345346            else if (flags & ARM7_TLB_ABORT_P)
346347            {
347348               LOG( ( "ARM7: Translation fault on unmapped virtual address, vaddr = %08x, PC %08X\n", vaddr, R15 ) );
348               cpustate->pendingAbtP = 1;
349               arm->pendingAbtP = 1;
349350            }
350351            return FALSE;
351352         case COPRO_TLB_LARGE_PAGE:
r20717r20718
356357            // Small page descriptor
357358            {
358359               UINT8 ap = ((((desc_lvl2 >> 4) & 0xFF) >> (((vaddr >> 10) & 3) << 1)) & 3);
359               int fault = detect_fault( cpustate, permission, ap, flags);
360               int fault = detect_fault( arm, permission, ap, flags);
360361               if (fault == FAULT_NONE)
361362               {
362363                  paddr = ( desc_lvl2 & COPRO_TLB_SMALL_PAGE_MASK ) | ( vaddr & ~COPRO_TLB_SMALL_PAGE_MASK );
r20717r20718
369370                     LOG( ( "ARM7: Page Table, Section %s fault on virtual address, vaddr = %08x, PC = %08x\n", (fault == FAULT_DOMAIN) ? "domain" : "permission", vaddr, R15 ) );
370371                     COPRO_FAULT_STATUS_D = ((fault == FAULT_DOMAIN) ? (11 << 0) : (15 << 0)) | (domain << 4); // 11 = page domain fault, 15 = page permission fault
371372                     COPRO_FAULT_ADDRESS = vaddr;
372                     cpustate->pendingAbtD = 1;
373                     arm->pendingAbtD = 1;
373374                     LOG( ( "vaddr %08X desc_lvl2 %08X domain %d permission %d ap %d s %d r %d mode %d read %d write %d\n",
374375                        vaddr, desc_lvl2, domain, permission, ap, (COPRO_CTRL & COPRO_CTRL_SYSTEM) ? 1 : 0, (COPRO_CTRL & COPRO_CTRL_ROM) ? 1 : 0,
375376                        GET_MODE, flags & ARM7_TLB_READ ? 1 : 0,  flags & ARM7_TLB_WRITE ? 1 : 0) );
r20717r20718
377378                  else if (flags & ARM7_TLB_ABORT_P)
378379                  {
379380                     LOG( ( "ARM7: Page Table, Section %s fault on virtual address, vaddr = %08x, PC = %08x\n", (fault == FAULT_DOMAIN) ? "domain" : "permission", vaddr, R15 ) );
380                     cpustate->pendingAbtP = 1;
381                     arm->pendingAbtP = 1;
381382                  }
382383                  return FALSE;
383384               }
r20717r20718
399400
400401static CPU_TRANSLATE( arm7 )
401402{
402   arm_state *cpustate = (device != NULL) ? (arm_state *)device->token() : NULL;
403   arm_state *arm = (device != NULL) ? (arm_state *)device->token() : NULL;
403404
404405   /* only applies to the program address space and only does something if the MMU's enabled */
405406   if( space == AS_PROGRAM && ( COPRO_CTRL & COPRO_CTRL_MMU_EN ) )
406407   {
407      return arm7_tlb_translate(cpustate, address, 0);
408      return arm7_tlb_translate(arm, address, 0);
408409   }
409410   return TRUE;
410411}
r20717r20718
418419 **************************************************************************/
419420static CPU_INIT( arm7 )
420421{
421   arm_state *cpustate = get_safe_token(device);
422   arm_state *arm = get_safe_token(device);
422423
423424   // must call core
424425   arm7_core_init(device, "arm7");
425426
426   cpustate->irq_callback = irqcallback;
427   cpustate->device = device;
428   cpustate->program = &device->space(AS_PROGRAM);
429   cpustate->direct = &cpustate->program->direct();
427   arm->irq_callback = irqcallback;
428   arm->device = device;
429   arm->program = &device->space(AS_PROGRAM);
430   arm->direct = &arm->program->direct();
430431
431432   // setup co-proc callbacks
432433   arm7_coproc_do_callback = arm7_do_callback;
r20717r20718
438439
439440static CPU_RESET( arm7 )
440441{
441   arm_state *cpustate = get_safe_token(device);
442   arm_state *arm = get_safe_token(device);
442443
443444   // must call core reset
444445   arm7_core_reset(device);
445446
446   cpustate->archRev = 4;  // ARMv4
447   cpustate->archFlags = eARM_ARCHFLAGS_T; // has Thumb
447   arm->archRev = 4;  // ARMv4
448   arm->archFlags = eARM_ARCHFLAGS_T; // has Thumb
448449}
449450
450451static CPU_RESET( arm7_be )
451452{
452   arm_state *cpustate = get_safe_token(device);
453   arm_state *arm = get_safe_token(device);
453454
454455   CPU_RESET_CALL( arm7 );
455   cpustate->endian = ENDIANNESS_BIG;
456   arm->endian = ENDIANNESS_BIG;
456457}
457458
458459static CPU_RESET( arm7500 )
459460{
460   arm_state *cpustate = get_safe_token(device);
461   arm_state *arm = get_safe_token(device);
461462
462463   // must call core reset
463464   arm7_core_reset(device);
464465
465   cpustate->archRev = 3;  // ARMv3
466   cpustate->archFlags = eARM_ARCHFLAGS_MODE26;
466   arm->archRev = 3;  // ARMv3
467   arm->archFlags = eARM_ARCHFLAGS_MODE26;
467468}
468469
469470static CPU_RESET( arm9 )
470471{
471   arm_state *cpustate = get_safe_token(device);
472   arm_state *arm = get_safe_token(device);
472473
473474   // must call core reset
474475   arm7_core_reset(device);
475476
476   cpustate->archRev = 5;  // ARMv5
477   cpustate->archFlags = eARM_ARCHFLAGS_T | eARM_ARCHFLAGS_E;  // has TE extensions
477   arm->archRev = 5;  // ARMv5
478   arm->archFlags = eARM_ARCHFLAGS_T | eARM_ARCHFLAGS_E;  // has TE extensions
478479}
479480
480481static CPU_RESET( arm920t )
481482{
482   arm_state *cpustate = get_safe_token(device);
483   arm_state *arm = get_safe_token(device);
483484
484485   // must call core reset
485486   arm7_core_reset(device);
486487
487   cpustate->archRev = 4;  // ARMv4
488   cpustate->archFlags = eARM_ARCHFLAGS_T; // has T extension
488   arm->archRev = 4;  // ARMv4
489   arm->archFlags = eARM_ARCHFLAGS_T; // has T extension
489490}
490491
491492static CPU_RESET( pxa255 )
492493{
493   arm_state *cpustate = get_safe_token(device);
494   arm_state *arm = get_safe_token(device);
494495
495496   // must call core reset
496497   arm7_core_reset(device);
497498
498   cpustate->archRev = 5;  // ARMv5
499   cpustate->archFlags = eARM_ARCHFLAGS_T | eARM_ARCHFLAGS_E | eARM_ARCHFLAGS_XSCALE;  // has TE and XScale extensions
499   arm->archRev = 5;  // ARMv5
500   arm->archFlags = eARM_ARCHFLAGS_T | eARM_ARCHFLAGS_E | eARM_ARCHFLAGS_XSCALE;  // has TE and XScale extensions
500501}
501502
502503static CPU_RESET( sa1110 )
503504{
504   arm_state *cpustate = get_safe_token(device);
505   arm_state *arm = get_safe_token(device);
505506
506507   // must call core reset
507508   arm7_core_reset(device);
508509
509   cpustate->archRev = 4;  // ARMv4
510   cpustate->archFlags = eARM_ARCHFLAGS_SA;    // has StrongARM, no Thumb, no Enhanced DSP
510   arm->archRev = 4;  // ARMv4
511   arm->archFlags = eARM_ARCHFLAGS_SA;    // has StrongARM, no Thumb, no Enhanced DSP
511512}
512513
513514static CPU_EXIT( arm7 )
r20717r20718
522523{
523524   UINT32 pc;
524525   UINT32 insn;
525   arm_state *cpustate = get_safe_token(device);
526   arm_state *arm = get_safe_token(device);
526527
527528   do
528529   {
529      debugger_instruction_hook(cpustate->device, GET_PC);
530      debugger_instruction_hook(arm->device, GET_PC);
530531
531532      /* handle Thumb instructions if active */
532533      if (T_IS_SET(GET_CPSR))
r20717r20718
540541
541542         if ( COPRO_CTRL & COPRO_CTRL_MMU_EN )
542543         {
543            if (!arm7_tlb_translate(cpustate, &raddr, ARM7_TLB_ABORT_P | ARM7_TLB_READ))
544            if (!arm7_tlb_translate(arm, &raddr, ARM7_TLB_ABORT_P | ARM7_TLB_READ))
544545            {
545546               goto skip_exec;
546547            }
547548         }
548549
549         insn = cpustate->direct->read_decrypted_word(raddr);
550         thumb_handler[(insn & 0xffc0) >> 6](cpustate, pc, insn);
550         insn = arm->direct->read_decrypted_word(raddr);
551         thumb_handler[(insn & 0xffc0) >> 6](arm, pc, insn);
551552
552553      }
553554      else
r20717r20718
562563
563564      if ( COPRO_CTRL & COPRO_CTRL_MMU_EN )
564565      {
565         if (!arm7_tlb_translate(cpustate, &raddr, ARM7_TLB_ABORT_P | ARM7_TLB_READ))
566         if (!arm7_tlb_translate(arm, &raddr, ARM7_TLB_ABORT_P | ARM7_TLB_READ))
566567         {
567568            goto skip_exec;
568569         }
r20717r20718
578579         }
579580#endif
580581
581         insn = cpustate->direct->read_decrypted_dword(raddr);
582         insn = arm->direct->read_decrypted_dword(raddr);
582583
583584         /* process condition codes for this instruction */
584585         switch (insn >> INSN_COND_SHIFT)
r20717r20718
646647         /*******************************************************************/
647648         /* If we got here - condition satisfied, so decode the instruction */
648649         /*******************************************************************/
649         ops_handler[((insn & 0xF000000) >> 24)](cpustate, insn);
650         ops_handler[((insn & 0xF000000) >> 24)](arm, insn);
650651      }
651652
652653skip_exec:
r20717r20718
658659   } while (ARM7_ICOUNT > 0);
659660}
660661
661static void set_irq_line(arm_state *cpustate, int irqline, int state)
662static void set_irq_line(arm_state *arm, int irqline, int state)
662663{
663664   // must call core
664   arm7_core_set_irq_line(cpustate, irqline, state);
665   arm7_core_set_irq_line(arm, irqline, state);
665666}
666667
667668static CPU_DISASSEMBLE( arm7 )
r20717r20718
669670   CPU_DISASSEMBLE( arm7arm );
670671   CPU_DISASSEMBLE( arm7thumb );
671672
672   arm_state *cpustate = get_safe_token(device);
673   arm_state *arm = get_safe_token(device);
673674
674675   if (T_IS_SET(GET_CPSR))
675676      return CPU_DISASSEMBLE_CALL(arm7thumb);
r20717r20718
682683   CPU_DISASSEMBLE( arm7arm_be );
683684   CPU_DISASSEMBLE( arm7thumb_be );
684685
685   arm_state *cpustate = get_safe_token(device);
686   arm_state *arm = get_safe_token(device);
686687
687688   if (T_IS_SET(GET_CPSR))
688689      return CPU_DISASSEMBLE_CALL(arm7thumb_be);
r20717r20718
697698
698699static CPU_SET_INFO( arm7 )
699700{
700   arm_state *cpustate = get_safe_token(device);
701   arm_state *arm = get_safe_token(device);
701702
702703   switch (state)
703704   {
704705      /* --- the following bits of info are set as 64-bit signed integers --- */
705706
706707      /* interrupt lines/exceptions */
707      case CPUINFO_INT_INPUT_STATE + ARM7_IRQ_LINE:                   set_irq_line(cpustate, ARM7_IRQ_LINE, info->i); break;
708      case CPUINFO_INT_INPUT_STATE + ARM7_FIRQ_LINE:                  set_irq_line(cpustate, ARM7_FIRQ_LINE, info->i); break;
709      case CPUINFO_INT_INPUT_STATE + ARM7_ABORT_EXCEPTION:            set_irq_line(cpustate, ARM7_ABORT_EXCEPTION, info->i); break;
710      case CPUINFO_INT_INPUT_STATE + ARM7_ABORT_PREFETCH_EXCEPTION:   set_irq_line(cpustate, ARM7_ABORT_PREFETCH_EXCEPTION, info->i); break;
711      case CPUINFO_INT_INPUT_STATE + ARM7_UNDEFINE_EXCEPTION:         set_irq_line(cpustate, ARM7_UNDEFINE_EXCEPTION, info->i); break;
708      case CPUINFO_INT_INPUT_STATE + ARM7_IRQ_LINE:                   set_irq_line(arm, ARM7_IRQ_LINE, info->i); break;
709      case CPUINFO_INT_INPUT_STATE + ARM7_FIRQ_LINE:                  set_irq_line(arm, ARM7_FIRQ_LINE, info->i); break;
710      case CPUINFO_INT_INPUT_STATE + ARM7_ABORT_EXCEPTION:            set_irq_line(arm, ARM7_ABORT_EXCEPTION, info->i); break;
711      case CPUINFO_INT_INPUT_STATE + ARM7_ABORT_PREFETCH_EXCEPTION:   set_irq_line(arm, ARM7_ABORT_PREFETCH_EXCEPTION, info->i); break;
712      case CPUINFO_INT_INPUT_STATE + ARM7_UNDEFINE_EXCEPTION:         set_irq_line(arm, ARM7_UNDEFINE_EXCEPTION, info->i); break;
712713
713714      /* registers shared by all operating modes */
714715      case CPUINFO_INT_REGISTER + ARM7_R0:            ARM7REG( 0) = info->i;                  break;
r20717r20718
731732
732733      case CPUINFO_INT_PC:
733734      case CPUINFO_INT_REGISTER + ARM7_PC:            R15 = info->i;                          break;
734      case CPUINFO_INT_SP:                            SetRegister(cpustate, 13,info->i);                break;
735      case CPUINFO_INT_SP:                            SetRegister(arm, 13,info->i);                break;
735736
736737      /* FIRQ Mode Shadowed Registers */
737738      case CPUINFO_INT_REGISTER + ARM7_FR8:           ARM7REG(eR8_FIQ)  = info->i;            break;
r20717r20718
773774
774775CPU_GET_INFO( arm7 )
775776{
776   arm_state *cpustate = (device != NULL && device->token() != NULL) ? get_safe_token(device) : NULL;
777   arm_state *arm = (device != NULL && device->token() != NULL) ? get_safe_token(device) : NULL;
777778
778779   switch (state)
779780   {
r20717r20718
802803      case CPUINFO_INT_ADDRBUS_SHIFT + AS_IO:      info->i = 0;                    break;
803804
804805      /* interrupt lines/exceptions */
805      case CPUINFO_INT_INPUT_STATE + ARM7_IRQ_LINE:                   info->i = cpustate->pendingIrq; break;
806      case CPUINFO_INT_INPUT_STATE + ARM7_FIRQ_LINE:                  info->i = cpustate->pendingFiq; break;
807      case CPUINFO_INT_INPUT_STATE + ARM7_ABORT_EXCEPTION:            info->i = cpustate->pendingAbtD; break;
808      case CPUINFO_INT_INPUT_STATE + ARM7_ABORT_PREFETCH_EXCEPTION:   info->i = cpustate->pendingAbtP; break;
809      case CPUINFO_INT_INPUT_STATE + ARM7_UNDEFINE_EXCEPTION:         info->i = cpustate->pendingUnd; break;
806      case CPUINFO_INT_INPUT_STATE + ARM7_IRQ_LINE:                   info->i = arm->pendingIrq; break;
807      case CPUINFO_INT_INPUT_STATE + ARM7_FIRQ_LINE:                  info->i = arm->pendingFiq; break;
808      case CPUINFO_INT_INPUT_STATE + ARM7_ABORT_EXCEPTION:            info->i = arm->pendingAbtD; break;
809      case CPUINFO_INT_INPUT_STATE + ARM7_ABORT_PREFETCH_EXCEPTION:   info->i = arm->pendingAbtP; break;
810      case CPUINFO_INT_INPUT_STATE + ARM7_UNDEFINE_EXCEPTION:         info->i = arm->pendingUnd; break;
810811
811812      /* registers shared by all operating modes */
812813      case CPUINFO_INT_REGISTER + ARM7_R0:    info->i = ARM7REG( 0);                          break;
r20717r20718
829830      case CPUINFO_INT_PREVIOUSPC:            info->i = 0;    /* not implemented */           break;
830831      case CPUINFO_INT_PC:
831832      case CPUINFO_INT_REGISTER + ARM7_PC:    info->i = GET_PC;                                  break;
832      case CPUINFO_INT_SP:                    info->i = GetRegister(cpustate, 13);            break;
833      case CPUINFO_INT_SP:                    info->i = GetRegister(arm, 13);            break;
833834
834835      /* FIRQ Mode Shadowed Registers */
835836      case CPUINFO_INT_REGISTER + ARM7_FR8:   info->i = ARM7REG(eR8_FIQ);                     break;
r20717r20718
10151016
10161017static WRITE32_DEVICE_HANDLER( arm7_do_callback )
10171018{
1018   arm_state *cpustate = get_safe_token(device);
1019   cpustate->pendingUnd = 1;
1019   arm_state *arm = get_safe_token(device);
1020   arm->pendingUnd = 1;
10201021}
10211022
10221023static READ32_DEVICE_HANDLER( arm7_rt_r_callback )
10231024{
1024   arm_state *cpustate = get_safe_token(device);
1025   arm_state *arm = get_safe_token(device);
10251026   UINT32 opcode = offset;
10261027   UINT8 cReg = ( opcode & INSN_COPRO_CREG ) >> INSN_COPRO_CREG_SHIFT;
10271028   UINT8 op2 =  ( opcode & INSN_COPRO_OP2 )  >> INSN_COPRO_OP2_SHIFT;
r20717r20718
10291030   UINT8 cpnum = (opcode & INSN_COPRO_CPNUM) >> INSN_COPRO_CPNUM_SHIFT;
10301031   UINT32 data = 0;
10311032
1032//    printf("cpnum %d cReg %d op2 %d op3 %d (%x)\n", cpnum, cReg, op2, op3, GET_REGISTER(cpustate, 15));
1033//    printf("cpnum %d cReg %d op2 %d op3 %d (%x)\n", cpnum, cReg, op2, op3, GET_REGISTER(arm, 15));
10331034
10341035   // we only handle system copro here
10351036   if (cpnum != 15)
10361037   {
1037      if (cpustate->archFlags & eARM_ARCHFLAGS_XSCALE)
1038      if (arm->archFlags & eARM_ARCHFLAGS_XSCALE)
10381039   {
10391040      // handle XScale specific CP14
10401041      if (cpnum == 14)
r20717r20718
10421043         switch( cReg )
10431044         {
10441045            case 1: // clock counter
1045               data = (UINT32)cpustate->device->total_cycles();
1046               data = (UINT32)arm->device->total_cycles();
10461047               break;
10471048
10481049            default:
r20717r20718
10511052      }
10521053      else
10531054      {
1054         fatalerror("XScale: Unhandled coprocessor %d (archFlags %x)\n", cpnum, cpustate->archFlags);
1055         fatalerror("XScale: Unhandled coprocessor %d (archFlags %x)\n", cpnum, arm->archFlags);
10551056      }
10561057
10571058      return data;
10581059   }
10591060   else
10601061   {
1061      LOG( ("ARM7: Unhandled coprocessor %d (archFlags %x)\n", cpnum, cpustate->archFlags) );
1062      cpustate->pendingUnd = 1;
1062      LOG( ("ARM7: Unhandled coprocessor %d (archFlags %x)\n", cpnum, arm->archFlags) );
1063      arm->pendingUnd = 1;
10631064      return 0;
10641065   }
10651066   }
r20717r20718
10801081      switch(op2)
10811082      {
10821083         case 0:
1083         switch (cpustate->archRev)
1084         switch (arm->archRev)
10841085         {
10851086            case 3: // ARM6 32-bit
10861087            data = 0x41;
10871088            break;
10881089
10891090         case 4: // ARM7/SA11xx
1090            if (cpustate->archFlags & eARM_ARCHFLAGS_SA)
1091            if (arm->archFlags & eARM_ARCHFLAGS_SA)
10911092            {
10921093               // ARM Architecture Version 4
10931094               // Part Number 0xB11 (SA1110)
r20717r20718
11131114
11141115         case 5: // ARM9/10/XScale
11151116            data = 0x41 | (9 << 12);
1116            if (cpustate->archFlags & eARM_ARCHFLAGS_T)
1117            if (arm->archFlags & eARM_ARCHFLAGS_T)
11171118            {
1118               if (cpustate->archFlags & eARM_ARCHFLAGS_E)
1119               if (arm->archFlags & eARM_ARCHFLAGS_E)
11191120               {
1120                  if (cpustate->archFlags & eARM_ARCHFLAGS_J)
1121                  if (arm->archFlags & eARM_ARCHFLAGS_J)
11211122                  {
11221123                     data |= (6<<16);    // v5TEJ
11231124                  }
r20717r20718
11931194
11941195static WRITE32_DEVICE_HANDLER( arm7_rt_w_callback )
11951196{
1196   arm_state *cpustate = get_safe_token(device);
1197   arm_state *arm = get_safe_token(device);
11971198   UINT32 opcode = offset;
11981199   UINT8 cReg = ( opcode & INSN_COPRO_CREG ) >> INSN_COPRO_CREG_SHIFT;
11991200   UINT8 op2 =  ( opcode & INSN_COPRO_OP2 )  >> INSN_COPRO_OP2_SHIFT;
r20717r20718
12111212      else
12121213      {
12131214         LOG( ("ARM7: Unhandled coprocessor %d\n", cpnum) );
1214         cpustate->pendingUnd = 1;
1215         arm->pendingUnd = 1;
12151216         return;
12161217      }
12171218   }
r20717r20718
12411242#if ARM7_MMU_ENABLE_HACK
12421243         if (((data & COPRO_CTRL_MMU_EN) != 0) && ((COPRO_CTRL & COPRO_CTRL_MMU_EN) == 0))
12431244         {
1244            cpustate->mmu_enable_addr = R15;
1245            arm->mmu_enable_addr = R15;
12451246         }
12461247         if (((data & COPRO_CTRL_MMU_EN) == 0) && ((COPRO_CTRL & COPRO_CTRL_MMU_EN) != 0))
12471248         {
1248            if (!arm7_tlb_translate( cpustate, &R15, 0))
1249            if (!arm7_tlb_translate( arm, &R15, 0))
12491250            {
12501251               fatalerror("ARM7_MMU_ENABLE_HACK translate failed\n");
12511252            }
r20717r20718
12951296   }
12961297}
12971298
1298void arm7_dt_r_callback(arm_state *cpustate, UINT32 insn, UINT32 *prn, UINT32 (*read32)(arm_state *cpustate, UINT32 addr))
1299void arm7_dt_r_callback(arm_state *arm, UINT32 insn, UINT32 *prn, UINT32 (*read32)(arm_state *arm, UINT32 addr))
12991300{
13001301   UINT8 cpn = (insn >> 8) & 0xF;
1301   if ((cpustate->archFlags & eARM_ARCHFLAGS_XSCALE) && (cpn == 0))
1302   if ((arm->archFlags & eARM_ARCHFLAGS_XSCALE) && (cpn == 0))
13021303   {
13031304      LOG( ( "arm7_dt_r_callback: DSP Coprocessor 0 (CP0) not yet emulated (PC %08x)\n", GET_PC ) );
13041305   }
13051306   else
13061307   {
1307      cpustate->pendingUnd = 1;
1308      arm->pendingUnd = 1;
13081309   }
13091310}
13101311
1311void arm7_dt_w_callback(arm_state *cpustate, UINT32 insn, UINT32 *prn, void (*write32)(arm_state *cpustate, UINT32 addr, UINT32 data))
1312void arm7_dt_w_callback(arm_state *arm, UINT32 insn, UINT32 *prn, void (*write32)(arm_state *arm, UINT32 addr, UINT32 data))
13121313{
13131314   UINT8 cpn = (insn >> 8) & 0xF;
1314   if ((cpustate->archFlags & eARM_ARCHFLAGS_XSCALE) && (cpn == 0))
1315   if ((arm->archFlags & eARM_ARCHFLAGS_XSCALE) && (cpn == 0))
13151316   {
13161317      LOG( ( "arm7_dt_w_callback: DSP Coprocessor 0 (CP0) not yet emulated (PC %08x)\n", GET_PC ) );
13171318   }
13181319   else
13191320   {
1320      cpustate->pendingUnd = 1;
1321      arm->pendingUnd = 1;
13211322   }
13221323}
13231324
trunk/src/emu/cpu/arm7/arm7ops.c
r20717r20718
33#include "arm7ops.h"
44#include "arm7help.h"
55
6INLINE INT64 saturate_qbit_overflow(arm_state *cpustate, INT64 res)
6INLINE INT64 saturate_qbit_overflow(arm_state *arm, INT64 res)
77{
88   if (res > 2147483647)   // INT32_MAX
99   {   // overflow high? saturate and set Q
r20717r20718
2020}
2121
2222// I could prob. convert to macro, but Switchmode shouldn't occur that often in emulated code..
23void SwitchMode(arm_state *cpustate, int cpsr_mode_val)
23void SwitchMode(arm_state *arm, int cpsr_mode_val)
2424{
2525   UINT32 cspr = GET_CPSR & ~MODE_FLAG;
2626   SET_CPSR(cspr | cpsr_mode_val);
r20717r20718
4545   ROR >32   = Same result as ROR n-32 until amount in range of 1-32 then follow rules
4646*/
4747
48UINT32 decodeShift(arm_state *cpustate, UINT32 insn, UINT32 *pCarry)
48UINT32 decodeShift(arm_state *arm, UINT32 insn, UINT32 *pCarry)
4949{
5050   UINT32 k  = (insn & INSN_OP2_SHIFT) >> INSN_OP2_SHIFT_SHIFT;  // Bits 11-7
51   UINT32 rm = GET_REGISTER(cpustate, insn & INSN_OP2_RM);
51   UINT32 rm = GET_REGISTER(arm, insn & INSN_OP2_RM);
5252   UINT32 t  = (insn & INSN_OP2_SHIFT_TYPE) >> INSN_OP2_SHIFT_TYPE_SHIFT;
5353
5454   if ((insn & INSN_OP2_RM) == 0xf) {
r20717r20718
5959   /* All shift types ending in 1 are Rk, not #k */
6060   if (t & 1)
6161   {
62//      LOG(("%08x:  RegShift %02x %02x\n", R15, k >> 1, GET_REGISTER(cpustate, k >> 1)));
62//      LOG(("%08x:  RegShift %02x %02x\n", R15, k >> 1, GET_REGISTER(arm, k >> 1)));
6363#if ARM7_DEBUG_CORE
6464         if ((insn & 0x80) == 0x80)
6565            LOG(("%08x:  RegShift ERROR (p36)\n", R15));
6666#endif
6767
6868      // see p35 for check on this
69      //k = GET_REGISTER(cpustate, k >> 1) & 0x1f;
69      //k = GET_REGISTER(arm, k >> 1) & 0x1f;
7070
7171      // Keep only the bottom 8 bits for a Register Shift
72      k = GET_REGISTER(cpustate, k >> 1) & 0xff;
72      k = GET_REGISTER(arm, k >> 1) & 0xff;
7373
7474      if (k == 0) /* Register shift by 0 is a no-op */
7575      {
r20717r20718
167167} /* decodeShift */
168168
169169
170static int loadInc(arm_state *cpustate, UINT32 pat, UINT32 rbv, UINT32 s, int mode)
170static int loadInc(arm_state *arm, UINT32 pat, UINT32 rbv, UINT32 s, int mode)
171171{
172172   int i, result;
173173   UINT32 data;
r20717r20718
178178   {
179179      if ((pat >> i) & 1)
180180      {
181         if (cpustate->pendingAbtD == 0) // "Overwriting of registers stops when the abort happens."
181         if (arm->pendingAbtD == 0) // "Overwriting of registers stops when the abort happens."
182182         {
183183         data = READ32(rbv += 4);
184184         if (i == 15) {
185185            if (s) /* Pull full contents from stack */
186               SET_MODE_REGISTER(cpustate, mode, 15, data);
186               SET_MODE_REGISTER(arm, mode, 15, data);
187187            else /* Pull only address, preserve mode & status flags */
188188               if (MODE32)
189                  SET_MODE_REGISTER(cpustate, mode, 15, data);
189                  SET_MODE_REGISTER(arm, mode, 15, data);
190190               else
191191               {
192                  SET_MODE_REGISTER(cpustate, mode, 15, (GET_MODE_REGISTER(cpustate, mode, 15) & ~0x03FFFFFC) | (data & 0x03FFFFFC));
192                  SET_MODE_REGISTER(arm, mode, 15, (GET_MODE_REGISTER(arm, mode, 15) & ~0x03FFFFFC) | (data & 0x03FFFFFC));
193193               }
194194         } else
195            SET_MODE_REGISTER(cpustate, mode, i, data);
195            SET_MODE_REGISTER(arm, mode, i, data);
196196         }
197197         result++;
198198      }
r20717r20718
200200   return result;
201201}
202202
203static int loadDec(arm_state *cpustate, UINT32 pat, UINT32 rbv, UINT32 s, int mode)
203static int loadDec(arm_state *arm, UINT32 pat, UINT32 rbv, UINT32 s, int mode)
204204{
205205   int i, result;
206206   UINT32 data;
r20717r20718
211211   {
212212      if ((pat >> i) & 1)
213213      {
214         if (cpustate->pendingAbtD == 0) // "Overwriting of registers stops when the abort happens."
214         if (arm->pendingAbtD == 0) // "Overwriting of registers stops when the abort happens."
215215         {
216216         data = READ32(rbv -= 4);
217217         if (i == 15) {
218218            if (s) /* Pull full contents from stack */
219               SET_MODE_REGISTER(cpustate, mode, 15, data);
219               SET_MODE_REGISTER(arm, mode, 15, data);
220220            else /* Pull only address, preserve mode & status flags */
221221               if (MODE32)
222                  SET_MODE_REGISTER(cpustate, mode, 15, data);
222                  SET_MODE_REGISTER(arm, mode, 15, data);
223223               else
224224               {
225                  SET_MODE_REGISTER(cpustate, mode, 15, (GET_MODE_REGISTER(cpustate, mode, 15) & ~0x03FFFFFC) | (data & 0x03FFFFFC));
225                  SET_MODE_REGISTER(arm, mode, 15, (GET_MODE_REGISTER(arm, mode, 15) & ~0x03FFFFFC) | (data & 0x03FFFFFC));
226226               }
227227         }
228228         else
229            SET_MODE_REGISTER(cpustate, mode, i, data);
229            SET_MODE_REGISTER(arm, mode, i, data);
230230         }
231231         result++;
232232      }
r20717r20718
234234   return result;
235235}
236236
237static int storeInc(arm_state *cpustate, UINT32 pat, UINT32 rbv, int mode)
237static int storeInc(arm_state *arm, UINT32 pat, UINT32 rbv, int mode)
238238{
239239   int i, result;
240240
r20717r20718
247247         if (i == 15) /* R15 is plus 12 from address of STM */
248248            LOG(("%08x: StoreInc on R15\n", R15));
249249#endif
250         WRITE32(rbv += 4, GET_MODE_REGISTER(cpustate, mode, i));
250         WRITE32(rbv += 4, GET_MODE_REGISTER(arm, mode, i));
251251         result++;
252252      }
253253   }
254254   return result;
255255} /* storeInc */
256256
257static int storeDec(arm_state *cpustate, UINT32 pat, UINT32 rbv, int mode)
257static int storeDec(arm_state *arm, UINT32 pat, UINT32 rbv, int mode)
258258{
259259   int i, result;
260260
r20717r20718
267267         if (i == 15) /* R15 is plus 12 from address of STM */
268268            LOG(("%08x: StoreDec on R15\n", R15));
269269#endif
270         WRITE32(rbv -= 4, GET_MODE_REGISTER(cpustate, mode, i));
270         WRITE32(rbv -= 4, GET_MODE_REGISTER(arm, mode, i));
271271         result++;
272272      }
273273   }
r20717r20718
279279 ***************************************************************************/
280280
281281// Co-Processor Data Operation
282static void HandleCoProcDO(arm_state *cpustate, UINT32 insn)
282static void HandleCoProcDO(arm_state *arm, UINT32 insn)
283283{
284284   // This instruction simply instructs the co-processor to do something, no data is returned to ARM7 core
285285   if (arm7_coproc_do_callback)
286      arm7_coproc_do_callback(cpustate->device, *cpustate->program, insn, 0, 0);    // simply pass entire opcode to callback - since data format is actually dependent on co-proc implementation
286      arm7_coproc_do_callback(arm->device, *arm->program, insn, 0, 0);    // simply pass entire opcode to callback - since data format is actually dependent on co-proc implementation
287287   else
288288      LOG(("%08x: Co-Processor Data Operation executed, but no callback defined!\n", R15));
289289}
290290
291291// Co-Processor Register Transfer - To/From Arm to Co-Proc
292static void HandleCoProcRT(arm_state *cpustate, UINT32 insn)
292static void HandleCoProcRT(arm_state *arm, UINT32 insn)
293293{
294294   /* xxxx 1110 oooL nnnn dddd cccc ppp1 mmmm */
295295
r20717r20718
298298   {
299299      if (arm7_coproc_rt_r_callback)
300300      {
301         UINT32 res = arm7_coproc_rt_r_callback(cpustate->device, *cpustate->program, insn, 0);   // RT Read handler must parse opcode & return appropriate result
302         if (cpustate->pendingUnd == 0)
301         UINT32 res = arm7_coproc_rt_r_callback(arm->device, *arm->program, insn, 0);   // RT Read handler must parse opcode & return appropriate result
302         if (arm->pendingUnd == 0)
303303         {
304            SET_REGISTER(cpustate, (insn >> 12) & 0xf, res);
304            SET_REGISTER(arm, (insn >> 12) & 0xf, res);
305305         }
306306      }
307307      else
r20717r20718
311311   else
312312   {
313313      if (arm7_coproc_rt_w_callback)
314         arm7_coproc_rt_w_callback(cpustate->device, *cpustate->program, insn, GET_REGISTER(cpustate, (insn >> 12) & 0xf), 0);
314         arm7_coproc_rt_w_callback(arm->device, *arm->program, insn, GET_REGISTER(arm, (insn >> 12) & 0xf), 0);
315315      else
316316         LOG(("%08x: Co-Processor Register Transfer executed, but no RT Write callback defined!\n", R15));
317317   }
r20717r20718
329329                but if co-proc reads multiple address, it must handle the offset adjustment itself.
330330*/
331331// todo: test with valid instructions
332static void HandleCoProcDT(arm_state *cpustate, UINT32 insn)
332static void HandleCoProcDT(arm_state *arm, UINT32 insn)
333333{
334334   UINT32 rn = (insn >> 16) & 0xf;
335   UINT32 rnv = GET_REGISTER(cpustate, rn);    // Get Address Value stored from Rn
335   UINT32 rnv = GET_REGISTER(arm, rn);    // Get Address Value stored from Rn
336336   UINT32 ornv = rnv;                // Keep value of Rn
337337   UINT32 off = (insn & 0xff) << 2;  // Offset is << 2 according to manual
338338   UINT32 *prn = &ARM7REG(rn);       // Pointer to our register, so it can be changed in the callback
339339
340340   // Pointers to read32/write32 functions
341   void (*write32)(arm_state *cpustate, UINT32 addr, UINT32 data);
342   UINT32 (*read32)(arm_state *cpustate, UINT32 addr);
341   void (*write32)(arm_state *arm, UINT32 addr, UINT32 data);
342   UINT32 (*read32)(arm_state *arm, UINT32 addr);
343343   write32 = PTR_WRITE32;
344344   read32 = PTR_READ32;
345345
r20717r20718
362362   if (insn & 0x00100000)
363363   {
364364      if (arm7_coproc_dt_r_callback)
365         arm7_coproc_dt_r_callback(cpustate, insn, prn, read32);
365         arm7_coproc_dt_r_callback(arm, insn, prn, read32);
366366      else
367367         LOG(("%08x: Co-Processer Data Transfer executed, but no READ callback defined!\n", R15));
368368   }
r20717r20718
370370   else
371371   {
372372      if (arm7_coproc_dt_w_callback)
373         arm7_coproc_dt_w_callback(cpustate, insn, prn, write32);
373         arm7_coproc_dt_w_callback(arm, insn, prn, write32);
374374      else
375375         LOG(("%08x: Co-Processer Data Transfer executed, but no WRITE callback defined!\n", R15));
376376   }
377377
378   if (cpustate->pendingUnd != 0) return;
378   if (arm->pendingUnd != 0) return;
379379
380380   // If writeback not used - ensure the original value of RN is restored in case co-proc callback changed value
381381   if ((insn & 0x200000) == 0)
382      SET_REGISTER(cpustate, rn, ornv);
382      SET_REGISTER(arm, rn, ornv);
383383}
384384
385INLINE void HandleBranch(arm_state *cpustate, UINT32 insn)
385INLINE void HandleBranch(arm_state *arm, UINT32 insn)
386386{
387387   UINT32 off = (insn & INSN_BRANCH) << 2;
388388
389389   /* Save PC into LR if this is a branch with link */
390390   if (insn & INSN_BL)
391391   {
392      SET_REGISTER(cpustate, 14, R15 + 4);
392      SET_REGISTER(arm, 14, R15 + 4);
393393   }
394394
395395   /* Sign-extend the 24-bit offset in our calculations */
r20717r20718
409409   }
410410}
411411
412static void HandleMemSingle(arm_state *cpustate, UINT32 insn)
412static void HandleMemSingle(arm_state *arm, UINT32 insn)
413413{
414414   UINT32 rn, rnv, off, rd, rnv_old = 0;
415415
r20717r20718
417417   if (insn & INSN_I)
418418   {
419419      /* Register Shift */
420      off = decodeShift(cpustate, insn, NULL);
420      off = decodeShift(arm, insn, NULL);
421421   }
422422   else
423423   {
r20717r20718
434434      if (insn & INSN_SDT_U)
435435      {
436436         if ((MODE32) || (rn != eR15))
437            rnv = (GET_REGISTER(cpustate, rn) + off);
437            rnv = (GET_REGISTER(arm, rn) + off);
438438         else
439439            rnv = (GET_PC + off);
440440      }
441441      else
442442      {
443443         if ((MODE32) || (rn != eR15))
444            rnv = (GET_REGISTER(cpustate, rn) - off);
444            rnv = (GET_REGISTER(arm, rn) - off);
445445         else
446446            rnv = (GET_PC - off);
447447      }
448448
449449      if (insn & INSN_SDT_W)
450450      {
451         rnv_old = GET_REGISTER(cpustate, rn);
452         SET_REGISTER(cpustate, rn, rnv);
451         rnv_old = GET_REGISTER(arm, rn);
452         SET_REGISTER(arm, rn, rnv);
453453
454454   // check writeback???
455455      }
r20717r20718
470470      }
471471      else
472472      {
473         rnv = GET_REGISTER(cpustate, rn);
473         rnv = GET_REGISTER(arm, rn);
474474      }
475475   }
476476
r20717r20718
482482      if (insn & INSN_SDT_B)
483483      {
484484         UINT32 data = READ8(rnv);
485         if (cpustate->pendingAbtD == 0)
485         if (arm->pendingAbtD == 0)
486486         {
487            SET_REGISTER(cpustate, rd, data);
487            SET_REGISTER(arm, rd, data);
488488         }
489489      }
490490      else
491491      {
492492         UINT32 data = READ32(rnv);
493         if (cpustate->pendingAbtD == 0)
493         if (arm->pendingAbtD == 0)
494494         {
495495            if (rd == eR15)
496496            {
r20717r20718
503503            }
504504            else
505505            {
506               SET_REGISTER(cpustate, rd, data);
506               SET_REGISTER(arm, rd, data);
507507            }
508508         }
509509      }
r20717r20718
518518               LOG(("Wrote R15 in byte mode\n"));
519519#endif
520520
521         WRITE8(rnv, (UINT8) GET_REGISTER(cpustate, rd) & 0xffu);
521         WRITE8(rnv, (UINT8) GET_REGISTER(arm, rd) & 0xffu);
522522      }
523523      else
524524      {
r20717r20718
527527               LOG(("Wrote R15 in 32bit mode\n"));
528528#endif
529529
530         //WRITE32(rnv, rd == eR15 ? R15 + 8 : GET_REGISTER(cpustate, rd));
531         WRITE32(rnv, rd == eR15 ? R15 + 8 + 4 : GET_REGISTER(cpustate, rd)); // manual says STR rd = PC, +12
530         //WRITE32(rnv, rd == eR15 ? R15 + 8 : GET_REGISTER(arm, rd));
531         WRITE32(rnv, rd == eR15 ? R15 + 8 + 4 : GET_REGISTER(arm, rd)); // manual says STR rd = PC, +12
532532      }
533533      // Store takes only 2 N Cycles, so add + 1
534534      ARM7_ICOUNT += 1;
535535   }
536536
537   if (cpustate->pendingAbtD != 0)
537   if (arm->pendingAbtD != 0)
538538   {
539539      if ((insn & INSN_SDT_P) && (insn & INSN_SDT_W))
540540      {
541         SET_REGISTER(cpustate, rn, rnv_old);
541         SET_REGISTER(arm, rn, rnv_old);
542542      }
543543   }
544544   else
r20717r20718
551551         /* Writeback is applied in pipeline, before value is read from mem,
552552             so writeback is effectively ignored */
553553         if (rd == rn) {
554            SET_REGISTER(cpustate, rn, GET_REGISTER(cpustate, rd));
554            SET_REGISTER(arm, rn, GET_REGISTER(arm, rd));
555555            // todo: check for offs... ?
556556         }
557557         else {
558558            if ((insn & INSN_SDT_W) != 0)
559559               LOG(("%08x:  RegisterWritebackIncrement %d %d %d\n", R15, (insn & INSN_SDT_P) != 0, (insn & INSN_SDT_W) != 0, (insn & INSN_SDT_U) != 0));
560560
561            SET_REGISTER(cpustate, rn, (rnv + off));
561            SET_REGISTER(arm, rn, (rnv + off));
562562         }
563563      }
564564      else
r20717r20718
566566         /* Writeback is applied in pipeline, before value is read from mem,
567567             so writeback is effectively ignored */
568568         if (rd == rn) {
569            SET_REGISTER(cpustate, rn, GET_REGISTER(cpustate, rd));
569            SET_REGISTER(arm, rn, GET_REGISTER(arm, rd));
570570         }
571571         else {
572            SET_REGISTER(cpustate, rn, (rnv - off));
572            SET_REGISTER(arm, rn, (rnv - off));
573573
574574            if ((insn & INSN_SDT_W) != 0)
575575               LOG(("%08x:  RegisterWritebackDecrement %d %d %d\n", R15, (insn & INSN_SDT_P) != 0, (insn & INSN_SDT_W) != 0, (insn & INSN_SDT_U) != 0));
r20717r20718
583583
584584} /* HandleMemSingle */
585585
586static void HandleHalfWordDT(arm_state *cpustate, UINT32 insn)
586static void HandleHalfWordDT(arm_state *arm, UINT32 insn)
587587{
588588   UINT32 rn, rnv, off, rd, rnv_old = 0;
589589
r20717r20718
594594   }
595595   else {
596596      // register
597      off = GET_REGISTER(cpustate, insn & 0x0f);
597      off = GET_REGISTER(arm, insn & 0x0f);
598598   }
599599
600600   /* Calculate Rn, accounting for PC */
r20717r20718
605605      /* Pre-indexed addressing */
606606      if (insn & INSN_SDT_U)
607607      {
608         rnv = (GET_REGISTER(cpustate, rn) + off);
608         rnv = (GET_REGISTER(arm, rn) + off);
609609      }
610610      else
611611      {
612         rnv = (GET_REGISTER(cpustate, rn) - off);
612         rnv = (GET_REGISTER(arm, rn) - off);
613613      }
614614
615615      if (insn & INSN_SDT_W)
616616      {
617         rnv_old = GET_REGISTER(cpustate, rn);
618         SET_REGISTER(cpustate, rn, rnv);
617         rnv_old = GET_REGISTER(arm, rn);
618         SET_REGISTER(arm, rn, rnv);
619619
620620      // check writeback???
621621      }
r20717r20718
633633      }
634634      else
635635      {
636         rnv = GET_REGISTER(cpustate, rn);
636         rnv = GET_REGISTER(arm, rn);
637637      }
638638   }
639639
r20717r20718
664664            newval = (UINT32)(signbyte << 8)|databyte;
665665         }
666666
667         if (cpustate->pendingAbtD == 0)
667         if (arm->pendingAbtD == 0)
668668         {
669669         // PC?
670670         if (rd == eR15)
r20717r20718
676676         }
677677         else
678678         {
679            SET_REGISTER(cpustate, rd, newval);
679            SET_REGISTER(arm, rd, newval);
680680            R15 += 4;
681681         }
682682
r20717r20718
692692      {
693693         UINT32 newval = READ16(rnv);
694694
695         if (cpustate->pendingAbtD == 0)
695         if (arm->pendingAbtD == 0)
696696         {
697697         if (rd == eR15)
698698         {
r20717r20718
702702         }
703703         else
704704         {
705            SET_REGISTER(cpustate, rd, newval);
705            SET_REGISTER(arm, rd, newval);
706706            R15 += 4;
707707         }
708708
r20717r20718
721721   {
722722      if ((insn & 0x60) == 0x40)  // LDRD
723723   {
724      SET_REGISTER(cpustate, rd, READ32(rnv));
725      SET_REGISTER(cpustate, rd+1, READ32(rnv+4));
724      SET_REGISTER(arm, rd, READ32(rnv));
725      SET_REGISTER(arm, rd+1, READ32(rnv+4));
726726            R15 += 4;
727727   }
728728      else if ((insn & 0x60) == 0x60) // STRD
729729   {
730      WRITE32(rnv, GET_REGISTER(cpustate, rd));
731      WRITE32(rnv+4, GET_REGISTER(cpustate, rd+1));
730      WRITE32(rnv, GET_REGISTER(arm, rd));
731      WRITE32(rnv+4, GET_REGISTER(arm, rd+1));
732732            R15 += 4;
733733   }
734734   else
735735   {
736         // WRITE16(rnv, rd == eR15 ? R15 + 8 : GET_REGISTER(cpustate, rd));
737         WRITE16(rnv, rd == eR15 ? R15 + 8 + 4 : GET_REGISTER(cpustate, rd)); // manual says STR RD=PC, +12 of address
736         // WRITE16(rnv, rd == eR15 ? R15 + 8 : GET_REGISTER(arm, rd));
737         WRITE16(rnv, rd == eR15 ? R15 + 8 + 4 : GET_REGISTER(arm, rd)); // manual says STR RD=PC, +12 of address
738738
739739// if R15 is not increased then e.g. "STRH R10, [R15,#$10]" will be executed over and over again
740740#if 0
r20717r20718
747747   }
748748   }
749749
750   if (cpustate->pendingAbtD != 0)
750   if (arm->pendingAbtD != 0)
751751   {
752752      if ((insn & INSN_SDT_P) && (insn & INSN_SDT_W))
753753      {
754         SET_REGISTER(cpustate, rn, rnv_old);
754         SET_REGISTER(arm, rn, rnv_old);
755755      }
756756   }
757757   else
r20717r20718
766766         /* Writeback is applied in pipeline, before value is read from mem,
767767             so writeback is effectively ignored */
768768         if (rd == rn) {
769            SET_REGISTER(cpustate, rn, GET_REGISTER(cpustate, rd));
769            SET_REGISTER(arm, rn, GET_REGISTER(arm, rd));
770770            // todo: check for offs... ?
771771         }
772772         else {
773773            if ((insn & INSN_SDT_W) != 0)
774774               LOG(("%08x:  RegisterWritebackIncrement %d %d %d\n", R15, (insn & INSN_SDT_P) != 0, (insn & INSN_SDT_W) != 0, (insn & INSN_SDT_U) != 0));
775775
776            SET_REGISTER(cpustate, rn, (rnv + off));
776            SET_REGISTER(arm, rn, (rnv + off));
777777         }
778778      }
779779      else
r20717r20718
781781         /* Writeback is applied in pipeline, before value is read from mem,
782782             so writeback is effectively ignored */
783783         if (rd == rn) {
784            SET_REGISTER(cpustate, rn, GET_REGISTER(cpustate, rd));
784            SET_REGISTER(arm, rn, GET_REGISTER(arm, rd));
785785         }
786786         else {
787            SET_REGISTER(cpustate, rn, (rnv - off));
787            SET_REGISTER(arm, rn, (rnv - off));
788788
789789            if ((insn & INSN_SDT_W) != 0)
790790               LOG(("%08x:  RegisterWritebackDecrement %d %d %d\n", R15, (insn & INSN_SDT_P) != 0, (insn & INSN_SDT_W) != 0, (insn & INSN_SDT_U) != 0));
r20717r20718
796796
797797}
798798
799static void HandleSwap(arm_state *cpustate, UINT32 insn)
799static void HandleSwap(arm_state *arm, UINT32 insn)
800800{
801801   UINT32 rn, rm, rd, tmp;
802802
803   rn = GET_REGISTER(cpustate, (insn >> 16) & 0xf);  // reg. w/read address
804   rm = GET_REGISTER(cpustate, insn & 0xf);          // reg. w/write address
803   rn = GET_REGISTER(arm, (insn >> 16) & 0xf);  // reg. w/read address
804   rm = GET_REGISTER(arm, insn & 0xf);          // reg. w/write address
805805   rd = (insn >> 12) & 0xf;                // dest reg
806806
807807#if ARM7_DEBUG_CORE
r20717r20718
814814   {
815815      tmp = READ8(rn);
816816      WRITE8(rn, rm);
817      SET_REGISTER(cpustate, rd, tmp);
817      SET_REGISTER(arm, rd, tmp);
818818   }
819819   else
820820   {
821821      tmp = READ32(rn);
822822      WRITE32(rn, rm);
823      SET_REGISTER(cpustate, rd, tmp);
823      SET_REGISTER(arm, rd, tmp);
824824   }
825825
826826   R15 += 4;
r20717r20718
828828   ARM7_ICOUNT -= 1;
829829}
830830
831static void HandlePSRTransfer(arm_state *cpustate, UINT32 insn)
831static void HandlePSRTransfer(arm_state *arm, UINT32 insn)
832832{
833833   int reg = (insn & 0x400000) ? SPSR : eCPSR; // Either CPSR or SPSR
834834   UINT32 newval, val = 0;
835835   int oldmode = GET_CPSR & MODE_FLAG;
836836
837837   // get old value of CPSR/SPSR
838   newval = GET_REGISTER(cpustate, reg);
838   newval = GET_REGISTER(arm, reg);
839839
840840   // MSR (bit 21 set) - Copy value to CPSR/SPSR
841841   if ((insn & 0x00200000))
r20717r20718
852852      // Value from Register
853853      else
854854      {
855         val = GET_REGISTER(cpustate, insn & 0x0f);
855         val = GET_REGISTER(arm, insn & 0x0f);
856856      }
857857
858858      // apply field code bits
r20717r20718
914914      if (reg == eCPSR)
915915         SET_CPSR(newval);
916916      else
917         SET_REGISTER(cpustate, reg, newval);
917         SET_REGISTER(arm, reg, newval);
918918
919919      // Switch to new mode if changed
920920      if ((newval & MODE_FLAG) != oldmode)
921         SwitchMode(cpustate, GET_MODE);
921         SwitchMode(arm, GET_MODE);
922922
923923   }
924924   // MRS (bit 21 clear) - Copy CPSR or SPSR to specified Register
925925   else
926926   {
927      SET_REGISTER(cpustate, (insn >> 12)& 0x0f, GET_REGISTER(cpustate, reg));
927      SET_REGISTER(arm, (insn >> 12)& 0x0f, GET_REGISTER(arm, reg));
928928   }
929929}
930930
931static void HandleALU(arm_state *cpustate, UINT32 insn)
931static void HandleALU(arm_state *arm, UINT32 insn)
932932{
933933   UINT32 op2, sc = 0, rd, rn, opcode;
934934   UINT32 by, rdn;
r20717r20718
965965   /* Op2 = Register Value */
966966   else
967967   {
968      op2 = decodeShift(cpustate, insn, (insn & INSN_S) ? &sc : NULL);
968      op2 = decodeShift(arm, insn, (insn & INSN_S) ? &sc : NULL);
969969
970970      // LD TODO sc will always be 0 if this applies
971971      if (!(insn & INSN_S))
r20717r20718
991991      }
992992      else
993993      {
994         rn = GET_REGISTER(cpustate, rn);
994         rn = GET_REGISTER(arm, rn);
995995      }
996996   }
997997
r20717r20718
10871087            if (GET_MODE != eARM7_MODE_USER)
10881088            {
10891089               // Update CPSR from SPSR
1090               SET_CPSR(GET_REGISTER(cpustate, SPSR));
1091               SwitchMode(cpustate, GET_MODE);
1090               SET_CPSR(GET_REGISTER(arm, SPSR));
1091               SwitchMode(arm, GET_MODE);
10921092            }
10931093
10941094            R15 = rd;
r20717r20718
11001100               R15 = rd; //(R15 & 0x03FFFFFC) | (rd & 0xFC000003);
11011101               temp = (GET_CPSR & 0x0FFFFF20) | (rd & 0xF0000000) /* N Z C V */ | ((rd & 0x0C000000) >> (26 - 6)) /* I F */ | (rd & 0x00000003) /* M1 M0 */;
11021102               SET_CPSR( temp);
1103               SwitchMode( cpustate, temp & 3);
1103               SwitchMode( arm, temp & 3);
11041104            }
11051105
11061106            // extra cycles (PC written)
r20717r20718
11111111         }
11121112         else
11131113            /* S Flag is set - Write results to register & update CPSR (which was already handled using HandleALU flag macros) */
1114            SET_REGISTER(cpustate, rdn, rd);
1114            SET_REGISTER(arm, rdn, rd);
11151115      }
11161116   }
11171117   // SJE: Don't think this applies any more.. (see page 44 at bottom)
r20717r20718
11301130            R15 = (R15 & 0x03FFFFFC) | (rd & ~0x03FFFFFC);
11311131            temp = (GET_CPSR & 0x0FFFFF20) | (rd & 0xF0000000) /* N Z C V */ | ((rd & 0x0C000000) >> (26 - 6)) /* I F */ | (rd & 0x00000003) /* M1 M0 */;
11321132            SET_CPSR( temp);
1133            SwitchMode( cpustate, temp & 3);
1133            SwitchMode( arm, temp & 3);
11341134         }
11351135
11361136         /* IRQ masks may have changed in this instruction */
r20717r20718
11501150   ARM7_ICOUNT += 2;
11511151}
11521152
1153static void HandleMul(arm_state *cpustate, UINT32 insn)
1153static void HandleMul(arm_state *arm, UINT32 insn)
11541154{
11551155   UINT32 r, rm, rs;
11561156
r20717r20718
11601160   // multiply, which is controlled by the value of the multiplier operand
11611161   // specified by Rs.
11621162
1163   rm = GET_REGISTER(cpustate, insn & INSN_MUL_RM);
1164   rs = GET_REGISTER(cpustate, (insn & INSN_MUL_RS) >> INSN_MUL_RS_SHIFT);
1163   rm = GET_REGISTER(arm, insn & INSN_MUL_RM);
1164   rs = GET_REGISTER(arm, (insn & INSN_MUL_RS) >> INSN_MUL_RS_SHIFT);
11651165
11661166   /* Do the basic multiply of Rm and Rs */
11671167   r = rm * rs;
r20717r20718
11761176   /* Add on Rn if this is a MLA */
11771177   if (insn & INSN_MUL_A)
11781178   {
1179      r += GET_REGISTER(cpustate, (insn & INSN_MUL_RN) >> INSN_MUL_RN_SHIFT);
1179      r += GET_REGISTER(arm, (insn & INSN_MUL_RN) >> INSN_MUL_RN_SHIFT);
11801180      // extra cycle for MLA
11811181      ARM7_ICOUNT -= 1;
11821182   }
11831183
11841184   /* Write the result */
1185   SET_REGISTER(cpustate, (insn & INSN_MUL_RD) >> INSN_MUL_RD_SHIFT, r);
1185   SET_REGISTER(arm, (insn & INSN_MUL_RD) >> INSN_MUL_RD_SHIFT, r);
11861186
11871187   /* Set N and Z if asked */
11881188   if (insn & INSN_S)
r20717r20718
12001200}
12011201
12021202// todo: add proper cycle counts
1203static void HandleSMulLong(arm_state *cpustate, UINT32 insn)
1203static void HandleSMulLong(arm_state *arm, UINT32 insn)
12041204{
12051205   INT32 rm, rs;
12061206   UINT32 rhi, rlo;
r20717r20718
12101210   // number of 8 bit multiplier array cycles required to complete the multiply, which is
12111211   // controlled by the value of the multiplier operand specified by Rs.
12121212
1213   rm  = (INT32)GET_REGISTER(cpustate, insn & 0xf);
1214   rs  = (INT32)GET_REGISTER(cpustate, ((insn >> 8) & 0xf));
1213   rm  = (INT32)GET_REGISTER(arm, insn & 0xf);
1214   rs  = (INT32)GET_REGISTER(arm, ((insn >> 8) & 0xf));
12151215   rhi = (insn >> 16) & 0xf;
12161216   rlo = (insn >> 12) & 0xf;
12171217
r20717r20718
12261226   /* Add on Rn if this is a MLA */
12271227   if (insn & INSN_MUL_A)
12281228   {
1229      INT64 acum = (INT64)((((INT64)(GET_REGISTER(cpustate, rhi))) << 32) | GET_REGISTER(cpustate, rlo));
1229      INT64 acum = (INT64)((((INT64)(GET_REGISTER(arm, rhi))) << 32) | GET_REGISTER(arm, rlo));
12301230      res += acum;
12311231      // extra cycle for MLA
12321232      ARM7_ICOUNT -= 1;
12331233   }
12341234
12351235   /* Write the result (upper dword goes to RHi, lower to RLo) */
1236   SET_REGISTER(cpustate, rhi, res >> 32);
1237   SET_REGISTER(cpustate, rlo, res & 0xFFFFFFFF);
1236   SET_REGISTER(arm, rhi, res >> 32);
1237   SET_REGISTER(arm, rlo, res & 0xFFFFFFFF);
12381238
12391239   /* Set N and Z if asked */
12401240   if (insn & INSN_S)
r20717r20718
12521252}
12531253
12541254// todo: add proper cycle counts
1255static void HandleUMulLong(arm_state *cpustate, UINT32 insn)
1255static void HandleUMulLong(arm_state *arm, UINT32 insn)
12561256{
12571257   UINT32 rm, rs;
12581258   UINT32 rhi, rlo;
r20717r20718
12621262   // number of 8 bit multiplier array cycles required to complete the multiply, which is
12631263   // controlled by the value of the multiplier operand specified by Rs.
12641264
1265   rm  = (INT32)GET_REGISTER(cpustate, insn & 0xf);
1266   rs  = (INT32)GET_REGISTER(cpustate, ((insn >> 8) & 0xf));
1265   rm  = (INT32)GET_REGISTER(arm, insn & 0xf);
1266   rs  = (INT32)GET_REGISTER(arm, ((insn >> 8) & 0xf));
12671267   rhi = (insn >> 16) & 0xf;
12681268   rlo = (insn >> 12) & 0xf;
12691269
r20717r20718
12781278   /* Add on Rn if this is a MLA */
12791279   if (insn & INSN_MUL_A)
12801280   {
1281      UINT64 acum = (UINT64)((((UINT64)(GET_REGISTER(cpustate, rhi))) << 32) | GET_REGISTER(cpustate, rlo));
1281      UINT64 acum = (UINT64)((((UINT64)(GET_REGISTER(arm, rhi))) << 32) | GET_REGISTER(arm, rlo));
12821282      res += acum;
12831283      // extra cycle for MLA
12841284      ARM7_ICOUNT -= 1;
12851285   }
12861286
12871287   /* Write the result (upper dword goes to RHi, lower to RLo) */
1288   SET_REGISTER(cpustate, rhi, res >> 32);
1289   SET_REGISTER(cpustate, rlo, res & 0xFFFFFFFF);
1288   SET_REGISTER(arm, rhi, res >> 32);
1289   SET_REGISTER(arm, rlo, res & 0xFFFFFFFF);
12901290
12911291   /* Set N and Z if asked */
12921292   if (insn & INSN_S)
r20717r20718
13021302   ARM7_ICOUNT += 3;
13031303}
13041304
1305static void HandleMemBlock(arm_state *cpustate, UINT32 insn)
1305static void HandleMemBlock(arm_state *arm, UINT32 insn)
13061306{
13071307   UINT32 rb = (insn & INSN_RN) >> INSN_RN_SHIFT;
1308   UINT32 rbp = GET_REGISTER(cpustate, rb);
1308   UINT32 rbp = GET_REGISTER(arm, rb);
13091309   int result;
13101310
13111311#if ARM7_DEBUG_CORE
r20717r20718
13351335            // !! actually switching to user mode triggers a section permission fault in Happy Fish 302-in-1 (BP C0030DF4, press F5 ~16 times) !!
13361336            // set to user mode - then do the transfer, and set back
13371337            //int curmode = GET_MODE;
1338            //SwitchMode(cpustate, eARM7_MODE_USER);
1338            //SwitchMode(arm, eARM7_MODE_USER);
13391339            LOG(("%08x: User Bank Transfer not fully tested - please check if working properly!\n", R15));
1340            result = loadInc(cpustate, insn & 0xffff, rbp, insn & INSN_BDT_S, eARM7_MODE_USER);
1340            result = loadInc(arm, insn & 0xffff, rbp, insn & INSN_BDT_S, eARM7_MODE_USER);
13411341            // todo - not sure if Writeback occurs on User registers also..
1342            //SwitchMode(cpustate, curmode);
1342            //SwitchMode(arm, curmode);
13431343         }
13441344         else
1345            result = loadInc(cpustate, insn & 0xffff, rbp, insn & INSN_BDT_S, GET_MODE);
1345            result = loadInc(arm, insn & 0xffff, rbp, insn & INSN_BDT_S, GET_MODE);
13461346
1347         if ((insn & INSN_BDT_W) && (cpustate->pendingAbtD == 0))
1347         if ((insn & INSN_BDT_W) && (arm->pendingAbtD == 0))
13481348         {
13491349#if ARM7_DEBUG_CORE
13501350               if (rb == 15)
r20717r20718
13541354            // GBA "V-Rally 3" expects R0 not to be overwritten with the updated base value [BP 8077B0C]
13551355            if (((insn >> rb) & 1) == 0)
13561356            {
1357               SET_REGISTER(cpustate, rb, GET_REGISTER(cpustate, rb) + result * 4);
1357               SET_REGISTER(arm, rb, GET_REGISTER(arm, rb) + result * 4);
13581358            }
13591359         }
13601360
13611361         // R15 included? (NOTE: CPSR restore must occur LAST otherwise wrong registers restored!)
1362         if ((insn & 0x8000) && (cpustate->pendingAbtD == 0)) {
1362         if ((insn & 0x8000) && (arm->pendingAbtD == 0)) {
13631363            R15 -= 4;     // SJE: I forget why i did this?
13641364            // S - Flag Set? Signals transfer of current mode SPSR->CPSR
13651365            if (insn & INSN_BDT_S)
13661366            {
13671367               if (MODE32)
13681368               {
1369                  SET_CPSR(GET_REGISTER(cpustate, SPSR));
1370                  SwitchMode(cpustate, GET_MODE);
1369                  SET_CPSR(GET_REGISTER(arm, SPSR));
1370                  SwitchMode(arm, GET_MODE);
13711371               }
13721372               else
13731373               {
r20717r20718
13751375//                      LOG(("LDM + S | R15 %08X CPSR %08X\n", R15, GET_CPSR));
13761376                  temp = (GET_CPSR & 0x0FFFFF20) | (R15 & 0xF0000000) /* N Z C V */ | ((R15 & 0x0C000000) >> (26 - 6)) /* I F */ | (R15 & 0x00000003) /* M1 M0 */;
13771377                  SET_CPSR( temp);
1378                  SwitchMode(cpustate, temp & 3);
1378                  SwitchMode(arm, temp & 3);
13791379               }
13801380            }
13811381            // LDM PC - takes 2 extra cycles
r20717r20718
13951395         {
13961396            // set to user mode - then do the transfer, and set back
13971397            //int curmode = GET_MODE;
1398            //SwitchMode(cpustate, eARM7_MODE_USER);
1398            //SwitchMode(arm, eARM7_MODE_USER);
13991399            LOG(("%08x: User Bank Transfer not fully tested - please check if working properly!\n", R15));
1400            result = loadDec(cpustate, insn & 0xffff, rbp, insn & INSN_BDT_S, eARM7_MODE_USER);
1400            result = loadDec(arm, insn & 0xffff, rbp, insn & INSN_BDT_S, eARM7_MODE_USER);
14011401            // todo - not sure if Writeback occurs on User registers also..
1402            //SwitchMode(cpustate, curmode);
1402            //SwitchMode(arm, curmode);
14031403         }
14041404         else
1405            result = loadDec(cpustate, insn & 0xffff, rbp, insn & INSN_BDT_S, GET_MODE);
1405            result = loadDec(arm, insn & 0xffff, rbp, insn & INSN_BDT_S, GET_MODE);
14061406
1407         if ((insn & INSN_BDT_W) && (cpustate->pendingAbtD == 0))
1407         if ((insn & INSN_BDT_W) && (arm->pendingAbtD == 0))
14081408         {
14091409            if (rb == 0xf)
14101410               LOG(("%08x:  Illegal LDRM writeback to r15\n", R15));
14111411            // "A LDM will always overwrite the updated base if the base is in the list." (also for a user bank transfer?)
14121412            if (((insn >> rb) & 1) == 0)
14131413            {
1414               SET_REGISTER(cpustate, rb, GET_REGISTER(cpustate, rb) - result * 4);
1414               SET_REGISTER(arm, rb, GET_REGISTER(arm, rb) - result * 4);
14151415            }
14161416         }
14171417
14181418         // R15 included? (NOTE: CPSR restore must occur LAST otherwise wrong registers restored!)
1419         if ((insn & 0x8000) && (cpustate->pendingAbtD == 0)) {
1419         if ((insn & 0x8000) && (arm->pendingAbtD == 0)) {
14201420            R15 -= 4;     // SJE: I forget why i did this?
14211421            // S - Flag Set? Signals transfer of current mode SPSR->CPSR
14221422            if (insn & INSN_BDT_S)
14231423            {
14241424               if (MODE32)
14251425               {
1426                  SET_CPSR(GET_REGISTER(cpustate, SPSR));
1427                  SwitchMode(cpustate, GET_MODE);
1426                  SET_CPSR(GET_REGISTER(arm, SPSR));
1427                  SwitchMode(arm, GET_MODE);
14281428               }
14291429               else
14301430               {
r20717r20718
14321432//                      LOG(("LDM + S | R15 %08X CPSR %08X\n", R15, GET_CPSR));
14331433                  temp = (GET_CPSR & 0x0FFFFF20) /* N Z C V I F M4 M3 M2 M1 M0 */ | (R15 & 0xF0000000) /* N Z C V */ | ((R15 & 0x0C000000) >> (26 - 6)) /* I F */ | (R15 & 0x00000003) /* M1 M0 */;
14341434                  SET_CPSR( temp);
1435                  SwitchMode(cpustate, temp & 3);
1435                  SwitchMode(arm, temp & 3);
14361436               }
14371437            }
14381438            // LDM PC - takes 2 extra cycles
r20717r20718
14681468
14691469            // set to user mode - then do the transfer, and set back
14701470            //int curmode = GET_MODE;
1471            //SwitchMode(cpustate, eARM7_MODE_USER);
1471            //SwitchMode(arm, eARM7_MODE_USER);
14721472            LOG(("%08x: User Bank Transfer not fully tested - please check if working properly!\n", R15));
1473            result = storeInc(cpustate, insn & 0xffff, rbp, eARM7_MODE_USER);
1473            result = storeInc(arm, insn & 0xffff, rbp, eARM7_MODE_USER);
14741474            // todo - not sure if Writeback occurs on User registers also..
1475            //SwitchMode(cpustate, curmode);
1475            //SwitchMode(arm, curmode);
14761476         }
14771477         else
1478            result = storeInc(cpustate, insn & 0xffff, rbp, GET_MODE);
1478            result = storeInc(arm, insn & 0xffff, rbp, GET_MODE);
14791479
1480         if ((insn & INSN_BDT_W) && (cpustate->pendingAbtD == 0))
1480         if ((insn & INSN_BDT_W) && (arm->pendingAbtD == 0))
14811481         {
1482            SET_REGISTER(cpustate, rb, GET_REGISTER(cpustate, rb) + result * 4);
1482            SET_REGISTER(arm, rb, GET_REGISTER(arm, rb) + result * 4);
14831483         }
14841484      }
14851485      else
r20717r20718
14951495         {
14961496            // set to user mode - then do the transfer, and set back
14971497            //int curmode = GET_MODE;
1498            //SwitchMode(cpustate, eARM7_MODE_USER);
1498            //SwitchMode(arm, eARM7_MODE_USER);
14991499            LOG(("%08x: User Bank Transfer not fully tested - please check if working properly!\n", R15));
1500            result = storeDec(cpustate, insn & 0xffff, rbp, eARM7_MODE_USER);
1500            result = storeDec(arm, insn & 0xffff, rbp, eARM7_MODE_USER);
15011501            // todo - not sure if Writeback occurs on User registers also..
1502            //SwitchMode(cpustate, curmode);
1502            //SwitchMode(arm, curmode);
15031503         }
15041504         else
1505            result = storeDec(cpustate, insn & 0xffff, rbp, GET_MODE);
1505            result = storeDec(arm, insn & 0xffff, rbp, GET_MODE);
15061506
1507         if ((insn & INSN_BDT_W) && (cpustate->pendingAbtD == 0))
1507         if ((insn & INSN_BDT_W) && (arm->pendingAbtD == 0))
15081508         {
1509            SET_REGISTER(cpustate, rb, GET_REGISTER(cpustate, rb) - result * 4);
1509            SET_REGISTER(arm, rb, GET_REGISTER(arm, rb) - result * 4);
15101510         }
15111511      }
15121512      if (insn & (1 << eR15))
r20717r20718
15271527   arm7ops_0123, arm7ops_0123, arm7ops_0123, arm7ops_0123,arm7ops_4567,arm7ops_4567,arm7ops_4567,arm7ops_4567,arm7ops_89,arm7ops_89,arm7ops_ab,arm7ops_ab,arm7ops_cd,arm7ops_cd,arm7ops_e,arm7ops_f,
15281528};
15291529
1530const void arm7ops_0123(arm_state *cpustate, UINT32 insn)
1530const void arm7ops_0123(arm_state *arm, UINT32 insn)
15311531{
15321532//case 0:
15331533//case 1:
r20717r20718
15361536   /* Branch and Exchange (BX) */
15371537   if ((insn & 0x0ffffff0) == 0x012fff10)     // bits 27-4 == 000100101111111111110001
15381538   {
1539      R15 = GET_REGISTER(cpustate, insn & 0x0f);
1539      R15 = GET_REGISTER(arm, insn & 0x0f);
15401540      // If new PC address has A0 set, switch to Thumb mode
15411541      if (R15 & 1) {
15421542         SET_CPSR(GET_CPSR|T_MASK);
r20717r20718
15481548      UINT32 rm = insn&0xf;
15491549      UINT32 rd = (insn>>12)&0xf;
15501550
1551      SET_REGISTER(cpustate, rd, count_leading_zeros(GET_REGISTER(cpustate, rm)));
1551      SET_REGISTER(arm, rd, count_leading_zeros(GET_REGISTER(arm, rm)));
15521552
15531553      R15 += 4;
15541554   }
15551555   else if ((insn & 0x0ff000f0) == 0x01000050) // QADD - v5
15561556   {
1557      INT32 src1 = GET_REGISTER(cpustate, insn&0xf);
1558      INT32 src2 = GET_REGISTER(cpustate, (insn>>16)&0xf);
1557      INT32 src1 = GET_REGISTER(arm, insn&0xf);
1558      INT32 src2 = GET_REGISTER(arm, (insn>>16)&0xf);
15591559      INT64 res;
15601560
1561      res = saturate_qbit_overflow(cpustate, (INT64)src1 + (INT64)src2);
1561      res = saturate_qbit_overflow(arm, (INT64)src1 + (INT64)src2);
15621562
1563      SET_REGISTER(cpustate, (insn>>12)&0xf, (INT32)res);
1563      SET_REGISTER(arm, (insn>>12)&0xf, (INT32)res);
15641564      R15 += 4;
15651565   }
15661566   else if ((insn & 0x0ff000f0) == 0x01400050) // QDADD - v5
15671567   {
1568      INT32 src1 = GET_REGISTER(cpustate, insn&0xf);
1569      INT32 src2 = GET_REGISTER(cpustate, (insn>>16)&0xf);
1568      INT32 src1 = GET_REGISTER(arm, insn&0xf);
1569      INT32 src2 = GET_REGISTER(arm, (insn>>16)&0xf);
15701570      INT64 res;
15711571
15721572      // check if doubling operation will overflow
15731573      res = (INT64)src2 * 2;
1574      saturate_qbit_overflow(cpustate, res);
1574      saturate_qbit_overflow(arm, res);
15751575
15761576      src2 *= 2;
1577      res = saturate_qbit_overflow(cpustate, (INT64)src1 + (INT64)src2);
1577      res = saturate_qbit_overflow(arm, (INT64)src1 + (INT64)src2);
15781578
1579      SET_REGISTER(cpustate, (insn>>12)&0xf, (INT32)res);
1579      SET_REGISTER(arm, (insn>>12)&0xf, (INT32)res);
15801580      R15 += 4;
15811581   }
15821582   else if ((insn & 0x0ff000f0) == 0x01200050) // QSUB - v5
15831583   {
1584      INT32 src1 = GET_REGISTER(cpustate, insn&0xf);
1585      INT32 src2 = GET_REGISTER(cpustate, (insn>>16)&0xf);
1584      INT32 src1 = GET_REGISTER(arm, insn&0xf);
1585      INT32 src2 = GET_REGISTER(arm, (insn>>16)&0xf);
15861586      INT64 res;
15871587
1588      res = saturate_qbit_overflow(cpustate, (INT64)src1 - (INT64)src2);
1588      res = saturate_qbit_overflow(arm, (INT64)src1 - (INT64)src2);
15891589
1590      SET_REGISTER(cpustate, (insn>>12)&0xf, (INT32)res);
1590      SET_REGISTER(arm, (insn>>12)&0xf, (INT32)res);
15911591      R15 += 4;
15921592   }
15931593   else if ((insn & 0x0ff000f0) == 0x01600050) // QDSUB - v5
15941594   {
1595      INT32 src1 = GET_REGISTER(cpustate, insn&0xf);
1596      INT32 src2 = GET_REGISTER(cpustate, (insn>>16)&0xf);
1595      INT32 src1 = GET_REGISTER(arm, insn&0xf);
1596      INT32 src2 = GET_REGISTER(arm, (insn>>16)&0xf);
15971597      INT64 res;
15981598
15991599      // check if doubling operation will overflow
16001600      res = (INT64)src2 * 2;
1601      saturate_qbit_overflow(cpustate, res);
1601      saturate_qbit_overflow(arm, res);
16021602
16031603      src2 *= 2;
1604      res = saturate_qbit_overflow(cpustate, (INT64)src1 - (INT64)src2);
1604      res = saturate_qbit_overflow(arm, (INT64)src1 - (INT64)src2);
16051605
1606      SET_REGISTER(cpustate, (insn>>12)&0xf, (INT32)res);
1606      SET_REGISTER(arm, (insn>>12)&0xf, (INT32)res);
16071607      R15 += 4;
16081608   }
16091609   else if ((insn & 0x0ff00090) == 0x01000080) // SMLAxy - v5
16101610   {
1611      INT32 src1 = GET_REGISTER(cpustate, insn&0xf);
1612      INT32 src2 = GET_REGISTER(cpustate, (insn>>8)&0xf);
1611      INT32 src1 = GET_REGISTER(arm, insn&0xf);
1612      INT32 src2 = GET_REGISTER(arm, (insn>>8)&0xf);
16131613      INT32 res1;
16141614
16151615      // select top and bottom halves of src1/src2 and sign extend if necessary
r20717r20718
16421642      // do the signed multiply
16431643      res1 = src1 * src2;
16441644      // and the accumulate.  NOTE: only the accumulate can cause an overflow, which is why we do it this way.
1645      saturate_qbit_overflow(cpustate, (INT64)res1 + (INT64)GET_REGISTER(cpustate, (insn>>12)&0xf));
1645      saturate_qbit_overflow(arm, (INT64)res1 + (INT64)GET_REGISTER(arm, (insn>>12)&0xf));
16461646
1647      SET_REGISTER(cpustate, (insn>>16)&0xf, res1 + GET_REGISTER(cpustate, (insn>>12)&0xf));
1647      SET_REGISTER(arm, (insn>>16)&0xf, res1 + GET_REGISTER(arm, (insn>>12)&0xf));
16481648      R15 += 4;
16491649   }
16501650   else if ((insn & 0x0ff00090) == 0x01400080) // SMLALxy - v5
16511651   {
1652      INT32 src1 = GET_REGISTER(cpustate, insn&0xf);
1653      INT32 src2 = GET_REGISTER(cpustate, (insn>>8)&0xf);
1652      INT32 src1 = GET_REGISTER(arm, insn&0xf);
1653      INT32 src2 = GET_REGISTER(arm, (insn>>8)&0xf);
16541654      INT64 dst;
16551655
16561656      // select top and bottom halves of src1/src2 and sign extend if necessary
r20717r20718
16801680         }
16811681      }
16821682
1683      dst = (INT64)GET_REGISTER(cpustate, (insn>>12)&0xf);
1684      dst |= (INT64)GET_REGISTER(cpustate, (insn>>16)&0xf)<<32;
1683      dst = (INT64)GET_REGISTER(arm, (insn>>12)&0xf);
1684      dst |= (INT64)GET_REGISTER(arm, (insn>>16)&0xf)<<32;
16851685
16861686      // do the multiply and accumulate
16871687      dst += (INT64)src1 * (INT64)src2;
r20717r20718
16921692   }
16931693   else if ((insn & 0x0ff00090) == 0x01600080) // SMULxy - v5
16941694   {
1695      INT32 src1 = GET_REGISTER(cpustate, insn&0xf);
1696      INT32 src2 = GET_REGISTER(cpustate, (insn>>8)&0xf);
1695      INT32 src1 = GET_REGISTER(arm, insn&0xf);
1696      INT32 src2 = GET_REGISTER(arm, (insn>>8)&0xf);
16971697      INT32 res;
16981698
16991699      // select top and bottom halves of src1/src2 and sign extend if necessary
r20717r20718
17281728   }
17291729   else if ((insn & 0x0ff000b0) == 0x012000a0) // SMULWy - v5
17301730   {
1731      INT32 src1 = GET_REGISTER(cpustate, insn&0xf);
1732      INT32 src2 = GET_REGISTER(cpustate, (insn>>8)&0xf);
1731      INT32 src1 = GET_REGISTER(arm, insn&0xf);
1732      INT32 src2 = GET_REGISTER(arm, (insn>>8)&0xf);
17331733      INT64 res;
17341734
17351735      if (insn & 0x40)
r20717r20718
17511751   }
17521752   else if ((insn & 0x0ff000b0) == 0x01200080) // SMLAWy - v5
17531753   {
1754      INT32 src1 = GET_REGISTER(cpustate, insn&0xf);
1755      INT32 src2 = GET_REGISTER(cpustate, (insn>>8)&0xf);
1756      INT32 src3 = GET_REGISTER(cpustate, (insn>>12)&0xf);
1754      INT32 src1 = GET_REGISTER(arm, insn&0xf);
1755      INT32 src2 = GET_REGISTER(arm, (insn>>8)&0xf);
1756      INT32 src3 = GET_REGISTER(arm, (insn>>12)&0xf);
17571757      INT64 res;
17581758
17591759      if (insn & 0x40)
r20717r20718
17731773      res >>= 16;
17741774
17751775      // check for overflow and set the Q bit
1776      saturate_qbit_overflow(cpustate, (INT64)src3 + res);
1776      saturate_qbit_overflow(arm, (INT64)src3 + res);
17771777
17781778      // do the real accumulate
17791779      src3 += (INT32)res;
r20717r20718
17881788      /* Half Word Data Transfer */
17891789      if (insn & 0x60)         // bits = 6-5 != 00
17901790      {
1791         HandleHalfWordDT(cpustate, insn);
1791         HandleHalfWordDT(arm, insn);
17921792      }
17931793      else
17941794      /* Swap */
17951795      if (insn & 0x01000000)   // bit 24 = 1
17961796      {
1797         HandleSwap(cpustate, insn);
1797         HandleSwap(arm, insn);
17981798      }
17991799      /* Multiply Or Multiply Long */
18001800      else
r20717r20718
18041804         {
18051805            /* Signed? */
18061806            if (insn & 0x00400000)
1807               HandleSMulLong(cpustate, insn);
1807               HandleSMulLong(arm, insn);
18081808            else
1809               HandleUMulLong(cpustate, insn);
1809               HandleUMulLong(arm, insn);
18101810         }
18111811         /* multiply */
18121812         else
18131813         {
1814            HandleMul(cpustate, insn);
1814            HandleMul(arm, insn);
18151815         }
18161816         R15 += 4;
18171817      }
r20717r20718
18221822      /* PSR Transfer (MRS & MSR) */
18231823      if (((insn & 0x00100000) == 0) && ((insn & 0x01800000) == 0x01000000)) // S bit must be clear, and bit 24,23 = 10
18241824      {
1825         HandlePSRTransfer(cpustate, insn);
1825         HandlePSRTransfer(arm, insn);
18261826         ARM7_ICOUNT += 2;       // PSR only takes 1 - S Cycle, so we add + 2, since at end, we -3..
18271827         R15 += 4;
18281828      }
18291829      /* Data Processing */
18301830      else
18311831      {
1832         HandleALU(cpustate, insn);
1832         HandleALU(arm, insn);
18331833      }
18341834   }
18351835//  break;
18361836}
18371837
1838const void arm7ops_4567(arm_state *cpustate, UINT32 insn) /* Data Transfer - Single Data Access */
1838const void arm7ops_4567(arm_state *arm, UINT32 insn) /* Data Transfer - Single Data Access */
18391839{
18401840//case 4:
18411841//case 5:
18421842//case 6:
18431843//case 7:
1844   HandleMemSingle(cpustate, insn);
1844   HandleMemSingle(arm, insn);
18451845   R15 += 4;
18461846//  break;
18471847}
18481848
1849const void arm7ops_89(arm_state *cpustate, UINT32 insn) /* Block Data Transfer/Access */
1849const void arm7ops_89(arm_state *arm, UINT32 insn) /* Block Data Transfer/Access */
18501850{
18511851//case 8:
18521852//case 9:
1853   HandleMemBlock(cpustate, insn);
1853   HandleMemBlock(arm, insn);
18541854   R15 += 4;
18551855//  break;
18561856}
18571857
1858const void arm7ops_ab(arm_state *cpustate, UINT32 insn) /* Branch or Branch & Link */
1858const void arm7ops_ab(arm_state *arm, UINT32 insn) /* Branch or Branch & Link */
18591859{
18601860//case 0xa:
18611861//case 0xb:
1862   HandleBranch(cpustate, insn);
1862   HandleBranch(arm, insn);
18631863//  break;
18641864}
18651865
1866const void arm7ops_cd(arm_state *cpustate, UINT32 insn) /* Co-Processor Data Transfer */
1866const void arm7ops_cd(arm_state *arm, UINT32 insn) /* Co-Processor Data Transfer */
18671867{
18681868//case 0xc:
18691869//case 0xd:
1870   HandleCoProcDT(cpustate, insn);
1870   HandleCoProcDT(arm, insn);
18711871   R15 += 4;
18721872//  break;
18731873}
18741874
1875const void arm7ops_e(arm_state *cpustate, UINT32 insn) /* Co-Processor Data Operation or Register Transfer */
1875const void arm7ops_e(arm_state *arm, UINT32 insn) /* Co-Processor Data Operation or Register Transfer */
18761876{
18771877//case 0xe:
18781878   if (insn & 0x10)
1879      HandleCoProcRT(cpustate, insn);
1879      HandleCoProcRT(arm, insn);
18801880   else
1881      HandleCoProcDO(cpustate, insn);
1881      HandleCoProcDO(arm, insn);
18821882   R15 += 4;
18831883//  break;
18841884}
18851885
1886const void arm7ops_f(arm_state *cpustate, UINT32 insn) /* Software Interrupt */
1886const void arm7ops_f(arm_state *arm, UINT32 insn) /* Software Interrupt */
18871887{
1888   cpustate->pendingSwi = 1;
1888   arm->pendingSwi = 1;
18891889   ARM7_CHECKIRQ;
18901890   //couldn't find any cycle counts for SWI
18911891//  break;
trunk/src/emu/cpu/arm7/arm7.h
r20717r20718
3434#define __ARM7_H__
3535
3636
37#define ARM7_MAX_FASTRAM       4
38#define ARM7_MAX_HOTSPOTS      16
39
40enum
41{
42   CPUINFO_INT_ARM7_DRC_OPTIONS = CPUINFO_INT_CPU_SPECIFIC,
43
44   CPUINFO_INT_ARM7_FASTRAM_SELECT,
45   CPUINFO_INT_ARM7_FASTRAM_START,
46   CPUINFO_INT_ARM7_FASTRAM_END,
47   CPUINFO_INT_ARM7_FASTRAM_READONLY,
48
49   CPUINFO_INT_ARM7_HOTSPOT_SELECT,
50   CPUINFO_INT_ARM7_HOTSPOT_PC,
51   CPUINFO_INT_ARM7_HOTSPOT_OPCODE,
52   CPUINFO_INT_ARM7_HOTSPOT_CYCLES,
53
54   CPUINFO_PTR_ARM7_FASTRAM_BASE = CPUINFO_PTR_CPU_SPECIFIC
55};
56
3757/****************************************************************************************************
3858 *  PUBLIC FUNCTIONS
3959 ***************************************************************************************************/
trunk/src/emu/cpu/arm7/arm7ops.h
r20717r20718
11
2const void arm7ops_0123(arm_state *cpustate, UINT32 insn);
3const void arm7ops_4567(arm_state *cpustate, UINT32 insn);
4const void arm7ops_89(arm_state *cpustate, UINT32 insn);
5const void arm7ops_ab(arm_state *cpustate, UINT32 insn);
6const void arm7ops_cd(arm_state *cpustate, UINT32 insn);
7const void arm7ops_e(arm_state *cpustate, UINT32 insn);
8const void arm7ops_f(arm_state *cpustate, UINT32 insn);
2const void arm7ops_0123(arm_state *arm, UINT32 insn);
3const void arm7ops_4567(arm_state *arm, UINT32 insn);
4const void arm7ops_89(arm_state *arm, UINT32 insn);
5const void arm7ops_ab(arm_state *arm, UINT32 insn);
6const void arm7ops_cd(arm_state *arm, UINT32 insn);
7const void arm7ops_e(arm_state *arm, UINT32 insn);
8const void arm7ops_f(arm_state *arm, UINT32 insn);
trunk/src/emu/cpu/arm7/arm7core.c
r20717r20718
8080/* Prototypes */
8181
8282
83extern UINT32 decodeShift(arm_state *cpustate, UINT32 insn, UINT32 *pCarry);
83extern UINT32 decodeShift(arm_state *arm, UINT32 insn, UINT32 *pCarry);
8484
85void arm7_check_irq_state(arm_state *cpustate);
85void arm7_check_irq_state(arm_state *arm);
8686
8787
8888/* Static Vars */
r20717r20718
9393
9494#ifdef UNUSED_DEFINITION
9595// custom dasm callback handlers for co-processor instructions
96char *(*arm7_dasm_cop_dt_callback)(arm_state *cpustate, char *pBuf, UINT32 opcode, char *pConditionCode, char *pBuf0);
97char *(*arm7_dasm_cop_rt_callback)(arm_state *cpustate, char *pBuf, UINT32 opcode, char *pConditionCode, char *pBuf0);
98char *(*arm7_dasm_cop_do_callback)(arm_state *cpustate, char *pBuf, UINT32 opcode, char *pConditionCode, char *pBuf0);
96char *(*arm7_dasm_cop_dt_callback)(arm_state *arm, char *pBuf, UINT32 opcode, char *pConditionCode, char *pBuf0);
97char *(*arm7_dasm_cop_rt_callback)(arm_state *arm, char *pBuf, UINT32 opcode, char *pConditionCode, char *pBuf0);
98char *(*arm7_dasm_cop_do_callback)(arm_state *arm, char *pBuf, UINT32 opcode, char *pConditionCode, char *pBuf0);
9999#endif
100100
101101
r20717r20718
119119// CPU INIT
120120static void arm7_core_init(device_t *device, const char *cpuname)
121121{
122   arm_state *cpustate = get_safe_token(device);
122   arm_state *arm = get_safe_token(device);
123123
124   device->save_item(NAME(cpustate->sArmRegister));
125   device->save_item(NAME(cpustate->pendingIrq));
126   device->save_item(NAME(cpustate->pendingFiq));
127   device->save_item(NAME(cpustate->pendingAbtD));
128   device->save_item(NAME(cpustate->pendingAbtP));
129   device->save_item(NAME(cpustate->pendingUnd));
130   device->save_item(NAME(cpustate->pendingSwi));
124   device->save_item(NAME(arm->r));
125   device->save_item(NAME(arm->pendingIrq));
126   device->save_item(NAME(arm->pendingFiq));
127   device->save_item(NAME(arm->pendingAbtD));
128   device->save_item(NAME(arm->pendingAbtP));
129   device->save_item(NAME(arm->pendingUnd));
130   device->save_item(NAME(arm->pendingSwi));
131131}
132132
133133// CPU RESET
134134static void arm7_core_reset(legacy_cpu_device *device)
135135{
136   arm_state *cpustate = get_safe_token(device);
136   arm_state *arm = get_safe_token(device);
137137
138   device_irq_acknowledge_callback save_irqcallback = cpustate->irq_callback;
138   device_irq_acknowledge_callback save_irqcallback = arm->irq_callback;
139139
140   memset(cpustate, 0, sizeof(arm_state));
141   cpustate->irq_callback = save_irqcallback;
142   cpustate->device = device;
143   cpustate->program = &device->space(AS_PROGRAM);
144   cpustate->endian = ENDIANNESS_LITTLE;
145   cpustate->direct = &cpustate->program->direct();
140   memset(arm, 0, sizeof(arm_state));
141   arm->irq_callback = save_irqcallback;
142   arm->device = device;
143   arm->program = &device->space(AS_PROGRAM);
144   arm->endian = ENDIANNESS_LITTLE;
145   arm->direct = &arm->program->direct();
146146
147147   /* start up in SVC mode with interrupts disabled. */
148148   ARM7REG(eCPSR) = I_MASK | F_MASK | 0x10;
149   SwitchMode(cpustate, eARM7_MODE_SVC);
149   SwitchMode(arm, eARM7_MODE_SVC);
150150   R15 = 0;
151151}
152152
153153// CPU CHECK IRQ STATE
154154// Note: couldn't find any exact cycle counts for most of these exceptions
155void arm7_check_irq_state(arm_state *cpustate)
155void arm7_check_irq_state(arm_state *arm)
156156{
157157   UINT32 cpsr = GET_CPSR;   /* save current CPSR */
158158   UINT32 pc = R15 + 4;      /* save old pc (already incremented in pipeline) */;
r20717r20718
169169   */
170170
171171   // Data Abort
172   if (cpustate->pendingAbtD) {
172   if (arm->pendingAbtD) {
173173      if (MODE26) fatalerror( "pendingAbtD (todo)\n");
174      SwitchMode(cpustate, eARM7_MODE_ABT);             /* Set ABT mode so PC is saved to correct R14 bank */
175      SET_REGISTER(cpustate, 14, pc - 8 + 8);                   /* save PC to R14 */
176      SET_REGISTER(cpustate, SPSR, cpsr);               /* Save current CPSR */
174      SwitchMode(arm, eARM7_MODE_ABT);             /* Set ABT mode so PC is saved to correct R14 bank */
175      SET_REGISTER(arm, 14, pc - 8 + 8);                   /* save PC to R14 */
176      SET_REGISTER(arm, SPSR, cpsr);               /* Save current CPSR */
177177      SET_CPSR(GET_CPSR | I_MASK);            /* Mask IRQ */
178178      SET_CPSR(GET_CPSR & ~T_MASK);
179179      R15 = 0x10;                             /* IRQ Vector address */
180180      if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000;
181      cpustate->pendingAbtD = 0;
181      arm->pendingAbtD = 0;
182182      return;
183183   }
184184
185185   // FIQ
186   if (cpustate->pendingFiq && (cpsr & F_MASK) == 0) {
186   if (arm->pendingFiq && (cpsr & F_MASK) == 0) {
187187      if (MODE26) fatalerror( "pendingFiq (todo)\n");
188      SwitchMode(cpustate, eARM7_MODE_FIQ);             /* Set FIQ mode so PC is saved to correct R14 bank */
189      SET_REGISTER(cpustate, 14, pc - 4 + 4);                   /* save PC to R14 */
190      SET_REGISTER(cpustate, SPSR, cpsr);               /* Save current CPSR */
188      SwitchMode(arm, eARM7_MODE_FIQ);             /* Set FIQ mode so PC is saved to correct R14 bank */
189      SET_REGISTER(arm, 14, pc - 4 + 4);                   /* save PC to R14 */
190      SET_REGISTER(arm, SPSR, cpsr);               /* Save current CPSR */
191191      SET_CPSR(GET_CPSR | I_MASK | F_MASK);   /* Mask both IRQ & FIQ */
192192      SET_CPSR(GET_CPSR & ~T_MASK);
193193      R15 = 0x1c;                             /* IRQ Vector address */
r20717r20718
196196   }
197197
198198   // IRQ
199   if (cpustate->pendingIrq && (cpsr & I_MASK) == 0) {
200      SwitchMode(cpustate, eARM7_MODE_IRQ);             /* Set IRQ mode so PC is saved to correct R14 bank */
201      SET_REGISTER(cpustate, 14, pc - 4 + 4);                   /* save PC to R14 */
199   if (arm->pendingIrq && (cpsr & I_MASK) == 0) {
200      SwitchMode(arm, eARM7_MODE_IRQ);             /* Set IRQ mode so PC is saved to correct R14 bank */
201      SET_REGISTER(arm, 14, pc - 4 + 4);                   /* save PC to R14 */
202202      if (MODE32)
203203      {
204         SET_REGISTER(cpustate, SPSR, cpsr);               /* Save current CPSR */
204         SET_REGISTER(arm, SPSR, cpsr);               /* Save current CPSR */
205205         SET_CPSR(GET_CPSR | I_MASK);            /* Mask IRQ */
206206         SET_CPSR(GET_CPSR & ~T_MASK);
207207         R15 = 0x18;                             /* IRQ Vector address */
r20717r20718
218218   }
219219
220220   // Prefetch Abort
221   if (cpustate->pendingAbtP) {
221   if (arm->pendingAbtP) {
222222      if (MODE26) fatalerror( "pendingAbtP (todo)\n");
223      SwitchMode(cpustate, eARM7_MODE_ABT);             /* Set ABT mode so PC is saved to correct R14 bank */
224      SET_REGISTER(cpustate, 14, pc - 4 + 4);                   /* save PC to R14 */
225      SET_REGISTER(cpustate, SPSR, cpsr);               /* Save current CPSR */
223      SwitchMode(arm, eARM7_MODE_ABT);             /* Set ABT mode so PC is saved to correct R14 bank */
224      SET_REGISTER(arm, 14, pc - 4 + 4);                   /* save PC to R14 */
225      SET_REGISTER(arm, SPSR, cpsr);               /* Save current CPSR */
226226      SET_CPSR(GET_CPSR | I_MASK);            /* Mask IRQ */
227227      SET_CPSR(GET_CPSR & ~T_MASK);
228228      R15 = 0x0c;                             /* IRQ Vector address */
229229      if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000;
230      cpustate->pendingAbtP = 0;
230      arm->pendingAbtP = 0;
231231      return;
232232   }
233233
234234   // Undefined instruction
235   if (cpustate->pendingUnd) {
235   if (arm->pendingUnd) {
236236      if (MODE26) fatalerror( "pendingUnd (todo)\n");
237      SwitchMode(cpustate, eARM7_MODE_UND);             /* Set UND mode so PC is saved to correct R14 bank */
237      SwitchMode(arm, eARM7_MODE_UND);             /* Set UND mode so PC is saved to correct R14 bank */
238238      // compensate for prefetch (should this also be done for normal IRQ?)
239239      if (T_IS_SET(GET_CPSR))
240240      {
241            SET_REGISTER(cpustate, 14, pc - 4 + 2);         /* save PC to R14 */
241            SET_REGISTER(arm, 14, pc - 4 + 2);         /* save PC to R14 */
242242      }
243243      else
244244      {
245            SET_REGISTER(cpustate, 14, pc - 4 + 4 - 4);           /* save PC to R14 */
245            SET_REGISTER(arm, 14, pc - 4 + 4 - 4);           /* save PC to R14 */
246246      }
247      SET_REGISTER(cpustate, SPSR, cpsr);               /* Save current CPSR */
247      SET_REGISTER(arm, SPSR, cpsr);               /* Save current CPSR */
248248      SET_CPSR(GET_CPSR | I_MASK);            /* Mask IRQ */
249249      SET_CPSR(GET_CPSR & ~T_MASK);
250250      R15 = 0x04;                             /* IRQ Vector address */
251251      if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000;
252      cpustate->pendingUnd = 0;
252      arm->pendingUnd = 0;
253253      return;
254254   }
255255
256256   // Software Interrupt
257   if (cpustate->pendingSwi) {
258      SwitchMode(cpustate, eARM7_MODE_SVC);             /* Set SVC mode so PC is saved to correct R14 bank */
257   if (arm->pendingSwi) {
258      SwitchMode(arm, eARM7_MODE_SVC);             /* Set SVC mode so PC is saved to correct R14 bank */
259259      // compensate for prefetch (should this also be done for normal IRQ?)
260260      if (T_IS_SET(GET_CPSR))
261261      {
262            SET_REGISTER(cpustate, 14, pc - 4 + 2);         /* save PC to R14 */
262            SET_REGISTER(arm, 14, pc - 4 + 2);         /* save PC to R14 */
263263      }
264264      else
265265      {
266            SET_REGISTER(cpustate, 14, pc - 4 + 4);           /* save PC to R14 */
266            SET_REGISTER(arm, 14, pc - 4 + 4);           /* save PC to R14 */
267267      }
268268      if (MODE32)
269269      {
270         SET_REGISTER(cpustate, SPSR, cpsr);               /* Save current CPSR */
270         SET_REGISTER(arm, SPSR, cpsr);               /* Save current CPSR */
271271         SET_CPSR(GET_CPSR | I_MASK);            /* Mask IRQ */
272272         SET_CPSR(GET_CPSR & ~T_MASK);           /* Go to ARM mode */
273273         R15 = 0x08;                             /* Jump to the SWI vector */
r20717r20718
280280         SET_CPSR(temp);            /* Mask IRQ */
281281      }
282282      if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000;
283      cpustate->pendingSwi = 0;
283      arm->pendingSwi = 0;
284284      return;
285285   }
286286}
287287
288288// CPU - SET IRQ LINE
289static void arm7_core_set_irq_line(arm_state *cpustate, int irqline, int state)
289static void arm7_core_set_irq_line(arm_state *arm, int irqline, int state)
290290{
291291   switch (irqline) {
292292   case ARM7_IRQ_LINE: /* IRQ */
293      cpustate->pendingIrq = state & 1;
293      arm->pendingIrq = state & 1;
294294      break;
295295
296296   case ARM7_FIRQ_LINE: /* FIRQ */
297      cpustate->pendingFiq = state & 1;
297      arm->pendingFiq = state & 1;
298298      break;
299299
300300   case ARM7_ABORT_EXCEPTION:
301      cpustate->pendingAbtD = state & 1;
301      arm->pendingAbtD = state & 1;
302302      break;
303303   case ARM7_ABORT_PREFETCH_EXCEPTION:
304      cpustate->pendingAbtP = state & 1;
304      arm->pendingAbtP = state & 1;
305305      break;
306306
307307   case ARM7_UNDEFINE_EXCEPTION:
308      cpustate->pendingUnd = state & 1;
308      arm->pendingUnd = state & 1;
309309      break;
310310   }
311311
trunk/src/emu/cpu/arm7/arm7drc.c
r0r20718
1/*****************************************************************************
2 *
3 *   arm7.c
4 *   Portable CPU Emulator for 32-bit ARM v3/4/5/6
5 *
6 *   Copyright Steve Ellenoff, all rights reserved.
7 *   Thumb, DSP, and MMU support and many bugfixes by R. Belmont and Ryan Holtz.
8 *   Dyanmic Recompiler (DRC) / Just In Time Compiler (JIT) by Ryan Holtz.
9 *
10 *   - This source code is released as freeware for non-commercial purposes.
11 *   - You are free to use and redistribute this code in modified or
12 *     unmodified form, provided you list me in the credits.
13 *   - If you modify this source code, you must add a notice to each modified
14 *     source file that it has been changed.  If you're a nice person, you
15 *     will clearly mark each change too.  :)
16 *   - If you wish to use this for commercial purposes, please contact me at
17 *     sellenoff@hotmail.com
18 *   - The author of this copywritten work reserves the right to change the
19 *     terms of its usage and license at any time, including retroactively
20 *   - This entire notice must remain in the source code.
21 *
22 *  This work is based on:
23 *  #1) 'Atmel Corporation ARM7TDMI (Thumb) Datasheet - January 1999'
24 *  #2) Arm 2/3/6 emulator By Bryan McPhail (bmcphail@tendril.co.uk) and Phil Stroffolino (MAME CORE 0.76)
25 *
26 *****************************************************************************/
27
28/******************************************************************************
29 *  Notes:
30
31    ** This is a plain vanilla implementation of an ARM7 cpu which incorporates my ARM7 core.
32       It can be used as is, or used to demonstrate how to utilize the arm7 core to create a cpu
33       that uses the core, since there are numerous different mcu packages that incorporate an arm7 core.
34
35       See the notes in the arm7core.c file itself regarding issues/limitations of the arm7 core.
36    **
37*****************************************************************************/
38
39#include "emu.h"
40#include "debugger.h"
41#include "arm7fe.h"
42#include "cpu/drcfe.h"
43#include "cpu/drcuml.h"
44#include "cpu/drcumlsh.h"
45
46#ifdef ARM7_USE_DRC
47
48using namespace uml;
49
50/***************************************************************************
51    DEBUGGING
52***************************************************************************/
53
54#define FORCE_C_BACKEND                 (0)
55#define LOG_UML                         (0)
56#define LOG_NATIVE                      (0)
57
58#define SINGLE_INSTRUCTION_MODE         (0)
59
60/***************************************************************************
61    CONSTANTS
62***************************************************************************/
63
64/* map variables */
65#define MAPVAR_PC                       M0
66#define MAPVAR_CYCLES                   M1
67
68/* size of the execution code cache */
69#define CACHE_SIZE                      (32 * 1024 * 1024)
70
71/* compilation boundaries -- how far back/forward does the analysis extend? */
72#define COMPILE_BACKWARDS_BYTES         128
73#define COMPILE_FORWARDS_BYTES          512
74#define COMPILE_MAX_INSTRUCTIONS        ((COMPILE_BACKWARDS_BYTES/4) + (COMPILE_FORWARDS_BYTES/4))
75#define COMPILE_MAX_SEQUENCE            64
76
77/* exit codes */
78#define EXECUTE_OUT_OF_CYCLES           0
79#define EXECUTE_MISSING_CODE            1
80#define EXECUTE_UNMAPPED_CODE           2
81#define EXECUTE_RESET_CACHE             3
82
83
84
85/***************************************************************************
86    MACROS
87***************************************************************************/
88
89/***************************************************************************
90    STRUCTURES & TYPEDEFS
91***************************************************************************/
92
93/* fast RAM info */
94struct fast_ram_info
95{
96   offs_t              start;                      /* start of the RAM block */
97   offs_t              end;                        /* end of the RAM block */
98   UINT8               readonly;                   /* TRUE if read-only */
99   void *              base;                       /* base in memory where the RAM lives */
100};
101
102
103/* internal compiler state */
104struct compiler_state
105{
106   UINT32              cycles;                     /* accumulated cycles */
107   UINT8               checkints;                  /* need to check interrupts before next instruction */
108   UINT8               checksoftints;              /* need to check software interrupts before next instruction */
109   code_label  labelnum;                   /* index for local labels */
110};
111
112
113/* ARM7 registers */
114struct arm7imp_state
115{
116   /* core state */
117   drc_cache *         cache;                      /* pointer to the DRC code cache */
118   drcuml_state *      drcuml;                     /* DRC UML generator state */
119   arm7_frontend *       drcfe;                      /* pointer to the DRC front-end state */
120   UINT32              drcoptions;                 /* configurable DRC options */
121
122   /* internal stuff */
123   UINT8               cache_dirty;                /* true if we need to flush the cache */
124   UINT32              jmpdest;                    /* destination jump target */
125
126   /* parameters for subroutines */
127   UINT64              numcycles;                  /* return value from gettotalcycles */
128   UINT32              mode;                       /* current global mode */
129   const char *        format;                     /* format string for print_debug */
130   UINT32              arg0;                       /* print_debug argument 1 */
131   UINT32              arg1;                       /* print_debug argument 2 */
132
133   /* register mappings */
134   parameter   regmap[NUM_REGS];               /* parameter to register mappings for all 16 integer registers */
135
136   /* subroutines */
137   code_handle *   entry;                      /* entry point */
138   code_handle *   nocode;                     /* nocode exception handler */
139   code_handle *   out_of_cycles;              /* out of cycles exception handler */
140   code_handle *   read8;                      /* read byte */
141   code_handle *   write8;                     /* write byte */
142   code_handle *   read16;                     /* read half */
143   code_handle *   write16;                    /* write half */
144   code_handle *   read32;                     /* read word */
145   code_handle *   write32;                    /* write word */
146
147   /* fast RAM */
148   UINT32              fastram_select;
149   fast_ram_info       fastram[MIPS3_MAX_FASTRAM];
150};
151
152
153
154/***************************************************************************
155    FUNCTION PROTOTYPES
156***************************************************************************/
157
158static void code_flush_cache(arm_state *arm);
159static void code_compile_block(arm_state *arm, UINT8 mode, offs_t pc);
160
161static void cfunc_printf_exception(void *param);
162static void cfunc_get_cycles(void *param);
163
164static void static_generate_entry_point(arm_state *arm);
165static void static_generate_nocode_handler(arm_state *arm);
166static void static_generate_out_of_cycles(arm_state *arm);
167static void static_generate_tlb_translate(arm_state *arm);
168
169static void generate_update_cycles(arm_state *arm, drcuml_block *block, compiler_state *compiler, parameter param, int allow_exception);
170static void generate_checksum_block(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *seqhead, const opcode_desc *seqlast);
171static void generate_sequence_instruction(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
172static void generate_delay_slot_and_branch(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT8 linkreg);
173static int generate_opcode(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
174
175static void log_add_disasm_comment(arm_state *arm, drcuml_block *block, UINT32 pc, UINT32 op);
176static const char *log_desc_flags_to_string(UINT32 flags);
177static void log_register_list(drcuml_state *drcuml, const char *string, const UINT32 *reglist, const UINT32 *regnostarlist);
178static void log_opcode_desc(drcuml_state *drcuml, const opcode_desc *desclist, int indent);
179
180/***************************************************************************
181    PRIVATE GLOBAL VARIABLES
182***************************************************************************/
183
184/***************************************************************************
185    INLINE FUNCTIONS
186***************************************************************************/
187
188INLINE arm_state *get_safe_token(device_t *device)
189{
190   assert(device != NULL);
191   assert(device->type() == ARM7 ||
192         device->type() == ARM7_BE ||
193         device->type() == ARM7500 ||
194         device->type() == ARM9 ||
195         device->type() == ARM920T ||
196         device->type() == PXA255 ||
197         device->type() == SA1110);
198   return *(arm_state **)downcast<legacy_cpu_device *>(device)->token();
199}
200
201/*-------------------------------------------------
202    epc - compute the exception PC from a
203    descriptor
204-------------------------------------------------*/
205
206INLINE UINT32 epc(const opcode_desc *desc)
207{
208   return desc->pc;
209}
210
211
212/*-------------------------------------------------
213    alloc_handle - allocate a handle if not
214    already allocated
215-------------------------------------------------*/
216
217INLINE void alloc_handle(drcuml_state *drcuml, code_handle **handleptr, const char *name)
218{
219   if (*handleptr == NULL)
220      *handleptr = drcuml->handle_alloc(name);
221}
222
223
224/*-------------------------------------------------
225    load_fast_iregs - load any fast integer
226    registers
227-------------------------------------------------*/
228
229INLINE void load_fast_iregs(arm_state *arm, drcuml_block *block)
230{
231   int regnum;
232
233   for (regnum = 0; regnum < ARRAY_LENGTH(arm->impstate->regmap); regnum++)
234      if (arm->impstate->regmap[regnum].is_int_register())
235         UML_DMOV(block, ireg(arm->impstate->regmap[regnum].ireg() - REG_I0), mem(&arm->r[regnum]));
236}
237
238
239/*-------------------------------------------------
240    save_fast_iregs - save any fast integer
241    registers
242-------------------------------------------------*/
243
244INLINE void save_fast_iregs(arm_state *arm, drcuml_block *block)
245{
246   int regnum;
247
248   for (regnum = 0; regnum < ARRAY_LENGTH(arm->impstate->regmap); regnum++)
249      if (arm->impstate->regmap[regnum].is_int_register())
250         UML_DMOV(block, mem(&arm->r[regnum]), ireg(arm->impstate->regmap[regnum].ireg() - REG_I0));
251}
252
253
254
255/***************************************************************************
256    CORE CALLBACKS
257***************************************************************************/
258
259/*-------------------------------------------------
260    arm7_init - initialize the processor
261-------------------------------------------------*/
262
263static void arm7_init(arm7_flavor flavor, int bigendian, legacy_cpu_device *device, device_irq_acknowledge_callback irqcallback)
264{
265   arm_state *arm;
266   drc_cache *cache;
267   drcbe_info beinfo;
268   UINT32 flags = 0;
269   int regnum;
270
271   arm7_core_init(device, "arm7");
272   /* allocate enough space for the cache and the core */
273   cache = auto_alloc(device->machine(), drc_cache(CACHE_SIZE + sizeof(*arm)));
274   if (cache == NULL)
275      fatalerror("Unable to allocate cache of size %d\n", (UINT32)(CACHE_SIZE + sizeof(*arm)));
276
277   /* allocate the core memory */
278   *(arm_state **)device->token() = arm = (arm_state *)cache->alloc_near(sizeof(*arm));
279   memset(arm, 0, sizeof(*arm));
280
281   /* initialize the core */
282   arm7_core_init(device, "arm7");
283
284   /* allocate the implementation-specific state from the full cache */
285   arm->impstate = (arm7imp_state *)cache->alloc_near(sizeof(*arm->impstate));
286   memset(arm->impstate, 0, sizeof(*arm->impstate));
287   arm->impstate->cache = cache;
288
289   /* initialize the UML generator */
290   if (FORCE_C_BACKEND)
291      flags |= DRCUML_OPTION_USE_C;
292   if (LOG_UML)
293      flags |= DRCUML_OPTION_LOG_UML;
294   if (LOG_NATIVE)
295      flags |= DRCUML_OPTION_LOG_NATIVE;
296   arm->impstate->drcuml = auto_alloc(device->machine(), drcuml_state(*device, *cache, flags, 1, 32, 1));
297
298   /* add symbols for our stuff */
299   arm->impstate->drcuml->symbol_add(&arm->pc, sizeof(mips3->pc), "pc");
300   arm->impstate->drcuml->symbol_add(&arm->icount, sizeof(mips3->icount), "icount");
301   for (int regnum = 0; regnum < 37; regnum++)
302   {
303      char buf[10];
304      sprintf(buf, "r%d", regnum);
305      arm->impstate->drcuml->symbol_add(&arm->r[regnum], sizeof(arm->r[regnum]), buf);
306   }
307   arm->impstate->drcuml->symbol_add(&arm->impstate->mode, sizeof(arm->impstate->mode), "mode");
308   arm->impstate->drcuml->symbol_add(&arm->impstate->arg0, sizeof(arm->impstate->arg0), "arg0");
309   arm->impstate->drcuml->symbol_add(&arm->impstate->arg1, sizeof(arm->impstate->arg1), "arg1");
310   arm->impstate->drcuml->symbol_add(&arm->impstate->numcycles, sizeof(arm->impstate->numcycles), "numcycles");
311   arm->impstate->drcuml->symbol_add(&arm->impstate->fpmode, sizeof(arm->impstate->fpmode), "fpmode");
312
313   /* initialize the front-end helper */
314   arm->impstate->drcfe = auto_alloc(device->machine(), arm7_frontend(*arm, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE));
315
316   /* allocate memory for cache-local state and initialize it */
317   memcpy(arm->impstate->fpmode, fpmode_source, sizeof(fpmode_source));
318
319   /* compute the register parameters */
320   for (int regnum = 0; regnum < 37; regnum++)
321   {
322      arm->impstate->regmap[regnum] = (regnum == 0) ? parameter(0) : parameter::make_memory(&arm->r[regnum]);
323   }
324
325   /* if we have registers to spare, assign r2, r3, r4 to leftovers */
326   if (!DISABLE_FAST_REGISTERS)
327   {
328      arm->impstate->drcuml->get_backend_info(beinfo);
329      if (beinfo.direct_iregs > 4)
330      {   // PC
331         arm->impstate->regmap[eR15] = I4;
332      }
333      if (beinfo.direct_iregs > 5)
334      {   // Status
335         arm->impstate->regmap[eCPSR] = I5;
336      }
337      if (beinfo.direct_iregs > 6)
338      {   // SP
339         arm->impstate->regmap[eR13] = I6;
340      }
341   }
342
343   /* mark the cache dirty so it is updated on next execute */
344   arm->impstate->cache_dirty = TRUE;
345}
346
347
348/*-------------------------------------------------
349    arm7_reset - reset the processor
350-------------------------------------------------*/
351
352static CPU_RESET( arm7 )
353{
354   arm_state *arm = get_safe_token(device);
355
356   /* reset the common code and mark the cache dirty */
357   arm7_core_reset(arm);
358
359   arm->impstate->cache_dirty = TRUE;
360
361   arm->archRev = 4;  // ARMv4
362   arm->archFlags = eARM_ARCHFLAGS_T; // has Thumb
363}
364
365static CPU_RESET( arm7_be )
366{
367   arm_state *arm = get_safe_token(device);
368
369   /* reset the common code and mark the cache dirty */
370   arm7_core_reset(arm);
371
372   arm->impstate->cache_dirty = TRUE;
373
374   arm->endian = ENDIANNESS_BIG;
375
376   arm->archRev = 4;  // ARMv4
377   arm->archFlags = eARM_ARCHFLAGS_T; // has Thumb
378}
379
380static CPU_RESET( arm7500 )
381{
382   arm_state *arm = get_safe_token(device);
383
384   // must call core reset
385   arm7_core_reset(device);
386
387   arm->impstate->cache_dirty = TRUE;
388
389   arm->archRev = 3;  // ARMv3
390   arm->archFlags = eARM_ARCHFLAGS_MODE26;
391}
392
393static CPU_RESET( arm9 )
394{
395   arm_state *arm = get_safe_token(device);
396
397   // must call core reset
398   arm7_core_reset(device);
399
400   arm->impstate->cache_dirty = TRUE;
401
402   arm->archRev = 5;  // ARMv5
403   arm->archFlags = eARM_ARCHFLAGS_T | eARM_ARCHFLAGS_E;  // has TE extensions
404}
405
406static CPU_RESET( arm920t )
407{
408   arm_state *arm = get_safe_token(device);
409
410   // must call core reset
411   arm7_core_reset(device);
412
413   arm->impstate->cache_dirty = TRUE;
414
415   arm->archRev = 4;  // ARMv4
416   arm->archFlags = eARM_ARCHFLAGS_T; // has T extension
417}
418
419static CPU_RESET( pxa255 )
420{
421   arm_state *arm = get_safe_token(device);
422
423   // must call core reset
424   arm7_core_reset(device);
425
426   arm->impstate->cache_dirty = TRUE;
427
428   arm->archRev = 5;  // ARMv5
429   arm->archFlags = eARM_ARCHFLAGS_T | eARM_ARCHFLAGS_E | eARM_ARCHFLAGS_XSCALE;  // has TE and XScale extensions
430}
431
432static CPU_RESET( sa1110 )
433{
434   arm_state *arm = get_safe_token(device);
435
436   // must call core reset
437   arm7_core_reset(device);
438
439   arm->impstate->cache_dirty = TRUE;
440
441   arm->archRev = 4;  // ARMv4
442   arm->archFlags = eARM_ARCHFLAGS_SA;    // has StrongARM, no Thumb, no Enhanced DSP
443}
444
445/*-------------------------------------------------
446    arm7_execute - execute the CPU for the
447    specified number of cycles
448-------------------------------------------------*/
449
450static CPU_EXECUTE( arm7 )
451{
452   arm_state *arm = get_safe_token(device);
453   drcuml_state *drcuml = arm->impstate->drcuml;
454   int execute_result;
455
456   /* reset the cache if dirty */
457   if (arm->impstate->cache_dirty)
458      code_flush_cache(arm);
459   arm->impstate->cache_dirty = FALSE;
460
461   /* execute */
462   do
463   {
464      /* run as much as we can */
465      execute_result = drcuml->execute(*arm->impstate->entry);
466
467      /* if we need to recompile, do it */
468      if (execute_result == EXECUTE_MISSING_CODE)
469         code_compile_block(arm, arm->impstate->mode, arm->r[eR15]);
470      else if (execute_result == EXECUTE_UNMAPPED_CODE)
471         fatalerror("Attempted to execute unmapped code at PC=%08X\n", arm->r[eR15]);
472      else if (execute_result == EXECUTE_RESET_CACHE)
473         code_flush_cache(arm);
474
475   } while (execute_result != EXECUTE_OUT_OF_CYCLES);
476}
477
478/*-------------------------------------------------
479    mips3_exit - cleanup from execution
480-------------------------------------------------*/
481
482static CPU_EXIT( mips3 )
483{
484   arm_state *arm = get_safe_token(device);
485
486   /* clean up the DRC */
487   auto_free(device->machine(), arm->impstate->drcfe);
488   auto_free(device->machine(), arm->impstate->drcuml);
489   auto_free(device->machine(), arm->impstate->cache);
490}
491
492
493/*-------------------------------------------------
494    mips3_translate - perform virtual-to-physical
495    address translation
496-------------------------------------------------*/
497
498static CPU_TRANSLATE( arm7 )
499{
500   arm_state *arm = get_safe_token(device);
501
502   /* only applies to the program address space and only does something if the MMU's enabled */
503   if( space == AS_PROGRAM && ( COPRO_CTRL & COPRO_CTRL_MMU_EN ) )
504   {
505      return arm7_tlb_translate(arm, address, 0);
506   }
507   return TRUE;
508}
509
510
511static CPU_DISASSEMBLE( arm7 )
512{
513   CPU_DISASSEMBLE( arm7arm );
514   CPU_DISASSEMBLE( arm7thumb );
515
516   arm_state *arm = get_safe_token(device);
517
518   if (T_IS_SET(GET_CPSR))
519      return CPU_DISASSEMBLE_CALL(arm7thumb);
520   else
521      return CPU_DISASSEMBLE_CALL(arm7arm);
522}
523
524
525/*-------------------------------------------------
526    arm7_set_info - set information about a given
527    CPU instance
528-------------------------------------------------*/
529
530static CPU_SET_INFO( arm7 )
531{
532   arm_state *arm = get_safe_token(device);
533
534   switch (state)
535   {
536      /* --- the following bits of info are set as 64-bit signed integers --- */
537
538      /* interrupt lines/exceptions */
539      case CPUINFO_INT_INPUT_STATE + ARM7_IRQ_LINE:                   set_irq_line(arm, ARM7_IRQ_LINE, info->i); break;
540      case CPUINFO_INT_INPUT_STATE + ARM7_FIRQ_LINE:                  set_irq_line(arm, ARM7_FIRQ_LINE, info->i); break;
541      case CPUINFO_INT_INPUT_STATE + ARM7_ABORT_EXCEPTION:            set_irq_line(arm, ARM7_ABORT_EXCEPTION, info->i); break;
542      case CPUINFO_INT_INPUT_STATE + ARM7_ABORT_PREFETCH_EXCEPTION:   set_irq_line(arm, ARM7_ABORT_PREFETCH_EXCEPTION, info->i); break;
543      case CPUINFO_INT_INPUT_STATE + ARM7_UNDEFINE_EXCEPTION:         set_irq_line(arm, ARM7_UNDEFINE_EXCEPTION, info->i); break;
544
545      /* registers shared by all operating modes */
546      case CPUINFO_INT_REGISTER + ARM7_R0:            ARM7REG( 0) = info->i;                  break;
547      case CPUINFO_INT_REGISTER + ARM7_R1:            ARM7REG( 1) = info->i;                  break;
548      case CPUINFO_INT_REGISTER + ARM7_R2:            ARM7REG( 2) = info->i;                  break;
549      case CPUINFO_INT_REGISTER + ARM7_R3:            ARM7REG( 3) = info->i;                  break;
550      case CPUINFO_INT_REGISTER + ARM7_R4:            ARM7REG( 4) = info->i;                  break;
551      case CPUINFO_INT_REGISTER + ARM7_R5:            ARM7REG( 5) = info->i;                  break;
552      case CPUINFO_INT_REGISTER + ARM7_R6:            ARM7REG( 6) = info->i;                  break;
553      case CPUINFO_INT_REGISTER + ARM7_R7:            ARM7REG( 7) = info->i;                  break;
554      case CPUINFO_INT_REGISTER + ARM7_R8:            ARM7REG( 8) = info->i;                  break;
555      case CPUINFO_INT_REGISTER + ARM7_R9:            ARM7REG( 9) = info->i;                  break;
556      case CPUINFO_INT_REGISTER + ARM7_R10:           ARM7REG(10) = info->i;                  break;
557      case CPUINFO_INT_REGISTER + ARM7_R11:           ARM7REG(11) = info->i;                  break;
558      case CPUINFO_INT_REGISTER + ARM7_R12:           ARM7REG(12) = info->i;                  break;
559      case CPUINFO_INT_REGISTER + ARM7_R13:           ARM7REG(13) = info->i;                  break;
560      case CPUINFO_INT_REGISTER + ARM7_R14:           ARM7REG(14) = info->i;                  break;
561      case CPUINFO_INT_REGISTER + ARM7_R15:           ARM7REG(15) = info->i;                  break;
562      case CPUINFO_INT_REGISTER + ARM7_CPSR:          SET_CPSR(info->i);                      break;
563
564      case CPUINFO_INT_PC:
565      case CPUINFO_INT_REGISTER + ARM7_PC:            R15 = info->i;                          break;
566      case CPUINFO_INT_SP:                            SetRegister(arm, 13,info->i);                break;
567
568      /* FIRQ Mode Shadowed Registers */
569      case CPUINFO_INT_REGISTER + ARM7_FR8:           ARM7REG(eR8_FIQ)  = info->i;            break;
570      case CPUINFO_INT_REGISTER + ARM7_FR9:           ARM7REG(eR9_FIQ)  = info->i;            break;
571      case CPUINFO_INT_REGISTER + ARM7_FR10:          ARM7REG(eR10_FIQ) = info->i;            break;
572      case CPUINFO_INT_REGISTER + ARM7_FR11:          ARM7REG(eR11_FIQ) = info->i;            break;
573      case CPUINFO_INT_REGISTER + ARM7_FR12:          ARM7REG(eR12_FIQ) = info->i;            break;
574      case CPUINFO_INT_REGISTER + ARM7_FR13:          ARM7REG(eR13_FIQ) = info->i;            break;
575      case CPUINFO_INT_REGISTER + ARM7_FR14:          ARM7REG(eR14_FIQ) = info->i;            break;
576      case CPUINFO_INT_REGISTER + ARM7_FSPSR:         ARM7REG(eSPSR_FIQ) = info->i;           break;
577
578      /* IRQ Mode Shadowed Registers */
579      case CPUINFO_INT_REGISTER + ARM7_IR13:          ARM7REG(eR13_IRQ) = info->i;            break;
580      case CPUINFO_INT_REGISTER + ARM7_IR14:          ARM7REG(eR14_IRQ) = info->i;            break;
581      case CPUINFO_INT_REGISTER + ARM7_ISPSR:         ARM7REG(eSPSR_IRQ) = info->i;           break;
582
583      /* Supervisor Mode Shadowed Registers */
584      case CPUINFO_INT_REGISTER + ARM7_SR13:          ARM7REG(eR13_SVC) = info->i;            break;
585      case CPUINFO_INT_REGISTER + ARM7_SR14:          ARM7REG(eR14_SVC) = info->i;            break;
586      case CPUINFO_INT_REGISTER + ARM7_SSPSR:         ARM7REG(eSPSR_SVC) = info->i;           break;
587
588      /* Abort Mode Shadowed Registers */
589      case CPUINFO_INT_REGISTER + ARM7_AR13:          ARM7REG(eR13_ABT) = info->i;            break;
590      case CPUINFO_INT_REGISTER + ARM7_AR14:          ARM7REG(eR14_ABT) = info->i;            break;
591      case CPUINFO_INT_REGISTER + ARM7_ASPSR:         ARM7REG(eSPSR_ABT) = info->i;           break;
592
593      /* Undefined Mode Shadowed Registers */
594      case CPUINFO_INT_REGISTER + ARM7_UR13:          ARM7REG(eR13_UND) = info->i;            break;
595      case CPUINFO_INT_REGISTER + ARM7_UR14:          ARM7REG(eR14_UND) = info->i;            break;
596      case CPUINFO_INT_REGISTER + ARM7_USPSR:         ARM7REG(eSPSR_UND) = info->i;           break;
597   }
598}
599
600
601/*-------------------------------------------------
602    arm7_get_info - return information about a
603    given CPU instance
604-------------------------------------------------*/
605
606static CPU_GET_INFO( arm7 )
607{
608   arm_state *arm = get_safe_token(device);
609
610   switch (state)
611   {
612      /* --- the following bits of info are returned as 64-bit signed integers --- */
613
614      /* cpu implementation data */
615      case CPUINFO_INT_CONTEXT_SIZE:                  info->i = sizeof(arm_state);                 break;
616      case CPUINFO_INT_INPUT_LINES:                   info->i = ARM7_NUM_LINES;               break;
617      case CPUINFO_INT_DEFAULT_IRQ_VECTOR:            info->i = 0;                            break;
618      case CPUINFO_INT_ENDIANNESS:                    info->i = ENDIANNESS_LITTLE;                    break;
619      case CPUINFO_INT_CLOCK_MULTIPLIER:              info->i = 1;                            break;
620      case CPUINFO_INT_CLOCK_DIVIDER:                 info->i = 1;                            break;
621      case CPUINFO_INT_MIN_INSTRUCTION_BYTES:         info->i = 2;                            break;
622      case CPUINFO_INT_MAX_INSTRUCTION_BYTES:         info->i = 4;                            break;
623      case CPUINFO_INT_MIN_CYCLES:                    info->i = 3;                            break;
624      case CPUINFO_INT_MAX_CYCLES:                    info->i = 4;                            break;
625
626      case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 32;                   break;
627      case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 32;                   break;
628      case CPUINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM: info->i = 0;                    break;
629      case CPUINFO_INT_DATABUS_WIDTH + AS_DATA:    info->i = 0;                    break;
630      case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA:    info->i = 0;                    break;
631      case CPUINFO_INT_ADDRBUS_SHIFT + AS_DATA:    info->i = 0;                    break;
632      case CPUINFO_INT_DATABUS_WIDTH + AS_IO:      info->i = 0;                    break;
633      case CPUINFO_INT_ADDRBUS_WIDTH + AS_IO:      info->i = 0;                    break;
634      case CPUINFO_INT_ADDRBUS_SHIFT + AS_IO:      info->i = 0;                    break;
635
636      /* interrupt lines/exceptions */
637      case CPUINFO_INT_INPUT_STATE + ARM7_IRQ_LINE:                   info->i = arm->pendingIrq; break;
638      case CPUINFO_INT_INPUT_STATE + ARM7_FIRQ_LINE:                  info->i = arm->pendingFiq; break;
639      case CPUINFO_INT_INPUT_STATE + ARM7_ABORT_EXCEPTION:            info->i = arm->pendingAbtD; break;
640      case CPUINFO_INT_INPUT_STATE + ARM7_ABORT_PREFETCH_EXCEPTION:   info->i = arm->pendingAbtP; break;
641      case CPUINFO_INT_INPUT_STATE + ARM7_UNDEFINE_EXCEPTION:         info->i = arm->pendingUnd; break;
642
643      /* registers shared by all operating modes */
644      case CPUINFO_INT_REGISTER + ARM7_R0:    info->i = ARM7REG( 0);                          break;
645      case CPUINFO_INT_REGISTER + ARM7_R1:    info->i = ARM7REG( 1);                          break;
646      case CPUINFO_INT_REGISTER + ARM7_R2:    info->i = ARM7REG( 2);                          break;
647      case CPUINFO_INT_REGISTER + ARM7_R3:    info->i = ARM7REG( 3);                          break;
648      case CPUINFO_INT_REGISTER + ARM7_R4:    info->i = ARM7REG( 4);                          break;
649      case CPUINFO_INT_REGISTER + ARM7_R5:    info->i = ARM7REG( 5);                          break;
650      case CPUINFO_INT_REGISTER + ARM7_R6:    info->i = ARM7REG( 6);                          break;
651      case CPUINFO_INT_REGISTER + ARM7_R7:    info->i = ARM7REG( 7);                          break;
652      case CPUINFO_INT_REGISTER + ARM7_R8:    info->i = ARM7REG( 8);                          break;
653      case CPUINFO_INT_REGISTER + ARM7_R9:    info->i = ARM7REG( 9);                          break;
654      case CPUINFO_INT_REGISTER + ARM7_R10:   info->i = ARM7REG(10);                          break;
655      case CPUINFO_INT_REGISTER + ARM7_R11:   info->i = ARM7REG(11);                          break;
656      case CPUINFO_INT_REGISTER + ARM7_R12:   info->i = ARM7REG(12);                          break;
657      case CPUINFO_INT_REGISTER + ARM7_R13:   info->i = ARM7REG(13);                          break;
658      case CPUINFO_INT_REGISTER + ARM7_R14:   info->i = ARM7REG(14);                          break;
659      case CPUINFO_INT_REGISTER + ARM7_R15:   info->i = ARM7REG(15);                          break;
660
661      case CPUINFO_INT_PREVIOUSPC:            info->i = 0;    /* not implemented */           break;
662      case CPUINFO_INT_PC:
663      case CPUINFO_INT_REGISTER + ARM7_PC:    info->i = GET_PC;                                  break;
664      case CPUINFO_INT_SP:                    info->i = GetRegister(arm, 13);            break;
665
666      /* FIRQ Mode Shadowed Registers */
667      case CPUINFO_INT_REGISTER + ARM7_FR8:   info->i = ARM7REG(eR8_FIQ);                     break;
668      case CPUINFO_INT_REGISTER + ARM7_FR9:   info->i = ARM7REG(eR9_FIQ);                     break;
669      case CPUINFO_INT_REGISTER + ARM7_FR10:  info->i = ARM7REG(eR10_FIQ);                    break;
670      case CPUINFO_INT_REGISTER + ARM7_FR11:  info->i = ARM7REG(eR11_FIQ);                    break;
671      case CPUINFO_INT_REGISTER + ARM7_FR12:  info->i = ARM7REG(eR12_FIQ);                    break;
672      case CPUINFO_INT_REGISTER + ARM7_FR13:  info->i = ARM7REG(eR13_FIQ);                    break;
673      case CPUINFO_INT_REGISTER + ARM7_FR14:  info->i = ARM7REG(eR14_FIQ);                    break;
674      case CPUINFO_INT_REGISTER + ARM7_FSPSR: info->i = ARM7REG(eSPSR_FIQ);                   break;
675
676      /* IRQ Mode Shadowed Registers */
677      case CPUINFO_INT_REGISTER + ARM7_IR13:  info->i = ARM7REG(eR13_IRQ);                    break;
678      case CPUINFO_INT_REGISTER + ARM7_IR14:  info->i = ARM7REG(eR14_IRQ);                    break;
679      case CPUINFO_INT_REGISTER + ARM7_ISPSR: info->i = ARM7REG(eSPSR_IRQ);                   break;
680
681      /* Supervisor Mode Shadowed Registers */
682      case CPUINFO_INT_REGISTER + ARM7_SR13:  info->i = ARM7REG(eR13_SVC);                    break;
683      case CPUINFO_INT_REGISTER + ARM7_SR14:  info->i = ARM7REG(eR14_SVC);                    break;
684      case CPUINFO_INT_REGISTER + ARM7_SSPSR: info->i = ARM7REG(eSPSR_SVC);                   break;
685
686      /* Abort Mode Shadowed Registers */
687      case CPUINFO_INT_REGISTER + ARM7_AR13:  info->i = ARM7REG(eR13_ABT);                    break;
688      case CPUINFO_INT_REGISTER + ARM7_AR14:  info->i = ARM7REG(eR14_ABT);                    break;
689      case CPUINFO_INT_REGISTER + ARM7_ASPSR: info->i = ARM7REG(eSPSR_ABT);                   break;
690
691      /* Undefined Mode Shadowed Registers */
692      case CPUINFO_INT_REGISTER + ARM7_UR13:  info->i = ARM7REG(eR13_UND);                    break;
693      case CPUINFO_INT_REGISTER + ARM7_UR14:  info->i = ARM7REG(eR14_UND);                    break;
694      case CPUINFO_INT_REGISTER + ARM7_USPSR: info->i = ARM7REG(eSPSR_UND);                   break;
695
696      /* --- the following bits of info are returned as pointers to data or functions --- */
697      case CPUINFO_FCT_SET_INFO:              info->setinfo = CPU_SET_INFO_NAME(arm7);                  break;
698      case CPUINFO_FCT_INIT:                  info->init = CPU_INIT_NAME(arm7);                         break;
699      case CPUINFO_FCT_RESET:                 info->reset = CPU_RESET_NAME(arm7);                       break;
700      case CPUINFO_FCT_EXIT:                  info->exit = CPU_EXIT_NAME(arm7);                         break;
701      case CPUINFO_FCT_EXECUTE:               info->execute = CPU_EXECUTE_NAME(arm7);                   break;
702      case CPUINFO_FCT_BURN:                  info->burn = NULL;                              break;
703      case CPUINFO_FCT_DISASSEMBLE:           info->disassemble = CPU_DISASSEMBLE_NAME(arm7);                  break;
704      case CPUINFO_PTR_INSTRUCTION_COUNTER:   info->icount = &ARM7_ICOUNT;                    break;
705   case CPUINFO_FCT_TRANSLATE:         info->translate = CPU_TRANSLATE_NAME(arm7);     break;
706
707      /* --- the following bits of info are returned as NULL-terminated strings --- */
708      case CPUINFO_STR_NAME:                  strcpy(info->s, "ARM7");                        break;
709      case CPUINFO_STR_FAMILY:           strcpy(info->s, "Acorn Risc Machine");          break;
710      case CPUINFO_STR_VERSION:          strcpy(info->s, "2.0");                         break;
711      case CPUINFO_STR_SOURCE_FILE:             strcpy(info->s, __FILE__);                      break;
712      case CPUINFO_STR_CREDITS:          strcpy(info->s, "Copyright Steve Ellenoff, sellenoff@hotmail.com"); break;
713
714      case CPUINFO_STR_FLAGS:
715         sprintf(info->s, "%c%c%c%c%c%c%c%c %s",
716               (ARM7REG(eCPSR) & N_MASK) ? 'N' : '-',
717               (ARM7REG(eCPSR) & Z_MASK) ? 'Z' : '-',
718               (ARM7REG(eCPSR) & C_MASK) ? 'C' : '-',
719               (ARM7REG(eCPSR) & V_MASK) ? 'V' : '-',
720               (ARM7REG(eCPSR) & Q_MASK) ? 'Q' : '-',
721               (ARM7REG(eCPSR) & I_MASK) ? 'I' : '-',
722               (ARM7REG(eCPSR) & F_MASK) ? 'F' : '-',
723               (ARM7REG(eCPSR) & T_MASK) ? 'T' : '-',
724               GetModeText(ARM7REG(eCPSR)));
725      break;
726
727      /* registers shared by all operating modes */
728      case CPUINFO_STR_REGISTER + ARM7_PC:    sprintf(info->s, "PC  :%08x", GET_PC);            break;
729      case CPUINFO_STR_REGISTER + ARM7_R0:    sprintf(info->s, "R0  :%08x", ARM7REG( 0));    break;
730      case CPUINFO_STR_REGISTER + ARM7_R1:    sprintf(info->s, "R1  :%08x", ARM7REG( 1));    break;
731      case CPUINFO_STR_REGISTER + ARM7_R2:    sprintf(info->s, "R2  :%08x", ARM7REG( 2));    break;
732      case CPUINFO_STR_REGISTER + ARM7_R3:    sprintf(info->s, "R3  :%08x", ARM7REG( 3));    break;
733      case CPUINFO_STR_REGISTER + ARM7_R4:    sprintf(info->s, "R4  :%08x", ARM7REG( 4));    break;
734      case CPUINFO_STR_REGISTER + ARM7_R5:    sprintf(info->s, "R5  :%08x", ARM7REG( 5));    break;
735      case CPUINFO_STR_REGISTER + ARM7_R6:    sprintf(info->s, "R6  :%08x", ARM7REG( 6));    break;
736      case CPUINFO_STR_REGISTER + ARM7_R7:    sprintf(info->s, "R7  :%08x", ARM7REG( 7));    break;
737      case CPUINFO_STR_REGISTER + ARM7_R8:    sprintf(info->s, "R8  :%08x", ARM7REG( 8));    break;
738      case CPUINFO_STR_REGISTER + ARM7_R9:    sprintf(info->s, "R9  :%08x", ARM7REG( 9));    break;
739      case CPUINFO_STR_REGISTER + ARM7_R10:   sprintf(info->s, "R10 :%08x", ARM7REG(10));    break;
740      case CPUINFO_STR_REGISTER + ARM7_R11:   sprintf(info->s, "R11 :%08x", ARM7REG(11));    break;
741      case CPUINFO_STR_REGISTER + ARM7_R12:   sprintf(info->s, "R12 :%08x", ARM7REG(12));    break;
742      case CPUINFO_STR_REGISTER + ARM7_R13:   sprintf(info->s, "R13 :%08x", ARM7REG(13));    break;
743      case CPUINFO_STR_REGISTER + ARM7_R14:   sprintf(info->s, "R14 :%08x", ARM7REG(14));    break;
744      case CPUINFO_STR_REGISTER + ARM7_R15:   sprintf(info->s, "R15 :%08x", ARM7REG(15));    break;
745
746      /* FIRQ Mode Shadowed Registers */
747      case CPUINFO_STR_REGISTER + ARM7_FR8:   sprintf(info->s, "FR8 :%08x", ARM7REG(eR8_FIQ)  ); break;
748      case CPUINFO_STR_REGISTER + ARM7_FR9:   sprintf(info->s, "FR9 :%08x", ARM7REG(eR9_FIQ)  ); break;
749      case CPUINFO_STR_REGISTER + ARM7_FR10:  sprintf(info->s, "FR10:%08x", ARM7REG(eR10_FIQ) ); break;
750      case CPUINFO_STR_REGISTER + ARM7_FR11:  sprintf(info->s, "FR11:%08x", ARM7REG(eR11_FIQ) ); break;
751      case CPUINFO_STR_REGISTER + ARM7_FR12:  sprintf(info->s, "FR12:%08x", ARM7REG(eR12_FIQ) ); break;
752      case CPUINFO_STR_REGISTER + ARM7_FR13:  sprintf(info->s, "FR13:%08x", ARM7REG(eR13_FIQ) ); break;
753      case CPUINFO_STR_REGISTER + ARM7_FR14:  sprintf(info->s, "FR14:%08x", ARM7REG(eR14_FIQ) ); break;
754      case CPUINFO_STR_REGISTER + ARM7_FSPSR: sprintf(info->s, "FR16:%08x", ARM7REG(eSPSR_FIQ)); break;
755
756      /* IRQ Mode Shadowed Registers */
757      case CPUINFO_STR_REGISTER + ARM7_IR13:  sprintf(info->s, "IR13:%08x", ARM7REG(eR13_IRQ) ); break;
758      case CPUINFO_STR_REGISTER + ARM7_IR14:  sprintf(info->s, "IR14:%08x", ARM7REG(eR14_IRQ) ); break;
759      case CPUINFO_STR_REGISTER + ARM7_ISPSR: sprintf(info->s, "IR16:%08x", ARM7REG(eSPSR_IRQ)); break;
760
761      /* Supervisor Mode Shadowed Registers */
762      case CPUINFO_STR_REGISTER + ARM7_SR13:  sprintf(info->s, "SR13:%08x", ARM7REG(eR13_SVC) ); break;
763      case CPUINFO_STR_REGISTER + ARM7_SR14:  sprintf(info->s, "SR14:%08x", ARM7REG(eR14_SVC) ); break;
764      case CPUINFO_STR_REGISTER + ARM7_SSPSR: sprintf(info->s, "SR16:%08x", ARM7REG(eSPSR_SVC)); break;
765
766      /* Abort Mode Shadowed Registers */
767      case CPUINFO_STR_REGISTER + ARM7_AR13:  sprintf(info->s, "AR13:%08x", ARM7REG(eR13_ABT) ); break;
768      case CPUINFO_STR_REGISTER + ARM7_AR14:  sprintf(info->s, "AR14:%08x", ARM7REG(eR14_ABT) ); break;
769      case CPUINFO_STR_REGISTER + ARM7_ASPSR: sprintf(info->s, "AR16:%08x", ARM7REG(eSPSR_ABT)); break;
770
771      /* Undefined Mode Shadowed Registers */
772      case CPUINFO_STR_REGISTER + ARM7_UR13:  sprintf(info->s, "UR13:%08x", ARM7REG(eR13_UND) ); break;
773      case CPUINFO_STR_REGISTER + ARM7_UR14:  sprintf(info->s, "UR14:%08x", ARM7REG(eR14_UND) ); break;
774      case CPUINFO_STR_REGISTER + ARM7_USPSR: sprintf(info->s, "UR16:%08x", ARM7REG(eSPSR_UND)); break;
775   }
776}
777
778CPU_GET_INFO( arm7_be )
779{
780   switch (state)
781   {
782      case CPUINFO_INT_ENDIANNESS:        info->i = ENDIANNESS_BIG;                               break;
783      case CPUINFO_FCT_RESET:             info->reset = CPU_RESET_NAME(arm7_be);                  break;
784      case CPUINFO_FCT_DISASSEMBLE:       info->disassemble = CPU_DISASSEMBLE_NAME(arm7_be);      break;
785      case CPUINFO_STR_NAME:              strcpy(info->s, "ARM7 (big endian)");                   break;
786      default:                            CPU_GET_INFO_CALL(arm7);
787   }
788}
789
790CPU_GET_INFO( arm7500 )
791{
792   switch (state)
793   {
794      case CPUINFO_FCT_RESET:     info->reset = CPU_RESET_NAME(arm7500);      break;
795      case CPUINFO_STR_NAME:      strcpy(info->s, "ARM7500");             break;
796      default:                    CPU_GET_INFO_CALL(arm7);
797      break;
798   }
799}
800
801CPU_GET_INFO( arm9 )
802{
803   switch (state)
804   {
805      case CPUINFO_FCT_RESET:                 info->reset = CPU_RESET_NAME(arm9);                       break;
806      case CPUINFO_STR_NAME:             strcpy(info->s, "ARM9");                        break;
807   default:    CPU_GET_INFO_CALL(arm7);
808      break;
809   }
810}
811
812CPU_GET_INFO( arm920t )
813{
814   switch (state)
815   {
816      case CPUINFO_FCT_RESET:                 info->reset = CPU_RESET_NAME(arm920t);                       break;
817      case CPUINFO_STR_NAME:             strcpy(info->s, "ARM920T");                        break;
818   default:    CPU_GET_INFO_CALL(arm7);
819      break;
820   }
821}
822
823CPU_GET_INFO( pxa255 )
824{
825   switch (state)
826   {
827      case CPUINFO_FCT_RESET:            info->reset = CPU_RESET_NAME(pxa255);                       break;
828      case CPUINFO_STR_NAME:             strcpy(info->s, "PXA255");                        break;
829   default:    CPU_GET_INFO_CALL(arm7);
830      break;
831   }
832}
833
834CPU_GET_INFO( sa1110 )
835{
836   switch (state)
837   {
838      case CPUINFO_FCT_RESET:            info->reset = CPU_RESET_NAME(sa1110);                       break;
839      case CPUINFO_STR_NAME:             strcpy(info->s, "SA1110");                        break;
840   default:    CPU_GET_INFO_CALL(arm7);
841      break;
842   }
843}
844
845
846/* ARM system coprocessor support */
847static WRITE32_DEVICE_HANDLER( arm7_do_callback )
848{
849   arm_state *arm = get_safe_token(device);
850   arm->pendingUnd = 1;
851}
852
853static READ32_DEVICE_HANDLER( arm7_rt_r_callback )
854{
855   arm_state *arm = get_safe_token(device);
856   UINT32 opcode = offset;
857   UINT8 cReg = ( opcode & INSN_COPRO_CREG ) >> INSN_COPRO_CREG_SHIFT;
858   UINT8 op2 =  ( opcode & INSN_COPRO_OP2 )  >> INSN_COPRO_OP2_SHIFT;
859   UINT8 op3 =    opcode & INSN_COPRO_OP3;
860   UINT8 cpnum = (opcode & INSN_COPRO_CPNUM) >> INSN_COPRO_CPNUM_SHIFT;
861   UINT32 data = 0;
862
863//    printf("cpnum %d cReg %d op2 %d op3 %d (%x)\n", cpnum, cReg, op2, op3, GET_REGISTER(arm, 15));
864
865   // we only handle system copro here
866   if (cpnum != 15)
867   {
868      if (arm->archFlags & eARM_ARCHFLAGS_XSCALE)
869   {
870      // handle XScale specific CP14
871      if (cpnum == 14)
872      {
873         switch( cReg )
874         {
875            case 1: // clock counter
876               data = (UINT32)arm->device->total_cycles();
877               break;
878
879            default:
880               break;
881         }
882      }
883      else
884      {
885         fatalerror("XScale: Unhandled coprocessor %d (archFlags %x)\n", cpnum, arm->archFlags);
886      }
887
888      return data;
889   }
890   else
891   {
892      LOG( ("ARM7: Unhandled coprocessor %d (archFlags %x)\n", cpnum, arm->archFlags) );
893      arm->pendingUnd = 1;
894      return 0;
895   }
896   }
897
898   switch( cReg )
899   {
900      case 4:
901      case 7:
902      case 8:
903      case 9:
904      case 10:
905      case 11:
906      case 12:
907         // RESERVED
908         LOG( ( "arm7_rt_r_callback CR%d, RESERVED\n", cReg ) );
909         break;
910      case 0:             // ID
911      switch(op2)
912      {
913         case 0:
914         switch (arm->archRev)
915         {
916            case 3: // ARM6 32-bit
917            data = 0x41;
918            break;
919
920         case 4: // ARM7/SA11xx
921            if (arm->archFlags & eARM_ARCHFLAGS_SA)
922            {
923               // ARM Architecture Version 4
924               // Part Number 0xB11 (SA1110)
925               // Stepping B5
926                  data = 0x69 | ( 0x01 << 16 ) | ( 0xB11 << 4 ) | 0x9;
927            }
928            else
929            {
930               if (device->type() == ARM920T)
931               {
932                  data = (0x41 << 24) | (1 << 20) | (2 << 16) | (0x920 << 4) | (0 << 0); // ARM920T (S3C24xx)
933               }
934               else if (device->type() == ARM7500)
935               {
936                  data = (0x41 << 24) | (0 << 20) | (1 << 16) | (0x710 << 4) | (0 << 0); // ARM7500
937               }
938               else
939               {
940                  data = 0x41 | (1 << 23) | (7 << 12); // <-- where did this come from?
941               }
942            }
943            break;
944
945         case 5: // ARM9/10/XScale
946            data = 0x41 | (9 << 12);
947            if (arm->archFlags & eARM_ARCHFLAGS_T)
948            {
949               if (arm->archFlags & eARM_ARCHFLAGS_E)
950               {
951                  if (arm->archFlags & eARM_ARCHFLAGS_J)
952                  {
953                     data |= (6<<16);    // v5TEJ
954                  }
955                  else
956                  {
957                     data |= (5<<16);    // v5TE
958                  }
959               }
960               else
961               {
962                  data |= (4<<16);    // v5T
963               }
964            }
965            break;
966
967         case 6: // ARM11
968            data = 0x41 | (10<< 12) | (7<<16);  // v6
969            break;
970         }
971         break;
972         case 1: // cache type
973         data = 0x0f0d2112;  // HACK: value expected by ARMWrestler (probably Nintendo DS ARM9's value)
974         //data = (6 << 25) | (1 << 24) | (0x172 << 12) | (0x172 << 0); // ARM920T (S3C24xx)
975         break;
976      case 2: // TCM type
977         data = 0;
978         break;
979      case 3: // TLB type
980         data = 0;
981         break;
982      case 4: // MPU type
983         data = 0;
984         break;
985      }
986         LOG( ( "arm7_rt_r_callback, ID\n" ) );
987         break;
988      case 1:             // Control
989         data = COPRO_CTRL | 0x70;   // bits 4-6 always read back as "1" (bit 3 too in XScale)
990         break;
991      case 2:             // Translation Table Base
992         data = COPRO_TLB_BASE;
993         break;
994      case 3:             // Domain Access Control
995         LOG( ( "arm7_rt_r_callback, Domain Access Control\n" ) );
996         data = COPRO_DOMAIN_ACCESS_CONTROL;
997         break;
998      case 5:             // Fault Status
999         LOG( ( "arm7_rt_r_callback, Fault Status\n" ) );
1000         switch (op3)
1001         {
1002            case 0: data = COPRO_FAULT_STATUS_D; break;
1003            case 1: data = COPRO_FAULT_STATUS_P; break;
1004         }
1005         break;
1006      case 6:             // Fault Address
1007         LOG( ( "arm7_rt_r_callback, Fault Address\n" ) );
1008         data = COPRO_FAULT_ADDRESS;
1009         break;
1010      case 13:            // Read Process ID (PID)
1011         LOG( ( "arm7_rt_r_callback, Read PID\n" ) );
1012         data = COPRO_FCSE_PID;
1013         break;
1014      case 14:            // Read Breakpoint
1015         LOG( ( "arm7_rt_r_callback, Read Breakpoint\n" ) );
1016         break;
1017      case 15:            // Test, Clock, Idle
1018         LOG( ( "arm7_rt_r_callback, Test / Clock / Idle \n" ) );
1019         break;
1020   }
1021
1022   return data;
1023}
1024
1025static WRITE32_DEVICE_HANDLER( arm7_rt_w_callback )
1026{
1027   arm_state *arm = get_safe_token(device);
1028   UINT32 opcode = offset;
1029   UINT8 cReg = ( opcode & INSN_COPRO_CREG ) >> INSN_COPRO_CREG_SHIFT;
1030   UINT8 op2 =  ( opcode & INSN_COPRO_OP2 )  >> INSN_COPRO_OP2_SHIFT;
1031   UINT8 op3 =    opcode & INSN_COPRO_OP3;
1032   UINT8 cpnum = (opcode & INSN_COPRO_CPNUM) >> INSN_COPRO_CPNUM_SHIFT;
1033
1034   // handle XScale specific CP14 - just eat writes for now
1035   if (cpnum != 15)
1036   {
1037      if (cpnum == 14)
1038      {
1039         LOG( ("arm7_rt_w_callback: write %x to XScale CP14 reg %d\n", data, cReg) );
1040         return;
1041      }
1042      else
1043      {
1044         LOG( ("ARM7: Unhandled coprocessor %d\n", cpnum) );
1045         arm->pendingUnd = 1;
1046         return;
1047      }
1048   }
1049
1050   switch( cReg )
1051   {
1052      case 0:
1053      case 4:
1054      case 10:
1055      case 11:
1056      case 12:
1057         // RESERVED
1058         LOG( ( "arm7_rt_w_callback CR%d, RESERVED = %08x\n", cReg, data) );
1059         break;
1060      case 1:             // Control
1061         LOG( ( "arm7_rt_w_callback Control = %08x (%d) (%d)\n", data, op2, op3 ) );
1062         LOG( ( "    MMU:%d, Address Fault:%d, Data Cache:%d, Write Buffer:%d\n",
1063               data & COPRO_CTRL_MMU_EN, ( data & COPRO_CTRL_ADDRFAULT_EN ) >> COPRO_CTRL_ADDRFAULT_EN_SHIFT,
1064               ( data & COPRO_CTRL_DCACHE_EN ) >> COPRO_CTRL_DCACHE_EN_SHIFT,
1065               ( data & COPRO_CTRL_WRITEBUF_EN ) >> COPRO_CTRL_WRITEBUF_EN_SHIFT ) );
1066         LOG( ( "    Endianness:%d, System:%d, ROM:%d, Instruction Cache:%d\n",
1067               ( data & COPRO_CTRL_ENDIAN ) >> COPRO_CTRL_ENDIAN_SHIFT,
1068               ( data & COPRO_CTRL_SYSTEM ) >> COPRO_CTRL_SYSTEM_SHIFT,
1069               ( data & COPRO_CTRL_ROM ) >> COPRO_CTRL_ROM_SHIFT,
1070               ( data & COPRO_CTRL_ICACHE_EN ) >> COPRO_CTRL_ICACHE_EN_SHIFT ) );
1071         LOG( ( "    Int Vector Adjust:%d\n", ( data & COPRO_CTRL_INTVEC_ADJUST ) >> COPRO_CTRL_INTVEC_ADJUST_SHIFT ) );
1072#if ARM7_MMU_ENABLE_HACK
1073         if (((data & COPRO_CTRL_MMU_EN) != 0) && ((COPRO_CTRL & COPRO_CTRL_MMU_EN) == 0))
1074         {
1075            arm->mmu_enable_addr = R15;
1076         }
1077         if (((data & COPRO_CTRL_MMU_EN) == 0) && ((COPRO_CTRL & COPRO_CTRL_MMU_EN) != 0))
1078         {
1079            if (!arm7_tlb_translate( arm, &R15, 0))
1080            {
1081               fatalerror("ARM7_MMU_ENABLE_HACK translate failed\n");
1082            }
1083         }
1084#endif
1085         COPRO_CTRL = data & COPRO_CTRL_MASK;
1086         break;
1087      case 2:             // Translation Table Base
1088         LOG( ( "arm7_rt_w_callback TLB Base = %08x (%d) (%d)\n", data, op2, op3 ) );
1089         COPRO_TLB_BASE = data;
1090         break;
1091      case 3:             // Domain Access Control
1092         LOG( ( "arm7_rt_w_callback Domain Access Control = %08x (%d) (%d)\n", data, op2, op3 ) );
1093         COPRO_DOMAIN_ACCESS_CONTROL = data;
1094         break;
1095      case 5:             // Fault Status
1096         LOG( ( "arm7_rt_w_callback Fault Status = %08x (%d) (%d)\n", data, op2, op3 ) );
1097         switch (op3)
1098         {
1099            case 0: COPRO_FAULT_STATUS_D = data; break;
1100            case 1: COPRO_FAULT_STATUS_P = data; break;
1101         }
1102         break;
1103      case 6:             // Fault Address
1104         LOG( ( "arm7_rt_w_callback Fault Address = %08x (%d) (%d)\n", data, op2, op3 ) );
1105         COPRO_FAULT_ADDRESS = data;
1106         break;
1107      case 7:             // Cache Operations
1108//            LOG( ( "arm7_rt_w_callback Cache Ops = %08x (%d) (%d)\n", data, op2, op3 ) );
1109         break;
1110      case 8:             // TLB Operations
1111         LOG( ( "arm7_rt_w_callback TLB Ops = %08x (%d) (%d)\n", data, op2, op3 ) );
1112         break;
1113      case 9:             // Read Buffer Operations
1114         LOG( ( "arm7_rt_w_callback Read Buffer Ops = %08x (%d) (%d)\n", data, op2, op3 ) );
1115         break;
1116      case 13:            // Write Process ID (PID)
1117         LOG( ( "arm7_rt_w_callback Write PID = %08x (%d) (%d)\n", data, op2, op3 ) );
1118         COPRO_FCSE_PID = data;
1119         break;
1120      case 14:            // Write Breakpoint
1121         LOG( ( "arm7_rt_w_callback Write Breakpoint = %08x (%d) (%d)\n", data, op2, op3 ) );
1122         break;
1123      case 15:            // Test, Clock, Idle
1124         LOG( ( "arm7_rt_w_callback Test / Clock / Idle = %08x (%d) (%d)\n", data, op2, op3 ) );
1125         break;
1126   }
1127}
1128
1129void arm7_dt_r_callback(arm_state *arm, UINT32 insn, UINT32 *prn, UINT32 (*read32)(arm_state *arm, UINT32 addr))
1130{
1131   UINT8 cpn = (insn >> 8) & 0xF;
1132   if ((arm->archFlags & eARM_ARCHFLAGS_XSCALE) && (cpn == 0))
1133   {
1134      LOG( ( "arm7_dt_r_callback: DSP Coprocessor 0 (CP0) not yet emulated (PC %08x)\n", GET_PC ) );
1135   }
1136   else
1137   {
1138      arm->pendingUnd = 1;
1139   }
1140}
1141
1142void arm7_dt_w_callback(arm_state *arm, UINT32 insn, UINT32 *prn, void (*write32)(arm_state *arm, UINT32 addr, UINT32 data))
1143{
1144   UINT8 cpn = (insn >> 8) & 0xF;
1145   if ((arm->archFlags & eARM_ARCHFLAGS_XSCALE) && (cpn == 0))
1146   {
1147      LOG( ( "arm7_dt_w_callback: DSP Coprocessor 0 (CP0) not yet emulated (PC %08x)\n", GET_PC ) );
1148   }
1149   else
1150   {
1151      arm->pendingUnd = 1;
1152   }
1153}
1154
1155
1156/*-------------------------------------------------
1157    arm7drc_set_options - configure DRC options
1158-------------------------------------------------*/
1159
1160void arm7drc_set_options(device_t *device, UINT32 options)
1161{
1162   arm_state *arm = get_safe_token(device);
1163   arm->impstate->drcoptions = options;
1164}
1165
1166
1167/*-------------------------------------------------
1168    arm7drc_add_fastram - add a new fastram
1169    region
1170-------------------------------------------------*/
1171
1172void arm7drc_add_fastram(device_t *device, offs_t start, offs_t end, UINT8 readonly, void *base)
1173{
1174   arm_state *arm = get_safe_token(device);
1175   if (arm->impstate->fastram_select < ARRAY_LENGTH(arm->impstate->fastram))
1176   {
1177      arm->impstate->fastram[arm->impstate->fastram_select].start = start;
1178      arm->impstate->fastram[arm->impstate->fastram_select].end = end;
1179      arm->impstate->fastram[arm->impstate->fastram_select].readonly = readonly;
1180      arm->impstate->fastram[arm->impstate->fastram_select].base = base;
1181      arm->impstate->fastram_select++;
1182   }
1183}
1184
1185
1186/*-------------------------------------------------
1187    arm7drc_add_hotspot - add a new hotspot
1188-------------------------------------------------*/
1189
1190void arm7drc_add_hotspot(device_t *device, offs_t pc, UINT32 opcode, UINT32 cycles)
1191{
1192   arm_state *arm = get_safe_token(device);
1193   if (arm->impstate->hotspot_select < ARRAY_LENGTH(arm->impstate->hotspot))
1194   {
1195      arm->impstate->hotspot[arm->impstate->hotspot_select].pc = pc;
1196      arm->impstate->hotspot[arm->impstate->hotspot_select].opcode = opcode;
1197      arm->impstate->hotspot[arm->impstate->hotspot_select].cycles = cycles;
1198      arm->impstate->hotspot_select++;
1199   }
1200}
1201
1202
1203
1204/***************************************************************************
1205    CACHE MANAGEMENT
1206***************************************************************************/
1207
1208/*-------------------------------------------------
1209    code_flush_cache - flush the cache and
1210    regenerate static code
1211-------------------------------------------------*/
1212
1213static void code_flush_cache(arm_state *arm)
1214{
1215   int mode;
1216
1217   /* empty the transient cache contents */
1218   arm->impstate->drcuml->reset();
1219
1220   try
1221   {
1222      /* generate the entry point and out-of-cycles handlers */
1223      static_generate_entry_point(arm);
1224      static_generate_nocode_handler(arm);
1225      static_generate_out_of_cycles(arm);
1226      static_generate_tlb_translate(arm);
1227      //static_generate_tlb_mismatch(arm);
1228
1229      /* append exception handlers for various types */
1230      /*static_generate_exception(mips3, EXCEPTION_INTERRUPT,     TRUE,  "exception_interrupt");
1231      static_generate_exception(mips3, EXCEPTION_INTERRUPT,     FALSE, "exception_interrupt_norecover");
1232      static_generate_exception(mips3, EXCEPTION_TLBMOD,        TRUE,  "exception_tlbmod");
1233      static_generate_exception(mips3, EXCEPTION_TLBLOAD,       TRUE,  "exception_tlbload");
1234      static_generate_exception(mips3, EXCEPTION_TLBSTORE,      TRUE,  "exception_tlbstore");
1235      static_generate_exception(mips3, EXCEPTION_TLBLOAD_FILL,  TRUE,  "exception_tlbload_fill");
1236      static_generate_exception(mips3, EXCEPTION_TLBSTORE_FILL, TRUE,  "exception_tlbstore_fill");
1237      static_generate_exception(mips3, EXCEPTION_ADDRLOAD,      TRUE,  "exception_addrload");
1238      static_generate_exception(mips3, EXCEPTION_ADDRSTORE,     TRUE,  "exception_addrstore");
1239      static_generate_exception(mips3, EXCEPTION_SYSCALL,       TRUE,  "exception_syscall");
1240      static_generate_exception(mips3, EXCEPTION_BREAK,         TRUE,  "exception_break");
1241      static_generate_exception(mips3, EXCEPTION_INVALIDOP,     TRUE,  "exception_invalidop");
1242      static_generate_exception(mips3, EXCEPTION_BADCOP,        TRUE,  "exception_badcop");
1243      static_generate_exception(mips3, EXCEPTION_OVERFLOW,      TRUE,  "exception_overflow");
1244      static_generate_exception(mips3, EXCEPTION_TRAP,          TRUE,  "exception_trap");*/
1245
1246      /* add subroutines for memory accesses */
1247      //for (mode = 0; mode < 3; mode++)
1248      //{
1249         static_generate_memory_accessor(mips3, mode, 1, FALSE, FALSE, "read8",       &mips3->impstate->read8[mode]);
1250         static_generate_memory_accessor(mips3, mode, 1, TRUE,  FALSE, "write8",      &mips3->impstate->write8[mode]);
1251         static_generate_memory_accessor(mips3, mode, 2, FALSE, FALSE, "read16",      &mips3->impstate->read16[mode]);
1252         static_generate_memory_accessor(mips3, mode, 2, TRUE,  FALSE, "write16",     &mips3->impstate->write16[mode]);
1253         static_generate_memory_accessor(mips3, mode, 4, FALSE, FALSE, "read32",      &mips3->impstate->read32[mode]);
1254         static_generate_memory_accessor(mips3, mode, 4, FALSE, TRUE,  "read32mask",  &mips3->impstate->read32mask[mode]);
1255         static_generate_memory_accessor(mips3, mode, 4, TRUE,  FALSE, "write32",     &mips3->impstate->write32[mode]);
1256         static_generate_memory_accessor(mips3, mode, 4, TRUE,  TRUE,  "write32mask", &mips3->impstate->write32mask[mode]);
1257         static_generate_memory_accessor(mips3, mode, 8, FALSE, FALSE, "read64",      &mips3->impstate->read64[mode]);
1258         static_generate_memory_accessor(mips3, mode, 8, FALSE, TRUE,  "read64mask",  &mips3->impstate->read64mask[mode]);
1259         static_generate_memory_accessor(mips3, mode, 8, TRUE,  FALSE, "write64",     &mips3->impstate->write64[mode]);
1260         static_generate_memory_accessor(mips3, mode, 8, TRUE,  TRUE,  "write64mask", &mips3->impstate->write64mask[mode]);
1261      //}
1262   }
1263   catch (drcuml_block::abort_compilation &)
1264   {
1265      fatalerror("Unrecoverable error generating static code\n");
1266   }
1267}
1268
1269
1270/*-------------------------------------------------
1271    code_compile_block - compile a block of the
1272    given mode at the specified pc
1273-------------------------------------------------*/
1274
1275static void code_compile_block(arm_state *arm, UINT8 mode, offs_t pc)
1276{
1277   drcuml_state *drcuml = arm->impstate->drcuml;
1278   compiler_state compiler = { 0 };
1279   const opcode_desc *seqlast;
1280   int override = FALSE;
1281
1282   g_profiler.start(PROFILER_DRC_COMPILE);
1283
1284   /* get a description of this sequence */
1285   const opcode_desc *desclist = arm->impstate->drcfe->describe_code(pc);
1286   if (LOG_UML || LOG_NATIVE)
1287      log_opcode_desc(drcuml, desclist, 0);
1288
1289   /* if we get an error back, flush the cache and try again */
1290   bool succeeded = false;
1291   while (!succeeded)
1292   {
1293      try
1294      {
1295         /* start the block */
1296         drcuml_block *block = drcuml->begin_block(4096);
1297
1298         /* loop until we get through all instruction sequences */
1299         for (const opcode_desc *seqhead = desclist; seqhead != NULL; seqhead = seqlast->next())
1300         {
1301            const opcode_desc *curdesc;
1302            UINT32 nextpc;
1303
1304            /* add a code log entry */
1305            if (LOG_UML)
1306               block->append_comment("-------------------------");                     // comment
1307
1308            /* determine the last instruction in this sequence */
1309            for (seqlast = seqhead; seqlast != NULL; seqlast = seqlast->next())
1310               if (seqlast->flags & OPFLAG_END_SEQUENCE)
1311                  break;
1312            assert(seqlast != NULL);
1313
1314            /* if we don't have a hash for this mode/pc, or if we are overriding all, add one */
1315            if (override || !drcuml->hash_exists(mode, seqhead->pc))
1316               UML_HASH(block, mode, seqhead->pc);                                     // hash    mode,pc
1317
1318            /* if we already have a hash, and this is the first sequence, assume that we */
1319            /* are recompiling due to being out of sync and allow future overrides */
1320            else if (seqhead == desclist)
1321            {
1322               override = TRUE;
1323               UML_HASH(block, mode, seqhead->pc);                                     // hash    mode,pc
1324            }
1325
1326            /* otherwise, redispatch to that fixed PC and skip the rest of the processing */
1327            else
1328            {
1329               UML_LABEL(block, seqhead->pc | 0x80000000);                             // label   seqhead->pc | 0x80000000
1330               UML_HASHJMP(block, 0, seqhead->pc, *arm->impstate->nocode);
1331                                                                     // hashjmp <mode>,seqhead->pc,nocode
1332               continue;
1333            }
1334
1335            /* validate this code block if we're not pointing into ROM */
1336            if (arm->program->get_write_ptr(seqhead->physpc) != NULL)
1337               generate_checksum_block(arm, block, &compiler, seqhead, seqlast);
1338
1339            /* label this instruction, if it may be jumped to locally */
1340            if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET)
1341               UML_LABEL(block, seqhead->pc | 0x80000000);                             // label   seqhead->pc | 0x80000000
1342
1343            /* iterate over instructions in the sequence and compile them */
1344            for (curdesc = seqhead; curdesc != seqlast->next(); curdesc = curdesc->next())
1345               generate_sequence_instruction(arm, block, &compiler, curdesc);
1346
1347            /* if we need to return to the start, do it */
1348            if (seqlast->flags & OPFLAG_RETURN_TO_START)
1349               nextpc = pc;
1350
1351            /* otherwise we just go to the next instruction */
1352            else
1353               nextpc = seqlast->pc + (seqlast->skipslots + 1) * 4;
1354
1355            /* count off cycles and go there */
1356            generate_update_cycles(arm, block, &compiler, nextpc, TRUE);          // <subtract cycles>
1357
1358            /* if the last instruction can change modes, use a variable mode; otherwise, assume the same mode */
1359            /*if (seqlast->flags & OPFLAG_CAN_CHANGE_MODES)
1360               UML_HASHJMP(block, mem(&arm->impstate->mode), nextpc, *arm->impstate->nocode);
1361                                                                     // hashjmp <mode>,nextpc,nocode
1362            else*/ if (seqlast->next() == NULL || seqlast->next()->pc != nextpc)
1363               UML_HASHJMP(block, arm->impstate->mode, nextpc, *arm->impstate->nocode);
1364                                                                     // hashjmp <mode>,nextpc,nocode
1365         }
1366
1367         /* end the sequence */
1368         block->end();
1369         g_profiler.stop();
1370         succeeded = true;
1371      }
1372      catch (drcuml_block::abort_compilation &)
1373      {
1374         code_flush_cache(arm);
1375      }
1376   }
1377}
1378
1379
1380/***************************************************************************
1381    C FUNCTION CALLBACKS
1382***************************************************************************/
1383
1384/*-------------------------------------------------
1385    cfunc_get_cycles - compute the total number
1386    of cycles executed so far
1387-------------------------------------------------*/
1388
1389static void cfunc_get_cycles(void *param)
1390{
1391   arm_state *arm = (arm_state *)param;
1392   arm->impstate->numcycles = arm->device->total_cycles();
1393}
1394
1395
1396/*-------------------------------------------------
1397    cfunc_unimplemented - handler for
1398    unimplemented opcdes
1399-------------------------------------------------*/
1400
1401static void cfunc_unimplemented(void *param)
1402{
1403   arm_state *arm = (arm_state *)param;
1404   UINT32 opcode = arm->impstate->arg0;
1405   fatalerror("PC=%08X: Unimplemented op %08X\n", arm->r[eR15], opcode);
1406}
1407
1408
1409/***************************************************************************
1410    STATIC CODEGEN
1411***************************************************************************/
1412
1413/*-------------------------------------------------
1414    static_generate_entry_point - generate a
1415    static entry point
1416-------------------------------------------------*/
1417
1418static void static_generate_entry_point(arm_state *arm)
1419{
1420   drcuml_state *drcuml = arm->impstate->drcuml;
1421   code_label nodabt;
1422   code_label nofiq;
1423   code_label noirq;
1424   code_label irq32;
1425   code_label nopabd;
1426   code_label nound;
1427   code_label swi32;
1428   code_label irqadjust;
1429   code_label done;
1430   int label = 1;
1431   drcuml_block *block;
1432
1433   block = drcuml->begin_block(110);
1434
1435   /* forward references */
1436   alloc_handle(drcuml, &arm->impstate->exception_norecover[EXCEPTION_INTERRUPT], "interrupt_norecover");
1437   alloc_handle(drcuml, &arm->impstate->nocode, "nocode");
1438
1439   alloc_handle(drcuml, &arm->impstate->entry, "entry");
1440   UML_HANDLE(block, *arm->impstate->entry);                                     // handle  entry
1441
1442   /* load fast integer registers */
1443   load_fast_iregs(arm, block);
1444
1445   /* Exception priorities:
1446
1447       Reset
1448       Data abort
1449       FIRQ
1450       IRQ
1451       Prefetch abort
1452       Undefined instruction
1453       Software Interrupt
1454   */
1455
1456   UML_ADD(block, I0, mem(&R15), 4);                           // add      i0, PC, 4  ;insn pc
1457
1458   // Data Abort
1459   UML_TEST(block, mem(&arm->pendingAbtD, 1);                     // test      pendingAbtD, 1
1460   UML_JMPc(block, COND_Z, nodabt = label++);                     // jmpz      nodabt
1461
1462   UML_ROLINS(block, mem(&GET_CPSR), eARM7_MODE_ABT, 0, MODE_FLAG)      // rolins   CPSR, eARM7_MODE_ABT, 0, MODE_FLAG
1463   UML_MOV(block, mem(&GET_REGISTER(arm, 14)), I0);               // mov      LR, i0
1464   UML_MOV(block, mem(&GET_REGISTER(arm, SPSR)), mem(&GET_CPSR));      // mov      SPSR, CPSR
1465   UML_OR(block, mem(&GET_CPSR), mem(&GET_CPSR), I_MASK);            // or      CPSR, CPSR, I_MASK
1466   UML_ROLAND(block, mem(&GET_CPSR), mem(&GET_CPSR), 0, ~T_MASK);      // roland   CPSR, CPSR, 0, ~T_MASK
1467   UML_MOV(block, mem(&R15), 0x00000010);                        // mov      PC, 0x10 (Data Abort vector address)
1468   UML_MOV(block, mem(&arm->pendingAbtD, 0);                     // mov      pendingAbtD, 0
1469   UML_JMP(block, irqadjust = label++);                        // jmp      irqadjust
1470
1471   UML_LABEL(block, nodabt);                                           // nodabt:
1472
1473   // FIQ
1474   UML_TEST(block, mem(&arm->pendingFiq, 1);                     // test      pendingFiq, 1
1475   UML_JMPc(block, COND_Z, nofiq = label++);                     // jmpz      nofiq
1476   UML_TEST(block, mem(&GET_CPSR), F_MASK);                     // test      CPSR, F_MASK
1477   UML_JMPc(block, COND_Z, nofiq);                              // jmpz      nofiq
1478
1479   UML_MOV(block, mem(&GET_REGISTER(arm, 14)), I0);               // mov      LR, i0
1480   UML_MOV(block, mem(&GET_REGISTER(arm, SPSR)), mem(&GET_CPSR));      // mov      SPSR, CPSR
1481   UML_OR(block, mem(&GET_CPSR), mem(&GET_CPSR), I_MASK | F_MASK);      // or      CPSR, CPSR, I_MASK | F_MASK
1482   UML_ROLAND(block, mem(&GET_CPSR), mem(&CPSR), 0, ~T_MASK);         // roland   CPSR, CPSR, 0, ~T_MASK
1483   UML_MOV(block, mem(&R15), 0x0000001c);                        // mov      PC, 0x1c (FIQ vector address)
1484   UML_MOV(block, mem(&arm->pendingFiq, 0);                     // mov      pendingFiq, 0
1485   UML_JMP(block, irqadjust);                                 // jmp      irqadjust
1486
1487   UML_LABEL(block, nofiq);                                 // nofiq:
1488
1489   // IRQ
1490   UML_TEST(block, mem(&arm->pendingIrq, 1);                     // test      pendingIrq, 1
1491   UML_JMPc(block, COND_Z, noirq = label++);                     // jmpz      noirq
1492   UML_TEST(block, mem(&GET_CPSR), I_MASK);                     // test      CPSR, I_MASK
1493   UML_JMPc(block, COND_Z, noirq);                              // jmpz      noirq
1494
1495   UML_MOV(block, mem(&GET_REGISTER(arm, 14)), I0);               // mov      LR, i0
1496   UML_TEST(block, mem(&GET_CPSR), SR_MODE32);                     // test      CPSR, MODE32
1497   UML_JMPc(block, COND_NZ, irq32 = label++);                     // jmpnz   irq32
1498   UML_AND(block, I1, I0, 0xf4000000);                           // and      i1, i0, 0xf4000000
1499   UML_OR(block, mem(&R15), I1, 0x0800001a);                     // or      PC, i1, 0x0800001a
1500   UML_AND(block, I1, mem(&GET_CPSR), 0x0fffff3f);                  // and      i1, CPSR, 0x0fffff3f
1501   UML_ROLAND(block, I0, mem(&R15), 32-20, 0x0000000c);            // roland   i0, R15, 32-20, 0x0000000c
1502   UML_ROLINS(block, I0, mem(&R15), 0, 0xf0000000);               // rolins   i0, R15, 0, 0xf0000000
1503   UML_OR(block, mem(&GET_CPSR), I0, I1);                        // or      CPSR, i0, i1
1504   UML_JMP(block, irqadjust);                                 // jmp      irqadjust
1505
1506   UML_LABEL(block, irq32);                                 // irq32:
1507   UML_MOV(block, mem(&GET_REGISTER(arm, SPSR)), mem(&GET_CPSR));      // mov      SPSR, CPSR
1508   UML_OR(block, mem(&GET_CPSR), mem(&GET_CPSR), I_MASK);            // or      CPSR, CPSR, I_MASK
1509   UML_ROLAND(block, mem(&GET_CPSR), mem(&CPSR), 0, ~T_MASK);         // roland   CPSR, CPSR, 0, ~T_MASK
1510   UML_MOV(block, mem(&R15), 0x00000018);                        // mov      PC, 0x18 (IRQ vector address)
1511
1512   UML_JMP(block, irqadjust);                                 // jmp      irqadjust
1513
1514   UML_LABEL(block, noirq);                                 // noirq:
1515
1516   // Prefetch Abort
1517   UML_TEST(block, mem(&arm->pendingAbtP, 1);                     // test      pendingAbtP, 1
1518   UML_JMPc(block, COND_Z, nopabt = label++);                     // jmpz      nopabt
1519
1520   UML_ROLINS(block, mem(&GET_CPSR), eARM7_MODE_ABT, 0, MODE_FLAG)      // rolins   CPSR, eARM7_MODE_ABT, 0, MODE_FLAG
1521   UML_MOV(block, mem(&GET_REGISTER(arm, 14)), I0);               // mov      LR, i0
1522   UML_MOV(block, mem(&GET_REGISTER(arm, SPSR)), mem(&GET_CPSR));      // mov      SPSR, CPSR
1523   UML_OR(block, mem(&GET_CPSR), mem(&GET_CPSR), I_MASK);            // or      CPSR, CPSR, I_MASK
1524   UML_ROLAND(block, mem(&GET_CPSR), mem(&CPSR), 0, ~T_MASK);         // roland   CPSR, CPSR, 0, ~T_MASK
1525   UML_MOV(block, mem(&R15), 0x0000000c);                        // mov      PC, 0x0c (Prefetch Abort vector address)
1526   UML_MOV(block, mem(&arm->pendingAbtP, 0);                     // mov      pendingAbtP, 0
1527   UML_JMP(block, irqadjust);                                 // jmp      irqadjust
1528
1529   UML_LABEL(block, nopabt);                                           // nopabt:
1530
1531   // Undefined instruction
1532   UML_TEST(block, mem(&arm->pendingUnd, 1);                     // test      pendingUnd, 1
1533   UML_JMPc(block, COND_Z, nopabt = label++);                     // jmpz      nound
1534
1535   UML_ROLINS(block, mem(&GET_CPSR), eARM7_MODE_UND, 0, MODE_FLAG)      // rolins   CPSR, eARM7_MODE_UND, 0, MODE_FLAG
1536   UML_MOV(block, I1, -4);                                    // mov      i1, -4
1537   UML_TEST(block, mem(&GET_CPSR), T_MASK);                     // test      CPSR, T_MASK
1538   UML_MOVc(block, COND_NZ, I1, -2);                           // movnz   i1, -2
1539   UML_ADD(block, mem(&GET_REGISTER(arm, 14)), I0, I1);            // add      LR, i0, i1
1540   UML_MOV(block, mem(&GET_REGISTER(arm, SPSR)), mem(&GET_CPSR));      // mov      SPSR, CPSR
1541   UML_OR(block, mem(&GET_CPSR), mem(&GET_CPSR), I_MASK);            // or      CPSR, CPSR, I_MASK
1542   UML_ROLAND(block, mem(&GET_CPSR), mem(&CPSR), 0, ~T_MASK);         // roland   CPSR, CPSR, 0, ~T_MASK
1543   UML_MOV(block, mem(&R15), 0x00000004);                        // mov      PC, 0x0c (Undefined Insn vector address)
1544   UML_MOV(block, mem(&arm->pendingUnd, 0);                     // mov      pendingUnd, 0
1545   UML_JMP(block, irqadjust);                                 // jmp      irqadjust
1546
1547   UML_LABEL(block, nound);                                              // nound:
1548
1549   // Software Interrupt
1550   UML_TEST(block, mem(&arm->pendingSwi, 1);                     // test      pendingSwi, 1
1551   UML_JMPc(block, COND_Z, done = label++);                     // jmpz      done
1552
1553   UML_ROLINS(block, mem(&GET_CPSR), eARM7_MODE_SVC, 0, MODE_FLAG)      // rolins   CPSR, eARM7_MODE_SVC, 0, MODE_FLAG
1554   UML_MOV(block, I1, -4);                                    // mov      i1, -4
1555   UML_TEST(block, mem(&GET_CPSR), T_MASK);                     // test      CPSR, T_MASK
1556   UML_MOVc(block, COND_NZ, I1, -2);                           // movnz   i1, -2
1557   UML_ADD(block, mem(&GET_REGISTER(arm, 14)), I0, I1);            // add      LR, i0, i1
1558
1559   UML_TEST(block, mem(&GET_CPSR), SR_MODE32);                     // test      CPSR, MODE32
1560   UML_JMPc(block, COND_NZ, swi32 = label++);                     // jmpnz   swi32
1561   UML_AND(block, I1, I0, 0xf4000000);                           // and      i1, i0, 0xf4000000
1562   UML_OR(block, mem(&R15), I1, 0x0800001b);                     // or      PC, i1, 0x0800001b
1563   UML_AND(block, I1, mem(&GET_CPSR), 0x0fffff3f);                  // and      i1, CPSR, 0x0fffff3f
1564   UML_ROLAND(block, I0, mem(&R15), 32-20, 0x0000000c);            // roland   i0, R15, 32-20, 0x0000000c
1565   UML_ROLINS(block, I0, mem(&R15), 0, 0xf0000000);               // rolins   i0, R15, 0, 0xf0000000
1566   UML_OR(block, mem(&GET_CPSR), I0, I1);                        // or      CPSR, i0, i1
1567   UML_MOV(block, mem(&arm->pendingSwi, 0);                     // mov      pendingSwi, 0
1568   UML_JMP(block, irqadjust);                                 // jmp      irqadjust
1569
1570   UML_LABEL(block, swi32);                                 // irq32:
1571   UML_MOV(block, mem(&GET_REGISTER(arm, SPSR)), mem(&GET_CPSR));      // mov      SPSR, CPSR
1572   UML_OR(block, mem(&GET_CPSR), mem(&GET_CPSR), I_MASK);            // or      CPSR, CPSR, I_MASK
1573   UML_ROLAND(block, mem(&GET_CPSR), mem(&CPSR), 0, ~T_MASK);         // roland   CPSR, CPSR, 0, ~T_MASK
1574   UML_MOV(block, mem(&R15), 0x00000008);                        // mov      PC, 0x08 (SWI vector address)
1575   UML_MOV(block, mem(&arm->pendingSwi, 0);                     // mov      pendingSwi, 0
1576   UML_JMP(block, irqadjust);                                 // jmp      irqadjust
1577
1578   UML_LABEL(block, irqadjust);                              // irqadjust:
1579   UML_MOV(block, I1, 0);                                    // mov      i1, 0
1580   UML_TEST(block, mem(&COPRO_CTRL), COPRO_CTRL_MMU_EN | COPRO_CTRL_INTVEC_ADJUST);   // test   COPRO_CTRL, MMU_EN | INTVEC_ADJUST
1581   UML_MOVc(block, COND_NZ, I1, 0xffff0000);                     // movnz   i1, 0xffff0000
1582   UML_OR(block, mem(&R15), mem(R15), I1);                        // or      PC, i1
1583
1584   UML_LABEL(block, done);                                    // done:
1585
1586   /* generate a hash jump via the current mode and PC */
1587   UML_HASHJMP(block, mem(&arm->impstate->mode), mem(&arm->pc), *arm->impstate->nocode);
1588                                                      // hashjmp <mode>,<pc>,nocode
1589   block->end();
1590}
1591
1592
1593/*-------------------------------------------------
1594    static_generate_nocode_handler - generate an
1595    exception handler for "out of code"
1596-------------------------------------------------*/
1597
1598static void static_generate_nocode_handler(arm_state *arm)
1599{
1600   drcuml_state *drcuml = arm->impstate->drcuml;
1601   drcuml_block *block;
1602
1603   /* begin generating */
1604   block = drcuml->begin_block(10);
1605
1606   /* generate a hash jump via the current mode and PC */
1607   alloc_handle(drcuml, &arm->impstate->nocode, "nocode");
1608   UML_HANDLE(block, *arm->impstate->nocode);                                  // handle  nocode
1609   UML_GETEXP(block, I0);                                                      // getexp  i0
1610   UML_MOV(block, mem(&R15), I0);                                              // mov     [pc],i0
1611   save_fast_iregs(arm, block);
1612   UML_EXIT(block, EXECUTE_MISSING_CODE);                                      // exit    EXECUTE_MISSING_CODE
1613
1614   block->end();
1615}
1616
1617
1618/*-------------------------------------------------
1619    static_generate_out_of_cycles - generate an
1620    out of cycles exception handler
1621-------------------------------------------------*/
1622
1623static void static_generate_out_of_cycles(arm_state *arm)
1624{
1625   drcuml_state *drcuml = arm->impstate->drcuml;
1626   drcuml_block *block;
1627
1628   /* begin generating */
1629   block = drcuml->begin_block(10);
1630
1631   /* generate a hash jump via the current mode and PC */
1632   alloc_handle(drcuml, &arm->impstate->out_of_cycles, "out_of_cycles");
1633   UML_HANDLE(block, *arm->impstate->out_of_cycles);                         // handle  out_of_cycles
1634   UML_GETEXP(block, I0);                                                  // getexp  i0
1635   UML_MOV(block, mem(&R15), I0);                                          // mov     <pc>,i0
1636   save_fast_iregs(arm, block);
1637   UML_EXIT(block, EXECUTE_OUT_OF_CYCLES);                                 // exit    EXECUTE_OUT_OF_CYCLES
1638
1639   block->end();
1640}
1641
1642
1643/*------------------------------------------------------------------
1644    static_generate_tlb_translate
1645------------------------------------------------------------------*/
1646
1647static void static_generate_detect_fault(arm_state *arm, code_handle **handleptr)
1648{
1649   /* on entry, flags are in I2, vaddr is in I3, desc_lvl1 is in I4, ap is in R5 */
1650   /* on exit, fault result is in I6 */
1651   drcuml_state *drcuml = arm->impstate->drcuml;
1652   drcuml_block *block;
1653   int donefault = 0;
1654   int checkuser = 0;
1655   int label = 1;
1656
1657   /* begin generating */
1658   block = drcuml->begin_block(1024);
1659
1660   /* add a global entry for this */
1661   alloc_handle(drcuml, handleptr, name);
1662   UML_HANDLE(block, **handleptr);                           // handle   *handleptr
1663
1664   UML_ROLAND(block, I6, I4, 32-4, 0x0f<<1);                  // roland   i6, i4, 32-4, 0xf<<1
1665   UML_ROLAND(block, I6, mem(&COPRO_DOMAIN_ACCESS_CONTROL), I6, 3);// roland   i6, COPRO_DOMAIN_ACCESS_CONTROL, i6, 3
1666   // if permission == 3, FAULT_NONE
1667   UML_CMP(block, I6, 3);                                 // cmp      i6, 3
1668   UML_MOVc(block, COND_E, I6, FAULT_NONE);                  // move      i6, FAULT_NONE
1669   UML_JMPc(block, COND_E, donefault = label++);               // jmpe      donefault
1670   // if permission == 0 || permission == 2, FAULT_DOMAIN
1671   UML_CMP(block, I6, 1);                                 // cmp      i6, 1
1672   UML_MOVc(block, COND_NE, I6, FAULT_DOMAIN);                  // movne   i6, FAULT_DOMAIN
1673   UML_JMPc(block, COND_NE, donefault);                     // jmpne   donefault
1674
1675   // if permission == 1
1676   UML_CMP(block, I5, 3);                                 // cmp      i5, 3
1677   UML_MOVc(block, COND_E, I6, FAULT_NONE);                  // move      i6, FAULT_NONE
1678   UML_JMPc(block, COND_E, donefault);                        // jmpe      donefault
1679   UML_CMP(block, I5, 0);                                 // cmp      i5, 1
1680   UML_JMPc(block, COND_NE, checkuser = label++);               // jmpne   checkuser
1681   UML_ROLAND(block, I6, mem(&COPRO_CTRL),                     // roland   i6, COPRO_CTRL, 32 - COPRO_CTRL_SYSTEM_SHIFT,
1682            32 - COPRO_CTRL_SYSTEM_SHIFT,                  //          COPRO_CTRL_SYSTEM | COPRO_CTRL_ROM
1683            COPRO_CTRL_SYSTEM | COPRO_CTRL_ROM);
1684   // if s == 0 && r == 0, FAULT_PERMISSION
1685   UML_CMP(block, I6, 0);                                 // cmp      i6, 0
1686   UML_MOVc(block, COND_E, I6, FAULT_PERMISSION);               // move      i6, FAULT_PERMISSION
1687   UML_JMPc(block, COND_E, donefault);                        // jmpe      donefault
1688   // if s == 1 && r == 1, FAULT_PERMISSION
1689   UML_CMP(block, I6, 3);                                 // cmp      i6, 3
1690   UML_MOVc(block, COND_E, I6, FAULT_PERMISSION);               // move      i6, FAULT_PERMISSION
1691   UML_JMPc(block, COND_E, donefault);                        // jmpe      donefault
1692   // if flags & TLB_WRITE, FAULT_PERMISSION
1693   UML_TEST(block, I2, ARM7_TLB_WRITE);                     // test      i2, ARM7_TLB_WRITE
1694   UML_MOVc(block, COND_NZ, I6, FAULT_PERMISSION);               // move      i6, FAULT_PERMISSION
1695   UML_JMPc(block, COND_NZ, donefault);                     // jmpe      donefault
1696   // if r == 1 && s == 0, FAULT_NONE
1697   UML_CMP(block, I6, 2);                                 // cmp      i6, 2
1698   UML_MOVc(block, COND_E, I6, FAULT_NONE);                  // move      i6, FAULT_NONE
1699   UML_JMPc(block, COND_E, donefault);                        // jmpe      donefault
1700   UML_AND(block, I6, mem(&GET_CPSR), MODE_FLAG);               // and      i6, GET_CPSR, MODE_FLAG
1701   UML_CMP(block, I6, eARM7_MODE_USER);                     // cmp      i6, eARM7_MODE_USER
1702   // if r == 0 && s == 1 && usermode, FAULT_PERMISSION
1703   UML_MOVc(block, COND_E, I6, FAULT_PERMISSION);               // move      i6, FAULT_PERMISSION
1704   UML_MOVc(block, COND_NE, I6, FAULT_NONE);                  // movne   i6, FAULT_NONE
1705   UML_JMP(block, donefault);                              // jmp      donefault
1706
1707   UML_LABEL(block, checkuser);                           // checkuser:
1708   // if !write, FAULT_NONE
1709   UML_TEST(block, I2, ARM7_TLB_WRITE);                     // test      i2, ARM7_TLB_WRITE
1710   UML_MOVc(block, COND_Z, I6, FAULT_NONE);                  // movz      i6, FAULT_NONE
1711   UML_JMPc(block, COND_Z, donefault);                        // jmp      donefault
1712   UML_AND(block, I6, mem(&GET_CPSR), MODE_FLAG);               // and      i6, GET_CPSR, MODE_FLAG
1713   UML_CMP(block, I6, eARM7_MODE_USER);                     // cmp      i6, eARM7_MODE_USER
1714   UML_MOVc(block, COND_E, I6, FAULT_PERMISSION);               // move      i6, FAULT_PERMISSION
1715   UML_MOVc(block, COND_NE, I6, FAULT_NONE);                  // move      i6, FAULT_NONE
1716
1717   UML_LABEL(block, donefault);                           // donefault:
1718   UML_RET(block);                                       // ret
1719}
1720
1721/*------------------------------------------------------------------
1722    static_generate_tlb_translate
1723------------------------------------------------------------------*/
1724
1725static void static_generate_tlb_translate(arm_state *arm, code_handle **handleptr)
1726{
1727   /* on entry, address is in I0 and flags are in I2 */
1728   /* on exit, translated address is in I0 and success/failure is in I2 */
1729   /* routine trashes I4-I7 */
1730   drcuml_state *drcuml = arm->impstate->drcuml;
1731   drcuml_block *block;
1732   int nopid = 0;
1733   int nounmapped = 0;
1734   int nounmapped2 = 0;
1735   int nocoarse = 0;
1736   int nofine = 0;
1737   int nosection = 0;
1738   int nolargepage = 0;
1739   int nosmallpage = 0;
1740   int notinypage = 0;
1741   int handlefault = 0;
1742   int level2 = 0;
1743   int prefetch = 0;
1744   int prefetch2 = 0;
1745   int label = 1;
1746
1747   /* begin generating */
1748   block = drcuml->begin_block(170);
1749
1750   /* add a global entry for this */
1751   alloc_handle(drcuml, handleptr, name);
1752   UML_HANDLE(block, **handleptr);                           // handle   *handleptr
1753
1754   // I3: vaddr
1755   UML_CMP(block, I0, 32 * 1024 * 1024);                     // cmp      i0, 32*1024*1024
1756   UML_JMPc(block, COND_GE, nopid = label++);                  // jmpge   nopid
1757   UML_AND(block, I3, mem(&COPRO_FCSE_PID), 0xfe000000);         // and      i3, COPRO_FCSE_PID, 0xfe000000
1758   UML_ADD(block, I3, I3, I0);                              // add      i3, i3, i0
1759
1760   // I4: desc_lvl1
1761   UML_AND(block, I4, mem(&COPRO_TLB_BASE), COPRO_TLB_BASE_MASK);   // and      i4, COPRO_TLB_BASE, COPRO_TLB_BASE_MASK
1762   UML_ROLINS(block, I4, I3, 32 - COPRO_TLB_VADDR_FLTI_MASK_SHIFT, // rolins   i4, i3, 32-COPRO_TLB_VADDR_FLTI_MASK_SHIFT,
1763            COPRO_TLB_VADDR_FLTI_MASK);                     //         COPRO_TLB_VADDR_FLTI_MASK
1764   UML_READ(block, I4, I4, SIZE_DWORD, SPACE_PROGRAM);            // read32   i4, i4, PROGRAM
1765
1766   // I7: desc_lvl1 & 3
1767   UML_AND(block, I7, I4, 3);                              // and      i7, i4, 3
1768
1769   UML_CMP(block, I7, COPRO_TLB_UNMAPPED);                     // cmp      i7, COPRO_TLB_UNMAPPED
1770   UML_JMPc(block, COND_NE, nounmapped = label++);               // jmpne   nounmapped
1771
1772   // TLB Unmapped
1773   UML_TEST(block, I2, ARM7_TLB_ABORT_D);                     // test      i2, ARM7_TLB_ABORT_D
1774   UML_MOVc(block, COND_E, mem(&COPRO_FAULT_STATUS_D), (5 << 0));   // move      COPRO_FAULT_STATUS_D, (5 << 0)
1775   UML_MOVc(block, COND_E, mem(&COPRO_FAULT_ADDRESS), I3);         // move      COPRO_FAULT_ADDRESS, i3
1776   UML_MOVc(block, COND_E, mem(&arm->pendingAbtD), 1);            // move      pendingAbtD, 1
1777   UML_MOVc(block, COND_E, I2, 0);                           // move      i2, 0
1778   UML_RETc(block, COND_E);                                        // rete
1779
1780   UML_TEST(block, I2, ARM7_TLB_ABORT_P);                     // test      i2, ARM7_TLB_ABORT_P
1781   UML_MOVc(block, COND_E, mem(&arm->pendingAbtP), 1);            // move      pendingAbtP, 1
1782   UML_MOV(block, I2, 0);                                 // mov      i2, 0
1783   UML_RET(block);                                                 // ret
1784
1785   UML_LABEL(block, nounmapped);                           // nounmapped:
1786   UML_CMP(block, I7, COPRO_TLB_COARSE_TABLE);                  // cmp      i7, COPRO_TLB_COARSE_TABLE
1787   UML_JMPc(block, COND_NE, nocoarse = label++);               // jmpne   nocoarse
1788
1789   UML_ROLAND(block, I5, I4, 32-4, 0x0f<<1);                  // roland   i5, i4, 32-4, 0xf<<1
1790   UML_ROLAND(block, I5, mem(&COPRO_DOMAIN_ACCESS_CONTROL), I5, 3);// roland   i5, COPRO_DOMAIN_ACCESS_CONTROL, i5, 3
1791   UML_CMP(block, I5, 1);                                 // cmp      i5, 1
1792   UML_JMPc(block, COND_E, level2 = label++);                  // jmpe      level2
1793   UML_CMP(block, I5, 3);                                 // cmp      i5, 3
1794   UML_JMPc(block, COND_NE, nofine = label++);                  // jmpne   nofine
1795   UML_LABEL(block, level2);                              // level2:
1796
1797   // I7: desc_level2
1798   UML_AND(block, I7, I4, COPRO_TLB_CFLD_ADDR_MASK);            // and      i7, i4, COPRO_TLB_CFLD_ADDR_MASK
1799   UML_ROLINS(block, I7, I3, 32 - COPRO_TLB_VADDR_CSLTI_MASK_SHIFT,// rolins   i7, i3, 32 - COPRO_TLB_VADDR_CSLTI_MASK_SHIFT
1800            COPRO_TLB_VADDR_CSLTI_MASK);                  //          COPRO_TLB_VADDR_CSLTI_MASK
1801   UML_READ(block, I7, I7, SIZE_DWORD, SPACE_PROGRAM);            // read32   i7, i7, PROGRAM
1802   UML_JMP(block, nofine);                                 // jmp      nofine
1803
1804   UML_LABEL(block, nocoarse);                              // nocoarse:
1805   UML_CMP(block, I7, COPRO_TLB_SECTION_TABLE);               // cmp      i7, COPRO_TLB_SECTION_TABLE
1806   UML_JMPc(block, COND_NE, nosection = label++);               // jmpne   nosection
1807
1808   UML_ROLAND(block, I5, I4, 32-10, 3);                     // roland   i7, i4, 32-10, 3
1809   // result in I6
1810   UML_CALLH(block, *arm->impstate->detect_fault);               // callh   detect_fault
1811   UML_CMP(block, I6, FAULT_NONE);                           // cmp       i6, FAULT_NONE
1812   UML_JMPc(block, COND_NE, handlefault = label++);            // jmpne   handlefault
1813
1814   // no fault, return translated address
1815   UML_AND(block, I0, I3, ~COPRO_TLB_SECTION_PAGE_MASK);         // and      i0, i3, ~COPRO_TLB_SECTION_PAGE_MASK
1816   UML_ROLINS(block, I0, I4, 0, COPRO_TLB_SECTION_PAGE_MASK);      // rolins   i0, i4, COPRO_TLB_SECTION_PAGE_MASK
1817   UML_MOV(block, I2, 1);                                 // mov      i2, 1
1818   UML_RET(block);                                       // ret
1819
1820   UML_LABEL(block, handlefault);                           // handlefault:
1821   UML_TEST(block, I2, ARM7_TLB_ABORT_D);                     // test      i2, ARM7_TLB_ABORT_D
1822   UML_JMPc(block, COND_Z, prefetch = label++);               // jmpz      prefetch
1823   UML_MOV(block, mem(&COPRO_FAULT_ADDRESS), I3);               // mov      COPRO_FAULT_ADDRESS, i3
1824   UML_MOV(block, mem(&arm->pendingAbtD), 1);                  // mov      arm->pendingAbtD, 1
1825   UML_ROLAND(block, I5, I4, 31, 0xf0);                     // roland   i5, i4, 31, 0xf0
1826   UML_CMP(block, I6, FAULT_DOMAIN);                        // cmp      i6, FAULT_DOMAIN
1827   UML_MOVc(block, COND_E, I6, 9 << 0);                     // move      i6, 9 << 0
1828   UML_MOVc(block, COND_NE, I6, 13 << 0);                     // movne   i6, 13 << 0
1829   UML_OR(block, mem(&COPRO_FAULT_STATUS_D), I5, I6);            // or      COPRO_FAULT_STATUS_D, i5, i6
1830   UML_MOV(block, I2, 0);                                 // mov      i2, 0
1831   UML_RET(block);                                       // ret
1832
1833   UML_LABEL(block, prefetch);                              // prefetch:
1834   UML_MOV(block, mem(&arm->pendingAbtP), 1);                  // mov      arm->pendingAbtP, 1
1835   UML_MOV(block, I2, 0);                                 // mov      i2, 0
1836   UML_RET(block);                                       // ret
1837
1838   UML_LABEL(block, nosection);                           // nosection:
1839   UML_CMP(block, I7, COPRO_TLB_FINE_TABLE);                  // cmp      i7, COPRO_TLB_FINE_TABLE
1840   UML_JMPc(block, COND_NE, nofine);                        // jmpne   nofine
1841
1842   // Not yet implemented
1843   UML_MOV(block, I2, 1);                                 // mov      i2, 1
1844   UML_RET(block);                                       // ret
1845
1846   UML_LABEL(block, nofine);                              // nofine:
1847
1848   // I7: desc_lvl2
1849   UML_AND(block, I6, I7, 3);                              // and      i6, i7, 3
1850   UML_CMP(block, I6, COPRO_TLB_UNMAPPED);                     // cmp      i6, COPRO_TLB_UNMAPPED
1851   UML_JMPc(block, COND_NE, nounmapped2 = label++);            // jmpne   nounmapped2
1852
1853   UML_TEST(block, I2, ARM7_TLB_ABORT_D);                     // test      i2, ARM7_TLB_ABORT_D
1854   UML_JMPc(block, COND_Z, prefetch2 = label++);               // jmpz      prefetch2
1855   UML_MOV(block, mem(&COPRO_FAULT_ADDRESS), I3);               // mov      COPRO_FAULT_ADDRESS, i3
1856   UML_MOV(block, mem(&arm->pendingAbtD), 1);                  // mov      arm->pendingAbtD, 1
1857   UML_ROLAND(block, I5, I4, 31, 0xf0);                     // roland   i5, i4, 31, 0xf0
1858   UML_OR(block, I5, I5, 7 << 0);                           // or      i5, i5, 7 << 0
1859   UML_OR(block, mem(&COPRO_FAULT_STATUS_D), I5, I6);            // or      COPRO_FAULT_STATUS_D, i5, i6
1860   UML_MOV(block, I2, 0);                                 // mov      i2, 0
1861   UML_RET(block);                                       // ret
1862
1863   UML_LABEL(block, prefetch2);                           // prefetch2:
1864   UML_MOV(block, mem(&arm->pendingAbtP), 1);                  // mov      arm->pendingAbtP, 1
1865   UML_MOV(block, I2, 0);                                 // mov      i2, 0
1866   UML_RET(block);                                       // ret
1867
1868   UML_LABEL(block, nounmapped2);                           // nounmapped2:
1869   UML_CMP(block, I6, COPRO_TLB_LARGE_PAGE);                  // cmp      i6, COPRO_TLB_LARGE_PAGE
1870   UML_JMPc(block, COND_NE, nolargepage = label++);            // jmpne   nolargepage
1871
1872   UML_AND(block, I0, I3, ~COPRO_TLB_LARGE_PAGE_MASK);            // and      i0, i3, ~COPRO_TLB_LARGE_PAGE_MASK
1873   UML_ROLINS(block, I0, I7, 0, COPRO_TLB_LARGE_PAGE_MASK);      // rolins   i0, i7, 0, COPRO_TLB_LARGE_PAGE_MASK
1874   UML_MOV(block, I2, 1);                                 // mov      i2, 1
1875   UML_RET(block);                                       // ret
1876
1877   UML_LABEL(block, nolargepage);                           // nolargepage:
1878   UML_CMP(block, I6, COPRO_TLB_SMALL_PAGE);                  // cmp      i6, COPRO_TLB_SMALL_PAGE
1879   UML_JMPc(block, COND_NE, nosmallpage = label++);            // jmpne   nosmallpage
1880
1881   UML_ROLAND(block, I5, I3, 32-9, 3<<1);                     // roland   i5, i3, 32-9, 3<<1
1882   UML_ROLAND(block, I6, I7, 32-4, 0xff);                     // roland   i6, i7, 32-4, 0xff
1883   UML_SHR(block, I5, I7, I5);                              // shr      i5, i7, i5
1884   UML_AND(block, I5, I5, 3);                              // and      i5, i5, 3
1885   // result in I6
1886   UML_CALLH(block, *arm->impstate->detect_fault);               // callh   detect_fault
1887
1888   UML_CMP(block, I6, FAULT_NONE);                           // cmp      i6, FAULT_NONE
1889   UML_JMPc(block, COND_NE, smallfault = label++);               // jmpne   smallfault
1890   UML_AND(block, I0, I7, COPRO_TLB_SMALL_PAGE_MASK);            // and      i0, i7, COPRO_TLB_SMALL_PAGE_MASK
1891   UML_ROLINS(block, I0, I3, 0, ~COPRO_TLB_SMALL_PAGE_MASK);      // rolins   i0, i3, 0, ~COPRO_TLB_SMALL_PAGE_MASK
1892   UML_MOV(block, I2, 1);                                 // mov      i2, 1
1893   UML_RET(block);                                       // ret
1894
1895   UML_LABEL(block, smallfault);                           // smallfault:
1896   UML_TEST(block, I2, ARM7_TLB_ABORT_D);                     // test      i2, ARM7_TLB_ABORT_D
1897   UML_JMPc(block, COND_NZ, smallprefetch = label++);            // jmpnz   smallprefetch
1898   UML_MOV(block, mem(&COPRO_FAULT_ADDRESS), I3);               // mov      COPRO_FAULT_ADDRESS, i3
1899   UML_MOV(block, mem(&arm->pendingAbtD), 1);                  // mov      pendingAbtD, 1
1900   UML_CMP(block, I6, FAULT_DOMAIN);                        // cmp      i6, FAULT_DOMAIN
1901   UML_MOVc(block, COND_E, I5, 11 << 0);                     // move      i5, 11 << 0
1902   UML_MOVc(block, COND_NE, I5, 15 << 0);                     // movne   i5, 15 << 0
1903   UML_ROLINS(block, I5, I4, 31, 0xf0);                     // rolins   i5, i4, 31, 0xf0
1904   UML_MOV(block, mem(&COPRO_FAULT_STATUS_D), I5);               // mov      COPRO_FAULT_STATUS_D, i5
1905   UML_MOV(block, I2, 0);                                 // mov      i2, 0
1906   UML_RET(block);                                       // ret
1907
1908   UML_LABEL(block, smallprefetch);                        // smallprefetch:
1909   UML_MOV(block, mem(&arm->pendingAbtP), 1);                  // mov      pendingAbtP, 1
1910   UML_MOV(block, I2, 0);                                 // mov      i2, 0
1911   UML_RET(block);                                       // ret
1912
1913   UML_LABEL(block, nosmallpage);                           // nosmallpage:
1914   UML_CMP(block, I6, COPRO_TLB_TINY_PAGE);                  // cmp      i6, COPRO_TLB_TINY_PAGE
1915   UML_JMPc(block, COND_NE, notinypage = label++);               // jmpne   notinypage
1916
1917   UML_AND(block, I0, I3, ~COPRO_TLB_TINY_PAGE_MASK);            // and      i0, i3, ~COPRO_TLB_TINY_PAGE_MASK
1918   UML_ROLINS(block, I0, I7, 0, COPRO_TLB_TINY_PAGE_MASK);         // rolins   i0, i7, 0, COPRO_TLB_TINY_PAGE_MASK
1919   UML_MOV(block, I2, 1);                                 // mov      i2, 1
1920   UML_RET(block);                                       // ret
1921
1922   UML_LABEL(block, notinypage);                           // notinypage:
1923   UML_MOV(block, I0, I3);                                 // mov      i0, i3
1924   UML_RET(block);                                       // ret
1925
1926   block->end();
1927}
1928
1929/*------------------------------------------------------------------
1930    static_generate_memory_accessor
1931------------------------------------------------------------------*/
1932
1933static void static_generate_memory_accessor(arm_state *arm, int size, bool istlb, bool iswrite, const char *name, code_handle **handleptr)
1934{
1935   /* on entry, address is in I0; data for writes is in I1 */
1936   /* on exit, read result is in I0 */
1937   /* routine trashes I0-I3 */
1938   //code_handle &exception_tlb = *mips3->impstate->exception[iswrite ? EXCEPTION_TLBSTORE : EXCEPTION_TLBLOAD];
1939   //code_handle &exception_tlbfill = *mips3->impstate->exception[iswrite ? EXCEPTION_TLBSTORE_FILL : EXCEPTION_TLBLOAD_FILL];
1940   //code_handle &exception_addrerr = *mips3->impstate->exception[iswrite ? EXCEPTION_ADDRSTORE : EXCEPTION_ADDRLOAD];
1941   drcuml_state *drcuml = arm->impstate->drcuml;
1942   drcuml_block *block;
1943   int tlbmiss = 0;
1944   int label = 1;
1945
1946   /* begin generating */
1947   block = drcuml->begin_block(1024);
1948
1949   /* add a global entry for this */
1950   alloc_handle(drcuml, handleptr, name);
1951   UML_HANDLE(block, **handleptr);                                 // handle  *handleptr
1952
1953   if (istlb)
1954   {
1955      UML_TEST(block, mem(&COPRO_CTRL), COPRO_CTRL_MMU_EN);            // test      COPRO_CTRL, COPRO_CTRL_MMU_EN
1956      if (iswrite)
1957      {
1958         UML_MOVc(block, COND_NZ, I2, ARM7_TLB_ABORT_D | ARM7_TLB_WRITE);// movnz   i2, ARM7_TLB_ABORT_D | ARM7_TLB_WRITE
1959      }
1960      else
1961      {
1962         UML_MOVc(block, COND_NZ, I2, ARM7_TLB_ABORT_D | ARM7_TLB_READ);   // movnz   i2, ARM7_TLB_ABORT_D | ARM7_TLB_READ
1963      }
1964      UML_CALLHc(block, COND_NZ, *arm->impstate->tlb_translate);         // callhnz   tlb_translate
1965   }
1966
1967   /* general case: assume paging and perform a translation */
1968   if ((arm->device->machine().debug_flags & DEBUG_FLAG_ENABLED) == 0)
1969   {
1970      for (int ramnum = 0; ramnum < ARM7_MAX_FASTRAM; ramnum++)
1971      {
1972         if (arm->impstate->fastram[ramnum].base != NULL && (!iswrite || !arm->impstate->fastram[ramnum].readonly))
1973         {
1974            void *fastbase = (UINT8 *)arm->impstate->fastram[ramnum].base - arm->impstate->fastram[ramnum].start;
1975            UINT32 skip = label++;
1976            if (arm->impstate->fastram[ramnum].end != 0xffffffff)
1977            {
1978               UML_CMP(block, I0, arm->impstate->fastram[ramnum].end);      // cmp     i0, end
1979               UML_JMPc(block, COND_A, skip);                        // ja      skip
1980            }
1981            if (arm->impstate->fastram[ramnum].start != 0x00000000)
1982            {
1983               UML_CMP(block, I0, arm->impstate->fastram[ramnum].start);   // cmp     i0, fastram_start
1984               UML_JMPc(block, COND_B, skip);                        // jb      skip
1985            }
1986
1987            if (!iswrite)
1988            {
1989               if (size == 1)
1990               {
1991                  UML_XOR(block, I0, I0, (arm->endianess == ENDIANNESS_BIG) ? BYTE4_XOR_BE(0) : BYTE4_XOR_LE(0));
1992                                                                  // xor     i0, i0, bytexor
1993                  UML_LOAD(block, I0, fastbase, I0, SIZE_BYTE, SCALE_x1);         // load    i0, fastbase, i0, byte
1994               }
1995               else if (size == 2)
1996               {
1997                  UML_XOR(block, I0, I0, (arm->endianess == ENDIANNESS_BIG) ? WORD_XOR_BE(0) : WORD_XOR_LE(0));
1998                                                                  // xor     i0, i0, wordxor
1999                  UML_LOAD(block, I0, fastbase, I0, SIZE_WORD, SCALE_x1);         // load    i0, fastbase, i0, word_x1
2000               }
2001               else if (size == 4)
2002               {
2003                  UML_LOAD(block, I0, fastbase, I0, SIZE_DWORD, SCALE_x1);      // load    i0, fastbase, i0, dword_x1
2004               }
2005               UML_RET(block);                                          // ret
2006            }
2007            else
2008            {
2009               if (size == 1)
2010               {
2011                  UML_XOR(block, I0, I0, (arm->endianess == ENDIANNESS_BIG) ? BYTE4_XOR_BE(0) : BYTE4_XOR_LE(0));
2012                                                                  // xor     i0, i0, bytexor
2013                  UML_STORE(block, fastbase, I0, I1, SIZE_BYTE, SCALE_x1);      // store   fastbase, i0, i1, byte
2014               }
2015               else if (size == 2)
2016               {
2017                  UML_XOR(block, I0, I0, mips3->bigendian ? WORD_XOR_BE(0) : WORD_XOR_LE(0));
2018                                                                  // xor     i0, i0, wordxor
2019                  UML_STORE(block, fastbase, I0, I1, SIZE_WORD, SCALE_x1);      // store   fastbase, i0, i1, word_x1
2020               }
2021               else if (size == 4)
2022               {
2023                  UML_STORE(block, fastbase, I0, I1, SIZE_DWORD, SCALE_x1);      // store   fastbase,i0,i1,dword_x1
2024               }
2025               UML_RET(block);                                                     // ret
2026            }
2027
2028            UML_LABEL(block, skip);                                       // skip:
2029         }
2030      }
2031   }
2032
2033   switch (size)
2034   {
2035      case 1:
2036         if (iswrite)
2037         {
2038            UML_WRITE(block, I0, I1, SIZE_BYTE, SPACE_PROGRAM);               // write   i0, i1, program_byte
2039         }
2040         else
2041         {
2042            UML_READ(block, I0, I0, SIZE_BYTE, SPACE_PROGRAM);               // read    i0, i0, program_byte
2043         }
2044         break;
2045
2046      case 2:
2047         if (iswrite)
2048         {
2049            UML_WRITE(block, I0, I1, SIZE_WORD, SPACE_PROGRAM);               // write   i0,i1,program_word
2050         }
2051         else
2052         {
2053            UML_READ(block, I0, I0, SIZE_WORD, SPACE_PROGRAM);               // read    i0,i0,program_word
2054         }
2055         break;
2056
2057      case 4:
2058         if (iswrite)
2059         {
2060            UML_WRITE(block, I0, I1, SIZE_DWORD, SPACE_PROGRAM);            // write   i0,i1,program_dword
2061         }
2062         else
2063         {
2064            UML_READ(block, I0, I0, SIZE_DWORD, SPACE_PROGRAM);               // read    i0,i0,program_dword
2065         }
2066         break;
2067   }
2068   UML_RET(block);                                                                 // ret
2069
2070   block->end();
2071}
2072
2073DEFINE_LEGACY_CPU_DEVICE(ARM7, arm7);
2074DEFINE_LEGACY_CPU_DEVICE(ARM7_BE, arm7_be);
2075DEFINE_LEGACY_CPU_DEVICE(ARM7500, arm7500);
2076DEFINE_LEGACY_CPU_DEVICE(ARM9, arm9);
2077DEFINE_LEGACY_CPU_DEVICE(ARM920T, arm920t);
2078DEFINE_LEGACY_CPU_DEVICE(PXA255, pxa255);
2079DEFINE_LEGACY_CPU_DEVICE(SA1110, sa1110);
2080
2081#endif  // ARM7_USE_DRC
Property changes on: trunk/src/emu/cpu/arm7/arm7drc.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain

Previous 199869 Revisions Next


© 1997-2024 The MAME Team