r8618 Sunday 25th July, 2010 at 13:43:17 UTC by Wilbert Pol
Added a big endian version of the arm2/3/6 cpu core.
[src/emu/cpu/arm]arm.c arm.h armdasm.c

src/emu/cpu/arm/arm.c
r8617r8618
2020#include "arm.h"
2121
2222CPU_DISASSEMBLE( arm );
23CPU_DISASSEMBLE( arm_be );
2324
2425#define READ8(addr)         cpu_read8(cpustate,addr)
2526#define WRITE8(addr,data)   cpu_write8(cpustate,addr,data)
r8617r8618
254255INLINE ARM_REGS *get_safe_token(running_device *device)
255256{
256257   assert(device != NULL);
257   assert(device->type() == ARM);
258   assert(device->type() == ARM || device->type() == ARM_BE);
258259   return (ARM_REGS *)downcast<legacy_cpu_device *>(device)->token();
259260}
260261
261262INLINE void cpu_write32( ARM_REGS* cpustate, int addr, UINT32 data )
262263{
263264   /* Unaligned writes are treated as normal writes */
264   memory_write_dword_32le(cpustate->program, addr&ADDRESS_MASK,data);
265   if ( cpustate->endian == ENDIANNESS_BIG )
266      memory_write_dword_32be(cpustate->program, addr&ADDRESS_MASK,data);
267   else
268      memory_write_dword_32le(cpustate->program, addr&ADDRESS_MASK,data);
265269   if (ARM_DEBUG_CORE && addr&3) logerror("%08x: Unaligned write %08x\n",R15,addr);
266270}
267271
268272INLINE void cpu_write8( ARM_REGS* cpustate, int addr, UINT8 data )
269273{
270   memory_write_byte_32le(cpustate->program,addr,data);
274   if ( cpustate->endian == ENDIANNESS_BIG )
275      memory_write_byte_32be(cpustate->program,addr,data);
276   else
277      memory_write_byte_32le(cpustate->program,addr,data);
271278}
272279
273280INLINE UINT32 cpu_read32( ARM_REGS* cpustate, int addr )
274281{
275   UINT32 result = memory_read_dword_32le(cpustate->program,addr&ADDRESS_MASK);
282   UINT32 result;
276283
284   if ( cpustate->endian == ENDIANNESS_BIG )
285      result = memory_read_dword_32be(cpustate->program,addr&ADDRESS_MASK);
286   else
287      result = memory_read_dword_32le(cpustate->program,addr&ADDRESS_MASK);
288
277289   /* Unaligned reads rotate the word, they never combine words */
278290   if (addr&3) {
279291      if (ARM_DEBUG_CORE && addr&1)
r8617r8618
292304
293305INLINE UINT8 cpu_read8( ARM_REGS* cpustate, int addr )
294306{
295   return memory_read_byte_32le(cpustate->program, addr);
307   if ( cpustate->endian == ENDIANNESS_BIG )
308      return memory_read_byte_32be(cpustate->program, addr);
309   else
310      return memory_read_byte_32le(cpustate->program, addr);
296311}
297312
298313INLINE UINT32 GetRegister( ARM_REGS* cpustate, int rIndex )
r8617r8618
312327   ARM_REGS *cpustate = get_safe_token(device);
313328
314329   device_irq_callback save_irqcallback = cpustate->irq_callback;
330   endianness_t save_endian = cpustate->endian;
331
315332   memset(cpustate, 0, sizeof(ARM_REGS));
316333   cpustate->irq_callback = save_irqcallback;
334   cpustate->endian = save_endian;
317335   cpustate->device = device;
318336   cpustate->program = device->space(AS_PROGRAM);
319337
r8617r8618
507525   state_save_register_device_item(device, 0, cpustate->endian);
508526}
509527
528
529static CPU_INIT( arm_be )
530{
531   ARM_REGS *cpustate = get_safe_token(device);
532
533   cpustate->irq_callback = irqcallback;
534   cpustate->device = device;
535   cpustate->program = device->space(AS_PROGRAM);
536   cpustate->endian = ENDIANNESS_BIG;
537
538   state_save_register_device_item_array(device, 0, cpustate->sArmRegister);
539   state_save_register_device_item_array(device, 0, cpustate->coproRegister);
540   state_save_register_device_item(device, 0, cpustate->pendingIrq);
541   state_save_register_device_item(device, 0, cpustate->pendingFiq);
542   state_save_register_device_item(device, 0, cpustate->endian);
543}
544
545
510546/***************************************************************************/
511547
512548static void HandleBranch( ARM_REGS* cpustate, UINT32 insn )
r8617r8618
596632      {
597633         if (ARM_DEBUG_CORE && rd == eR15)
598634            logerror("read byte R15 %08x\n", R15);
599         SetRegister(cpustate, rd,(UINT32) READ8( ( cpustate->endian == ENDIANNESS_LITTLE ? rnv : (rnv ^ 0x03) ) ) );
635         SetRegister(cpustate, rd,(UINT32) READ8(rnv) );
600636      }
601637      else
602638      {
r8617r8618
619655         }
620656         else
621657         {
622            UINT32 data = READ32(rnv);
623
624            if ( cpustate->endian == ENDIANNESS_BIG )
625            {
626               if ( rnv & 0x02 )
627                  data = ( data >> 16 ) | ( data << 16 );
628               if ( rnv & 0x01 )
629                  data = ( data >> 24 ) | ( data << 8 );
630            }
631            SetRegister(cpustate, rd, data);
658            SetRegister(cpustate, rd, READ32(rnv));
632659         }
633660      }
634661   }
r8617r8618
641668         if (ARM_DEBUG_CORE && rd==eR15)
642669            logerror("Wrote R15 in byte mode\n");
643670
644         WRITE8( ( cpustate->endian == ENDIANNESS_LITTLE ? rnv : (rnv ^ 0x03) ), (UINT8) GetRegister(cpustate, rd) & 0xffu);
671         WRITE8(rnv, (UINT8) GetRegister(cpustate, rd) & 0xffu);
645672      }
646673      else
647674      {
r8617r8618
13881415}
13891416
13901417
1391void arm_set_endianness( legacy_cpu_device *device, endianness_t endianness )
1392{
1393   ARM_REGS *cpustate = get_safe_token(device);
1394
1395   cpustate->endian = endianness;
1396}
1397
13981418/**************************************************************************
13991419 * Generic set_info
14001420 **************************************************************************/
r8617r8618
15871607   }
15881608}
15891609
1610
1611CPU_GET_INFO( arm_be )
1612{
1613   switch (state)
1614   {
1615      /* --- the following bits of info are returned as 64-bit signed integers --- */
1616      case DEVINFO_INT_ENDIANNESS:               info->i = ENDIANNESS_BIG;                     break;
1617
1618      /* --- the following bits of info are returned as pointers to data or functions --- */
1619      case CPUINFO_FCT_INIT:                     info->init = CPU_INIT_NAME(arm_be);               break;
1620      case CPUINFO_FCT_DISASSEMBLE:               info->disassemble = CPU_DISASSEMBLE_NAME(arm_be);   break;
1621
1622      /* --- the following bits of info are returned as NULL-terminated strings --- */
1623        case DEVINFO_STR_NAME:                     strcpy(info->s, "ARM (big endian)");            break;
1624
1625      default:                              CPU_GET_INFO_CALL(arm);                        break;
1626   }
1627}
1628
1629
15901630DEFINE_LEGACY_CPU_DEVICE(ARM, arm);
1631DEFINE_LEGACY_CPU_DEVICE(ARM_BE, arm_be);
1632
src/emu/cpu/arm/arm.h
r8617r8618
1515 ***************************************************************************************************/
1616
1717DECLARE_LEGACY_CPU_DEVICE(ARM, arm);
18DECLARE_LEGACY_CPU_DEVICE(ARM_BE, arm_be);
1819
1920enum
2021{
r8617r8618
2526   ARM32_IR13, ARM32_IR14, ARM32_SR13, ARM32_SR14
2627};
2728
28void arm_set_endianness( legacy_cpu_device *device, endianness_t endianness );
29
3029#endif /* __ARM_H__ */
src/emu/cpu/arm/armdasm.c
r8617r8618
398398   UINT32 opcode = oprom[0] | (oprom[1] << 8) | (oprom[2] << 16) | (oprom[3] << 24);
399399   return 4 | arm_disasm(buffer, pc, opcode);
400400}
401
402CPU_DISASSEMBLE( arm_be )
403{
404   UINT32 opcode = oprom[3] | (oprom[2] << 8) | (oprom[1] << 16) | (oprom[0] << 24);
405   return 4 | arm_disasm(buffer, pc, opcode);
406}
407

Previous 509076 RevisionsNext 50


© 1998-2010 The MESS Team