summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--68kinst.c236
-rw-r--r--68kinst.h1
-rw-r--r--dis.c6
3 files changed, 129 insertions, 114 deletions
diff --git a/68kinst.c b/68kinst.c
index 3e73e25..97a30a8 100644
--- a/68kinst.c
+++ b/68kinst.c
@@ -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);
diff --git a/68kinst.h b/68kinst.h
index 3a0847c..3aa46cf 100644
--- a/68kinst.h
+++ b/68kinst.h
@@ -95,6 +95,7 @@ typedef enum {
typedef enum {
VAR_NORMAL,
VAR_QUICK,
+ VAR_IMMEDIATE,
VAR_BYTE,
VAR_WORD,
VAR_LONG
diff --git a/dis.c b/dis.c
index d269059..3c5fcce 100644
--- a/dis.c
+++ b/dis.c
@@ -18,13 +18,11 @@ int main(int argc, char ** argv)
fclose(f);
for(cur = filebuf; cur - filebuf < (filesize/2); ++cur)
{
- //printf("%x:", *cur);
*cur = (*cur >> 8) | (*cur << 8);
- //printf("%x\n", *cur);
}
- for(cur = filebuf; (cur - filebuf) < (filesize/2); ++cur)
+ for(cur = filebuf; (cur - filebuf) < (filesize/2); )
{
- printf("cur: %p: %x\n", cur, *cur);
+ //printf("cur: %p: %x\n", cur, *cur);
cur = m68K_decode(cur, &instbuf);
m68k_disasm(&instbuf, disbuf);
puts(disbuf);