diff options
author | Mike Pavone <pavone@retrodev.com> | 2012-11-09 22:01:26 -0800 |
---|---|---|
committer | Mike Pavone <pavone@retrodev.com> | 2012-11-09 22:01:26 -0800 |
commit | 65d97a68e119dc25d125594d64a4888d9e4d878a (patch) | |
tree | cf0e2e62acfdf408e36da4e6bef3f89837226c58 /68kinst.c | |
parent | ea4e49497845a870343d2944f3ab519f375b3bd2 (diff) |
Finish bit/movep/immediate group except for 68020 instructions
Diffstat (limited to '68kinst.c')
-rw-r--r-- | 68kinst.c | 236 |
1 files changed, 126 insertions, 110 deletions
@@ -124,6 +124,11 @@ uint16_t * m68K_decode(uint16_t * istream, m68kinst * decoded) decoded->src.addr_mode = MODE_REG; decoded->src.params.regs.pri = m68K_reg_quick_field(*istream); istream = m68k_decode_op(istream, OPSIZE_LONG, &(decoded->dst)); + } else if ((*istream & 0xF00) == 0x800) { + } else if ((*istream & 0xC0) == 0xC0) { +#ifdef M68020 + //CMP2, CHK2, CAS, CAS2, RTM, CALLM +#endif } else { switch ((*istream >> 9) & 0x7) { @@ -139,79 +144,8 @@ uint16_t * m68K_decode(uint16_t * istream, m68kinst * decoded) decoded->src.addr_mode = MODE_IMMEDIATE; decoded->src.params.u16 = *(++istream); } else { - //ORI, CMP2.b, CHK2.b - if ((*istream & 0xC0) != 0xC0) { - decoded->op = M68K_OR; - decoded->src.addr_mode = MODE_IMMEDIATE; - decoded->extra.size = size = (*istream >> 6) & 3; - reg = *istream & 0x7; - opmode = (*istream >> 3) & 0x7; - switch (size) - { - case OPSIZE_BYTE: - decoded->src.params.u8 = *(++istream); - break; - case OPSIZE_WORD: - decoded->src.params.16 = *(++istream); - break; - case OPSIZE_LONG: - immed = *(++istream); - decoded->src.params.u32 = immed << 16 | *(++istream); - break; - } - istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); - } else { - #ifdef M68020 - //TODO: Implement me for 68020 support - #endif - } - } - break; - case 1: - //ANDI, ANDI to CCR, ANDI to SR, CMP2.w CHK2.w - if ((*istream & 0xFF) == 0x3C) { - decoded->op = M68K_ANDI_CCR; - decoded->extra.size = OPSIZE_BYTE; - decoded->src.addr_mode = MODE_IMMEDIATE; - decoded->src.params.u8 = *(++istream); - } else if((*istream & 0xFF) == 0x7C) { - decoded->op = M68K_ANDI_SR; - decoded->extra.size = OPSIZE_WORD; - decoded->src.addr_mode = MODE_IMMEDIATE; - decoded->src.params.u16 = *(++istream); - } else { - //ANDI, CMP2.w, CHK2.w - if ((*istream & 0xC0) != 0xC0) { - decoded->op = M68K_AND; - decoded->src.addr_mode = MODE_IMMEDIATE; - decoded->extra.size = size = (*istream >> 6) & 3; - reg = *istream & 0x7; - opmode = (*istream >> 3) & 0x7; - switch (size) - { - case OPSIZE_BYTE: - decoded->src.params.u8 = *(++istream); - break; - case OPSIZE_WORD: - decoded->src.params.16 = *(++istream); - break; - case OPSIZE_LONG: - immed = *(++istream); - decoded->src.params.u32 = immed << 16 | *(++istream); - break; - } - istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); - } else { - #ifdef M68020 - //TODO: Implement me for 68020 support - #endif - } - } - break; - case 2: - //SUBI, CMP2.l, CHK2.l - if ((*istream & 0xC0) != 0xC0) { - decoded->op = M68K_SUB; + decoded->op = M68K_OR; + decoded->variant = VAR_IMMEDIATE; decoded->src.addr_mode = MODE_IMMEDIATE; decoded->extra.size = size = (*istream >> 6) & 3; reg = *istream & 0x7; @@ -222,7 +156,7 @@ uint16_t * m68K_decode(uint16_t * istream, m68kinst * decoded) decoded->src.params.u8 = *(++istream); break; case OPSIZE_WORD: - decoded->src.params.16 = *(++istream); + decoded->src.params.u16 = *(++istream); break; case OPSIZE_LONG: immed = *(++istream); @@ -230,16 +164,23 @@ uint16_t * m68K_decode(uint16_t * istream, m68kinst * decoded) break; } istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); - } else { - #ifdef M68020 - //TODO: Implement me for 68020 support - #endif } break; - case 3: - //RTM, CALLM, ADDI - if ((*istream & 0xC0) != 0xC0) { - decoded->op = M68K_ADD; + case 1: + //ANDI, ANDI to CCR, ANDI to SR + if ((*istream & 0xFF) == 0x3C) { + decoded->op = M68K_ANDI_CCR; + decoded->extra.size = OPSIZE_BYTE; + decoded->src.addr_mode = MODE_IMMEDIATE; + decoded->src.params.u8 = *(++istream); + } else if((*istream & 0xFF) == 0x7C) { + decoded->op = M68K_ANDI_SR; + decoded->extra.size = OPSIZE_WORD; + decoded->src.addr_mode = MODE_IMMEDIATE; + decoded->src.params.u16 = *(++istream); + } else { + decoded->op = M68K_AND; + decoded->variant = VAR_IMMEDIATE; decoded->src.addr_mode = MODE_IMMEDIATE; decoded->extra.size = size = (*istream >> 6) & 3; reg = *istream & 0x7; @@ -250,7 +191,7 @@ uint16_t * m68K_decode(uint16_t * istream, m68kinst * decoded) decoded->src.params.u8 = *(++istream); break; case OPSIZE_WORD: - decoded->src.params.16 = *(++istream); + decoded->src.params.u16 = *(++istream); break; case OPSIZE_LONG: immed = *(++istream); @@ -258,12 +199,52 @@ uint16_t * m68K_decode(uint16_t * istream, m68kinst * decoded) break; } istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); - } else { - #ifdef M68020 - //TODO: Implement me for 68020 support - #endif } break; + case 2: + decoded->op = M68K_SUB; + decoded->variant = VAR_IMMEDIATE; + decoded->src.addr_mode = MODE_IMMEDIATE; + decoded->extra.size = size = (*istream >> 6) & 3; + reg = *istream & 0x7; + opmode = (*istream >> 3) & 0x7; + switch (size) + { + case OPSIZE_BYTE: + decoded->src.params.u8 = *(++istream); + break; + case OPSIZE_WORD: + decoded->src.params.u16 = *(++istream); + break; + case OPSIZE_LONG: + immed = *(++istream); + decoded->src.params.u32 = immed << 16 | *(++istream); + break; + } + istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); + break; + case 3: + decoded->op = M68K_ADD; + decoded->variant = VAR_IMMEDIATE; + decoded->src.addr_mode = MODE_IMMEDIATE; + decoded->extra.size = size = (*istream >> 6) & 3; + reg = *istream & 0x7; + opmode = (*istream >> 3) & 0x7; + switch (size) + { + case OPSIZE_BYTE: + decoded->src.params.u8 = *(++istream); + break; + case OPSIZE_WORD: + decoded->src.params.u16 = *(++istream); + break; + case OPSIZE_LONG: + immed = *(++istream); + decoded->src.params.u32 = immed << 16 | *(++istream); + break; + } + istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); + break; case 4: //BTST, BCHG, BCLR, BSET switch ((*istream >> 6) & 0x3) @@ -298,34 +279,69 @@ uint16_t * m68K_decode(uint16_t * istream, m68kinst * decoded) decoded->src.addr_mode = MODE_IMMEDIATE; decoded->src.params.u16 = *(++istream); } else { - //EORI, CMP2.w, CHK2.w - if ((*istream & 0xC0) != 0xC0) { - decoded->op = M68K_EOR; - decoded->src.addr_mode = MODE_IMMEDIATE; - decoded->extra.size = size = (*istream >> 6) & 3; - reg = *istream & 0x7; - opmode = (*istream >> 3) & 0x7; - switch (size) - { - case OPSIZE_BYTE: - decoded->src.params.u8 = *(++istream); - break; - case OPSIZE_WORD: - decoded->src.params.16 = *(++istream); - break; - case OPSIZE_LONG: - immed = *(++istream); - decoded->src.params.u32 = immed << 16 | *(++istream); - break; - } - istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); + decoded->op = M68K_EOR; + decoded->variant = VAR_IMMEDIATE; + decoded->src.addr_mode = MODE_IMMEDIATE; + decoded->extra.size = size = (*istream >> 6) & 3; + reg = *istream & 0x7; + opmode = (*istream >> 3) & 0x7; + switch (size) + { + case OPSIZE_BYTE: + decoded->src.params.u8 = *(++istream); + break; + case OPSIZE_WORD: + decoded->src.params.u16 = *(++istream); + break; + case OPSIZE_LONG: + immed = *(++istream); + decoded->src.params.u32 = immed << 16 | *(++istream); + break; } + istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); } break; case 6: - + decoded->op = M68K_CMP; + decoded->variant = VAR_IMMEDIATE; + decoded->extra.size = (*istream >> 6) & 0x3; + decoded->src.addr_mode = MODE_IMMEDIATE; + reg = *istream & 0x7; + opmode = (*istream >> 3) & 0x7; + switch (decoded->extra.size) + { + case OPSIZE_BYTE: + decoded->src.params.u8 = *(++istream); + break; + case OPSIZE_WORD: + decoded->src.params.u16 = *(++istream); + break; + case OPSIZE_LONG: + immed = *(++istream); + decoded->src.params.u32 = (immed << 16) | *(++istream); + break; + } + istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); break; case 7: + //MOVEP + deocded->op = M68K_MOVEP; + decoded->extra.size = *istream & 0x40 ? OPSIZE_LONG : OPSIZE_WORD; + if (*istream & 0x80) { + //memory dest + decoded->src.addr_mode = MODE_REG; + decoded->src.params.regs.pri = m68K_reg_quick_field(*istream); + decoded->dst.addr_mode = MODE_AREG_DISPLACE; + decoded->dst.params.regs.pri = *istream & 0x7; + } else { + //memory source + decoded->dst.addr_mode = MODE_REG; + decoded->dst.params.regs.pri = m68K_reg_quick_field(*istream); + decoded->sr.addr_mode = MODE_AREG_DISPLACE; + decoded->sr.params.regs.pri = *istream & 0x7; + } + immed = *(++istream); + break; } } @@ -860,7 +876,7 @@ int m68k_disasm(m68kinst * decoded, char * dst) size = decoded->extra.size; ret = sprintf(dst, "%s%s.%c", mnemonics[decoded->op], - decoded->variant == VAR_QUICK ? "q" : "", + decoded->variant == VAR_QUICK ? "q" : (decoded->variant == VAR_IMMEDIATE ? "i" : ""), decoded->extra.size == OPSIZE_BYTE ? 'b' : (size == OPSIZE_WORD ? 'w' : 'l')); } op1len = m68K_disasm_op(&(decoded->src), size, dst + ret, 0); |