diff --git a/source/Debugger/Debug.cpp b/source/Debugger/Debug.cpp index 9359da68a..6e05af2f3 100644 --- a/source/Debugger/Debug.cpp +++ b/source/Debugger/Debug.cpp @@ -3361,7 +3361,7 @@ Update_t CmdDisk ( int nArgs) if (nArgs > 2) return HelpLastCommand(); - char buffer[200] = ""; + char buffer[200] = ""; // HACK: Magic number TODO: Should be MAX_CONSOLE_WIDTH*2 ConsoleBufferPushFormat(buffer, "FW%2d: D%d at T$%s, phase $%s, offset $%X, mask $%02X, extraCycles %.2f, %s", diskCard.GetCurrentFirmware(), diskCard.GetCurrentDrive() + 1, diff --git a/source/Debugger/Debugger_Assembler.cpp b/source/Debugger/Debugger_Assembler.cpp index c86483e1d..6578ec986 100644 --- a/source/Debugger/Debugger_Assembler.cpp +++ b/source/Debugger/Debugger_Assembler.cpp @@ -509,6 +509,7 @@ int _6502_GetOpmodeOpbyte ( const int nBaseAddress, int & iOpmode_, int & nOpby case NOP_BYTE_2: nOpbyte_ = 2; iOpmode_ = AM_M; break; case NOP_BYTE_4: nOpbyte_ = 4; iOpmode_ = AM_M; break; case NOP_BYTE_8: nOpbyte_ = 8; iOpmode_ = AM_M; break; + case NOP_FAC : nOpbyte_ = 5; iOpmode_ = AM_M; break; case NOP_WORD_1: nOpbyte_ = 2; iOpmode_ = AM_M; break; case NOP_WORD_2: nOpbyte_ = 4; iOpmode_ = AM_M; break; case NOP_WORD_4: nOpbyte_ = 8; iOpmode_ = AM_M; break; diff --git a/source/Debugger/Debugger_Assembler.h b/source/Debugger/Debugger_Assembler.h index 56dddcb48..16fa7d2ae 100644 --- a/source/Debugger/Debugger_Assembler.h +++ b/source/Debugger/Debugger_Assembler.h @@ -100,6 +100,7 @@ ,NUM_ASM_W_DIRECTIVES }; + // NOTE: Keep in sync! AsmCustomDirective_e g_aAssemblerDirectives enum AsmCustomDirective_e { ASM_DEFINE_BYTE diff --git a/source/Debugger/Debugger_Commands.cpp b/source/Debugger/Debugger_Commands.cpp index abd55a8e0..7aef5b76d 100644 --- a/source/Debugger/Debugger_Commands.cpp +++ b/source/Debugger/Debugger_Commands.cpp @@ -140,7 +140,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA {TEXT("DW2") , CmdDisasmDataDefWord2 , CMD_DEFINE_DATA_WORD2, "Define address array, display 2 words/line" }, {TEXT("DW4") , CmdDisasmDataDefWord4 , CMD_DEFINE_DATA_WORD4, "Define address array, display 4 words/line" }, {TEXT("ASC") , CmdDisasmDataDefString , CMD_DEFINE_DATA_STR , "Define text string" }, // 2.7.0.26 Changed: DS to ASC because DS is used as "Define Space" assembler directive -// {TEXT("DF") , CmdDisasmDataDefFloat , CMD_DEFINE_DATA_FLOAT, "Define AppleSoft (packed) Float" }, + {TEXT("DF") , CmdDisasmDataDefFloat , CMD_DEFINE_DATA_FLOAT, "Define AppleSoft (packed) Float" }, // {TEXT("DFX") , CmdDisasmDataDefFloatUnpack , CMD_DEFINE_DATA_FLOAT2,"Define AppleSoft (unpacked) Float" }, // with symbol lookup // {TEXT("DA<>") , CmdDisasmDataDefAddress8HL , CMD_DEFINE_ADDR_8_HL , "Define split array of addresses, high byte section followed by low byte section" }, @@ -148,7 +148,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // {TEXT("DA<") , CmdDisasmDataDefAddress8H , CMD_DEFINE_ADDR_BYTE_H , "Define array of high byte addresses" }, // {TEXT("DB>") , CmdDisasmDataDefAddress8L , CMD_DEFINE_ADDR_BYTE_L , "Define array of low byte addresses" } {TEXT("DA") , CmdDisasmDataDefAddress16 , CMD_DEFINE_ADDR_WORD , "Define array of word addresses" }, -// TODO: Rename config cmd: DISASM +// TODO: Rename config cmd: DISASM or ID (Interactive Disassembly) // {TEXT("UA") , CmdDisasmDataSmart , CMD_SMART_DISASSEMBLE, "Analyze opcodes to determine if code or data" }, // Disk {TEXT("DISK") , CmdDisk , CMD_DISK , "Access Disk Drive Functions" }, diff --git a/source/Debugger/Debugger_Disassembler.cpp b/source/Debugger/Debugger_Disassembler.cpp index 7f7372122..6c8e12981 100644 --- a/source/Debugger/Debugger_Disassembler.cpp +++ b/source/Debugger/Debugger_Disassembler.cpp @@ -466,6 +466,45 @@ void FormatOpcodeBytes(WORD nBaseAddress, DisasmLine_t& line_) } } +struct FAC_t +{ + uint8_t negative; + int8_t exponent; + uint32_t mantissa; + + bool isZero; +}; + +void FAC_Unpack(WORD nAddress, FAC_t& fac_) +{ + BYTE e0 = *(LPBYTE)(mem + nAddress + 0); + BYTE m1 = *(LPBYTE)(mem + nAddress + 1); + BYTE m2 = *(LPBYTE)(mem + nAddress + 2); + BYTE m3 = *(LPBYTE)(mem + nAddress + 3); + BYTE m4 = *(LPBYTE)(mem + nAddress + 4); + + // sign + // EB82:A5 9D SIGN LDA FAC + // EB84:F0 09 BEQ SIGN3 ; zero + // EB86:A5 A2 SIGN1 LDA FAC.SIGN + // EB88:2A SIGN2 ROL + // EB89:A9 FF LDA #$FF ; negative + // EB8B:B0 02 BCS SIGN3 + // EB8D:A9 01 LDA #$01 ; positive + // EB8F:60 SIGN3 + + fac_.exponent = e0 - 0x80; + fac_.negative =(m1 & 0x80) >> 7; // EBAF:46 A2 ABS LSR FAC.SIGN + fac_.mantissa = 0 + | ((m1 | 0x80) << 24) // implicit 1.0, EB12: ORA #$80, STA FAC+1 + | ((m2 ) << 16) + | ((m3 ) << 8) + | ((m4 ) << 0); + + fac_.isZero = (e0 == 0); // TODO: need to check mantissa? +} + + // Formats Target string with bytes,words, string, etc... //=========================================================================== void FormatNopcodeBytes(WORD nBaseAddress, DisasmLine_t& line_) @@ -473,85 +512,106 @@ void FormatNopcodeBytes(WORD nBaseAddress, DisasmLine_t& line_) char* pDst = line_.sTarget; const char* pSrc = 0; DWORD nStartAddress = line_.pDisasmData->nStartAddress; - DWORD nEndAddress = line_.pDisasmData->nEndAddress; + DWORD nEndAddress = line_.pDisasmData->nEndAddress; // int nDataLen = nEndAddress - nStartAddress + 1 ; int nDisplayLen = nEndAddress - nBaseAddress + 1; // *inclusive* KEEP IN SYNC: _CmdDefineByteRange() CmdDisasmDataList() _6502_GetOpmodeOpbyte() FormatNopcodeBytes() int len = nDisplayLen; for (int iByte = 0; iByte < line_.nOpbyte; ) { - BYTE nTarget8 = *(LPBYTE)(mem + nBaseAddress + iByte); + BYTE nTarget8 = *(LPBYTE)(mem + nBaseAddress + iByte); WORD nTarget16 = *(LPWORD)(mem + nBaseAddress + iByte); switch (line_.iNoptype) { - case NOP_BYTE_1: - case NOP_BYTE_2: - case NOP_BYTE_4: - case NOP_BYTE_8: - sprintf(pDst, "%02X", nTarget8); // sBytes+strlen(sBytes) - pDst += 2; - iByte++; - if (line_.iNoptype == NOP_BYTE_1) - if (iByte < line_.nOpbyte) + case NOP_BYTE_1: + case NOP_BYTE_2: + case NOP_BYTE_4: + case NOP_BYTE_8: + sprintf(pDst, "%02X", nTarget8); // sBytes+strlen(sBytes) + pDst += 2; + iByte++; + if (line_.iNoptype == NOP_BYTE_1) + if (iByte < line_.nOpbyte) + { + *pDst++ = ','; + } + break; + + case NOP_FAC: + { + FAC_t fac; + FAC_Unpack( nBaseAddress, fac ); + const char aSign[2] = { '+', '-' }; + if (fac.isZero) + sprintf( pDst, "0" ); + else { - *pDst++ = ','; + double f = fac.mantissa * pow( 2.0, fac.exponent - 32 ); + //sprintf( "s%1X m%04X e%02X", fac.negative, fac.mantissa, fac.exponent ); + sprintf( pDst, "%c%f", aSign[ fac.negative ], f ); } - break; - case NOP_WORD_1: - case NOP_WORD_2: - case NOP_WORD_4: - sprintf(pDst, "%04X", nTarget16); // sBytes+strlen(sBytes) - pDst += 4; - iByte += 2; - if (iByte < line_.nOpbyte) - { - *pDst++ = ','; + iByte += 5; + break; } - break; - case NOP_ADDRESS: - // Nothing to do, already handled :-) - iByte += 2; - break; - case NOP_STRING_APPLESOFT: - iByte = line_.nOpbyte; - strncpy(pDst, (const char*)(mem + nBaseAddress), iByte); - pDst += iByte; - *pDst = 0; - case NOP_STRING_APPLE: - iByte = line_.nOpbyte; // handle all bytes of text - pSrc = (const char*)mem + nStartAddress; - - if (len > (DISASM_DISPLAY_MAX_IMMEDIATE_LEN - 2)) // does "text" fit? - { - if (len > DISASM_DISPLAY_MAX_IMMEDIATE_LEN) // no; need extra characters for ellipsis? - len = (DISASM_DISPLAY_MAX_IMMEDIATE_LEN - 3); // ellipsis = true - // DISPLAY: text_longer_18... - FormatCharCopy(pDst, pSrc, len); // BUG: #251 v2.8.0.7: ASC #:# with null byte doesn't mark up properly - - if (nDisplayLen > len) // ellipsis + case NOP_WORD_1: + case NOP_WORD_2: + case NOP_WORD_4: + sprintf(pDst, "%04X", nTarget16); // sBytes+strlen(sBytes) + pDst += 4; + iByte += 2; + if (iByte < line_.nOpbyte) { - *pDst++ = '.'; - *pDst++ = '.'; - *pDst++ = '.'; + *pDst++ = ','; + } + break; + + case NOP_ADDRESS: + // Nothing to do, already handled :-) + iByte += 2; + break; + + case NOP_STRING_APPLESOFT: + iByte = line_.nOpbyte; + strncpy(pDst, (const char*)(mem + nBaseAddress), iByte); + pDst += iByte; + *pDst = 0; + case NOP_STRING_APPLE: + iByte = line_.nOpbyte; // handle all bytes of text + pSrc = (const char*)mem + nStartAddress; + + if (len > (DISASM_DISPLAY_MAX_IMMEDIATE_LEN - 2)) // does "text" fit? + { + if (len > DISASM_DISPLAY_MAX_IMMEDIATE_LEN) // no; need extra characters for ellipsis? + len = (DISASM_DISPLAY_MAX_IMMEDIATE_LEN - 3); // ellipsis = true + + // DISPLAY: text_longer_18... + FormatCharCopy(pDst, pSrc, len); // BUG: #251 v2.8.0.7: ASC #:# with null byte doesn't mark up properly + + if (nDisplayLen > len) // ellipsis + { + *pDst++ = '.'; + *pDst++ = '.'; + *pDst++ = '.'; + } + } + else { // DISPLAY: "max_18_char" + *pDst++ = '"'; + pDst = FormatCharCopy(pDst, pSrc, len); // BUG: #251 v2.8.0.7: ASC #:# with null byte doesn't mark up properly + *pDst++ = '"'; } - } - else { // DISPLAY: "max_18_char" - *pDst++ = '"'; - pDst = FormatCharCopy(pDst, pSrc, len); // BUG: #251 v2.8.0.7: ASC #:# with null byte doesn't mark up properly - *pDst++ = '"'; - } - *pDst = 0; - break; - default: -#if _DEBUG // Unhandled data disassembly! - int* FATAL = 0; - *FATAL = 0xDEADC0DE; -#endif - iByte++; - break; + *pDst = 0; + break; + + default: + #if _DEBUG // Unhandled data disassembly! + int* FATAL = 0; + *FATAL = 0xDEADC0DE; + #endif + iByte++; + break; } } } diff --git a/source/Debugger/Debugger_DisassemblerData.cpp b/source/Debugger/Debugger_DisassemblerData.cpp index 011530ec8..6ff7ddd96 100644 --- a/source/Debugger/Debugger_DisassemblerData.cpp +++ b/source/Debugger/Debugger_DisassemblerData.cpp @@ -40,6 +40,9 @@ void _GetAutoSymbolName ( const Nopcode_e &nopcode, const WORD nStartAddress, ch sprintf( pSymbolName, "A_%04X", nStartAddress ); // DA range break; + case NOP_FAC: + sprintf( pSymbolName, "F_%04X", nStartAddress ); // DF range + case NOP_STRING_ASCII: case NOP_STRING_APPLE: sprintf( pSymbolName, "T_%04X", nStartAddress ); // ASC range @@ -159,10 +162,12 @@ WORD _CmdDefineByteRange(int nArgs,int iArg,DisasmData_t & tData_) // Old name: auto define D_# DB $XX // Example 'DB' or 'DW' with 1 arg // DB 801 - if( bAutoDefineName ) - { Nopcode_e nopcode = NOP_BYTE_1; + bool isFloat = (g_iCommand == CMD_DEFINE_DATA_FLOAT); + if( isFloat ) + nopcode = NOP_FAC; + bool isString = (g_iCommand == CMD_DEFINE_DATA_STR); if( isString ) nopcode = NOP_STRING_ASCII; @@ -175,6 +180,8 @@ WORD _CmdDefineByteRange(int nArgs,int iArg,DisasmData_t & tData_) if( isAddr ) nopcode = NOP_ADDRESS; + if( bAutoDefineName ) + { _GetAutoSymbolName( nopcode, tData_.nStartAddress , aSymbolName ); pSymbolName = aSymbolName; } @@ -184,6 +191,10 @@ WORD _CmdDefineByteRange(int nArgs,int iArg,DisasmData_t & tData_) SymbolUpdate( eSymbolTable, pSymbolName, nAddress, false, true ); // TODO: Note: need to call ConsoleUpdate(), as may print symbol has been updated + + // NOTE: We don't set the type here + // tData_.eElementType = nopcode; + // As that is done by the caller. strcpy_s( tData_.sSymbol, sizeof(tData_.sSymbol), pSymbolName ); @@ -359,6 +370,11 @@ Update_t CmdDisasmDataList (int nArgs) } // Common code + + +// TODO: merge _CmdDisasmDataDefByteX() and _CmdDisasmDataDefWordX +// add params( iDirective, iOpcode ) to allow ASM_DEFINE_FLOAT, NOP_FAC + //=========================================================================== Update_t _CmdDisasmDataDefByteX (int nArgs) { @@ -469,6 +485,13 @@ Update_t CmdDisasmDataDefAddress8L (int nArgs) return UPDATE_DISASM; } +// Command: DA +// Description: Markup data as an address (i.e. table of function pointers) +// Usage: +// DA +// Example: +// DA D000 +// DA D000:D0B1 //=========================================================================== Update_t CmdDisasmDataDefAddress16 (int nArgs) { @@ -502,46 +525,72 @@ Update_t CmdDisasmDataDefAddress16 (int nArgs) return UPDATE_DISASM | ConsoleUpdate(); } -// DB +// Command: DB +// Usage: +// DB Update_t CmdDisasmDataDefByte1 ( int nArgs ) { g_aArgs[0].nValue = NOP_BYTE_1; return _CmdDisasmDataDefByteX( nArgs ); } -// DB2 +// Command: DB2 +// Usage: +// DB2 Update_t CmdDisasmDataDefByte2 ( int nArgs ) { g_aArgs[0].nValue = NOP_BYTE_2; return _CmdDisasmDataDefByteX( nArgs ); } +// Command: DB4 +// Usage: +// DB4 Update_t CmdDisasmDataDefByte4 ( int nArgs ) { g_aArgs[0].nValue = NOP_BYTE_4; return _CmdDisasmDataDefByteX( nArgs ); } +// Command DB8 +// Usage: +// DB8 Update_t CmdDisasmDataDefByte8 ( int nArgs ) { g_aArgs[0].nValue = NOP_BYTE_8; return _CmdDisasmDataDefByteX( nArgs ); } -// DW +// Command: DF +// Usage: +// DF +Update_t CmdDisasmDataDefFloat(int nArgs) +{ + g_aArgs[0].nValue = NOP_FAC; + return _CmdDisasmDataDefByteX( nArgs ); +} + +// Command: DW +// Usage: +// DW Update_t CmdDisasmDataDefWord1 ( int nArgs ) { g_aArgs[0].nValue = NOP_WORD_1; return _CmdDisasmDataDefWordX( nArgs ); } -// DW2 +// Command: DW2 +// Usage: +// DW2 Update_t CmdDisasmDataDefWord2 ( int nArgs ) { g_aArgs[0].nValue = NOP_WORD_2; return _CmdDisasmDataDefWordX( nArgs ); } +// Command: DW4 +// Usage: +// DW4 Update_t CmdDisasmDataDefWord4 ( int nArgs ) { g_aArgs[0].nValue = NOP_WORD_4; @@ -549,6 +598,8 @@ Update_t CmdDisasmDataDefWord4 ( int nArgs ) } // Command: DS +// Usage: +// DS // ASC range Auto-define T_#### where # is the address Update_t CmdDisasmDataDefString ( int nArgs ) { diff --git a/source/Debugger/Debugger_Types.h b/source/Debugger/Debugger_Types.h index 391e2ba4c..3e79fc6eb 100644 --- a/source/Debugger/Debugger_Types.h +++ b/source/Debugger/Debugger_Types.h @@ -398,6 +398,7 @@ , CMD_DEFINE_DATA_WORD2 , CMD_DEFINE_DATA_WORD4 , CMD_DEFINE_DATA_STR + , CMD_DEFINE_DATA_FLOAT// FAC Packed // , CMD_DEFINE_DATA_FACP // FAC Packed // , CMD_DEFINE_DATA_FACU // FAC Unpacked // , CMD_DATA_DEFINE_ADDR_BYTE_L // DB< address symbol @@ -590,6 +591,8 @@ Update_t CmdDisasmDataDefByte4 (int nArgs); Update_t CmdDisasmDataDefByte8 (int nArgs); + Update_t CmdDisasmDataDefFloat (int nArgs); + Update_t CmdDisasmDataDefWord1 (int nArgs); Update_t CmdDisasmDataDefWord2 (int nArgs); Update_t CmdDisasmDataDefWord4 (int nArgs); @@ -877,7 +880,7 @@ char sSymbol[ MAX_SYMBOLS_LEN+1 ]; Nopcode_e eElementType ; // eElementType -> iNoptype - int iDirective ; // iDirective -> iNopcode + int iDirective ; // iDirective -> iNopcode ASC DA DB DF DW etc. WORD nStartAddress; // link to block [start,end) WORD nEndAddress ;