/* AppleWin : An Apple //e emulator for Windows Copyright (C) 1994-1996, Michael O'Brien Copyright (C) 1999-2001, Oliver Schmidt Copyright (C) 2002-2005, Tom Charlesworth Copyright (C) 2006, Tom Charlesworth, Michael Pohoreski AppleWin 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 2 of the License, or (at your option) any later version. AppleWin 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 AppleWin; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Description: Debugger * * Author: Copyright (C) 2006, Michael Pohoreski */ #include "StdAfx.h" #pragma hdrstop // Utility ________________________________________________________________________________________ /* String types: http://www.codeproject.com/cpp/unicode.asp TEXT() _tcsrev _UNICODE Unicode _wcsrev _MBCS Multi-byte _mbsrev n/a ASCII strrev */ // tests if pSrc fits into pDst // returns true if pSrc safely fits into pDst, else false (pSrc would of overflowed pDst) //=========================================================================== bool TestStringCat ( TCHAR * pDst, LPCSTR pSrc, const int nDstSize ) { int nLenDst = _tcslen( pDst ); int nLenSrc = _tcslen( pSrc ); int nSpcDst = nDstSize - nLenDst; int nChars = MIN( nLenSrc, nSpcDst ); bool bOverflow = (nSpcDst < nLenSrc); if (bOverflow) { return false; } return true; } // tests if pSrc fits into pDst // returns true if pSrc safely fits into pDst, else false (pSrc would of overflowed pDst) //=========================================================================== bool TryStringCat ( TCHAR * pDst, LPCSTR pSrc, const int nDstSize ) { int nLenDst = _tcslen( pDst ); int nLenSrc = _tcslen( pSrc ); int nSpcDst = nDstSize - nLenDst; int nChars = MIN( nLenSrc, nSpcDst ); bool bOverflow = (nSpcDst < nLenSrc); if (bOverflow) { return false; } _tcsncat( pDst, pSrc, nChars ); return true; } // cats string as much as possible // returns true if pSrc safely fits into pDst, else false (pSrc would of overflowed pDst) //=========================================================================== bool StringCat ( TCHAR * pDst, LPCSTR pSrc, const int nDstSize ) { int nLenDst = _tcslen( pDst ); int nLenSrc = _tcslen( pSrc ); int nSpcDst = nDstSize - nLenDst; int nChars = MIN( nLenSrc, nSpcDst ); _tcsncat( pDst, pSrc, nChars ); bool bOverflow = (nSpcDst < nLenSrc); if (bOverflow) return false; return true; } // Help ___________________________________________________________________________________________ //=========================================================================== Update_t HelpLastCommand() { return Help_Arg_1( g_iCommand ); } // Loads the arguments with the command to get help on and call display help. //=========================================================================== Update_t Help_Arg_1( int iCommandHelp ) { _Arg_1( iCommandHelp ); wsprintf( g_aArgs[ 1 ].sArg, g_aCommands[ iCommandHelp ].m_sName ); // .3 Fixed: Help_Arg_1() now copies command name into arg.name return CmdHelpSpecific( 1 ); } //=========================================================================== Update_t CmdMOTD( int nArgs ) { TCHAR sText[ CONSOLE_WIDTH ]; ConsoleBufferPush( TEXT(" Apple ][ ][+ //e Emulator for Windows") ); CmdVersion(0); CmdSymbols(0); wsprintf( sText, " '~' console, '%s' (specific), '%s' (all)" , g_aCommands[ CMD_HELP_SPECIFIC ].m_sName // , g_aCommands[ CMD_HELP_SPECIFIC ].pHelpSummary , g_aCommands[ CMD_HELP_LIST ].m_sName // , g_aCommands[ CMD_HELP_LIST ].pHelpSummary ); ConsoleBufferPush( sText ); ConsoleUpdate(); return UPDATE_ALL; } // Help on specific command //=========================================================================== Update_t CmdHelpSpecific (int nArgs) { int iArg; TCHAR sText[ CONSOLE_WIDTH ]; ZeroMemory( sText, CONSOLE_WIDTH ); if (! nArgs) { // ConsoleBufferPush( TEXT(" [] = optional, {} = mandatory. Categories are: ") ); _tcscpy( sText, TEXT("Usage: [< ") ); for (int iCategory = _PARAM_HELPCATEGORIES_BEGIN ; iCategory < _PARAM_HELPCATEGORIES_END; iCategory++) { TCHAR *pName = g_aParameters[ iCategory ].m_sName; if (! TestStringCat( sText, pName, CONSOLE_WIDTH - 2 )) // CONSOLE_WIDTH // g_nConsoleDisplayWidth - 3 { ConsoleBufferPush( sText ); _tcscpy( sText, TEXT(" ") ); } StringCat( sText, pName, CONSOLE_WIDTH ); if (iCategory < (_PARAM_HELPCATEGORIES_END - 1)) { StringCat( sText, TEXT(" | "), CONSOLE_WIDTH ); } } StringCat( sText, TEXT(" >]"), CONSOLE_WIDTH ); ConsoleBufferPush( sText ); wsprintf( sText, TEXT("Note: [] = optional, <> = mandatory"), CONSOLE_WIDTH ); ConsoleBufferPush( sText ); } bool bAllCommands = false; bool bCategory = false; if ((! _tcscmp( g_aArgs[1].sArg, g_aParameters[ PARAM_WILDSTAR ].m_sName)) || (! _tcscmp( g_aArgs[1].sArg, g_aParameters[ PARAM_MEM_SEARCH_WILD ].m_sName)) ) { bAllCommands = true; nArgs = NUM_COMMANDS; } // If Help on category, push command name as arg // Mame has categories: // General, Memory, Execution, Breakpoints, Watchpoints, Expressions, Comments int iParam = 0; int nNewArgs = 0; int iCmdBegin = 0; int iCmdEnd = 0; if (! bAllCommands) { for (iArg = 1; iArg <= nArgs; iArg++ ) { // int nFoundCategory = FindParam( g_aArgs[ iArg ].sArg, MATCH_EXACT, iParam, _PARAM_HELPCATEGORIES_BEGIN, _PARAM_HELPCATEGORIES_END ); int nFoundCategory = FindParam( g_aArgs[ iArg ].sArg, MATCH_FUZZY, iParam, _PARAM_HELPCATEGORIES_BEGIN, _PARAM_HELPCATEGORIES_END ); switch( iParam ) { case PARAM_CAT_BREAKPOINTS: iCmdBegin = CMD_BREAKPOINT ; iCmdEnd = CMD_BREAKPOINT_SAVE + 1; break; case PARAM_CAT_CONFIG : iCmdBegin = CMD_CONFIG_COLOR ; iCmdEnd = CMD_CONFIG_SAVE + 1; break; case PARAM_CAT_CPU : iCmdBegin = CMD_ASSEMBLE ; iCmdEnd = CMD_TRACE_LINE + 1; break; case PARAM_CAT_FLAGS : iCmdBegin = CMD_FLAG_CLEAR ; iCmdEnd = CMD_FLAG_SET_N + 1; break; case PARAM_CAT_MEMORY : iCmdBegin = CMD_MEMORY_COMPARE ; iCmdEnd = CMD_MEMORY_FILL + 1; break; case PARAM_CAT_SYMBOLS : iCmdBegin = CMD_SYMBOLS_LOOKUP ; iCmdEnd = CMD_SYMBOLS_LIST + 1; break; case PARAM_CAT_WATCHES : iCmdBegin = CMD_WATCH_ADD ; iCmdEnd = CMD_WATCH_LIST + 1; break; case PARAM_CAT_WINDOW : iCmdBegin = CMD_WINDOW ; iCmdEnd = CMD_WINDOW_OUTPUT + 1; break; case PARAM_CAT_ZEROPAGE : iCmdBegin = CMD_ZEROPAGE_POINTER; iCmdEnd = CMD_ZEROPAGE_POINTER_SAVE+1;break; default: break; } nNewArgs = (iCmdEnd - iCmdBegin); if (nNewArgs > 0) break; } } if (nNewArgs > 0) { bCategory = true; nArgs = nNewArgs; for (iArg = 1; iArg <= nArgs; iArg++ ) { #if DEBUG_VAL_2 g_aArgs[ iArg ].nVal2 = iCmdBegin + iArg - 1; #endif g_aArgs[ iArg ].nValue = iCmdBegin + iArg - 1; } } CmdFuncPtr_t pFunction; for (iArg = 1; iArg <= nArgs; iArg++ ) { int iCommand = 0; int nFound = 0; if (bCategory) { #if DEBUG_VAL_2 iCommand = g_aArgs[iArg].nVal2; #endif iCommand = g_aArgs[ iArg ].nValue; nFound = 1; } else if (bAllCommands) { iCommand = iArg; if (iCommand == NUM_COMMANDS) // skip: Internal Consistency Check __COMMANDS_VERIFY_TXT__ continue; nFound = 1; } else nFound = FindCommand( g_aArgs[iArg].sArg, pFunction, & iCommand ); if (nFound > 1) { DisplayAmbigiousCommands( nFound ); } if (iCommand > NUM_COMMANDS) continue; if ((nArgs == 1) && (! nFound)) iCommand = g_aArgs[iArg].nValue; Command_t *pCommand = & g_aCommands[ iCommand ]; if (! nFound) { iCommand = NUM_COMMANDS; pCommand = NULL; } if (nFound && (! bAllCommands) && (! bCategory)) { TCHAR sCategory[ CONSOLE_WIDTH ]; int iCmd = g_aCommands[ iCommand ].iCommand; // Unaliased command // HACK: Major kludge to display category!!! if (iCmd <= CMD_TRACE_LINE) wsprintf( sCategory, "Main" ); else if (iCmd <= CMD_BREAKPOINT_SAVE) wsprintf( sCategory, "Breakpoint" ); else if (iCmd <= CMD_PROFILE) wsprintf( sCategory, "Profile" ); else if (iCmd <= CMD_CONFIG_SAVE) wsprintf( sCategory, "Config" ); else if (iCmd <= CMD_CURSOR_PAGE_DOWN_4K) wsprintf( sCategory, "Scrolling" ); else if (iCmd <= CMD_FLAG_SET_N) wsprintf( sCategory, "Flags" ); else if (iCmd <= CMD_MOTD) wsprintf( sCategory, "Help" ); else if (iCmd <= CMD_MEMORY_FILL) wsprintf( sCategory, "Memory" ); else if (iCmd <= CMD_REGISTER_SET) wsprintf( sCategory, "Registers" ); else if (iCmd <= CMD_SYNC) wsprintf( sCategory, "Source" ); else if (iCmd <= CMD_STACK_PUSH) wsprintf( sCategory, "Stack" ); else if (iCmd <= CMD_SYMBOLS_LIST) wsprintf( sCategory, "Symbols" ); else if (iCmd <= CMD_WATCH_SAVE) wsprintf( sCategory, "Watch" ); else if (iCmd <= CMD_WINDOW_OUTPUT) wsprintf( sCategory, "Window" ); else if (iCmd <= CMD_ZEROPAGE_POINTER_SAVE) wsprintf( sCategory, "Zero Page" ); else wsprintf( sCategory, "Unknown!" ); wsprintf( sText, "Category: %s", sCategory ); ConsoleBufferPush( sText ); } if (pCommand) { char *pHelp = pCommand->pHelpSummary; if (pHelp) { wsprintf( sText, "%s, ", pCommand->m_sName ); if (! TryStringCat( sText, pHelp, g_nConsoleDisplayWidth )) { if (! TryStringCat( sText, pHelp, CONSOLE_WIDTH )) { StringCat( sText, pHelp, CONSOLE_WIDTH ); ConsoleBufferPush( sText ); } } ConsoleBufferPush( sText ); } else { wsprintf( sText, "%s", pCommand->m_sName ); ConsoleBufferPush( sText ); #if DEBUG_COMMAND_HELP if (! bAllCommands) // Release version doesn't display message { wsprintf( sText, "Missing Summary Help: %s", g_aCommands[ iCommand ].aName ); ConsoleBufferPush( sText ); } #endif } } // MASTER HELP switch (iCommand) { // CPU / General case CMD_ASSEMBLE: ConsoleBufferPush( TEXT(" Built-in assember isn't functional yet.") ); break; case CMD_UNASSEMBLE: ConsoleBufferPush( TEXT(" Usage: {address | symbol}") ); ConsoleBufferPush( TEXT(" Disassembles memory.") ); break; case CMD_GO: ConsoleBufferPush( TEXT(" Usage: address | symbol [Skip,Length]]") ); ConsoleBufferPush( TEXT(" addres | symbol [Start:End]") ); ConsoleBufferPush( TEXT(" Skip : Start address to skip stepping" ) ); ConsoleBufferPush( TEXT(" Length: Range of bytes past start address to skip stepping" ) ); ConsoleBufferPush( TEXT(" End : Inclusive end address to skip stepping" ) ); ConsoleBufferPush( TEXT(" If the Program Counter is outside the skip range, resumes single-stepping." ) ); ConsoleBufferPush( TEXT(" Can be used to skip ROM/OS/user code." )); ConsoleBufferPush( TEXT(" Examples:" ) ); ConsoleBufferPush( TEXT(" G C600 FA00,600" ) ); ConsoleBufferPush( TEXT(" G C600 F000:FFFF" ) ); break; case CMD_JSR: ConsoleBufferPush( TEXT(" Usage: {symbol | address}") ); ConsoleBufferPush( TEXT(" Pushes PC on stack; calls the named subroutine.") ); break; case CMD_NOP: ConsoleBufferPush( TEXT(" Puts a NOP opcode at current instruction") ); break; case CMD_OUT: ConsoleBufferPush( TEXT(" Usage: {address8 | address16 | symbol} ## [##]") ); ConsoleBufferPush( TEXT(" Ouput a byte or word to the IO address $C0xx" ) ); break; case CMD_PROFILE: wsprintf( sText, TEXT(" Usage: [%s | %s | %s]") , g_aParameters[ PARAM_RESET ].m_sName , g_aParameters[ PARAM_SAVE ].m_sName , g_aParameters[ PARAM_LIST ].m_sName ); ConsoleBufferPush( sText ); ConsoleBufferPush( TEXT(" No arguments resets the profile.") ); break; case CMD_SOURCE: ConsoleBufferPush( TEXT(" Reads assembler source file." ) ); wsprintf( sText, TEXT(" Usage: [ %s | %s ] \"filename\"" ), g_aParameters[ PARAM_SRC_MEMORY ].m_sName, g_aParameters[ PARAM_SRC_SYMBOLS ].m_sName ); ConsoleBufferPush( sText ); wsprintf( sText, TEXT(" %s: read source bytes into memory." ), g_aParameters[ PARAM_SRC_MEMORY ].m_sName ); ConsoleBufferPush( sText ); wsprintf( sText, TEXT(" %s: read symbols into Source symbol table."), g_aParameters[ PARAM_SRC_SYMBOLS ].m_sName ); ConsoleBufferPush( sText ); wsprintf( sText, TEXT(" Supports: %s." ), g_aParameters[ PARAM_SRC_MERLIN ].m_sName ); ConsoleBufferPush( sText ); break; case CMD_STEP_OUT: ConsoleBufferPush( TEXT(" Steps out of current subroutine") ); ConsoleBufferPush( TEXT(" Hotkey: Ctrl-Space" ) ); // TODO: FIXME break; case CMD_STEP_OVER: // Bad name? FIXME/TODO: do we need to rename? ConsoleBufferPush( TEXT(" Usage: [#]") ); ConsoleBufferPush( TEXT(" Steps, # times, thru current instruction") ); ConsoleBufferPush( TEXT(" JSR will be stepped into AND out of.") ); ConsoleBufferPush( TEXT(" Hotkey: Ctrl-Space" ) ); // TODO: FIXME break; case CMD_TRACE: ConsoleBufferPush( TEXT(" Usage: [#]") ); ConsoleBufferPush( TEXT(" Traces, # times, current instruction(s)") ); ConsoleBufferPush( TEXT(" JSR will be stepped into") ); ConsoleBufferPush( TEXT(" Hotkey: Shift-Space" ) ); case CMD_TRACE_FILE: ConsoleBufferPush( TEXT(" Usage: [filename]") ); break; case CMD_TRACE_LINE: ConsoleBufferPush( TEXT(" Usage: [#]") ); ConsoleBufferPush( TEXT(" Traces into current instruction") ); ConsoleBufferPush( TEXT(" with cycle counting." ) ); break; // Breakpoints case CMD_BREAKPOINT: wsprintf( sText, " Maximum breakpoints: %d", MAX_BREAKPOINTS ); ConsoleBufferPush( sText ); wsprintf( sText, TEXT(" Usage: [%s | %s | %s]") , g_aParameters[ PARAM_LOAD ].m_sName , g_aParameters[ PARAM_SAVE ].m_sName , g_aParameters[ PARAM_RESET ].m_sName ); ConsoleBufferPush( sText ); ConsoleBufferPush( TEXT(" Set breakpoint at PC if no args.") ); ConsoleBufferPush( TEXT(" Loading/Saving not yet implemented.") ); break; case CMD_BREAKPOINT_ADD_REG: ConsoleBufferPush( TEXT(" Usage: [A|X|Y|PC|S] [<,=,>] value") ); ConsoleBufferPush( TEXT(" Set breakpoint when reg is [op] value") ); break; case CMD_BREAKPOINT_ADD_SMART: ConsoleBufferPush( TEXT(" Usage: [address | register]") ); ConsoleBufferPush( TEXT(" If address, sets two breakpoints" ) ); ConsoleBufferPush( TEXT(" 1. one memory access at address" ) ); ConsoleBufferPush( TEXT(" 2. if PC reaches address" ) ); // "Sets a breakpoint at the current PC or specified address." ) ); ConsoleBufferPush( TEXT(" If an IO address, sets breakpoint on IO access.") ); ConsoleBufferPush( TEXT(" If register, sets a breakpoint on memory access at address of register.") ); break; case CMD_BREAKPOINT_ADD_PC: ConsoleBufferPush( TEXT(" Usage: [address]") ); ConsoleBufferPush( TEXT(" Sets a breakpoint at the current PC or at the specified address.") ); break; case CMD_BREAKPOINT_CLEAR: ConsoleBufferPush( TEXT(" Usage: [# | *]") ); ConsoleBufferPush( TEXT(" Clears specified breakpoint, or all.") ); wsprintf( sText, TEXT(" i.e. %s 1" ), pCommand->m_sName ); ConsoleBufferPush( sText ); break; case CMD_BREAKPOINT_DISABLE: ConsoleBufferPush( TEXT(" Usage: [# [,#] | *]") ); ConsoleBufferPush( TEXT(" Disable breakpoint previously set, or all.") ); wsprintf( sText, TEXT(" i.e. %s 1" ), pCommand->m_sName ); ConsoleBufferPush( sText ); break; case CMD_BREAKPOINT_ENABLE: ConsoleBufferPush( TEXT(" Usage: [# [,#] | *]") ); ConsoleBufferPush( TEXT(" Re-enables breakpoint previously set, or all.") ); wsprintf( sText, TEXT(" i.e. %s 1" ), pCommand->m_sName ); ConsoleBufferPush( sText ); break; case CMD_BREAKPOINT_LIST: break; // Config - Color case CMD_CONFIG_MENU: ConsoleBufferPush( TEXT(" Load/Save configuration, or change disasm view options." ) ); wsprintf( sText, TEXT(" %s" ": Loads config from last/default \"filename\"" ), g_aParameters[ PARAM_SAVE ].m_sName ); ConsoleBufferPush( sText ); wsprintf( sText, TEXT(" %s" ": Saves config to \"filename\"" ), g_aParameters[ PARAM_LOAD ].m_sName ); ConsoleBufferPush( sText ); break; case CMD_CONFIG_COLOR: ConsoleBufferPush( TEXT(" Usage: [{#} | {# RR GG BB}]" ) ); ConsoleBufferPush( TEXT(" 0 params: switch to 'color' scheme" ) ); ConsoleBufferPush( TEXT(" 1 param : dumps R G B for scheme 'color'") ); ConsoleBufferPush( TEXT(" 4 params: sets R G B for scheme 'color'" ) ); break; case CMD_CONFIG_MONOCHROME: ConsoleBufferPush( TEXT(" Usage: [{#} | {# RR GG BB}]" ) ); ConsoleBufferPush( TEXT(" 0 params: switch to 'monochrome' scheme" ) ); ConsoleBufferPush( TEXT(" 1 param : dumps R G B for scheme 'monochrome'") ); ConsoleBufferPush( TEXT(" 4 params: sets R G B for scheme 'monochrome'" ) ); break; // Config - Diasm case CMD_CONFIG_DISASM: { ConsoleBufferPush( TEXT(" Note: All arguments effect the disassembly view" ) ); wsprintf( sText, TEXT(" Usage: [%s | %s | %s | %s | %s]") , g_aParameters[ PARAM_CONFIG_BRANCH ].m_sName , g_aParameters[ PARAM_CONFIG_COLON ].m_sName , g_aParameters[ PARAM_CONFIG_OPCODE ].m_sName , g_aParameters[ PARAM_CONFIG_SPACES ].m_sName , g_aParameters[ PARAM_CONFIG_TARGET ].m_sName ); ConsoleBufferPush( sText ); ConsoleBufferPush( TEXT(" Display current settings if no args." ) ); iParam = PARAM_CONFIG_BRANCH; wsprintf( sText, TEXT(" Usage: %s [#]" ), g_aParameters[ iParam ].m_sName ); ConsoleBufferPush( sText ); ConsoleBufferPush( TEXT(" Set the type of branch character:" ) ); wsprintf( sText, TEXT(" %d off, %d plain, %d fancy" ), DISASM_BRANCH_OFF, DISASM_BRANCH_PLAIN, DISASM_BRANCH_FANCY ); ConsoleBufferPush( sText ); wsprintf( sText, TEXT(" i.e. %s %s 1" ), pCommand->m_sName, g_aParameters[ iParam ].m_sName ); ConsoleBufferPush( sText ); iParam = PARAM_CONFIG_COLON; wsprintf( sText, TEXT(" Usage: %s [0|1]" ), g_aParameters[ iParam ].m_sName ); ConsoleBufferPush( sText ); ConsoleBufferPush( TEXT(" Display a colon after the address" ) ); wsprintf( sText, TEXT(" i.e. %s %s 0" ), pCommand->m_sName, g_aParameters[ iParam ].m_sName ); ConsoleBufferPush( sText ); iParam = PARAM_CONFIG_OPCODE; wsprintf( sText, TEXT(" Usage: %s [0|1]" ), g_aParameters[ iParam ].m_sName ); ConsoleBufferPush( sText ); ConsoleBufferPush( TEXT(" Display opcode(s) after colon" ) ); wsprintf( sText, TEXT(" i.e. %s %s 1" ), pCommand->m_sName, g_aParameters[ iParam ].m_sName ); ConsoleBufferPush( sText ); iParam = PARAM_CONFIG_SPACES; wsprintf( sText, TEXT(" Usage: %s [0|1]" ), g_aParameters[ iParam ].m_sName ); ConsoleBufferPush( sText ); ConsoleBufferPush( TEXT(" Display spaces between opcodes" ) ); wsprintf( sText, TEXT(" i.e. %s %s 0" ), pCommand->m_sName, g_aParameters[ iParam ].m_sName ); ConsoleBufferPush( sText ); iParam = PARAM_CONFIG_TARGET; wsprintf( sText, TEXT(" Usage: %s [#]" ), g_aParameters[ iParam ].m_sName ); ConsoleBufferPush( sText ); ConsoleBufferPush( TEXT(" Set the type of target address/value displayed:" ) ); wsprintf( sText, TEXT(" %d off, %d value only, %d address only, %d both" ), DISASM_TARGET_OFF, DISASM_TARGET_VAL, DISASM_TARGET_ADDR, DISASM_TARGET_BOTH ); ConsoleBufferPush( sText ); wsprintf( sText, TEXT(" i.e. %s %s %d" ), pCommand->m_sName, g_aParameters[ iParam ].m_sName, DISASM_TARGET_VAL ); ConsoleBufferPush( sText ); break; } // Config - Font case CMD_CONFIG_FONT: wsprintf( sText, TEXT(" Usage: [%s | %s] \"FontName\" [Height]" ), g_aParameters[ PARAM_FONT_MODE ].m_sName, g_aParameters[ PARAM_DISASM ].m_sName ); ConsoleBufferPush( sText ); ConsoleBufferPush( TEXT(" i.e. FONT \"Courier\" 12" ) ); ConsoleBufferPush( TEXT(" i.e. FONT \"Lucida Console\" 12" ) ); wsprintf( sText, TEXT(" %s Controls line spacing."), g_aParameters[ PARAM_FONT_MODE ].m_sName ); ConsoleBufferPush( sText ); wsprintf( sText, TEXT(" Valid values are: %d, %d, %d." ), FONT_SPACING_CLASSIC, FONT_SPACING_CLEAN, FONT_SPACING_COMPRESSED ); ConsoleBufferPush( sText ); break; // Memory case CMD_MEMORY_ENTER_BYTE: ConsoleBufferPush( TEXT(" Usage: {address | symbol} ## [## ... ##]") ); ConsoleBufferPush( TEXT(" Sets memory to the specified 8-Bit Values (bytes)" ) ); break; case CMD_MEMORY_ENTER_WORD: ConsoleBufferPush( TEXT(" Usage: {address | symbol} #### [#### ... ####]") ); ConsoleBufferPush( TEXT(" Sets memory to the specified 16-Bit Values (words)" ) ); break; case CMD_MEMORY_FILL: ConsoleBufferPush( TEXT(" Usage: {address | symbol} {address | symbol} ##" ) ); ConsoleBufferPush( TEXT(" Fills the memory range with the specified byte" ) ); ConsoleBufferPush( TEXT(" Can't fill IO address $C0xx" ) ); break; // case CMD_MEM_MINI_DUMP_ASC_1: // case CMD_MEM_MINI_DUMP_ASC_2: case CMD_MEM_MINI_DUMP_ASCII_1: case CMD_MEM_MINI_DUMP_ASCII_2: ConsoleBufferPush( TEXT(" Usage: {address | symbol}") ); ConsoleBufferPush( TEXT(" Displays ASCII text in the Mini-Memory area") ); ConsoleBufferPush( TEXT(" ASCII control chars are hilighted") ); ConsoleBufferPush( TEXT(" ASCII hi-bit chars are normal") ); // break; // case CMD_MEM_MINI_DUMP_TXT_LO_1: // case CMD_MEM_MINI_DUMP_TXT_LO_2: case CMD_MEM_MINI_DUMP_APPLE_1: case CMD_MEM_MINI_DUMP_APPLE_2: ConsoleBufferPush( TEXT(" Usage: {address | symbol}") ); ConsoleBufferPush( TEXT(" Displays APPLE text in the Mini-Memory area") ); ConsoleBufferPush( TEXT(" APPLE control chars are inverse") ); ConsoleBufferPush( TEXT(" APPLE hi-bit chars are normal") ); break; // case CMD_MEM_MINI_DUMP_TXT_HI_1: // case CMD_MEM_MINI_DUMP_TXT_HI_2: // ConsoleBufferPush( TEXT(" Usage: {address | symbol}") ); // ConsoleBufferPush( TEXT(" Displays text in the Memory Mini-Dump area") ); // ConsoleBufferPush( TEXT(" ASCII chars with the hi-bit set, is inverse") ); break; case CMD_MEMORY_LOAD: // BLOAD "Filename" addr[,len] case CMD_MEMORY_SAVE: // BSAVE ["Filename"] addr,len if (iCommand == CMD_MEMORY_LOAD) { ConsoleBufferPush( TEXT(" Usage: [\"Filename\"],address[,length]" ) ); ConsoleBufferPush( TEXT(" If no filename specified, defaults to the last filename (if possible)" ) ); } if (iCommand == CMD_MEMORY_SAVE) { ConsoleBufferPush( TEXT(" Usage: [\"Filename\"],address[,length]" ) ); ConsoleBufferPush( TEXT(" If no filename specified, defaults to:" ) ); ConsoleBufferPush( TEXT(" '####.####.bin' with the form" ) ); ConsoleBufferPush( TEXT(" {address}.{length}.bin" ) ); } ConsoleBufferPush( TEXT(" Examples:" ) ); ConsoleBufferPush( TEXT(" BSAVE \"test\",FF00,100" ) ); ConsoleBufferPush( TEXT(" BLOAD \"test\",2000" ) ); break; // Output case CMD_OUTPUT_CALC: ConsoleBufferPush( TEXT(" Usage:
" ) ); ConsoleBufferPush( TEXT(" Expression is one of: + - * / % ^ ~" ) ); ConsoleBufferPush( TEXT(" Output order is: Hex Bin Dec Char" ) ); ConsoleBufferPush( TEXT(" Note: symbols take piority." ) ); ConsoleBufferPush( TEXT("i.e. #A (if you don't want accum. val)" ) ); ConsoleBufferPush( TEXT("i.e. #F (if you don't want flags val)" ) ); break; case CMD_OUTPUT_ECHO: ConsoleBufferPush( TEXT(" Usage: string" ) ); ConsoleBufferPush( TEXT(" Examples:" ) ); wsprintf( sText, TEXT(" %s Checkpoint"), pCommand->m_sName ); ConsoleBufferPush( sText ); wsprintf( sText, TEXT(" %s PC" ), pCommand->m_sName ); ConsoleBufferPush( sText ); // ConsoleBufferPush( TEXT(" Echo the string to the console" ) ); break; case CMD_OUTPUT_PRINT: ConsoleBufferPush( TEXT(" Usage: