Mercurial > repos > blastem
comparison 68kinst.c @ 518:775802dab98f
Refactor debugger next command
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 09 Feb 2014 12:35:27 -0800 |
parents | 140af5509ce7 |
children | 09d5adf8d1ca 47123183c336 |
comparison
equal
deleted
inserted
replaced
517:3fc1d145493c | 518:775802dab98f |
---|---|
1 /* | 1 /* |
2 Copyright 2013 Michael Pavone | 2 Copyright 2013 Michael Pavone |
3 This file is part of BlastEm. | 3 This file is part of BlastEm. |
4 BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. | 4 BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. |
5 */ | 5 */ |
6 #include "68kinst.h" | 6 #include "68kinst.h" |
7 #include <string.h> | 7 #include <string.h> |
8 #include <stdio.h> | 8 #include <stdio.h> |
432 decoded->op = M68K_INVALID; | 432 decoded->op = M68K_INVALID; |
433 return start+1; | 433 return start+1; |
434 } | 434 } |
435 break; | 435 break; |
436 case 7: | 436 case 7: |
437 | 437 |
438 | 438 |
439 break; | 439 break; |
440 } | 440 } |
441 } | 441 } |
442 break; | 442 break; |
443 case MOVE_BYTE: | 443 case MOVE_BYTE: |
457 decoded->op = M68K_INVALID; | 457 decoded->op = M68K_INVALID; |
458 return start+1; | 458 return start+1; |
459 } | 459 } |
460 break; | 460 break; |
461 case MISC: | 461 case MISC: |
462 | 462 |
463 if ((*istream & 0x1C0) == 0x1C0) { | 463 if ((*istream & 0x1C0) == 0x1C0) { |
464 decoded->op = M68K_LEA; | 464 decoded->op = M68K_LEA; |
465 decoded->extra.size = OPSIZE_LONG; | 465 decoded->extra.size = OPSIZE_LONG; |
466 decoded->dst.addr_mode = MODE_AREG; | 466 decoded->dst.addr_mode = MODE_AREG; |
467 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); | 467 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); |
680 decoded->op = M68K_INVALID; | 680 decoded->op = M68K_INVALID; |
681 return start+1; | 681 return start+1; |
682 } | 682 } |
683 } | 683 } |
684 } | 684 } |
685 break; | 685 break; |
686 case 6: | 686 case 6: |
687 //MULU, MULS, DIVU, DIVUL, DIVS, DIVSL | 687 //MULU, MULS, DIVU, DIVUL, DIVS, DIVSL |
688 #ifdef M68020 | 688 #ifdef M68020 |
689 //TODO: Implement these for 68020+ support | 689 //TODO: Implement these for 68020+ support |
690 #endif | 690 #endif |
916 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); | 916 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); |
917 if (!istream || decoded->src.addr_mode == MODE_AREG) { | 917 if (!istream || decoded->src.addr_mode == MODE_AREG) { |
918 decoded->op = M68K_INVALID; | 918 decoded->op = M68K_INVALID; |
919 return start+1; | 919 return start+1; |
920 } | 920 } |
921 break; | 921 break; |
922 } | 922 } |
923 } else { | 923 } else { |
924 decoded->op = M68K_OR; | 924 decoded->op = M68K_OR; |
925 decoded->extra.size = size; | 925 decoded->extra.size = size; |
926 if (opmode & 0x4) { | 926 if (opmode & 0x4) { |
1257 } | 1257 } |
1258 decoded->src.params.immed = immed; | 1258 decoded->src.params.immed = immed; |
1259 } | 1259 } |
1260 decoded->dst.addr_mode = MODE_REG; | 1260 decoded->dst.addr_mode = MODE_REG; |
1261 decoded->dst.params.regs.pri = *istream & 0x7; | 1261 decoded->dst.params.regs.pri = *istream & 0x7; |
1262 | 1262 |
1263 } else { | 1263 } else { |
1264 #ifdef M68020 | 1264 #ifdef M68020 |
1265 //TODO: Implement bitfield instructions for M68020+ support | 1265 //TODO: Implement bitfield instructions for M68020+ support |
1266 #endif | 1266 #endif |
1267 } | 1267 } |
1270 //TODO: Implement me | 1270 //TODO: Implement me |
1271 break; | 1271 break; |
1272 } | 1272 } |
1273 return istream+1; | 1273 return istream+1; |
1274 } | 1274 } |
1275 | |
1276 uint32_t m68k_branch_target(m68kinst * inst, uint32_t *dregs, uint32_t *aregs) | |
1277 { | |
1278 if(inst->op == M68K_BCC || inst->op == M68K_BSR || inst->op == M68K_DBCC) { | |
1279 return inst->address + 2 + inst->src.params.immed; | |
1280 } else if(inst->op == M68K_JMP || inst->op == M68K_JSR) { | |
1281 uint32_t ret = 0; | |
1282 switch(inst->src.addr_mode) | |
1283 { | |
1284 case MODE_AREG_INDIRECT: | |
1285 ret = aregs[inst->src.params.regs.pri]; | |
1286 break; | |
1287 case MODE_AREG_INDEX_DISP8: { | |
1288 uint8_t sec_reg = inst->src.params.regs.sec >> 1 & 0x7; | |
1289 ret = aregs[inst->src.params.regs.pri]; | |
1290 uint32_t * regfile = inst->src.params.regs.sec & 0x10 ? aregs : dregs; | |
1291 if (inst->src.params.regs.sec & 1) { | |
1292 //32-bit index register | |
1293 ret += regfile[sec_reg]; | |
1294 } else { | |
1295 //16-bit index register | |
1296 if (regfile[sec_reg] & 0x8000) { | |
1297 ret += (0xFFFF0000 | regfile[sec_reg]); | |
1298 } else { | |
1299 ret += regfile[sec_reg]; | |
1300 } | |
1301 } | |
1302 ret += inst->src.params.regs.displacement; | |
1303 break; | |
1304 } | |
1305 case MODE_PC_DISPLACE: | |
1306 ret = inst->src.params.regs.displacement + inst->address + 2; | |
1307 break; | |
1308 case MODE_PC_INDEX_DISP8: { | |
1309 uint8_t sec_reg = inst->src.params.regs.sec >> 1 & 0x7; | |
1310 ret = inst->address + 2; | |
1311 uint32_t * regfile = inst->src.params.regs.sec & 0x10 ? aregs : dregs; | |
1312 if (inst->src.params.regs.sec & 1) { | |
1313 //32-bit index register | |
1314 ret += regfile[sec_reg]; | |
1315 } else { | |
1316 //16-bit index register | |
1317 if (regfile[sec_reg] & 0x8000) { | |
1318 ret += (0xFFFF0000 | regfile[sec_reg]); | |
1319 } else { | |
1320 ret += regfile[sec_reg]; | |
1321 } | |
1322 } | |
1323 ret += inst->src.params.regs.displacement; | |
1324 break; | |
1325 } | |
1326 case MODE_ABSOLUTE: | |
1327 case MODE_ABSOLUTE_SHORT: | |
1328 ret = inst->src.params.immed; | |
1329 break; | |
1330 } | |
1331 return ret; | |
1332 } | |
1333 return 0; | |
1334 } | |
1335 | |
1336 uint8_t m68k_is_branch(m68kinst * inst) | |
1337 { | |
1338 return (inst->op == M68K_BCC && inst->extra.cond != COND_FALSE) | |
1339 || (inst->op == M68K_DBCC && inst->extra.cond != COND_TRUE) | |
1340 || inst->op == M68K_BSR || inst->op == M68K_JMP || inst->op == M68K_JSR; | |
1341 } | |
1342 | |
1343 uint8_t m68k_is_noncall_branch(m68kinst * inst) | |
1344 { | |
1345 return m68k_is_branch(inst) && inst->op != M68K_BSR && inst->op != M68K_JSR; | |
1346 } | |
1347 | |
1275 | 1348 |
1276 char * mnemonics[] = { | 1349 char * mnemonics[] = { |
1277 "abcd", | 1350 "abcd", |
1278 "add", | 1351 "add", |
1279 "addx", | 1352 "addx", |
1502 return ret; | 1575 return ret; |
1503 } | 1576 } |
1504 break; | 1577 break; |
1505 case M68K_BSR: | 1578 case M68K_BSR: |
1506 if (labels) { | 1579 if (labels) { |
1507 ret = sprintf(dst, "bsr%s ADR_%X", decoded->variant == VAR_BYTE ? ".s" : "", | 1580 ret = sprintf(dst, "bsr%s ADR_%X", decoded->variant == VAR_BYTE ? ".s" : "", |
1508 decoded->address + 2 + decoded->src.params.immed); | 1581 decoded->address + 2 + decoded->src.params.immed); |
1509 } else { | 1582 } else { |
1510 ret = sprintf(dst, "bsr%s #%d <%X>", decoded->variant == VAR_BYTE ? ".s" : "", decoded->src.params.immed, decoded->address + 2 + decoded->src.params.immed); | 1583 ret = sprintf(dst, "bsr%s #%d <%X>", decoded->variant == VAR_BYTE ? ".s" : "", decoded->src.params.immed, decoded->address + 2 + decoded->src.params.immed); |
1511 } | 1584 } |
1512 return ret; | 1585 return ret; |
1538 ret += m68k_disasm_op(&(decoded->dst), dst + ret, 0, labels, decoded->address); | 1611 ret += m68k_disasm_op(&(decoded->dst), dst + ret, 0, labels, decoded->address); |
1539 } | 1612 } |
1540 return ret; | 1613 return ret; |
1541 default: | 1614 default: |
1542 size = decoded->extra.size; | 1615 size = decoded->extra.size; |
1543 ret = sprintf(dst, "%s%s%s", | 1616 ret = sprintf(dst, "%s%s%s", |
1544 mnemonics[decoded->op], | 1617 mnemonics[decoded->op], |
1545 decoded->variant == VAR_QUICK ? "q" : (decoded->variant == VAR_IMMEDIATE ? "i" : ""), | 1618 decoded->variant == VAR_QUICK ? "q" : (decoded->variant == VAR_IMMEDIATE ? "i" : ""), |
1546 size == OPSIZE_BYTE ? ".b" : (size == OPSIZE_WORD ? ".w" : (size == OPSIZE_LONG ? ".l" : ""))); | 1619 size == OPSIZE_BYTE ? ".b" : (size == OPSIZE_WORD ? ".w" : (size == OPSIZE_LONG ? ".l" : ""))); |
1547 } | 1620 } |
1548 if (decoded->op == M68K_MOVEM) { | 1621 if (decoded->op == M68K_MOVEM) { |
1549 op1len = m68k_disasm_movem_op(&(decoded->src), &(decoded->dst), dst + ret, 0, labels, decoded->address); | 1622 op1len = m68k_disasm_movem_op(&(decoded->src), &(decoded->dst), dst + ret, 0, labels, decoded->address); |
1550 ret += op1len; | 1623 ret += op1len; |