Mercurial > repos > blastem
diff 68kinst.c @ 0:2432d177e1ac
Initial work on M68K instruction decoding
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Mon, 29 Oct 2012 01:18:38 -0700 |
parents | |
children | 5df303bf72e6 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/68kinst.c Mon Oct 29 01:18:38 2012 -0700 @@ -0,0 +1,92 @@ +#include "68kinst.h" + +void m68k_decode_op(uint16_t op, m68k_op_info *dst) +{ + uint8_t mode = (op >> 3) & 0x7; + uint8_t reg = op & 0x7; + dst->addr_mode = mode; + switch(mode) + { + case MODE_REG: + case MODE_AREG: + dst->params.regs.pri = reg; + break; + case MODE_ + } +} + +uint16_t * m68K_decode(uint16_t * istream, m68kinst * decoded) +{ + uint8_t optype = *istream >> 12; + uint8_t size; + uint8_t immed; + switch(optype) + { + case BIT_MOVEP_IMMED: + //TODO: Implement me + break; + case MOVE_BYTE: + case MOVE_LONG: + case MOVE_WORD: + decoded->op = M68K_MOVE; + decoded->extra.size = optype == MOVE_BYTE ? OPSIZE_BYTE : (optype == MOVE_WORD ? OPSIZE_WORD : OPSIZE_LONG); + m68k_decode_op(*istream, &(decoded->src)); + m68k_decode_op(((*istream >> 9) & 0x7) | , &(decoded->dst)); + break; + case MISC: + //TODO: Implement me + break; + case QUICK_ARITH_LOOP: + size = (*istream >> 6) & 3; + if (size == 0x3) { + //DBcc, TRAPcc or Scc + decoded->extra.cond = (*istream >> 0x8) & 0xF; + switch ((*istream >> 3) & 0x7) + { + case 1: //DBcc + decoded->op = M68K_DBCC; + decoded->dst.addr_mode = MODE_REG; + decoded->dst.regs.pri = *istream & 0x7; + break; + case 7: //TRAPcc + decoded->op = M68K_TRAPCC; + decoded->src.addr_mode = MODE_PC_INDIRECT_ABS_IMMED; + decoded->src.regs.pri = MODE_IMMEDIATE; + //TODO: Figure out what to do with OPMODE and optional extention words + break; + default: //Scc + decoded->op = M68K_SCC; + M68k_decode_op(*istream, &(decoded->dst)); + break; + } + } else { + //ADDQ, SUBQ + decoded->variant = VAR_QUICK; + decoded->extra.size = size; + decoded->src.addr_mode = MODE_PC_INDIRECT_ABS_IMMED; + decoded->src.regs.pri = MODE_IMMEDIATE; + immed = (*istream >> 9) & 0x7 + if (!immed) { + immed = 8; + } + switch (size) + { + case OPSIZE_BYTE; + decoded->src.params.u8 = immed; + break; + case OPSIZE_WORD: + decoded->src.params.u16 = immed; + break; + case OPSIZE_LONG: + decoded->src.params.u38 = immed; + break; + } + if (*istream & 0x10) { + decoded->op = M68K_SUB; + } else { + decoded->op = M68K_ADD; + } + } + break; + } +}