Mercurial > repos > blastem
comparison 68kinst.c @ 184:ebcbdd1c4cc8
Fix a bunch of bugs in the CPU core, add a 68K debugger
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 13 Jan 2013 13:01:13 -0800 |
parents | 2f08d9e90a4c |
children | 7c227a8ec53d |
comparison
equal
deleted
inserted
replaced
183:2f08d9e90a4c | 184:ebcbdd1c4cc8 |
---|---|
477 #else | 477 #else |
478 decoded->op = M68K_INVALID; | 478 decoded->op = M68K_INVALID; |
479 break; | 479 break; |
480 #endif | 480 #endif |
481 } | 481 } |
482 decoded->dst.addr_mode = MODE_REG; | |
483 decoded->dst.addr_mode = m68k_reg_quick_field(*istream); | |
482 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); | 484 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); |
483 if (!istream) { | 485 if (!istream) { |
484 decoded->op = M68K_INVALID; | 486 decoded->op = M68K_INVALID; |
485 return start+1; | 487 return start+1; |
486 } | 488 } |
487 decoded->dst.addr_mode = MODE_REG; | |
488 decoded->dst.addr_mode = m68k_reg_quick_field(*istream); | |
489 } else { | 489 } else { |
490 opmode = (*istream >> 3) & 0x7; | 490 opmode = (*istream >> 3) & 0x7; |
491 if ((*istream & 0xB80) == 0x880 && opmode != MODE_REG && opmode != MODE_AREG) { | 491 if ((*istream & 0xB80) == 0x880 && opmode != MODE_REG && opmode != MODE_AREG) { |
492 //TODO: Check for invalid modes that are dependent on direction | 492 //TODO: Check for invalid modes that are dependent on direction |
493 decoded->op = M68K_MOVEM; | 493 decoded->op = M68K_MOVEM; |
957 } | 957 } |
958 } else { | 958 } else { |
959 //SUBX | 959 //SUBX |
960 decoded->op = M68K_SUBX; | 960 decoded->op = M68K_SUBX; |
961 decoded->extra.size = size; | 961 decoded->extra.size = size; |
962 istream = m68k_decode_op(istream, size, &(decoded->src)); | |
963 if (!istream) { | |
964 decoded->op = M68K_INVALID; | |
965 return start+1; | |
966 } | |
967 decoded->dst.addr_mode = decoded->src.addr_mode; | |
968 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 962 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); |
963 decoded->src.params.regs.pri = *istream & 0x7; | |
964 if (*istream & 0x8) { | |
965 decoded->dst.addr_mode = decoded->src.addr_mode = MODE_AREG_PREDEC; | |
966 } else { | |
967 decoded->dst.addr_mode = decoded->src.addr_mode = MODE_REG; | |
968 } | |
969 } | 969 } |
970 } else { | 970 } else { |
971 if (size == OPSIZE_INVALID) { | 971 if (size == OPSIZE_INVALID) { |
972 //SUBA.w | 972 //SUBA.w |
973 decoded->extra.size = OPSIZE_WORD; | 973 decoded->extra.size = OPSIZE_WORD; |
999 if (!istream) { | 999 if (!istream) { |
1000 decoded->op = M68K_INVALID; | 1000 decoded->op = M68K_INVALID; |
1001 return start+1; | 1001 return start+1; |
1002 } | 1002 } |
1003 } else { | 1003 } else { |
1004 reg = m68k_reg_quick_field(*istream); | |
1004 istream = m68k_decode_op(istream, size, &(decoded->dst)); | 1005 istream = m68k_decode_op(istream, size, &(decoded->dst)); |
1005 if (!istream) { | 1006 if (!istream) { |
1006 decoded->op = M68K_INVALID; | 1007 decoded->op = M68K_INVALID; |
1007 return start+1; | 1008 return start+1; |
1008 } | 1009 } |
1009 decoded->extra.size = size; | 1010 decoded->extra.size = size; |
1010 if (decoded->dst.addr_mode == MODE_AREG) { | 1011 if (decoded->dst.addr_mode == MODE_AREG) { |
1011 //CMPM | 1012 //CMPM |
1012 decoded->src.addr_mode = decoded->dst.addr_mode = MODE_AREG_POSTINC; | 1013 decoded->src.addr_mode = decoded->dst.addr_mode = MODE_AREG_POSTINC; |
1013 decoded->src.params.regs.pri = decoded->dst.params.regs.pri; | 1014 decoded->src.params.regs.pri = decoded->dst.params.regs.pri; |
1014 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1015 decoded->dst.params.regs.pri = reg; |
1015 } else { | 1016 } else { |
1016 //EOR | 1017 //EOR |
1017 decoded->op = M68K_EOR; | 1018 decoded->op = M68K_EOR; |
1018 decoded->src.addr_mode = MODE_REG; | 1019 decoded->src.addr_mode = MODE_REG; |
1019 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); | 1020 decoded->src.params.regs.pri = reg; |
1020 } | 1021 } |
1021 } | 1022 } |
1022 } else { | 1023 } else { |
1023 //CMP or CMPA.w | 1024 //CMP or CMPA.w |
1024 if (size == OPSIZE_INVALID) { | 1025 if (size == OPSIZE_INVALID) { |
1140 } | 1141 } |
1141 } | 1142 } |
1142 } else { | 1143 } else { |
1143 //ADDX | 1144 //ADDX |
1144 decoded->op = M68K_ADDX; | 1145 decoded->op = M68K_ADDX; |
1145 //FIXME: Size is not technically correct | |
1146 decoded->extra.size = size; | 1146 decoded->extra.size = size; |
1147 istream = m68k_decode_op(istream, size, &(decoded->src)); | |
1148 if (!istream) { | |
1149 decoded->op = M68K_INVALID; | |
1150 return start+1; | |
1151 } | |
1152 decoded->dst.addr_mode = decoded->src.addr_mode; | |
1153 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 1147 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); |
1148 decoded->src.params.regs.pri = *istream & 0x7; | |
1149 if (*istream & 0x8) { | |
1150 decoded->dst.addr_mode = decoded->src.addr_mode = MODE_AREG_PREDEC; | |
1151 } else { | |
1152 decoded->dst.addr_mode = decoded->src.addr_mode = MODE_REG; | |
1153 } | |
1154 } | 1154 } |
1155 } else { | 1155 } else { |
1156 if (size == OPSIZE_INVALID) { | 1156 if (size == OPSIZE_INVALID) { |
1157 //ADDA.w | 1157 //ADDA.w |
1158 decoded->extra.size = OPSIZE_WORD; | 1158 decoded->extra.size = OPSIZE_WORD; |