Previous 199869 Revisions Next

r23978 Thursday 27th June, 2013 at 18:40:44 UTC by Wilbert Pol
arm.c: Modernized cpu core. (nw)
[src/emu/cpu/arm]arm.c arm.h

trunk/src/emu/cpu/arm/arm.h
r23977r23978
1414 *  PUBLIC FUNCTIONS
1515 ***************************************************************************************************/
1616
17DECLARE_LEGACY_CPU_DEVICE(ARM, arm);
18DECLARE_LEGACY_CPU_DEVICE(ARM_BE, arm_be);
1917
2018enum
2119{
r23977r23978
2624   ARM32_IR13, ARM32_IR14, ARM32_SR13, ARM32_SR14
2725};
2826
27
28class arm_cpu_device : public cpu_device
29{
30public:
31   // construction/destruction
32   arm_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
33   arm_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source, endianness_t endianness);
34
35protected:
36   // device-level overrides
37   virtual void device_start();
38   virtual void device_reset();
39
40   // device_execute_interface overrides
41   virtual UINT32 execute_min_cycles() const { return 3; }
42   virtual UINT32 execute_max_cycles() const { return 4; }
43   virtual UINT32 execute_input_lines() const { return 2; }
44   virtual void execute_run();
45   virtual void execute_set_input(int inputnum, int state);
46
47   // device_memory_interface overrides
48   virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const { return (spacenum == AS_PROGRAM) ? &m_program_config : NULL; }
49
50   // device_state_interface overrides
51   void state_string_export(const device_state_entry &entry, astring &string);
52
53   // device_disasm_interface overrides
54   virtual UINT32 disasm_min_opcode_bytes() const { return 4; }
55   virtual UINT32 disasm_max_opcode_bytes() const { return 4; }
56   virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
57
58   address_space_config m_program_config;
59
60   int m_icount;
61   UINT32 m_sArmRegister[27];
62   UINT32 m_coproRegister[16];
63   UINT8 m_pendingIrq;
64   UINT8 m_pendingFiq;
65   address_space *m_program;
66   direct_read_data *m_direct;
67   endianness_t m_endian;
68
69   void cpu_write32( int addr, UINT32 data );
70   void cpu_write8( int addr, UINT8 data );
71   UINT32 cpu_read32( int addr );
72   UINT8 cpu_read8( int addr );
73   UINT32 GetRegister( int rIndex );
74   void SetRegister( int rIndex, UINT32 value );
75   UINT32 GetModeRegister( int mode, int rIndex );
76   void SetModeRegister( int mode, int rIndex, UINT32 value );
77   void HandleALU(UINT32 insn);
78   void HandleMul(UINT32 insn);
79   void HandleBranch(UINT32 insn);
80   void HandleMemSingle(UINT32 insn);
81   void HandleMemBlock(UINT32 insn);
82   void HandleCoPro(UINT32 insn);
83   UINT32 decodeShift(UINT32 insn, UINT32 *pCarry);
84   void arm_check_irq_state();
85   int loadInc(UINT32 pat, UINT32 rbv, UINT32 s);
86   int loadDec(UINT32 pat, UINT32 rbv, UINT32 s, UINT32* deferredR15, int* defer);
87   int storeInc(UINT32 pat, UINT32 rbv);
88   int storeDec(UINT32 pat, UINT32 rbv);
89   static UINT32 BCDToDecimal(UINT32 value);
90   static UINT32 DecimalToBCD(UINT32 value);
91
92};
93
94
95class arm_be_cpu_device : public arm_cpu_device
96{
97public:
98    // construction/destruction
99    arm_be_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
100
101protected:
102   virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
103};
104
105
106extern const device_type ARM;
107extern const device_type ARM_BE;
108
109
29110#endif /* __ARM_H__ */
trunk/src/emu/cpu/arm/arm.c
r23977r23978
2222CPU_DISASSEMBLE( arm );
2323CPU_DISASSEMBLE( arm_be );
2424
25#define READ8(addr)         cpu_read8(cpustate,addr)
26#define WRITE8(addr,data)   cpu_write8(cpustate,addr,data)
27#define READ32(addr)        cpu_read32(cpustate,addr)
28#define WRITE32(addr,data)  cpu_write32(cpustate,addr,data)
25#define READ8(addr)         cpu_read8(addr)
26#define WRITE8(addr,data)   cpu_write8(addr,data)
27#define READ32(addr)        cpu_read32(addr)
28#define WRITE32(addr,data)  cpu_write32(addr,data)
2929
3030#define ARM_DEBUG_CORE 0
3131#define ARM_DEBUG_COPRO 0
r23977r23978
125125#define ADDRESS_MASK    ((UINT32) 0x03fffffcu)
126126#define MODE_MASK       ((UINT32) 0x00000003u)
127127
128#define R15                     cpustate->sArmRegister[eR15]
128#define R15                     m_sArmRegister[eR15]
129129#define MODE                    (R15&0x03)
130130#define SIGN_BIT                ((UINT32)(1<<31))
131131#define SIGN_BITS_DIFFER(a,b)   (((a)^(b)) >> 31)
r23977r23978
224224#define ROL(v,s) (LSL((v),(s)) | (LSR((v),32u - (s))))
225225#define ROR(v,s) (LSR((v),(s)) | (LSL((v),32u - (s))))
226226
227/* Private Data */
228227
229/* sArmRegister defines the CPU state */
230struct ARM_REGS
228/***************************************************************************/
229
230const device_type ARM = &device_creator<arm_cpu_device>;
231const device_type ARM_BE = &device_creator<arm_be_cpu_device>;
232
233
234arm_cpu_device::arm_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
235   : cpu_device(mconfig, ARM, "ARM", tag, owner, clock, "arm", __FILE__)
236   , m_program_config("program", ENDIANNESS_LITTLE, 32, 26, 0)
237   , m_endian(ENDIANNESS_LITTLE)
231238{
232   int icount;
233   UINT32 sArmRegister[kNumRegisters];
234   UINT32 coproRegister[16];
235   UINT8 pendingIrq;
236   UINT8 pendingFiq;
237   device_irq_acknowledge_callback irq_callback;
238   legacy_cpu_device *device;
239   address_space *program;
240   direct_read_data *direct;
241   endianness_t endian;
242};
239}
243240
244/* Prototypes */
245static void HandleALU( ARM_REGS* cpustate, UINT32 insn);
246static void HandleMul( ARM_REGS* cpustate, UINT32 insn);
247static void HandleBranch( ARM_REGS* cpustate, UINT32 insn);
248static void HandleMemSingle( ARM_REGS* cpustate, UINT32 insn);
249static void HandleMemBlock( ARM_REGS* cpustate, UINT32 insn);
250static void HandleCoPro( ARM_REGS* cpustate, UINT32 insn);
251static UINT32 decodeShift( ARM_REGS* cpustate, UINT32 insn, UINT32 *pCarry);
252static void arm_check_irq_state(ARM_REGS* cpustate);
253241
254/***************************************************************************/
242arm_cpu_device::arm_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source, endianness_t endianness)
243   : cpu_device(mconfig, type, name, tag, owner, clock, shortname, source)
244   , m_program_config("program", endianness, 32, 26, 0)
245   , m_endian(endianness)
246{
247}
255248
256INLINE ARM_REGS *get_safe_token(device_t *device)
249
250arm_be_cpu_device::arm_be_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
251   : arm_cpu_device(mconfig, ARM_BE, "ARM (big endian)", tag, owner, clock, "arm be", __FILE__, ENDIANNESS_BIG)
257252{
258   assert(device != NULL);
259   assert(device->type() == ARM || device->type() == ARM_BE);
260   return (ARM_REGS *)downcast<legacy_cpu_device *>(device)->token();
261253}
262254
263INLINE void cpu_write32( ARM_REGS* cpustate, int addr, UINT32 data )
255
256void arm_cpu_device::cpu_write32( int addr, UINT32 data )
264257{
265258   /* Unaligned writes are treated as normal writes */
266   if ( cpustate->endian == ENDIANNESS_BIG )
267      cpustate->program->write_dword(addr&ADDRESS_MASK,data);
259   if ( m_endian == ENDIANNESS_BIG )
260      m_program->write_dword(addr&ADDRESS_MASK,data);
268261   else
269      cpustate->program->write_dword(addr&ADDRESS_MASK,data);
262      m_program->write_dword(addr&ADDRESS_MASK,data);
270263   if (ARM_DEBUG_CORE && addr&3) logerror("%08x: Unaligned write %08x\n",R15,addr);
271264}
272265
273INLINE void cpu_write8( ARM_REGS* cpustate, int addr, UINT8 data )
266void arm_cpu_device::cpu_write8( int addr, UINT8 data )
274267{
275   if ( cpustate->endian == ENDIANNESS_BIG )
276      cpustate->program->write_byte(addr,data);
268   if ( m_endian == ENDIANNESS_BIG )
269      m_program->write_byte(addr,data);
277270   else
278      cpustate->program->write_byte(addr,data);
271      m_program->write_byte(addr,data);
279272}
280273
281INLINE UINT32 cpu_read32( ARM_REGS* cpustate, int addr )
274UINT32 arm_cpu_device::cpu_read32( int addr )
282275{
283276   UINT32 result;
284277
285   if ( cpustate->endian == ENDIANNESS_BIG )
286      result = cpustate->program->read_dword(addr&ADDRESS_MASK);
278   if ( m_endian == ENDIANNESS_BIG )
279      result = m_program->read_dword(addr&ADDRESS_MASK);
287280   else
288      result = cpustate->program->read_dword(addr&ADDRESS_MASK);
281      result = m_program->read_dword(addr&ADDRESS_MASK);
289282
290283   /* Unaligned reads rotate the word, they never combine words */
291284   if (addr&3) {
r23977r23978
303296   return result;
304297}
305298
306INLINE UINT8 cpu_read8( ARM_REGS* cpustate, int addr )
299UINT8 arm_cpu_device::cpu_read8( int addr )
307300{
308   if ( cpustate->endian == ENDIANNESS_BIG )
309      return cpustate->program->read_byte(addr);
301   if ( m_endian == ENDIANNESS_BIG )
302      return m_program->read_byte(addr);
310303   else
311      return cpustate->program->read_byte(addr);
304      return m_program->read_byte(addr);
312305}
313306
314INLINE UINT32 GetRegister( ARM_REGS* cpustate, int rIndex )
307UINT32 arm_cpu_device::GetRegister( int rIndex )
315308{
316   return cpustate->sArmRegister[sRegisterTable[MODE][rIndex]];
309   return m_sArmRegister[sRegisterTable[MODE][rIndex]];
317310}
318311
319INLINE void SetRegister( ARM_REGS* cpustate, int rIndex, UINT32 value )
312void arm_cpu_device::SetRegister( int rIndex, UINT32 value )
320313{
321   cpustate->sArmRegister[sRegisterTable[MODE][rIndex]] = value;
314   m_sArmRegister[sRegisterTable[MODE][rIndex]] = value;
322315}
323316
324INLINE UINT32 GetModeRegister( ARM_REGS* cpustate, int mode, int rIndex )
317UINT32 arm_cpu_device::GetModeRegister( int mode, int rIndex )
325318{
326   return cpustate->sArmRegister[sRegisterTable[mode][rIndex]];
319   return m_sArmRegister[sRegisterTable[mode][rIndex]];
327320}
328321
329INLINE void SetModeRegister( ARM_REGS* cpustate, int mode, int rIndex, UINT32 value )
322void arm_cpu_device::SetModeRegister( int mode, int rIndex, UINT32 value )
330323{
331   cpustate->sArmRegister[sRegisterTable[mode][rIndex]] = value;
324   m_sArmRegister[sRegisterTable[mode][rIndex]] = value;
332325}
333326
334327
335328/***************************************************************************/
336329
337static CPU_RESET( arm )
330void arm_cpu_device::device_reset()
338331{
339   ARM_REGS *cpustate = get_safe_token(device);
332   for ( int i = 0; i < 27; i++ )
333   {
334      m_sArmRegister[i] = 0;
335   }
336   for ( int i = 0; i < 16; i++ )
337   {
338      m_coproRegister[i] = 0;
339   }
340   m_pendingIrq = 0;
341   m_pendingFiq = 0;
340342
341   device_irq_acknowledge_callback save_irqcallback = cpustate->irq_callback;
342   endianness_t save_endian = cpustate->endian;
343
344   memset(cpustate, 0, sizeof(ARM_REGS));
345   cpustate->irq_callback = save_irqcallback;
346   cpustate->endian = save_endian;
347   cpustate->device = device;
348   cpustate->program = &device->space(AS_PROGRAM);
349   cpustate->direct = &cpustate->program->direct();
350
351343   /* start up in SVC mode with interrupts disabled. */
352344   R15 = eARM_MODE_SVC|I_MASK|F_MASK;
353345}
354346
355static CPU_EXIT( arm )
356{
357   /* nothing to do here */
358}
359347
360static CPU_EXECUTE( arm )
348void arm_cpu_device::execute_run()
361349{
362350   UINT32 pc;
363351   UINT32 insn;
364   ARM_REGS *cpustate = get_safe_token(device);
365352
366353   do
367354   {
368      debugger_instruction_hook(device, R15 & ADDRESS_MASK);
355      debugger_instruction_hook(this, R15 & ADDRESS_MASK);
369356
370357      /* load instruction */
371358      pc = R15;
372      insn = cpustate->direct->read_decrypted_dword( pc & ADDRESS_MASK );
359      insn = m_direct->read_decrypted_dword( pc & ADDRESS_MASK );
373360
374361      switch (insn >> INSN_COND_SHIFT)
375362      {
r23977r23978
421408      /* Condition satisfied, so decode the instruction */
422409      if ((insn & 0x0fc000f0u) == 0x00000090u)    /* Multiplication */
423410      {
424         HandleMul(cpustate, insn);
411         HandleMul(insn);
425412         R15 += 4;
426413      }
427414      else if (!(insn & 0x0c000000u)) /* Data processing */
428415      {
429         HandleALU(cpustate, insn);
416         HandleALU(insn);
430417      }
431418      else if ((insn & 0x0c000000u) == 0x04000000u) /* Single data access */
432419      {
433         HandleMemSingle(cpustate, insn);
420         HandleMemSingle(insn);
434421         R15 += 4;
435422      }
436423      else if ((insn & 0x0e000000u) == 0x08000000u ) /* Block data access */
437424      {
438         HandleMemBlock(cpustate, insn);
425         HandleMemBlock(insn);
439426         R15 += 4;
440427      }
441428      else if ((insn & 0x0e000000u) == 0x0a000000u)   /* Branch */
442429      {
443         HandleBranch(cpustate, insn);
430         HandleBranch(insn);
444431      }
445432      else if ((insn & 0x0f000000u) == 0x0e000000u)   /* Coprocessor */
446433      {
447         HandleCoPro(cpustate, insn);
434         HandleCoPro(insn);
448435         R15 += 4;
449436      }
450437      else if ((insn & 0x0f000000u) == 0x0f000000u)   /* Software interrupt */
451438      {
452439         pc=R15+4;
453440         R15 = eARM_MODE_SVC;    /* Set SVC mode so PC is saved to correct R14 bank */
454         SetRegister( cpustate, 14, pc );    /* save PC */
441         SetRegister( 14, pc );    /* save PC */
455442         R15 = (pc&PSR_MASK)|(pc&IRQ_MASK)|0x8|eARM_MODE_SVC|I_MASK|(pc&MODE_MASK);
456         cpustate->icount -= 2 * S_CYCLE + N_CYCLE;
443         m_icount -= 2 * S_CYCLE + N_CYCLE;
457444      }
458445      else /* Undefined */
459446      {
460447         logerror("%08x:  Undefined instruction\n",R15);
461448      L_Next:
462         cpustate->icount -= S_CYCLE;
449         m_icount -= S_CYCLE;
463450         R15 += 4;
464451      }
465452
466      arm_check_irq_state(cpustate);
453      arm_check_irq_state();
467454
468   } while( cpustate->icount > 0 );
455   } while( m_icount > 0 );
469456} /* arm_execute */
470457
471458
472static void arm_check_irq_state(ARM_REGS* cpustate)
459void arm_cpu_device::arm_check_irq_state()
473460{
474461   UINT32 pc = R15+4; /* save old pc (already incremented in pipeline) */;
475462
r23977r23978
483470       Undefined instruction
484471   */
485472
486   if (cpustate->pendingFiq && (pc&F_MASK)==0) {
473   if (m_pendingFiq && (pc&F_MASK)==0) {
487474      R15 = eARM_MODE_FIQ;    /* Set FIQ mode so PC is saved to correct R14 bank */
488      SetRegister( cpustate, 14, pc );    /* save PC */
475      SetRegister( 14, pc );    /* save PC */
489476      R15 = (pc&PSR_MASK)|(pc&IRQ_MASK)|0x1c|eARM_MODE_FIQ|I_MASK|F_MASK; /* Mask both IRQ & FIRQ, set PC=0x1c */
490      cpustate->pendingFiq=0;
477      m_pendingFiq=0;
491478      return;
492479   }
493480
494   if (cpustate->pendingIrq && (pc&I_MASK)==0) {
481   if (m_pendingIrq && (pc&I_MASK)==0) {
495482      R15 = eARM_MODE_IRQ;    /* Set IRQ mode so PC is saved to correct R14 bank */
496      SetRegister( cpustate, 14, pc );    /* save PC */
483      SetRegister( 14, pc );    /* save PC */
497484      R15 = (pc&PSR_MASK)|(pc&IRQ_MASK)|0x18|eARM_MODE_IRQ|I_MASK|(pc&F_MASK); /* Mask only IRQ, set PC=0x18 */
498      cpustate->pendingIrq=0;
485      m_pendingIrq=0;
499486      return;
500487   }
501488}
502489
503static void set_irq_line(ARM_REGS* cpustate, int irqline, int state)
490
491void arm_cpu_device::execute_set_input(int irqline, int state)
504492{
505493   switch (irqline) {
506494   case ARM_IRQ_LINE: /* IRQ */
507495      if (state && (R15&0x3)!=eARM_MODE_IRQ) /* Don't allow nested IRQs */
508         cpustate->pendingIrq=1;
496         m_pendingIrq=1;
509497      else
510         cpustate->pendingIrq=0;
498         m_pendingIrq=0;
511499      break;
512500
513501   case ARM_FIRQ_LINE: /* FIRQ */
514502      if (state && (R15&0x3)!=eARM_MODE_FIQ) /* Don't allow nested FIRQs */
515         cpustate->pendingFiq=1;
503         m_pendingFiq=1;
516504      else
517         cpustate->pendingFiq=0;
505         m_pendingFiq=0;
518506      break;
519507   }
520508
521   arm_check_irq_state(cpustate);
509   arm_check_irq_state();
522510}
523511
524static CPU_INIT( arm )
512
513void arm_cpu_device::device_start()
525514{
526   ARM_REGS *cpustate = get_safe_token(device);
515   m_program = &space(AS_PROGRAM);
516   m_direct = &m_program->direct();
527517
528   cpustate->irq_callback = irqcallback;
529   cpustate->device = device;
530   cpustate->program = &device->space(AS_PROGRAM);
531   cpustate->endian = ENDIANNESS_LITTLE;
518   save_item(NAME(m_sArmRegister));
519   save_item(NAME(m_coproRegister));
520   save_item(NAME(m_pendingIrq));
521   save_item(NAME(m_pendingFiq));
532522
533   device->save_item(NAME(cpustate->sArmRegister));
534   device->save_item(NAME(cpustate->coproRegister));
535   device->save_item(NAME(cpustate->pendingIrq));
536   device->save_item(NAME(cpustate->pendingFiq));
523   state_add( ARM32_PC,   "PC",   m_sArmRegister[15]       ).mask(ADDRESS_MASK).formatstr("%08X");
524   state_add( ARM32_R0,   "R0",   m_sArmRegister[ 0]       ).formatstr("%08X");
525   state_add( ARM32_R1,   "R1",   m_sArmRegister[ 1]       ).formatstr("%08X");
526   state_add( ARM32_R2,   "R2",   m_sArmRegister[ 2]       ).formatstr("%08X");
527   state_add( ARM32_R3,   "R3",   m_sArmRegister[ 3]       ).formatstr("%08X");
528   state_add( ARM32_R4,   "R4",   m_sArmRegister[ 4]       ).formatstr("%08X");
529   state_add( ARM32_R5,   "R5",   m_sArmRegister[ 5]       ).formatstr("%08X");
530   state_add( ARM32_R6,   "R6",   m_sArmRegister[ 6]       ).formatstr("%08X");
531   state_add( ARM32_R7,   "R7",   m_sArmRegister[ 7]       ).formatstr("%08X");
532   state_add( ARM32_R8,   "R8",   m_sArmRegister[ 8]       ).formatstr("%08X");
533   state_add( ARM32_R9,   "R9",   m_sArmRegister[ 9]       ).formatstr("%08X");
534   state_add( ARM32_R10,  "R10",  m_sArmRegister[10]       ).formatstr("%08X");
535   state_add( ARM32_R11,  "R11",  m_sArmRegister[11]       ).formatstr("%08X");
536   state_add( ARM32_R12,  "R12",  m_sArmRegister[12]       ).formatstr("%08X");
537   state_add( ARM32_R13,  "R13",  m_sArmRegister[13]       ).formatstr("%08X");
538   state_add( ARM32_R14,  "R14",  m_sArmRegister[14]       ).formatstr("%08X");
539   state_add( ARM32_R15,  "R15",  m_sArmRegister[15]       ).formatstr("%08X");
540   state_add( ARM32_FR8,  "FR8",  m_sArmRegister[eR8_FIQ]  ).formatstr("%08X");
541   state_add( ARM32_FR9,  "FR9",  m_sArmRegister[eR9_FIQ]  ).formatstr("%08X");
542   state_add( ARM32_FR10, "FR10", m_sArmRegister[eR10_FIQ] ).formatstr("%08X");
543   state_add( ARM32_FR11, "FR11", m_sArmRegister[eR11_FIQ] ).formatstr("%08X");
544   state_add( ARM32_FR12, "FR12", m_sArmRegister[eR12_FIQ] ).formatstr("%08X");
545   state_add( ARM32_FR13, "FR13", m_sArmRegister[eR13_FIQ] ).formatstr("%08X");
546   state_add( ARM32_FR14, "FR14", m_sArmRegister[eR14_FIQ] ).formatstr("%08X");
547   state_add( ARM32_IR13, "IR13", m_sArmRegister[eR13_IRQ] ).formatstr("%08X");
548   state_add( ARM32_IR14, "IR14", m_sArmRegister[eR14_IRQ] ).formatstr("%08X");
549   state_add( ARM32_SR13, "SR13", m_sArmRegister[eR13_SVC] ).formatstr("%08X");
550   state_add( ARM32_SR14, "SR14", m_sArmRegister[eR14_SVC] ).formatstr("%08X");
551
552   state_add(STATE_GENPC, "curpc", m_sArmRegister[15]).mask(ADDRESS_MASK).callimport().callexport().formatstr("%11s").noshow();
553   state_add(STATE_GENFLAGS, "GENFLAGS", m_sArmRegister[15]).formatstr("%8s").noshow();
554
555   m_icountptr = &m_icount;
537556}
538557
539558
540static CPU_INIT( arm_be )
559void arm_cpu_device::state_string_export(const device_state_entry &entry, astring &string)
541560{
542   ARM_REGS *cpustate = get_safe_token(device);
561   static const char *s[4] = { "USER", "FIRQ", "IRQ ", "SVC " };
543562
544   cpustate->irq_callback = irqcallback;
545   cpustate->device = device;
546   cpustate->program = &device->space(AS_PROGRAM);
547   cpustate->endian = ENDIANNESS_BIG;
548
549   device->save_item(NAME(cpustate->sArmRegister));
550   device->save_item(NAME(cpustate->coproRegister));
551   device->save_item(NAME(cpustate->pendingIrq));
552   device->save_item(NAME(cpustate->pendingFiq));
563   switch (entry.index())
564   {
565      case STATE_GENFLAGS:
566         string.printf("%c%c%c%c%c%c %s",
567             (m_sArmRegister[15] & N_MASK) ? 'N' : '-',
568             (m_sArmRegister[15] & Z_MASK) ? 'Z' : '-',
569             (m_sArmRegister[15] & C_MASK) ? 'C' : '-',
570             (m_sArmRegister[15] & V_MASK) ? 'V' : '-',
571             (m_sArmRegister[15] & I_MASK) ? 'I' : '-',
572             (m_sArmRegister[15] & F_MASK) ? 'F' : '-',
573             s[m_sArmRegister[15] & 3] );
574         break;
575   }
553576}
554577
555578
556579/***************************************************************************/
557580
558static void HandleBranch( ARM_REGS* cpustate, UINT32 insn )
581void arm_cpu_device::HandleBranch( UINT32 insn )
559582{
560583   UINT32 off = (insn & INSN_BRANCH) << 2;
561584
562585   /* Save PC into LR if this is a branch with link */
563586   if (insn & INSN_BL)
564587   {
565      SetRegister(cpustate, 14,R15 + 4);
588      SetRegister(14,R15 + 4);
566589   }
567590
568591   /* Sign-extend the 24-bit offset in our calculations */
r23977r23978
574597   {
575598      R15 += off + 8;
576599   }
577   cpustate->icount -= 2 * S_CYCLE + N_CYCLE;
600   m_icount -= 2 * S_CYCLE + N_CYCLE;
578601}
579602
580static void HandleMemSingle( ARM_REGS* cpustate, UINT32 insn )
603
604void arm_cpu_device::HandleMemSingle( UINT32 insn )
581605{
582606   UINT32 rn, rnv, off, rd;
583607
584608   /* Fetch the offset */
585609   if (insn & INSN_I)
586610   {
587      off = decodeShift(cpustate, insn, NULL);
611      off = decodeShift(insn, NULL);
588612   }
589613   else
590614   {
r23977r23978
602626      if (insn & INSN_SDT_U)
603627      {
604628         if (rn != eR15)
605            rnv = (GetRegister(cpustate, rn) + off);
629            rnv = (GetRegister(rn) + off);
606630         else
607631            rnv = (R15 & ADDRESS_MASK) + off;
608632      }
609633      else
610634      {
611635         if (rn != eR15)
612            rnv = (GetRegister(cpustate, rn) - off);
636            rnv = (GetRegister(rn) - off);
613637         else
614638            rnv = (R15 & ADDRESS_MASK) - off;
615639      }
616640
617641      if (insn & INSN_SDT_W)
618642      {
619         SetRegister(cpustate, rn,rnv);
643         SetRegister(rn,rnv);
620644         if (ARM_DEBUG_CORE && rn == eR15)
621645            logerror("writeback R15 %08x\n", R15);
622646      }
r23977r23978
634658      }
635659      else
636660      {
637         rnv = GetRegister(cpustate, rn);
661         rnv = GetRegister(rn);
638662      }
639663   }
640664
r23977r23978
643667   if (insn & INSN_SDT_L)
644668   {
645669      /* Load */
646      cpustate->icount -= S_CYCLE + I_CYCLE + N_CYCLE;
670      m_icount -= S_CYCLE + I_CYCLE + N_CYCLE;
647671      if (insn & INSN_SDT_B)
648672      {
649673         if (ARM_DEBUG_CORE && rd == eR15)
650674            logerror("read byte R15 %08x\n", R15);
651         SetRegister(cpustate, rd,(UINT32) READ8(rnv) );
675         SetRegister(rd,(UINT32) READ8(rnv) );
652676      }
653677      else
654678      {
r23977r23978
667691            if ((READ32(rnv)&3)==0)
668692               R15 -= 4;
669693
670            cpustate->icount -= S_CYCLE + N_CYCLE;
694            m_icount -= S_CYCLE + N_CYCLE;
671695         }
672696         else
673697         {
674            SetRegister(cpustate, rd, READ32(rnv));
698            SetRegister(rd, READ32(rnv));
675699         }
676700      }
677701   }
678702   else
679703   {
680704      /* Store */
681      cpustate->icount -= 2 * N_CYCLE;
705      m_icount -= 2 * N_CYCLE;
682706      if (insn & INSN_SDT_B)
683707      {
684708         if (ARM_DEBUG_CORE && rd==eR15)
685709            logerror("Wrote R15 in byte mode\n");
686710
687         WRITE8(rnv, (UINT8) GetRegister(cpustate, rd) & 0xffu);
711         WRITE8(rnv, (UINT8) GetRegister(rd) & 0xffu);
688712      }
689713      else
690714      {
691715         if (ARM_DEBUG_CORE && rd==eR15)
692716            logerror("Wrote R15 in 32bit mode\n");
693717
694         WRITE32(rnv, rd == eR15 ? R15 + 8 : GetRegister(cpustate, rd));
718         WRITE32(rnv, rd == eR15 ? R15 + 8 : GetRegister(rd));
695719      }
696720   }
697721
r23977r23978
703727         /* Writeback is applied in pipeline, before value is read from mem,
704728             so writeback is effectively ignored */
705729         if (rd==rn) {
706            SetRegister(cpustate, rn,GetRegister(cpustate, rd));
730            SetRegister(rn,GetRegister(rd));
707731         }
708732         else {
709733            if ((insn&INSN_SDT_W)!=0)
710734            logerror("%08x:  RegisterWritebackIncrement %d %d %d\n",R15,(insn & INSN_SDT_P)!=0,(insn&INSN_SDT_W)!=0,(insn & INSN_SDT_U)!=0);
711735
712            SetRegister(cpustate, rn,(rnv + off));
736            SetRegister(rn,(rnv + off));
713737         }
714738      }
715739      else
r23977r23978
717741         /* Writeback is applied in pipeline, before value is read from mem,
718742             so writeback is effectively ignored */
719743         if (rd==rn) {
720            SetRegister(cpustate, rn,GetRegister(cpustate, rd));
744            SetRegister(rn,GetRegister(rd));
721745         }
722746         else {
723            SetRegister(cpustate, rn,(rnv - off));
747            SetRegister(rn,(rnv - off));
724748
725749            if ((insn&INSN_SDT_W)!=0)
726750            logerror("%08x:  RegisterWritebackDecrement %d %d %d\n",R15,(insn & INSN_SDT_P)!=0,(insn&INSN_SDT_W)!=0,(insn & INSN_SDT_U)!=0);
r23977r23978
768792                  | (((sc) != 0) << C_BIT)) + 4; \
769793   else R15 += 4;
770794
771static void HandleALU( ARM_REGS* cpustate, UINT32 insn )
795void arm_cpu_device::HandleALU( UINT32 insn )
772796{
773797   UINT32 op2, sc=0, rd, rn, opcode;
774798   UINT32 by, rdn;
775799
776800   opcode = (insn & INSN_OPCODE) >> INSN_OPCODE_SHIFT;
777   cpustate->icount -= S_CYCLE;
801   m_icount -= S_CYCLE;
778802
779803   rd = 0;
780804   rn = 0;
r23977r23978
797821   }
798822   else
799823   {
800      op2 = decodeShift(cpustate, insn, (insn & INSN_S) ? &sc : NULL);
824      op2 = decodeShift(insn, (insn & INSN_S) ? &sc : NULL);
801825
802826         if (!(insn & INSN_S))
803827         sc=0;
r23977r23978
817841      }
818842      else
819843      {
820         rn = GetRegister(cpustate, rn);
844         rn = GetRegister(rn);
821845      }
822846   }
823847
r23977r23978
888912      {
889913         /* Merge the old NZCV flags into the new PC value */
890914         R15 = (rd & ADDRESS_MASK) | (R15 & PSR_MASK) | (R15 & IRQ_MASK) | (R15&MODE_MASK);
891         cpustate->icount -= S_CYCLE + N_CYCLE;
915         m_icount -= S_CYCLE + N_CYCLE;
892916      }
893917      else
894918      {
r23977r23978
897921            /* S Flag is set - update PSR & mode if in non-user mode only */
898922            if ((R15&MODE_MASK)!=0)
899923            {
900               SetRegister(cpustate,rdn,rd);
924               SetRegister(rdn,rd);
901925            }
902926            else
903927            {
904               SetRegister(cpustate, rdn,(rd&ADDRESS_MASK) | (rd&PSR_MASK) | (R15&IRQ_MASK) | (R15&MODE_MASK));
928               SetRegister(rdn,(rd&ADDRESS_MASK) | (rd&PSR_MASK) | (R15&IRQ_MASK) | (R15&MODE_MASK));
905929            }
906            cpustate->icount -= S_CYCLE + N_CYCLE;
930            m_icount -= S_CYCLE + N_CYCLE;
907931         }
908932         else
909933         {
910            SetRegister(cpustate,rdn,rd);
934            SetRegister(rdn,rd);
911935         }
912936      }
913937   /* TST & TEQ can affect R15 (the condition code register) with the S bit set */
r23977r23978
920944         // combine the flags from rd with the address from R15
921945         rd &= ~ADDRESS_MASK;
922946         rd |= (R15 & ADDRESS_MASK);
923         SetRegister(cpustate,rdn,rd);
947         SetRegister(rdn,rd);
924948      }
925949      else
926950      {
927951         // combine the flags from rd with the address from R15
928952         rd &= ~ADDRESS_MASK;    // clear address part of RD
929953         rd |= (R15 & ADDRESS_MASK); // RD = address part of R15
930         SetRegister(cpustate, rdn,(rd&ADDRESS_MASK) | (rd&PSR_MASK) | (R15&IRQ_MASK) | (R15&MODE_MASK));
954         SetRegister(rdn,(rd&ADDRESS_MASK) | (rd&PSR_MASK) | (R15&IRQ_MASK) | (R15&MODE_MASK));
931955      }
932      cpustate->icount -= S_CYCLE + N_CYCLE;
956      m_icount -= S_CYCLE + N_CYCLE;
933957   }
934958}
935959
936static void HandleMul( ARM_REGS* cpustate, UINT32 insn)
960void arm_cpu_device::HandleMul( UINT32 insn)
937961{
938962   UINT32 r;
939963
940   cpustate->icount -= S_CYCLE + I_CYCLE;
964   m_icount -= S_CYCLE + I_CYCLE;
941965   /* should be:
942966           Range of Rs            Number of cycles
943967
r23977r23978
960984   */
961985
962986   /* Do the basic multiply of Rm and Rs */
963   r = GetRegister( cpustate, insn&INSN_MUL_RM ) *
964      GetRegister( cpustate, (insn&INSN_MUL_RS)>>INSN_MUL_RS_SHIFT );
987   r = GetRegister( insn&INSN_MUL_RM ) *
988      GetRegister( (insn&INSN_MUL_RS)>>INSN_MUL_RS_SHIFT );
965989
966990   if (ARM_DEBUG_CORE && ((insn&INSN_MUL_RM)==0xf
967991      || ((insn&INSN_MUL_RS)>>INSN_MUL_RS_SHIFT )==0xf
r23977r23978
972996   /* Add on Rn if this is a MLA */
973997   if (insn & INSN_MUL_A)
974998   {
975      r += GetRegister(cpustate, (insn&INSN_MUL_RN)>>INSN_MUL_RN_SHIFT);
999      r += GetRegister((insn&INSN_MUL_RN)>>INSN_MUL_RN_SHIFT);
9761000   }
9771001
9781002   /* Write the result */
979   SetRegister(cpustate,(insn&INSN_MUL_RD)>>INSN_MUL_RD_SHIFT,r);
1003   SetRegister((insn&INSN_MUL_RD)>>INSN_MUL_RD_SHIFT,r);
9801004
9811005   /* Set N and Z if asked */
9821006   if( insn & INSN_S )
r23977r23978
9851009   }
9861010}
9871011
988static int loadInc ( ARM_REGS* cpustate, UINT32 pat, UINT32 rbv, UINT32 s)
1012
1013int arm_cpu_device::loadInc(UINT32 pat, UINT32 rbv, UINT32 s)
9891014{
9901015   int i,result;
9911016
r23977r23978
9961021      {
9971022         if (i==15) {
9981023            if (s) /* Pull full contents from stack */
999               SetRegister( cpustate, 15, READ32(rbv+=4) );
1024               SetRegister( 15, READ32(rbv+=4) );
10001025            else /* Pull only address, preserve mode & status flags */
1001               SetRegister( cpustate, 15, (R15&PSR_MASK) | (R15&IRQ_MASK) | (R15&MODE_MASK) | ((READ32(rbv+=4))&ADDRESS_MASK) );
1026               SetRegister( 15, (R15&PSR_MASK) | (R15&IRQ_MASK) | (R15&MODE_MASK) | ((READ32(rbv+=4))&ADDRESS_MASK) );
10021027         } else
1003            SetRegister( cpustate, i, READ32(rbv+=4) );
1028            SetRegister( i, READ32(rbv+=4) );
10041029
10051030         result++;
10061031      }
r23977r23978
10081033   return result;
10091034}
10101035
1011static int loadDec( ARM_REGS* cpustate, UINT32 pat, UINT32 rbv, UINT32 s, UINT32* deferredR15, int* defer)
1036
1037int arm_cpu_device::loadDec(UINT32 pat, UINT32 rbv, UINT32 s, UINT32* deferredR15, int* defer)
10121038{
10131039   int i,result;
10141040
r23977r23978
10251051               *deferredR15=(R15&PSR_MASK) | (R15&IRQ_MASK) | (R15&MODE_MASK) | ((READ32(rbv-=4))&ADDRESS_MASK);
10261052         }
10271053         else
1028            SetRegister( cpustate, i, READ32(rbv -=4) );
1054            SetRegister( i, READ32(rbv -=4) );
10291055         result++;
10301056      }
10311057   }
10321058   return result;
10331059}
10341060
1035static int storeInc( ARM_REGS* cpustate, UINT32 pat, UINT32 rbv)
1061
1062int arm_cpu_device::storeInc(UINT32 pat, UINT32 rbv)
10361063{
10371064   int i,result;
10381065
r23977r23978
10441071         if (ARM_DEBUG_CORE && i==15) /* R15 is plus 12 from address of STM */
10451072            logerror("%08x: StoreInc on R15\n",R15);
10461073
1047         WRITE32( rbv += 4, GetRegister(cpustate, i) );
1074         WRITE32( rbv += 4, GetRegister(i) );
10481075         result++;
10491076      }
10501077   }
10511078   return result;
10521079} /* storeInc */
10531080
1054static int storeDec( ARM_REGS* cpustate, UINT32 pat, UINT32 rbv)
1081
1082int arm_cpu_device::storeDec(UINT32 pat, UINT32 rbv)
10551083{
10561084   int i,result;
10571085
r23977r23978
10631091         if (ARM_DEBUG_CORE && i==15) /* R15 is plus 12 from address of STM */
10641092            logerror("%08x: StoreDec on R15\n",R15);
10651093
1066         WRITE32( rbv -= 4, GetRegister(cpustate, i) );
1094         WRITE32( rbv -= 4, GetRegister(i) );
10671095         result++;
10681096      }
10691097   }
10701098   return result;
10711099} /* storeDec */
10721100
1073static void HandleMemBlock( ARM_REGS* cpustate, UINT32 insn )
1101
1102void arm_cpu_device::HandleMemBlock( UINT32 insn )
10741103{
10751104   UINT32 rb = (insn & INSN_RN) >> INSN_RN_SHIFT;
1076   UINT32 rbp = GetRegister(cpustate, rb);
1105   UINT32 rbp = GetRegister(rb);
10771106   int result;
10781107
10791108   if (ARM_DEBUG_CORE && insn & INSN_BDT_S)
r23977r23978
10891118         /* Incrementing */
10901119         if (!(insn & INSN_BDT_P)) rbp = rbp + (- 4);
10911120
1092         result = loadInc( cpustate, insn & 0xffff, rbp, insn&INSN_BDT_S );
1121         result = loadInc( insn & 0xffff, rbp, insn&INSN_BDT_S );
10931122
10941123         if (insn & 0x8000) {
10951124            R15-=4;
1096            cpustate->icount -= S_CYCLE + N_CYCLE;
1125            m_icount -= S_CYCLE + N_CYCLE;
10971126         }
10981127
10991128         if (insn & INSN_BDT_W)
r23977r23978
11131142               logerror("%08x:  Illegal LDRM writeback to r15\n",R15);
11141143
11151144            if ((insn&(1<<rb))==0)
1116               SetModeRegister(cpustate, mode, rb, GetModeRegister(cpustate, mode, rb) + result * 4);
1145               SetModeRegister(mode, rb, GetModeRegister(mode, rb) + result * 4);
11171146            else if (ARM_DEBUG_CORE)
11181147               logerror("%08x:  Illegal LDRM writeback to base register (%d)\n",R15, rb);
11191148         }
r23977r23978
11291158            rbp = rbp - (- 4);
11301159         }
11311160
1132         result = loadDec( cpustate, insn&0xffff, rbp, insn&INSN_BDT_S, &deferredR15, &defer );
1161         result = loadDec( insn&0xffff, rbp, insn&INSN_BDT_S, &deferredR15, &defer );
11331162
11341163         if (insn & INSN_BDT_W)
11351164         {
11361165            if (rb==0xf)
11371166               logerror("%08x:  Illegal LDRM writeback to r15\n",R15);
1138            SetRegister(cpustate,rb,GetRegister(cpustate, rb)-result*4);
1167            SetRegister(rb,GetRegister(rb)-result*4);
11391168         }
11401169
11411170         // If R15 is pulled from memory we defer setting it until after writeback
11421171         // is performed, else we may writeback to the wrong context (ie, the new
11431172         // context if the mode has changed as a result of the R15 read)
11441173         if (defer)
1145            SetRegister(cpustate, 15, deferredR15);
1174            SetRegister(15, deferredR15);
11461175
11471176         if (insn & 0x8000) {
1148            cpustate->icount -= S_CYCLE + N_CYCLE;
1177            m_icount -= S_CYCLE + N_CYCLE;
11491178            R15-=4;
11501179         }
11511180      }
1152      cpustate->icount -= result * S_CYCLE + N_CYCLE + I_CYCLE;
1181      m_icount -= result * S_CYCLE + N_CYCLE + I_CYCLE;
11531182   } /* Loading */
11541183   else
11551184   {
r23977r23978
11751204         {
11761205            rbp = rbp + (- 4);
11771206         }
1178         result = storeInc( cpustate, insn&0xffff, rbp );
1207         result = storeInc( insn&0xffff, rbp );
11791208         if( insn & INSN_BDT_W )
11801209         {
1181            SetRegister(cpustate,rb,GetRegister(cpustate, rb)+result*4);
1210            SetRegister(rb,GetRegister(rb)+result*4);
11821211         }
11831212      }
11841213      else
r23977r23978
11881217         {
11891218            rbp = rbp - (- 4);
11901219         }
1191         result = storeDec( cpustate, insn&0xffff, rbp );
1220         result = storeDec( insn&0xffff, rbp );
11921221         if( insn & INSN_BDT_W )
11931222         {
1194            SetRegister(cpustate,rb,GetRegister(cpustate, rb)-result*4);
1223            SetRegister(rb,GetRegister(rb)-result*4);
11951224         }
11961225      }
11971226      if( insn & (1<<eR15) )
11981227         R15 -= 12;
11991228
1200      cpustate->icount -= (result - 1) * S_CYCLE + 2 * N_CYCLE;
1229      m_icount -= (result - 1) * S_CYCLE + 2 * N_CYCLE;
12011230   }
12021231} /* HandleMemBlock */
12031232
r23977r23978
12071236 * shifter carry output will manifest itself as @*carry == 0@ for carry clear
12081237 * and @*carry != 0@ for carry set.
12091238 */
1210static UINT32 decodeShift( ARM_REGS* cpustate, UINT32 insn, UINT32 *pCarry)
1239UINT32 arm_cpu_device::decodeShift(UINT32 insn, UINT32 *pCarry)
12111240{
12121241   UINT32 k    = (insn & INSN_OP2_SHIFT) >> INSN_OP2_SHIFT_SHIFT;
1213   UINT32 rm   = GetRegister( cpustate, insn & INSN_OP2_RM );
1242   UINT32 rm   = GetRegister( insn & INSN_OP2_RM );
12141243   UINT32 t    = (insn & INSN_OP2_SHIFT_TYPE) >> INSN_OP2_SHIFT_TYPE_SHIFT;
12151244
12161245   if ((insn & INSN_OP2_RM)==0xf) {
r23977r23978
12221251   /* All shift types ending in 1 are Rk, not #k */
12231252   if( t & 1 )
12241253   {
1225//      logerror("%08x:  RegShift %02x %02x\n",R15, k>>1,GetRegister(cpustate, k >> 1));
1254//      logerror("%08x:  RegShift %02x %02x\n",R15, k>>1,GetRegister(k >> 1));
12261255      if (ARM_DEBUG_CORE && (insn&0x80)==0x80)
12271256         logerror("%08x:  RegShift ERROR (p36)\n",R15);
12281257
12291258      //see p35 for check on this
1230      k = GetRegister(cpustate, k >> 1)&0x1f;
1231      cpustate->icount -= S_CYCLE;
1259      k = GetRegister(k >> 1)&0x1f;
1260      m_icount -= S_CYCLE;
12321261      if( k == 0 ) /* Register shift by 0 is a no-op */
12331262      {
12341263//          logerror("%08x:  NO-OP Regshift\n",R15);
r23977r23978
12991328} /* decodeShift */
13001329
13011330
1302static UINT32 BCDToDecimal(UINT32 value)
1331UINT32 arm_cpu_device::BCDToDecimal(UINT32 value)
13031332{
13041333   UINT32  accumulator = 0;
13051334   UINT32  multiplier = 1;
r23977r23978
13161345   return accumulator;
13171346}
13181347
1319static UINT32 DecimalToBCD(UINT32 value)
1348
1349UINT32 arm_cpu_device::DecimalToBCD(UINT32 value)
13201350{
13211351   UINT32  accumulator = 0;
13221352   UINT32  divisor = 10;
r23977r23978
13381368   return accumulator;
13391369}
13401370
1341static void HandleCoPro( ARM_REGS* cpustate, UINT32 insn )
1371
1372void arm_cpu_device::HandleCoPro( UINT32 insn )
13421373{
13431374   UINT32 rn=(insn>>12)&0xf;
13441375   UINT32 crn=(insn>>16)&0xf;
13451376
1346   cpustate->icount -= S_CYCLE;
1377   m_icount -= S_CYCLE;
13471378
13481379   /* MRC - transfer copro register to main register */
13491380   if( (insn&0x0f100010)==0x0e100010 )
13501381   {
1351      SetRegister(cpustate, rn, cpustate->coproRegister[crn]);
1382      SetRegister(rn, m_coproRegister[crn]);
13521383
13531384      if (ARM_DEBUG_COPRO)
1354         logerror("%08x:  Copro read CR%d (%08x) to R%d\n", R15, crn, cpustate->coproRegister[crn], rn);
1385         logerror("%08x:  Copro read CR%d (%08x) to R%d\n", R15, crn, m_coproRegister[crn], rn);
13551386   }
13561387   /* MCR - transfer main register to copro register */
13571388   else if( (insn&0x0f100010)==0x0e000010 )
13581389   {
1359      cpustate->coproRegister[crn]=GetRegister(cpustate, rn);
1390      m_coproRegister[crn]=GetRegister(rn);
13601391
13611392      /* Data East 156 copro specific - trigger BCD operation */
13621393      if (crn==2)
13631394      {
1364         if (cpustate->coproRegister[crn]==0)
1395         if (m_coproRegister[crn]==0)
13651396         {
13661397            /* Unpack BCD */
1367            int v0=BCDToDecimal(cpustate->coproRegister[0]);
1368            int v1=BCDToDecimal(cpustate->coproRegister[1]);
1398            int v0=BCDToDecimal(m_coproRegister[0]);
1399            int v1=BCDToDecimal(m_coproRegister[1]);
13691400
13701401            /* Repack vcd */
1371            cpustate->coproRegister[5]=DecimalToBCD(v0+v1);
1402            m_coproRegister[5]=DecimalToBCD(v0+v1);
13721403
13731404            if (ARM_DEBUG_COPRO)
1374               logerror("Cmd:  Add 0 + 1, result in 5 (%08x + %08x == %08x)\n", v0, v1, cpustate->coproRegister[5]);
1405               logerror("Cmd:  Add 0 + 1, result in 5 (%08x + %08x == %08x)\n", v0, v1, m_coproRegister[5]);
13751406         }
1376         else if (cpustate->coproRegister[crn]==1)
1407         else if (m_coproRegister[crn]==1)
13771408         {
13781409            /* Unpack BCD */
1379            int v0=BCDToDecimal(cpustate->coproRegister[0]);
1380            int v1=BCDToDecimal(cpustate->coproRegister[1]);
1410            int v0=BCDToDecimal(m_coproRegister[0]);
1411            int v1=BCDToDecimal(m_coproRegister[1]);
13811412
13821413            /* Repack vcd */
1383            cpustate->coproRegister[5]=DecimalToBCD(v0*v1);
1414            m_coproRegister[5]=DecimalToBCD(v0*v1);
13841415
13851416            if (ARM_DEBUG_COPRO)
1386               logerror("Cmd:  Multiply 0 * 1, result in 5 (%08x * %08x == %08x)\n", v0, v1, cpustate->coproRegister[5]);
1417               logerror("Cmd:  Multiply 0 * 1, result in 5 (%08x * %08x == %08x)\n", v0, v1, m_coproRegister[5]);
13871418         }
1388         else if (cpustate->coproRegister[crn]==3)
1419         else if (m_coproRegister[crn]==3)
13891420         {
13901421            /* Unpack BCD */
1391            int v0=BCDToDecimal(cpustate->coproRegister[0]);
1392            int v1=BCDToDecimal(cpustate->coproRegister[1]);
1422            int v0=BCDToDecimal(m_coproRegister[0]);
1423            int v1=BCDToDecimal(m_coproRegister[1]);
13931424
13941425            /* Repack vcd */
1395            cpustate->coproRegister[5]=DecimalToBCD(v0-v1);
1426            m_coproRegister[5]=DecimalToBCD(v0-v1);
13961427
13971428            if (ARM_DEBUG_COPRO)
1398               logerror("Cmd:  Sub 0 - 1, result in 5 (%08x - %08x == %08x)\n", v0, v1, cpustate->coproRegister[5]);
1429               logerror("Cmd:  Sub 0 - 1, result in 5 (%08x - %08x == %08x)\n", v0, v1, m_coproRegister[5]);
13991430         }
14001431         else
14011432         {
1402            logerror("Unknown bcd copro command %08x\n", cpustate->coproRegister[crn]);
1433            logerror("Unknown bcd copro command %08x\n", m_coproRegister[crn]);
14031434         }
14041435      }
14051436
14061437      if (ARM_DEBUG_COPRO)
1407         logerror("%08x:  Copro write R%d (%08x) to CR%d\n", R15, rn, GetRegister(cpustate, rn), crn);
1438         logerror("%08x:  Copro write R%d (%08x) to CR%d\n", R15, rn, GetRegister(rn), crn);
14081439   }
14091440   /* CDP - perform copro operation */
14101441   else if( (insn&0x0f000010)==0x0e000000 )
14111442   {
14121443      /* Data East 156 copro specific divider - result in reg 3/4 */
1413      if (cpustate->coproRegister[1])
1444      if (m_coproRegister[1])
14141445      {
1415         cpustate->coproRegister[3]=cpustate->coproRegister[0] / cpustate->coproRegister[1];
1416         cpustate->coproRegister[4]=cpustate->coproRegister[0] % cpustate->coproRegister[1];
1446         m_coproRegister[3]=m_coproRegister[0] / m_coproRegister[1];
1447         m_coproRegister[4]=m_coproRegister[0] % m_coproRegister[1];
14171448      }
14181449      else
14191450      {
14201451         /* Unverified */
1421         cpustate->coproRegister[3]=0xffffffff;
1422         cpustate->coproRegister[4]=0xffffffff;
1452         m_coproRegister[3]=0xffffffff;
1453         m_coproRegister[4]=0xffffffff;
14231454      }
14241455
14251456      if (ARM_DEBUG_COPRO)
1426         logerror("%08x:  Copro cdp (%08x) (3==> %08x, 4==> %08x)\n", R15, insn, cpustate->coproRegister[3], cpustate->coproRegister[4]);
1457         logerror("%08x:  Copro cdp (%08x) (3==> %08x, 4==> %08x)\n", R15, insn, m_coproRegister[3], m_coproRegister[4]);
14271458   }
14281459   else
14291460   {
r23977r23978
14321463}
14331464
14341465
1435/**************************************************************************
1436 * Generic set_info
1437 **************************************************************************/
1438
1439static CPU_SET_INFO( arm )
1466offs_t arm_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
14401467{
1441   ARM_REGS *cpustate = get_safe_token(device);
1442
1443   switch (state)
1444   {
1445      /* --- the following bits of info are set as 64-bit signed integers --- */
1446      case CPUINFO_INT_INPUT_STATE + ARM_IRQ_LINE:    set_irq_line(cpustate, ARM_IRQ_LINE, info->i);  break;
1447      case CPUINFO_INT_INPUT_STATE + ARM_FIRQ_LINE:   set_irq_line(cpustate, ARM_FIRQ_LINE, info->i); break;
1448
1449      case CPUINFO_INT_REGISTER + ARM32_R0:   cpustate->sArmRegister[ 0]= info->i;                    break;
1450      case CPUINFO_INT_REGISTER + ARM32_R1:   cpustate->sArmRegister[ 1]= info->i;                    break;
1451      case CPUINFO_INT_REGISTER + ARM32_R2:   cpustate->sArmRegister[ 2]= info->i;                    break;
1452      case CPUINFO_INT_REGISTER + ARM32_R3:   cpustate->sArmRegister[ 3]= info->i;                    break;
1453      case CPUINFO_INT_REGISTER + ARM32_R4:   cpustate->sArmRegister[ 4]= info->i;                    break;
1454      case CPUINFO_INT_REGISTER + ARM32_R5:   cpustate->sArmRegister[ 5]= info->i;                    break;
1455      case CPUINFO_INT_REGISTER + ARM32_R6:   cpustate->sArmRegister[ 6]= info->i;                    break;
1456      case CPUINFO_INT_REGISTER + ARM32_R7:   cpustate->sArmRegister[ 7]= info->i;                    break;
1457      case CPUINFO_INT_REGISTER + ARM32_R8:   cpustate->sArmRegister[ 8]= info->i;                    break;
1458      case CPUINFO_INT_REGISTER + ARM32_R9:   cpustate->sArmRegister[ 9]= info->i;                    break;
1459      case CPUINFO_INT_REGISTER + ARM32_R10:  cpustate->sArmRegister[10]= info->i;                    break;
1460      case CPUINFO_INT_REGISTER + ARM32_R11:  cpustate->sArmRegister[11]= info->i;                    break;
1461      case CPUINFO_INT_REGISTER + ARM32_R12:  cpustate->sArmRegister[12]= info->i;                    break;
1462      case CPUINFO_INT_REGISTER + ARM32_R13:  cpustate->sArmRegister[13]= info->i;                    break;
1463      case CPUINFO_INT_REGISTER + ARM32_R14:  cpustate->sArmRegister[14]= info->i;                    break;
1464      case CPUINFO_INT_REGISTER + ARM32_R15:  cpustate->sArmRegister[15]= info->i;                    break;
1465      case CPUINFO_INT_REGISTER + ARM32_FR8:  cpustate->sArmRegister[eR8_FIQ] = info->i;          break;
1466      case CPUINFO_INT_REGISTER + ARM32_FR9:  cpustate->sArmRegister[eR9_FIQ] = info->i;          break;
1467      case CPUINFO_INT_REGISTER + ARM32_FR10: cpustate->sArmRegister[eR10_FIQ] = info->i;         break;
1468      case CPUINFO_INT_REGISTER + ARM32_FR11: cpustate->sArmRegister[eR11_FIQ] = info->i;         break;
1469      case CPUINFO_INT_REGISTER + ARM32_FR12: cpustate->sArmRegister[eR12_FIQ] = info->i;         break;
1470      case CPUINFO_INT_REGISTER + ARM32_FR13: cpustate->sArmRegister[eR13_FIQ] = info->i;         break;
1471      case CPUINFO_INT_REGISTER + ARM32_FR14: cpustate->sArmRegister[eR14_FIQ] = info->i;         break;
1472      case CPUINFO_INT_REGISTER + ARM32_IR13: cpustate->sArmRegister[eR13_IRQ] = info->i;         break;
1473      case CPUINFO_INT_REGISTER + ARM32_IR14: cpustate->sArmRegister[eR14_IRQ] = info->i;         break;
1474      case CPUINFO_INT_REGISTER + ARM32_SR13: cpustate->sArmRegister[eR13_SVC] = info->i;         break;
1475      case CPUINFO_INT_REGISTER + ARM32_SR14: cpustate->sArmRegister[eR14_SVC] = info->i;         break;
1476
1477      case CPUINFO_INT_PC:
1478      case CPUINFO_INT_REGISTER + ARM32_PC:   R15 = (R15&~ADDRESS_MASK)|info->i;              break;
1479      case CPUINFO_INT_SP:                    SetRegister(cpustate,13,info->i);                       break;
1480   }
1468   extern CPU_DISASSEMBLE( arm );
1469   return CPU_DISASSEMBLE_NAME(arm)(this, buffer, pc, oprom, opram, options);
14811470}
14821471
14831472
1484
1485/**************************************************************************
1486 * Generic get_info
1487 **************************************************************************/
1488
1489CPU_GET_INFO( arm )
1473offs_t arm_be_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
14901474{
1491   ARM_REGS *cpustate = (device != NULL && device->token() != NULL) ? get_safe_token(device) : NULL;
1492
1493   switch (state)
1494   {
1495      /* --- the following bits of info are returned as 64-bit signed integers --- */
1496      case CPUINFO_INT_CONTEXT_SIZE:                  info->i = sizeof(ARM_REGS);             break;
1497      case CPUINFO_INT_INPUT_LINES:                   info->i = 2;                            break;
1498      case CPUINFO_INT_DEFAULT_IRQ_VECTOR:            info->i = 0;                            break;
1499      case CPUINFO_INT_ENDIANNESS:                    info->i = ENDIANNESS_LITTLE;            break;
1500      case CPUINFO_INT_CLOCK_MULTIPLIER:              info->i = 1;                            break;
1501      case CPUINFO_INT_CLOCK_DIVIDER:                 info->i = 1;                            break;
1502      case CPUINFO_INT_MIN_INSTRUCTION_BYTES:         info->i = 4;                            break;
1503      case CPUINFO_INT_MAX_INSTRUCTION_BYTES:         info->i = 4;                            break;
1504      case CPUINFO_INT_MIN_CYCLES:                    info->i = 3;                            break;
1505      case CPUINFO_INT_MAX_CYCLES:                    info->i = 4;                            break;
1506
1507      case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM:    info->i = 32;                   break;
1508      case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 26;                  break;
1509      case CPUINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM: info->i = 0;                   break;
1510      case CPUINFO_INT_DATABUS_WIDTH + AS_DATA:   info->i = 0;                    break;
1511      case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA:   info->i = 0;                    break;
1512      case CPUINFO_INT_ADDRBUS_SHIFT + AS_DATA:   info->i = 0;                    break;
1513      case CPUINFO_INT_DATABUS_WIDTH + AS_IO:     info->i = 0;                    break;
1514      case CPUINFO_INT_ADDRBUS_WIDTH + AS_IO:     info->i = 0;                    break;
1515      case CPUINFO_INT_ADDRBUS_SHIFT + AS_IO:     info->i = 0;                    break;
1516
1517      case CPUINFO_INT_INPUT_STATE + ARM_IRQ_LINE:    info->i = cpustate->pendingIrq;         break;
1518      case CPUINFO_INT_INPUT_STATE + ARM_FIRQ_LINE:   info->i = cpustate->pendingFiq;         break;
1519
1520      case CPUINFO_INT_PREVIOUSPC:                    info->i = 0;    /* not implemented */   break;
1521      case CPUINFO_INT_PC:
1522      case CPUINFO_INT_REGISTER + ARM32_PC:           info->i = cpustate->sArmRegister[15]&ADDRESS_MASK; break;
1523      case CPUINFO_INT_SP:                            info->i = GetRegister(cpustate, 13);    break;
1524
1525      case CPUINFO_INT_REGISTER + ARM32_R0:           info->i = cpustate->sArmRegister[ 0];   break;
1526      case CPUINFO_INT_REGISTER + ARM32_R1:           info->i = cpustate->sArmRegister[ 1];   break;
1527      case CPUINFO_INT_REGISTER + ARM32_R2:           info->i = cpustate->sArmRegister[ 2];   break;
1528      case CPUINFO_INT_REGISTER + ARM32_R3:           info->i = cpustate->sArmRegister[ 3];   break;
1529      case CPUINFO_INT_REGISTER + ARM32_R4:           info->i = cpustate->sArmRegister[ 4];   break;
1530      case CPUINFO_INT_REGISTER + ARM32_R5:           info->i = cpustate->sArmRegister[ 5];   break;
1531      case CPUINFO_INT_REGISTER + ARM32_R6:           info->i = cpustate->sArmRegister[ 6];   break;
1532      case CPUINFO_INT_REGISTER + ARM32_R7:           info->i = cpustate->sArmRegister[ 7];   break;
1533      case CPUINFO_INT_REGISTER + ARM32_R8:           info->i = cpustate->sArmRegister[ 8];   break;
1534      case CPUINFO_INT_REGISTER + ARM32_R9:           info->i = cpustate->sArmRegister[ 9];   break;
1535      case CPUINFO_INT_REGISTER + ARM32_R10:          info->i = cpustate->sArmRegister[10];   break;
1536      case CPUINFO_INT_REGISTER + ARM32_R11:          info->i = cpustate->sArmRegister[11];   break;
1537      case CPUINFO_INT_REGISTER + ARM32_R12:          info->i = cpustate->sArmRegister[12];   break;
1538      case CPUINFO_INT_REGISTER + ARM32_R13:          info->i = cpustate->sArmRegister[13];   break;
1539      case CPUINFO_INT_REGISTER + ARM32_R14:          info->i = cpustate->sArmRegister[14];   break;
1540      case CPUINFO_INT_REGISTER + ARM32_R15:          info->i = cpustate->sArmRegister[15];   break;
1541
1542      case CPUINFO_INT_REGISTER + ARM32_FR8:          info->i = cpustate->sArmRegister[eR8_FIQ];  break;
1543      case CPUINFO_INT_REGISTER + ARM32_FR9:          info->i = cpustate->sArmRegister[eR9_FIQ];  break;
1544      case CPUINFO_INT_REGISTER + ARM32_FR10:         info->i = cpustate->sArmRegister[eR10_FIQ]; break;
1545      case CPUINFO_INT_REGISTER + ARM32_FR11:         info->i = cpustate->sArmRegister[eR11_FIQ]; break;
1546      case CPUINFO_INT_REGISTER + ARM32_FR12:         info->i = cpustate->sArmRegister[eR12_FIQ]; break;
1547      case CPUINFO_INT_REGISTER + ARM32_FR13:         info->i = cpustate->sArmRegister[eR13_FIQ]; break;
1548      case CPUINFO_INT_REGISTER + ARM32_FR14:         info->i = cpustate->sArmRegister[eR14_FIQ]; break;
1549      case CPUINFO_INT_REGISTER + ARM32_IR13:         info->i = cpustate->sArmRegister[eR13_IRQ]; break;
1550      case CPUINFO_INT_REGISTER + ARM32_IR14:         info->i = cpustate->sArmRegister[eR14_IRQ]; break;
1551      case CPUINFO_INT_REGISTER + ARM32_SR13:         info->i = cpustate->sArmRegister[eR13_SVC]; break;
1552      case CPUINFO_INT_REGISTER + ARM32_SR14:         info->i = cpustate->sArmRegister[eR14_SVC]; break;
1553
1554      /* --- the following bits of info are returned as pointers to data or functions --- */
1555      case CPUINFO_FCT_SET_INFO:                      info->setinfo = CPU_SET_INFO_NAME(arm);         break;
1556      case CPUINFO_FCT_INIT:                          info->init = CPU_INIT_NAME(arm);                break;
1557      case CPUINFO_FCT_RESET:                         info->reset = CPU_RESET_NAME(arm);              break;
1558      case CPUINFO_FCT_EXIT:                          info->exit = CPU_EXIT_NAME(arm);                break;
1559      case CPUINFO_FCT_EXECUTE:                       info->execute = CPU_EXECUTE_NAME(arm);          break;
1560      case CPUINFO_FCT_BURN:                          info->burn = NULL;                              break;
1561      case CPUINFO_FCT_DISASSEMBLE:                   info->disassemble = CPU_DISASSEMBLE_NAME(arm);  break;
1562      case CPUINFO_PTR_INSTRUCTION_COUNTER:           info->icount = &cpustate->icount;               break;
1563
1564      /* --- the following bits of info are returned as NULL-terminated strings --- */
1565      case CPUINFO_STR_NAME:                          strcpy(info->s, "ARM");                 break;
1566      case CPUINFO_STR_FAMILY:                    strcpy(info->s, "Acorn Risc Machine");  break;
1567      case CPUINFO_STR_VERSION:                   strcpy(info->s, "1.3");                 break;
1568      case CPUINFO_STR_SOURCE_FILE:                       strcpy(info->s, __FILE__);              break;
1569      case CPUINFO_STR_CREDITS:                   strcpy(info->s, "Copyright Bryan McPhail, bmcphail@tendril.co.uk"); break;
1570
1571      case CPUINFO_STR_FLAGS:
1572         sprintf(info->s, "%c%c%c%c%c%c",
1573            (cpustate->sArmRegister[15] & N_MASK) ? 'N' : '-',
1574            (cpustate->sArmRegister[15] & Z_MASK) ? 'Z' : '-',
1575            (cpustate->sArmRegister[15] & C_MASK) ? 'C' : '-',
1576            (cpustate->sArmRegister[15] & V_MASK) ? 'V' : '-',
1577            (cpustate->sArmRegister[15] & I_MASK) ? 'I' : '-',
1578            (cpustate->sArmRegister[15] & F_MASK) ? 'F' : '-');
1579         switch (cpustate->sArmRegister[15] & 3)
1580         {
1581         case 0:
1582            strcat(info->s, " USER");
1583            break;
1584         case 1:
1585            strcat(info->s, " FIRQ");
1586            break;
1587         case 2:
1588            strcat(info->s, " IRQ ");
1589            break;
1590         default:
1591            strcat(info->s, " SVC ");
1592            break;
1593         }
1594         break;
1595
1596      case CPUINFO_STR_REGISTER + ARM32_PC:   sprintf( info->s, "PC  :%08x", cpustate->sArmRegister[15]&ADDRESS_MASK ); break;
1597      case CPUINFO_STR_REGISTER + ARM32_R0:   sprintf( info->s, "R0  :%08x", cpustate->sArmRegister[ 0] ); break;
1598      case CPUINFO_STR_REGISTER + ARM32_R1:   sprintf( info->s, "R1  :%08x", cpustate->sArmRegister[ 1] ); break;
1599      case CPUINFO_STR_REGISTER + ARM32_R2:   sprintf( info->s, "R2  :%08x", cpustate->sArmRegister[ 2] ); break;
1600      case CPUINFO_STR_REGISTER + ARM32_R3:   sprintf( info->s, "R3  :%08x", cpustate->sArmRegister[ 3] ); break;
1601      case CPUINFO_STR_REGISTER + ARM32_R4:   sprintf( info->s, "R4  :%08x", cpustate->sArmRegister[ 4] ); break;
1602      case CPUINFO_STR_REGISTER + ARM32_R5:   sprintf( info->s, "R5  :%08x", cpustate->sArmRegister[ 5] ); break;
1603      case CPUINFO_STR_REGISTER + ARM32_R6:   sprintf( info->s, "R6  :%08x", cpustate->sArmRegister[ 6] ); break;
1604      case CPUINFO_STR_REGISTER + ARM32_R7:   sprintf( info->s, "R7  :%08x", cpustate->sArmRegister[ 7] ); break;
1605      case CPUINFO_STR_REGISTER + ARM32_R8:   sprintf( info->s, "R8  :%08x", cpustate->sArmRegister[ 8] ); break;
1606      case CPUINFO_STR_REGISTER + ARM32_R9:   sprintf( info->s, "R9  :%08x", cpustate->sArmRegister[ 9] ); break;
1607      case CPUINFO_STR_REGISTER + ARM32_R10:  sprintf( info->s, "R10 :%08x", cpustate->sArmRegister[10] ); break;
1608      case CPUINFO_STR_REGISTER + ARM32_R11:  sprintf( info->s, "R11 :%08x", cpustate->sArmRegister[11] ); break;
1609      case CPUINFO_STR_REGISTER + ARM32_R12:  sprintf( info->s, "R12 :%08x", cpustate->sArmRegister[12] ); break;
1610      case CPUINFO_STR_REGISTER + ARM32_R13:  sprintf( info->s, "R13 :%08x", cpustate->sArmRegister[13] ); break;
1611      case CPUINFO_STR_REGISTER + ARM32_R14:  sprintf( info->s, "R14 :%08x", cpustate->sArmRegister[14] ); break;
1612      case CPUINFO_STR_REGISTER + ARM32_R15:  sprintf( info->s, "R15 :%08x", cpustate->sArmRegister[15] ); break;
1613      case CPUINFO_STR_REGISTER + ARM32_FR8:  sprintf( info->s, "FR8 :%08x", cpustate->sArmRegister[eR8_FIQ] ); break;
1614      case CPUINFO_STR_REGISTER + ARM32_FR9:  sprintf( info->s, "FR9 :%08x", cpustate->sArmRegister[eR9_FIQ] ); break;
1615      case CPUINFO_STR_REGISTER + ARM32_FR10: sprintf( info->s, "FR10:%08x", cpustate->sArmRegister[eR10_FIQ] ); break;
1616      case CPUINFO_STR_REGISTER + ARM32_FR11: sprintf( info->s, "FR11:%08x", cpustate->sArmRegister[eR11_FIQ]); break;
1617      case CPUINFO_STR_REGISTER + ARM32_FR12: sprintf( info->s, "FR12:%08x", cpustate->sArmRegister[eR12_FIQ] ); break;
1618      case CPUINFO_STR_REGISTER + ARM32_FR13: sprintf( info->s, "FR13:%08x", cpustate->sArmRegister[eR13_FIQ] ); break;
1619      case CPUINFO_STR_REGISTER + ARM32_FR14: sprintf( info->s, "FR14:%08x", cpustate->sArmRegister[eR14_FIQ] ); break;
1620      case CPUINFO_STR_REGISTER + ARM32_IR13: sprintf( info->s, "IR13:%08x", cpustate->sArmRegister[eR13_IRQ] ); break;
1621      case CPUINFO_STR_REGISTER + ARM32_IR14: sprintf( info->s, "IR14:%08x", cpustate->sArmRegister[eR14_IRQ] ); break;
1622      case CPUINFO_STR_REGISTER + ARM32_SR13: sprintf( info->s, "SR13:%08x", cpustate->sArmRegister[eR13_SVC] ); break;
1623      case CPUINFO_STR_REGISTER + ARM32_SR14: sprintf( info->s, "SR14:%08x", cpustate->sArmRegister[eR14_SVC] ); break;
1624   }
1475   extern CPU_DISASSEMBLE( arm_be );
1476   return CPU_DISASSEMBLE_NAME(arm_be)(this, buffer, pc, oprom, opram, options);
16251477}
16261478
1627
1628CPU_GET_INFO( arm_be )
1629{
1630   switch (state)
1631   {
1632      /* --- the following bits of info are returned as 64-bit signed integers --- */
1633      case CPUINFO_INT_ENDIANNESS:                    info->i = ENDIANNESS_BIG;                           break;
1634
1635      /* --- the following bits of info are returned as pointers to data or functions --- */
1636      case CPUINFO_FCT_INIT:                          info->init = CPU_INIT_NAME(arm_be);                 break;
1637      case CPUINFO_FCT_DISASSEMBLE:                   info->disassemble = CPU_DISASSEMBLE_NAME(arm_be);   break;
1638
1639      /* --- the following bits of info are returned as NULL-terminated strings --- */
1640      case CPUINFO_STR_NAME:                          strcpy(info->s, "ARM (big endian)");                break;
1641
1642      default:                                        CPU_GET_INFO_CALL(arm);                             break;
1643   }
1644}
1645
1646
1647DEFINE_LEGACY_CPU_DEVICE(ARM, arm);
1648DEFINE_LEGACY_CPU_DEVICE(ARM_BE, arm_be);

Previous 199869 Revisions Next


© 1997-2024 The MAME Team