diff --git a/Src/Debugger/CPU/68KDebug.cpp b/Src/Debugger/CPU/68KDebug.cpp
index 66619801..dc9f9fea 100644
--- a/Src/Debugger/CPU/68KDebug.cpp
+++ b/Src/Debugger/CPU/68KDebug.cpp
@@ -1,82 +1,82 @@
-/**
- ** Supermodel
- ** A Sega Model 3 Arcade Emulator.
- ** Copyright 2011 Bart Trzynadlowski, Nik Henson
- **
- ** This file is part of Supermodel.
- **
- ** Supermodel is free software: you can redistribute it and/or modify it under
- ** the terms of the GNU General Public License as published by the Free
- ** Software Foundation, either version 3 of the License, or (at your option)
- ** any later version.
- **
- ** Supermodel is distributed in the hope that it will be useful, but WITHOUT
- ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- ** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- ** more details.
- **
- ** You should have received a copy of the GNU General Public License along
- ** with Supermodel. If not, see .
- **/
-
+/**
+ ** Supermodel
+ ** A Sega Model 3 Arcade Emulator.
+ ** Copyright 2011 Bart Trzynadlowski, Nik Henson
+ **
+ ** This file is part of Supermodel.
+ **
+ ** Supermodel is free software: you can redistribute it and/or modify it under
+ ** the terms of the GNU General Public License as published by the Free
+ ** Software Foundation, either version 3 of the License, or (at your option)
+ ** any later version.
+ **
+ ** Supermodel is distributed in the hope that it will be useful, but WITHOUT
+ ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ ** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ ** more details.
+ **
+ ** You should have received a copy of the GNU General Public License along
+ ** with Supermodel. If not, see .
+ **/
+
/*
* 68KDebug.cpp
- */
-
-#ifdef SUPERMODEL_DEBUGGER
-
-#include "68KDebug.h"
-
-#include
-#include
-
-#define M68KSPECIAL_SP 0
-#define M68KSPECIAL_SR 1
-
-namespace Debugger
-{
- C68KDebug::C68KDebug(const char *name) : CCPUDebug("68K", name, 2, 10, true, 24, 7)
- {
- // Exceptions
- AddException("BUS", 2, "Bus Error");
- AddException("ADDRESS", 3, "Address Error");
- AddException("ILLEGAL", 4, "Illegal Instruction");
- AddException("DIVZERO", 5, "Divide by Zero");
- AddException("CHK", 6, "CHK Instruction");
- AddException("TRAPV", 7, "TRAPV Instruction");
- AddException("PRIVEX", 8, "Privilege Exception");
- AddException("TRACE", 9, "Trace");
- AddException("L1010", 10, "Line 1010 Emulator");
- AddException("L1111", 11, "Line 1111 Emulator");
- AddException("SPUR", 24, "Spurious Interrupt");
- AddException("AUTO", 25, "Interrupt Autovector");
- AddException("TRAP0", 32, "TRAP #0 Instruction Vector");
- AddException("TRAP1", 33, "TRAP #1 Instruction Vector");
- AddException("TRAP2", 34, "TRAP #2 Instruction Vector");
- AddException("TRAP3", 35, "TRAP #3 Instruction Vector");
- AddException("TRAP4", 36, "TRAP #4 Instruction Vector");
- AddException("TRAP5", 37, "TRAP #5 Instruction Vector");
- AddException("TRAP6", 38, "TRAP #6 Instruction Vector");
- AddException("TRAP7", 39, "TRAP #7 Instruction Vector");
- AddException("TRAP8", 40, "TRAP #8 Instruction Vector");
- AddException("TRAP9", 41, "TRAP #9 Instruction Vector");
- AddException("TRAP10", 42, "TRAP #10 Instruction Vector");
- AddException("TRAP11", 43, "TRAP #11 Instruction Vector");
- AddException("TRAP12", 44, "TRAP #12 Instruction Vector");
- AddException("TRAP13", 45, "TRAP #13 Instruction Vector");
- AddException("TRAP14", 46, "TRAP #14 Instruction Vector");
- AddException("TRAP15", 47, "TRAP #15 Instruction Vector");
-
- // Interrupts
- AddInterrupt("AUTO1", 0, "Level 1 Interrupt Autovector");
- AddInterrupt("AUTO2", 1, "Level 2 Interrupt Autovector");
- AddInterrupt("AUTO3", 2, "Level 3 Interrupt Autovector");
- AddInterrupt("AUTO4", 3, "Level 4 Interrupt Autovector");
- AddInterrupt("AUTO5", 4, "Level 5 Interrupt Autovector");
- AddInterrupt("AUTO6", 5, "Level 6 Interrupt Autovector");
- AddInterrupt("AUTO7", 6, "Level 7 Interrupt Autovector");
- }
-
+ */
+
+#ifdef SUPERMODEL_DEBUGGER
+
+#include "68KDebug.h"
+
+#include
+#include
+
+#define M68KSPECIAL_SP 0
+#define M68KSPECIAL_SR 1
+
+namespace Debugger
+{
+ C68KDebug::C68KDebug(const char *name) : CCPUDebug("68K", name, 2, 10, true, 24, 7)
+ {
+ // Exceptions
+ AddException("BUS", 2, "Bus Error");
+ AddException("ADDRESS", 3, "Address Error");
+ AddException("ILLEGAL", 4, "Illegal Instruction");
+ AddException("DIVZERO", 5, "Divide by Zero");
+ AddException("CHK", 6, "CHK Instruction");
+ AddException("TRAPV", 7, "TRAPV Instruction");
+ AddException("PRIVEX", 8, "Privilege Exception");
+ AddException("TRACE", 9, "Trace");
+ AddException("L1010", 10, "Line 1010 Emulator");
+ AddException("L1111", 11, "Line 1111 Emulator");
+ AddException("SPUR", 24, "Spurious Interrupt");
+ AddException("AUTO", 25, "Interrupt Autovector");
+ AddException("TRAP0", 32, "TRAP #0 Instruction Vector");
+ AddException("TRAP1", 33, "TRAP #1 Instruction Vector");
+ AddException("TRAP2", 34, "TRAP #2 Instruction Vector");
+ AddException("TRAP3", 35, "TRAP #3 Instruction Vector");
+ AddException("TRAP4", 36, "TRAP #4 Instruction Vector");
+ AddException("TRAP5", 37, "TRAP #5 Instruction Vector");
+ AddException("TRAP6", 38, "TRAP #6 Instruction Vector");
+ AddException("TRAP7", 39, "TRAP #7 Instruction Vector");
+ AddException("TRAP8", 40, "TRAP #8 Instruction Vector");
+ AddException("TRAP9", 41, "TRAP #9 Instruction Vector");
+ AddException("TRAP10", 42, "TRAP #10 Instruction Vector");
+ AddException("TRAP11", 43, "TRAP #11 Instruction Vector");
+ AddException("TRAP12", 44, "TRAP #12 Instruction Vector");
+ AddException("TRAP13", 45, "TRAP #13 Instruction Vector");
+ AddException("TRAP14", 46, "TRAP #14 Instruction Vector");
+ AddException("TRAP15", 47, "TRAP #15 Instruction Vector");
+
+ // Interrupts
+ AddInterrupt("AUTO1", 0, "Level 1 Interrupt Autovector");
+ AddInterrupt("AUTO2", 1, "Level 2 Interrupt Autovector");
+ AddInterrupt("AUTO3", 2, "Level 3 Interrupt Autovector");
+ AddInterrupt("AUTO4", 3, "Level 4 Interrupt Autovector");
+ AddInterrupt("AUTO5", 4, "Level 5 Interrupt Autovector");
+ AddInterrupt("AUTO6", 5, "Level 6 Interrupt Autovector");
+ AddInterrupt("AUTO7", 6, "Level 7 Interrupt Autovector");
+ }
+
static const char *opATable0004[] = { "movep.w [DW3](A0),D0","movep.w [DW3](A1),D0","movep.w [DW3](A2),D0",
"movep.w [DW3](A3),D0","movep.w [DW3](A4),D0","movep.w [DW3](A5),D0","movep.w [DW3](A6),D0",
"movep.w [DW3](A7),D0" };
@@ -1235,163 +1235,163 @@ namespace Debugger
"roxld [AM2]",NULL,NULL,NULL,"rord [AM2]",NULL,NULL,NULL,"rold [AM2]" };
static const char *brTable[] = { "bra [LV2]","bsr [LV2]","bhi [LV2]","bls [LV2]","bcc [LV2]","bcs [LV2]",
"bne [LV2]","beq [LV2]","bvc [LV2]","bvs [LV2]","bpl [LV2]","bmi [LV2]","bge [LV2]",
- "blt [LV2]","bgt [LV2]","ble [LV2]" };
-
- int C68KDebug::Disassemble(UINT32 addr, char *mnemonic, char *operands)
- {
- // Read opcode head word
- UINT16 opcode = (UINT16)ReadMem(addr, 2);
- int offset = 2;
-
- const char *instr;
- char moveStr[50];
- char dataStr[20];
- INT8 i8;
- INT16 i16;
- INT32 i32;
- UINT8 u8;
- UINT16 u16;
- UINT32 u32;
-
- // First check for special cases that don't fit into op tables A & B
- UINT16 hd = (opcode>>12);
- UINT16 tl;
- switch (hd)
- {
- case 0x1:
- // move.b as,ad
- instr = "move.b [AM2],[AR1]";
- break;
- case 0x2:
- if ((opcode&0x01C0) == 0x0040)
- {
- // movea.l as,ad
- sprintf(moveStr, "movea.l [AM2],A%u", (opcode>>9)&0x7);
- instr = moveStr;
- }
- else
- {
- // move.l as,Ad
- instr = "move.l [AM2],[AR1]";
- }
- break;
- case 0x3:
- if ((opcode&0x01C0) == 0x0040)
- {
- // movea.w as,ad
- sprintf(moveStr, "movea.w [AM2],A%u", (opcode>>9)&0x7);
- instr = moveStr;
- }
- else
- {
- // move.w as,Ad
- instr = "move.w [AM2],[AR1]";
- }
- break;
- case 0x4:
- if ((opcode&0x0B80) == 0x0880)
- {
- // movem.z reg-list,a or movem.z a,reg-list
- u16 = (UINT16)ReadMem(addr + offset, 2);
- offset += 2;
- char sizeC = (opcode&0x40 ? 'l' : 'w');
- char regList[50];
- char *p = regList;
- int range = 0;
- for (unsigned r = 0; r < 17; r++)
- {
- // Get bit position of register r (if address mode is pre-decrement, then bits are in reverse order)
- unsigned bitPos = ((opcode&0x38) == 0x20 ? 15 - r : r);
- // Check given bit is set
- if (r < 16 && ((u16>>bitPos)&0x0001))
- {
- // Check not in middle of register range
- if (range == 0)
- {
- if (p > regList)
- *p++ = '/';
- // If address mode is pre-decrement, then reverse order of registers
- if (r < 8)
- {
- *p++ = 'D';
- *p++ = '0' + r;
- }
- else
- {
- *p++ = 'A';
- *p++ = '0' + r - 8;
- }
- }
- range++;
- }
- else
- {
- if (range > 1)
- {
- // Close off a register range
- *p++ = '-';
- // If address mode is pre-decrement, then reverse order of registers
- unsigned prevR = r - 1;
- if (prevR < 8)
- {
- *p++ = 'D';
- *p++ = '0' + prevR;
- }
- else
- {
- *p++ = 'A';
- *p++ = '0' + prevR - 8;
- }
- }
- range = 0;
- }
- }
- *p++ = '\0';
- if (opcode&0x0400)
- sprintf(moveStr, "movem.%c [AM2],%s", sizeC, regList);
- else
- sprintf(moveStr, "movem.%c %s,[AM2]", sizeC, regList);
- instr = moveStr;
- }
- else
- instr = NULL;
- break;
- case 0x6:
- // bra label, bsr label && bCC label
- tl = (opcode>>8)&0xF;
- instr = brTable[tl];
- break;
- case 0x7:
- // moveq #data8,Dn
- if (opcode&0x100)
- goto invalid;
- u8 = (UINT8)opcode&0xFF;
- FormatData(dataStr, 1, u8);
- sprintf(moveStr, "moveq #%s,D%u", dataStr, (opcode>>9)&0x7);
- //i8 = (INT8)opcode&0xFF;
- //if (i8 < 0)
- //{
- // FormatData(dataStr, 1, -i8);
- // sprintf(moveStr, "moveq #-%s,D%u", dataStr, (opcode>>9)&0x7);
- // //sprintf(moveStr, "moveq #-0x%02X,D%u", -i8, (opcode>>9)&0x7);
- //}
- //else
- //{
- // FormatData(dataStr, 1, i8);
- // sprintf(moveStr, "moveq #%s,D%u", dataStr, (opcode>>9)&0x7);
- // //sprintf(moveStr, "moveq #0x%02X,D%u", i8, (opcode>>9)&0x7);
- //}
- instr = moveStr;
- break;
- default:
- instr = NULL;
- break;
- }
-
- // Next, try op table A if no match found
- if (instr == NULL)
- {
- UINT16 hdA = (opcode>>6);
+ "blt [LV2]","bgt [LV2]","ble [LV2]" };
+
+ int C68KDebug::Disassemble(UINT32 addr, char *mnemonic, char *operands)
+ {
+ // Read opcode head word
+ UINT16 opcode = (UINT16)ReadMem(addr, 2);
+ int offset = 2;
+
+ const char *instr;
+ char moveStr[64];
+ char dataStr[20];
+ INT8 i8;
+ INT16 i16;
+ INT32 i32;
+ UINT8 u8;
+ UINT16 u16;
+ UINT32 u32;
+
+ // First check for special cases that don't fit into op tables A & B
+ UINT16 hd = (opcode>>12);
+ UINT16 tl;
+ switch (hd)
+ {
+ case 0x1:
+ // move.b as,ad
+ instr = "move.b [AM2],[AR1]";
+ break;
+ case 0x2:
+ if ((opcode&0x01C0) == 0x0040)
+ {
+ // movea.l as,ad
+ sprintf(moveStr, "movea.l [AM2],A%u", (opcode>>9)&0x7);
+ instr = moveStr;
+ }
+ else
+ {
+ // move.l as,Ad
+ instr = "move.l [AM2],[AR1]";
+ }
+ break;
+ case 0x3:
+ if ((opcode&0x01C0) == 0x0040)
+ {
+ // movea.w as,ad
+ sprintf(moveStr, "movea.w [AM2],A%u", (opcode>>9)&0x7);
+ instr = moveStr;
+ }
+ else
+ {
+ // move.w as,Ad
+ instr = "move.w [AM2],[AR1]";
+ }
+ break;
+ case 0x4:
+ if ((opcode&0x0B80) == 0x0880)
+ {
+ // movem.z reg-list,a or movem.z a,reg-list
+ u16 = (UINT16)ReadMem(addr + offset, 2);
+ offset += 2;
+ char sizeC = (opcode&0x40 ? 'l' : 'w');
+ char regList[50];
+ char *p = regList;
+ int range = 0;
+ for (unsigned r = 0; r < 17; r++)
+ {
+ // Get bit position of register r (if address mode is pre-decrement, then bits are in reverse order)
+ unsigned bitPos = ((opcode&0x38) == 0x20 ? 15 - r : r);
+ // Check given bit is set
+ if (r < 16 && ((u16>>bitPos)&0x0001))
+ {
+ // Check not in middle of register range
+ if (range == 0)
+ {
+ if (p > regList)
+ *p++ = '/';
+ // If address mode is pre-decrement, then reverse order of registers
+ if (r < 8)
+ {
+ *p++ = 'D';
+ *p++ = '0' + r;
+ }
+ else
+ {
+ *p++ = 'A';
+ *p++ = '0' + r - 8;
+ }
+ }
+ range++;
+ }
+ else
+ {
+ if (range > 1)
+ {
+ // Close off a register range
+ *p++ = '-';
+ // If address mode is pre-decrement, then reverse order of registers
+ unsigned prevR = r - 1;
+ if (prevR < 8)
+ {
+ *p++ = 'D';
+ *p++ = '0' + prevR;
+ }
+ else
+ {
+ *p++ = 'A';
+ *p++ = '0' + prevR - 8;
+ }
+ }
+ range = 0;
+ }
+ }
+ *p++ = '\0';
+ if (opcode&0x0400)
+ sprintf(moveStr, "movem.%c [AM2],%s", sizeC, regList);
+ else
+ sprintf(moveStr, "movem.%c %s,[AM2]", sizeC, regList);
+ instr = moveStr;
+ }
+ else
+ instr = NULL;
+ break;
+ case 0x6:
+ // bra label, bsr label && bCC label
+ tl = (opcode>>8)&0xF;
+ instr = brTable[tl];
+ break;
+ case 0x7:
+ // moveq #data8,Dn
+ if (opcode&0x100)
+ goto invalid;
+ u8 = (UINT8)opcode&0xFF;
+ FormatData(dataStr, 1, u8);
+ sprintf(moveStr, "moveq #%s,D%u", dataStr, (opcode>>9)&0x7);
+ //i8 = (INT8)opcode&0xFF;
+ //if (i8 < 0)
+ //{
+ // FormatData(dataStr, 1, -i8);
+ // sprintf(moveStr, "moveq #-%s,D%u", dataStr, (opcode>>9)&0x7);
+ // //sprintf(moveStr, "moveq #-0x%02X,D%u", -i8, (opcode>>9)&0x7);
+ //}
+ //else
+ //{
+ // FormatData(dataStr, 1, i8);
+ // sprintf(moveStr, "moveq #%s,D%u", dataStr, (opcode>>9)&0x7);
+ // //sprintf(moveStr, "moveq #0x%02X,D%u", i8, (opcode>>9)&0x7);
+ //}
+ instr = moveStr;
+ break;
+ default:
+ instr = NULL;
+ break;
+ }
+
+ // Next, try op table A if no match found
+ if (instr == NULL)
+ {
+ UINT16 hdA = (opcode>>6);
UINT16 tlA = opcode & 0x3F;
switch (hdA)
{
@@ -1613,7 +1613,7 @@ namespace Debugger
// Lastly, try op table B if no match found
if (instr == NULL)
{
- UINT16 hdB = opcode>>12;
+ UINT16 hdB = opcode>>12;
UINT16 tlB = (opcode>>6) & 0x3F;
switch (hdB)
{
@@ -1631,595 +1631,595 @@ namespace Debugger
default: instr = NULL; break;
}
}
-
- if (instr == NULL)
- goto invalid;
-
- // Split instruction into mnemonic and operands and substitute any data and address mode tags
- const char *p, *q;
- char *r;
- char opsCopy[255];
- char sizeC;
- UINT8 addrMode;
- int part;
- EOpFlags opFlags;
-
- // TODO - address mode masks for each instruction
-
- q = instr;
- if (p = strchr(q, ' '))
- {
- // Split instruction
- strncpy(mnemonic, instr, p - q);
- mnemonic[p - q] = '\0';
- operands[0] = '\0';
- opsCopy[0] = '\0';
-
- // Get size character in nmnemonic, if any, otherwise assume word
- if (q = strchr(mnemonic, '.'))
- sizeC = tolower(q[1]);
- else
- sizeC = 'w';
-
- // Substitute any data tags
- q = p + 1;
- r = opsCopy;
- while (p = strchr(q, '['))
- {
- strncpy(r, q, p - q);
- r[p - q] = '\0';
- r += strlen(r);
-
- // TODO - get rid of part indices - not needed for 68000 instruction set (only needed for 020 or 030 etc)
- if (sscanf(p, "[BN%d]", &part) == 1 ||
- sscanf(p, "[DB%d]", &part) == 1 || sscanf(p, "[DW%d]", &part) == 1 || sscanf(p, "[DL%d]", &part) == 1)
- {
- // Bit number or byte, word or long immediate data
- if (p[2] == 'N')
- {
- // Check first byte is zero
- u8 = (UINT8)ReadMem(addr + offset++, 1);
- if (u8 != 0)
- {
- offset++;
- goto invalid;
- }
- // Get data byte
- u8 = (UINT8)ReadMem(addr + offset++, 1);
- // Check top 3 bits are zero
- if (u8&0xE0)
- goto invalid;
- FormatData(r, 1, u8);
- //sprintf(r, "0x%02X", u8);
- }
- else if (p[2] == 'B')
- {
- // Check first byte is zero
- u8 = (UINT8)ReadMem(addr + offset++, 1);
- if (u8 != 0)
- {
- offset++;
- goto invalid;
- }
- // Get data byte
- u8 = (UINT8)ReadMem(addr + offset++, 1);
- FormatData(r, 1, u8);
- //i8 = (INT8)ReadMem(addr + offset++, 1);
- //if (i8 < 0)
- //{
- // *r++ = '-';
- // FormatData(r, 1, -i8);
- // //sprintf(r, "-0x%02X", -i8);
- //}
- //else
- //{
- // FormatData(r, 1, i8);
- // //sprintf(r, "0x%02X", i8);
- //}
- }
- else if (p[2] == 'W')
- {
- u16 = (UINT16)ReadMem(addr + offset, 2);
- offset += 2;
- FormatData(r, 2, u16);
- //i16 = (INT16)ReadMem(addr + offset, 2);
- //offset += 2;
- //if (i16 < 0)
- //{
- // *r++ = '-';
- // FormatData(r, 2, -i16);
- // //sprintf(r, "-0x%04X", -i16);
- //}
- //else
- //{
- // FormatData(r, 2, i16);
- // //sprintf(r, "0x%04X", i16);
- //}
- }
- else
- {
- u32 = (UINT32)ReadMem(addr + offset, 4);
- offset += 4;
- FormatData(r, 4, u32);
- //i32 = (INT32)ReadMem(addr + offset, 4);
- //offset += 4;
- //if (i32 < 0)
- //{
- // *r++ = '-';
- // FormatData(r, 4, -i32);
- // //sprintf(r, "-0x%08X", -i32);
- //}
- //else
- //{
- // FormatData(r, 4, i32);
- // //sprintf(r, "0x%08X", i32);
- //}
- }
- q = p + 5;
- r += strlen(r);
- }
- else if (sscanf(p, "[LL%d]", &part) == 1) // TODO - this should be LW
- {
- // Fixed width label offset
- i16 = (INT16)ReadMem(addr + offset, 2);
- offset += 2;
- // Offset is from PC + 2
- opFlags = GetOpFlags(addr, opcode);
- FormatJumpAddress(r, addr + 2 + i16, opFlags);
- //sprintf(r, "0x%06X", addr + 2 + i16); // Format this way as memory bus width is only 24-bits
- q = p + 5;
- r += strlen(r);
- }
- else if (sscanf(p, "[LV%d]", &part) == 1)
- {
- // Variable width label offset
- i8 = (INT8)(opcode&0xFF);
- INT32 labOffset;
- if (i8 == 0x00)
- {
- i16 = (INT16)ReadMem(addr + offset, 2);
- offset += 2;
- labOffset = i16;
- }
- // Following 68020+ only
- //else if (i8 == 0xFF)
- //{
- // i32 = (INT32)ReadMem(addr + offset, 4);
- // offset += 4;
- // labOffset = i32;
- //*/
- else
- labOffset = i8;
- // Offset is from PC + 2
- opFlags = GetOpFlags(addr, opcode);
- FormatJumpAddress(r, addr + 2 + labOffset, opFlags);
- //sprintf(r, "0x%06X", addr + 2 + labOffset); // Format this way as memory bus width is only 24-bits
- q = p + 5;
- r += strlen(r);
- }
- else
- {
- // TODO - if not AM or AR, goto invalid
- q = p + 1;
- r += strlen(r);
- *r++ = '[';
- *r = '\0';
- }
- }
- strcat(r, q);
-
- // Substitute any address mode tags
- q = opsCopy;
- r = operands;
- while (p = strchr(q, '['))
- {
- strncpy(r, q, p - q);
- r[p - q] = '\0';
- r += strlen(r);
-
- if (sscanf(p, "[AM%d]", &part) == 1 || sscanf(p, "[AR%d]", &part) == 1)
- {
- // Part index must be 1 or 2
- if (part == 1)
- addrMode = (UINT8)((opcode >> 6) & 0x3F);
- else if (part == 2)
- addrMode = (UINT8)(opcode & 0x3F);
- else
- goto invalid;
- // Check if address mode parts are reversed
- if (p[2] == 'R')
- {
- // If so, swap 3-bit mode and register info
- addrMode = ((addrMode&0x7)<<3) | ((addrMode>>3)&0x7);
- }
- if (!FormatAddrMode(addr, opcode, offset, addrMode, sizeC, r))
- goto invalid;
- q = p + 5;
- r += strlen(r);
- }
- else
- {
- q = p + 1;
- r += strlen(r);
- *r++ = '[';
- *r = '\0';
- }
- }
- strcat(r, q);
- }
- else
- {
- // Empty operands
- strcpy(mnemonic, instr);
- operands[0] = '\0';
- }
- return offset;
-
- invalid:
- mnemonic[0] = '\0';
- operands[0] = '\0';
- return -offset;
- }
-
- bool C68KDebug::FormatAddrMode(UINT32 addr, UINT32 opcode, int &offset, UINT8 addrMode, char sizeC, char *dest)
- {
- UINT8 mode = (addrMode>>3)&0x07;
- UINT8 reg = addrMode&0x07;
- char dataStr[20];
- UINT8 ofsReg;
- char ofsRegC, ofsSizeC;
- INT8 i8;
- INT16 i16;
- INT32 i32;
- UINT8 u8;
- UINT16 u16;
- UINT32 u32;
- EOpFlags opFlags;
- switch (mode)
- {
- case 0x00: // Dn
- sprintf(dest, "D%u", reg);
- break;
- case 0x01: // An
- sprintf(dest, "A%u", reg);
- break;
- case 0x02: // (An)
- sprintf(dest, "(A%u)", reg);
- break;
- case 0x03: // (An)+
- sprintf(dest, "(A%u)+", reg);
- break;
- case 0x04: // -(An)
- sprintf(dest, "-(A%u)", reg);
- break;
- case 0x05: // (d16,An)
- i16 = (INT16)ReadMem(addr + offset, 2);
- offset += 2;
- if (i16 < 0)
- {
- FormatData(dataStr, 2, -i16);
- sprintf(dest, "(-%s,A%u)", dataStr, reg);
- //sprintf(dest, "(-0x%04X,A%u)", -i16, reg);
- }
- else
- {
- FormatData(dataStr, 2, i16);
- sprintf(dest, "(%s,A%u)", dataStr, reg);
- //sprintf(dest, "(0x%04X,A%u)", i16, reg);
- }
- break;
- case 0x06: // (d8,An,Ri.z)
- u8 = (UINT8)ReadMem(addr + offset++, 1);
- // Check first 3-bits of first byte are zero
- if (u8&0x7)
- {
- offset++;
- return false;
- }
- // Get second offset register type, number and size (w or l)
- ofsReg = (u8>>4)&0xF;
- if (ofsReg < 8)
- ofsRegC = 'D';
- else
- {
- ofsRegC = 'A';
- ofsReg -= 8;
- }
- ofsSizeC = (u8&0x8 ? 'l' : 'w');
- i8 = (INT8)ReadMem(addr + offset++, 1);
- if (i8 < 0)
- {
- FormatData(dataStr, 1, -i8);
- sprintf(dest, "(-%s,A%u,%c%u.%c)", dataStr, reg, ofsRegC, ofsReg, ofsSizeC);
- //sprintf(dest, "(-0x%02X,A%u,%c%u.%c)", -i8, reg, ofsRegC, ofsReg, ofsSizeC);
- }
- else
- {
- FormatData(dataStr, 1, i8);
- sprintf(dest, "(%s,A%u,%c%u.%c)", dataStr, reg, ofsRegC, ofsReg, ofsSizeC);
- //sprintf(dest, "(0x%02X,A%u,%c%u.%c)", i8, reg, ofsRegC, ofsReg, ofsSizeC);
- }
- break;
- case 0x07:
- switch (reg)
- {
- case 0x00: // addr16
- u16 = (UINT16)ReadMem(addr + offset, 2);
- offset += 2;
- opFlags = GetOpFlags(addr, opcode);
- FormatJumpAddress(dest, u16, opFlags);
- //sprintf(dest, "0x%06X", u16); // Format this way as memory bus width is 24-bits
- break;
- case 0x01: // addr32
- u32 = (UINT32)ReadMem(addr + offset, 4);
- offset += 4;
- opFlags = GetOpFlags(addr, opcode);
- FormatJumpAddress(dest, u32, opFlags);
- //sprintf(dest, "0x%06X", u32); // Format this way as memory bus width is only 24-bits
- break;
- case 0x02: // d16(PC)
- i16 = (INT16)ReadMem(addr + offset, 2);
- offset += 2;
- if (i16 < 0)
- {
- FormatData(dataStr, 2, -i16);
- sprintf(dest, "-%s(PC)", dataStr);
- //sprintf(dest, "-0x%04X(PC)", -i16);
- }
- else
- {
- FormatData(dataStr, 2, i16);
- sprintf(dest, "%s(PC)", dataStr);
- //sprintf(dest, "0x%04X(PC)", i16);
- }
- break;
- case 0x03: // u8(PC,Ri.x)
- u8 = (UINT8)ReadMem(addr + offset++, 1);
- // Check first 3-bits of first byte are zero
- if (u8&0x7)
- {
- offset++;
- return false;
- }
- // Get second offset register type, number and size (w or l)
- ofsReg = (u8>>4)&0xF;
- if (ofsReg < 8)
- ofsRegC = 'D';
- else
- {
- ofsRegC = 'A';
- ofsReg -= 8;
- }
- ofsSizeC = (u8&0x8 ? 'l' : 'w');
- i8 = (INT8)ReadMem(addr + offset++, 1);
- if (i8 < 0)
- {
- FormatData(dataStr, 1, -i8);
- sprintf(dest, "-%s(PC,%c%u.%c)", dataStr, ofsRegC, ofsReg, ofsSizeC);
- //sprintf(dest, "-0x%02X(PC,%c%u.%c)", -i8, ofsRegC, ofsReg, ofsSizeC);
- }
- else
- {
- FormatData(dataStr, 1, i8);
- sprintf(dest, "%s(PC,%c%u.%c)", dataStr, ofsRegC, ofsReg, ofsSizeC);
- //sprintf(dest, "0x%02X(PC,%c%u.%c)", i8, ofsRegC, ofsReg, ofsSizeC);
- }
- break;
- case 0x04: // immediate data, implied size
- if (sizeC == 'b')
- {
- // Check first byte is zero
- u8 = (UINT8)ReadMem(addr + offset++, 1);
- if (u8 != 0)
- {
- offset++;
- return false;
- }
- // Get data byte
- u8 = (UINT8)ReadMem(addr + offset++, 1);
- FormatData(dataStr, 1, u8);
- sprintf(dest, "#%s", dataStr);
- //i8 = (INT8)ReadMem(addr + offset++, 1);
- //if (i8 < 0)
- //{
- // FormatData(dataStr, 1, -i8);
- // sprintf(dest, "#-%s", dataStr);
- // //sprintf(dest, "#-0x%02X", -i8);
- //}
- //else
- //{
- // FormatData(dataStr, 1, i8);
- // sprintf(dest, "#%s", dataStr);
- // //sprintf(dest, "#0x%02X", i8);
- //}
- }
- else if (sizeC == 'w')
- {
- u16 = (UINT16)ReadMem(addr + offset, 2);
- offset += 2;
- FormatData(dataStr, 2, u16);
- sprintf(dest, "#%s", dataStr);
- //i16 = (INT16)ReadMem(addr + offset, 2);
- //offset += 2;
- //if (i16 < 0)
- //{
- // FormatData(dataStr, 2, -i16);
- // sprintf(dest, "#-%s", dataStr);
- // //sprintf(dest, "#-0x%04X", -i16);
- //}
- //else
- //{
- // FormatData(dataStr, 2, i16);
- // sprintf(dest, "#%s", dataStr);
- // //sprintf(dest, "#0x%04X", i16);
- //}
- }
- else if (sizeC == 'l')
- {
- u32 = (UINT32)ReadMem(addr + offset, 4);
- offset += 4;
- FormatData(dataStr, 4, u32);
- sprintf(dest, "#%s", dataStr);
- //i32 = (INT32)ReadMem(addr + offset, 4);
- //offset += 4;
- //if (i32 < 0)
- //{
- // FormatData(dataStr, 4, -i32);
- // sprintf(dest, "#-%s", dataStr);
- // //sprintf(dest, "#-0x%08X", -i32);
- //}
- //else
- //{
- // FormatData(dataStr, 4, i32);
- // sprintf(dest, "#%s", dataStr);
- // //sprintf(dest, "#0x%08X", i32);
- //}
- }
- else
- return false;
- break;
- default:
- return false;
- }
- break;
- default:
- return false;
- }
- return true;
- }
-
- EOpFlags C68KDebug::GetOpFlags(UINT32 addr, UINT32 opcode)
- {
- UINT32 head = opcode>>6;
- if (head == 0x013A) // Instruction is jmp
- return JumpSimple;
- else if (head == 0x013B) // Instruction is jsr
- return JumpSub;
- else if ((opcode>>12) == 0x0006) // Instruction is bra, bsr or bCC
- {
- UINT32 cond = (opcode>>8)&0x000F;
- if (cond == 0x0000) // Instruction is bra
- return (EOpFlags)(JumpSimple | Relative);
- else if (cond == 0x0001) // Instruction is bsr
- return (EOpFlags)(JumpSub | Relative);
- else // Instruction is bCC
- return (EOpFlags)(JumpSimple | Relative | Conditional);
- }
- else if ((opcode&0xF0F8) == 0x50C8) // Instruction is dbCC
- return (EOpFlags)(JumpLoop | Relative | Conditional);
- else if (opcode == 0x4E74 || opcode == 0x4E75) // Instruction is rtr or rts
- return ReturnSub;
- else if (opcode == 0x4E73) // Instruction is rte
- return ReturnEx;
- else
- return NormalOp;
- }
-
- bool C68KDebug::GetJumpAddr(UINT32 addr, UINT32 opcode, UINT32 &jumpAddr)
- {
- if ((opcode>>7) == 0x009D)
- {
- // Instruction is jmp or jsr
- UINT8 addrMode = (UINT8)(opcode&0x3F);
- UINT8 mode = (addrMode>>3)&0x07;
- UINT8 reg = addrMode&0x07;
- if (mode == 0x07)
- {
- if (reg == 0x00)
- {
- jumpAddr = (UINT32)ReadMem(addr + 2, 4);
- return true;
- }
- else if (reg == 0x01)
- {
- jumpAddr = (UINT32)ReadMem(addr + 2, 4);
- return true;
- }
- }
- return false;
- }
- else if ((opcode>>12) == 0x0006)
- {
- // Instruction is bra, bsr or bCC
- INT8 i8 = (INT8)(opcode&0xFF);
- if (i8 == 0x00)
- jumpAddr = addr + 2 + (INT16)ReadMem(addr + 2, 2);
- else
- jumpAddr = addr + 2 + i8;
- return true;
- }
- else if ((opcode&0xF0F8) == 0x50C8)
- {
- // Instruction is dbCC
- jumpAddr = addr + 2 + (INT16)ReadMem(addr + 2, 2);
- return true;
- }
- else
- return false;
- }
-
- bool C68KDebug::GetJumpRetAddr(UINT32 addr, UINT32 opcode, UINT32 &retAddr)
- {
- if ((opcode>>6) == 0x013B)
- {
- // Instruction is jsr
- UINT8 addrMode = (UINT8)(opcode&0x3F);
- UINT8 mode = (addrMode>>3)&0x07;
- UINT8 reg = addrMode&0x07;
- if (mode == 0x05 || mode == 0x06)
- retAddr = addr + 2;
- else if (mode == 0x07)
- {
- if (reg == 0x00 || reg == 0x02 || reg == 0x03)
- retAddr = addr + 2;
- else if (reg == 0x01)
- retAddr = addr + 4;
- else
- retAddr = addr;
- }
- else
- retAddr = addr;
- return true;
- }
- else if ((opcode>>8) == 0x0061)
- {
- // Instruction is bsr
- if ((opcode&0xFF) == 0x00)
- retAddr = addr + 4;
- else
- retAddr = addr + 2;
- return true;
- }
- return false;
- }
-
- bool C68KDebug::GetReturnAddr(UINT32 addr, UINT32 opcode, UINT32 &retAddr)
- {
- // Check opcode is rtr, rts or rte
- if (opcode != 0x4E74 && opcode != 0x4E75 && opcode != 0x4E73)
- return false;
- // Return address will be at top of stack for rts and stack + 2 for rtr or rte
- UINT32 sp = GetSP();
- if (opcode == 0x4E75)
- retAddr = (UINT32)ReadMem(sp, 4);
- else
- retAddr = (UINT32)ReadMem(sp + 2, 4);
- return true;
- }
-
- bool C68KDebug::GetHandlerAddr(CException *ex, UINT32 &handlerAddr)
- {
- UINT32 vecAddr = ex->code * 4;
- handlerAddr = (UINT32)ReadMem(vecAddr, 4);
- return !!handlerAddr;
- }
-
- bool C68KDebug::GetHandlerAddr(CInterrupt *in, UINT32 &handlerAddr)
- {
- UINT32 vecAddr = (in->code + 25) * 4;
- handlerAddr = (UINT32)ReadMem(vecAddr, 4);
- return !!handlerAddr;
- }
-}
-
-#endif // SUPERMODEL_DEBUGGER
\ No newline at end of file
+
+ if (instr == NULL)
+ goto invalid;
+
+ // Split instruction into mnemonic and operands and substitute any data and address mode tags
+ const char *p, *q;
+ char *r;
+ char opsCopy[255];
+ char sizeC;
+ UINT8 addrMode;
+ int part;
+ EOpFlags opFlags;
+
+ // TODO - address mode masks for each instruction
+
+ q = instr;
+ if (p = strchr(q, ' '))
+ {
+ // Split instruction
+ strncpy(mnemonic, instr, p - q);
+ mnemonic[p - q] = '\0';
+ operands[0] = '\0';
+ opsCopy[0] = '\0';
+
+ // Get size character in nmnemonic, if any, otherwise assume word
+ if (q = strchr(mnemonic, '.'))
+ sizeC = tolower(q[1]);
+ else
+ sizeC = 'w';
+
+ // Substitute any data tags
+ q = p + 1;
+ r = opsCopy;
+ while (p = strchr(q, '['))
+ {
+ strncpy(r, q, p - q);
+ r[p - q] = '\0';
+ r += strlen(r);
+
+ // TODO - get rid of part indices - not needed for 68000 instruction set (only needed for 020 or 030 etc)
+ if (sscanf(p, "[BN%d]", &part) == 1 ||
+ sscanf(p, "[DB%d]", &part) == 1 || sscanf(p, "[DW%d]", &part) == 1 || sscanf(p, "[DL%d]", &part) == 1)
+ {
+ // Bit number or byte, word or long immediate data
+ if (p[2] == 'N')
+ {
+ // Check first byte is zero
+ u8 = (UINT8)ReadMem(addr + offset++, 1);
+ if (u8 != 0)
+ {
+ offset++;
+ goto invalid;
+ }
+ // Get data byte
+ u8 = (UINT8)ReadMem(addr + offset++, 1);
+ // Check top 3 bits are zero
+ if (u8&0xE0)
+ goto invalid;
+ FormatData(r, 1, u8);
+ //sprintf(r, "0x%02X", u8);
+ }
+ else if (p[2] == 'B')
+ {
+ // Check first byte is zero
+ u8 = (UINT8)ReadMem(addr + offset++, 1);
+ if (u8 != 0)
+ {
+ offset++;
+ goto invalid;
+ }
+ // Get data byte
+ u8 = (UINT8)ReadMem(addr + offset++, 1);
+ FormatData(r, 1, u8);
+ //i8 = (INT8)ReadMem(addr + offset++, 1);
+ //if (i8 < 0)
+ //{
+ // *r++ = '-';
+ // FormatData(r, 1, -i8);
+ // //sprintf(r, "-0x%02X", -i8);
+ //}
+ //else
+ //{
+ // FormatData(r, 1, i8);
+ // //sprintf(r, "0x%02X", i8);
+ //}
+ }
+ else if (p[2] == 'W')
+ {
+ u16 = (UINT16)ReadMem(addr + offset, 2);
+ offset += 2;
+ FormatData(r, 2, u16);
+ //i16 = (INT16)ReadMem(addr + offset, 2);
+ //offset += 2;
+ //if (i16 < 0)
+ //{
+ // *r++ = '-';
+ // FormatData(r, 2, -i16);
+ // //sprintf(r, "-0x%04X", -i16);
+ //}
+ //else
+ //{
+ // FormatData(r, 2, i16);
+ // //sprintf(r, "0x%04X", i16);
+ //}
+ }
+ else
+ {
+ u32 = (UINT32)ReadMem(addr + offset, 4);
+ offset += 4;
+ FormatData(r, 4, u32);
+ //i32 = (INT32)ReadMem(addr + offset, 4);
+ //offset += 4;
+ //if (i32 < 0)
+ //{
+ // *r++ = '-';
+ // FormatData(r, 4, -i32);
+ // //sprintf(r, "-0x%08X", -i32);
+ //}
+ //else
+ //{
+ // FormatData(r, 4, i32);
+ // //sprintf(r, "0x%08X", i32);
+ //}
+ }
+ q = p + 5;
+ r += strlen(r);
+ }
+ else if (sscanf(p, "[LL%d]", &part) == 1) // TODO - this should be LW
+ {
+ // Fixed width label offset
+ i16 = (INT16)ReadMem(addr + offset, 2);
+ offset += 2;
+ // Offset is from PC + 2
+ opFlags = GetOpFlags(addr, opcode);
+ FormatJumpAddress(r, addr + 2 + i16, opFlags);
+ //sprintf(r, "0x%06X", addr + 2 + i16); // Format this way as memory bus width is only 24-bits
+ q = p + 5;
+ r += strlen(r);
+ }
+ else if (sscanf(p, "[LV%d]", &part) == 1)
+ {
+ // Variable width label offset
+ i8 = (INT8)(opcode&0xFF);
+ INT32 labOffset;
+ if (i8 == 0x00)
+ {
+ i16 = (INT16)ReadMem(addr + offset, 2);
+ offset += 2;
+ labOffset = i16;
+ }
+ // Following 68020+ only
+ //else if (i8 == 0xFF)
+ //{
+ // i32 = (INT32)ReadMem(addr + offset, 4);
+ // offset += 4;
+ // labOffset = i32;
+ //*/
+ else
+ labOffset = i8;
+ // Offset is from PC + 2
+ opFlags = GetOpFlags(addr, opcode);
+ FormatJumpAddress(r, addr + 2 + labOffset, opFlags);
+ //sprintf(r, "0x%06X", addr + 2 + labOffset); // Format this way as memory bus width is only 24-bits
+ q = p + 5;
+ r += strlen(r);
+ }
+ else
+ {
+ // TODO - if not AM or AR, goto invalid
+ q = p + 1;
+ r += strlen(r);
+ *r++ = '[';
+ *r = '\0';
+ }
+ }
+ strcat(r, q);
+
+ // Substitute any address mode tags
+ q = opsCopy;
+ r = operands;
+ while (p = strchr(q, '['))
+ {
+ strncpy(r, q, p - q);
+ r[p - q] = '\0';
+ r += strlen(r);
+
+ if (sscanf(p, "[AM%d]", &part) == 1 || sscanf(p, "[AR%d]", &part) == 1)
+ {
+ // Part index must be 1 or 2
+ if (part == 1)
+ addrMode = (UINT8)((opcode >> 6) & 0x3F);
+ else if (part == 2)
+ addrMode = (UINT8)(opcode & 0x3F);
+ else
+ goto invalid;
+ // Check if address mode parts are reversed
+ if (p[2] == 'R')
+ {
+ // If so, swap 3-bit mode and register info
+ addrMode = ((addrMode&0x7)<<3) | ((addrMode>>3)&0x7);
+ }
+ if (!FormatAddrMode(addr, opcode, offset, addrMode, sizeC, r))
+ goto invalid;
+ q = p + 5;
+ r += strlen(r);
+ }
+ else
+ {
+ q = p + 1;
+ r += strlen(r);
+ *r++ = '[';
+ *r = '\0';
+ }
+ }
+ strcat(r, q);
+ }
+ else
+ {
+ // Empty operands
+ strcpy(mnemonic, instr);
+ operands[0] = '\0';
+ }
+ return offset;
+
+ invalid:
+ mnemonic[0] = '\0';
+ operands[0] = '\0';
+ return -offset;
+ }
+
+ bool C68KDebug::FormatAddrMode(UINT32 addr, UINT32 opcode, int &offset, UINT8 addrMode, char sizeC, char *dest)
+ {
+ UINT8 mode = (addrMode>>3)&0x07;
+ UINT8 reg = addrMode&0x07;
+ char dataStr[20];
+ UINT8 ofsReg;
+ char ofsRegC, ofsSizeC;
+ INT8 i8;
+ INT16 i16;
+ INT32 i32;
+ UINT8 u8;
+ UINT16 u16;
+ UINT32 u32;
+ EOpFlags opFlags;
+ switch (mode)
+ {
+ case 0x00: // Dn
+ sprintf(dest, "D%u", reg);
+ break;
+ case 0x01: // An
+ sprintf(dest, "A%u", reg);
+ break;
+ case 0x02: // (An)
+ sprintf(dest, "(A%u)", reg);
+ break;
+ case 0x03: // (An)+
+ sprintf(dest, "(A%u)+", reg);
+ break;
+ case 0x04: // -(An)
+ sprintf(dest, "-(A%u)", reg);
+ break;
+ case 0x05: // (d16,An)
+ i16 = (INT16)ReadMem(addr + offset, 2);
+ offset += 2;
+ if (i16 < 0)
+ {
+ FormatData(dataStr, 2, -i16);
+ sprintf(dest, "(-%s,A%u)", dataStr, reg);
+ //sprintf(dest, "(-0x%04X,A%u)", -i16, reg);
+ }
+ else
+ {
+ FormatData(dataStr, 2, i16);
+ sprintf(dest, "(%s,A%u)", dataStr, reg);
+ //sprintf(dest, "(0x%04X,A%u)", i16, reg);
+ }
+ break;
+ case 0x06: // (d8,An,Ri.z)
+ u8 = (UINT8)ReadMem(addr + offset++, 1);
+ // Check first 3-bits of first byte are zero
+ if (u8&0x7)
+ {
+ offset++;
+ return false;
+ }
+ // Get second offset register type, number and size (w or l)
+ ofsReg = (u8>>4)&0xF;
+ if (ofsReg < 8)
+ ofsRegC = 'D';
+ else
+ {
+ ofsRegC = 'A';
+ ofsReg -= 8;
+ }
+ ofsSizeC = (u8&0x8 ? 'l' : 'w');
+ i8 = (INT8)ReadMem(addr + offset++, 1);
+ if (i8 < 0)
+ {
+ FormatData(dataStr, 1, -i8);
+ sprintf(dest, "(-%s,A%u,%c%u.%c)", dataStr, reg, ofsRegC, ofsReg, ofsSizeC);
+ //sprintf(dest, "(-0x%02X,A%u,%c%u.%c)", -i8, reg, ofsRegC, ofsReg, ofsSizeC);
+ }
+ else
+ {
+ FormatData(dataStr, 1, i8);
+ sprintf(dest, "(%s,A%u,%c%u.%c)", dataStr, reg, ofsRegC, ofsReg, ofsSizeC);
+ //sprintf(dest, "(0x%02X,A%u,%c%u.%c)", i8, reg, ofsRegC, ofsReg, ofsSizeC);
+ }
+ break;
+ case 0x07:
+ switch (reg)
+ {
+ case 0x00: // addr16
+ u16 = (UINT16)ReadMem(addr + offset, 2);
+ offset += 2;
+ opFlags = GetOpFlags(addr, opcode);
+ FormatJumpAddress(dest, u16, opFlags);
+ //sprintf(dest, "0x%06X", u16); // Format this way as memory bus width is 24-bits
+ break;
+ case 0x01: // addr32
+ u32 = (UINT32)ReadMem(addr + offset, 4);
+ offset += 4;
+ opFlags = GetOpFlags(addr, opcode);
+ FormatJumpAddress(dest, u32, opFlags);
+ //sprintf(dest, "0x%06X", u32); // Format this way as memory bus width is only 24-bits
+ break;
+ case 0x02: // d16(PC)
+ i16 = (INT16)ReadMem(addr + offset, 2);
+ offset += 2;
+ if (i16 < 0)
+ {
+ FormatData(dataStr, 2, -i16);
+ sprintf(dest, "-%s(PC)", dataStr);
+ //sprintf(dest, "-0x%04X(PC)", -i16);
+ }
+ else
+ {
+ FormatData(dataStr, 2, i16);
+ sprintf(dest, "%s(PC)", dataStr);
+ //sprintf(dest, "0x%04X(PC)", i16);
+ }
+ break;
+ case 0x03: // u8(PC,Ri.x)
+ u8 = (UINT8)ReadMem(addr + offset++, 1);
+ // Check first 3-bits of first byte are zero
+ if (u8&0x7)
+ {
+ offset++;
+ return false;
+ }
+ // Get second offset register type, number and size (w or l)
+ ofsReg = (u8>>4)&0xF;
+ if (ofsReg < 8)
+ ofsRegC = 'D';
+ else
+ {
+ ofsRegC = 'A';
+ ofsReg -= 8;
+ }
+ ofsSizeC = (u8&0x8 ? 'l' : 'w');
+ i8 = (INT8)ReadMem(addr + offset++, 1);
+ if (i8 < 0)
+ {
+ FormatData(dataStr, 1, -i8);
+ sprintf(dest, "-%s(PC,%c%u.%c)", dataStr, ofsRegC, ofsReg, ofsSizeC);
+ //sprintf(dest, "-0x%02X(PC,%c%u.%c)", -i8, ofsRegC, ofsReg, ofsSizeC);
+ }
+ else
+ {
+ FormatData(dataStr, 1, i8);
+ sprintf(dest, "%s(PC,%c%u.%c)", dataStr, ofsRegC, ofsReg, ofsSizeC);
+ //sprintf(dest, "0x%02X(PC,%c%u.%c)", i8, ofsRegC, ofsReg, ofsSizeC);
+ }
+ break;
+ case 0x04: // immediate data, implied size
+ if (sizeC == 'b')
+ {
+ // Check first byte is zero
+ u8 = (UINT8)ReadMem(addr + offset++, 1);
+ if (u8 != 0)
+ {
+ offset++;
+ return false;
+ }
+ // Get data byte
+ u8 = (UINT8)ReadMem(addr + offset++, 1);
+ FormatData(dataStr, 1, u8);
+ sprintf(dest, "#%s", dataStr);
+ //i8 = (INT8)ReadMem(addr + offset++, 1);
+ //if (i8 < 0)
+ //{
+ // FormatData(dataStr, 1, -i8);
+ // sprintf(dest, "#-%s", dataStr);
+ // //sprintf(dest, "#-0x%02X", -i8);
+ //}
+ //else
+ //{
+ // FormatData(dataStr, 1, i8);
+ // sprintf(dest, "#%s", dataStr);
+ // //sprintf(dest, "#0x%02X", i8);
+ //}
+ }
+ else if (sizeC == 'w')
+ {
+ u16 = (UINT16)ReadMem(addr + offset, 2);
+ offset += 2;
+ FormatData(dataStr, 2, u16);
+ sprintf(dest, "#%s", dataStr);
+ //i16 = (INT16)ReadMem(addr + offset, 2);
+ //offset += 2;
+ //if (i16 < 0)
+ //{
+ // FormatData(dataStr, 2, -i16);
+ // sprintf(dest, "#-%s", dataStr);
+ // //sprintf(dest, "#-0x%04X", -i16);
+ //}
+ //else
+ //{
+ // FormatData(dataStr, 2, i16);
+ // sprintf(dest, "#%s", dataStr);
+ // //sprintf(dest, "#0x%04X", i16);
+ //}
+ }
+ else if (sizeC == 'l')
+ {
+ u32 = (UINT32)ReadMem(addr + offset, 4);
+ offset += 4;
+ FormatData(dataStr, 4, u32);
+ sprintf(dest, "#%s", dataStr);
+ //i32 = (INT32)ReadMem(addr + offset, 4);
+ //offset += 4;
+ //if (i32 < 0)
+ //{
+ // FormatData(dataStr, 4, -i32);
+ // sprintf(dest, "#-%s", dataStr);
+ // //sprintf(dest, "#-0x%08X", -i32);
+ //}
+ //else
+ //{
+ // FormatData(dataStr, 4, i32);
+ // sprintf(dest, "#%s", dataStr);
+ // //sprintf(dest, "#0x%08X", i32);
+ //}
+ }
+ else
+ return false;
+ break;
+ default:
+ return false;
+ }
+ break;
+ default:
+ return false;
+ }
+ return true;
+ }
+
+ EOpFlags C68KDebug::GetOpFlags(UINT32 addr, UINT32 opcode)
+ {
+ UINT32 head = opcode>>6;
+ if (head == 0x013A) // Instruction is jmp
+ return JumpSimple;
+ else if (head == 0x013B) // Instruction is jsr
+ return JumpSub;
+ else if ((opcode>>12) == 0x0006) // Instruction is bra, bsr or bCC
+ {
+ UINT32 cond = (opcode>>8)&0x000F;
+ if (cond == 0x0000) // Instruction is bra
+ return (EOpFlags)(JumpSimple | Relative);
+ else if (cond == 0x0001) // Instruction is bsr
+ return (EOpFlags)(JumpSub | Relative);
+ else // Instruction is bCC
+ return (EOpFlags)(JumpSimple | Relative | Conditional);
+ }
+ else if ((opcode&0xF0F8) == 0x50C8) // Instruction is dbCC
+ return (EOpFlags)(JumpLoop | Relative | Conditional);
+ else if (opcode == 0x4E74 || opcode == 0x4E75) // Instruction is rtr or rts
+ return ReturnSub;
+ else if (opcode == 0x4E73) // Instruction is rte
+ return ReturnEx;
+ else
+ return NormalOp;
+ }
+
+ bool C68KDebug::GetJumpAddr(UINT32 addr, UINT32 opcode, UINT32 &jumpAddr)
+ {
+ if ((opcode>>7) == 0x009D)
+ {
+ // Instruction is jmp or jsr
+ UINT8 addrMode = (UINT8)(opcode&0x3F);
+ UINT8 mode = (addrMode>>3)&0x07;
+ UINT8 reg = addrMode&0x07;
+ if (mode == 0x07)
+ {
+ if (reg == 0x00)
+ {
+ jumpAddr = (UINT32)ReadMem(addr + 2, 4);
+ return true;
+ }
+ else if (reg == 0x01)
+ {
+ jumpAddr = (UINT32)ReadMem(addr + 2, 4);
+ return true;
+ }
+ }
+ return false;
+ }
+ else if ((opcode>>12) == 0x0006)
+ {
+ // Instruction is bra, bsr or bCC
+ INT8 i8 = (INT8)(opcode&0xFF);
+ if (i8 == 0x00)
+ jumpAddr = addr + 2 + (INT16)ReadMem(addr + 2, 2);
+ else
+ jumpAddr = addr + 2 + i8;
+ return true;
+ }
+ else if ((opcode&0xF0F8) == 0x50C8)
+ {
+ // Instruction is dbCC
+ jumpAddr = addr + 2 + (INT16)ReadMem(addr + 2, 2);
+ return true;
+ }
+ else
+ return false;
+ }
+
+ bool C68KDebug::GetJumpRetAddr(UINT32 addr, UINT32 opcode, UINT32 &retAddr)
+ {
+ if ((opcode>>6) == 0x013B)
+ {
+ // Instruction is jsr
+ UINT8 addrMode = (UINT8)(opcode&0x3F);
+ UINT8 mode = (addrMode>>3)&0x07;
+ UINT8 reg = addrMode&0x07;
+ if (mode == 0x05 || mode == 0x06)
+ retAddr = addr + 2;
+ else if (mode == 0x07)
+ {
+ if (reg == 0x00 || reg == 0x02 || reg == 0x03)
+ retAddr = addr + 2;
+ else if (reg == 0x01)
+ retAddr = addr + 4;
+ else
+ retAddr = addr;
+ }
+ else
+ retAddr = addr;
+ return true;
+ }
+ else if ((opcode>>8) == 0x0061)
+ {
+ // Instruction is bsr
+ if ((opcode&0xFF) == 0x00)
+ retAddr = addr + 4;
+ else
+ retAddr = addr + 2;
+ return true;
+ }
+ return false;
+ }
+
+ bool C68KDebug::GetReturnAddr(UINT32 addr, UINT32 opcode, UINT32 &retAddr)
+ {
+ // Check opcode is rtr, rts or rte
+ if (opcode != 0x4E74 && opcode != 0x4E75 && opcode != 0x4E73)
+ return false;
+ // Return address will be at top of stack for rts and stack + 2 for rtr or rte
+ UINT32 sp = GetSP();
+ if (opcode == 0x4E75)
+ retAddr = (UINT32)ReadMem(sp, 4);
+ else
+ retAddr = (UINT32)ReadMem(sp + 2, 4);
+ return true;
+ }
+
+ bool C68KDebug::GetHandlerAddr(CException *ex, UINT32 &handlerAddr)
+ {
+ UINT32 vecAddr = ex->code * 4;
+ handlerAddr = (UINT32)ReadMem(vecAddr, 4);
+ return !!handlerAddr;
+ }
+
+ bool C68KDebug::GetHandlerAddr(CInterrupt *in, UINT32 &handlerAddr)
+ {
+ UINT32 vecAddr = (in->code + 25) * 4;
+ handlerAddr = (UINT32)ReadMem(vecAddr, 4);
+ return !!handlerAddr;
+ }
+}
+
+#endif // SUPERMODEL_DEBUGGER
diff --git a/Src/OSD/Logger.cpp b/Src/OSD/Logger.cpp
index 4e63e6ee..954254b6 100644
--- a/Src/OSD/Logger.cpp
+++ b/Src/OSD/Logger.cpp
@@ -239,8 +239,8 @@ void CFileLogger::DebugLog(const char *fmt, va_list vl)
char string1[4096];
char string2[4096];
- vsprintf(string1, fmt, vl);
- sprintf(string2, "[Debug] %s", string1);
+ vsnprintf(string1, sizeof(string1), fmt, vl);
+ snprintf(string2, sizeof(string2), "[Debug] %s", string1);
// Debug logging is so copious that we don't bother to guarantee it is saved
std::unique_lock lock(m_mtx);
@@ -257,8 +257,8 @@ void CFileLogger::InfoLog(const char *fmt, va_list vl)
char string1[4096];
char string2[4096];
- vsprintf(string1, fmt, vl);
- sprintf(string2, "[Info] %s\n", string1);
+ vsnprintf(string1, sizeof(string1), fmt, vl);
+ snprintf(string2, sizeof(string2), "[Info] %s\n", string1);
// Write to file, close, and reopen to ensure it was saved
std::unique_lock lock(m_mtx);
@@ -276,8 +276,8 @@ void CFileLogger::ErrorLog(const char *fmt, va_list vl)
char string1[4096];
char string2[4096];
- vsprintf(string1, fmt, vl);
- sprintf(string2, "[Error] %s\n", string1);
+ vsnprintf(string1, sizeof(string1), fmt, vl);
+ snprintf(string2, sizeof(string2), "[Error] %s\n", string1);
// Write to file, close, and reopen to ensure it was saved
std::unique_lock lock(m_mtx);
@@ -347,8 +347,8 @@ void CSystemLogger::DebugLog(const char *fmt, va_list vl)
char string1[4096];
char string2[4096];
- vsprintf(string1, fmt, vl);
- sprintf(string2, "[Debug] %s", string1);
+ vsnprintf(string1, sizeof(string1), fmt, vl);
+ snprintf(string2, sizeof(string2), "[Debug] %s", string1);
#ifdef _WIN32
OutputDebugString(string2);
@@ -367,8 +367,8 @@ void CSystemLogger::InfoLog(const char *fmt, va_list vl)
char string1[4096];
char string2[4096];
- vsprintf(string1, fmt, vl);
- sprintf(string2, "[Info] %s\n", string1);
+ vsnprintf(string1, sizeof(string1), fmt, vl);
+ snprintf(string2, sizeof(string2), "[Info] %s\n", string1);
#ifdef _WIN32
OutputDebugString(string2);
@@ -387,8 +387,8 @@ void CSystemLogger::ErrorLog(const char *fmt, va_list vl)
char string1[4096];
char string2[4096];
- vsprintf(string1, fmt, vl);
- sprintf(string2, "[Error] %s\n", string1);
+ vsnprintf(string1, sizeof(string1), fmt, vl);
+ snprintf(string2, sizeof(string2), "[Error] %s\n", string1);
#ifdef _WIN32
OutputDebugString(string2);
diff --git a/Src/OSD/SDL/Main.cpp b/Src/OSD/SDL/Main.cpp
index dc37b669..806e3df3 100644
--- a/Src/OSD/SDL/Main.cpp
+++ b/Src/OSD/SDL/Main.cpp
@@ -919,7 +919,7 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
// Set the video mode
char baseTitleStr[128];
- char titleStr[128];
+ char titleStr[256];
totalXRes = xRes = s_runtime_config["XResolution"].ValueAs();
totalYRes = yRes = s_runtime_config["YResolution"].ValueAs();
sprintf(baseTitleStr, "Supermodel - %s", game.title.c_str());
@@ -1089,7 +1089,7 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
{
Model3->PauseThreads();
SetAudioEnabled(false);
- sprintf(titleStr, "%s (Paused)", baseTitleStr);
+ snprintf(titleStr, sizeof(titleStr), "%s (Paused)", baseTitleStr);
SDL_SetWindowTitle(s_window, titleStr);
}
else
@@ -1303,7 +1303,7 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
if (measurementTicks >= s_perfCounterFrequency) // update FPS every 1 second (s_perfCounterFrequency is how many perf ticks in one second)
{
float fps = float(fpsFramesElapsed) / (float(measurementTicks) / float(s_perfCounterFrequency));
- sprintf(titleStr, "%s - %1.3f FPS%s", baseTitleStr, fps, paused ? " (Paused)" : "");
+ snprintf(titleStr, sizeof(titleStr), "%s - %1.3f FPS%s", baseTitleStr, fps, paused ? " (Paused)" : "");
SDL_SetWindowTitle(s_window, titleStr);
prevFPSTicks = currentFPSTicks; // reset tick count
fpsFramesElapsed = 0; // reset frame count