Search
lxdream.org :: lxdream :: r811:7ff871670e58
lxdream 0.9.1
released Jun 29
Download Now
changeset811:7ff871670e58
parent810:833cc4960556
child812:8cc61d5ea1f8
authornkeynes
dateWed Aug 13 10:27:49 2008 +0000 (11 years ago)
Implement LDRH/STRH/LDRSH/LDRSB instructions
src/aica/armcore.c
src/aica/armdasm.c
src/aica/armmem.c
1.1 --- a/src/aica/armcore.c Sat Aug 09 11:17:06 2008 +0000
1.2 +++ b/src/aica/armcore.c Wed Aug 13 10:27:49 2008 +0000
1.3 @@ -401,10 +401,13 @@
1.4
1.5 #define IMM8(ir) (ir&0xFF)
1.6 #define IMM12(ir) (ir&0xFFF)
1.7 +#define IMMSPLIT8(ir) (((ir&0xF00)>>4)|(ir&0x0F))
1.8 #define SHIFTIMM(ir) ((ir>>7)&0x1F)
1.9 #define IMMROT(ir) ((ir>>7)&0x1E)
1.10 #define ROTIMM12(ir) ROTATE_RIGHT_LONG(IMM8(ir),IMMROT(ir))
1.11 #define SIGNEXT24(n) (((n)&0x00800000) ? ((n)|0xFF000000) : ((n)&0x00FFFFFF))
1.12 +#define SIGNEXT8(n) ((int32_t)((int8_t)(n)))
1.13 +#define SIGNEXT16(n) ((int32_t)((int16_t)(n)))
1.14 #define SHIFT(ir) ((ir>>4)&0x07)
1.15 #define DISP24(ir) ((ir&0x00FFFFFF))
1.16 #define UNDEF(ir) do{ arm_raise_exception( EXC_UNDEFINED ); return TRUE; } while(0)
1.17 @@ -687,6 +690,72 @@
1.18 return addr;
1.19 }
1.20
1.21 +/**
1.22 + * Determine the address operand of a miscellaneous load/store instruction,
1.23 + * including applying any pre/post adjustments to the address registers.
1.24 + * @see s5.3 Addressing Mode 3 - Miscellaneous Loads and Stores
1.25 + * @param The instruction word.
1.26 + * @return The calculated address
1.27 + */
1.28 +static uint32_t arm_get_address3_operand( uint32_t ir )
1.29 +{
1.30 + uint32_t addr=0;
1.31 +
1.32 + /* x x P U x W */
1.33 + switch( (ir>>21)&0x0F ) {
1.34 + case 0: /* Rn -= Rm (post-indexed) [5.3.7 A5-48] */
1.35 + case 1: /* UNPREDICTABLE */
1.36 + addr = RN(ir);
1.37 + LRN(ir) -= RM(ir);
1.38 + break;
1.39 + case 2: /* Rn -= imm (post-indexed) [5.3.6 A5-46] */
1.40 + case 3: /* UNPREDICTABLE */
1.41 + addr = RN(ir);
1.42 + LRN(ir) -= IMMSPLIT8(ir);
1.43 + break;
1.44 + case 4: /* Rn += Rm (post-indexed) [5.3.7 A5-48] */
1.45 + case 5: /* UNPREDICTABLE */
1.46 + addr = RN(ir);
1.47 + LRN(ir) += RM(ir);
1.48 + break;
1.49 + case 6: /* Rn += imm (post-indexed) [5.3.6 A5-44] */
1.50 + case 7: /* UNPREDICTABLE */
1.51 + addr = RN(ir);
1.52 + LRN(ir) += IMMSPLIT8(ir);
1.53 + break;
1.54 + case 8: /* Rn - Rm [5.3.3 A5-38] */
1.55 + addr = RN(ir) - RM(ir);
1.56 + break;
1.57 + case 9: /* Rn -= Rm (pre-indexed) [5.3.5 A5-42] */
1.58 + addr = RN(ir) - RM(ir);
1.59 + LRN(ir) = addr;
1.60 + break;
1.61 + case 10: /* Rn - imm offset [5.3.2 A5-36] */
1.62 + addr = RN(ir) - IMMSPLIT8(ir);
1.63 + break;
1.64 + case 11: /* Rn -= imm offset (pre-indexed) [5.3.4 A5-40] */
1.65 + addr = RN(ir) - IMMSPLIT8(ir);
1.66 + LRN(ir) = addr;
1.67 + break;
1.68 + case 12: /* Rn + Rm [5.3.3 A5-38] */
1.69 + addr = RN(ir) + RM(ir);
1.70 + break;
1.71 + case 13: /* Rn += Rm (pre-indexed) [5.3.5 A5-42] */
1.72 + addr = RN(ir) + RM(ir);
1.73 + LRN(ir) = addr;
1.74 + break;
1.75 + case 14: /* Rn + imm offset [5.3.2 A5-36] */
1.76 + addr = RN(ir) + IMMSPLIT8(ir);
1.77 + break;
1.78 + case 15: /* Rn += imm offset (pre-indexed) [5.3.4 A5-40] */
1.79 + addr = RN(ir) + IMMSPLIT8(ir);
1.80 + LRN(ir) = addr;
1.81 + break;
1.82 +
1.83 + }
1.84 + return addr;
1.85 +}
1.86 +
1.87 gboolean arm_execute_instruction( void )
1.88 {
1.89 uint32_t pc;
1.90 @@ -859,26 +928,28 @@
1.91 }
1.92 break;
1.93 case 1:
1.94 - if( LFLAG(ir) ) {
1.95 - /* LDRH */
1.96 - } else {
1.97 - /* STRH */
1.98 + operand = arm_get_address3_operand(ir);
1.99 + if( LFLAG(ir) ) { /* LDRH */
1.100 + LRD(ir) = MEM_READ_WORD( operand ) & 0x0000FFFF;
1.101 + } else { /* STRH */
1.102 + MEM_WRITE_WORD( operand, RD(ir) );
1.103 }
1.104 - UNIMP(ir);
1.105 break;
1.106 case 2:
1.107 - if( LFLAG(ir) ) {
1.108 - /* LDRSB */
1.109 + if( LFLAG(ir) ) { /* LDRSB */
1.110 + operand = arm_get_address3_operand(ir);
1.111 + LRD(ir) = SIGNEXT8( MEM_READ_BYTE( operand ) );
1.112 } else {
1.113 + UNIMP(ir);
1.114 }
1.115 - UNIMP(ir);
1.116 break;
1.117 case 3:
1.118 - if( LFLAG(ir) ) {
1.119 - /* LDRSH */
1.120 + if( LFLAG(ir) ) { /* LDRSH */
1.121 + operand = arm_get_address3_operand(ir);
1.122 + LRD(ir) = SIGNEXT16( MEM_READ_WORD( operand ) );
1.123 } else {
1.124 + UNIMP(ir);
1.125 }
1.126 - UNIMP(ir);
1.127 break;
1.128 }
1.129 } else {
2.1 --- a/src/aica/armdasm.c Sat Aug 09 11:17:06 2008 +0000
2.2 +++ b/src/aica/armdasm.c Wed Aug 13 10:27:49 2008 +0000
2.3 @@ -37,6 +37,7 @@
2.4
2.5 #define IMM8(ir) (ir&0xFF)
2.6 #define IMM12(ir) (ir&0xFFF)
2.7 +#define IMMSPLIT8(ir) (((ir&0xF00)>>4)|(ir&0x0F))
2.8 #define SHIFTIMM(ir) ((ir>>7)&0x1F)
2.9 #define IMMROT(ir) ((ir>>7)&0x1E)
2.10 #define SHIFT(ir) ((ir>>4)&0x07)
2.11 @@ -186,6 +187,30 @@
2.12 }
2.13 }
2.14
2.15 +static int arm_disasm_address3_operand( uint32_t ir, char *buf, int len, int pc )
2.16 +{
2.17 + char sign = UFLAG(ir) ? '+' : '-';
2.18 +
2.19 + switch( (ir>>21) & 0x0B) {
2.20 + case 0: /* Rn -= Rm (post-indexed) [5.3.7 A5-48] */
2.21 + case 1: /* UNPREDICTABLE */
2.22 + return snprintf( buf, len, "[R%d], R%d %c= R%d", RN(ir), RN(ir), sign, RM(ir) ) ;
2.23 + case 2: /* Rn -= imm (post-indexed) [5.3.6 A5-46] */
2.24 + case 3: /* UNPREDICTABLE */
2.25 + return snprintf( buf, len, "[R%d], R%d %c= #%04Xh", RN(ir), RN(ir), sign, IMMSPLIT8(ir) );
2.26 + case 8: /* Rn - Rm [5.3.3 A5-38] */
2.27 + return snprintf( buf, len, "[R%d %c R%d]", RN(ir), sign, RM(ir) );
2.28 + case 9: /* Rn -= Rm (pre-indexed) [5.3.5 A5-42] */
2.29 + return snprintf( buf, len, "[R%d %c= R%d]", RN(ir), sign, RM(ir) );
2.30 + case 10: /* Rn - imm offset [5.3.2 A5-36] */
2.31 + return snprintf( buf, len, "[R%d %c #%04Xh]", RN(ir), sign, IMMSPLIT8(ir) );
2.32 + case 11: /* Rn -= imm offset (pre-indexed) [5.3.4 A5-40] */
2.33 + return snprintf( buf, len, "[R%d %c= #%04Xh]", RN(ir), sign, IMMSPLIT8(ir) );
2.34 + default:
2.35 + return UNIMP(ir); /* Unreachable */
2.36 + }
2.37 +}
2.38 +
2.39 uint32_t arm_disasm_instruction( uint32_t pc, char *buf, int len, char *opcode )
2.40 {
2.41 char operand[64];
2.42 @@ -278,26 +303,28 @@
2.43 }
2.44 break;
2.45 case 1:
2.46 - if( LFLAG(ir) ) {
2.47 - /* LDRH */
2.48 - } else {
2.49 - /* STRH */
2.50 + arm_disasm_address3_operand( ir, operand, sizeof(operand), pc );
2.51 + if( LFLAG(ir) ) { /* LDRH */
2.52 + snprintf(buf, len, "LDR%sH R%d, %s", cond, RD(ir), operand );
2.53 + } else { /* STRH */
2.54 + snprintf(buf, len, "STR%sH R%d, %s", cond, RD(ir), operand );
2.55 }
2.56 - UNIMP(ir);
2.57 break;
2.58 case 2:
2.59 - if( LFLAG(ir) ) {
2.60 - /* LDRSB */
2.61 + if( LFLAG(ir) ) { /* LDRSB */
2.62 + arm_disasm_address3_operand( ir, operand, sizeof(operand), pc );
2.63 + snprintf(buf, len, "LDR%sSB R%d, %s", cond, RD(ir), operand );
2.64 } else {
2.65 + UNIMP(ir);
2.66 }
2.67 - UNIMP(ir);
2.68 break;
2.69 case 3:
2.70 - if( LFLAG(ir) ) {
2.71 - /* LDRSH */
2.72 + if( LFLAG(ir) ) { /* LDRSH */
2.73 + arm_disasm_address3_operand( ir, operand, sizeof(operand), pc );
2.74 + snprintf(buf, len, "LDR%sSH R%d, %s", cond, RD(ir), operand );
2.75 } else {
2.76 + UNIMP(ir);
2.77 }
2.78 - UNIMP(ir);
2.79 break;
2.80 }
2.81 } else {
3.1 --- a/src/aica/armmem.c Sat Aug 09 11:17:06 2008 +0000
3.2 +++ b/src/aica/armmem.c Wed Aug 13 10:27:49 2008 +0000
3.3 @@ -20,6 +20,7 @@
3.4 #include "dream.h"
3.5 #include "mem.h"
3.6 #include "aica.h"
3.7 +#include "armcore.h"
3.8
3.9 unsigned char *arm_mem = NULL;
3.10 unsigned char *arm_mem_scratch = NULL;
3.11 @@ -58,8 +59,8 @@
3.12 return *(int32_t *)(arm_mem_scratch + addr - 0x00803000);
3.13 }
3.14 }
3.15 - ERROR( "Attempted long read to undefined page: %08X",
3.16 - addr );
3.17 + ERROR( "Attempted long read to undefined page: %08X at %08X",
3.18 + addr, armr.r[15] );
3.19 /* Undefined memory */
3.20 return 0;
3.21 }
3.22 @@ -119,7 +120,14 @@
3.23 return val; // Can't happen, but make gcc happy
3.24 }
3.25 }
3.26 -
3.27 +void arm_write_word( uint32_t addr, uint32_t value )
3.28 +{
3.29 + if( addr < 0x00200000 ) {
3.30 + *(uint16_t *)(arm_mem + addr) = (uint16_t)value;
3.31 + } else {
3.32 +
3.33 + }
3.34 +}
3.35 void arm_write_byte( uint32_t addr, uint32_t value )
3.36 {
3.37 if( addr < 0x00200000 ) {
.