From 3b09e634ac724df04ddefc8208617bae74578d41 Mon Sep 17 00:00:00 2001 From: "R. Belmont" Date: Tue, 21 Jul 2009 01:18:50 +0000 Subject: [PATCH] ARM7 updates: - Preliminary PXA255 support, including Intel-specific CP14 - Hooked up TLB --- src/emu/cpu/arm7/arm7.c | 208 +++++++++++++++++++++++++++++++++--- src/emu/cpu/arm7/arm7.h | 3 + src/emu/cpu/arm7/arm7core.c | 36 +++++-- src/emu/cpu/arm7/arm7core.h | 4 + src/emu/cpu/arm7/arm7exec.c | 14 ++- src/mame/drivers/39in1.c | 41 ++----- 6 files changed, 249 insertions(+), 57 deletions(-) diff --git a/src/emu/cpu/arm7/arm7.c b/src/emu/cpu/arm7/arm7.c index 816e4868772..51206cd0a40 100644 --- a/src/emu/cpu/arm7/arm7.c +++ b/src/emu/cpu/arm7/arm7.c @@ -38,8 +38,11 @@ #include "debugger.h" #include "arm7core.h" //include arm7 core -/* Example for showing how Co-Proc functions work */ -#define TEST_COPROC_FUNCS 1 +#if 0 +#define LOG(x) mame_printf_debug x +#else +#define LOG(x) logerror x +#endif /* prototypes of coprocessor functions */ static WRITE32_DEVICE_HANDLER(arm7_do_callback); @@ -69,7 +72,7 @@ INLINE arm_state *get_safe_token(const device_config *device) assert(device != NULL); assert(device->token != NULL); assert(device->type == CPU); - assert(cpu_get_type(device) == CPU_ARM7 || cpu_get_type(device) == CPU_ARM9); + assert(cpu_get_type(device) == CPU_ARM7 || cpu_get_type(device) == CPU_ARM9 || cpu_get_type(device) == CPU_PXA255); return (arm_state *)device->token; } @@ -89,6 +92,115 @@ INLINE INT64 saturate_qbit_overflow(arm_state *cpustate, INT64 res) return res; } +/************************************************************************** + * ARM TLB IMPLEMENTATION + **************************************************************************/ + +enum +{ + TLB_COARSE = 0, + TLB_FINE, +}; + +INLINE UINT32 arm7_tlb_get_first_level_descriptor( arm_state *cpustate, UINT32 vaddr ) +{ + UINT32 entry_paddr = ( COPRO_TLB_BASE & COPRO_TLB_BASE_MASK ) | ( ( vaddr & COPRO_TLB_VADDR_FLTI_MASK ) >> COPRO_TLB_VADDR_FLTI_MASK_SHIFT ); + return memory_read_dword_32le( cpustate->program, entry_paddr ); +} + +INLINE UINT32 arm7_tlb_get_second_level_descriptor( arm_state *cpustate, UINT32 granularity, UINT32 first_desc, UINT32 vaddr ) +{ + UINT32 desc_lvl2 = vaddr; + + switch( granularity ) + { + case TLB_COARSE: + desc_lvl2 = ( first_desc & COPRO_TLB_CFLD_ADDR_MASK ) | ( ( vaddr & COPRO_TLB_VADDR_CSLTI_MASK ) >> COPRO_TLB_VADDR_CSLTI_MASK_SHIFT ); + break; + case TLB_FINE: + LOG( ( "ARM7: Attempting to get second-level TLB descriptor of fine granularity\n" ) ); + break; + default: + // We shouldn't be here + LOG( ( "ARM7: Attempting to get second-level TLB descriptor of invalid granularity (%d)\n", granularity ) ); + break; + } + + return memory_read_dword_32le( cpustate->program, desc_lvl2 ); +} + +INLINE UINT32 arm7_tlb_translate(arm_state *cpustate, UINT32 vaddr) +{ + UINT32 desc_lvl1 = arm7_tlb_get_first_level_descriptor( cpustate, vaddr ); + UINT32 desc_lvl2 = 0; + UINT32 paddr = vaddr; + + switch( desc_lvl1 & 3 ) + { + case COPRO_TLB_UNMAPPED: + // Unmapped, generate a translation fault + LOG( ( "ARM7: Not Yet Implemented: Translation fault on unmapped virtual address, PC = %08x, vaddr = %08x\n", R15, vaddr ) ); + break; + case COPRO_TLB_COARSE_TABLE: + // Entry is the physical address of a coarse second-level table + desc_lvl2 = arm7_tlb_get_second_level_descriptor( cpustate, TLB_COARSE, desc_lvl1, vaddr ); + break; + case COPRO_TLB_SECTION_TABLE: + // Entry is a section + paddr = ( desc_lvl1 & COPRO_TLB_SECTION_PAGE_MASK ) | ( vaddr & ~COPRO_TLB_SECTION_PAGE_MASK ); + break; + case COPRO_TLB_FINE_TABLE: + // Entry is the physical address of a fine second-level table + LOG( ( "ARM7: Not Yet Implemented: fine second-level TLB lookup, PC = %08x, vaddr = %08x\n", R15, vaddr ) ); + break; + default: + // Entry is the physical address of a three-legged termite-eaten table + break; + } + + if( ( desc_lvl1 & 3 ) == COPRO_TLB_COARSE_TABLE || ( desc_lvl1 & 3 ) == COPRO_TLB_FINE_TABLE ) + { + switch( desc_lvl2 & 3 ) + { + case COPRO_TLB_UNMAPPED: + // Unmapped, generate a translation fault + LOG( ( "ARM7: Not Yet Implemented: Translation fault on unmapped virtual address, vaddr = %08x\n", vaddr ) ); + break; + case COPRO_TLB_LARGE_PAGE: + // Large page descriptor + paddr = ( desc_lvl2 & COPRO_TLB_LARGE_PAGE_MASK ) | ( vaddr & ~COPRO_TLB_LARGE_PAGE_MASK ); + break; + case COPRO_TLB_SMALL_PAGE: + // Small page descriptor + paddr = ( desc_lvl2 & COPRO_TLB_SMALL_PAGE_MASK ) | ( vaddr & ~COPRO_TLB_SMALL_PAGE_MASK ); + break; + case COPRO_TLB_TINY_PAGE: + // Tiny page descriptor + if( ( desc_lvl1 & 3 ) == 1 ) + { + LOG( ( "ARM7: It would appear that we're looking up a tiny page from a coarse TLB lookup. This is bad. vaddr = %08x\n", vaddr ) ); + } + paddr = ( desc_lvl2 & COPRO_TLB_TINY_PAGE_MASK ) | ( vaddr & ~COPRO_TLB_TINY_PAGE_MASK ); + break; + } + } + + return paddr; +} + +static CPU_TRANSLATE( arm7 ) +{ + arm_state *cpustate = (device != NULL) ? device->token : NULL; + + /* only applies to the program address space and only does something if the MMU's enabled */ + if( space == ADDRESS_SPACE_PROGRAM && ( COPRO_CTRL & COPRO_CTRL_MMU_EN ) ) + { + *address = arm7_tlb_translate(cpustate, *address); + } + return TRUE; +} + + /* include the arm7 core */ #include "arm7core.c" @@ -130,10 +242,21 @@ static CPU_RESET( arm9 ) arm_state *cpustate = device->token; // must call core reset - cpustate->archRev = 5; // ARMv5 - cpustate->archFlags = eARM_ARCHFLAGS_T; // has Thumb - arm7_core_reset(device); + + cpustate->archRev = 5; // ARMv5 + cpustate->archFlags = eARM_ARCHFLAGS_T | eARM_ARCHFLAGS_E; // has TE extensions +} + +static CPU_RESET( pxa255 ) +{ + arm_state *cpustate = device->token; + + // must call core reset + arm7_core_reset(device); + + cpustate->archRev = 5; // ARMv5 + cpustate->archFlags = eARM_ARCHFLAGS_T | eARM_ARCHFLAGS_E | eARM_ARCHFLAGS_XSCALE; // has TE and XScale extensions } static CPU_EXIT( arm7 ) @@ -348,6 +471,7 @@ CPU_GET_INFO( arm7 ) case CPUINFO_FCT_BURN: info->burn = NULL; break; case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(arm7); break; case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &ARM7_ICOUNT; break; + case CPUINFO_FCT_TRANSLATE: info->translate = CPU_TRANSLATE_NAME(arm7); break; /* --- the following bits of info are returned as NULL-terminated strings --- */ case DEVINFO_STR_NAME: strcpy(info->s, "ARM7"); break; @@ -431,9 +555,18 @@ CPU_GET_INFO( arm9 ) } } -/* ARM system coprocessor support */ +CPU_GET_INFO( pxa255 ) +{ + switch (state) + { + case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(pxa255); break; + case DEVINFO_STR_NAME: strcpy(info->s, "PXA255"); break; + default: CPU_GET_INFO_CALL(arm7); + break; + } +} -#define LOG(x) logerror x +/* ARM system coprocessor support */ static WRITE32_DEVICE_HANDLER( arm7_do_callback ) { @@ -446,8 +579,42 @@ static READ32_DEVICE_HANDLER( arm7_rt_r_callback ) UINT8 cReg = ( opcode & INSN_COPRO_CREG ) >> INSN_COPRO_CREG_SHIFT; UINT8 op2 = ( opcode & INSN_COPRO_OP2 ) >> INSN_COPRO_OP2_SHIFT; UINT8 op3 = opcode & INSN_COPRO_OP3; + UINT8 cpnum = (opcode & INSN_COPRO_CPNUM) >> INSN_COPRO_CPNUM_SHIFT; UINT32 data = 0; +// printf("cpnum %d cReg %d op2 %d op3 %d (%x)\n", cpnum, cReg, op2, op3, GET_REGISTER(cpustate, 15)); + + // we only handle system copro here + if (cpnum != 15) + { + if (cpustate->archFlags & eARM_ARCHFLAGS_XSCALE) + { + // handle XScale specific CP14 + if (cpnum == 14) + { + switch( cReg ) + { + case 1: // clock counter + data = (UINT32)cpu_get_total_cycles(device); + break; + + default: + break; + } + } + else + { + fatalerror("XScale: Unhandled coprocessor %d (archFlags %x)\n", cpnum, cpustate->archFlags); + } + + return data; + } + else + { + fatalerror("ARM7: Unhandled coprocessor %d (archFlags %x)\n", cpnum, cpustate->archFlags); + } + } + switch( cReg ) { case 4: @@ -517,11 +684,9 @@ static READ32_DEVICE_HANDLER( arm7_rt_r_callback ) LOG( ( "arm7_rt_r_callback, ID\n" ) ); break; case 1: // Control - LOG( ( "arm7_rt_r_callback, Control\n" ) ); - data = COPRO_CTRL; + data = COPRO_CTRL | 0x70; // bits 4-6 always read back as "1" (bit 3 too in XScale) break; case 2: // Translation Table Base - LOG( ( "arm7_rt_r_callback, TLB Base\n" ) ); data = COPRO_TLB_BASE; break; case 3: // Domain Access Control @@ -557,7 +722,22 @@ static WRITE32_DEVICE_HANDLER( arm7_rt_w_callback ) UINT8 cReg = ( opcode & INSN_COPRO_CREG ) >> INSN_COPRO_CREG_SHIFT; UINT8 op2 = ( opcode & INSN_COPRO_OP2 ) >> INSN_COPRO_OP2_SHIFT; UINT8 op3 = opcode & INSN_COPRO_OP3; + UINT8 cpnum = (opcode & INSN_COPRO_CPNUM) >> INSN_COPRO_CPNUM_SHIFT; + // handle XScale specific CP14 - just eat writes for now + if (cpnum != 15) + { + if (cpnum == 14) + { + LOG( ("arm7_rt_w_callback: write %x to XScale CP14 reg %d\n", data, cReg) ); + return; + } + else + { + fatalerror("ARM7: Unhandled coprocessor %d\n", cpnum); + } + } + switch( cReg ) { case 0: @@ -581,10 +761,6 @@ static WRITE32_DEVICE_HANDLER( arm7_rt_w_callback ) ( data & COPRO_CTRL_ICACHE_EN ) >> COPRO_CTRL_ICACHE_EN_SHIFT ) ); LOG( ( " Int Vector Adjust:%d\n", ( data & COPRO_CTRL_INTVEC_ADJUST ) >> COPRO_CTRL_INTVEC_ADJUST_SHIFT ) ); COPRO_CTRL = data & COPRO_CTRL_MASK; - if( COPRO_CTRL & COPRO_CTRL_MMU_EN ) - { -// change_pc(arm7_tlb_translate(R15)); - } break; case 2: // Translation Table Base LOG( ( "arm7_rt_w_callback TLB Base = %08x (%d) (%d)\n", data, op2, op3 ) ); @@ -600,7 +776,7 @@ static WRITE32_DEVICE_HANDLER( arm7_rt_w_callback ) LOG( ( "arm7_rt_w_callback Fault Address = %08x (%d) (%d)\n", data, op2, op3 ) ); break; case 7: // Cache Operations - LOG( ( "arm7_rt_w_callback Cache Ops = %08x (%d) (%d)\n", data, op2, op3 ) ); +// LOG( ( "arm7_rt_w_callback Cache Ops = %08x (%d) (%d)\n", data, op2, op3 ) ); break; case 8: // TLB Operations LOG( ( "arm7_rt_w_callback TLB Ops = %08x (%d) (%d)\n", data, op2, op3 ) ); diff --git a/src/emu/cpu/arm7/arm7.h b/src/emu/cpu/arm7/arm7.h index 5fa7eb37311..99da16bb5a1 100644 --- a/src/emu/cpu/arm7/arm7.h +++ b/src/emu/cpu/arm7/arm7.h @@ -44,4 +44,7 @@ extern CPU_GET_INFO( arm7 ); extern CPU_GET_INFO( arm9 ); #define CPU_ARM9 CPU_GET_INFO_NAME( arm9 ) +extern CPU_GET_INFO( pxa255 ); +#define CPU_PXA255 CPU_GET_INFO_NAME( pxa255 ) + #endif /* __ARM7_H__ */ diff --git a/src/emu/cpu/arm7/arm7core.c b/src/emu/cpu/arm7/arm7core.c index 50ee155b066..2a05d01541c 100644 --- a/src/emu/cpu/arm7/arm7core.c +++ b/src/emu/cpu/arm7/arm7core.c @@ -81,12 +81,6 @@ #define ARM7_DEBUG_CORE 0 -#if 0 -#define LOG(x) mame_printf_debug x -#else -#define LOG(x) logerror x -#endif - /* Prototypes */ // SJE: should these be inline? or are they too big to see any benefit? @@ -137,6 +131,11 @@ char *(*arm7_dasm_cop_do_callback)(arm_state *cpustate, char *pBuf, UINT32 opcod ***************************************************************************/ INLINE void arm7_cpu_write32(arm_state *cpustate, UINT32 addr, UINT32 data) { + if( COPRO_CTRL & COPRO_CTRL_MMU_EN ) + { + addr = arm7_tlb_translate( cpustate, addr ); + } + addr &= ~3; memory_write_dword_32le(cpustate->program, addr, data); } @@ -144,12 +143,22 @@ INLINE void arm7_cpu_write32(arm_state *cpustate, UINT32 addr, UINT32 data) INLINE void arm7_cpu_write16(arm_state *cpustate, UINT32 addr, UINT16 data) { + if( COPRO_CTRL & COPRO_CTRL_MMU_EN ) + { + addr = arm7_tlb_translate( cpustate, addr ); + } + addr &= ~1; memory_write_word_32le(cpustate->program, addr, data); } INLINE void arm7_cpu_write8(arm_state *cpustate, UINT32 addr, UINT8 data) { + if( COPRO_CTRL & COPRO_CTRL_MMU_EN ) + { + addr = arm7_tlb_translate( cpustate, addr ); + } + memory_write_byte_32le(cpustate->program, addr, data); } @@ -157,6 +166,11 @@ INLINE UINT32 arm7_cpu_read32(arm_state *cpustate, offs_t addr) { UINT32 result; + if( COPRO_CTRL & COPRO_CTRL_MMU_EN ) + { + addr = arm7_tlb_translate( cpustate, addr ); + } + if (addr & 3) { result = memory_read_dword_32le(cpustate->program, addr & ~3); @@ -174,6 +188,11 @@ INLINE UINT16 arm7_cpu_read16(arm_state *cpustate, offs_t addr) { UINT16 result; + if( COPRO_CTRL & COPRO_CTRL_MMU_EN ) + { + addr = arm7_tlb_translate( cpustate, addr ); + } + result = memory_read_word_32le(cpustate->program, addr & ~1); if (addr & 1) @@ -186,6 +205,11 @@ INLINE UINT16 arm7_cpu_read16(arm_state *cpustate, offs_t addr) INLINE UINT8 arm7_cpu_read8(arm_state *cpustate, offs_t addr) { + if( COPRO_CTRL & COPRO_CTRL_MMU_EN ) + { + addr = arm7_tlb_translate( cpustate, addr ); + } + // Handle through normal 8 bit handler (for 32 bit cpu) return memory_read_byte_32le(cpustate->program, addr); } diff --git a/src/emu/cpu/arm7/arm7core.h b/src/emu/cpu/arm7/arm7core.h index 6edd511f065..51607ea64e6 100644 --- a/src/emu/cpu/arm7/arm7core.h +++ b/src/emu/cpu/arm7/arm7core.h @@ -148,6 +148,8 @@ enum eARM_ARCHFLAGS_E = 2, // extended DSP operations present (only for v5+) eARM_ARCHFLAGS_J = 4, // "Jazelle" (direct execution of Java bytecode) eARM_ARCHFLAGS_MMU = 8, // has on-board MMU (traditional ARM style like the SA1110) + eARM_ARCHFLAGS_SA = 16, // StrongARM extensions (enhanced TLB) + eARM_ARCHFLAGS_XSCALE = 32, // XScale extensions (CP14, enhanced TLB) }; #define ARM7CORE_REGS \ @@ -350,11 +352,13 @@ static const int sRegisterTable[ARM7_NUM_MODES][18] = #define INSN_COPRO_N ((UINT32) 0x00100000u) #define INSN_COPRO_CREG ((UINT32) 0x000f0000u) #define INSN_COPRO_AREG ((UINT32) 0x0000f000u) +#define INSN_COPRO_CPNUM ((UINT32) 0x00000f00u) #define INSN_COPRO_OP2 ((UINT32) 0x000000e0u) #define INSN_COPRO_OP3 ((UINT32) 0x0000000fu) #define INSN_COPRO_N_SHIFT 20 #define INSN_COPRO_CREG_SHIFT 16 #define INSN_COPRO_AREG_SHIFT 12 +#define INSN_COPRO_CPNUM_SHIFT 8 #define INSN_COPRO_OP2_SHIFT 5 #define THUMB_INSN_TYPE ((UINT16)0xf000) diff --git a/src/emu/cpu/arm7/arm7exec.c b/src/emu/cpu/arm7/arm7exec.c index 9170f813623..6e4412e0640 100644 --- a/src/emu/cpu/arm7/arm7exec.c +++ b/src/emu/cpu/arm7/arm7exec.c @@ -53,13 +53,17 @@ /* handle Thumb instructions if active */ if (T_IS_SET(GET_CPSR)) { - UINT32 readword; - UINT32 addr; + UINT32 readword, addr, raddr; UINT32 rm, rn, rs, rd, op2, imm, rrs, rrd; INT32 offs; pc = R15; - insn = memory_decrypted_read_word(cpustate->program, pc & (~1)); + raddr = pc & (~1); + if ( COPRO_CTRL & COPRO_CTRL_MMU_EN ) + { + raddr = arm7_tlb_translate(cpustate, raddr); + } + insn = memory_decrypted_read_word(cpustate->program, raddr); ARM7_ICOUNT -= (3 - thumbCycles[insn >> 8]); switch ((insn & THUMB_INSN_TYPE) >> THUMB_INSN_TYPE_SHIFT) { @@ -1165,6 +1169,10 @@ /* load 32 bit instruction */ pc = R15; + if ( COPRO_CTRL & COPRO_CTRL_MMU_EN ) + { + pc = arm7_tlb_translate(cpustate, pc); + } insn = memory_decrypted_read_dword(cpustate->program, pc); /* process condition codes for this instruction */ diff --git a/src/mame/drivers/39in1.c b/src/mame/drivers/39in1.c index 46602323e21..0df0954e271 100644 --- a/src/mame/drivers/39in1.c +++ b/src/mame/drivers/39in1.c @@ -15,8 +15,7 @@ * PCB also contains a custom ASIC, probably used for the decryption * * TODO: - * Figure out weird memory test subroutine at 1c8 - * PXA255 MMU and peripherals + * PXA255 peripherals * **************************************************************************/ @@ -37,9 +36,16 @@ static READ32_HANDLER( os_timer_counter_r ) return ret; } +// intel docs says nothing's here, but code at e4010 begs to differ +static READ32_HANDLER( unknown_r ) +{ + return 2; // TST #$2 +} + static ADDRESS_MAP_START( 39in1_map, ADDRESS_SPACE_PROGRAM, 32 ) AM_RANGE(0x00000000, 0x0007ffff) AM_ROM AM_RANGE(0x40a00010, 0x40a00013) AM_READ( os_timer_counter_r ) + AM_RANGE(0x40e00000, 0x40e00003) AM_READ( unknown_r ) AM_RANGE(0xa0000000, 0xa3ffffff) AM_RAM ADDRESS_MAP_END @@ -65,7 +71,7 @@ static MACHINE_START(39in1) } static MACHINE_DRIVER_START( 39in1 ) - MDRV_CPU_ADD("maincpu", ARM9, 200000000) // actually Xscale PXA255, but ARM9 is a compatible subset + MDRV_CPU_ADD("maincpu", PXA255, 200000000) MDRV_CPU_PROGRAM_MAP(39in1_map) MDRV_PALETTE_LENGTH(32768) @@ -92,32 +98,3 @@ ROM_START( 39in1 ) ROM_END GAME(2004, 39in1, 0, 39in1, 39in1, 0, ROT0, "????", "39 in 1 MAME bootleg", GAME_NOT_WORKING|GAME_NO_SOUND) - -/* - -cpu #0 (PC=00000010): unmapped program memory dword write to 40E00024 = FFFFFFFF & FFFFFFFF GPIO pin output clear 31:0 -cpu #0 (PC=00000014): unmapped program memory dword write to 40E00028 = FFFFFFFF & FFFFFFFF 63:32 -cpu #0 (PC=00000018): unmapped program memory dword write to 40E0002C = FFFFFFFF & FFFFFFFF 80:64 -cpu #0 (PC=00000028): unmapped program memory dword write to 40E00018 = 01008000 & FFFFFFFF GPIO pin direction register 63:32 -cpu #0 (PC=0000002C): unmapped program memory dword write to 40E0001C = 00020802 & FFFFFFFF pin output set 63:32 -cpu #0 (PC=00000030): unmapped program memory dword write to 40E00020 = 0001CC00 & FFFFFFFF 80:64 -cpu #0 (PC=00000040): unmapped program memory dword write to 40E0000C = DFE3FFDC & FFFFFFFF GPIO pin direction 31:0 -cpu #0 (PC=00000044): unmapped program memory dword write to 40E00010 = FC9FAF83 & FFFFFFFF 63:32 -cpu #0 (PC=00000048): unmapped program memory dword write to 40E00014 = 0001FFFF & FFFFFFFF -cpu #0 (PC=00000064): unmapped program memory dword write to 40E00054 = 80000000 & FFFFFFFF GPIO alternate function -cpu #0 (PC=00000068): unmapped program memory dword write to 40E00058 = 59000110 & FFFFFFFF -cpu #0 (PC=0000006C): unmapped program memory dword write to 40E0005C = 600A9559 & FFFFFFFF -cpu #0 (PC=00000070): unmapped program memory dword write to 40E00060 = AAA00008 & FFFFFFFF -cpu #0 (PC=00000074): unmapped program memory dword write to 40E00064 = AAAAAAAA & FFFFFFFF -cpu #0 (PC=00000078): unmapped program memory dword write to 40E00068 = 00000002 & FFFFFFFF -cpu #0 (PC=00000084): unmapped program memory dword write to 40F00004 = 00000020 & FFFFFFFF power manager sleep status -test_rt_r_callback opcode=ee160e10 -test_rt_w_callback opcode=ee060e10, data from ARM7 register=2 -cpu #0 (PC=0000009C): unmapped program memory dword write to 41300000 = 00000141 & FFFFFFFF core clock configure (multiplier=27, RAM is 99.53 MHz + multiplier = 2 * memory + turbo = 1x) -test_rt_w_callback opcode=ee060e10, data from ARM7 register=3 -test_rt_w_callback opcode=ee060e10, data from ARM7 register=1 -cpu #0 (PC=000000B4): unmapped program memory dword read from 40A00010 & FFFFFFFF OS timer/counter -cpu #0 (PC=000000B8): unmapped program memory dword read from 40A00010 & FFFFFFFF -cpu #0 (PC=000000B8): unmapped program memory dword read from 40A00010 & FFFFFFFF - -*/