From 4042cdd42b239e05067de1cec33d80238450979f Mon Sep 17 00:00:00 2001 From: firewave Date: Sat, 2 Dec 2023 19:13:52 +0100 Subject: [PATCH] fixed `-Wformat-overflow` compiler warnings and switched to `*snprintf()` --- Src/Debugger/CPU/68KDebug.cpp | 1652 ++++++++++++++++----------------- Src/OSD/Logger.cpp | 24 +- Src/OSD/SDL/Main.cpp | 6 +- 3 files changed, 841 insertions(+), 841 deletions(-) diff --git a/Src/Debugger/CPU/68KDebug.cpp b/Src/Debugger/CPU/68KDebug.cpp index 66619801..814af774 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; - } -} - + + 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 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