changeset 518:775802dab98f

Refactor debugger next command
author Mike Pavone <pavone@retrodev.com>
date Sun, 09 Feb 2014 12:35:27 -0800
parents 3fc1d145493c
children 0b21a1a73fb7
files 68kinst.c 68kinst.h blastem.c
diffstat 3 files changed, 96 insertions(+), 76 deletions(-) [+]
line wrap: on
line diff
--- a/68kinst.c	Sun Feb 09 10:29:29 2014 -0800
+++ b/68kinst.c	Sun Feb 09 12:35:27 2014 -0800
@@ -1,6 +1,6 @@
 /*
  Copyright 2013 Michael Pavone
- This file is part of BlastEm. 
+ This file is part of BlastEm.
  BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text.
 */
 #include "68kinst.h"
@@ -434,8 +434,8 @@
 				}
 				break;
 			case 7:
-				
-				
+
+
 				break;
 			}
 		}
@@ -459,7 +459,7 @@
 		}
 		break;
 	case MISC:
-		
+
 		if ((*istream & 0x1C0) == 0x1C0) {
 			decoded->op = M68K_LEA;
 			decoded->extra.size = OPSIZE_LONG;
@@ -682,7 +682,7 @@
 								}
 							}
 						}
-						break;	
+						break;
 					case 6:
 						//MULU, MULS, DIVU, DIVUL, DIVS, DIVSL
 #ifdef M68020
@@ -918,7 +918,7 @@
 					decoded->op = M68K_INVALID;
 					return start+1;
 				}
-				break;		
+				break;
 			}
 		} else {
 			decoded->op = M68K_OR;
@@ -1259,7 +1259,7 @@
 			}
 			decoded->dst.addr_mode = MODE_REG;
 			decoded->dst.params.regs.pri = *istream & 0x7;
-			
+
 		} else {
 #ifdef M68020
 			//TODO: Implement bitfield instructions for M68020+ support
@@ -1273,6 +1273,79 @@
 	return istream+1;
 }
 
+uint32_t m68k_branch_target(m68kinst * inst, uint32_t *dregs, uint32_t *aregs)
+{
+	if(inst->op == M68K_BCC || inst->op == M68K_BSR || inst->op == M68K_DBCC) {
+		return inst->address + 2 + inst->src.params.immed;
+	} else if(inst->op == M68K_JMP || inst->op == M68K_JSR) {
+		uint32_t ret = 0;
+		switch(inst->src.addr_mode)
+		{
+		case MODE_AREG_INDIRECT:
+			ret = aregs[inst->src.params.regs.pri];
+			break;
+		case MODE_AREG_INDEX_DISP8: {
+			uint8_t sec_reg = inst->src.params.regs.sec >> 1 & 0x7;
+			ret = aregs[inst->src.params.regs.pri];
+			uint32_t * regfile = inst->src.params.regs.sec & 0x10 ? aregs : dregs;
+			if (inst->src.params.regs.sec & 1) {
+				//32-bit index register
+				ret += regfile[sec_reg];
+			} else {
+				//16-bit index register
+				if (regfile[sec_reg] & 0x8000) {
+					ret += (0xFFFF0000 | regfile[sec_reg]);
+				} else {
+					ret += regfile[sec_reg];
+				}
+			}
+			ret += inst->src.params.regs.displacement;
+			break;
+		}
+		case MODE_PC_DISPLACE:
+			ret = inst->src.params.regs.displacement + inst->address + 2;
+			break;
+		case MODE_PC_INDEX_DISP8: {
+			uint8_t sec_reg = inst->src.params.regs.sec >> 1 & 0x7;
+			ret = inst->address + 2;
+			uint32_t * regfile = inst->src.params.regs.sec & 0x10 ? aregs : dregs;
+			if (inst->src.params.regs.sec & 1) {
+				//32-bit index register
+				ret += regfile[sec_reg];
+			} else {
+				//16-bit index register
+				if (regfile[sec_reg] & 0x8000) {
+					ret += (0xFFFF0000 | regfile[sec_reg]);
+				} else {
+					ret += regfile[sec_reg];
+				}
+			}
+			ret += inst->src.params.regs.displacement;
+			break;
+		}
+		case MODE_ABSOLUTE:
+		case MODE_ABSOLUTE_SHORT:
+			ret = inst->src.params.immed;
+			break;
+		}
+		return ret;
+	}
+	return 0;
+}
+
+uint8_t m68k_is_branch(m68kinst * inst)
+{
+	return (inst->op == M68K_BCC && inst->extra.cond != COND_FALSE)
+		|| (inst->op == M68K_DBCC && inst->extra.cond != COND_TRUE)
+		|| inst->op == M68K_BSR || inst->op == M68K_JMP || inst->op == M68K_JSR;
+}
+
+uint8_t m68k_is_noncall_branch(m68kinst * inst)
+{
+	return m68k_is_branch(inst) && inst->op != M68K_BSR && inst->op != M68K_JSR;
+}
+
+
 char * mnemonics[] = {
 	"abcd",
 	"add",
@@ -1504,7 +1577,7 @@
 		break;
 	case M68K_BSR:
 		if (labels) {
-			ret = sprintf(dst, "bsr%s ADR_%X", decoded->variant == VAR_BYTE ? ".s" : "", 
+			ret = sprintf(dst, "bsr%s ADR_%X", decoded->variant == VAR_BYTE ? ".s" : "",
 			decoded->address + 2 + decoded->src.params.immed);
 		} else {
 			ret = sprintf(dst, "bsr%s #%d <%X>", decoded->variant == VAR_BYTE ? ".s" : "", decoded->src.params.immed, decoded->address + 2 + decoded->src.params.immed);
@@ -1540,9 +1613,9 @@
 		return ret;
 	default:
 		size = decoded->extra.size;
-		ret = sprintf(dst, "%s%s%s", 
-				mnemonics[decoded->op], 
-				decoded->variant == VAR_QUICK ? "q" : (decoded->variant == VAR_IMMEDIATE ? "i" : ""), 
+		ret = sprintf(dst, "%s%s%s",
+				mnemonics[decoded->op],
+				decoded->variant == VAR_QUICK ? "q" : (decoded->variant == VAR_IMMEDIATE ? "i" : ""),
 				size == OPSIZE_BYTE ? ".b" : (size == OPSIZE_WORD ? ".w" : (size == OPSIZE_LONG ? ".l" : "")));
 	}
 	if (decoded->op == M68K_MOVEM) {
--- a/68kinst.h	Sun Feb 09 10:29:29 2014 -0800
+++ b/68kinst.h	Sun Feb 09 12:35:27 2014 -0800
@@ -1,6 +1,6 @@
 /*
  Copyright 2013 Michael Pavone
- This file is part of BlastEm. 
+ This file is part of BlastEm.
  BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text.
 */
 #ifndef M68KINST_H_
@@ -230,7 +230,9 @@
 } m68k_vector;
 
 uint16_t * m68k_decode(uint16_t * istream, m68kinst * dst, uint32_t address);
-uint32_t m68k_cycles(m68kinst * inst);
+uint32_t m68k_branch_target(m68kinst * inst, uint32_t *dregs, uint32_t *aregs);
+uint8_t m68k_is_branch(m68kinst * inst);
+uint8_t m68k_is_noncall_branch(m68kinst * inst);
 int m68k_disasm(m68kinst * decoded, char * dst);
 int m68k_disasm_labels(m68kinst * decoded, char * dst);
 
--- a/blastem.c	Sun Feb 09 10:29:29 2014 -0800
+++ b/blastem.c	Sun Feb 09 12:35:27 2014 -0800
@@ -1469,72 +1469,17 @@
 					after = (read_dma_value(context->aregs[7]/2) << 16) | read_dma_value(context->aregs[7]/2 + 1);
 				} else if (inst.op == M68K_RTE || inst.op == M68K_RTR) {
 					after = (read_dma_value((context->aregs[7]+2)/2) << 16) | read_dma_value((context->aregs[7]+2)/2 + 1);
-				} else if(inst.op == M68K_BCC && inst.extra.cond != COND_FALSE) {
-					if (inst.extra.cond == COND_TRUE) {
-						after = inst.address + 2 + inst.src.params.immed;
-					} else {
+				} else if(m68k_is_noncall_branch(&inst)) {
+					if (inst.op == M68K_BCC && inst.extra.cond != COND_TRUE) {
 						branch_f = after;
-						branch_t = inst.address + 2 + inst.src.params.immed;
+						branch_t = m68k_branch_target(&inst, context->dregs, context->aregs);
 						insert_breakpoint(context, branch_t, (uint8_t *)debugger);
-					}
-				} else if(inst.op == M68K_DBCC) {
-					if (inst.extra.cond == COND_FALSE) {
-						if (context->dregs[inst.dst.params.regs.pri] & 0xFFFF) {
-							after = inst.address + 2 + inst.src.params.immed;
-						}
-					} else if (inst.extra.cond != COND_TRUE) {
+					} else if(inst.op == M68K_BCC && inst.extra.cond != COND_FALSE) {
 						branch_t = after;
-						branch_f = inst.address + 2 + inst.src.params.immed;
-					}
-				} else if(inst.op == M68K_JMP) {
-					switch(inst.src.addr_mode)
-					{
-					case MODE_AREG_INDIRECT:
-						after = context->aregs[inst.src.params.regs.pri];
-						break;
-					case MODE_AREG_INDEX_DISP8: {
-						uint8_t sec_reg = inst.src.params.regs.sec >> 1 & 0x7;
-						after = context->aregs[inst.src.params.regs.pri];
-						uint32_t * regfile = inst.src.params.regs.sec & 0x10 ? context->aregs : context->dregs;
-						if (inst.src.params.regs.sec & 1) {
-							//32-bit index register
-							after += regfile[sec_reg];
-						} else {
-							//16-bit index register
-							if (regfile[sec_reg] & 0x8000) {
-								after += (0xFFFF0000 | regfile[sec_reg]);
-							} else {
-								after += regfile[sec_reg];
-							}
-						}
-						after += inst.src.params.regs.displacement;
-						break;
-					}
-					case MODE_PC_DISPLACE:
-						after = inst.src.params.regs.displacement + address + 2;
-						break;
-					case MODE_PC_INDEX_DISP8: {
-						uint8_t sec_reg = inst.src.params.regs.sec >> 1 & 0x7;
-						after = address + 2;
-						uint32_t * regfile = inst.src.params.regs.sec & 0x10 ? context->aregs : context->dregs;
-						if (inst.src.params.regs.sec & 1) {
-							//32-bit index register
-							after += regfile[sec_reg];
-						} else {
-							//16-bit index register
-							if (regfile[sec_reg] & 0x8000) {
-								after += (0xFFFF0000 | regfile[sec_reg]);
-							} else {
-								after += regfile[sec_reg];
-							}
-						}
-						after += inst.src.params.regs.displacement;
-						break;
-					}
-					case MODE_ABSOLUTE:
-					case MODE_ABSOLUTE_SHORT:
-						after = inst.src.params.immed;
-						break;
+						branch_f = m68k_branch_target(&inst, context->dregs, context->aregs);
+						insert_breakpoint(context, branch_f, (uint8_t *)debugger);
+					} else {
+						after = m68k_branch_target(&inst, context->dregs, context->aregs);
 					}
 				}
 				insert_breakpoint(context, after, (uint8_t *)debugger);