2006-02-25 20:50:29 +00:00
/*
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
2007-04-01 15:24:52 +00:00
Copyright ( C ) 2006 - 2007 , Tom Charlesworth , Michael Pohoreski
2006-02-25 20:50:29 +00:00
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
*/
// disable warning C4786: symbol greater than 255 character:
2006-02-26 06:26:56 +00:00
//#pragma warning(disable: 4786)
2006-02-25 20:50:29 +00:00
# include "StdAfx.h"
# pragma hdrstop
2006-07-01 06:45:50 +00:00
# include <algorithm> // find
2006-02-26 06:26:56 +00:00
2006-07-01 06:45:50 +00:00
// #define DEBUG_COMMAND_HELP 1
// #define DEBUG_ASM_HASH 1
# define ALLOW_INPUT_LOWERCASE 1
2006-02-25 20:50:29 +00:00
// TODO: COLOR RESET
// TODO: COLOR SAVE ["filename"]
// TODO: COLOR LOAD ["filename"]
2006-02-26 21:39:09 +00:00
// See Debugger_Changelong.txt for full details
2006-08-16 18:58:56 +00:00
const int DEBUGGER_VERSION = MAKE_VERSION ( 2 , 5 , 7 , 11 ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// Public _________________________________________________________________________________________
2006-02-25 20:50:29 +00:00
2006-06-26 16:59:48 +00:00
// Bookmarks __________________________________________________________________
2006-06-27 22:04:03 +00:00
// vector<int> g_aBookmarks;
int g_nBookmarks ;
Bookmark_t g_aBookmarks [ MAX_BOOKMARKS ] ;
2006-06-26 16:59:48 +00:00
2006-02-26 06:26:56 +00:00
// Breakpoints ________________________________________________________________
2006-02-25 20:50:29 +00:00
2006-05-14 00:43:19 +00:00
// Full-Speed debugging
2006-06-12 22:06:50 +00:00
int g_nDebugOnBreakInvalid = 0 ;
int g_iDebugOnOpcode = 0 ;
bool g_bDebugDelayBreakCheck = false ;
2006-05-14 00:43:19 +00:00
2006-02-25 20:50:29 +00:00
int g_nBreakpoints = 0 ;
2006-06-26 16:59:48 +00:00
Breakpoint_t g_aBreakpoints [ MAX_BREAKPOINTS ] ;
2006-02-25 20:50:29 +00:00
// NOTE: Breakpoint_Source_t and g_aBreakpointSource must match!
2006-07-09 04:53:08 +00:00
const char * g_aBreakpointSource [ NUM_BREAKPOINT_SOURCES ] =
2006-02-26 06:26:56 +00:00
{ // Used to be one char, since ArgsCook also uses // TODO/FIXME: Parser use Param[] ?
2006-02-25 20:50:29 +00:00
// Used for both Input & Output!
// Regs
2006-07-09 04:53:08 +00:00
" A " , // Reg A
" X " , // Reg X
" Y " , // Reg Y
2006-02-25 20:50:29 +00:00
// Special
2006-07-09 04:53:08 +00:00
" PC " , // Program Counter
" S " , // Stack Pointer
2006-02-25 20:50:29 +00:00
// Flags -- .8 Moved: Flag names from g_aFlagNames[] to "inlined" g_aBreakpointSource[]
2006-07-09 04:53:08 +00:00
" P " , // Processor Status
" C " , // ---- ---1 Carry
" Z " , // ---- --1- Zero
" I " , // ---- -1-- Interrupt
" D " , // ---- 1--- Decimal
" B " , // ---1 ---- Break
" R " , // --1- ---- Reserved
" V " , // -1-- ---- Overflow
" N " , // 1--- ---- Sign
2006-02-25 20:50:29 +00:00
// Misc
2006-07-09 04:53:08 +00:00
" OP " , // Opcode/Instruction/Mnemonic
2006-02-25 20:50:29 +00:00
// Memory
2006-07-09 04:53:08 +00:00
" M " // Main
2006-02-25 20:50:29 +00:00
} ;
// Note: BreakpointOperator_t, _PARAM_BREAKPOINT_, and g_aBreakpointSymbols must match!
2006-07-01 06:45:50 +00:00
const char * g_aBreakpointSymbols [ NUM_BREAKPOINT_OPERATORS ] =
2006-02-25 20:50:29 +00:00
{ // Output: Must be 2 chars!
2006-07-01 06:45:50 +00:00
" <= " , // LESS_EQAUL
" < " , // LESS_THAN
" = " , // EQUAL
" != " , // NOT_EQUAL
// "! ", // NOT_EQUAL_1
" > " , // GREATER_THAN
" >= " , // GREATER_EQUAL
" ? " , // READ // Q. IO Read use 'I'? A. No, since I=Interrupt
" @ " , // WRITE // Q. IO Write use 'O'? A. No, since O=Opcode
" * " , // Read/Write
2006-02-25 20:50:29 +00:00
} ;
// Commands _______________________________________________________________________________________
# define __COMMANDS_VERIFY_TXT__ "\xDE\xAD\xC0\xDE"
# define __PARAMS_VERIFY_TXT__ "\xDE\xAD\xDA\x1A"
class commands_functor_compare
{
public :
int operator ( ) ( const Command_t & rLHS , const Command_t & rRHS ) const
{
return _tcscmp ( rLHS . m_sName , rRHS . m_sName ) ;
}
} ;
int g_iCommand ; // last command (enum) // used for consecuitive commands
vector < int > g_vPotentialCommands ; // global, since TAB-completion also needs
vector < Command_t > g_vSortedCommands ;
// Setting function to NULL, allows g_aCommands arguments to be safely listed here
// Commands should be listed alphabetically per category.
// For the list sorted by category, check Commands_e
// NOTE: Commands_e and g_aCommands[] must match! Aliases are listed at the end
Command_t g_aCommands [ ] =
{
// CPU (Main)
2006-06-27 22:04:03 +00:00
{ TEXT ( " . " ) , CmdCursorJumpPC , CMD_CURSOR_JUMP_PC , " Locate the cursor in the disasm window " } , // centered
{ TEXT ( " = " ) , CmdCursorSetPC , CMD_CURSOR_SET_PC , " Sets the PC to the current instruction " } ,
2006-02-25 20:50:29 +00:00
{ TEXT ( " A " ) , CmdAssemble , CMD_ASSEMBLE , " Assemble instructions " } ,
2006-05-14 00:43:19 +00:00
{ TEXT ( " BRK " ) , CmdBreakInvalid , CMD_BREAK_INVALID , " Enter debugger on BRK or INVALID " } ,
{ TEXT ( " BRKOP " ) , CmdBreakOpcode , CMD_BREAK_OPCODE , " Enter debugger on opcode " } ,
2006-06-27 22:04:03 +00:00
{ TEXT ( " GO " ) , CmdGo , CMD_GO , " Run [until PC = address] " } ,
{ TEXT ( " IN " ) , CmdIn , CMD_IN , " Input byte from IO $C0xx " } ,
{ TEXT ( " KEY " ) , CmdKey , CMD_INPUT_KEY , " Feed key into emulator " } ,
2006-02-25 20:50:29 +00:00
{ TEXT ( " JSR " ) , CmdJSR , CMD_JSR , " Call sub-routine " } ,
{ TEXT ( " NOP " ) , CmdNOP , CMD_NOP , " Zap the current instruction with a NOP " } ,
2006-06-27 22:04:03 +00:00
{ TEXT ( " OUT " ) , CmdOut , CMD_OUT , " Output byte to IO $C0xx " } ,
2006-07-01 06:45:50 +00:00
{ TEXT ( " PROFILE " ) , CmdProfile , CMD_PROFILE , " List/Save 6502 profiling " } ,
{ TEXT ( " R " ) , CmdRegisterSet , CMD_REGISTER_SET , " Set register " } ,
{ TEXT ( " POP " ) , CmdStackPop , CMD_STACK_POP } ,
{ TEXT ( " PPOP " ) , CmdStackPopPseudo , CMD_STACK_POP_PSEUDO } ,
{ TEXT ( " PUSH " ) , CmdStackPop , CMD_STACK_PUSH } ,
// {TEXT("RTS") , CmdStackReturn , CMD_STACK_RETURN },
2006-02-25 20:50:29 +00:00
{ TEXT ( " P " ) , CmdStepOver , CMD_STEP_OVER , " Step current instruction " } ,
{ TEXT ( " RTS " ) , CmdStepOut , CMD_STEP_OUT , " Step out of subroutine " } ,
{ TEXT ( " T " ) , CmdTrace , CMD_TRACE , " Trace current instruction " } ,
{ TEXT ( " TF " ) , CmdTraceFile , CMD_TRACE_FILE , " Save trace to filename " } ,
{ TEXT ( " TL " ) , CmdTraceLine , CMD_TRACE_LINE , " Trace (with cycle counting) " } ,
2006-06-27 22:04:03 +00:00
{ TEXT ( " U " ) , CmdUnassemble , CMD_UNASSEMBLE , " Disassemble instructions " } ,
// {TEXT("WAIT") , CmdWait , CMD_WAIT , "Run until
// Bookmarks
2006-07-01 06:45:50 +00:00
{ TEXT ( " BM " ) , CmdBookmark , CMD_BOOKMARK , " Alias for BMA (Bookmark Add) " } ,
{ TEXT ( " BMA " ) , CmdBookmarkAdd , CMD_BOOKMARK_ADD , " Add/Update addess to bookmark " } ,
{ TEXT ( " BMC " ) , CmdBookmarkClear , CMD_BOOKMARK_CLEAR , " Clear (remove) bookmark " } ,
{ TEXT ( " BML " ) , CmdBookmarkList , CMD_BOOKMARK_LIST , " List all bookmarks " } ,
{ " BMG " , CmdBookmarkGoto , CMD_BOOKMARK_GOTO , " Move cursor to bookmark " } ,
// {TEXT("BMLOAD") , CmdBookmarkLoad , CMD_BOOKMARK_LOAD , "Load bookmarks" },
{ TEXT ( " BMSAVE " ) , CmdBookmarkSave , CMD_BOOKMARK_SAVE , " Save bookmarks " } ,
2006-02-25 20:50:29 +00:00
// Breakpoints
2006-07-01 06:45:50 +00:00
{ TEXT ( " BP " ) , CmdBreakpoint , CMD_BREAKPOINT , " Alias for BPR (Breakpoint Register Add) " } ,
2006-02-25 20:50:29 +00:00
{ TEXT ( " BPA " ) , CmdBreakpointAddSmart , CMD_BREAKPOINT_ADD_SMART , " Add (smart) breakpoint " } ,
// {TEXT("BPP") , CmdBreakpointAddFlag , CMD_BREAKPOINT_ADD_FLAG , "Add breakpoint on flags" },
{ TEXT ( " BPR " ) , CmdBreakpointAddReg , CMD_BREAKPOINT_ADD_REG , " Add breakpoint on register value " } , // NOTE! Different from SoftICE !!!!
{ TEXT ( " BPX " ) , CmdBreakpointAddPC , CMD_BREAKPOINT_ADD_PC , " Add breakpoint at current instruction " } ,
{ TEXT ( " BPIO " ) , CmdBreakpointAddIO , CMD_BREAKPOINT_ADD_IO , " Add breakpoint for IO address $C0xx " } ,
{ TEXT ( " BPM " ) , CmdBreakpointAddMem , CMD_BREAKPOINT_ADD_MEM , " Add breakpoint on memory access " } , // SoftICE
2006-06-27 22:04:03 +00:00
2006-07-01 06:45:50 +00:00
{ TEXT ( " BC " ) , CmdBreakpointClear , CMD_BREAKPOINT_CLEAR , " Clear (remove) breakpoint " } , // SoftICE
{ TEXT ( " BD " ) , CmdBreakpointDisable , CMD_BREAKPOINT_DISABLE , " Disable breakpoint- it is still in the list, just not active " } , // SoftICE
2006-06-25 03:43:49 +00:00
{ TEXT ( " BPE " ) , CmdBreakpointEdit , CMD_BREAKPOINT_EDIT , " Edit breakpoint " } , // SoftICE
2006-07-01 06:45:50 +00:00
{ TEXT ( " BE " ) , CmdBreakpointEnable , CMD_BREAKPOINT_ENABLE , " (Re)Enable disabled breakpoint " } , // SoftICE
{ TEXT ( " BL " ) , CmdBreakpointList , CMD_BREAKPOINT_LIST , " List all breakpoints " } , // SoftICE
// {TEXT("BPLOAD") , CmdBreakpointLoad , CMD_BREAKPOINT_LOAD , "Loads breakpoints" },
2006-02-25 20:50:29 +00:00
{ TEXT ( " BPSAVE " ) , CmdBreakpointSave , CMD_BREAKPOINT_SAVE , " Saves breakpoints " } ,
// Config
2006-07-01 06:45:50 +00:00
{ TEXT ( " BENCHMARK " ) , CmdBenchmark , CMD_BENCHMARK , " Benchmark the emulator " } ,
2006-02-26 06:26:56 +00:00
{ TEXT ( " BW " ) , CmdConfigColorMono , CMD_CONFIG_BW , " Sets/Shows RGB for Black & White scheme " } ,
2006-02-25 20:50:29 +00:00
{ TEXT ( " COLOR " ) , CmdConfigColorMono , CMD_CONFIG_COLOR , " Sets/Shows RGB for color scheme " } ,
2006-07-01 06:45:50 +00:00
// {TEXT("OPTION") , CmdConfigMenu , CMD_CONFIG_MENU , "Access config options" },
2006-06-25 03:43:49 +00:00
{ TEXT ( " DISASM " ) , CmdConfigDisasm , CMD_CONFIG_DISASM , " Sets/Shows disassembly view options. " } ,
2006-02-25 20:50:29 +00:00
{ TEXT ( " FONT " ) , CmdConfigFont , CMD_CONFIG_FONT , " Shows current font or sets new one " } ,
{ TEXT ( " HCOLOR " ) , CmdConfigHColor , CMD_CONFIG_HCOLOR , " Sets/Shows colors mapped to Apple HGR " } ,
{ TEXT ( " LOAD " ) , CmdConfigLoad , CMD_CONFIG_LOAD , " Load debugger configuration " } ,
{ TEXT ( " MONO " ) , CmdConfigColorMono , CMD_CONFIG_MONOCHROME , " Sets/Shows RGB for monochrome scheme " } ,
{ TEXT ( " SAVE " ) , CmdConfigSave , CMD_CONFIG_SAVE , " Save debugger configuration " } ,
// Cursor
{ TEXT ( " RET " ) , CmdCursorJumpRetAddr , CMD_CURSOR_JUMP_RET_ADDR , " Sets the cursor to the sub-routine caller " } ,
{ TEXT ( " ^ " ) , NULL , CMD_CURSOR_LINE_UP } , // \x2191 = Up Arrow (Unicode)
{ TEXT ( " Shift ^ " ) , NULL , CMD_CURSOR_LINE_UP_1 } ,
{ TEXT ( " v " ) , NULL , CMD_CURSOR_LINE_DOWN } , // \x2193 = Dn Arrow (Unicode)
{ TEXT ( " Shift v " ) , NULL , CMD_CURSOR_LINE_DOWN_1 } ,
{ TEXT ( " PAGEUP " ) , CmdCursorPageUp , CMD_CURSOR_PAGE_UP , " Scroll up one screen " } ,
{ TEXT ( " PAGEUP256 " ) , CmdCursorPageUp256 , CMD_CURSOR_PAGE_UP_256 , " Scroll up 256 bytes " } , // Shift
{ TEXT ( " PAGEUP4K " ) , CmdCursorPageUp4K , CMD_CURSOR_PAGE_UP_4K , " Scroll up 4096 bytes " } , // Ctrl
{ TEXT ( " PAGEDN " ) , CmdCursorPageDown , CMD_CURSOR_PAGE_DOWN , " Scroll down one scren " } ,
{ TEXT ( " PAGEDOWN256 " ) , CmdCursorPageDown256 , CMD_CURSOR_PAGE_DOWN_256 , " Scroll down 256 bytes " } , // Shift
{ TEXT ( " PAGEDOWN4K " ) , CmdCursorPageDown4K , CMD_CURSOR_PAGE_DOWN_4K , " Scroll down 4096 bytes " } , // Ctrl
2006-02-26 06:26:56 +00:00
// Disk
{ TEXT ( " DISK " ) , CmdDisk , CMD_DISK , " Access Disk Drive Functions " } ,
2006-02-25 20:50:29 +00:00
// Flags
// {TEXT("FC") , CmdFlag , CMD_FLAG_CLEAR , "Clear specified Flag" }, // NVRBDIZC see AW_CPU.cpp AF_*
{ TEXT ( " CL " ) , CmdFlag , CMD_FLAG_CLEAR , " Clear specified Flag " } , // NVRBDIZC see AW_CPU.cpp AF_*
{ TEXT ( " CLC " ) , CmdFlagClear , CMD_FLAG_CLR_C , " Clear Flag Carry " } , // 0 // Legacy
{ TEXT ( " CLZ " ) , CmdFlagClear , CMD_FLAG_CLR_Z , " Clear Flag Zero " } , // 1
{ TEXT ( " CLI " ) , CmdFlagClear , CMD_FLAG_CLR_I , " Clear Flag Interrupts Disabled " } , // 2
{ TEXT ( " CLD " ) , CmdFlagClear , CMD_FLAG_CLR_D , " Clear Flag Decimal (BCD) " } , // 3
{ TEXT ( " CLB " ) , CmdFlagClear , CMD_FLAG_CLR_B , " CLear Flag Break " } , // 4 // Legacy
{ TEXT ( " CLR " ) , CmdFlagClear , CMD_FLAG_CLR_R , " Clear Flag Reserved " } , // 5
{ TEXT ( " CLV " ) , CmdFlagClear , CMD_FLAG_CLR_V , " Clear Flag Overflow " } , // 6
{ TEXT ( " CLN " ) , CmdFlagClear , CMD_FLAG_CLR_N , " Clear Flag Negative (Sign) " } , // 7
// {TEXT("FS") , CmdFlag , CMD_FLAG_SET , "Set specified Flag" },
{ TEXT ( " SE " ) , CmdFlag , CMD_FLAG_SET , " Set specified Flag " } ,
{ TEXT ( " SEC " ) , CmdFlagSet , CMD_FLAG_SET_C , " Set Flag Carry " } , // 0
{ TEXT ( " SEZ " ) , CmdFlagSet , CMD_FLAG_SET_Z , " Set Flag Zero " } , // 1
{ TEXT ( " SEI " ) , CmdFlagSet , CMD_FLAG_SET_I , " Set Flag Interrupts Disabled " } , // 2
{ TEXT ( " SED " ) , CmdFlagSet , CMD_FLAG_SET_D , " Set Flag Decimal (BCD) " } , // 3
{ TEXT ( " SEB " ) , CmdFlagSet , CMD_FLAG_SET_B , " Set Flag Break " } , // 4 // Legacy
{ TEXT ( " SER " ) , CmdFlagSet , CMD_FLAG_SET_R , " Set Flag Reserved " } , // 5
{ TEXT ( " SEV " ) , CmdFlagSet , CMD_FLAG_SET_V , " Set Flag Overflow " } , // 6
{ TEXT ( " SEN " ) , CmdFlagSet , CMD_FLAG_SET_N , " Set Flag Negative " } , // 7
// Help
{ TEXT ( " ? " ) , CmdHelpList , CMD_HELP_LIST , " List all available commands " } ,
{ TEXT ( " HELP " ) , CmdHelpSpecific , CMD_HELP_SPECIFIC , " Help on specific command " } ,
{ TEXT ( " VERSION " ) , CmdVersion , CMD_VERSION , " Displays version of emulator/debugger " } ,
{ TEXT ( " MOTD " ) , CmdMOTD , CMD_MOTD } ,
// Memory
{ TEXT ( " MC " ) , CmdMemoryCompare , CMD_MEMORY_COMPARE } ,
{ TEXT ( " D " ) , CmdMemoryMiniDumpHex , CMD_MEM_MINI_DUMP_HEX_1 , " Hex dump in the mini memory area 1 " } , // FIXME: Must also work in DATA screen
{ TEXT ( " MD " ) , CmdMemoryMiniDumpHex , CMD_MEM_MINI_DUMP_HEX_1 } , // alias
{ TEXT ( " MD1 " ) , CmdMemoryMiniDumpHex , CMD_MEM_MINI_DUMP_HEX_1 , " Hex dump in the mini memory area 1 " } ,
{ TEXT ( " MD2 " ) , CmdMemoryMiniDumpHex , CMD_MEM_MINI_DUMP_HEX_2 , " Hex dump in the mini memory area 2 " } ,
{ TEXT ( " M1 " ) , CmdMemoryMiniDumpHex , CMD_MEM_MINI_DUMP_HEX_1 } , // alias
{ TEXT ( " M2 " ) , CmdMemoryMiniDumpHex , CMD_MEM_MINI_DUMP_HEX_2 } , // alias
{ TEXT ( " MA1 " ) , CmdMemoryMiniDumpAscii , CMD_MEM_MINI_DUMP_ASCII_1 , " ASCII text in mini memory area 1 " } ,
{ TEXT ( " MA2 " ) , CmdMemoryMiniDumpAscii , CMD_MEM_MINI_DUMP_ASCII_2 , " ASCII text in mini memory area 2 " } ,
{ TEXT ( " MT1 " ) , CmdMemoryMiniDumpApple , CMD_MEM_MINI_DUMP_APPLE_1 , " Apple Text in mini memory area 1 " } ,
{ TEXT ( " MT2 " ) , CmdMemoryMiniDumpApple , CMD_MEM_MINI_DUMP_APPLE_2 , " Apple Text in mini memory area 2 " } ,
// {TEXT("ML1") , CmdMemoryMiniDumpLow , CMD_MEM_MINI_DUMP_TXT_LO_1, "Text (Ctrl) in mini memory dump area 1" },
// {TEXT("ML2") , CmdMemoryMiniDumpLow , CMD_MEM_MINI_DUMP_TXT_LO_2, "Text (Ctrl) in mini memory dump area 2" },
// {TEXT("MH1") , CmdMemoryMiniDumpHigh, CMD_MEM_MINI_DUMP_TXT_HI_1, "Text (High) in mini memory dump area 1" },
// {TEXT("MH2") , CmdMemoryMiniDumpHigh, CMD_MEM_MINI_DUMP_TXT_HI_2, "Text (High) in mini memory dump area 2" },
{ TEXT ( " ME " ) , CmdMemoryEdit , CMD_MEMORY_EDIT } , // TODO: like Copy ][+ Sector Edit
2006-07-01 06:45:50 +00:00
{ TEXT ( " E " ) , CmdMemoryEnterByte , CMD_MEMORY_ENTER_BYTE , " Enter byte " } ,
{ TEXT ( " EW " ) , CmdMemoryEnterWord , CMD_MEMORY_ENTER_WORD , " Enter word " } ,
{ TEXT ( " BLOAD " ) , CmdMemoryLoad , CMD_MEMORY_LOAD , " Load a region of memory " } ,
{ TEXT ( " M " ) , CmdMemoryMove , CMD_MEMORY_MOVE , " Memory move " } ,
{ TEXT ( " BSAVE " ) , CmdMemorySave , CMD_MEMORY_SAVE , " Save a region of memory " } ,
{ TEXT ( " S " ) , CmdMemorySearch , CMD_MEMORY_SEARCH , " Search memory for text / hex values " } ,
// {TEXT("SA") , CmdMemorySearchAscii, CMD_MEMORY_SEARCH_ASCII , "Search ASCII text" },
// {TEXT("ST") , CmdMemorySearchApple , CMD_MEMORY_SEARCH_APPLE , "Search Apple text (hi-bit)" },
{ TEXT ( " SH " ) , CmdMemorySearchHex , CMD_MEMORY_SEARCH_HEX , " Search memory for hex values " } ,
{ TEXT ( " F " ) , CmdMemoryFill , CMD_MEMORY_FILL , " Memory fill " } ,
2006-06-27 22:04:03 +00:00
// Output / Scripts
{ TEXT ( " CALC " ) , CmdOutputCalc , CMD_OUTPUT_CALC , " Display mini calc result " } ,
{ TEXT ( " ECHO " ) , CmdOutputEcho , CMD_OUTPUT_ECHO , " Echo string to console " } , // or toggle command echoing"
{ TEXT ( " PRINT " ) , CmdOutputPrint , CMD_OUTPUT_PRINT , " Display string and/or hex values " } ,
{ TEXT ( " PRINTF " ) , CmdOutputPrintf , CMD_OUTPUT_PRINTF , " Display formatted string " } ,
{ TEXT ( " RUN " ) , CmdOutputRun , CMD_OUTPUT_RUN , " Run script file of debugger commands " } ,
2006-02-25 20:50:29 +00:00
// Source Level Debugging
{ TEXT ( " SOURCE " ) , CmdSource , CMD_SOURCE , " Starts/Stops source level debugging " } ,
{ TEXT ( " SYNC " ) , CmdSync , CMD_SYNC , " Syncs the cursor to the source file " } ,
// Symbols
2006-07-01 06:45:50 +00:00
{ TEXT ( " SYM " ) , CmdSymbols , CMD_SYMBOLS_LOOKUP , " Lookup symbol or address, or define symbol " } ,
2006-02-25 20:50:29 +00:00
{ TEXT ( " SYMMAIN " ) , CmdSymbolsMain , CMD_SYMBOLS_MAIN , " Main symbol table lookup/menu " } , // CLEAR,LOAD,SAVE
{ TEXT ( " SYMUSER " ) , CmdSymbolsUser , CMD_SYMBOLS_USER , " User symbol table lookup/menu " } , // CLEAR,LOAD,SAVE
{ TEXT ( " SYMSRC " ) , CmdSymbolsSource , CMD_SYMBOLS_SRC , " Source symbol table lookup/menu " } , // CLEAR,LOAD,SAVE
// {TEXT("SYMCLEAR") , CmdSymbolsClear , CMD_SYMBOLS_CLEAR }, // can't use SC = SetCarry
2006-07-01 06:45:50 +00:00
{ TEXT ( " SYMINFO " ) , CmdSymbolsInfo , CMD_SYMBOLS_INFO , " Display summary of symbols " } ,
{ TEXT ( " SYMLIST " ) , CmdSymbolsList , CMD_SYMBOLS_LIST , " Lookup symbol in main/user/src tables " } , // 'symbolname', can't use param '*'
2006-02-25 20:50:29 +00:00
// Variables
// {TEXT("CLEAR") , CmdVarsClear , CMD_VARIABLES_CLEAR },
// {TEXT("VAR") , CmdVarsDefine , CMD_VARIABLES_DEFINE },
// {TEXT("INT8") , CmdVarsDefineInt8 , CMD_VARIABLES_DEFINE_INT8},
// {TEXT("INT16") , CmdVarsDefineInt16 , CMD_VARIABLES_DEFINE_INT16},
// {TEXT("VARS") , CmdVarsList , CMD_VARIABLES_LIST },
// {TEXT("VARSLOAD") , CmdVarsLoad , CMD_VARIABLES_LOAD },
// {TEXT("VARSSAVE") , CmdVarsSave , CMD_VARIABLES_SAVE },
// {TEXT("SET") , CmdVarsSet , CMD_VARIABLES_SET },
// Watch
2006-07-01 06:45:50 +00:00
{ TEXT ( " W " ) , CmdWatch , CMD_WATCH_ADD , " Alias for WA (Watch Add) " } ,
{ TEXT ( " WA " ) , CmdWatchAdd , CMD_WATCH_ADD , " Add/Update address or symbol to watch " } ,
{ TEXT ( " WC " ) , CmdWatchClear , CMD_WATCH_CLEAR , " Clear (remove) watch " } ,
{ TEXT ( " WD " ) , CmdWatchDisable , CMD_WATCH_DISABLE , " Disable specific watch - it is still in the list, just not active " } ,
{ TEXT ( " WE " ) , CmdWatchEnable , CMD_WATCH_ENABLE , " (Re)Enable disabled watch " } ,
{ TEXT ( " WL " ) , CmdWatchList , CMD_WATCH_LIST , " List all watches " } ,
// {TEXT("WLOAD") , CmdWatchLoad , CMD_WATCH_LOAD , "Load Watches" }, // Cant use as param to W
{ TEXT ( " WSAVE " ) , CmdWatchSave , CMD_WATCH_SAVE , " Save Watches " } , // due to symbol look-up
2006-02-25 20:50:29 +00:00
// Window
{ TEXT ( " WIN " ) , CmdWindow , CMD_WINDOW , " Show specified debugger window " } ,
{ TEXT ( " CODE " ) , CmdWindowViewCode , CMD_WINDOW_CODE , " Switch to full code window " } , // Can't use WC = WatchClear
{ TEXT ( " CODE1 " ) , CmdWindowShowCode1 , CMD_WINDOW_CODE_1 , " Show code on top split window " } ,
{ TEXT ( " CODE2 " ) , CmdWindowShowCode2 , CMD_WINDOW_CODE_2 , " Show code on bottom split window " } ,
{ TEXT ( " CONSOLE " ) , CmdWindowViewConsole , CMD_WINDOW_CONSOLE , " Switch to full console window " } ,
{ TEXT ( " DATA " ) , CmdWindowViewData , CMD_WINDOW_DATA , " Switch to full data window " } ,
{ TEXT ( " DATA1 " ) , CmdWindowShowCode1 , CMD_WINDOW_CODE_1 , " Show data on top split window " } ,
{ TEXT ( " DATA2 " ) , CmdWindowShowData2 , CMD_WINDOW_DATA_2 , " Show data on bottom split window " } ,
{ TEXT ( " SOURCE1 " ) , CmdWindowShowSource1 , CMD_WINDOW_SOURCE_1 , " Show source on top split screen " } ,
{ TEXT ( " SOURCE2 " ) , CmdWindowShowSource2 , CMD_WINDOW_SOURCE_2 , " Show source on bottom split screen " } ,
2006-07-01 06:45:50 +00:00
{ TEXT ( " \\ " ) , CmdWindowViewOutput , CMD_WINDOW_OUTPUT , " Display Apple output until key pressed " } ,
2006-02-25 20:50:29 +00:00
// {TEXT("INFO") , CmdToggleInfoPanel , CMD_WINDOW_TOGGLE },
// {TEXT("WINSOURCE") , CmdWindowShowSource , CMD_WINDOW_SOURCE },
// {TEXT("ZEROPAGE") , CmdWindowShowZeropage, CMD_WINDOW_ZEROPAGE },
2006-07-01 06:45:50 +00:00
// Zero Page
{ TEXT ( " ZP " ) , CmdZeroPage , CMD_ZEROPAGE_POINTER , " Alias for ZPA (Zero Page Add) " } ,
{ TEXT ( " ZP0 " ) , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_0 , " Set/Update/Remove ZP watch 0 " } ,
{ TEXT ( " ZP1 " ) , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_1 , " Set/Update/Remove ZP watch 1 " } ,
{ TEXT ( " ZP2 " ) , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_2 , " Set/Update/Remove ZP watch 2 " } ,
{ TEXT ( " ZP3 " ) , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_3 , " Set/Update/Remove ZP watch 3 " } ,
{ TEXT ( " ZP4 " ) , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_4 , " Set/Update/Remove ZP watch 4 " } ,
{ TEXT ( " ZP5 " ) , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_5 , " Set/Update/Remove ZP watch 5 " } ,
{ TEXT ( " ZP6 " ) , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_6 , " Set/Update/Remove ZP watch 6 " } ,
{ TEXT ( " ZP7 " ) , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_7 , " Set/Update/Remove ZP watch 7 " } ,
{ TEXT ( " ZPA " ) , CmdZeroPageAdd , CMD_ZEROPAGE_POINTER_ADD , " Add/Update address to zero page pointer " } ,
{ TEXT ( " ZPC " ) , CmdZeroPageClear , CMD_ZEROPAGE_POINTER_CLEAR , " Clear (remove) zero page pointer " } ,
{ TEXT ( " ZPD " ) , CmdZeroPageDisable , CMD_ZEROPAGE_POINTER_DISABLE , " Disable zero page pointer - it is still in the list, just not active " } ,
{ TEXT ( " ZPE " ) , CmdZeroPageEnable , CMD_ZEROPAGE_POINTER_ENABLE , " (Re)Enable disabled zero page pointer " } ,
{ TEXT ( " ZPL " ) , CmdZeroPageList , CMD_ZEROPAGE_POINTER_LIST , " List all zero page pointers " } ,
// {TEXT("ZPLOAD") , CmdZeroPageLoad , CMD_ZEROPAGE_POINTER_LOAD , "Load zero page pointers" }, // Cant use as param to ZP
{ TEXT ( " ZPSAVE " ) , CmdZeroPageSave , CMD_ZEROPAGE_POINTER_SAVE , " Save zero page pointers " } , // due to symbol look-up
2006-02-25 20:50:29 +00:00
// {TEXT("TIMEDEMO"),CmdTimeDemo, CMD_TIMEDEMO }, // CmdBenchmarkStart(), CmdBenchmarkStop()
// {TEXT("WC"),CmdShowCodeWindow}, // Can't use since WatchClear
// {TEXT("WD"),CmdShowDataWindow}, //
// Internal Consistency Check
{ TEXT ( __COMMANDS_VERIFY_TXT__ ) , NULL , NUM_COMMANDS } ,
// Aliasies - Can be in any order
{ TEXT ( " -> " ) , NULL , CMD_CURSOR_JUMP_PC } ,
{ TEXT ( " Ctrl -> " ) , NULL , CMD_CURSOR_SET_PC } ,
{ TEXT ( " Shift -> " ) , NULL , CMD_CURSOR_JUMP_PC } , // at top
2006-06-27 22:04:03 +00:00
{ TEXT ( " INPUT " ) , CmdIn , CMD_IN } ,
2006-02-25 20:50:29 +00:00
// Flags - Clear
{ TEXT ( " RC " ) , CmdFlagClear , CMD_FLAG_CLR_C , " Clear Flag Carry " } , // 0 // Legacy
{ TEXT ( " RZ " ) , CmdFlagClear , CMD_FLAG_CLR_Z , " Clear Flag Zero " } , // 1
{ TEXT ( " RI " ) , CmdFlagClear , CMD_FLAG_CLR_I , " Clear Flag Interrupts Disabled " } , // 2
{ TEXT ( " RD " ) , CmdFlagClear , CMD_FLAG_CLR_D , " Clear Flag Decimal (BCD) " } , // 3
{ TEXT ( " RB " ) , CmdFlagClear , CMD_FLAG_CLR_B , " CLear Flag Break " } , // 4 // Legacy
{ TEXT ( " RR " ) , CmdFlagClear , CMD_FLAG_CLR_R , " Clear Flag Reserved " } , // 5
{ TEXT ( " RV " ) , CmdFlagClear , CMD_FLAG_CLR_V , " Clear Flag Overflow " } , // 6
{ TEXT ( " RN " ) , CmdFlagClear , CMD_FLAG_CLR_N , " Clear Flag Negative (Sign) " } , // 7
// Flags - Set
{ TEXT ( " SC " ) , CmdFlagSet , CMD_FLAG_SET_C , " Set Flag Carry " } , // 0
{ TEXT ( " SZ " ) , CmdFlagSet , CMD_FLAG_SET_Z , " Set Flag Zero " } , // 1
{ TEXT ( " SI " ) , CmdFlagSet , CMD_FLAG_SET_I , " Set Flag Interrupts Disabled " } , // 2
{ TEXT ( " SD " ) , CmdFlagSet , CMD_FLAG_SET_D , " Set Flag Decimal (BCD) " } , // 3
{ TEXT ( " SB " ) , CmdFlagSet , CMD_FLAG_SET_B , " CLear Flag Break " } , // 4 // Legacy
{ TEXT ( " SR " ) , CmdFlagSet , CMD_FLAG_SET_R , " Clear Flag Reserved " } , // 5
{ TEXT ( " SV " ) , CmdFlagSet , CMD_FLAG_SET_V , " Clear Flag Overflow " } , // 6
{ TEXT ( " SN " ) , CmdFlagSet , CMD_FLAG_SET_N , " Clear Flag Negative " } , // 7
{ TEXT ( " EB " ) , CmdMemoryEnterByte , CMD_MEMORY_ENTER_BYTE } ,
{ TEXT ( " E8 " ) , CmdMemoryEnterByte , CMD_MEMORY_ENTER_BYTE } ,
{ TEXT ( " E16 " ) , CmdMemoryEnterWord , CMD_MEMORY_ENTER_WORD } ,
{ TEXT ( " MF " ) , CmdMemoryFill , CMD_MEMORY_FILL } ,
{ TEXT ( " MM " ) , CmdMemoryMove , CMD_MEMORY_MOVE } ,
{ TEXT ( " MS " ) , CmdMemorySearch , CMD_MEMORY_SEARCH } , // CmdMemorySearch
{ TEXT ( " P0 " ) , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_0 } ,
{ TEXT ( " P1 " ) , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_1 } ,
{ TEXT ( " P2 " ) , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_2 } ,
{ TEXT ( " P3 " ) , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_3 } ,
{ TEXT ( " P4 " ) , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_4 } ,
{ TEXT ( " REGISTER " ) , CmdRegisterSet , CMD_REGISTER_SET } ,
// {TEXT("RET") , CmdStackReturn , CMD_STACK_RETURN },
{ TEXT ( " TRACE " ) , CmdTrace , CMD_TRACE } ,
{ TEXT ( " SYMBOLS " ) , CmdSymbols , CMD_SYMBOLS_LOOKUP , " Return " } ,
// {TEXT("SYMBOLS1") , CmdSymbolsInfo , CMD_SYMBOLS_1 },
// {TEXT("SYMBOLS2") , CmdSymbolsInfo , CMD_SYMBOLS_2 },
{ TEXT ( " SYM1 " ) , CmdSymbolsInfo , CMD_SYMBOLS_MAIN } ,
{ TEXT ( " SYM2 " ) , CmdSymbolsInfo , CMD_SYMBOLS_USER } ,
{ TEXT ( " SYM3 " ) , CmdSymbolsInfo , CMD_SYMBOLS_SRC } ,
{ TEXT ( " WATCH " ) , CmdWatchAdd , CMD_WATCH_ADD } ,
{ TEXT ( " WINDOW " ) , CmdWindow , CMD_WINDOW } ,
// {TEXT("W?") , CmdWatchAdd , CMD_WATCH_ADD },
{ TEXT ( " ZAP " ) , CmdNOP , CMD_NOP } ,
// DEPRECATED -- Probably should be removed in a future version
{ TEXT ( " BENCH " ) , CmdBenchmarkStart , CMD_BENCHMARK } ,
{ TEXT ( " EXITBENCH " ) , CmdBenchmarkStop , CMD_BENCHMARK } ,
{ TEXT ( " MDB " ) , CmdMemoryMiniDumpHex , CMD_MEM_MINI_DUMP_HEX_1 } , // MemoryDumpByte // Did anyone actually use this??
{ TEXT ( " MDC " ) , CmdUnassemble , CMD_UNASSEMBLE } , // MemoryDumpCode // Did anyone actually use this??
{ TEXT ( " MEB " ) , CmdMemoryEnterByte , CMD_MEMORY_ENTER_BYTE } , // MemoryEnterByte // Did anyone actually use this??
{ TEXT ( " MEMORY " ) , CmdMemoryMiniDumpHex , CMD_MEM_MINI_DUMP_HEX_1 } , // MemoryDumpByte // Did anyone actually use this??
} ;
2006-07-09 04:53:08 +00:00
// static const char g_aFlagNames[_6502_NUM_FLAGS+1] = TEXT("CZIDBRVN");// Reversed since arrays are from left-to-right
2006-02-25 20:50:29 +00:00
const int NUM_COMMANDS_WITH_ALIASES = sizeof ( g_aCommands ) / sizeof ( Command_t ) ; // Determined at compile-time ;-)
2006-02-26 06:26:56 +00:00
// Color ______________________________________________________________________
2006-02-25 20:50:29 +00:00
int g_iColorScheme = SCHEME_COLOR ;
// Used when the colors are reset
COLORREF gaColorPalette [ NUM_PALETTE ] =
{
RGB ( 0 , 0 , 0 ) ,
// NOTE: See _SetupColorRamp() if you want to programmitically set/change
RGB ( 255 , 0 , 0 ) , RGB ( 223 , 0 , 0 ) , RGB ( 191 , 0 , 0 ) , RGB ( 159 , 0 , 0 ) , RGB ( 127 , 0 , 0 ) , RGB ( 95 , 0 , 0 ) , RGB ( 63 , 0 , 0 ) , RGB ( 31 , 0 , 0 ) , // 001 // Red
RGB ( 0 , 255 , 0 ) , RGB ( 0 , 223 , 0 ) , RGB ( 0 , 191 , 0 ) , RGB ( 0 , 159 , 0 ) , RGB ( 0 , 127 , 0 ) , RGB ( 0 , 95 , 0 ) , RGB ( 0 , 63 , 0 ) , RGB ( 0 , 31 , 0 ) , // 010 // Green
RGB ( 255 , 255 , 0 ) , RGB ( 223 , 223 , 0 ) , RGB ( 191 , 191 , 0 ) , RGB ( 159 , 159 , 0 ) , RGB ( 127 , 127 , 0 ) , RGB ( 95 , 95 , 0 ) , RGB ( 63 , 63 , 0 ) , RGB ( 31 , 31 , 0 ) , // 011 // Yellow
RGB ( 0 , 0 , 255 ) , RGB ( 0 , 0 , 223 ) , RGB ( 0 , 0 , 191 ) , RGB ( 0 , 0 , 159 ) , RGB ( 0 , 0 , 127 ) , RGB ( 0 , 0 , 95 ) , RGB ( 0 , 0 , 63 ) , RGB ( 0 , 0 , 31 ) , // 100 // Blue
RGB ( 255 , 0 , 255 ) , RGB ( 223 , 0 , 223 ) , RGB ( 191 , 0 , 191 ) , RGB ( 159 , 0 , 159 ) , RGB ( 127 , 0 , 127 ) , RGB ( 95 , 0 , 95 ) , RGB ( 63 , 0 , 63 ) , RGB ( 31 , 0 , 31 ) , // 101 // Magenta
RGB ( 0 , 255 , 255 ) , RGB ( 0 , 223 , 223 ) , RGB ( 0 , 191 , 191 ) , RGB ( 0 , 159 , 159 ) , RGB ( 0 , 127 , 127 ) , RGB ( 0 , 95 , 95 ) , RGB ( 0 , 63 , 63 ) , RGB ( 0 , 31 , 31 ) , // 110 // Cyan
RGB ( 255 , 255 , 255 ) , RGB ( 223 , 223 , 223 ) , RGB ( 191 , 191 , 191 ) , RGB ( 159 , 159 , 159 ) , RGB ( 127 , 127 , 127 ) , RGB ( 95 , 95 , 95 ) , RGB ( 63 , 63 , 63 ) , RGB ( 31 , 31 , 31 ) , // 111 // White/Gray
// Custom Colors
RGB ( 80 , 192 , 255 ) , // Light Sky Blue // Used for console FG
RGB ( 0 , 128 , 192 ) , // Darker Sky Blue
RGB ( 0 , 64 , 128 ) , // Deep Sky Blue
RGB ( 255 , 128 , 0 ) , // Orange (Full)
RGB ( 128 , 64 , 0 ) , // Orange (Half)
RGB ( 0 , 0 , 0 ) ,
RGB ( 0 , 0 , 0 ) ,
RGB ( 0 , 0 , 0 ) ,
RGB ( 0 , 0 , 0 ) ,
RGB ( 0 , 0 , 0 ) ,
RGB ( 0 , 0 , 0 ) ,
RGB ( 0 , 0 , 0 ) ,
RGB ( 0 , 0 , 0 ) ,
RGB ( 0 , 0 , 0 ) ,
RGB ( 0 , 0 , 0 ) ,
RGB ( 0 , 0 , 0 ) ,
} ;
// Index into Palette
int g_aColorIndex [ NUM_COLORS ] =
{
K0 , W8 , // BG_CONSOLE_OUTPUT FG_CONSOLE_OUTPUT (W8)
B1 , COLOR_CUSTOM_01 , // BG_CONSOLE_INPUT FG_CONSOLE_INPUT (W8)
B2 , B3 , // BG_DISASM_1 BG_DISASM_2
R8 , W8 , // BG_DISASM_BP_S_C FG_DISASM_BP_S_C
R6 , W5 , // BG_DISASM_BP_0_C FG_DISASM_BP_0_C
R7 , // FG_DISASM_BP_S_X // Y8 lookes better on Info Cyan // R6
W5 , // FG_DISASM_BP_0_X
2006-02-26 06:26:56 +00:00
W8 , K0 , // BG_DISASM_C FG_DISASM_C // B8 -> K0
Y8 , K0 , // BG_DISASM_PC_C FG_DISASM_PC_C // K8 -> K0
2006-02-25 20:50:29 +00:00
Y4 , W8 , // BG_DISASM_PC_X FG_DISASM_PC_X
2006-06-26 16:59:48 +00:00
C4 , // BG_DISASM_BOOKMARK
W8 , // FG_DISASM_BOOKMARK
2006-02-25 20:50:29 +00:00
W8 , // FG_DISASM_ADDRESS
G192 , // FG_DISASM_OPERATOR
Y8 , // FG_DISASM_OPCODE
W8 , // FG_DISASM_MNEMONIC
COLOR_CUSTOM_04 , // FG_DISASM_TARGET (or W8)
G8 , // FG_DISASM_SYMBOL
C8 , // FG_DISASM_CHAR
G8 , // FG_DISASM_BRANCH
C3 , // BG_INFO (C4, C2 too dark)
W8 , // FG_INFO_TITLE (or W8)
Y7 , // FG_INFO_BULLET (W8)
G192 , // FG_INFO_OPERATOR
COLOR_CUSTOM_04 , // FG_INFO_ADDRESS (was Y8)
Y8 , // FG_INFO_OPCODE
COLOR_CUSTOM_01 , // FG_INFO_REG (was orange)
W8 , // BG_INFO_INVERSE
C3 , // FG_INFO_INVERSE
C5 , // BG_INFO_CHAR
W8 , // FG_INFO_CHAR_HI
Y8 , // FG_INFO_CHAR_LO
COLOR_CUSTOM_04 , // BG_INFO_IO_BYTE
COLOR_CUSTOM_04 , // FG_INFO_IO_BYTE
C2 , // BG_DATA_1
C3 , // BG_DATA_2
Y8 , // FG_DATA_BYTE
W8 , // FG_DATA_TEXT
G4 , // BG_SYMBOLS_1
G3 , // BG_SYMBOLS_2
W8 , // FG_SYMBOLS_ADDRESS
M8 , // FG_SYMBOLS_NAME
K0 , // BG_SOURCE_TITLE
W8 , // FG_SOURCE_TITLE
W2 , // BG_SOURCE_1 // C2 W2 for "Paper Look"
W3 , // BG_SOURCE_2
W8 // FG_SOURCE
} ;
COLORREF g_aColors [ NUM_COLOR_SCHEMES ] [ NUM_COLORS ] ;
2006-02-26 06:26:56 +00:00
COLORREF DebuggerGetColor ( int iColor ) ;
2006-02-25 20:50:29 +00:00
2006-07-05 21:23:13 +00:00
// Cursor (Console Input) _____________________________________________________
// char g_aInputCursor[] = "\|/-";
enum InputCursor
{
CURSOR_INSERT ,
CURSOR_OVERSTRIKE ,
NUM_INPUT_CURSORS
} ;
const char g_aInputCursor [ ] = " _ \x7F " ; // insert over-write
bool g_bInputCursor = false ;
int g_iInputCursor = CURSOR_OVERSTRIKE ; // which cursor to use
const int g_nInputCursor = sizeof ( g_aInputCursor ) ;
void DebuggerCursorUpdate ( ) ;
char DebuggerCursorGet ( ) ;
// Cursor (Disasm) ____________________________________________________________
2006-02-25 20:50:29 +00:00
WORD g_nDisasmTopAddress = 0 ;
WORD g_nDisasmBotAddress = 0 ;
WORD g_nDisasmCurAddress = 0 ;
bool g_bDisasmCurBad = false ;
int g_nDisasmCurLine = 0 ; // Aligned to Top or Center
2006-07-05 21:23:13 +00:00
int g_iDisasmCurState = CURSOR_NORMAL ;
2006-02-25 20:50:29 +00:00
int g_nDisasmWinHeight = 0 ;
2006-07-09 04:53:08 +00:00
// char g_aConfigDisasmAddressColon[] = TEXT(" :");
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
extern const int WINDOW_DATA_BYTES_PER_LINE = 8 ;
2006-02-25 20:50:29 +00:00
2006-07-09 04:53:08 +00:00
# if OLD_FONT
2006-02-25 20:50:29 +00:00
// Font
TCHAR g_sFontNameDefault [ MAX_FONT_NAME ] = TEXT ( " Courier New " ) ;
TCHAR g_sFontNameConsole [ MAX_FONT_NAME ] = TEXT ( " Courier New " ) ;
TCHAR g_sFontNameDisasm [ MAX_FONT_NAME ] = TEXT ( " Courier New " ) ;
TCHAR g_sFontNameInfo [ MAX_FONT_NAME ] = TEXT ( " Courier New " ) ;
TCHAR g_sFontNameBranch [ MAX_FONT_NAME ] = TEXT ( " Webdings " ) ;
HFONT g_hFontWebDings = ( HFONT ) 0 ;
2006-07-09 04:53:08 +00:00
# endif
int g_iFontSpacing = FONT_SPACING_CLEAN ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// TODO: This really needs to be phased out, and use the ConfigFont[] settings
2006-07-02 22:59:08 +00:00
# if USE_APPLE_FONT
2006-07-03 15:27:49 +00:00
int g_nFontHeight = CONSOLE_FONT_HEIGHT ; // 13 -> 12 Lucida Console is readable
2006-07-02 22:59:08 +00:00
# else
2006-02-26 06:26:56 +00:00
int g_nFontHeight = 15 ; // 13 -> 12 Lucida Console is readable
2006-07-02 22:59:08 +00:00
# endif
2006-02-25 20:50:29 +00:00
2006-07-05 21:23:13 +00:00
const int MIN_DISPLAY_CONSOLE_LINES = 5 ; // doesn't include ConsoleInput
2006-02-25 20:50:29 +00:00
2006-07-05 21:23:13 +00:00
int g_nDisasmDisplayLines = 0 ;
2006-02-25 20:50:29 +00:00
2006-06-27 22:04:03 +00:00
// Config _____________________________________________________________________
// Config - Disassembly
2006-06-13 01:21:45 +00:00
bool g_bConfigDisasmAddressColon = true ;
bool g_bConfigDisasmOpcodesView = true ;
bool g_bConfigDisasmOpcodeSpaces = true ;
int g_iConfigDisasmTargets = DISASM_TARGET_BOTH ;
int g_iConfigDisasmBranchType = DISASM_BRANCH_FANCY ;
int g_bConfigDisasmImmediateChar = DISASM_IMMED_BOTH ;
2006-06-26 16:59:48 +00:00
int g_iConfigDisasmScroll = 3 ; // favor 3 byte opcodes
2006-06-27 22:04:03 +00:00
// Config - Info
bool g_bConfigInfoTargetPointer = false ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
MemoryTextFile_t g_ConfigState ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// Display ____________________________________________________________________
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
void UpdateDisplay ( Update_t bUpdate ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// Memory _____________________________________________________________________
2006-02-25 20:50:29 +00:00
2006-06-26 16:59:48 +00:00
const int _6502_BRANCH_POS = + 127 ;
const int _6502_BRANCH_NEG = - 128 ;
2006-02-26 06:26:56 +00:00
const unsigned int _6502_ZEROPAGE_END = 0x00FF ;
const unsigned int _6502_STACK_END = 0x01FF ;
const unsigned int _6502_IO_BEGIN = 0xC000 ;
const unsigned int _6502_IO_END = 0xC0FF ;
2006-06-25 03:43:49 +00:00
const unsigned int _6502_MEM_BEGIN = 0x0000 ;
2006-06-26 16:59:48 +00:00
const unsigned int _6502_MEM_END = 0xFFFF ;
2006-02-25 20:50:29 +00:00
MemoryDump_t g_aMemDump [ NUM_MEM_DUMPS ] ;
2006-05-10 22:00:27 +00:00
// Made global so operator @# can be used with other commands.
MemorySearchResults_t g_vMemorySearchResults ;
2006-02-25 20:50:29 +00:00
// Parameters _____________________________________________________________________________________
// NOTE: Order MUST match Parameters_e[] !!!
Command_t g_aParameters [ ] =
{
// Breakpoint
{ TEXT ( " <= " ) , NULL , PARAM_BP_LESS_EQUAL } ,
{ TEXT ( " < " ) , NULL , PARAM_BP_LESS_THAN } ,
{ TEXT ( " = " ) , NULL , PARAM_BP_EQUAL } ,
2006-07-01 06:45:50 +00:00
{ TEXT ( " != " ) , NULL , PARAM_BP_NOT_EQUAL } ,
{ TEXT ( " ! " ) , NULL , PARAM_BP_NOT_EQUAL_1 } ,
2006-02-25 20:50:29 +00:00
{ TEXT ( " > " ) , NULL , PARAM_BP_GREATER_THAN } ,
{ TEXT ( " >= " ) , NULL , PARAM_BP_GREATER_EQUAL } ,
{ TEXT ( " R " ) , NULL , PARAM_BP_READ } ,
{ TEXT ( " ? " ) , NULL , PARAM_BP_READ } ,
{ TEXT ( " W " ) , NULL , PARAM_BP_WRITE } ,
{ TEXT ( " @ " ) , NULL , PARAM_BP_WRITE } ,
{ TEXT ( " * " ) , NULL , PARAM_BP_READ_WRITE } ,
// Regs (for PUSH / POP)
{ TEXT ( " A " ) , NULL , PARAM_REG_A } ,
{ TEXT ( " X " ) , NULL , PARAM_REG_X } ,
{ TEXT ( " Y " ) , NULL , PARAM_REG_Y } ,
{ TEXT ( " PC " ) , NULL , PARAM_REG_PC } ,
{ TEXT ( " S " ) , NULL , PARAM_REG_SP } ,
// Flags
{ TEXT ( " P " ) , NULL , PARAM_FLAGS } ,
{ TEXT ( " C " ) , NULL , PARAM_FLAG_C } , // ---- ---1 Carry
{ TEXT ( " Z " ) , NULL , PARAM_FLAG_Z } , // ---- --1- Zero
{ TEXT ( " I " ) , NULL , PARAM_FLAG_I } , // ---- -1-- Interrupt
{ TEXT ( " D " ) , NULL , PARAM_FLAG_D } , // ---- 1--- Decimal
{ TEXT ( " B " ) , NULL , PARAM_FLAG_B } , // ---1 ---- Break
{ TEXT ( " R " ) , NULL , PARAM_FLAG_R } , // --1- ---- Reserved
{ TEXT ( " V " ) , NULL , PARAM_FLAG_V } , // -1-- ---- Overflow
{ TEXT ( " N " ) , NULL , PARAM_FLAG_N } , // 1--- ---- Sign
2006-06-11 23:24:39 +00:00
// Disasm
{ TEXT ( " BRANCH " ) , NULL , PARAM_CONFIG_BRANCH } ,
{ TEXT ( " COLON " ) , NULL , PARAM_CONFIG_COLON } ,
{ TEXT ( " OPCODE " ) , NULL , PARAM_CONFIG_OPCODE } ,
2006-06-27 22:04:03 +00:00
{ TEXT ( " POINTER " ) , NULL , PARAM_CONFIG_POINTER } ,
2006-06-11 23:24:39 +00:00
{ TEXT ( " SPACES " ) , NULL , PARAM_CONFIG_SPACES } ,
2006-06-13 01:21:45 +00:00
{ TEXT ( " TARGET " ) , NULL , PARAM_CONFIG_TARGET } ,
2006-02-26 06:26:56 +00:00
// Disk
{ TEXT ( " EJECT " ) , NULL , PARAM_DISK_EJECT } ,
{ TEXT ( " PROTECT " ) , NULL , PARAM_DISK_PROTECT } ,
{ TEXT ( " READ " ) , NULL , PARAM_DISK_READ } ,
// Font (Config)
2006-02-25 20:50:29 +00:00
{ TEXT ( " MODE " ) , NULL , PARAM_FONT_MODE } , // also INFO, CONSOLE, DISASM (from Window)
// General
{ TEXT ( " FIND " ) , NULL , PARAM_FIND } ,
2006-02-26 06:26:56 +00:00
{ TEXT ( " BRANCH " ) , NULL , PARAM_BRANCH } ,
2006-07-01 06:45:50 +00:00
{ " CATEGORY " , NULL , PARAM_CATEGORY } ,
2006-02-25 20:50:29 +00:00
{ TEXT ( " CLEAR " ) , NULL , PARAM_CLEAR } ,
{ TEXT ( " LOAD " ) , NULL , PARAM_LOAD } ,
{ TEXT ( " LIST " ) , NULL , PARAM_LIST } ,
{ TEXT ( " OFF " ) , NULL , PARAM_OFF } ,
{ TEXT ( " ON " ) , NULL , PARAM_ON } ,
{ TEXT ( " RESET " ) , NULL , PARAM_RESET } ,
{ TEXT ( " SAVE " ) , NULL , PARAM_SAVE } ,
{ TEXT ( " START " ) , NULL , PARAM_START } , // benchmark
{ TEXT ( " STOP " ) , NULL , PARAM_STOP } , // benchmark
// Help Categories
2006-07-02 09:57:26 +00:00
{ " * " , NULL , PARAM_WILDSTAR } ,
{ " BOOKMARKS " , NULL , PARAM_CAT_BOOKMARKS } ,
{ " BREAKPOINTS " , NULL , PARAM_CAT_BREAKPOINTS } ,
{ " CONFIG " , NULL , PARAM_CAT_CONFIG } ,
{ " CPU " , NULL , PARAM_CAT_CPU } ,
2006-07-01 06:45:50 +00:00
// {TEXT("EXPRESSION") ,
2006-07-02 09:57:26 +00:00
{ " FLAGS " , NULL , PARAM_CAT_FLAGS } ,
{ " HELP " , NULL , PARAM_CAT_HELP } ,
{ " KEYBOARD " , NULL , PARAM_CAT_KEYBOARD } ,
{ " MEMORY " , NULL , PARAM_CAT_MEMORY } , // alias // SOURCE [SYMBOLS] [MEMORY] filename
{ " OUTPUT " , NULL , PARAM_CAT_OUTPUT } ,
{ " OPERATORS " , NULL , PARAM_CAT_OPERATORS } ,
{ " RANGE " , NULL , PARAM_CAT_RANGE } ,
2006-07-01 06:45:50 +00:00
// {TEXT("REGISTERS") , NULL, PARAM_CAT_REGISTERS },
2006-07-02 09:57:26 +00:00
{ " SYMBOLS " , NULL , PARAM_CAT_SYMBOLS } ,
{ " WATCHES " , NULL , PARAM_CAT_WATCHES } ,
{ " WINDOW " , NULL , PARAM_CAT_WINDOW } ,
{ " ZEROPAGE " , NULL , PARAM_CAT_ZEROPAGE } ,
2006-02-26 10:28:18 +00:00
// Memory
{ TEXT ( " ? " ) , NULL , PARAM_MEM_SEARCH_WILD } ,
// {TEXT("*") , NULL, PARAM_MEM_SEARCH_BYTE },
2006-02-25 20:50:29 +00:00
// Source level debugging
{ TEXT ( " MEM " ) , NULL , PARAM_SRC_MEMORY } ,
{ TEXT ( " MEMORY " ) , NULL , PARAM_SRC_MEMORY } ,
{ TEXT ( " SYM " ) , NULL , PARAM_SRC_SYMBOLS } ,
{ TEXT ( " SYMBOLS " ) , NULL , PARAM_SRC_SYMBOLS } ,
{ TEXT ( " MERLIN " ) , NULL , PARAM_SRC_MERLIN } ,
{ TEXT ( " ORCA " ) , NULL , PARAM_SRC_ORCA } ,
// Window Win Cmd WinEffects CmdEffects
{ TEXT ( " CODE " ) , NULL , PARAM_CODE } , // x x code win only switch to code window
// {TEXT("CODE1") , NULL, PARAM_CODE_1 }, // - x code/data win
{ TEXT ( " CODE2 " ) , NULL , PARAM_CODE_2 } , // - x code/data win
{ TEXT ( " CONSOLE " ) , NULL , PARAM_CONSOLE } , // x - switch to console window
{ TEXT ( " DATA " ) , NULL , PARAM_DATA } , // x x data win only switch to data window
// {TEXT("DATA1") , NULL, PARAM_DATA_1 }, // - x code/data win
{ TEXT ( " DATA2 " ) , NULL , PARAM_DATA_2 } , // - x code/data win
{ TEXT ( " DISASM " ) , NULL , PARAM_DISASM } , //
{ TEXT ( " INFO " ) , NULL , PARAM_INFO } , // - x code/data Toggles showing/hiding Regs/Stack/BP/Watches/ZP
{ TEXT ( " SOURCE " ) , NULL , PARAM_SOURCE } , // x x switch to source window
{ TEXT ( " SRC " ) , NULL , PARAM_SOURCE } , // alias
// {TEXT("SOURCE_1") , NULL, PARAM_SOURCE_1 }, // - x code/data
{ TEXT ( " SOURCE2 " ) , NULL , PARAM_SOURCE_2 } , // - x
{ TEXT ( " SYMBOLS " ) , NULL , PARAM_SYMBOLS } , // x x code/data win switch to symbols window
{ TEXT ( " SYM " ) , NULL , PARAM_SYMBOLS } , // alias x SOURCE [SYM] [MEM] filename
// {TEXT("SYMBOL1") , NULL, PARAM_SYMBOL_1 }, // - x code/data win
{ TEXT ( " SYMBOL2 " ) , NULL , PARAM_SYMBOL_2 } , // - x code/data win
// Internal Consistency Check
{ TEXT ( __PARAMS_VERIFY_TXT__ ) , NULL , NUM_PARAMS } ,
} ;
// Profile
const int NUM_PROFILE_LINES = NUM_OPCODES + NUM_OPMODES + 16 ;
ProfileOpcode_t g_aProfileOpcodes [ NUM_OPCODES ] ;
ProfileOpmode_t g_aProfileOpmodes [ NUM_OPMODES ] ;
TCHAR g_FileNameProfile [ ] = TEXT ( " Profile.txt " ) ; // changed from .csv to .txt since Excel doesn't give import options.
int g_nProfileLine = 0 ;
char g_aProfileLine [ NUM_PROFILE_LINES ] [ CONSOLE_WIDTH ] ;
void ProfileReset ( ) ;
bool ProfileSave ( ) ;
void ProfileFormat ( bool bSeperateColumns , ProfileFormat_e eFormatMode ) ;
char * ProfileLinePeek ( int iLine ) ;
char * ProfileLinePush ( ) ;
void ProfileLineReset ( ) ;
// Source Level Debugging _________________________________________________________________________
bool g_bSourceLevelDebugging = false ;
bool g_bSourceAddSymbols = false ;
bool g_bSourceAddMemory = false ;
2006-08-16 18:58:56 +00:00
char g_aSourceFileName [ MAX_PATH ] = " " ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
MemoryTextFile_t g_AssemblerSourceBuffer ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
int g_iSourceDisplayStart = 0 ;
2006-02-25 20:50:29 +00:00
int g_nSourceAssembleBytes = 0 ;
int g_nSourceAssemblySymbols = 0 ;
// TODO: Support multiple source filenames
SourceAssembly_t g_aSourceDebug ;
// Symbols ________________________________________________________________________________________
2006-08-16 18:58:56 +00:00
char * g_aSymbolTableNames [ NUM_SYMBOL_TABLES ] =
2006-02-25 20:50:29 +00:00
{
2006-08-16 18:58:56 +00:00
" Main " ,
" User " ,
" Src "
2006-02-25 20:50:29 +00:00
} ;
SymbolTable_t g_aSymbols [ NUM_SYMBOL_TABLES ] ;
int g_nSymbolsLoaded = 0 ; // on Last Load
bool g_aConfigSymbolsDisplayed [ NUM_SYMBOL_TABLES ] =
{
true ,
true ,
true
} ;
// Watches ________________________________________________________________________________________
int g_nWatches = 0 ;
2006-02-26 06:26:56 +00:00
Watches_t g_aWatches [ MAX_WATCHES ] ; // TODO: use vector<Watch_t> ??
2006-02-25 20:50:29 +00:00
// Window _________________________________________________________________________________________
int g_iWindowLast = WINDOW_CODE ;
int g_iWindowThis = WINDOW_CODE ;
WindowSplit_t g_aWindowConfig [ NUM_WINDOWS ] ;
// Zero Page Pointers _____________________________________________________________________________
int g_nZeroPagePointers = 0 ;
ZeroPagePointers_t g_aZeroPagePointers [ MAX_ZEROPAGE_POINTERS ] ; // TODO: use vector<> ?
2006-02-26 06:26:56 +00:00
// TODO: // CONFIG SAVE --> VERSION #
2006-02-25 20:50:29 +00:00
enum DebugConfigVersion_e
{
VERSION_0 ,
CURRENT_VERSION = VERSION_0
} ;
// Misc. __________________________________________________________________________________________
2006-07-01 06:45:50 +00:00
char g_sFileNameConfig [ ] =
# ifdef MSDOS
" AWDEBUGR.CFG " ;
# else
" AppleWinDebugger.cfg " ;
# endif
char g_sFileNameSymbolsMain [ ] = " APPLE2E.SYM " ;
char g_sFileNameSymbolsUser [ MAX_PATH ] = " " ;
char g_sFileNameTrace [ ] = " Trace.txt " ;
2006-02-25 20:50:29 +00:00
bool g_bBenchmarking = false ;
BOOL fulldisp = 0 ;
WORD lastpc = 0 ;
BOOL g_bProfiling = 0 ;
int g_nDebugSteps = 0 ;
DWORD g_nDebugStepCycles = 0 ;
int g_nDebugStepStart = 0 ;
2006-02-26 06:26:56 +00:00
int g_nDebugStepUntil = - 1 ; // HACK: MAGIC #
2006-02-25 20:50:29 +00:00
int g_nDebugSkipStart = 0 ;
int g_nDebugSkipLen = 0 ;
FILE * g_hTraceFile = NULL ;
2006-08-16 18:58:56 +00:00
bool g_bTraceHeader = false ; // semaphore, flag header to be printed
2006-02-25 20:50:29 +00:00
DWORD extbench = 0 ;
bool g_bDebuggerViewingAppleOutput = false ;
2006-06-27 22:04:03 +00:00
bool g_bIgnoreNextKey = false ;
2006-06-26 16:59:48 +00:00
2006-02-26 06:26:56 +00:00
// Private ________________________________________________________________________________________
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// Prototypes _______________________________________________________________
2006-02-25 20:50:29 +00:00
2006-06-27 22:04:03 +00:00
static int ParseInput ( LPTSTR pConsoleInput , bool bCook = true ) ;
static Update_t ExecuteCommand ( int nArgs ) ;
// Breakpoints
2006-07-05 21:23:13 +00:00
void _BWZ_List ( const Breakpoint_t * aBreakWatchZero , const int iBWZ ) ; // bool bZeroBased = true );
void _BWZ_ListAll ( const Breakpoint_t * aBreakWatchZero , const int nMax ) ;
2006-06-27 22:04:03 +00:00
// bool CheckBreakpoint (WORD address, BOOL memory);
bool CheckBreakpointsIO ( ) ;
bool CheckBreakpointsReg ( ) ;
bool _CmdBreakpointAddReg ( Breakpoint_t * pBP , BreakpointSource_t iSrc , BreakpointOperator_t iCmp , WORD nAddress , int nLen ) ;
2006-07-01 06:45:50 +00:00
int _CmdBreakpointAddCommonArg ( int iArg , int nArg , BreakpointSource_t iSrc , BreakpointOperator_t iCmp ) ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
// Config - Colors
2006-06-27 22:04:03 +00:00
static void _ConfigColorsReset ( ) ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
// Config - Save
bool ConfigSave_BufferToDisk ( char * pFileName , ConfigSave_t eConfigSave ) ;
void ConfigSave_PrepareHeader ( const Parameters_e eCategory , const Commands_e eCommandClear ) ;
2006-02-25 20:50:29 +00:00
// Drawing
2006-06-27 22:04:03 +00:00
static bool DebuggerSetColor ( const int iScheme , const int iColor , const COLORREF nColor ) ;
static void _CmdColorGet ( const int iScheme , const int iColor ) ;
2006-02-26 06:26:56 +00:00
// Font
2006-06-27 22:04:03 +00:00
static void _UpdateWindowFontHeights ( int nFontHeight ) ;
2006-02-25 20:50:29 +00:00
2006-06-27 22:04:03 +00:00
// Symbols
2006-02-25 20:50:29 +00:00
Update_t _CmdSymbolsClear ( Symbols_e eSymbolTable ) ;
Update_t _CmdSymbolsCommon ( int nArgs , int bSymbolTables ) ;
Update_t _CmdSymbolsListTables ( int nArgs , int bSymbolTables ) ;
Update_t _CmdSymbolsUpdate ( int nArgs ) ;
bool _CmdSymbolList_Address2Symbol ( int nAddress , int bSymbolTables ) ;
bool _CmdSymbolList_Symbol2Address ( LPCTSTR pSymbol , int bSymbolTables ) ;
2006-02-26 06:26:56 +00:00
// Source Level Debugging
2006-08-16 18:58:56 +00:00
static bool BufferAssemblyListing ( char * pFileName ) ;
2006-06-27 22:04:03 +00:00
static bool ParseAssemblyListing ( bool bBytesToMemory , bool bAddSymbols ) ;
2006-02-25 20:50:29 +00:00
// Window
void _WindowJoin ( ) ;
void _WindowSplit ( Window_e eNewBottomWindow ) ;
void _WindowLast ( ) ;
void _WindowSwitch ( int eNewWindow ) ;
int WindowGetHeight ( int iWindow ) ;
void WindowUpdateDisasmSize ( ) ;
void WindowUpdateConsoleDisplayedSize ( ) ;
void WindowUpdateSizes ( ) ;
Update_t _CmdWindowViewFull ( int iNewWindow ) ;
Update_t _CmdWindowViewCommon ( int iNewWindow ) ;
// Utility
2006-07-01 06:45:50 +00:00
RangeType_t Range_Get ( WORD & nAddress1_ , WORD & nAddress2_ , const int iArg = 1 ) ;
bool Range_CalcEndLen ( const RangeType_t eRange
, const WORD & nAddress1 , const WORD & nAddress2
, WORD & nAddressEnd_ , int & nAddressLen_ ) ;
2006-06-12 03:08:35 +00:00
2006-02-25 20:50:29 +00:00
bool StringCat ( TCHAR * pDst , LPCSTR pSrc , const int nDstSize ) ;
bool TestStringCat ( TCHAR * pDst , LPCSTR pSrc , const int nDstSize ) ;
bool TryStringCat ( TCHAR * pDst , LPCSTR pSrc , const int nDstSize ) ;
char FormatCharTxtCtrl ( const BYTE b , bool * pWasCtrl_ ) ;
char FormatCharTxtAsci ( const BYTE b , bool * pWasAsci_ ) ;
char FormatCharTxtHigh ( const BYTE b , bool * pWasHi_ ) ;
char FormatChar4Font ( const BYTE b , bool * pWasHi_ , bool * pWasLo_ ) ;
void _CursorMoveDownAligned ( int nDelta ) ;
void _CursorMoveUpAligned ( int nDelta ) ;
void DisasmCalcTopFromCurAddress ( bool bUpdateTop = true ) ;
bool InternalSingleStep ( ) ;
void DisasmCalcCurFromTopAddress ( ) ;
void DisasmCalcBotFromTopAddress ( ) ;
void DisasmCalcTopBotAddress ( ) ;
WORD DisasmCalcAddressFromLines ( WORD iAddress , int nLines ) ;
2006-02-26 06:26:56 +00:00
//===========================================================================
LPCTSTR FormatAddress ( WORD nAddress , int nBytes )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
// No symbol for this addres -- string with nAddress
static TCHAR sSymbol [ 8 ] = TEXT ( " " ) ;
switch ( nBytes )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
case 2 : wsprintf ( sSymbol , TEXT ( " $%02X " ) , ( unsigned ) nAddress ) ; break ;
case 3 : wsprintf ( sSymbol , TEXT ( " $%04X " ) , ( unsigned ) nAddress ) ; break ;
default : sSymbol [ 0 ] = 0 ; break ; // clear since is static
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
return sSymbol ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
2006-07-01 06:45:50 +00:00
// Util - Range _______________________________________________________________
//===========================================================================
bool Range_CalcEndLen ( const RangeType_t eRange
, const WORD & nAddress1 , const WORD & nAddress2
, WORD & nAddressEnd_ , int & nAddressLen_ )
{
bool bValid = false ;
if ( eRange = = RANGE_HAS_LEN )
{
// BSAVE 2000,0 Len=0 End=n/a
// BSAVE 2000,1 Len=1 End=2000
// 0,FFFF [,)
// End = FFFE = Len-1
// Len = FFFF
nAddressLen_ = nAddress2 ;
int nTemp = nAddress1 + nAddressLen_ - 1 ;
if ( nTemp > _6502_MEM_END )
nTemp = _6502_MEM_END ;
nAddressEnd_ = nTemp ;
bValid = true ;
}
else
if ( eRange = = RANGE_HAS_END )
{
// BSAVE 2000:2000 Len=0, End=n/a
// BSAVE 2000:2001 Len=1, End=2000
// 0:FFFF [,]
// End = FFFF
// Len = 10000 = End+1
nAddressEnd_ = nAddress2 ;
nAddressLen_ = nAddress2 - nAddress1 + 1 ;
bValid = true ;
}
return bValid ;
}
//===========================================================================
RangeType_t Range_Get ( WORD & nAddress1_ , WORD & nAddress2_ , const int iArg ) // =1
{
nAddress1_ = ( unsigned ) g_aArgs [ iArg ] . nValue ;
if ( nAddress1_ > _6502_MEM_END )
nAddress1_ = _6502_MEM_END ;
nAddress2_ = 0 ;
int nTemp = 0 ;
RangeType_t eRange = RANGE_MISSING_ARG_2 ;
if ( g_aArgs [ iArg + 1 ] . eToken = = TOKEN_COMMA )
{
// 0,FFFF [,) // Note the mathematical range
// End = FFFE = Len-1
// Len = FFFF
eRange = RANGE_HAS_LEN ;
nTemp = g_aArgs [ iArg + 2 ] . nValue ;
nAddress2_ = nTemp ;
}
else
if ( g_aArgs [ iArg + 1 ] . eToken = = TOKEN_COLON )
{
// 0:FFFF [,] // Note the mathematical range
// End = FFFF
// Len = 10000 = End+1
eRange = RANGE_HAS_END ;
nTemp = g_aArgs [ iArg + 2 ] . nValue ;
// i.e.
// FFFF:D000
// 1 2 Temp
// FFFF D000
// FFFF
// D000
if ( nAddress1_ > nTemp )
{
nAddress2_ = nAddress1_ ;
nAddress1_ = nTemp ;
}
else
nAddress2_ = nTemp ;
}
// .17 Bug Fix: D000,FFFF -> D000,CFFF (nothing searched!)
// if (nTemp > _6502_MEM_END)
// nTemp = _6502_MEM_END;
return eRange ;
}
2006-06-26 16:59:48 +00:00
// Bookmarks __________________________________________________________________
//===========================================================================
bool _Bookmark_Add ( const int iBookmark , const WORD nAddress )
{
if ( iBookmark < MAX_BOOKMARKS )
{
// g_aBookmarks.push_back( nAddress );
2006-06-27 22:04:03 +00:00
// g_aBookmarks.at( iBookmark ) = nAddress;
g_aBookmarks [ iBookmark ] . nAddress = nAddress ;
g_aBookmarks [ iBookmark ] . bSet = true ;
g_nBookmarks + + ;
2006-06-26 16:59:48 +00:00
return true ;
}
return false ;
}
//===========================================================================
bool _Bookmark_Del ( const WORD nAddress )
{
bool bDeleted = false ;
2006-06-27 22:04:03 +00:00
// int nSize = g_aBookmarks.size();
2006-06-26 16:59:48 +00:00
int iBookmark ;
2006-06-27 22:04:03 +00:00
for ( iBookmark = 0 ; iBookmark < MAX_BOOKMARKS ; iBookmark + + )
2006-06-26 16:59:48 +00:00
{
2006-06-27 22:04:03 +00:00
if ( g_aBookmarks [ iBookmark ] . nAddress = = nAddress )
2006-06-26 16:59:48 +00:00
{
2006-06-27 22:04:03 +00:00
// g_aBookmarks.at( iBookmark ) = NO_6502_TARGET;
g_aBookmarks [ iBookmark ] . bSet = false ;
2006-06-26 16:59:48 +00:00
bDeleted = true ;
}
}
return bDeleted ;
}
bool Bookmark_Find ( const WORD nAddress )
{
// Ugh, linear search
2006-06-27 22:04:03 +00:00
// int nSize = g_aBookmarks.size();
2006-06-26 16:59:48 +00:00
int iBookmark ;
2006-06-27 22:04:03 +00:00
for ( iBookmark = 0 ; iBookmark < MAX_BOOKMARKS ; iBookmark + + )
2006-06-26 16:59:48 +00:00
{
2006-06-27 22:04:03 +00:00
if ( g_aBookmarks [ iBookmark ] . nAddress = = nAddress )
2006-06-26 16:59:48 +00:00
{
2006-06-27 22:04:03 +00:00
if ( g_aBookmarks [ iBookmark ] . bSet )
return true ;
2006-06-26 16:59:48 +00:00
}
}
return false ;
}
//===========================================================================
bool _Bookmark_Get ( const int iBookmark , WORD & nAddress )
{
2006-06-27 22:04:03 +00:00
// int nSize = g_aBookmarks.size();
if ( iBookmark > = MAX_BOOKMARKS )
2006-06-26 16:59:48 +00:00
return false ;
2006-06-27 22:04:03 +00:00
if ( g_aBookmarks [ iBookmark ] . bSet )
2006-06-26 16:59:48 +00:00
{
2006-06-27 22:04:03 +00:00
nAddress = g_aBookmarks [ iBookmark ] . nAddress ;
2006-06-26 16:59:48 +00:00
return true ;
}
return false ;
}
//===========================================================================
void _Bookmark_Reset ( )
{
2006-06-27 22:04:03 +00:00
// g_aBookmarks.reserve( MAX_BOOKMARKS );
// g_aBookmarks.insert( g_aBookma int iBookmark = 0;
int iBookmark = 0 ;
for ( iBookmark = 0 ; iBookmark < MAX_BOOKMARKS ; iBookmark + + )
{
g_aBookmarks [ iBookmark ] . bSet = false ;
}
2006-06-26 16:59:48 +00:00
}
//===========================================================================
int _Bookmark_Size ( )
{
2006-06-27 22:04:03 +00:00
int g_nBookmarks = 0 ;
2006-06-26 16:59:48 +00:00
int iBookmark ;
2006-06-27 22:04:03 +00:00
for ( iBookmark = 0 ; iBookmark < MAX_BOOKMARKS ; iBookmark + + )
{
if ( g_aBookmarks [ iBookmark ] . bSet )
g_nBookmarks + + ;
}
return g_nBookmarks ;
}
//===========================================================================
2006-07-01 06:45:50 +00:00
Update_t CmdBookmark ( int nArgs )
2006-06-27 22:04:03 +00:00
{
2006-07-01 06:45:50 +00:00
return CmdBookmarkAdd ( nArgs ) ;
2006-06-27 22:04:03 +00:00
}
//===========================================================================
Update_t CmdBookmarkAdd ( int nArgs )
{
2006-07-01 06:45:50 +00:00
// BMA [address]
// BMA # address
if ( ! nArgs )
2006-06-27 22:04:03 +00:00
{
2006-07-01 06:45:50 +00:00
return CmdZeroPageList ( 0 ) ;
}
2006-06-27 22:04:03 +00:00
2006-07-01 06:45:50 +00:00
int iArg = 1 ;
int iBookmark = NO_6502_TARGET ;
if ( nArgs > 1 )
{
iBookmark = g_aArgs [ 1 ] . nValue ;
2006-06-27 22:04:03 +00:00
iArg + + ;
2006-07-01 06:45:50 +00:00
}
bool bAdded = false ;
for ( ; iArg < = nArgs ; iArg + + )
{
WORD nAddress = g_aArgs [ iArg ] . nValue ;
if ( iBookmark = = NO_6502_TARGET )
{
iBookmark = 0 ;
while ( ( iBookmark < MAX_BOOKMARKS ) & & ( g_aBookmarks [ iBookmark ] . bSet ) )
{
iBookmark + + ;
}
}
if ( ( iBookmark > = MAX_BOOKMARKS ) & & ! bAdded )
2006-06-27 22:04:03 +00:00
{
2006-07-01 06:45:50 +00:00
char sText [ CONSOLE_WIDTH ] ;
sprintf ( sText , " All bookmarks are currently in use. (Max: %d) " , MAX_BOOKMARKS ) ;
ConsoleDisplayPush ( sText ) ;
return ConsoleUpdate ( ) ;
}
if ( ( iBookmark < MAX_BOOKMARKS ) & & ( g_nBookmarks < MAX_BOOKMARKS ) )
{
g_aBookmarks [ iBookmark ] . bSet = true ;
g_aBookmarks [ iBookmark ] . nAddress = nAddress ;
bAdded = true ;
g_nBookmarks + + ;
iBookmark + + ;
2006-06-27 22:04:03 +00:00
}
}
2006-07-01 06:45:50 +00:00
if ( ! bAdded )
goto _Help ;
2006-06-27 22:04:03 +00:00
2006-07-01 06:45:50 +00:00
return UPDATE_DISASM | ConsoleUpdate ( ) ;
2006-06-27 22:04:03 +00:00
2006-07-01 06:45:50 +00:00
_Help :
return Help_Arg_1 ( CMD_BOOKMARK_ADD ) ;
2006-06-27 22:04:03 +00:00
}
2006-07-01 06:45:50 +00:00
2006-06-27 22:04:03 +00:00
//===========================================================================
Update_t CmdBookmarkClear ( int nArgs )
{
int iBookmark = 0 ;
bool bClearAll = false ;
int iArg ;
for ( iArg = 1 ; iArg < = nArgs ; iArg + + )
2006-06-26 16:59:48 +00:00
{
2006-06-27 22:04:03 +00:00
if ( ! _tcscmp ( g_aArgs [ nArgs ] . sArg , g_aParameters [ PARAM_WILDSTAR ] . m_sName ) )
{
for ( iBookmark = 0 ; iBookmark < MAX_BOOKMARKS ; iBookmark + + )
{
if ( g_aBookmarks [ iBookmark ] . bSet )
g_aBookmarks [ iBookmark ] . bSet = false ;
}
break ;
}
iBookmark = g_aArgs [ iArg ] . nValue ;
if ( g_aBookmarks [ iBookmark ] . bSet )
g_aBookmarks [ iBookmark ] . bSet = false ;
2006-06-26 16:59:48 +00:00
}
2006-06-27 22:04:03 +00:00
return UPDATE_DISASM ;
2006-06-26 16:59:48 +00:00
}
//===========================================================================
Update_t CmdBookmarkGoto ( int nArgs )
{
2006-07-01 06:45:50 +00:00
if ( ! nArgs )
return Help_Arg_1 ( CMD_BOOKMARK_GOTO ) ;
int iBookmark = g_aArgs [ 1 ] . nValue ;
2006-06-26 16:59:48 +00:00
WORD nAddress ;
if ( _Bookmark_Get ( iBookmark , nAddress ) )
{
g_nDisasmCurAddress = nAddress ;
g_nDisasmCurLine = 0 ;
DisasmCalcTopBotAddress ( ) ;
}
return UPDATE_DISASM ;
}
//===========================================================================
2006-06-27 22:04:03 +00:00
Update_t CmdBookmarkList ( int nArgs )
2006-06-26 16:59:48 +00:00
{
2006-06-27 22:04:03 +00:00
if ( ! g_nBookmarks )
{
TCHAR sText [ CONSOLE_WIDTH ] ;
wsprintf ( sText , TEXT ( " There are no current bookmarks. (Max: %d) " ) , MAX_BOOKMARKS ) ;
ConsoleBufferPush ( sText ) ;
}
else
{
2006-07-05 21:23:13 +00:00
_BWZ_ListAll ( g_aBookmarks , MAX_BOOKMARKS ) ;
2006-06-27 22:04:03 +00:00
}
return ConsoleUpdate ( ) ;
}
2006-06-26 16:59:48 +00:00
2006-06-27 22:04:03 +00:00
//===========================================================================
Update_t CmdBookmarkLoad ( int nArgs )
{
2006-07-01 06:45:50 +00:00
char sFilePath [ MAX_PATH ] = " " ;
2006-06-26 16:59:48 +00:00
2006-07-01 06:45:50 +00:00
if ( nArgs = = 1 )
{
// strcpy( sMiniFileName, pFileName );
// strcat( sMiniFileName, ".aws" ); // HACK: MAGIC STRING
// _tcscpy(sFileName, g_sCurrentDir); //
// _tcscat(sFileName, sMiniFileName);
}
2006-06-27 22:04:03 +00:00
return UPDATE_CONSOLE_DISPLAY ;
}
2006-05-14 00:43:19 +00:00
//===========================================================================
2006-07-01 06:45:50 +00:00
Update_t CmdBookmarkSave ( int nArgs )
2006-05-14 00:43:19 +00:00
{
TCHAR sText [ CONSOLE_WIDTH ] ;
2006-07-01 06:45:50 +00:00
g_ConfigState . Reset ( ) ;
2006-05-14 00:43:19 +00:00
2006-07-01 06:45:50 +00:00
ConfigSave_PrepareHeader ( PARAM_CAT_BOOKMARKS , CMD_BOOKMARK_CLEAR ) ;
2006-05-14 00:43:19 +00:00
2006-07-01 06:45:50 +00:00
int iBookmark = 0 ;
while ( iBookmark < MAX_BOOKMARKS )
2006-05-14 00:43:19 +00:00
{
2006-07-01 06:45:50 +00:00
if ( g_aBookmarks [ iBookmark ] . bSet )
2006-05-14 00:43:19 +00:00
{
2006-07-01 06:45:50 +00:00
sprintf ( sText , " %s %x %04X \n "
, g_aCommands [ CMD_BOOKMARK_ADD ] . m_sName
, iBookmark
, g_aBookmarks [ iBookmark ] . nAddress
) ;
g_ConfigState . PushLine ( sText ) ;
2006-05-14 00:43:19 +00:00
}
2006-07-01 06:45:50 +00:00
iBookmark + + ;
}
2006-05-14 00:43:19 +00:00
2006-07-01 06:45:50 +00:00
if ( nArgs )
{
if ( ! ( g_aArgs [ 1 ] . bType & TYPE_QUOTED_2 ) )
return Help_Arg_1 ( CMD_BOOKMARK_SAVE ) ;
2006-05-14 00:43:19 +00:00
2006-07-01 06:45:50 +00:00
if ( ConfigSave_BufferToDisk ( g_aArgs [ 1 ] . sArg , CONFIG_SAVE_FILE_CREATE ) )
{
ConsoleBufferPush ( TEXT ( " Saved. " ) ) ;
2006-05-14 00:43:19 +00:00
return ConsoleUpdate ( ) ;
}
2006-07-01 06:45:50 +00:00
}
2006-05-14 00:43:19 +00:00
return UPDATE_CONSOLE_DISPLAY ;
}
2006-07-01 06:45:50 +00:00
2006-05-14 00:43:19 +00:00
//===========================================================================
2006-07-01 06:45:50 +00:00
BOOL CheckJump ( WORD targetaddress )
2006-05-14 00:43:19 +00:00
{
2006-07-01 06:45:50 +00:00
WORD savedpc = regs . pc ;
InternalSingleStep ( ) ;
BOOL result = ( regs . pc = = targetaddress ) ;
regs . pc = savedpc ;
return result ;
}
2006-05-14 00:43:19 +00:00
2006-07-01 06:45:50 +00:00
// Benchmark ______________________________________________________________________________________
2006-05-14 00:43:19 +00:00
2006-07-01 06:45:50 +00:00
//===========================================================================
Update_t CmdBenchmark ( int nArgs )
{
if ( g_bBenchmarking )
CmdBenchmarkStart ( 0 ) ;
2006-05-14 00:43:19 +00:00
else
2006-07-01 06:45:50 +00:00
CmdBenchmarkStop ( 0 ) ;
return UPDATE_ALL ; // TODO/FIXME Verify
2006-05-14 00:43:19 +00:00
}
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-07-01 06:45:50 +00:00
Update_t CmdBenchmarkStart ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
CpuSetupBenchmark ( ) ;
g_nDisasmCurAddress = regs . pc ;
DisasmCalcTopBotAddress ( ) ;
g_bBenchmarking = true ;
return UPDATE_ALL ; // 1;
}
//===========================================================================
Update_t CmdBenchmarkStop ( int nArgs )
{
g_bBenchmarking = false ;
DebugEnd ( ) ;
g_nAppMode = MODE_RUNNING ;
FrameRefreshStatus ( DRAW_TITLE ) ;
VideoRedrawScreen ( ) ;
DWORD currtime = GetTickCount ( ) ;
while ( ( extbench = GetTickCount ( ) ) ! = currtime )
; // intentional busy-waiting
KeybQueueKeypress ( TEXT ( ' ' ) , 1 ) ;
g_bResetTiming = true ;
return UPDATE_ALL ; // 0;
}
//===========================================================================
Update_t CmdProfile ( int nArgs )
{
if ( ! nArgs )
{
sprintf ( g_aArgs [ 1 ] . sArg , g_aParameters [ PARAM_RESET ] . m_sName ) ;
nArgs = 1 ;
}
if ( nArgs = = 1 )
{
int iParam ;
int nFound = FindParam ( g_aArgs [ 1 ] . sArg , MATCH_EXACT , iParam , _PARAM_GENERAL_BEGIN , _PARAM_GENERAL_END ) ;
if ( ! nFound )
goto _Help ;
if ( iParam = = PARAM_RESET )
{
ProfileReset ( ) ;
g_bProfiling = 1 ;
ConsoleBufferPush ( TEXT ( " Resetting profile data. " ) ) ;
}
else
{
if ( ( iParam ! = PARAM_SAVE ) & & ( iParam ! = PARAM_LIST ) )
goto _Help ;
bool bExport = true ;
if ( iParam = = PARAM_LIST )
bExport = false ;
// .csv (Comma Seperated Value)
// ProfileFormat( bExport, bExport ? PROFILE_FORMAT_COMMA : PROFILE_FORMAT_SPACE );
// .txt (Tab Seperated Value)
ProfileFormat ( bExport , bExport ? PROFILE_FORMAT_TAB : PROFILE_FORMAT_SPACE ) ;
// Dump to console
if ( iParam = = PARAM_LIST )
{
char * pText ;
char sText [ CONSOLE_WIDTH ] ;
int nLine = g_nProfileLine ;
int iLine ;
for ( iLine = 0 ; iLine < nLine ; iLine + + )
{
pText = ProfileLinePeek ( iLine ) ;
if ( pText )
{
TextConvertTabsToSpaces ( sText , pText , CONSOLE_WIDTH , 4 ) ;
2006-08-16 18:58:56 +00:00
// ConsoleBufferPush( sText );
ConsolePrint ( sText ) ;
2006-07-01 06:45:50 +00:00
}
}
}
if ( iParam = = PARAM_SAVE )
{
if ( ProfileSave ( ) )
{
TCHAR sText [ CONSOLE_WIDTH ] ;
wsprintf ( sText , " Saved: %s " , g_FileNameProfile ) ;
ConsoleBufferPush ( sText ) ;
}
else
ConsoleBufferPush ( TEXT ( " ERROR: Couldn't save file. (In use?) " ) ) ;
}
}
}
else
goto _Help ;
return ConsoleUpdate ( ) ; // UPDATE_CONSOLE_DISPLAY;
_Help :
return Help_Arg_1 ( CMD_PROFILE ) ;
}
// Breakpoints ____________________________________________________________________________________
//===========================================================================
Update_t CmdBreakInvalid ( int nArgs ) // Breakpoint IFF Full-speed!
{
if ( ( nArgs > 2 ) | | ( nArgs = = 0 ) )
goto _Help ;
int iType = 0 ; // default to BRK
int nActive ;
// if (nArgs == 2)
iType = g_aArgs [ 1 ] . nValue ;
// Cases:
// 0. CMD // display
// 1a. CMD # // display
// 1b. CMD ON | OFF //set
// 1c. CMD ? // error
// 2a. CMD # ON | OFF // set
// 2b. CMD # ? // error
TCHAR sText [ CONSOLE_WIDTH ] ;
bool bValidParam = true ;
int iParamArg = nArgs ;
int iParam ;
int nFound = FindParam ( g_aArgs [ iParamArg ] . sArg , MATCH_EXACT , iParam , _PARAM_GENERAL_BEGIN , _PARAM_GENERAL_END ) ;
if ( nFound )
{
if ( iParam = = PARAM_ON )
nActive = 1 ;
else
if ( iParam = = PARAM_OFF )
nActive = 0 ;
else
bValidParam = false ;
}
else
bValidParam = false ;
if ( nArgs = = 1 )
{
if ( ! nFound ) // bValidParam) // case 1a or 1c
{
if ( ( iType < 0 ) | | ( iType > AM_3 ) )
goto _Help ;
if ( IsDebugBreakOnInvalid ( iType ) )
iParam = PARAM_ON ;
else
iParam = PARAM_OFF ;
}
else // case 1b
{
SetDebugBreakOnInvalid ( iType , nActive ) ;
}
if ( iType = = 0 )
wsprintf ( sText , TEXT ( " Enter debugger on BRK opcode: %s " ) , g_aParameters [ iParam ] . m_sName ) ;
else
wsprintf ( sText , TEXT ( " Enter debugger on INVALID %1X opcode: %s " ) , iType , g_aParameters [ iParam ] . m_sName ) ;
ConsoleBufferPush ( sText ) ;
return ConsoleUpdate ( ) ;
}
else
if ( nArgs = = 2 )
{
if ( ! bValidParam ) // case 2b
{
goto _Help ;
}
else // case 2a (or not 2b ;-)
{
if ( ( iType < 0 ) | | ( iType > AM_3 ) )
goto _Help ;
SetDebugBreakOnInvalid ( iType , nActive ) ;
if ( iType = = 0 )
wsprintf ( sText , TEXT ( " Enter debugger on BRK opcode: %s " ) , g_aParameters [ iParam ] . m_sName ) ;
else
wsprintf ( sText , TEXT ( " Enter debugger on INVALID %1X opcode: %s " ) , iType , g_aParameters [ iParam ] . m_sName ) ;
ConsoleBufferPush ( sText ) ;
return ConsoleUpdate ( ) ;
}
}
return UPDATE_CONSOLE_DISPLAY ;
_Help :
return HelpLastCommand ( ) ;
}
//===========================================================================
Update_t CmdBreakOpcode ( int nArgs ) // Breakpoint IFF Full-speed!
{
TCHAR sText [ CONSOLE_WIDTH ] ;
if ( nArgs > 1 )
return HelpLastCommand ( ) ;
TCHAR sAction [ CONSOLE_WIDTH ] = TEXT ( " Current " ) ; // default to display
if ( nArgs = = 1 )
{
int iOpcode = g_aArgs [ 1 ] . nValue ;
g_iDebugOnOpcode = iOpcode & 0xFF ;
_tcscpy ( sAction , TEXT ( " Setting " ) ) ;
if ( iOpcode > = NUM_OPCODES )
{
wsprintf ( sText , TEXT ( " Warning: clamping opcode: %02X " ) , g_iDebugOnOpcode ) ;
ConsoleBufferPush ( sText ) ;
return ConsoleUpdate ( ) ;
}
}
if ( g_iDebugOnOpcode = = 0 )
// Show what the current break opcode is
wsprintf ( sText , TEXT ( " %s full speed Break on Opcode: None " )
, sAction
, g_iDebugOnOpcode
, g_aOpcodes65C02 [ g_iDebugOnOpcode ] . sMnemonic
) ;
else
// Show what the current break opcode is
wsprintf ( sText , TEXT ( " %s full speed Break on Opcode: %02X %s " )
, sAction
, g_iDebugOnOpcode
, g_aOpcodes65C02 [ g_iDebugOnOpcode ] . sMnemonic
) ;
ConsoleBufferPush ( sText ) ;
return ConsoleUpdate ( ) ;
}
// bool bBP = g_nBreakpoints && CheckBreakpoint(nOffset,nOffset == regs.pc);
//===========================================================================
bool GetBreakpointInfo ( WORD nOffset , bool & bBreakpointActive_ , bool & bBreakpointEnable_ )
{
for ( int iBreakpoint = 0 ; iBreakpoint < MAX_BREAKPOINTS ; iBreakpoint + + )
{
2006-02-26 06:26:56 +00:00
Breakpoint_t * pBP = & g_aBreakpoints [ iBreakpoint ] ;
if ( ( pBP - > nLength )
// && (pBP->bEnabled) // not bSet
& & ( nOffset > = pBP - > nAddress ) & & ( nOffset < ( pBP - > nAddress + pBP - > nLength ) ) ) // [nAddress,nAddress+nLength]
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
bBreakpointActive_ = pBP - > bSet ;
bBreakpointEnable_ = pBP - > bEnabled ;
return true ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
// if (g_aBreakpoints[iBreakpoint].nLength && g_aBreakpoints[iBreakpoint].bEnabled &&
// (g_aBreakpoints[iBreakpoint].nAddress <= targetaddr) &&
// (g_aBreakpoints[iBreakpoint].nAddress + g_aBreakpoints[iBreakpoint].nLength > targetaddr))
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
bBreakpointActive_ = false ;
bBreakpointEnable_ = false ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return false ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
// Returns true if we should continue checking breakpoint details, else false
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
bool _BreakpointValid ( Breakpoint_t * pBP ) //, BreakpointSource_t iSrc )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
bool bStatus = false ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( ! pBP - > bEnabled )
return bStatus ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// if (pBP->eSource != iSrc)
// return bStatus;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( ! pBP - > nLength )
return bStatus ;
return true ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
bool _CheckBreakpointValue ( Breakpoint_t * pBP , int nVal )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
bool bStatus = false ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
int iCmp = pBP - > eOperator ;
switch ( iCmp )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
case BP_OP_LESS_EQUAL :
if ( nVal < = pBP - > nAddress )
bStatus = true ;
2006-02-25 20:50:29 +00:00
break ;
2006-02-26 06:26:56 +00:00
case BP_OP_LESS_THAN :
if ( nVal < pBP - > nAddress )
bStatus = true ;
break ;
case BP_OP_EQUAL : // Range is like C++ STL: [,) (inclusive,not-inclusive)
if ( ( nVal > = pBP - > nAddress ) & & ( nVal < ( pBP - > nAddress + pBP - > nLength ) ) )
bStatus = true ;
break ;
case BP_OP_NOT_EQUAL : // Rnage is: (,] (not-inclusive, inclusive)
if ( ( nVal < pBP - > nAddress ) | | ( nVal > = ( pBP - > nAddress + pBP - > nLength ) ) )
bStatus = true ;
break ;
case BP_OP_GREATER_THAN :
if ( nVal > pBP - > nAddress )
bStatus = true ;
break ;
case BP_OP_GREATER_EQUAL :
if ( nVal > = pBP - > nAddress )
bStatus = true ;
break ;
default :
2006-02-25 20:50:29 +00:00
break ;
}
2006-02-26 06:26:56 +00:00
return bStatus ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
bool CheckBreakpointsIO ( )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
const int NUM_TARGETS = 2 ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
int aTarget [ NUM_TARGETS ] =
{
NO_6502_TARGET ,
NO_6502_TARGET
} ;
int nBytes ;
bool bStatus = false ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
int iTarget ;
int nAddress ;
2006-02-25 20:50:29 +00:00
2006-06-26 16:59:48 +00:00
_6502_GetTargets ( regs . pc , & aTarget [ 0 ] , & aTarget [ 1 ] , & nBytes ) ;
2006-02-26 06:26:56 +00:00
if ( nBytes )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
for ( iTarget = 0 ; iTarget < NUM_TARGETS ; iTarget + + )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
nAddress = aTarget [ iTarget ] ;
if ( nAddress ! = NO_6502_TARGET )
2006-02-25 20:50:29 +00:00
{
2006-06-26 16:59:48 +00:00
for ( int iBreakpoint = 0 ; iBreakpoint < MAX_BREAKPOINTS ; iBreakpoint + + )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
Breakpoint_t * pBP = & g_aBreakpoints [ iBreakpoint ] ;
if ( _BreakpointValid ( pBP ) )
{
if ( pBP - > eSource = = BP_SRC_MEM_1 )
{
if ( _CheckBreakpointValue ( pBP , nAddress ) )
{
return true ;
}
}
}
2006-02-25 20:50:29 +00:00
}
}
}
}
2006-02-26 06:26:56 +00:00
return bStatus ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
// Returns true if a register breakpoint is triggered
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
bool CheckBreakpointsReg ( )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
bool bStatus = false ;
2006-02-25 20:50:29 +00:00
2006-06-26 16:59:48 +00:00
for ( int iBreakpoint = 0 ; iBreakpoint < MAX_BREAKPOINTS ; iBreakpoint + + )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
Breakpoint_t * pBP = & g_aBreakpoints [ iBreakpoint ] ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( ! _BreakpointValid ( pBP ) )
continue ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
switch ( pBP - > eSource )
{
case BP_SRC_REG_PC :
if ( _CheckBreakpointValue ( pBP , regs . pc ) )
return true ;
break ;
case BP_SRC_REG_A :
if ( _CheckBreakpointValue ( pBP , regs . a ) )
return true ;
break ;
case BP_SRC_REG_X :
if ( _CheckBreakpointValue ( pBP , regs . x ) )
return true ;
break ;
case BP_SRC_REG_Y :
if ( _CheckBreakpointValue ( pBP , regs . y ) )
return true ;
break ;
case BP_SRC_REG_P :
if ( _CheckBreakpointValue ( pBP , regs . ps ) )
return true ;
break ;
case BP_SRC_REG_S :
if ( _CheckBreakpointValue ( pBP , regs . sp ) )
return true ;
break ;
default :
break ;
}
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return bStatus ;
2006-02-25 20:50:29 +00:00
}
2006-06-27 22:04:03 +00:00
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-07-01 06:45:50 +00:00
Update_t CmdBreakpoint ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
return CmdBreakpointAddPC ( nArgs ) ;
2006-02-25 20:50:29 +00:00
}
2006-07-01 06:45:50 +00:00
// smart breakpoint
2006-06-27 22:04:03 +00:00
//===========================================================================
2006-07-01 06:45:50 +00:00
Update_t CmdBreakpointAddSmart ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
int nAddress = g_aArgs [ 1 ] . nValue ;
2006-02-26 06:26:56 +00:00
2006-07-01 06:45:50 +00:00
if ( ! nArgs )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
nArgs = 1 ;
g_aArgs [ nArgs ] . nValue = g_nDisasmCurAddress ;
}
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
if ( ( nAddress > = _6502_IO_BEGIN ) & & ( nAddress < = _6502_IO_END ) )
{
return CmdBreakpointAddIO ( nArgs ) ;
}
else
{
CmdBreakpointAddReg ( nArgs ) ;
CmdBreakpointAddMem ( nArgs ) ;
return UPDATE_BREAKPOINTS ;
}
2006-02-26 06:26:56 +00:00
2006-07-01 06:45:50 +00:00
return UPDATE_CONSOLE_DISPLAY ;
2006-02-25 20:50:29 +00:00
}
2006-07-01 06:45:50 +00:00
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-07-01 06:45:50 +00:00
Update_t CmdBreakpointAddReg ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
if ( ! nArgs )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
return Help_Arg_1 ( CMD_BREAKPOINT_ADD_REG ) ;
2006-02-25 20:50:29 +00:00
}
2006-07-01 06:45:50 +00:00
BreakpointSource_t iSrc = BP_SRC_REG_PC ;
BreakpointOperator_t iCmp = BP_OP_EQUAL ;
int nLen = 1 ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
bool bHaveSrc = false ;
bool bHaveCmp = false ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
int iParamSrc ;
int iParamCmp ;
int nFound ;
bool bAdded = false ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
int iArg = 0 ;
while ( iArg + + < nArgs )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
char * sArg = g_aArgs [ iArg ] . sArg ;
bHaveSrc = false ;
bHaveCmp = false ;
nFound = FindParam ( sArg , MATCH_EXACT , iParamSrc , _PARAM_REGS_BEGIN , _PARAM_REGS_END ) ;
if ( nFound )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
switch ( iParamSrc )
{
case PARAM_REG_A : iSrc = BP_SRC_REG_A ; bHaveSrc = true ; break ;
case PARAM_FLAGS : iSrc = BP_SRC_REG_P ; bHaveSrc = true ; break ;
case PARAM_REG_X : iSrc = BP_SRC_REG_X ; bHaveSrc = true ; break ;
case PARAM_REG_Y : iSrc = BP_SRC_REG_Y ; bHaveSrc = true ; break ;
case PARAM_REG_PC : iSrc = BP_SRC_REG_PC ; bHaveSrc = true ; break ;
case PARAM_REG_SP : iSrc = BP_SRC_REG_S ; bHaveSrc = true ; break ;
default :
break ;
}
2006-02-25 20:50:29 +00:00
}
2006-07-01 06:45:50 +00:00
nFound = FindParam ( sArg , MATCH_EXACT , iParamCmp , _PARAM_BREAKPOINT_BEGIN , _PARAM_BREAKPOINT_END ) ;
if ( nFound )
{
switch ( iParamCmp )
{
case PARAM_BP_LESS_EQUAL : iCmp = BP_OP_LESS_EQUAL ; bHaveCmp = true ; break ;
case PARAM_BP_LESS_THAN : iCmp = BP_OP_LESS_THAN ; bHaveCmp = true ; break ;
case PARAM_BP_EQUAL : iCmp = BP_OP_EQUAL ; bHaveCmp = true ; break ;
case PARAM_BP_NOT_EQUAL : iCmp = BP_OP_NOT_EQUAL ; bHaveCmp = true ; break ;
case PARAM_BP_NOT_EQUAL_1 : iCmp = BP_OP_NOT_EQUAL ; bHaveCmp = true ; break ;
case PARAM_BP_GREATER_THAN : iCmp = BP_OP_GREATER_THAN ; bHaveCmp = true ; break ;
case PARAM_BP_GREATER_EQUAL : iCmp = BP_OP_GREATER_EQUAL ; bHaveCmp = true ; break ;
default :
break ;
}
}
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
if ( ( ! bHaveSrc ) & & ( ! bHaveCmp ) )
{
int dArgs = _CmdBreakpointAddCommonArg ( iArg , nArgs , iSrc , iCmp ) ;
if ( ! dArgs )
{
return Help_Arg_1 ( CMD_BREAKPOINT_ADD_REG ) ;
}
iArg + = dArgs ;
}
2006-02-25 20:50:29 +00:00
}
2006-07-01 06:45:50 +00:00
return UPDATE_ALL ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-07-01 06:45:50 +00:00
bool _CmdBreakpointAddReg ( Breakpoint_t * pBP , BreakpointSource_t iSrc , BreakpointOperator_t iCmp , WORD nAddress , int nLen )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
bool bStatus = false ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
if ( pBP )
{
pBP - > eSource = iSrc ;
pBP - > eOperator = iCmp ;
pBP - > nAddress = nAddress ;
pBP - > nLength = nLen ;
pBP - > bSet = true ;
pBP - > bEnabled = true ;
bStatus = true ;
}
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
return bStatus ;
2006-02-25 20:50:29 +00:00
}
2006-07-01 06:45:50 +00:00
// @return Number of args processed
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-07-01 06:45:50 +00:00
int _CmdBreakpointAddCommonArg ( int iArg , int nArg , BreakpointSource_t iSrc , BreakpointOperator_t iCmp )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
int dArg = 0 ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
int iBreakpoint = 0 ;
Breakpoint_t * pBP = & g_aBreakpoints [ iBreakpoint ] ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
while ( ( iBreakpoint < MAX_BREAKPOINTS ) & & g_aBreakpoints [ iBreakpoint ] . bSet ) //g_aBreakpoints[iBreakpoint].nLength)
{
iBreakpoint + + ;
pBP + + ;
}
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
if ( iBreakpoint > = MAX_BREAKPOINTS )
{
ConsoleDisplayError ( TEXT ( " All Breakpoints slots are currently in use. " ) ) ;
return dArg ;
}
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
if ( iArg < = nArg )
{
# if DEBUG_VAL_2
int nLen = g_aArgs [ iArg ] . nVal2 ;
# endif
WORD nAddress = 0 ;
WORD nAddress2 = 0 ;
WORD nEnd = 0 ;
int nLen = 0 ;
2006-02-26 06:26:56 +00:00
2006-07-01 06:45:50 +00:00
dArg = 1 ;
RangeType_t eRange = Range_Get ( nAddress , nAddress2 , iArg ) ;
if ( ( eRange = = RANGE_HAS_END ) | |
( eRange = = RANGE_HAS_LEN ) )
{
Range_CalcEndLen ( eRange , nAddress , nAddress2 , nEnd , nLen ) ;
dArg = 2 ;
}
2006-02-26 06:26:56 +00:00
2006-07-01 06:45:50 +00:00
if ( ! nLen )
{
nLen = 1 ;
}
2006-02-26 06:26:56 +00:00
2006-07-01 06:45:50 +00:00
if ( ! _CmdBreakpointAddReg ( pBP , iSrc , iCmp , nAddress , nLen ) )
{
dArg = 0 ;
}
g_nBreakpoints + + ;
}
2006-02-26 06:26:56 +00:00
2006-07-01 06:45:50 +00:00
return dArg ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-07-01 06:45:50 +00:00
Update_t CmdBreakpointAddPC ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
BreakpointSource_t iSrc = BP_SRC_REG_PC ;
BreakpointOperator_t iCmp = BP_OP_EQUAL ;
2006-02-26 06:26:56 +00:00
2006-07-01 06:45:50 +00:00
if ( ! nArgs )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
nArgs = 1 ;
// g_aArgs[1].nValue = regs.pc;
g_aArgs [ 1 ] . nValue = g_nDisasmCurAddress ;
2006-02-25 20:50:29 +00:00
}
2006-07-01 06:45:50 +00:00
bool bHaveSrc = false ;
bool bHaveCmp = false ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
// int iParamSrc;
int iParamCmp ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
int nFound = 0 ;
bool bAdded = false ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
int iArg = 0 ;
while ( iArg + + < nArgs )
{
char * sArg = g_aArgs [ iArg ] . sArg ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
if ( g_aArgs [ iArg ] . bType & TYPE_OPERATOR )
{
nFound = FindParam ( sArg , MATCH_EXACT , iParamCmp , _PARAM_BREAKPOINT_BEGIN , _PARAM_BREAKPOINT_END ) ;
if ( nFound )
{
switch ( iParamCmp )
{
case PARAM_BP_LESS_EQUAL : iCmp = BP_OP_LESS_EQUAL ; bHaveCmp = true ; break ;
case PARAM_BP_LESS_THAN : iCmp = BP_OP_LESS_THAN ; bHaveCmp = true ; break ;
case PARAM_BP_EQUAL : iCmp = BP_OP_EQUAL ; bHaveCmp = true ; break ;
case PARAM_BP_NOT_EQUAL : iCmp = BP_OP_NOT_EQUAL ; bHaveCmp = true ; break ;
case PARAM_BP_GREATER_THAN : iCmp = BP_OP_GREATER_THAN ; bHaveCmp = true ; break ;
case PARAM_BP_GREATER_EQUAL : iCmp = BP_OP_GREATER_EQUAL ; bHaveCmp = true ; break ;
default :
break ;
}
}
}
else
{
int dArg = _CmdBreakpointAddCommonArg ( iArg , nArgs , iSrc , iCmp ) ;
if ( ! dArg )
{
return Help_Arg_1 ( CMD_BREAKPOINT_ADD_PC ) ;
}
iArg + = dArg ;
}
}
return UPDATE_BREAKPOINTS | UPDATE_CONSOLE_DISPLAY ; // 1;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-07-01 06:45:50 +00:00
Update_t CmdBreakpointAddIO ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
return UPDATE_CONSOLE_DISPLAY ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-07-01 06:45:50 +00:00
Update_t CmdBreakpointAddMem ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
BreakpointSource_t iSrc = BP_SRC_MEM_1 ;
BreakpointOperator_t iCmp = BP_OP_EQUAL ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
bool bAdded = false ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
int iArg = 0 ;
while ( iArg + + < nArgs )
2006-02-26 06:26:56 +00:00
{
2006-07-01 06:45:50 +00:00
char * sArg = g_aArgs [ iArg ] . sArg ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
if ( g_aArgs [ iArg ] . bType & TYPE_OPERATOR )
2006-02-26 06:26:56 +00:00
{
2006-07-01 06:45:50 +00:00
return Help_Arg_1 ( CMD_BREAKPOINT_ADD_MEM ) ;
2006-02-26 06:26:56 +00:00
}
else
{
2006-07-01 06:45:50 +00:00
int dArg = _CmdBreakpointAddCommonArg ( iArg , nArgs , iSrc , iCmp ) ;
if ( ! dArg )
2006-02-26 06:26:56 +00:00
{
2006-07-01 06:45:50 +00:00
return Help_Arg_1 ( CMD_BREAKPOINT_ADD_MEM ) ;
2006-02-26 06:26:56 +00:00
}
2006-07-01 06:45:50 +00:00
iArg + = dArg ;
2006-02-26 06:26:56 +00:00
}
}
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
return UPDATE_BREAKPOINTS | UPDATE_CONSOLE_DISPLAY ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-07-05 21:23:13 +00:00
void _BWZ_Clear ( Breakpoint_t * aBreakWatchZero , int iSlot )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
aBreakWatchZero [ iSlot ] . bSet = false ;
aBreakWatchZero [ iSlot ] . bEnabled = false ;
aBreakWatchZero [ iSlot ] . nLength = 0 ;
}
2006-07-05 21:23:13 +00:00
void _BWZ_RemoveOne ( Breakpoint_t * aBreakWatchZero , const int iSlot , int & nTotal )
2006-07-01 06:45:50 +00:00
{
if ( aBreakWatchZero [ iSlot ] . bSet )
2006-02-26 06:26:56 +00:00
{
2006-07-05 21:23:13 +00:00
_BWZ_Clear ( aBreakWatchZero , iSlot ) ;
2006-07-01 06:45:50 +00:00
nTotal - - ;
2006-02-26 06:26:56 +00:00
}
2006-07-01 06:45:50 +00:00
}
2006-07-05 21:23:13 +00:00
void _BWZ_RemoveAll ( Breakpoint_t * aBreakWatchZero , const int nMax , int & nTotal )
2006-07-01 06:45:50 +00:00
{
2006-07-05 21:23:13 +00:00
for ( int iSlot = 0 ; iSlot < nMax ; iSlot + + )
2006-02-26 21:39:09 +00:00
{
2006-07-05 21:23:13 +00:00
_BWZ_RemoveOne ( aBreakWatchZero , iSlot , nTotal ) ;
2006-07-01 06:45:50 +00:00
}
}
2006-02-26 21:39:09 +00:00
2006-07-01 06:45:50 +00:00
// called by BreakpointsClear, WatchesClear, ZeroPagePointersClear
//===========================================================================
2006-07-05 21:23:13 +00:00
void _BWZ_ClearViaArgs ( int nArgs , Breakpoint_t * aBreakWatchZero , const int nMax , int & nTotal )
2006-07-01 06:45:50 +00:00
{
int iSlot = 0 ;
// Clear specified breakpoints
while ( nArgs )
{
iSlot = g_aArgs [ nArgs ] . nValue ;
if ( ! _tcscmp ( g_aArgs [ nArgs ] . sArg , g_aParameters [ PARAM_WILDSTAR ] . m_sName ) )
2006-02-26 21:39:09 +00:00
{
2006-07-05 21:23:13 +00:00
_BWZ_RemoveAll ( aBreakWatchZero , nMax , nTotal ) ;
2006-07-01 06:45:50 +00:00
break ;
2006-02-26 21:39:09 +00:00
}
2006-07-01 06:45:50 +00:00
else
2006-07-05 21:23:13 +00:00
if ( ( iSlot > = 0 ) & & ( iSlot < nMax ) )
2006-02-26 21:39:09 +00:00
{
2006-07-05 21:23:13 +00:00
_BWZ_RemoveOne ( aBreakWatchZero , iSlot , nTotal ) ;
2006-02-26 21:39:09 +00:00
}
2006-07-01 06:45:50 +00:00
nArgs - - ;
}
}
// called by BreakpointsEnable, WatchesEnable, ZeroPagePointersEnable
// called by BreakpointsDisable, WatchesDisable, ZeroPagePointersDisable
2006-07-05 21:23:13 +00:00
void _BWZ_EnableDisableViaArgs ( int nArgs , Breakpoint_t * aBreakWatchZero , const int nMax , const bool bEnabled )
2006-07-01 06:45:50 +00:00
{
int iSlot = 0 ;
// Enable each breakpoint in the list
while ( nArgs )
{
iSlot = g_aArgs [ nArgs ] . nValue ;
if ( ! _tcscmp ( g_aArgs [ nArgs ] . sArg , g_aParameters [ PARAM_WILDSTAR ] . m_sName ) )
2006-02-26 21:39:09 +00:00
{
2006-07-05 21:23:13 +00:00
for ( ; iSlot < nMax ; iSlot + + )
2006-07-01 06:45:50 +00:00
{
aBreakWatchZero [ iSlot ] . bEnabled = bEnabled ;
}
2006-02-26 21:39:09 +00:00
}
2006-07-01 06:45:50 +00:00
else
2006-07-05 21:23:13 +00:00
if ( ( iSlot > = 0 ) & & ( iSlot < nMax ) )
2006-02-26 21:39:09 +00:00
{
2006-07-05 21:23:13 +00:00
aBreakWatchZero [ iSlot ] . bEnabled = bEnabled ;
2006-02-26 21:39:09 +00:00
}
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
nArgs - - ;
}
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-07-01 06:45:50 +00:00
Update_t CmdBreakpointClear ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
if ( ! g_nBreakpoints )
return ConsoleDisplayError ( TEXT ( " There are no breakpoints defined. " ) ) ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
if ( ! nArgs )
2006-02-25 20:50:29 +00:00
{
2006-07-05 21:23:13 +00:00
_BWZ_RemoveAll ( g_aBreakpoints , MAX_BREAKPOINTS , g_nBreakpoints ) ;
2006-02-26 06:26:56 +00:00
}
else
{
2006-07-05 21:23:13 +00:00
_BWZ_ClearViaArgs ( nArgs , g_aBreakpoints , MAX_BREAKPOINTS , g_nBreakpoints ) ;
2006-02-25 20:50:29 +00:00
}
2006-07-01 06:45:50 +00:00
return UPDATE_DISASM | UPDATE_BREAKPOINTS | UPDATE_CONSOLE_DISPLAY ;
}
2006-02-26 06:26:56 +00:00
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-07-01 06:45:50 +00:00
Update_t CmdBreakpointDisable ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
if ( ! g_nBreakpoints )
return ConsoleDisplayError ( TEXT ( " There are no (PC) Breakpoints defined . " )) ;
2006-02-26 06:26:56 +00:00
if ( ! nArgs )
2006-07-01 06:45:50 +00:00
return Help_Arg_1 ( CMD_BREAKPOINT_DISABLE ) ;
2006-02-25 20:50:29 +00:00
2006-07-05 21:23:13 +00:00
_BWZ_EnableDisableViaArgs ( nArgs , g_aBreakpoints , MAX_BREAKPOINTS , false ) ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
return UPDATE_BREAKPOINTS ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-07-01 06:45:50 +00:00
Update_t CmdBreakpointEdit ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
return ( UPDATE_DISASM | UPDATE_BREAKPOINTS ) ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-07-01 06:45:50 +00:00
Update_t CmdBreakpointEnable ( int nArgs ) {
2006-02-26 06:26:56 +00:00
2006-07-01 06:45:50 +00:00
if ( ! g_nBreakpoints )
return ConsoleDisplayError ( TEXT ( " There are no (PC) Breakpoints defined . " )) ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
if ( ! nArgs )
return Help_Arg_1 ( CMD_BREAKPOINT_ENABLE ) ;
2006-02-25 20:50:29 +00:00
2006-07-05 21:23:13 +00:00
_BWZ_EnableDisableViaArgs ( nArgs , g_aBreakpoints , MAX_BREAKPOINTS , true ) ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
return UPDATE_BREAKPOINTS ;
}
2006-06-27 02:33:40 +00:00
2006-07-05 21:23:13 +00:00
void _BWZ_List ( const Breakpoint_t * aBreakWatchZero , const int iBWZ ) //, bool bZeroBased )
2006-07-01 06:45:50 +00:00
{
2006-07-09 04:53:08 +00:00
static char sText [ CONSOLE_WIDTH ] ;
static const char sFlags [ ] = " -* " ;
static char sName [ MAX_SYMBOLS_LEN + 1 ] ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
WORD nAddress = aBreakWatchZero [ iBWZ ] . nAddress ;
LPCTSTR pSymbol = GetSymbol ( nAddress , 2 ) ;
if ( ! pSymbol )
{
sName [ 0 ] = 0 ;
pSymbol = sName ;
2006-02-25 20:50:29 +00:00
}
2006-07-09 04:53:08 +00:00
sprintf ( sText , " #%d %c %04X %s " ,
2006-07-05 21:23:13 +00:00
// (bZeroBased ? iBWZ + 1 : iBWZ),
iBWZ ,
2006-07-01 06:45:50 +00:00
sFlags [ ( int ) aBreakWatchZero [ iBWZ ] . bEnabled ] ,
aBreakWatchZero [ iBWZ ] . nAddress ,
pSymbol
) ;
ConsoleBufferPush ( sText ) ;
2006-02-25 20:50:29 +00:00
}
2006-07-05 21:23:13 +00:00
void _BWZ_ListAll ( const Breakpoint_t * aBreakWatchZero , const int nMax )
{
int iBWZ = 0 ;
while ( iBWZ < MAX_BOOKMARKS )
{
if ( aBreakWatchZero [ iBWZ ] . bSet )
{
_BWZ_List ( aBreakWatchZero , iBWZ ) ;
}
iBWZ + + ;
}
}
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-07-01 06:45:50 +00:00
Update_t CmdBreakpointList ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
// ConsoleBufferPush( );
// vector<int> vBreakpoints;
// int iBreakpoint = MAX_BREAKPOINTS;
// while (iBreakpoint--)
// {
// if (g_aBreakpoints[iBreakpoint].enabled)
// {
// vBreakpoints.push_back( g_aBreakpoints[iBreakpoint].address );
// }
// }
// sort( vBreakpoints.begin(), vBreakpoints.end() );
// iBreakpoint = vBreakPoints.size();
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
if ( ! g_nBreakpoints )
2006-02-26 06:26:56 +00:00
{
2006-07-01 06:45:50 +00:00
TCHAR sText [ CONSOLE_WIDTH ] ;
wsprintf ( sText , TEXT ( " There are no current breakpoints. (Max: %d) " ) , MAX_BREAKPOINTS ) ;
ConsoleBufferPush ( sText ) ;
2006-02-26 06:26:56 +00:00
}
2006-07-01 06:45:50 +00:00
else
{
2006-07-05 21:23:13 +00:00
_BWZ_ListAll ( g_aBreakpoints , MAX_BREAKPOINTS ) ;
2006-02-26 06:26:56 +00:00
}
2006-07-01 06:45:50 +00:00
return ConsoleUpdate ( ) ;
2006-02-26 06:26:56 +00:00
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
2006-07-01 06:45:50 +00:00
Update_t CmdBreakpointLoad ( int nArgs )
2006-02-26 06:26:56 +00:00
{
2006-07-01 06:45:50 +00:00
return UPDATE_ALL ;
2006-02-26 06:26:56 +00:00
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
2006-07-01 06:45:50 +00:00
Update_t CmdBreakpointSave ( int nArgs )
2006-02-26 06:26:56 +00:00
{
2006-07-01 06:45:50 +00:00
TCHAR sText [ CONSOLE_WIDTH ] ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
g_ConfigState . Reset ( ) ;
2006-02-26 06:26:56 +00:00
2006-07-01 06:45:50 +00:00
ConfigSave_PrepareHeader ( PARAM_CAT_BREAKPOINTS , CMD_BREAKPOINT_CLEAR ) ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
int iBreakpoint = 0 ;
while ( iBreakpoint < MAX_BREAKPOINTS )
{
if ( g_aBreakpoints [ iBreakpoint ] . bSet )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
sprintf ( sText , " %s %x %04X,%04X \n "
, g_aCommands [ CMD_BREAKPOINT_ADD_REG ] . m_sName
, iBreakpoint
, g_aBreakpoints [ iBreakpoint ] . nAddress
, g_aBreakpoints [ iBreakpoint ] . nLength
) ;
g_ConfigState . PushLine ( sText ) ;
2006-02-25 20:50:29 +00:00
}
2006-07-01 06:45:50 +00:00
if ( ! g_aBreakpoints [ iBreakpoint ] . bEnabled )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
sprintf ( sText , " %s %x \n "
, g_aCommands [ CMD_BREAKPOINT_DISABLE ] . m_sName
, iBreakpoint
) ;
g_ConfigState . PushLine ( sText ) ;
2006-02-25 20:50:29 +00:00
}
2006-07-01 06:45:50 +00:00
iBreakpoint + + ;
2006-02-26 06:26:56 +00:00
}
2006-07-01 06:45:50 +00:00
if ( nArgs )
{
if ( ! ( g_aArgs [ 1 ] . bType & TYPE_QUOTED_2 ) )
return Help_Arg_1 ( CMD_BREAKPOINT_SAVE ) ;
2006-02-26 06:26:56 +00:00
2006-07-01 06:45:50 +00:00
if ( ConfigSave_BufferToDisk ( g_aArgs [ 1 ] . sArg , CONFIG_SAVE_FILE_CREATE ) )
{
ConsoleBufferPush ( TEXT ( " Saved. " ) ) ;
return ConsoleUpdate ( ) ;
}
}
2006-02-26 06:26:56 +00:00
2006-07-01 06:45:50 +00:00
return UPDATE_CONSOLE_DISPLAY ;
2006-02-26 06:26:56 +00:00
}
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
// CPU ____________________________________________________________________________________________
// CPU Step, Trace ________________________________________________________________________________
//===========================================================================
Update_t CmdGo ( int nArgs )
2006-02-26 21:39:09 +00:00
{
2006-07-01 06:45:50 +00:00
// G StopAddress [SkipAddress,Length]
// Example:
// G C600 FA00,FFFF
// TODO: G addr1,len addr3,len
// TODO: G addr1:addr2 addr3:addr4
g_nDebugSteps = - 1 ;
g_nDebugStepCycles = 0 ;
g_nDebugStepStart = regs . pc ;
g_nDebugStepUntil = nArgs ? g_aArgs [ 1 ] . nValue : - 1 ;
g_nDebugSkipStart = - 1 ;
g_nDebugSkipLen = - 1 ;
if ( nArgs > 4 )
return Help_Arg_1 ( CMD_GO ) ;
// G StopAddress [SkipAddress,Len]
// Old 1 2 2
// G addr addr [, len]
// New 1 2 3 4
if ( nArgs > 1 )
2006-02-26 21:39:09 +00:00
{
2006-07-01 06:45:50 +00:00
int iArg = 2 ;
g_nDebugSkipStart = g_aArgs [ iArg ] . nValue ;
# if DEBUG_VAL_2
WORD nAddress = g_aArgs [ iArg ] . nVal2 ;
# endif
int nLen = 0 ;
int nEnd = 0 ;
if ( nArgs > 2 )
{
if ( g_aArgs [ iArg + 1 ] . eToken = = TOKEN_COMMA )
{
if ( nArgs > 3 )
{
nLen = g_aArgs [ iArg + 2 ] . nValue ;
nEnd = g_nDebugSkipStart + nLen ;
if ( nEnd > _6502_MEM_END )
nEnd = _6502_MEM_END + 1 ;
}
else
{
return Help_Arg_1 ( CMD_GO ) ;
}
}
else
if ( g_aArgs [ iArg + 1 ] . eToken = = TOKEN_COLON )
{
nEnd = g_aArgs [ iArg + 2 ] . nValue + 1 ;
}
else
return Help_Arg_1 ( CMD_GO ) ;
}
else
return Help_Arg_1 ( CMD_GO ) ;
nLen = nEnd - g_nDebugSkipStart ;
if ( nLen < 0 )
nLen = - nLen ;
g_nDebugSkipLen = nLen ;
g_nDebugSkipLen & = _6502_MEM_END ;
# if _DEBUG
TCHAR sText [ CONSOLE_WIDTH ] ;
wsprintf ( sText , TEXT ( " Start: %04X,%04X End: %04X Len: %04X " ) ,
g_nDebugSkipStart , g_nDebugSkipLen , nEnd , nLen ) ;
ConsoleBufferPush ( sText ) ;
ConsoleBufferToDisplay ( ) ;
# endif
2006-02-26 21:39:09 +00:00
}
2006-07-01 06:45:50 +00:00
// WORD nAddressSymbol = 0;
// bool bFoundSymbol = FindAddressFromSymbol( g_aArgs[1].sArg, & nAddressSymbol );
// if (bFoundSymbol)
// g_nDebugStepUntil = nAddressSymbol;
// if (!g_nDebugStepUntil)
// g_nDebugStepUntil = GetAddress(g_aArgs[1].sArg);
g_nAppMode = MODE_STEPPING ;
FrameRefreshStatus ( DRAW_TITLE ) ;
return UPDATE_CONSOLE_DISPLAY ; // TODO: Verify // 0;
2006-02-26 21:39:09 +00:00
}
2006-07-01 06:45:50 +00:00
//===========================================================================
Update_t CmdStepOver ( int nArgs )
2006-02-26 21:39:09 +00:00
{
2006-07-01 06:45:50 +00:00
// assert( g_nDisasmCurAddress == regs.pc );
2006-02-26 21:39:09 +00:00
2006-07-01 06:45:50 +00:00
// g_nDebugSteps = nArgs ? g_aArgs[1].nValue : 1;
WORD nDebugSteps = nArgs ? g_aArgs [ 1 ] . nValue : 1 ;
while ( nDebugSteps - - > 0 )
2006-02-26 21:39:09 +00:00
{
2006-07-01 06:45:50 +00:00
int nOpcode = * ( mem + regs . pc ) ; // g_nDisasmCurAddress
// int eMode = g_aOpcodes[ nOpcode ].addrmode;
// int nByte = g_aOpmodes[eMode]._nBytes;
// if ((eMode == ADDR_ABS) &&
CmdTrace ( 0 ) ;
if ( nOpcode = = OPCODE_JSR )
{
CmdStepOut ( 0 ) ;
g_nDebugSteps = 0xFFFF ;
while ( g_nDebugSteps ! = 0 )
DebugContinueStepping ( ) ;
}
2006-02-26 21:39:09 +00:00
}
2006-07-01 06:45:50 +00:00
return UPDATE_ALL ;
2006-02-26 21:39:09 +00:00
}
2006-02-26 06:26:56 +00:00
//===========================================================================
2006-07-01 06:45:50 +00:00
Update_t CmdStepOut ( int nArgs )
2006-02-26 06:26:56 +00:00
{
2006-07-01 06:45:50 +00:00
// TODO: "RET" should probably pop the Call stack
// Also see: CmdCursorJumpRetAddr
WORD nAddress ;
if ( _6502_GetStackReturnAddress ( nAddress ) )
2006-02-26 06:26:56 +00:00
{
2006-07-01 06:45:50 +00:00
nArgs = _Arg_1 ( nAddress ) ;
g_aArgs [ 1 ] . sArg [ 0 ] = 0 ;
CmdGo ( 1 ) ;
}
2006-02-26 21:39:09 +00:00
2006-07-01 06:45:50 +00:00
return UPDATE_ALL ;
}
2006-02-26 21:39:09 +00:00
2006-07-01 06:45:50 +00:00
//===========================================================================
Update_t CmdTrace ( int nArgs )
{
g_nDebugSteps = nArgs ? g_aArgs [ 1 ] . nValue : 1 ;
g_nDebugStepCycles = 0 ;
g_nDebugStepStart = regs . pc ;
g_nDebugStepUntil = - 1 ;
g_nAppMode = MODE_STEPPING ;
FrameRefreshStatus ( DRAW_TITLE ) ;
DebugContinueStepping ( ) ;
return UPDATE_ALL ; // TODO: Verify // 0
2006-02-25 20:50:29 +00:00
}
2006-07-01 06:45:50 +00:00
//===========================================================================
2006-08-16 18:58:56 +00:00
Update_t CmdTraceFile ( int nArgs )
{
char sText [ CONSOLE_WIDTH ] = " " ;
2006-07-01 06:45:50 +00:00
2006-08-16 18:58:56 +00:00
if ( g_hTraceFile )
{
fclose ( g_hTraceFile ) ;
g_hTraceFile = NULL ;
2006-07-01 06:45:50 +00:00
2006-08-16 18:58:56 +00:00
sprintf ( sText , " Trace stopped. " ) ;
}
2006-07-01 06:45:50 +00:00
else
2006-08-16 18:58:56 +00:00
{
char sFileName [ MAX_PATH ] ;
if ( nArgs )
strcpy ( sFileName , g_aArgs [ 1 ] . sArg ) ;
else
strcpy ( sFileName , g_sFileNameTrace ) ;
char sFilePath [ MAX_PATH ] ;
strcpy ( sFilePath , g_sCurrentDir ) ; // g_sProgramDir
strcat ( sFilePath , sFileName ) ;
g_hTraceFile = fopen ( sFilePath , " wt " ) ;
if ( g_hTraceFile )
{
sprintf ( sText , " Trace started: %s " , sFileName ) ;
g_bTraceHeader = true ;
}
else
{
sprintf ( sText , " Trace ERROR: %s " , sFileName ) ;
}
}
ConsoleBufferPush ( sText ) ;
ConsoleBufferToDisplay ( ) ;
2006-07-01 06:45:50 +00:00
return UPDATE_ALL ; // TODO: Verify // 0
}
//===========================================================================
Update_t CmdTraceLine ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
g_nDebugSteps = nArgs ? g_aArgs [ 1 ] . nValue : 1 ;
g_nDebugStepCycles = 1 ;
g_nDebugStepStart = regs . pc ;
g_nDebugStepUntil = - 1 ;
2006-02-26 21:39:09 +00:00
2006-07-01 06:45:50 +00:00
g_nAppMode = MODE_STEPPING ;
FrameRefreshStatus ( DRAW_TITLE ) ;
DebugContinueStepping ( ) ;
return UPDATE_ALL ; // TODO: Verify // 0
}
//===========================================================================
Update_t _CmdAssemble ( WORD nAddress , int iArg , int nArgs )
{
bool bHaveLabel = false ;
// if AlphaNumeric
ArgToken_e iTokenSrc = NO_TOKEN ;
ParserFindToken ( g_pConsoleInput , g_aTokens , NUM_TOKENS , & iTokenSrc ) ;
if ( iTokenSrc = = NO_TOKEN ) // is TOKEN_ALPHANUMERIC
if ( g_pConsoleInput [ 0 ] ! = CHAR_SPACE )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
bHaveLabel = true ;
2006-02-26 21:39:09 +00:00
2006-07-01 06:45:50 +00:00
// Symbol
char * pSymbolName = g_aArgs [ iArg ] . sArg ; // pArg->sArg;
SymbolUpdate ( SYMBOLS_SRC , pSymbolName , nAddress , false , true ) ; // bool bRemoveSymbol, bool bUpdateSymbol )
iArg + + ;
}
bool bStatus = Assemble ( iArg , nArgs , nAddress ) ;
if ( bStatus )
return UPDATE_ALL ;
return UPDATE_CONSOLE_DISPLAY ; // UPDATE_NOTHING;
}
//===========================================================================
Update_t CmdAssemble ( int nArgs )
{
if ( ! g_bAssemblerOpcodesHashed )
{
AssemblerStartup ( ) ;
g_bAssemblerOpcodesHashed = true ;
}
// 0 : A
// 1 : A address
// 2+: A address mnemonic...
if ( ! nArgs )
{
// return Help_Arg_1( CMD_ASSEMBLE );
// Start assembler, continue with last assembled address
AssemblerOn ( ) ;
return UPDATE_CONSOLE_DISPLAY ;
}
g_nAssemblerAddress = g_aArgs [ 1 ] . nValue ;
if ( nArgs = = 1 )
{
int iArg = 1 ;
// undocumented ASM *
if ( ( ! _tcscmp ( g_aArgs [ iArg ] . sArg , g_aParameters [ PARAM_WILDSTAR ] . m_sName ) ) | |
( ! _tcscmp ( g_aArgs [ iArg ] . sArg , g_aParameters [ PARAM_MEM_SEARCH_WILD ] . m_sName ) ) )
2006-02-26 06:26:56 +00:00
{
2006-07-01 06:45:50 +00:00
_CmdAssembleHashDump ( ) ;
2006-02-26 06:26:56 +00:00
}
2006-02-26 21:39:09 +00:00
2006-07-01 06:45:50 +00:00
AssemblerOn ( ) ;
return UPDATE_CONSOLE_DISPLAY ;
// return Help_Arg_1( CMD_ASSEMBLE );
}
if ( nArgs > 1 )
{
return _CmdAssemble ( g_nAssemblerAddress , 2 , nArgs ) ; // disasm, memory, watches, zeropage
2006-02-25 20:50:29 +00:00
}
2006-07-01 06:45:50 +00:00
// return Help_Arg_1( CMD_ASSEMBLE );
// g_nAssemblerAddress; // g_aArgs[1].nValue;
// return ConsoleUpdate();
return UPDATE_CONSOLE_DISPLAY ;
2006-02-26 06:26:56 +00:00
}
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
// Unassemble
2006-02-26 06:26:56 +00:00
//===========================================================================
2006-07-01 06:45:50 +00:00
Update_t CmdUnassemble ( int nArgs )
2006-02-26 06:26:56 +00:00
{
2006-07-01 06:45:50 +00:00
if ( ! nArgs )
return Help_Arg_1 ( CMD_UNASSEMBLE ) ;
WORD nAddress = g_aArgs [ 1 ] . nValue ;
g_nDisasmTopAddress = nAddress ;
DisasmCalcCurFromTopAddress ( ) ;
DisasmCalcBotFromTopAddress ( ) ;
return UPDATE_DISASM ;
}
//===========================================================================
Update_t CmdKey ( int nArgs )
{
KeybQueueKeypress (
nArgs ? g_aArgs [ 1 ] . nValue ? g_aArgs [ 1 ] . nValue : g_aArgs [ 1 ] . sArg [ 0 ] : TEXT ( ' ' ) , 1 ) ; // FIXME!!!
return UPDATE_CONSOLE_DISPLAY ;
}
//===========================================================================
Update_t CmdIn ( int nArgs )
{
if ( ! nArgs )
return Help_Arg_1 ( CMD_IN ) ;
WORD nAddress = g_aArgs [ 1 ] . nValue ;
// ioread[ g_aArgs[1].nValue & 0xFF ](regs.pc,g_aArgs[1].nValue & 0xFF,0,0,0);
ioread [ nAddress & 0xFF ] ( regs . pc , nAddress & 0xFF , 0 , 0 , 0 ) ; // g_aArgs[1].nValue
return UPDATE_CONSOLE_DISPLAY ; // TODO: Verify // 1
}
//===========================================================================
Update_t CmdJSR ( int nArgs )
{
if ( ! nArgs )
return Help_Arg_1 ( CMD_JSR ) ;
WORD nAddress = g_aArgs [ 1 ] . nValue & _6502_MEM_END ;
// Mark Stack Page as dirty
* ( memdirty + ( regs . sp > > 8 ) ) = 1 ;
// Push PC onto stack
* ( mem + regs . sp ) = ( ( regs . pc > > 8 ) & 0xFF ) ;
regs . sp - - ;
* ( mem + regs . sp ) = ( ( regs . pc > > 0 ) - 1 ) & 0xFF ;
regs . sp - - ;
// Jump to new address
regs . pc = nAddress ;
return UPDATE_ALL ;
}
//===========================================================================
Update_t CmdNOP ( int nArgs )
{
int iOpcode ;
int iOpmode ;
int nOpbytes ;
2006-08-16 18:58:56 +00:00
_6502_GetOpcodeOpmodeOpbyte ( iOpcode , iOpmode , nOpbytes ) ;
2006-07-01 06:45:50 +00:00
while ( nOpbytes - - )
{
* ( mem + regs . pc + nOpbytes ) = 0xEA ;
}
return UPDATE_ALL ;
}
//===========================================================================
Update_t CmdOut ( int nArgs )
{
// if ((!nArgs) ||
// ((g_aArgs[1].sArg[0] != TEXT('0')) && (!g_aArgs[1].nValue) && (!GetAddress(g_aArgs[1].sArg))))
// return DisplayHelp(CmdInput);
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( ! nArgs )
2006-07-01 06:45:50 +00:00
Help_Arg_1 ( CMD_OUT ) ;
WORD nAddress = g_aArgs [ 1 ] . nValue ;
// iowrite[ g_aArgs[1].nValue & 0xFF](regs.pc,g_aArgs[1].nValue & 0xFF,1,g_aArgs[2].nValue & 0xFF,0);
iowrite [ nAddress & 0xFF ] ( regs . pc , nAddress & 0xFF , 1 , g_aArgs [ 2 ] . nValue & 0xFF , 0 ) ;
return UPDATE_CONSOLE_DISPLAY ; // TODO: Verify // 1
}
// Color __________________________________________________________________________________________
void _ColorPrint ( int iColor , COLORREF nColor )
{
int R = ( nColor > > 0 ) & 0xFF ;
int G = ( nColor > > 8 ) & 0xFF ;
int B = ( nColor > > 16 ) & 0xFF ;
TCHAR sText [ CONSOLE_WIDTH ] ;
wsprintf ( sText , " Color %01X: %02X %02X %02X " , iColor , R , G , B ) ; // TODO: print name of colors!
ConsoleBufferPush ( sText ) ;
}
void _CmdColorGet ( const int iScheme , const int iColor )
{
if ( iColor < NUM_COLORS )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
// COLORREF nColor = g_aColors[ iScheme ][ iColor ];
DebugColors_e eColor = static_cast < DebugColors_e > ( iColor ) ;
COLORREF nColor = DebuggerGetColor ( eColor ) ;
_ColorPrint ( iColor , nColor ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 21:39:09 +00:00
else
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
TCHAR sText [ CONSOLE_WIDTH ] ;
wsprintf ( sText , " Color: %d \n Out of range! " , iColor ) ;
MessageBox ( g_hFrameWindow , sText , TEXT ( " ERROR " ) , MB_OK ) ;
2006-02-25 20:50:29 +00:00
}
}
//===========================================================================
2006-07-01 06:45:50 +00:00
inline COLORREF DebuggerGetColor ( int iColor )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
COLORREF nColor = RGB ( 0 , 255 , 255 ) ; // 0xFFFF00; // Hot Pink! -- so we notice errors. Not that there is anything wrong with pink...
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
if ( ( g_iColorScheme < NUM_COLOR_SCHEMES ) & & ( iColor < NUM_COLORS ) )
{
nColor = g_aColors [ g_iColorScheme ] [ iColor ] ;
}
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
return nColor ;
2006-02-25 20:50:29 +00:00
}
2006-07-01 06:45:50 +00:00
bool DebuggerSetColor ( const int iScheme , const int iColor , const COLORREF nColor )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
bool bStatus = false ;
if ( ( g_iColorScheme < NUM_COLOR_SCHEMES ) & & ( iColor < NUM_COLORS ) )
{
g_aColors [ iScheme ] [ iColor ] = nColor ;
bStatus = true ;
}
2006-07-09 04:53:08 +00:00
// Propogate to console since it has its own copy of colors
if ( iColor = = FG_CONSOLE_OUTPUT )
{
COLORREF nConsole = DebuggerGetColor ( FG_CONSOLE_OUTPUT ) ;
g_anConsoleColor [ CONSOLE_COLOR_x ] = nConsole ;
}
2006-07-01 06:45:50 +00:00
return bStatus ;
2006-02-26 06:26:56 +00:00
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
2006-07-01 06:45:50 +00:00
Update_t CmdConfigColorMono ( int nArgs )
{
int iScheme ;
if ( g_iCommand = = CMD_CONFIG_COLOR )
iScheme = SCHEME_COLOR ;
if ( g_iCommand = = CMD_CONFIG_MONOCHROME )
iScheme = SCHEME_MONO ;
if ( g_iCommand = = CMD_CONFIG_BW )
iScheme = SCHEME_BW ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
if ( ( iScheme < 0 ) | | ( iScheme > NUM_COLOR_SCHEMES ) ) // sanity check
iScheme = SCHEME_COLOR ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( ! nArgs )
2006-07-01 06:45:50 +00:00
{
g_iColorScheme = iScheme ;
UpdateDisplay ( UPDATE_BACKGROUND ) ;
return UPDATE_ALL ;
}
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
// if ((nArgs != 1) && (nArgs != 4))
if ( nArgs > 4 )
return HelpLastCommand ( ) ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
int iColor = g_aArgs [ 1 ] . nValue ;
if ( ( iColor < 0 ) | | iColor > = NUM_COLORS )
return HelpLastCommand ( ) ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
int iParam ;
int nFound = FindParam ( g_aArgs [ 1 ] . sArg , MATCH_EXACT , iParam , _PARAM_GENERAL_BEGIN , _PARAM_GENERAL_END ) ;
2006-02-26 06:26:56 +00:00
2006-07-01 06:45:50 +00:00
if ( nFound )
2006-02-26 06:26:56 +00:00
{
2006-07-01 06:45:50 +00:00
if ( iParam = = PARAM_RESET )
{
_ConfigColorsReset ( ) ;
ConsoleBufferPush ( TEXT ( " Resetting colors. " ) ) ;
}
else
if ( iParam = = PARAM_SAVE )
{
}
else
if ( iParam = = PARAM_LOAD )
{
}
else
return HelpLastCommand ( ) ;
}
else
{
if ( nArgs = = 1 )
{ // Dump Color
_CmdColorGet ( iScheme , iColor ) ;
return ConsoleUpdate ( ) ;
}
else
if ( nArgs = = 4 )
{ // Set Color
int R = g_aArgs [ 2 ] . nValue & 0xFF ;
int G = g_aArgs [ 3 ] . nValue & 0xFF ;
int B = g_aArgs [ 4 ] . nValue & 0xFF ;
COLORREF nColor = RGB ( R , G , B ) ;
DebuggerSetColor ( iScheme , iColor , nColor ) ;
}
else
return HelpLastCommand ( ) ;
2006-02-26 06:26:56 +00:00
}
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
return UPDATE_ALL ;
2006-02-25 20:50:29 +00:00
}
2006-07-01 06:45:50 +00:00
Update_t CmdConfigHColor ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
if ( ( nArgs ! = 1 ) & & ( nArgs ! = 4 ) )
return Help_Arg_1 ( g_iCommand ) ;
2006-02-26 06:26:56 +00:00
2006-07-01 06:45:50 +00:00
int iColor = g_aArgs [ 1 ] . nValue ;
if ( ( iColor < 0 ) | | iColor > = NUM_COLORS )
return Help_Arg_1 ( g_iCommand ) ;
if ( nArgs = = 1 )
{ // Dump Color
// _CmdColorGet( iScheme, iColor );
// TODO/FIXME: must export AW_Video.cpp: static LPBITMAPINFO framebufferinfo;
// COLORREF nColor = g_aColors[ iScheme ][ iColor ];
// _ColorPrint( iColor, nColor );
return ConsoleUpdate ( ) ;
2006-02-26 06:26:56 +00:00
}
else
2006-07-01 06:45:50 +00:00
{ // Set Color
// DebuggerSetColor( iScheme, iColor );
return UPDATE_ALL ;
2006-02-26 06:26:56 +00:00
}
2006-02-25 20:50:29 +00:00
}
2006-07-01 06:45:50 +00:00
// Config _________________________________________________________________________________________
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-07-01 06:45:50 +00:00
Update_t CmdConfigLoad ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
// TODO: CmdConfigRun( gaFileNameConfig )
// TCHAR sFileNameConfig[ MAX_PATH ];
if ( ! nArgs )
{
}
// gDebugConfigName
// DEBUGLOAD file // load debugger setting
2006-02-26 06:26:56 +00:00
return UPDATE_ALL ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-07-01 06:45:50 +00:00
bool ConfigSave_BufferToDisk ( char * pFileName , ConfigSave_t eConfigSave )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
bool bStatus = false ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
char sModeCreate [ ] = " w+t " ;
char sModeAppend [ ] = " a+t " ;
char * pMode = NULL ;
if ( eConfigSave = = CONFIG_SAVE_FILE_CREATE )
pMode = sModeCreate ;
else
if ( eConfigSave = = CONFIG_SAVE_FILE_APPEND )
pMode = sModeAppend ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
char sFileName [ MAX_PATH ] ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
_tcscpy ( sFileName , g_sCurrentDir ) ;
_tcscat ( sFileName , pFileName ) ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
FILE * hFile = fopen ( pFileName , pMode ) ;
2006-02-26 06:26:56 +00:00
2006-07-01 06:45:50 +00:00
if ( hFile )
2006-02-26 06:26:56 +00:00
{
2006-07-01 06:45:50 +00:00
char * pText ;
int nLine = g_ConfigState . GetNumLines ( ) ;
int iLine ;
for ( iLine = 0 ; iLine < nLine ; iLine + + )
2006-02-26 06:26:56 +00:00
{
2006-07-01 06:45:50 +00:00
pText = g_ConfigState . GetLine ( iLine ) ;
if ( pText )
2006-02-26 06:26:56 +00:00
{
2006-07-01 06:45:50 +00:00
fputs ( pText , hFile ) ;
2006-02-26 06:26:56 +00:00
}
}
2006-07-01 06:45:50 +00:00
fclose ( hFile ) ;
bStatus = true ;
}
else
{
2006-02-26 06:26:56 +00:00
}
2006-07-01 06:45:50 +00:00
return bStatus ;
2006-02-26 06:26:56 +00:00
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
2006-07-01 06:45:50 +00:00
void ConfigSave_PrepareHeader ( const Parameters_e eCategory , const Commands_e eCommandClear )
2006-02-26 06:26:56 +00:00
{
2006-07-01 06:45:50 +00:00
char sText [ CONSOLE_WIDTH ] ;
2006-02-26 06:26:56 +00:00
2006-07-01 06:45:50 +00:00
sprintf ( sText , " %s %s = %s \n "
, g_aTokens [ TOKEN_COMMENT_EOL ] . sToken
, g_aParameters [ PARAM_CATEGORY ] . m_sName
, g_aParameters [ eCategory ]
) ;
g_ConfigState . PushLine ( sText ) ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
sprintf ( sText , " %s %s \n "
, g_aCommands [ eCommandClear ] . m_sName
, g_aParameters [ PARAM_WILDSTAR ] . m_sName
) ;
g_ConfigState . PushLine ( sText ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
// Save Debugger Settings
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdConfigSave ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
TCHAR sFilename [ MAX_PATH ] ;
_tcscpy ( sFilename , g_sProgramDir ) ; // g_sCurrentDir
_tcscat ( sFilename , g_sFileNameConfig ) ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
/*
HANDLE hFile = CreateFile ( sfilename ,
2006-02-26 06:26:56 +00:00
GENERIC_WRITE ,
0 ,
( LPSECURITY_ATTRIBUTES ) NULL ,
CREATE_ALWAYS ,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN ,
NULL ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( hFile ! = INVALID_HANDLE_VALUE )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
void * pSrc ;
int nLen ;
DWORD nPut ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// FIXME: Shouldn be saving in Text format, not binary!
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
int nVersion = CURRENT_VERSION ;
pSrc = ( void * ) & nVersion ;
nLen = sizeof ( nVersion ) ;
WriteFile ( hFile , pSrc , nLen , & nPut , NULL ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
pSrc = ( void * ) & gaColorPalette ;
nLen = sizeof ( gaColorPalette ) ;
WriteFile ( hFile , pSrc , nLen , & nPut , NULL ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
pSrc = ( void * ) & g_aColorIndex ;
nLen = sizeof ( g_aColorIndex ) ;
WriteFile ( hFile , pSrc , nLen , & nPut , NULL ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
CloseHandle ( hFile ) ;
2006-02-25 20:50:29 +00:00
}
2006-07-01 06:45:50 +00:00
*/
// Bookmarks
CmdBookmarkSave ( 0 ) ;
// Breakpoints
CmdBreakpointSave ( 0 ) ;
// Watches
CmdWatchSave ( 0 ) ;
// Zeropage pointers
CmdZeroPageSave ( 0 ) ;
// Color Palete
// Color Index
// CmdColorSave( 0 );
// UserSymbol
// History
2006-02-26 06:26:56 +00:00
return UPDATE_CONSOLE_DISPLAY ;
2006-02-25 20:50:29 +00:00
}
2006-07-01 06:45:50 +00:00
// Config - Disasm ________________________________________________________________________________
2006-06-11 23:24:39 +00:00
//===========================================================================
Update_t CmdConfigDisasm ( int nArgs )
{
int iParam = 0 ;
2006-06-13 01:21:45 +00:00
TCHAR sText [ CONSOLE_WIDTH ] ;
bool bDisplayCurrentSettings = false ;
2006-06-27 22:04:03 +00:00
// if (! _tcscmp( g_aArgs[ 1 ].sArg, g_aParameters[ PARAM_WILDSTAR ].m_sName ))
2006-06-13 01:21:45 +00:00
if ( ! nArgs )
{
2006-06-27 22:04:03 +00:00
bDisplayCurrentSettings = true ;
2006-06-13 01:21:45 +00:00
nArgs = PARAM_CONFIG_NUM ;
}
else
{
if ( nArgs > 2 )
return Help_Arg_1 ( CMD_CONFIG_DISASM ) ;
}
2006-06-11 23:24:39 +00:00
for ( int iArg = 1 ; iArg < = nArgs ; iArg + + )
{
2006-06-13 01:21:45 +00:00
if ( bDisplayCurrentSettings )
iParam = _PARAM_CONFIG_BEGIN + iArg - 1 ;
else
2006-06-11 23:24:39 +00:00
if ( FindParam ( g_aArgs [ iArg ] . sArg , MATCH_FUZZY , iParam ) )
{
2006-06-13 01:21:45 +00:00
}
2006-06-11 23:24:39 +00:00
switch ( iParam )
{
case PARAM_CONFIG_BRANCH :
2006-06-13 01:21:45 +00:00
if ( ( nArgs > 1 ) & & ( ! bDisplayCurrentSettings ) ) // set
{
iArg + + ;
2006-06-27 02:33:40 +00:00
g_iConfigDisasmBranchType = g_aArgs [ iArg ] . nValue ;
2006-06-13 01:21:45 +00:00
if ( g_iConfigDisasmBranchType < 0 )
g_iConfigDisasmBranchType = 0 ;
if ( g_iConfigDisasmBranchType > = NUM_DISASM_BRANCH_TYPES )
g_iConfigDisasmBranchType = NUM_DISASM_BRANCH_TYPES - 1 ;
}
else // show current setting
{
wsprintf ( sText , TEXT ( " Branch Type: %d " ) , g_iConfigDisasmBranchType ) ;
ConsoleBufferPush ( sText ) ;
ConsoleBufferToDisplay ( ) ;
}
2006-06-11 23:24:39 +00:00
break ;
case PARAM_CONFIG_COLON :
2006-06-13 01:21:45 +00:00
if ( ( nArgs > 1 ) & & ( ! bDisplayCurrentSettings ) ) // set
{
iArg + + ;
2006-06-27 02:33:40 +00:00
g_bConfigDisasmAddressColon = ( g_aArgs [ iArg ] . nValue ) ? true : false ;
2006-06-13 01:21:45 +00:00
}
else // show current setting
{
int iState = g_bConfigDisasmAddressColon ? PARAM_ON : PARAM_OFF ;
wsprintf ( sText , TEXT ( " Colon: %s " ) , g_aParameters [ iState ] . m_sName ) ;
ConsoleBufferPush ( sText ) ;
ConsoleBufferToDisplay ( ) ;
}
2006-06-11 23:24:39 +00:00
break ;
case PARAM_CONFIG_OPCODE :
2006-06-13 01:21:45 +00:00
if ( ( nArgs > 1 ) & & ( ! bDisplayCurrentSettings ) ) // set
{
iArg + + ;
2006-06-27 02:33:40 +00:00
g_bConfigDisasmOpcodesView = ( g_aArgs [ iArg ] . nValue ) ? true : false ;
2006-06-13 01:21:45 +00:00
}
else
{
2006-06-27 22:04:03 +00:00
int iState = g_bConfigDisasmOpcodesView ? PARAM_ON : PARAM_OFF ;
2006-06-13 01:21:45 +00:00
wsprintf ( sText , TEXT ( " Opcodes: %s " ) , g_aParameters [ iState ] . m_sName ) ;
ConsoleBufferPush ( sText ) ;
ConsoleBufferToDisplay ( ) ;
}
2006-06-11 23:24:39 +00:00
break ;
2006-06-27 22:04:03 +00:00
case PARAM_CONFIG_POINTER :
if ( ( nArgs > 1 ) & & ( ! bDisplayCurrentSettings ) ) // set
{
iArg + + ;
g_bConfigInfoTargetPointer = ( g_aArgs [ iArg ] . nValue ) ? true : false ;
}
else
{
int iState = g_bConfigInfoTargetPointer ? PARAM_ON : PARAM_OFF ;
wsprintf ( sText , TEXT ( " Info Target Pointer: %s " ) , g_aParameters [ iState ] . m_sName ) ;
ConsoleBufferPush ( sText ) ;
ConsoleBufferToDisplay ( ) ;
}
break ;
2006-06-11 23:24:39 +00:00
case PARAM_CONFIG_SPACES :
2006-06-13 01:21:45 +00:00
if ( ( nArgs > 1 ) & & ( ! bDisplayCurrentSettings ) ) // set
{
iArg + + ;
2006-06-27 02:33:40 +00:00
g_bConfigDisasmOpcodeSpaces = ( g_aArgs [ iArg ] . nValue ) ? true : false ;
2006-06-13 01:21:45 +00:00
}
else
{
int iState = g_bConfigDisasmOpcodeSpaces ? PARAM_ON : PARAM_OFF ;
wsprintf ( sText , TEXT ( " Opcode spaces: %s " ) , g_aParameters [ iState ] . m_sName ) ;
ConsoleBufferPush ( sText ) ;
ConsoleBufferToDisplay ( ) ;
}
2006-06-11 23:24:39 +00:00
break ;
2006-06-13 01:21:45 +00:00
case PARAM_CONFIG_TARGET :
if ( ( nArgs > 1 ) & & ( ! bDisplayCurrentSettings ) ) // set
{
iArg + + ;
2006-06-27 02:33:40 +00:00
g_iConfigDisasmTargets = g_aArgs [ iArg ] . nValue ;
2006-06-13 01:21:45 +00:00
if ( g_iConfigDisasmTargets < 0 )
g_iConfigDisasmTargets = 0 ;
if ( g_iConfigDisasmTargets > = NUM_DISASM_TARGET_TYPES )
g_iConfigDisasmTargets = NUM_DISASM_TARGET_TYPES - 1 ;
}
else // show current setting
{
wsprintf ( sText , TEXT ( " Target: %d " ) , g_iConfigDisasmTargets ) ;
ConsoleBufferPush ( sText ) ;
ConsoleBufferToDisplay ( ) ;
}
break ;
2006-06-11 23:24:39 +00:00
default :
return Help_Arg_1 ( CMD_CONFIG_DISASM ) ; // CMD_CONFIG_DISASM_OPCODE );
}
2006-06-13 01:21:45 +00:00
// }
// else
// return Help_Arg_1( CMD_CONFIG_DISASM );
2006-06-11 23:24:39 +00:00
}
return UPDATE_CONSOLE_DISPLAY | UPDATE_DISASM ;
}
2006-07-01 06:45:50 +00:00
// Config - Font __________________________________________________________________________________
2006-02-26 06:26:56 +00:00
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdConfigFontLoad ( int nArgs )
2006-02-25 20:50:29 +00:00
{
return UPDATE_CONSOLE_DISPLAY ;
}
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdConfigFontSave ( int nArgs )
2006-02-25 20:50:29 +00:00
{
return UPDATE_CONSOLE_DISPLAY ;
}
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdConfigFontMode ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( nArgs ! = 2 )
return Help_Arg_1 ( CMD_CONFIG_FONT ) ;
2006-02-25 20:50:29 +00:00
2006-06-27 02:33:40 +00:00
int nMode = g_aArgs [ 2 ] . nValue ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( ( nMode < 0 ) | | ( nMode > = NUM_FONT_SPACING ) )
return Help_Arg_1 ( CMD_CONFIG_FONT ) ;
g_iFontSpacing = nMode ;
_UpdateWindowFontHeights ( g_aFontConfig [ FONT_DISASM_DEFAULT ] . _nFontHeight ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return UPDATE_CONSOLE_DISPLAY | UPDATE_DISASM ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
Update_t CmdConfigFont ( int nArgs )
{
int iArg ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( ! nArgs )
return CmdConfigGetFont ( nArgs ) ;
else
2006-07-01 06:45:50 +00:00
if ( nArgs < = 2 ) // nArgs
2006-02-26 06:26:56 +00:00
{
iArg = 1 ;
2006-02-25 20:50:29 +00:00
2006-06-27 22:04:03 +00:00
// FONT * is undocumented, like VERSION *
if ( ( ! _tcscmp ( g_aArgs [ iArg ] . sArg , g_aParameters [ PARAM_WILDSTAR ] . m_sName ) ) | |
( ! _tcscmp ( g_aArgs [ iArg ] . sArg , g_aParameters [ PARAM_MEM_SEARCH_WILD ] . m_sName ) ) )
2006-02-25 20:50:29 +00:00
{
2006-06-27 22:04:03 +00:00
TCHAR sText [ CONSOLE_WIDTH ] ;
wsprintf ( sText , " Lines: %d Font Px: %d Line Px: %d "
2006-07-05 21:23:13 +00:00
, g_nDisasmDisplayLines
2006-06-27 22:04:03 +00:00
, g_aFontConfig [ FONT_DISASM_DEFAULT ] . _nFontHeight
, g_aFontConfig [ FONT_DISASM_DEFAULT ] . _nLineHeight ) ;
ConsoleBufferPush ( sText ) ;
ConsoleBufferToDisplay ( ) ;
return UPDATE_CONSOLE_DISPLAY ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
int iFound ;
int nFound ;
nFound = FindParam ( g_aArgs [ iArg ] . sArg , MATCH_EXACT , iFound , _PARAM_GENERAL_BEGIN , _PARAM_GENERAL_END ) ;
2006-02-25 20:50:29 +00:00
if ( nFound )
{
2006-02-26 06:26:56 +00:00
switch ( iFound )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
case PARAM_LOAD :
return CmdConfigFontLoad ( nArgs ) ;
break ;
case PARAM_SAVE :
return CmdConfigFontSave ( nArgs ) ;
2006-02-25 20:50:29 +00:00
break ;
2006-02-26 06:26:56 +00:00
// TODO: FONT SIZE #
// TODO: AA {ON|OFF}
default :
break ;
2006-02-25 20:50:29 +00:00
}
}
2006-02-26 06:26:56 +00:00
nFound = FindParam ( g_aArgs [ iArg ] . sArg , MATCH_EXACT , iFound , _PARAM_FONT_BEGIN , _PARAM_FONT_END ) ;
if ( nFound )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( iFound = = PARAM_FONT_MODE )
return CmdConfigFontMode ( nArgs ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
return CmdConfigSetFont ( nArgs ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
return Help_Arg_1 ( CMD_CONFIG_FONT ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
// Only for FONT_DISASM_DEFAULT !
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
void _UpdateWindowFontHeights ( int nFontHeight )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( nFontHeight )
2006-02-25 20:50:29 +00:00
{
2006-07-05 21:23:13 +00:00
int nConsoleTopY = GetConsoleTopPixels ( g_nConsoleDisplayLines ) ;
2006-02-26 06:26:56 +00:00
int nHeight = 0 ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( g_iFontSpacing = = FONT_SPACING_CLASSIC )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
nHeight = nFontHeight + 1 ;
2006-07-05 21:23:13 +00:00
g_nDisasmDisplayLines = nConsoleTopY / nHeight ;
2006-02-26 06:26:56 +00:00
}
else
if ( g_iFontSpacing = = FONT_SPACING_CLEAN )
{
nHeight = nFontHeight ;
2006-07-05 21:23:13 +00:00
g_nDisasmDisplayLines = nConsoleTopY / nHeight ;
2006-02-25 20:50:29 +00:00
}
else
2006-02-26 06:26:56 +00:00
if ( g_iFontSpacing = = FONT_SPACING_COMPRESSED )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
nHeight = nFontHeight - 1 ;
2006-07-05 21:23:13 +00:00
g_nDisasmDisplayLines = ( nConsoleTopY + nHeight ) / nHeight ; // Ceil()
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
g_aFontConfig [ FONT_DISASM_DEFAULT ] . _nLineHeight = nHeight ;
// int nHeightOptimal = (nHeight0 + nHeight1) / 2;
// int nLinesOptimal = nConsoleTopY / nHeightOptimal;
2006-07-05 21:23:13 +00:00
// g_nDisasmDisplayLines = nLinesOptimal;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
WindowUpdateSizes ( ) ;
}
}
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
bool _CmdConfigFont ( int iFont , LPCSTR pFontName , int iPitchFamily , int nFontHeight )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
bool bStatus = false ;
HFONT hFont = ( HFONT ) 0 ;
FontConfig_t * pFont = NULL ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( iFont < NUM_FONTS )
pFont = & g_aFontConfig [ iFont ] ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( pFontName )
{
// int nFontHeight = g_nFontHeight - 1;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
int bAntiAlias = ( nFontHeight < 14 ) ? DEFAULT_QUALITY : ANTIALIASED_QUALITY ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// Try allow new font
hFont = CreateFont (
nFontHeight
, 0 // Width
, 0 // Escapement
, 0 // Orientatin
, FW_MEDIUM // Weight
, 0 // Italic
, 0 // Underline
, 0 // Strike Out
, DEFAULT_CHARSET // OEM_CHARSET
, OUT_DEFAULT_PRECIS
, CLIP_DEFAULT_PRECIS
, bAntiAlias // ANTIALIASED_QUALITY // DEFAULT_QUALITY
, iPitchFamily // HACK: MAGIC #: 4
, pFontName ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( hFont )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( iFont = = FONT_DISASM_DEFAULT )
_UpdateWindowFontHeights ( nFontHeight ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
_tcsncpy ( pFont - > _sFontName , pFontName , MAX_FONT_NAME - 1 ) ;
pFont - > _sFontName [ MAX_FONT_NAME - 1 ] = 0 ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
HDC hDC = FrameGetDC ( ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
TEXTMETRIC tm ;
GetTextMetrics ( hDC , & tm ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
SIZE size ;
TCHAR sText [ ] = " W " ;
int nLen = 1 ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
int nFontWidthAvg ;
int nFontWidthMax ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// if (! (tm.tmPitchAndFamily & TMPF_FIXED_PITCH)) // Windows has this bitflag reversed!
// { // Proportional font?
// bool bStop = true;
// }
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// GetCharWidth32() doesn't work with TrueType Fonts
if ( GetTextExtentPoint32 ( hDC , sText , nLen , & size ) )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
nFontWidthAvg = tm . tmAveCharWidth ;
nFontWidthMax = size . cx ;
}
else
{
// Font Name Avg Max "W"
// Arial 7 8 11
// Courier 5 32 11
// Courier New 7 14
nFontWidthAvg = tm . tmAveCharWidth ;
nFontWidthMax = tm . tmMaxCharWidth ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
if ( ! nFontWidthAvg )
{
nFontWidthAvg = 7 ;
nFontWidthMax = 7 ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
FrameReleaseDC ( ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// DeleteObject( g_hFontDisasm );
// g_hFontDisasm = hFont;
pFont - > _hFont = hFont ;
pFont - > _nFontWidthAvg = nFontWidthAvg ;
pFont - > _nFontWidthMax = nFontWidthMax ;
pFont - > _nFontHeight = nFontHeight ;
bStatus = true ;
}
}
return bStatus ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdConfigSetFont ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-07-09 04:53:08 +00:00
# if OLD_FONT
2006-02-26 06:26:56 +00:00
HFONT hFont = ( HFONT ) 0 ;
TCHAR * pFontName = NULL ;
int nHeight = g_nFontHeight ;
int iFontTarget = FONT_DISASM_DEFAULT ;
int iFontPitch = FIXED_PITCH | FF_MODERN ;
// int iFontMode =
bool bHaveTarget = false ;
bool bHaveFont = false ;
if ( ! nArgs )
{ // reset to defaut font
pFontName = g_sFontNameDefault ;
}
else
if ( nArgs < = 3 )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
int iArg = 1 ;
pFontName = g_aArgs [ 1 ] . sArg ;
// [DISASM|INFO|CONSOLE] "FontName" [#]
// "FontName" can be either arg 1 or 2
int iFound ;
int nFound = FindParam ( g_aArgs [ iArg ] . sArg , MATCH_EXACT , iFound , _PARAM_WINDOW_BEGIN , _PARAM_WINDOW_END ) ;
if ( nFound )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
switch ( iFound )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
case PARAM_DISASM : iFontTarget = FONT_DISASM_DEFAULT ; iFontPitch = FIXED_PITCH | FF_MODERN ; bHaveTarget = true ; break ;
case PARAM_INFO : iFontTarget = FONT_INFO ; iFontPitch = FIXED_PITCH | FF_MODERN ; bHaveTarget = true ; break ;
case PARAM_CONSOLE : iFontTarget = FONT_CONSOLE ; iFontPitch = DEFAULT_PITCH | FF_DECORATIVE ; bHaveTarget = true ; break ;
default :
2006-06-27 02:33:40 +00:00
if ( g_aArgs [ 2 ] . bType ! = TOKEN_QUOTE_DOUBLE )
2006-02-26 06:26:56 +00:00
return Help_Arg_1 ( CMD_CONFIG_FONT ) ;
break ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
if ( bHaveTarget )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
pFontName = g_aArgs [ 2 ] . sArg ;
2006-02-25 20:50:29 +00:00
}
}
2006-02-26 06:26:56 +00:00
else
if ( nArgs = = 2 )
{
nHeight = atoi ( g_aArgs [ 2 ] . sArg ) ;
if ( ( nHeight < 6 ) | | ( nHeight > 36 ) )
nHeight = g_nFontHeight ;
}
}
else
{
return Help_Arg_1 ( CMD_CONFIG_FONT ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
if ( ! _CmdConfigFont ( iFontTarget , pFontName , iFontPitch , nHeight ) )
2006-02-25 20:50:29 +00:00
{
}
2006-07-09 04:53:08 +00:00
# endif
2006-02-26 06:26:56 +00:00
return UPDATE_ALL ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdConfigGetFont ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( ! nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
for ( int iFont = 0 ; iFont < NUM_FONTS ; iFont + + )
{
TCHAR sText [ CONSOLE_WIDTH ] = TEXT ( " " ) ;
wsprintf ( sText , " Font: %-20s A:%2d M:%2d " ,
// g_sFontNameCustom, g_nFontWidthAvg, g_nFontWidthMax );
g_aFontConfig [ iFont ] . _sFontName ,
g_aFontConfig [ iFont ] . _nFontWidthAvg ,
g_aFontConfig [ iFont ] . _nFontWidthMax ) ;
ConsoleBufferPush ( sText ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
return ConsoleUpdate ( ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
return UPDATE_CONSOLE_DISPLAY ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
// Cursor _________________________________________________________________________________________
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// Given an Address, and Line to display it on
// Calculate the address of the top and bottom lines
// @param bUpdateCur
// true = Update Cur based on Top
// false = Update Top & Bot based on Cur
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
void DisasmCalcTopFromCurAddress ( bool bUpdateTop )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
int nLen = ( ( g_nDisasmWinHeight - g_nDisasmCurLine ) * 3 ) ; // max 3 opcodes/instruction, is our search window
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// Look for a start address that when disassembled,
// will have the cursor on the specified line and address
int iTop = g_nDisasmCurAddress - nLen ;
int iCur = g_nDisasmCurAddress ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
g_bDisasmCurBad = false ;
bool bFound = false ;
while ( iTop < = iCur )
{
WORD iAddress = iTop ;
2006-06-26 16:59:48 +00:00
// int iOpcode;
int iOpmode ;
int nOpbytes ;
2006-02-26 06:26:56 +00:00
for ( int iLine = 0 ; iLine < = nLen ; iLine + + ) // min 1 opcode/instruction
{
2006-06-26 16:59:48 +00:00
// a.
2006-08-16 18:58:56 +00:00
_6502_GetOpmodeOpbyte ( iAddress , iOpmode , nOpbytes ) ;
2006-06-26 16:59:48 +00:00
// b.
2006-08-16 18:58:56 +00:00
// _6502_GetOpcodeOpmodeOpbyte( iOpcode, iOpmode, nOpbytes );
2006-06-26 16:59:48 +00:00
2006-02-26 06:26:56 +00:00
if ( iLine = = g_nDisasmCurLine ) // && (iAddress == g_nDisasmCurAddress))
{
if ( iAddress = = g_nDisasmCurAddress )
2006-06-26 16:59:48 +00:00
// b.
// && (iOpmode != AM_1) &&
// && (iOpmode != AM_2) &&
// && (iOpmode != AM_3) &&
// && _6502_IsOpcodeValid( iOpcode))
2006-02-26 06:26:56 +00:00
{
g_nDisasmTopAddress = iTop ;
bFound = true ;
break ;
}
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// .20 Fixed: DisasmCalcTopFromCurAddress()
//if ((eMode >= ADDR_INVALID1) && (eMode <= ADDR_INVALID3))
#if 0 // _DEBUG
2006-06-26 16:59:48 +00:00
TCHAR sText [ CONSOLE_WIDTH ] ;
wsprintf ( sText , " %04X : %d bytes \n " , iAddress , nOpbytes ) ;
OutputDebugString ( sText ) ;
2006-02-26 06:26:56 +00:00
# endif
2006-06-26 16:59:48 +00:00
iAddress + = nOpbytes ;
2006-02-26 06:26:56 +00:00
}
if ( bFound )
{
break ;
}
iTop + + ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( ! bFound )
{
// Well, we're up the creek.
// There is no (valid) solution!
// Basically, there is no address, that when disassembled,
// will put our Address on the cursor Line!
// So, like typical game programming, when we don't like the solution, change the problem!
// if (bUpdateTop)
g_nDisasmTopAddress = g_nDisasmCurAddress ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
g_bDisasmCurBad = true ; // Bad Disassembler, no opcode for you!
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// We reall should move the cursor line to the top for one instruction.
2006-06-26 16:59:48 +00:00
// Moving the cursor line around is not really a good idea, since we're breaking consistency paradigm for the user.
2006-02-26 06:26:56 +00:00
// g_nDisasmCurLine = 0;
#if 0 // _DEBUG
TCHAR sText [ CONSOLE_WIDTH * 2 ] ;
sprintf ( sText , TEXT ( " DisasmCalcTopFromCurAddress() \n "
" \t Top: %04X \n "
" \t Len: %04X \n "
" \t Missed: %04X " ) ,
g_nDisasmCurAddress - nLen , nLen , g_nDisasmCurAddress ) ;
2006-05-14 00:43:19 +00:00
MessageBox ( g_hFrameWindow , sText , " ERROR " , MB_OK ) ;
2006-02-26 06:26:56 +00:00
# endif
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
}
2006-02-25 20:50:29 +00:00
2006-06-26 16:59:48 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
WORD DisasmCalcAddressFromLines ( WORD iAddress , int nLines )
{
while ( nLines - - > 0 )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
int iOpmode ;
int nOpbytes ;
2006-08-16 18:58:56 +00:00
_6502_GetOpmodeOpbyte ( iAddress , iOpmode , nOpbytes ) ;
2006-02-26 06:26:56 +00:00
iAddress + = nOpbytes ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
return iAddress ;
2006-02-25 20:50:29 +00:00
}
2006-06-26 16:59:48 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
void DisasmCalcCurFromTopAddress ( )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
g_nDisasmCurAddress = DisasmCalcAddressFromLines ( g_nDisasmTopAddress , g_nDisasmCurLine ) ;
2006-02-25 20:50:29 +00:00
}
2006-06-26 16:59:48 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
void DisasmCalcBotFromTopAddress ( )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
g_nDisasmBotAddress = DisasmCalcAddressFromLines ( g_nDisasmTopAddress , g_nDisasmWinHeight ) ;
2006-02-25 20:50:29 +00:00
}
2006-06-26 16:59:48 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
void DisasmCalcTopBotAddress ( )
{
DisasmCalcTopFromCurAddress ( ) ;
DisasmCalcBotFromTopAddress ( ) ;
}
2006-02-25 20:50:29 +00:00
2006-06-26 16:59:48 +00:00
//===========================================================================
Update_t CmdCursorFollowTarget ( int nArgs )
{
WORD nAddress = 0 ;
if ( _6502_GetTargetAddress ( g_nDisasmCurAddress , nAddress ) )
{
g_nDisasmCurAddress = nAddress ;
if ( CURSOR_ALIGN_CENTER = = nArgs )
{
WindowUpdateDisasmSize ( ) ;
}
else
if ( CURSOR_ALIGN_TOP = = nArgs )
{
g_nDisasmCurLine = 0 ;
}
DisasmCalcTopBotAddress ( ) ;
}
return UPDATE_ALL ;
}
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdCursorLineDown ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
int iOpmode ;
int nOpbytes ;
2006-08-16 18:58:56 +00:00
_6502_GetOpmodeOpbyte ( g_nDisasmCurAddress , iOpmode , nOpbytes ) ; // g_nDisasmTopAddress
2006-02-26 06:26:56 +00:00
if ( g_iWindowThis = = WINDOW_DATA )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
_CursorMoveDownAligned ( WINDOW_DATA_BYTES_PER_LINE ) ;
2006-06-26 16:59:48 +00:00
DisasmCalcTopBotAddress ( ) ;
2006-02-26 06:26:56 +00:00
}
else
2006-06-26 16:59:48 +00:00
if ( nArgs ) // scroll down by 'n' bytes
2006-02-26 06:26:56 +00:00
{
nOpbytes = nArgs ; // HACKL g_aArgs[1].val
g_nDisasmTopAddress + = nOpbytes ;
g_nDisasmCurAddress + = nOpbytes ;
g_nDisasmBotAddress + = nOpbytes ;
2006-06-26 16:59:48 +00:00
DisasmCalcTopBotAddress ( ) ;
2006-02-26 06:26:56 +00:00
}
else
{
2006-06-26 16:59:48 +00:00
# if DEBUG_SCROLL == 6
2006-02-26 06:26:56 +00:00
// Works except on one case: G FB53, SPACE, DOWN
WORD nTop = g_nDisasmTopAddress ;
WORD nCur = g_nDisasmCurAddress + nOpbytes ;
if ( g_bDisasmCurBad )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
g_nDisasmCurAddress = nCur ;
g_bDisasmCurBad = false ;
DisasmCalcTopFromCurAddress ( ) ;
return UPDATE_DISASM ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
// Adjust Top until nNewCur is at > Cur
do
{
g_nDisasmTopAddress + + ;
DisasmCalcCurFromTopAddress ( ) ;
} while ( g_nDisasmCurAddress < nCur ) ;
DisasmCalcCurFromTopAddress ( ) ;
DisasmCalcBotFromTopAddress ( ) ;
g_bDisasmCurBad = false ;
2006-06-26 16:59:48 +00:00
# endif
g_nDisasmCurAddress + = nOpbytes ;
2006-08-16 18:58:56 +00:00
_6502_GetOpmodeOpbyte ( g_nDisasmTopAddress , iOpmode , nOpbytes ) ;
2006-06-26 16:59:48 +00:00
g_nDisasmTopAddress + = nOpbytes ;
2006-08-16 18:58:56 +00:00
_6502_GetOpmodeOpbyte ( g_nDisasmBotAddress , iOpmode , nOpbytes ) ;
2006-06-26 16:59:48 +00:00
g_nDisasmBotAddress + = nOpbytes ;
if ( g_bDisasmCurBad )
{
// MessageBox( NULL, TEXT("Bad Disassembly of opcodes"), TEXT("Debugger"), MB_OK );
// g_nDisasmCurAddress = nCur;
// g_bDisasmCurBad = false;
// DisasmCalcTopFromCurAddress();
DisasmCalcTopBotAddress ( ) ;
// return UPDATE_DISASM;
}
g_bDisasmCurBad = false ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
// Can't use use + nBytes due to Disasm Singularity
// DisasmCalcTopBotAddress();
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return UPDATE_DISASM ;
}
2006-02-25 20:50:29 +00:00
2006-06-26 16:59:48 +00:00
// C++ Bug, can't have local structs used in STL containers
struct LookAhead_t
{
int _nAddress ;
int _iOpcode ;
int _iOpmode ;
int _nOpbytes ;
} ;
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdCursorLineUp ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
int nBytes = 1 ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( g_iWindowThis = = WINDOW_DATA )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
_CursorMoveUpAligned ( WINDOW_DATA_BYTES_PER_LINE ) ;
}
else
if ( nArgs )
{
2006-06-27 02:33:40 +00:00
nBytes = nArgs ; // HACK: g_aArgs[1].nValue
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
g_nDisasmTopAddress - - ;
DisasmCalcCurFromTopAddress ( ) ;
DisasmCalcBotFromTopAddress ( ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
else
{
2006-06-26 16:59:48 +00:00
// if (! g_nDisasmCurLine)
// {
// g_nDisasmCurLine = 1;
// DisasmCalcTopFromCurAddress( false );
// g_nDisasmCurLine = 0;
// DisasmCalcCurFromTopAddress();
// DisasmCalcBotFromTopAddress();
// return UPDATE_DISASM;
// }
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// SmartLineUp()
// Figure out if we should move up 1, 2, or 3 bytes since we have 2 possible cases:
//
// a) Scroll up by 2 bytes
// xx-2: A9 yy LDA #xx
// xxxx: top
//
// b) Scroll up by 3 bytes
// xx-3: 20 A9 xx JSR $00A9
// xxxx: top of window
//
2006-06-26 16:59:48 +00:00
# define DEBUG_SCROLL 3
# if DEBUG_SCROLL == 1
2006-02-26 06:26:56 +00:00
WORD nCur = g_nDisasmCurAddress - nBytes ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// Adjust Top until nNewCur is at > Cur
do
{
g_nDisasmTopAddress - - ;
DisasmCalcCurFromTopAddress ( ) ;
} while ( g_nDisasmCurAddress > nCur ) ;
2006-06-26 16:59:48 +00:00
# endif
# if DEBUG_SCROLL == 2
WORD nCur = g_nDisasmCurAddress - nBytes ;
int iOpcode ;
int iOpmode ;
int nOpbytes ;
int aOpBytes [ 4 ] ; // index is relative offset from cursor
int nLeastDesiredTopAddress = NO_6502_TARGET ;
do
{
g_nDisasmTopAddress - - ;
2006-08-16 18:58:56 +00:00
// _6502_GetOpcodeOpmodeOpbyte( iOpcode, iOpmode, nOpbytes );
iOpcode = _6502_GetOpmodeOpbyte ( g_nDisasmTopAddress , iOpmode , nOpbytes ) ;
2006-06-26 16:59:48 +00:00
aOpBytes [ 1 ] = nOpbytes ;
// Disasm is kept in sync. Maybe bad opcode, but if no other choices...
if ( nOpbytes = = 1 )
nLeastDesiredTopAddress = g_nDisasmTopAddress ;
if ( ( iOpmode = = AM_1 )
| | ( iOpmode = = AM_2 )
| | ( iOpmode = = AM_3 )
| | ! _6502_IsOpcodeValid ( iOpcode )
| | ( nOpbytes ! = 1 ) )
{
g_nDisasmTopAddress - - ;
DisasmCalcCurFromTopAddress ( ) ;
2006-08-16 18:58:56 +00:00
iOpcode = _6502_GetOpmodeOpbyte ( g_nDisasmTopAddress , iOpmode , nOpbytes ) ;
2006-06-26 16:59:48 +00:00
aOpBytes [ 2 ] = nOpbytes ;
if ( ( iOpmode = = AM_1 )
| | ( iOpmode = = AM_2 )
| | ( iOpmode = = AM_3 )
| | ! _6502_IsOpcodeValid ( iOpcode )
| | ( nOpbytes ! = 2 ) )
{
g_nDisasmTopAddress - - ;
DisasmCalcCurFromTopAddress ( ) ;
2006-08-16 18:58:56 +00:00
iOpcode = _6502_GetOpmodeOpbyte ( g_nDisasmTopAddress , iOpmode , nOpbytes ) ;
2006-06-26 16:59:48 +00:00
aOpBytes [ 3 ] = nOpbytes ;
if ( ( iOpmode = = AM_1 )
| | ( iOpmode = = AM_2 )
| | ( iOpmode = = AM_3 )
| | ( nOpbytes ! = 3 ) )
g_nDisasmTopAddress - - ;
DisasmCalcCurFromTopAddress ( ) ;
}
}
DisasmCalcCurFromTopAddress ( ) ;
} while ( g_nDisasmCurAddress > nCur ) ;
# endif
# if DEBUG_SCROLL == 3
// Isn't this the new DisasmCalcTopFromCurAddress() ??
int iOpcode ;
int iOpmode ;
int nOpbytes ;
const int MAX_LOOK_AHEAD = g_nDisasmWinHeight ;
static vector < LookAhead_t > aTopCandidates ;
LookAhead_t tCandidate ;
// if (! aBestTop.capacity() )
aTopCandidates . reserve ( MAX_LOOK_AHEAD ) ;
aTopCandidates . erase ( aTopCandidates . begin ( ) , aTopCandidates . end ( ) ) ;
2006-07-05 21:23:13 +00:00
WORD nTop = g_nDisasmTopAddress ;
WORD iTop = 0 ;
WORD nCur = 0 ;
2006-06-26 16:59:48 +00:00
do
{
nTop - - ;
nCur = nTop ;
iTop = ( g_nDisasmTopAddress - nTop ) ;
2006-07-05 21:23:13 +00:00
2006-06-26 16:59:48 +00:00
for ( int iLine = 0 ; iLine < MAX_LOOK_AHEAD ; iLine + + )
{
2006-08-16 18:58:56 +00:00
iOpcode = _6502_GetOpmodeOpbyte ( nCur , iOpmode , nOpbytes ) ;
2006-06-26 16:59:48 +00:00
// If address on iLine = g_nDisasmCurLine + 1
if ( iLine = = ( g_nDisasmCurLine + 1 ) )
{
if ( nCur = = ( g_nDisasmCurAddress ) )
{
2006-08-16 18:58:56 +00:00
iOpcode = _6502_GetOpmodeOpbyte ( nTop , iOpmode , nOpbytes ) ;
2006-06-26 16:59:48 +00:00
tCandidate . _nAddress = nTop ;
tCandidate . _iOpcode = iOpcode ;
tCandidate . _iOpmode = iOpmode ;
tCandidate . _nOpbytes = nOpbytes ;
aTopCandidates . push_back ( tCandidate ) ;
}
}
nCur + = nOpbytes ;
if ( nCur > g_nDisasmCurAddress )
break ;
}
} while ( iTop < MAX_LOOK_AHEAD ) ;
int nCandidates = aTopCandidates . size ( ) ;
if ( nCandidates )
{
int iBest = NO_6502_TARGET ;
int iCandidate = 0 ;
for ( ; iCandidate < nCandidates ; iCandidate + + )
{
tCandidate = aTopCandidates . at ( iCandidate ) ;
iOpcode = tCandidate . _iOpcode ;
iOpmode = tCandidate . _iOpmode ;
if ( ( iOpmode ! = AM_1 )
& & ( iOpmode ! = AM_2 )
& & ( iOpmode ! = AM_3 )
& & _6502_IsOpcodeValid ( iOpcode ) )
{
if ( g_iConfigDisasmScroll = = 1 )
{
// Favor min opbytes
if ( iBest ! = NO_6502_TARGET )
iBest = iCandidate ;
}
else
if ( g_iConfigDisasmScroll = = 3 )
{
// Favor max opbytes
iBest = iCandidate ;
}
}
}
// All were "invalid", pick first choice
if ( iBest = = NO_6502_TARGET )
iBest = 0 ;
tCandidate = aTopCandidates . at ( iBest ) ;
g_nDisasmTopAddress = tCandidate . _nAddress ;
DisasmCalcCurFromTopAddress ( ) ;
DisasmCalcBotFromTopAddress ( ) ;
g_bDisasmCurBad = false ;
}
else
{
// Singularity
g_bDisasmCurBad = true ;
// g_nDisasmTopAddress--;
g_nDisasmCurAddress - - ;
// g_nDisasmBotAddress--;
DisasmCalcTopBotAddress ( ) ;
}
# endif
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
}
return UPDATE_DISASM ;
2006-02-25 20:50:29 +00:00
}
2006-06-26 16:59:48 +00:00
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdCursorJumpPC ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
// TODO: Allow user to decide if they want next g_aOpcodes at
// 1) Centered (traditionaly), or
// 2) Top of the screen
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// if (UserPrefs.bNextInstructionCentered)
if ( CURSOR_ALIGN_CENTER = = nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
g_nDisasmCurAddress = regs . pc ; // (2)
WindowUpdateDisasmSize ( ) ; // calc cur line
}
else
if ( CURSOR_ALIGN_TOP = = nArgs )
{
g_nDisasmCurAddress = regs . pc ; // (2)
g_nDisasmCurLine = 0 ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
DisasmCalcTopBotAddress ( ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return UPDATE_ALL ;
}
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdCursorJumpRetAddr ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-06-26 16:59:48 +00:00
WORD nAddress = 0 ;
if ( _6502_GetStackReturnAddress ( nAddress ) )
2006-02-26 06:26:56 +00:00
{
g_nDisasmCurAddress = nAddress ;
if ( CURSOR_ALIGN_CENTER = = nArgs )
{
WindowUpdateDisasmSize ( ) ;
}
else
if ( CURSOR_ALIGN_TOP = = nArgs )
{
g_nDisasmCurLine = 0 ;
}
DisasmCalcTopBotAddress ( ) ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return UPDATE_ALL ;
}
2006-02-25 20:50:29 +00:00
2006-06-26 16:59:48 +00:00
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdCursorRunUntil ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
nArgs = _Arg_1 ( g_nDisasmCurAddress ) ;
return CmdGo ( nArgs ) ;
2006-02-25 20:50:29 +00:00
}
2006-06-26 16:59:48 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
WORD _ClampAddress ( int nAddress )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( nAddress < 0 )
nAddress = 0 ;
2006-08-16 18:58:56 +00:00
if ( nAddress > _6502_MEM_END )
nAddress = _6502_MEM_END ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return ( WORD ) nAddress ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
// nDelta must be a power of 2
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
void _CursorMoveDownAligned ( int nDelta )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( g_iWindowThis = = WINDOW_DATA )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( g_aMemDump [ 0 ] . bActive )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( g_aMemDump [ 0 ] . eDevice = = DEV_MEMORY )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
g_aMemDump [ 0 ] . nAddress + = nDelta ;
2006-06-25 03:43:49 +00:00
g_aMemDump [ 0 ] . nAddress & = _6502_MEM_END ;
2006-02-25 20:50:29 +00:00
}
}
2006-02-26 06:26:56 +00:00
}
else
{
int nNewAddress = g_nDisasmTopAddress ; // BUGFIX: g_nDisasmCurAddress;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( ( nNewAddress & ( nDelta - 1 ) ) = = 0 )
nNewAddress + = nDelta ;
else
nNewAddress + = ( nDelta - ( nNewAddress & ( nDelta - 1 ) ) ) ; // .22 Fixed: Shift-PageUp Shift-PageDown Ctrl-PageUp Ctrl-PageDown -> _CursorMoveUpAligned() & _CursorMoveDownAligned()
2006-06-25 03:43:49 +00:00
g_nDisasmTopAddress = nNewAddress & _6502_MEM_END ; // .21 Fixed: _CursorMoveUpAligned() & _CursorMoveDownAligned() not wrapping around past FF00 to 0, and wrapping around past 0 to FF00
2006-02-26 06:26:56 +00:00
}
}
// nDelta must be a power of 2
//===========================================================================
void _CursorMoveUpAligned ( int nDelta )
{
if ( g_iWindowThis = = WINDOW_DATA )
{
if ( g_aMemDump [ 0 ] . bActive )
{
if ( g_aMemDump [ 0 ] . eDevice = = DEV_MEMORY )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
g_aMemDump [ 0 ] . nAddress - = nDelta ;
2006-06-25 03:43:49 +00:00
g_aMemDump [ 0 ] . nAddress & = _6502_MEM_END ;
2006-02-25 20:50:29 +00:00
}
}
2006-02-26 06:26:56 +00:00
}
else
{
int nNewAddress = g_nDisasmTopAddress ; // BUGFIX: g_nDisasmCurAddress;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( ( nNewAddress & ( nDelta - 1 ) ) = = 0 )
nNewAddress - = nDelta ;
else
nNewAddress - = ( nNewAddress & ( nDelta - 1 ) ) ; // .22 Fixed: Shift-PageUp Shift-PageDown Ctrl-PageUp Ctrl-PageDown -> _CursorMoveUpAligned() & _CursorMoveDownAligned()
2006-02-25 20:50:29 +00:00
2006-06-25 03:43:49 +00:00
g_nDisasmTopAddress = nNewAddress & _6502_MEM_END ; // .21 Fixed: _CursorMoveUpAligned() & _CursorMoveDownAligned() not wrapping around past FF00 to 0, and wrapping around past 0 to FF00
2006-02-25 20:50:29 +00:00
}
}
2006-02-26 06:26:56 +00:00
//===========================================================================
Update_t CmdCursorPageDown ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-06-26 16:59:48 +00:00
int iLines = 0 ; // show at least 1 line from previous display
2006-02-26 06:26:56 +00:00
int nLines = WindowGetHeight ( g_iWindowThis ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( nLines < 2 )
nLines = 2 ;
if ( g_iWindowThis = = WINDOW_DATA )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
const int nStep = 128 ;
_CursorMoveDownAligned ( nStep ) ;
2006-02-25 20:50:29 +00:00
}
else
{
2006-06-26 16:59:48 +00:00
// 4
// while (++iLines < nLines)
// CmdCursorLineDown(nArgs);
// 5
nLines - = ( g_nDisasmCurLine + 1 ) ;
if ( nLines < 1 )
nLines = 1 ;
while ( iLines + + < nLines )
{
CmdCursorLineDown ( 0 ) ; // nArgs
}
// 6
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
return UPDATE_DISASM ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
//===========================================================================
Update_t CmdCursorPageDown256 ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
const int nStep = 256 ;
_CursorMoveDownAligned ( nStep ) ;
return UPDATE_DISASM ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
//===========================================================================
Update_t CmdCursorPageDown4K ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
const int nStep = 4096 ;
_CursorMoveDownAligned ( nStep ) ;
return UPDATE_DISASM ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
Update_t CmdCursorPageUp ( int nArgs )
{
2006-06-26 16:59:48 +00:00
int iLines = 0 ; // show at least 1 line from previous display
2006-02-26 06:26:56 +00:00
int nLines = WindowGetHeight ( g_iWindowThis ) ;
if ( nLines < 2 )
nLines = 2 ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( g_iWindowThis = = WINDOW_DATA )
{
const int nStep = 128 ;
_CursorMoveUpAligned ( nStep ) ;
}
else
{
2006-06-26 16:59:48 +00:00
// while (++iLines < nLines)
// CmdCursorLineUp(nArgs);
nLines - = ( g_nDisasmCurLine + 1 ) ;
if ( nLines < 1 )
nLines = 1 ;
while ( iLines + + < nLines )
{
CmdCursorLineUp ( 0 ) ; // smart line up
// CmdCursorLineUp( -nLines );
}
2006-02-26 06:26:56 +00:00
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return UPDATE_DISASM ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
Update_t CmdCursorPageUp256 ( int nArgs )
{
const int nStep = 256 ;
_CursorMoveUpAligned ( nStep ) ;
return UPDATE_DISASM ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
Update_t CmdCursorPageUp4K ( int nArgs )
{
const int nStep = 4096 ;
_CursorMoveUpAligned ( nStep ) ;
return UPDATE_DISASM ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdCursorSetPC ( int nArgs ) // TODO rename
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
regs . pc = nArgs ; // HACK:
return UPDATE_DISASM ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// Flags __________________________________________________________________________________________
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
Update_t CmdFlagClear ( int nArgs )
{
int iFlag = ( g_iCommand - CMD_FLAG_CLR_C ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( g_iCommand = = CMD_FLAG_CLEAR )
{
int iArg = nArgs ;
while ( iArg )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
iFlag = 0 ;
while ( iFlag < _6502_NUM_FLAGS )
{
// if (g_aFlagNames[iFlag] == g_aArgs[iArg].sArg[0])
if ( g_aBreakpointSource [ BP_SRC_FLAG_N + iFlag ] [ 0 ] = = g_aArgs [ iArg ] . sArg [ 0 ] )
{
regs . ps & = ~ ( 1 < < iFlag ) ;
}
iFlag + + ;
}
iArg - - ;
}
}
else
{
regs . ps & = ~ ( 1 < < iFlag ) ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return UPDATE_FLAGS ; // 1;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
Update_t CmdFlagSet ( int nArgs )
{
int iFlag = ( g_iCommand - CMD_FLAG_SET_C ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( g_iCommand = = CMD_FLAG_SET )
{
int iArg = nArgs ;
while ( iArg )
{
iFlag = 0 ;
while ( iFlag < _6502_NUM_FLAGS )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
// if (g_aFlagNames[iFlag] == g_aArgs[iArg].sArg[0])
if ( g_aBreakpointSource [ BP_SRC_FLAG_N + iFlag ] [ 0 ] = = g_aArgs [ iArg ] . sArg [ 0 ] )
{
regs . ps | = ( 1 < < iFlag ) ;
}
iFlag + + ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
iArg - - ;
2006-02-25 20:50:29 +00:00
}
}
else
{
2006-02-26 06:26:56 +00:00
regs . ps | = ( 1 < < iFlag ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
return UPDATE_FLAGS ; // 1;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdFlag ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
// if (g_aArgs[0].sArg[0] == g_aParameters[PARAM_FLAG_CLEAR].aName[0] ) // TEXT('R')
if ( g_iCommand = = CMD_FLAG_CLEAR )
return CmdFlagClear ( nArgs ) ;
else
if ( g_iCommand = = CMD_FLAG_SET )
// if (g_aArgs[0].sArg[0] == g_aParameters[PARAM_FLAG_SET].aName[0] ) // TEXT('S')
return CmdFlagSet ( nArgs ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return UPDATE_ALL ; // 0;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
// Disk ___________________________________________________________________________________________
Update_t CmdDisk ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( ! nArgs )
goto _Help ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( nArgs < 2 )
goto _Help ;
2006-02-25 20:50:29 +00:00
2006-06-27 02:33:40 +00:00
int iDrive = g_aArgs [ 1 ] . nValue ;
2006-02-26 06:26:56 +00:00
if ( ( iDrive < 1 ) | | ( iDrive > 2 ) )
return HelpLastCommand ( ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
iDrive - - ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
int iParam = 0 ;
int nFound = FindParam ( g_aArgs [ 2 ] . sArg , MATCH_EXACT , iParam , _PARAM_DISK_BEGIN , _PARAM_DISK_END ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( ! nFound )
goto _Help ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( iParam = = PARAM_DISK_EJECT )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( nArgs > 2 )
goto _Help ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
DiskEject ( iDrive ) ;
FrameRefreshStatus ( DRAW_LEDS | DRAW_BUTTON_DRIVES ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
else
if ( iParam = = PARAM_DISK_PROTECT )
{
if ( nArgs > 3 )
goto _Help ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
bool bProtect = true ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( nArgs = = 3 )
2006-06-27 02:33:40 +00:00
bProtect = g_aArgs [ 3 ] . nValue ? true : false ;
2006-02-25 20:50:29 +00:00
2006-03-07 18:15:45 +00:00
DiskSetProtect ( iDrive , bProtect ) ;
2006-02-26 06:26:56 +00:00
FrameRefreshStatus ( DRAW_LEDS | DRAW_BUTTON_DRIVES ) ;
}
else
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( nArgs ! = 3 )
goto _Help ;
LPCTSTR pDiskName = g_aArgs [ 3 ] . sArg ;
// DISK # "Diskname"
DiskInsert ( iDrive , pDiskName , true , false ) ; // write_protected, dont_create
FrameRefreshStatus ( DRAW_LEDS | DRAW_BUTTON_DRIVES ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
return UPDATE_CONSOLE_DISPLAY ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
_Help :
return HelpLastCommand ( ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
// Memory _________________________________________________________________________________________
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// TO DO:
// . Add support for dumping Disk][ device
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
bool MemoryDumpCheck ( int nArgs , WORD * pAddress_ )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( ! nArgs )
return false ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
Arg_t * pArg = & g_aArgs [ 1 ] ;
2006-06-27 02:33:40 +00:00
WORD nAddress = pArg - > nValue ;
2006-02-26 06:26:56 +00:00
bool bUpdate = false ;
pArg - > eDevice = DEV_MEMORY ; // Default
if ( strncmp ( g_aArgs [ 1 ] . sArg , " SY " , 2 ) = = 0 ) // SY6522
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
nAddress = ( g_aArgs [ 1 ] . sArg [ 2 ] - ' 0 ' ) & 3 ;
pArg - > eDevice = DEV_SY6522 ;
bUpdate = true ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
else if ( strncmp ( g_aArgs [ 1 ] . sArg , " AY " , 2 ) = = 0 ) // AY8910
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
nAddress = ( g_aArgs [ 1 ] . sArg [ 2 ] - ' 0 ' ) & 3 ;
pArg - > eDevice = DEV_AY8910 ;
bUpdate = true ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
# ifdef SUPPORT_Z80_EMU
else if ( strcmp ( g_aArgs [ 1 ] . sArg , " *AF " ) = = 0 )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
nAddress = * ( WORD * ) ( mem + REG_AF ) ;
bUpdate = true ;
}
else if ( strcmp ( g_aArgs [ 1 ] . sArg , " *BC " ) = = 0 )
{
nAddress = * ( WORD * ) ( mem + REG_BC ) ;
bUpdate = true ;
}
else if ( strcmp ( g_aArgs [ 1 ] . sArg , " *DE " ) = = 0 )
{
nAddress = * ( WORD * ) ( mem + REG_DE ) ;
bUpdate = true ;
}
else if ( strcmp ( g_aArgs [ 1 ] . sArg , " *HL " ) = = 0 )
{
nAddress = * ( WORD * ) ( mem + REG_HL ) ;
bUpdate = true ;
}
else if ( strcmp ( g_aArgs [ 1 ] . sArg , " *IX " ) = = 0 )
{
nAddress = * ( WORD * ) ( mem + REG_IX ) ;
bUpdate = true ;
}
# endif
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( bUpdate )
{
2006-06-27 02:33:40 +00:00
pArg - > nValue = nAddress ;
2006-02-26 06:26:56 +00:00
sprintf ( pArg - > sArg , " %04X " , nAddress ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
if ( pAddress_ )
{
* pAddress_ = nAddress ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return true ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdMemoryCompare ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( nArgs < 3 )
return Help_Arg_1 ( CMD_MEMORY_COMPARE ) ;
2006-06-27 02:33:40 +00:00
WORD nSrcAddr = g_aArgs [ 1 ] . nValue ;
2006-02-26 06:26:56 +00:00
WORD nLenByte = 0 ;
2006-06-27 02:33:40 +00:00
WORD nDstAddr = g_aArgs [ 3 ] . nValue ;
2006-02-26 06:26:56 +00:00
WORD nSrcSymAddr ;
WORD nDstSymAddr ;
if ( ! nSrcAddr )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
nSrcSymAddr = GetAddressFromSymbol ( g_aArgs [ 1 ] . sArg ) ;
if ( nSrcAddr ! = nSrcSymAddr )
nSrcAddr = nSrcSymAddr ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
if ( ! nDstAddr )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
nDstSymAddr = GetAddressFromSymbol ( g_aArgs [ 3 ] . sArg ) ;
if ( nDstAddr ! = nDstSymAddr )
nDstAddr = nDstSymAddr ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// if ((!nSrcAddr) || (!nDstAddr))
// return Help_Arg_1( CMD_MEMORY_COMPARE );
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return UPDATE_CONSOLE_DISPLAY ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
static Update_t _CmdMemoryDump ( int nArgs , int iWhich , int iView )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
WORD nAddress = 0 ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( ! MemoryDumpCheck ( nArgs , & nAddress ) )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
return Help_Arg_1 ( g_iCommand ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
g_aMemDump [ iWhich ] . nAddress = nAddress ;
g_aMemDump [ iWhich ] . eDevice = g_aArgs [ 1 ] . eDevice ;
g_aMemDump [ iWhich ] . bActive = true ;
g_aMemDump [ iWhich ] . eView = ( MemoryView_e ) iView ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return UPDATE_ALL ; // TODO: This really needed? Don't think we do any actual ouput
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
bool _MemoryCheckMiniDump ( int iWhich )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( ( iWhich < 0 ) | | ( iWhich > NUM_MEM_MINI_DUMPS ) )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
TCHAR sText [ CONSOLE_WIDTH ] ;
wsprintf ( sText , TEXT ( " Only %d memory mini dumps " ) , NUM_MEM_MINI_DUMPS ) ;
ConsoleDisplayError ( sText ) ;
2006-02-25 20:50:29 +00:00
return true ;
}
return false ;
}
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdMemoryMiniDumpHex ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
int iWhich = g_iCommand - CMD_MEM_MINI_DUMP_HEX_1 ;
if ( _MemoryCheckMiniDump ( iWhich ) )
return UPDATE_CONSOLE_DISPLAY ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return _CmdMemoryDump ( nArgs , iWhich , MEM_VIEW_HEX ) ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
Update_t CmdMemoryMiniDumpAscii ( int nArgs )
{
int iWhich = g_iCommand - CMD_MEM_MINI_DUMP_ASCII_1 ;
if ( _MemoryCheckMiniDump ( iWhich ) )
return UPDATE_CONSOLE_DISPLAY ;
return _CmdMemoryDump ( nArgs , iWhich , MEM_VIEW_ASCII ) ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdMemoryMiniDumpApple ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
int iWhich = g_iCommand - CMD_MEM_MINI_DUMP_APPLE_1 ;
if ( _MemoryCheckMiniDump ( iWhich ) )
return UPDATE_CONSOLE_DISPLAY ;
return _CmdMemoryDump ( nArgs , iWhich , MEM_VIEW_APPLE ) ; // MEM_VIEW_TXT_LO );
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
//===========================================================================
//Update_t CmdMemoryMiniDumpLow (int nArgs)
//{
// int iWhich = g_iCommand - CMD_MEM_MINI_DUMP_TXT_LO_1;
// if (_MemoryCheckMiniDump( iWhich ))
// return UPDATE_CONSOLE_DISPLAY;
//
// return _CmdMemoryDump(nArgs, iWhich, MEM_VIEW_APPLE ); // MEM_VIEW_TXT_LO );
//}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
//Update_t CmdMemoryMiniDumpHigh (int nArgs)
//{
// int iWhich = g_iCommand - CMD_MEM_MINI_DUMP_TXT_HI_1;
// if (_MemoryCheckMiniDump( iWhich ))
// return UPDATE_CONSOLE_DISPLAY;
//
// return _CmdMemoryDump(nArgs, iWhich, MEM_VIEW_APPLE ); // MEM_VIEW_TXT_HI );
//}
//===========================================================================
Update_t CmdMemoryEdit ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
return UPDATE_CONSOLE_DISPLAY ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdMemoryEnterByte ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( ( nArgs < 2 ) | |
2006-06-27 02:33:40 +00:00
( ( g_aArgs [ 2 ] . sArg [ 0 ] ! = TEXT ( ' 0 ' ) ) & & ( ! g_aArgs [ 2 ] . nValue ) ) ) // arg2 not numeric or not specified
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
Help_Arg_1 ( CMD_MEMORY_ENTER_WORD ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
2006-06-27 02:33:40 +00:00
WORD nAddress = g_aArgs [ 1 ] . nValue ;
2006-02-26 06:26:56 +00:00
while ( nArgs > = 2 )
2006-02-25 20:50:29 +00:00
{
2006-06-27 02:33:40 +00:00
* ( mem + nAddress + nArgs - 2 ) = ( BYTE ) g_aArgs [ nArgs ] . nValue ;
2006-02-26 06:26:56 +00:00
* ( memdirty + ( nAddress > > 8 ) ) = 1 ;
nArgs - - ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
return UPDATE_ALL ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdMemoryEnterWord ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( ( nArgs < 2 ) | |
2006-06-27 02:33:40 +00:00
( ( g_aArgs [ 2 ] . sArg [ 0 ] ! = TEXT ( ' 0 ' ) ) & & ( ! g_aArgs [ 2 ] . nValue ) ) ) // arg2 not numeric or not specified
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
Help_Arg_1 ( CMD_MEMORY_ENTER_WORD ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
2006-06-27 02:33:40 +00:00
WORD nAddress = g_aArgs [ 1 ] . nValue ;
2006-02-26 06:26:56 +00:00
while ( nArgs > = 2 )
2006-02-25 20:50:29 +00:00
{
2006-06-27 02:33:40 +00:00
WORD nData = g_aArgs [ nArgs ] . nValue ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// Little Endian
* ( mem + nAddress + nArgs - 2 ) = ( BYTE ) ( nData > > 0 ) ;
* ( mem + nAddress + nArgs - 1 ) = ( BYTE ) ( nData > > 8 ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
* ( memdirty + ( nAddress > > 8 ) ) | = 1 ;
nArgs - - ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
return UPDATE_ALL ;
}
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdMemoryFill ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-06-27 02:33:40 +00:00
// F address [,len] value
// F address end value
if ( ( ! nArgs ) | | ( nArgs > 5 ) )
2006-02-26 06:26:56 +00:00
return Help_Arg_1 ( CMD_MEMORY_FILL ) ;
2006-06-27 02:33:40 +00:00
WORD nAddress = g_aArgs [ 1 ] . nValue ;
WORD nBytes = 1 ;
int iValue = 2 ;
if ( g_aArgs [ 2 ] . eToken = = TOKEN_COMMA )
{
nBytes = MAX ( 1 , g_aArgs [ iValue + 1 ] . nValue ) ;
iValue = 4 ;
}
else
if ( nArgs > 3 )
return Help_Arg_1 ( CMD_MEMORY_FILL ) ;
# if DEBUG_VAL_2
nBytes = MAX ( 1 , g_aArgs [ 1 ] . nVal2 ) ; // TODO: This actually work??
# endif
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
while ( nBytes - - )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( ( nAddress < _6502_IO_BEGIN ) | | ( nAddress > _6502_IO_END ) )
{
2006-06-27 02:33:40 +00:00
* ( mem + nAddress ) = ( BYTE ) ( g_aArgs [ iValue ] . nValue & 0xFF ) ; // HACK: Undocumented fill with ZERO
2006-02-26 06:26:56 +00:00
}
nAddress + + ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
return UPDATE_CONSOLE_DISPLAY ;
2006-02-25 20:50:29 +00:00
}
2006-06-12 03:08:35 +00:00
2006-06-27 02:33:40 +00:00
static TCHAR g_sMemoryLoadSaveFileName [ MAX_PATH ] = TEXT ( " " ) ;
2006-06-12 03:08:35 +00:00
//===========================================================================
Update_t CmdMemoryLoad ( int nArgs )
{
2006-06-27 02:33:40 +00:00
// BLOAD ["Filename"] , addr[, len]
2006-07-01 06:45:50 +00:00
// BLOAD ["Filename"] , addr[: end]
2006-06-27 02:33:40 +00:00
// 1 2 3 4 5
if ( nArgs > 5 )
2006-06-12 03:08:35 +00:00
return Help_Arg_1 ( CMD_MEMORY_LOAD ) ;
2006-06-27 02:33:40 +00:00
bool bHaveFileName = false ;
int iArgAddress = 3 ;
if ( g_aArgs [ 1 ] . bType & TYPE_QUOTED_2 )
bHaveFileName = true ;
// if (g_aArgs[2].bType & TOKEN_QUOTE_DOUBLE)
// bHaveFileName = true;
if ( nArgs > 1 )
2006-06-12 03:08:35 +00:00
{
2006-06-27 02:33:40 +00:00
if ( g_aArgs [ 1 ] . bType & TYPE_QUOTED_2 )
bHaveFileName = true ;
int iArgComma1 = 2 ;
int iArgAddress = 3 ;
int iArgComma2 = 4 ;
int iArgLength = 5 ;
if ( ! bHaveFileName )
{
iArgComma1 = 1 ;
iArgAddress = 2 ;
iArgComma2 = 3 ;
iArgLength = 4 ;
if ( nArgs > 4 )
return Help_Arg_1 ( CMD_MEMORY_LOAD ) ;
}
2006-07-01 06:45:50 +00:00
if ( g_aArgs [ iArgComma1 ] . eToken ! = TOKEN_COMMA )
return Help_Arg_1 ( CMD_MEMORY_SAVE ) ;
TCHAR sLoadSaveFilePath [ MAX_PATH ] ;
_tcscpy ( sLoadSaveFilePath , g_sCurrentDir ) ; // g_sProgramDir
WORD nAddressStart ;
WORD nAddress2 = 0 ;
WORD nAddressEnd = 0 ;
int nAddressLen = 0 ;
2006-06-27 02:33:40 +00:00
2006-07-01 06:45:50 +00:00
RangeType_t eRange ;
eRange = Range_Get ( nAddressStart , nAddress2 , iArgAddress ) ;
2006-06-27 02:33:40 +00:00
if ( nArgs > 4 )
{
2006-07-01 06:45:50 +00:00
if ( eRange = = RANGE_MISSING_ARG_2 )
{
return Help_Arg_1 ( CMD_MEMORY_LOAD ) ;
}
// if (eRange == RANGE_MISSING_ARG_2)
if ( ! Range_CalcEndLen ( eRange , nAddressStart , nAddress2 , nAddressEnd , nAddressLen ) )
2006-06-27 02:33:40 +00:00
{
return Help_Arg_1 ( CMD_MEMORY_SAVE ) ;
}
}
2006-07-01 06:45:50 +00:00
BYTE * pMemory = new BYTE [ _6502_MEM_END + 1 ] ; // default 64K buffer
BYTE * pDst = mem + nAddressStart ;
BYTE * pSrc = pMemory ;
2006-06-27 02:33:40 +00:00
2006-07-01 06:45:50 +00:00
if ( bHaveFileName )
2006-06-12 03:08:35 +00:00
{
2006-07-01 06:45:50 +00:00
_tcscpy ( g_sMemoryLoadSaveFileName , g_aArgs [ 1 ] . sArg ) ;
}
_tcscat ( sLoadSaveFilePath , g_sMemoryLoadSaveFileName ) ;
FILE * hFile = fopen ( sLoadSaveFilePath , " rb " ) ;
if ( hFile )
{
fseek ( hFile , 0 , SEEK_END ) ;
int nFileBytes = ftell ( hFile ) ;
fseek ( hFile , 0 , SEEK_SET ) ;
2006-06-12 03:08:35 +00:00
2006-07-01 06:45:50 +00:00
if ( nFileBytes > _6502_MEM_END )
nFileBytes = _6502_MEM_END + 1 ; // Bank-switched RAMR/ROM is only 16-bit
2006-06-12 03:08:35 +00:00
2006-07-01 06:45:50 +00:00
// Caller didnt' specify how many bytes to read, default to them all
if ( nAddressLen = = 0 )
2006-06-27 02:33:40 +00:00
{
2006-07-01 06:45:50 +00:00
nAddressLen = nFileBytes ;
2006-06-27 02:33:40 +00:00
}
2006-06-12 03:08:35 +00:00
2006-07-01 06:45:50 +00:00
size_t nRead = fread ( pMemory , nAddressLen , 1 , hFile ) ;
if ( nRead = = 1 ) // (size_t)nLen)
{
int iByte ;
for ( iByte = 0 ; iByte < nAddressLen ; iByte + + )
2006-06-12 03:08:35 +00:00
{
2006-07-01 06:45:50 +00:00
* pDst + + = * pSrc + + ;
2006-06-12 03:08:35 +00:00
}
2006-07-01 06:45:50 +00:00
ConsoleBufferPush ( TEXT ( " Loaded. " ) ) ;
2006-06-12 03:08:35 +00:00
}
2006-07-01 06:45:50 +00:00
fclose ( hFile ) ;
}
else
{
ConsoleBufferPush ( TEXT ( " ERROR: Bad filename " ) ) ;
TCHAR sPath [ MAX_PATH + 8 ] = " Path: " ;
_tcscat ( sPath , g_sCurrentDir ) ;
ConsoleBufferPush ( sPath ) ;
TCHAR sFile [ MAX_PATH + 8 ] = " File: " ;
_tcscat ( sFile , g_sMemoryLoadSaveFileName ) ;
ConsoleBufferPush ( sFile ) ;
2006-06-12 03:08:35 +00:00
}
2006-07-01 06:45:50 +00:00
delete [ ] pMemory ;
2006-06-12 03:08:35 +00:00
}
2006-06-27 02:33:40 +00:00
else
return Help_Arg_1 ( CMD_MEMORY_LOAD ) ;
2006-06-12 03:08:35 +00:00
2006-06-25 03:43:49 +00:00
return ConsoleUpdate ( ) ;
2006-06-12 03:08:35 +00:00
}
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdMemoryMove ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( nArgs < 3 )
return Help_Arg_1 ( CMD_MEMORY_MOVE ) ;
2006-06-27 02:33:40 +00:00
WORD nSrc = g_aArgs [ 1 ] . nValue ;
WORD nLen = g_aArgs [ 2 ] . nValue - nSrc ;
WORD nDst = g_aArgs [ 3 ] . nValue ;
2006-02-26 06:26:56 +00:00
return UPDATE_CONSOLE_DISPLAY ;
2006-02-25 20:50:29 +00:00
}
2006-06-12 03:08:35 +00:00
//===========================================================================
Update_t CmdMemorySave ( int nArgs )
{
2006-06-27 02:33:40 +00:00
// BSAVE ["Filename"] , addr , len
2006-07-01 06:45:50 +00:00
// BSAVE ["Filename"] , addr : end
2006-06-27 02:33:40 +00:00
// 1 2 3 4 5
2006-06-12 03:08:35 +00:00
static WORD nAddressStart = 0 ;
2006-07-01 06:45:50 +00:00
WORD nAddress2 = 0 ;
2006-06-12 03:08:35 +00:00
static WORD nAddressEnd = 0 ;
2006-07-01 06:45:50 +00:00
static int nAddressLen = 0 ;
2006-06-12 03:08:35 +00:00
2006-06-27 02:33:40 +00:00
if ( nArgs > 5 )
return Help_Arg_1 ( CMD_MEMORY_SAVE ) ;
2006-06-12 03:08:35 +00:00
if ( ! nArgs )
{
TCHAR sLast [ CONSOLE_WIDTH ] = TEXT ( " " ) ;
if ( nAddressLen )
{
2006-06-27 02:33:40 +00:00
wsprintf ( sLast , TEXT ( " Last saved: $%04X:$%04X, %04X " ) ,
2006-06-12 03:08:35 +00:00
nAddressStart , nAddressEnd , nAddressLen ) ;
}
else
{
2006-06-25 03:43:49 +00:00
wsprintf ( sLast , TEXT ( " Last saved: none " ) ) ;
2006-06-12 03:08:35 +00:00
}
ConsoleBufferPush ( sLast ) ;
}
else
{
2006-06-27 02:33:40 +00:00
bool bHaveFileName = false ;
if ( g_aArgs [ 1 ] . bType & TYPE_QUOTED_2 )
bHaveFileName = true ;
// if (g_aArgs[1].bType & TOKEN_QUOTE_DOUBLE)
// bHaveFileName = true;
int iArgComma1 = 2 ;
int iArgAddress = 3 ;
int iArgComma2 = 4 ;
int iArgLength = 5 ;
if ( ! bHaveFileName )
{
iArgComma1 = 1 ;
iArgAddress = 2 ;
iArgComma2 = 3 ;
iArgLength = 4 ;
if ( nArgs > 4 )
return Help_Arg_1 ( CMD_MEMORY_SAVE ) ;
}
2006-07-01 06:45:50 +00:00
// if ((g_aArgs[ iArgComma1 ].eToken != TOKEN_COMMA) ||
// (g_aArgs[ iArgComma2 ].eToken != TOKEN_COLON))
// return Help_Arg_1( CMD_MEMORY_SAVE );
2006-06-27 02:33:40 +00:00
TCHAR sLoadSaveFilePath [ MAX_PATH ] ;
_tcscpy ( sLoadSaveFilePath , g_sCurrentDir ) ; // g_sProgramDir
2006-07-01 06:45:50 +00:00
RangeType_t eRange ;
eRange = Range_Get ( nAddressStart , nAddress2 , iArgAddress ) ;
// if (eRange == RANGE_MISSING_ARG_2)
if ( ! Range_CalcEndLen ( eRange , nAddressStart , nAddress2 , nAddressEnd , nAddressLen ) )
return Help_Arg_1 ( CMD_MEMORY_SAVE ) ;
if ( ( nAddressLen ) & & ( nAddressEnd < = _6502_MEM_END ) )
2006-06-12 03:08:35 +00:00
{
2006-07-01 06:45:50 +00:00
if ( ! bHaveFileName )
{
sprintf ( g_sMemoryLoadSaveFileName , " %04X.%04X.bin " , nAddressStart , nAddressLen ) ; // nAddressEnd );
}
else
{
_tcscpy ( g_sMemoryLoadSaveFileName , g_aArgs [ 1 ] . sArg ) ;
}
_tcscat ( sLoadSaveFilePath , g_sMemoryLoadSaveFileName ) ;
2006-06-12 03:08:35 +00:00
2006-07-01 06:45:50 +00:00
// if (nArgs == 2)
2006-06-12 03:08:35 +00:00
{
2006-07-01 06:45:50 +00:00
BYTE * pMemory = new BYTE [ nAddressLen ] ;
BYTE * pDst = pMemory ;
BYTE * pSrc = mem + nAddressStart ;
int iByte ;
for ( iByte = 0 ; iByte < nAddressLen ; iByte + + )
2006-06-12 03:08:35 +00:00
{
2006-07-01 06:45:50 +00:00
* pDst + + = * pSrc + + ;
2006-06-27 02:33:40 +00:00
}
2006-07-01 06:45:50 +00:00
FILE * hFile = fopen ( sLoadSaveFilePath , " rb " ) ;
if ( hFile )
2006-06-27 02:33:40 +00:00
{
2006-07-01 06:45:50 +00:00
ConsoleBufferPush ( TEXT ( " Warning: File already exists. Overwriting. " ) ) ;
fclose ( hFile ) ;
2006-06-27 02:33:40 +00:00
}
2006-06-12 03:08:35 +00:00
2006-07-01 06:45:50 +00:00
hFile = fopen ( sLoadSaveFilePath , " wb " ) ;
if ( hFile )
2006-06-12 03:08:35 +00:00
{
2006-07-01 06:45:50 +00:00
size_t nWrote = fwrite ( pMemory , nAddressLen , 1 , hFile ) ;
if ( nWrote = = 1 ) // (size_t)nAddressLen)
2006-06-12 03:08:35 +00:00
{
2006-07-01 06:45:50 +00:00
ConsoleBufferPush ( TEXT ( " Saved. " ) ) ;
2006-06-12 03:08:35 +00:00
}
2006-07-01 06:45:50 +00:00
else
2006-06-12 03:08:35 +00:00
{
2006-07-01 06:45:50 +00:00
ConsoleBufferPush ( TEXT ( " Error saving. " ) ) ;
2006-06-12 03:08:35 +00:00
}
2006-07-01 06:45:50 +00:00
fclose ( hFile ) ;
2006-06-12 03:08:35 +00:00
}
2006-07-01 06:45:50 +00:00
delete [ ] pMemory ;
2006-06-12 03:08:35 +00:00
}
}
}
2006-06-25 03:43:49 +00:00
return ConsoleUpdate ( ) ;
2006-06-12 03:08:35 +00:00
}
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-05-10 22:00:27 +00:00
int _SearchMemoryFind (
MemorySearchValues_t vMemorySearchValues ,
WORD nAddressStart ,
WORD nAddressEnd )
2006-02-25 20:50:29 +00:00
{
2006-02-26 10:28:18 +00:00
int nFound = 0 ;
2006-05-10 22:00:27 +00:00
g_vMemorySearchResults . erase ( g_vMemorySearchResults . begin ( ) , g_vMemorySearchResults . end ( ) ) ;
2006-06-29 05:41:04 +00:00
g_vMemorySearchResults . push_back ( NO_6502_TARGET ) ;
2006-02-26 10:28:18 +00:00
WORD nAddress ;
for ( nAddress = nAddressStart ; nAddress < nAddressEnd ; nAddress + + )
{
bool bMatchAll = true ;
WORD nAddress2 = nAddress ;
2006-05-10 22:00:27 +00:00
int nMemBlocks = vMemorySearchValues . size ( ) ;
2006-02-26 10:28:18 +00:00
for ( int iBlock = 0 ; iBlock < nMemBlocks ; iBlock + + , nAddress2 + + )
{
2006-05-10 22:00:27 +00:00
MemorySearch_t ms = vMemorySearchValues . at ( iBlock ) ;
2006-02-26 10:28:18 +00:00
ms . m_bFound = false ;
if ( ( ms . m_iType = = MEM_SEARCH_BYTE_EXACT ) | |
( ms . m_iType = = MEM_SEARCH_NIB_HIGH_EXACT ) | |
( ms . m_iType = = MEM_SEARCH_NIB_LOW_EXACT ) )
{
BYTE nTarget = * ( mem + nAddress2 ) ;
if ( ms . m_iType = = MEM_SEARCH_NIB_LOW_EXACT )
nTarget & = 0x0F ;
if ( ms . m_iType = = MEM_SEARCH_NIB_HIGH_EXACT )
nTarget & = 0xF0 ;
if ( ms . m_nValue = = nTarget )
{ // ms.m_nAddress = nAddress2;
ms . m_bFound = true ;
continue ;
}
else
{
bMatchAll = false ;
break ;
}
}
else
if ( ms . m_iType = = MEM_SEARCH_BYTE_1_WILD )
{
// match by definition
}
else
{
// start 2ndary search
// if next block matches, then this block matches (since we are wild)
if ( ( iBlock + 1 ) = = nMemBlocks ) // there is no next block, hence we match
continue ;
2006-05-10 22:00:27 +00:00
MemorySearch_t ms2 = vMemorySearchValues . at ( iBlock + 1 ) ;
2006-02-26 10:28:18 +00:00
WORD nAddress3 = nAddress2 ;
for ( nAddress3 = nAddress2 ; nAddress3 < nAddressEnd ; nAddress3 + + )
{
if ( ( ms . m_iType = = MEM_SEARCH_BYTE_EXACT ) | |
( ms . m_iType = = MEM_SEARCH_NIB_HIGH_EXACT ) | |
( ms . m_iType = = MEM_SEARCH_NIB_LOW_EXACT ) )
{
BYTE nTarget = * ( mem + nAddress3 ) ;
if ( ms . m_iType = = MEM_SEARCH_NIB_LOW_EXACT )
nTarget & = 0x0F ;
if ( ms . m_iType = = MEM_SEARCH_NIB_HIGH_EXACT )
nTarget & = 0xF0 ;
if ( ms . m_nValue = = nTarget )
{
nAddress2 = nAddress3 ;
continue ;
}
else
{
bMatchAll = false ;
break ;
}
}
}
}
}
if ( bMatchAll )
{
nFound + + ;
2006-05-10 22:00:27 +00:00
// Save the search result
g_vMemorySearchResults . push_back ( nAddress ) ;
}
}
return nFound ;
}
//===========================================================================
Update_t _SearchMemoryDisplay ( )
{
2006-06-29 05:41:04 +00:00
int nFound = g_vMemorySearchResults . size ( ) - 1 ;
2006-05-10 22:00:27 +00:00
TCHAR sMatches [ CONSOLE_WIDTH ] = TEXT ( " " ) ;
int nThisLineLen = 0 ; // string length of matches for this line, for word-wrap
2006-06-29 05:41:04 +00:00
if ( nFound > 0 )
2006-05-10 22:00:27 +00:00
{
TCHAR sText [ CONSOLE_WIDTH ] ;
2006-06-29 05:41:04 +00:00
int iFound = 1 ;
while ( iFound < = nFound )
2006-05-10 22:00:27 +00:00
{
WORD nAddress = g_vMemorySearchResults . at ( iFound ) ;
wsprintf ( sText , " %2d:$%04X " , iFound , nAddress ) ;
2006-02-26 10:28:18 +00:00
int nLen = _tcslen ( sText ) ;
// Fit on same line?
2006-05-10 22:00:27 +00:00
if ( ( nThisLineLen + nLen ) > ( g_nConsoleDisplayWidth ) ) // CONSOLE_WIDTH
2006-02-26 10:28:18 +00:00
{
ConsoleDisplayPush ( sMatches ) ;
_tcscpy ( sMatches , sText ) ;
2006-05-10 22:00:27 +00:00
nThisLineLen = nLen ;
2006-02-26 10:28:18 +00:00
}
else
{
_tcscat ( sMatches , sText ) ;
2006-05-10 22:00:27 +00:00
nThisLineLen + = nLen ;
2006-02-26 10:28:18 +00:00
}
2006-05-10 22:00:27 +00:00
iFound + + ;
2006-02-26 10:28:18 +00:00
}
2006-05-10 22:00:27 +00:00
ConsoleDisplayPush ( sMatches ) ;
2006-02-26 10:28:18 +00:00
}
wsprintf ( sMatches , " Total: %d (#$%04X) " , nFound , nFound ) ;
ConsoleDisplayPush ( sMatches ) ;
2006-05-10 22:00:27 +00:00
// g_vMemorySearchResults is cleared in DebugEnd()
2006-02-26 06:26:56 +00:00
return UPDATE_CONSOLE_DISPLAY ;
2006-05-10 22:00:27 +00:00
}
2006-02-26 10:28:18 +00:00
2006-05-10 22:00:27 +00:00
//===========================================================================
Update_t _CmdMemorySearch ( int nArgs , bool bTextIsAscii = true )
{
2006-07-01 06:45:50 +00:00
WORD nAddressStart = 0 ;
WORD nAddress2 = 0 ;
WORD nAddressEnd = 0 ;
int nAddressLen = 0 ;
2006-06-29 05:41:04 +00:00
2006-07-01 06:45:50 +00:00
RangeType_t eRange ;
eRange = Range_Get ( nAddressStart , nAddress2 ) ;
// if (eRange == RANGE_MISSING_ARG_2)
if ( ! Range_CalcEndLen ( eRange , nAddressStart , nAddress2 , nAddressEnd , nAddressLen ) )
2006-06-29 05:41:04 +00:00
return ConsoleDisplayError ( TEXT ( " Error: Missing address seperator (comma or colon) " ) ) ;
int iArgFirstByte = 4 ;
2006-05-10 22:00:27 +00:00
// S start,len #
2006-06-29 05:41:04 +00:00
int nMinLen = nArgs - ( iArgFirstByte - 1 ) ;
2006-05-10 22:00:27 +00:00
bool bHaveWildCards = false ;
int iArg ;
MemorySearchValues_t vMemorySearchValues ;
MemorySearch_e tLastType = MEM_SEARCH_BYTE_N_WILD ;
// Get search "string"
2006-06-29 05:41:04 +00:00
Arg_t * pArg = & g_aArgs [ iArgFirstByte ] ;
2006-05-10 22:00:27 +00:00
WORD nTarget ;
2006-06-29 05:41:04 +00:00
for ( iArg = iArgFirstByte ; iArg < = nArgs ; iArg + + , pArg + + )
2006-05-10 22:00:27 +00:00
{
MemorySearch_t ms ;
2006-06-27 02:33:40 +00:00
nTarget = pArg - > nValue ;
2006-05-10 22:00:27 +00:00
ms . m_nValue = nTarget & 0xFF ;
ms . m_iType = MEM_SEARCH_BYTE_EXACT ;
if ( nTarget > 0xFF ) // searching for 16-bit address
{
vMemorySearchValues . push_back ( ms ) ;
ms . m_nValue = ( nTarget > > 8 ) ;
tLastType = ms . m_iType ;
}
else
{
TCHAR * pByte = pArg - > sArg ;
if ( pArg - > bType & TYPE_QUOTED_1 )
{
2006-06-29 05:41:04 +00:00
// Convert string to hex byte(s)
int iChar = 0 ;
int nChars = pArg - > nArgLen ;
2006-05-10 22:00:27 +00:00
2006-06-29 05:41:04 +00:00
if ( nChars )
{
ms . m_iType = MEM_SEARCH_BYTE_EXACT ;
ms . m_bFound = false ;
while ( iChar < nChars )
{
ms . m_nValue = pArg - > sArg [ iChar ] ;
// Ascii (Low-Bit)
// Apple (High-Bit)
// if (! bTextIsAscii) // NOTE: Single quote chars is opposite hi-bit !!!
// ms.m_nValue &= 0x7F;
// else
ms . m_nValue | = 0x80 ;
// last char is handle in common case below
iChar + + ;
if ( iChar < nChars )
vMemorySearchValues . push_back ( ms ) ;
}
}
2006-05-10 22:00:27 +00:00
}
else
if ( pArg - > bType & TYPE_QUOTED_2 )
{
// Convert string to hex byte(s)
int iChar = 0 ;
int nChars = pArg - > nArgLen ;
if ( nChars )
{
ms . m_iType = MEM_SEARCH_BYTE_EXACT ;
ms . m_bFound = false ;
while ( iChar < nChars )
{
ms . m_nValue = pArg - > sArg [ iChar ] ;
// Ascii (Low-Bit)
// Apple (High-Bit)
2006-06-29 05:41:04 +00:00
// if (bTextIsAscii)
2006-05-10 22:00:27 +00:00
ms . m_nValue & = 0x7F ;
2006-06-29 05:41:04 +00:00
// else
// ms.m_nValue |= 0x80;
2006-05-10 22:00:27 +00:00
2006-06-29 05:41:04 +00:00
iChar + + ; // last char is handle in common case below
if ( iChar < nChars )
vMemorySearchValues . push_back ( ms ) ;
2006-05-10 22:00:27 +00:00
}
}
}
else
{
// must be numeric .. make sure not too big
if ( pArg - > nArgLen > 2 )
{
vMemorySearchValues . erase ( vMemorySearchValues . begin ( ) , vMemorySearchValues . end ( ) ) ;
return HelpLastCommand ( ) ;
}
if ( pArg - > nArgLen = = 1 )
{
if ( pByte [ 0 ] = = g_aParameters [ PARAM_MEM_SEARCH_WILD ] . m_sName [ 0 ] ) // Hack: hard-coded one char token
{
ms . m_iType = MEM_SEARCH_BYTE_1_WILD ;
}
}
else
{
if ( pByte [ 0 ] = = g_aParameters [ PARAM_MEM_SEARCH_WILD ] . m_sName [ 0 ] ) // Hack: hard-coded one char token
{
ms . m_iType = MEM_SEARCH_NIB_LOW_EXACT ;
2006-06-27 02:33:40 +00:00
ms . m_nValue = pArg - > nValue & 0x0F ;
2006-05-10 22:00:27 +00:00
}
if ( pByte [ 1 ] = = g_aParameters [ PARAM_MEM_SEARCH_WILD ] . m_sName [ 0 ] ) // Hack: hard-coded one char token
{
if ( ms . m_iType = = MEM_SEARCH_NIB_LOW_EXACT )
{
ms . m_iType = MEM_SEARCH_BYTE_N_WILD ;
}
else
{
ms . m_iType = MEM_SEARCH_NIB_HIGH_EXACT ;
2006-06-27 02:33:40 +00:00
ms . m_nValue = ( pArg - > nValue < < 4 ) & 0xF0 ;
2006-05-10 22:00:27 +00:00
}
}
}
}
}
// skip over multiple byte_wild, since they are redundent
// xx ?? ?? xx
// ^
// redundant
if ( ( tLastType = = MEM_SEARCH_BYTE_N_WILD ) & & ( ms . m_iType = = MEM_SEARCH_BYTE_N_WILD ) )
continue ;
vMemorySearchValues . push_back ( ms ) ;
tLastType = ms . m_iType ;
}
2006-06-27 22:04:03 +00:00
_SearchMemoryFind ( vMemorySearchValues , nAddressStart , nAddressEnd ) ;
vMemorySearchValues . erase ( vMemorySearchValues . begin ( ) , vMemorySearchValues . end ( ) ) ;
return _SearchMemoryDisplay ( ) ;
}
//===========================================================================
Update_t CmdMemorySearch ( int nArgs )
{
2006-06-29 05:41:04 +00:00
// S address,length # [,#]
if ( nArgs < 4 )
2006-06-27 22:04:03 +00:00
return HelpLastCommand ( ) ;
return _CmdMemorySearch ( nArgs , true ) ;
return UPDATE_CONSOLE_DISPLAY ;
}
// Search for ASCII text (no Hi-Bit set)
//===========================================================================
Update_t CmdMemorySearchAscii ( int nArgs )
{
2006-06-29 05:41:04 +00:00
if ( nArgs < 4 )
2006-06-27 22:04:03 +00:00
return HelpLastCommand ( ) ;
return _CmdMemorySearch ( nArgs , true ) ;
}
// Search for Apple text (Hi-Bit set)
//===========================================================================
Update_t CmdMemorySearchApple ( int nArgs )
{
2006-06-29 05:41:04 +00:00
if ( nArgs < 4 )
2006-06-27 22:04:03 +00:00
return HelpLastCommand ( ) ;
return _CmdMemorySearch ( nArgs , false ) ;
}
//===========================================================================
Update_t CmdMemorySearchHex ( int nArgs )
{
2006-06-29 05:41:04 +00:00
if ( nArgs < 4 )
2006-06-27 22:04:03 +00:00
return HelpLastCommand ( ) ;
return _CmdMemorySearch ( nArgs , true ) ;
}
// Registers ______________________________________________________________________________________
//===========================================================================
Update_t CmdRegisterSet ( int nArgs )
{
if ( ( nArgs = = 2 ) & &
( g_aArgs [ 1 ] . sArg [ 0 ] = = TEXT ( ' P ' ) ) & & ( g_aArgs [ 2 ] . sArg [ 0 ] = = TEXT ( ' L ' ) ) ) //HACK: TODO/FIXME: undocumented hard-coded command?!?!
{
regs . pc = lastpc ;
}
else
if ( nArgs < 2 ) // || ((g_aArgs[2].sArg[0] != TEXT('0')) && !g_aArgs[2].nValue))
{
2006-07-01 06:45:50 +00:00
return Help_Arg_1 ( CMD_REGISTER_SET ) ;
2006-06-27 22:04:03 +00:00
}
else
{
TCHAR * pName = g_aArgs [ 1 ] . sArg ;
int iParam ;
if ( FindParam ( pName , MATCH_EXACT , iParam , _PARAM_REGS_BEGIN , _PARAM_REGS_END ) )
{
int iArg = 2 ;
if ( g_aArgs [ iArg ] . eToken = = TOKEN_EQUAL )
iArg + + ;
if ( iArg > nArgs )
return Help_Arg_1 ( CMD_REGISTER_SET ) ;
BYTE b = ( BYTE ) ( g_aArgs [ iArg ] . nValue & 0xFF ) ;
WORD w = ( WORD ) ( g_aArgs [ iArg ] . nValue & 0xFFFF ) ;
switch ( iParam )
{
case PARAM_REG_A : regs . a = b ; break ;
case PARAM_REG_PC : regs . pc = w ; g_nDisasmCurAddress = regs . pc ; DisasmCalcTopBotAddress ( ) ; break ;
case PARAM_REG_SP : regs . sp = b | 0x100 ; break ;
case PARAM_REG_X : regs . x = b ; break ;
case PARAM_REG_Y : regs . y = b ; break ;
default : return Help_Arg_1 ( CMD_REGISTER_SET ) ;
}
}
}
// g_nDisasmCurAddress = regs.pc;
// DisasmCalcTopBotAddress();
return UPDATE_ALL ; // 1
}
// Output _________________________________________________________________________________________
//===========================================================================
Update_t CmdOutputCalc ( int nArgs )
{
const int nBits = 8 ;
if ( ! nArgs )
return Help_Arg_1 ( CMD_OUTPUT_CALC ) ;
WORD nAddress = g_aArgs [ 1 ] . nValue ;
TCHAR sText [ CONSOLE_WIDTH ] ;
bool bHi = false ;
bool bLo = false ;
char c = FormatChar4Font ( ( BYTE ) nAddress , & bHi , & bLo ) ;
bool bParen = bHi | | bLo ;
int nBit = 0 ;
int iBit = 0 ;
for ( iBit = 0 ; iBit < nBits ; iBit + + )
{
bool bSet = ( nAddress > > iBit ) & 1 ;
if ( bSet )
nBit | = ( 1 < < ( iBit * 4 ) ) ; // 4 bits per hex digit
}
wsprintf ( sText , TEXT ( " $%04X 0z%08X %5d '%c' " ) ,
nAddress , nBit , nAddress , c ) ;
if ( bParen )
_tcscat ( sText , TEXT ( " ( " ) ) ;
if ( bHi & bLo )
_tcscat ( sText , TEXT ( " High Ctrl " ) ) ;
else
if ( bHi )
_tcscat ( sText , TEXT ( " High " ) ) ;
else
if ( bLo )
_tcscat ( sText , TEXT ( " Ctrl " ) ) ;
if ( bParen )
_tcscat ( sText , TEXT ( " ) " ) ) ;
2006-05-10 22:00:27 +00:00
2006-06-27 22:04:03 +00:00
ConsoleBufferPush ( sText ) ;
return ConsoleUpdate ( ) ;
2006-02-25 20:50:29 +00:00
}
2006-05-10 22:00:27 +00:00
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-06-27 22:04:03 +00:00
Update_t CmdOutputEcho ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-06-27 22:04:03 +00:00
TCHAR sText [ CONSOLE_WIDTH ] = TEXT ( " " ) ;
2006-05-10 22:00:27 +00:00
2006-06-27 22:04:03 +00:00
if ( g_aArgs [ 1 ] . bType & TYPE_QUOTED_2 )
{
ConsoleDisplayPush ( g_aArgs [ 1 ] . sArg ) ;
}
else
{
2006-07-07 19:30:39 +00:00
const char * pText = g_pConsoleFirstArg ; // ConsoleInputPeek();
2006-06-27 22:04:03 +00:00
if ( pText )
{
ConsoleDisplayPush ( pText ) ;
}
}
2006-02-26 06:26:56 +00:00
2006-06-27 22:04:03 +00:00
return ConsoleUpdate ( ) ;
2006-02-25 20:50:29 +00:00
}
2006-06-27 22:04:03 +00:00
enum PrintState_e
{ PS_LITERAL
, PS_TYPE
, PS_ESCAPE
, PS_NEXT_ARG_BIN
, PS_NEXT_ARG_HEX
, PS_NEXT_ARG_DEC
, PS_NEXT_ARG_CHR
} ;
struct PrintFormat_t
2006-05-10 22:00:27 +00:00
{
2006-06-27 22:04:03 +00:00
int nValue ;
int eType ;
} ;
2006-05-10 22:00:27 +00:00
//===========================================================================
2006-06-27 22:04:03 +00:00
Update_t CmdOutputPrint ( int nArgs )
2006-05-10 22:00:27 +00:00
{
2006-06-27 22:04:03 +00:00
// PRINT "A:",A," X:",X
// Removed: PRINT "A:%d",A," X: %d",X
TCHAR sText [ CONSOLE_WIDTH ] = TEXT ( " " ) ;
int nLen = 0 ;
2006-05-10 22:00:27 +00:00
2006-06-27 22:04:03 +00:00
int nValue ;
if ( ! nArgs )
goto _Help ;
int iArg ;
for ( iArg = 1 ; iArg < = nArgs ; iArg + + )
{
if ( g_aArgs [ iArg ] . bType & TYPE_QUOTED_2 )
{
int iChar ;
int nChar = _tcslen ( g_aArgs [ iArg ] . sArg ) ;
for ( iChar = 0 ; iChar < nChar ; iChar + + )
{
TCHAR c = g_aArgs [ iArg ] . sArg [ iChar ] ;
sText [ nLen + + ] = c ;
}
iArg + + ;
2006-07-01 06:45:50 +00:00
// if (iArg > nArgs)
// goto _Help;
2006-06-27 22:04:03 +00:00
if ( iArg < = nArgs )
if ( g_aArgs [ iArg ] . eToken ! = TOKEN_COMMA )
goto _Help ;
}
else
{
nValue = g_aArgs [ iArg ] . nValue ;
sprintf ( & sText [ nLen ] , " %04X " , nValue ) ;
while ( sText [ nLen ] )
nLen + + ;
iArg + + ;
if ( iArg < = nArgs )
if ( g_aArgs [ iArg ] . eToken ! = TOKEN_COMMA )
goto _Help ;
}
#if 0
sprintf ( & sText [ nLen ] , " %04X " , nValue ) ;
sprintf ( & sText [ nLen ] , " %d " , nValue ) ;
sprintf ( & sText [ nLen ] , " %c " , nValue ) ;
# endif
}
if ( nLen )
ConsoleBufferPush ( sText ) ;
return ConsoleUpdate ( ) ;
_Help :
return Help_Arg_1 ( CMD_OUTPUT_PRINT ) ;
2006-05-10 22:00:27 +00:00
}
2006-06-27 22:04:03 +00:00
2006-05-10 22:00:27 +00:00
//===========================================================================
2006-06-27 22:04:03 +00:00
Update_t CmdOutputPrintf ( int nArgs )
2006-05-10 22:00:27 +00:00
{
2006-06-27 22:04:03 +00:00
// PRINTF "A:%d X:%d",A,X
// PRINTF "Hex:%x Dec:%d Bin:%z",A,A,A
2006-05-10 22:00:27 +00:00
2006-06-27 22:04:03 +00:00
TCHAR sText [ CONSOLE_WIDTH ] = TEXT ( " " ) ;
2006-02-26 06:26:56 +00:00
2006-06-27 22:04:03 +00:00
// vector<PrintFormat_t> aValues;
// PrintFormat_t entry;
vector < Arg_t > aValues ;
Arg_t entry ;
int iValue = 0 ;
int nValue = 0 ;
2006-02-26 06:26:56 +00:00
2006-06-27 22:04:03 +00:00
if ( ! nArgs )
goto _Help ;
2006-02-25 20:50:29 +00:00
2006-06-27 22:04:03 +00:00
int nLen = 0 ;
2006-02-25 20:50:29 +00:00
2006-06-27 22:04:03 +00:00
PrintState_e eThis = PS_LITERAL ;
// PrintState_e eNext = PS_NEXT_ARG_HEX; // PS_LITERAL;
int nWidth = 0 ;
int iArg ;
for ( iArg = 1 ; iArg < = nArgs ; iArg + + )
2006-02-25 20:50:29 +00:00
{
2006-06-27 22:04:03 +00:00
if ( g_aArgs [ iArg ] . bType & TYPE_QUOTED_2 )
continue ;
else
if ( g_aArgs [ iArg ] . eToken = = TOKEN_COMMA )
continue ;
else
{
// entry.eType = PS_LITERAL;
entry . nValue = g_aArgs [ iArg ] . nValue ;
aValues . push_back ( entry ) ;
// nValue = g_aArgs[ iArg ].nValue;
// aValues.push_back( nValue );
}
2006-02-25 20:50:29 +00:00
}
2006-06-27 22:04:03 +00:00
const int nParamValues = ( int ) aValues . size ( ) ;
for ( iArg = 1 ; iArg < = nArgs ; iArg + + )
2006-02-25 20:50:29 +00:00
{
2006-06-27 22:04:03 +00:00
if ( g_aArgs [ iArg ] . bType & TYPE_QUOTED_2 )
2006-02-25 20:50:29 +00:00
{
2006-06-27 22:04:03 +00:00
int iChar ;
int nChar = _tcslen ( g_aArgs [ iArg ] . sArg ) ;
for ( iChar = 0 ; iChar < nChar ; iChar + + )
2006-02-25 20:50:29 +00:00
{
2006-06-27 22:04:03 +00:00
TCHAR c = g_aArgs [ iArg ] . sArg [ iChar ] ;
switch ( eThis )
{
case PS_LITERAL :
switch ( c )
{
case ' \\ ' :
eThis = PS_ESCAPE ;
case ' % ' :
eThis = PS_TYPE ;
break ;
default :
sText [ nLen + + ] = c ;
break ;
}
break ;
case PS_ESCAPE :
switch ( c )
{
case ' n ' :
case ' r ' :
eThis = PS_LITERAL ;
sText [ nLen + + ] = ' \n ' ;
break ;
}
break ;
case PS_TYPE :
if ( iValue > = nParamValues )
{
wsprintf ( sText , TEXT ( " Error: Missing value arg: %d " ) , iValue + 1 ) ;
ConsoleBufferPush ( sText ) ;
return ConsoleUpdate ( ) ;
}
switch ( c )
{
case ' X ' :
case ' x ' : // PS_NEXT_ARG_HEX
nValue = aValues [ iValue ] . nValue ;
sprintf ( & sText [ nLen ] , " %04X " , nValue ) ;
iValue + + ;
break ;
case ' D ' :
case ' d ' : // PS_NEXT_ARG_DEC
nValue = aValues [ iValue ] . nValue ;
sprintf ( & sText [ nLen ] , " %d " , nValue ) ;
iValue + + ;
break ;
break ;
case ' Z ' :
case ' z ' :
{
nValue = aValues [ iValue ] . nValue ;
if ( ! nWidth )
nWidth = 8 ;
int nBits = nWidth ;
while ( nBits - - > 0 )
{
if ( ( nValue > > nBits ) & 1 )
sText [ nLen + + ] = ' 1 ' ;
else
sText [ nLen + + ] = ' 0 ' ;
}
iValue + + ;
break ;
}
case ' c ' : // PS_NEXT_ARG_CHR;
nValue = aValues [ iValue ] . nValue ;
sprintf ( & sText [ nLen ] , " %c " , nValue ) ;
iValue + + ;
break ;
case ' % ' :
default :
sText [ nLen + + ] = c ;
break ;
}
while ( sText [ nLen ] )
nLen + + ;
eThis = PS_LITERAL ;
break ;
default :
break ;
}
2006-02-25 20:50:29 +00:00
}
}
2006-06-27 22:04:03 +00:00
else
if ( g_aArgs [ iArg ] . eToken = = TOKEN_COMMA )
{
iArg + + ;
if ( iArg > nArgs )
goto _Help ;
}
else
goto _Help ;
2006-02-25 20:50:29 +00:00
}
2006-06-27 22:04:03 +00:00
if ( nLen )
ConsoleBufferPush ( sText ) ;
return ConsoleUpdate ( ) ;
_Help :
return Help_Arg_1 ( CMD_OUTPUT_PRINTF ) ;
}
//===========================================================================
Update_t CmdOutputRun ( int nArgs )
{
if ( ! nArgs )
return Help_Arg_1 ( CMD_OUTPUT_RUN ) ;
if ( nArgs ! = 1 )
return Help_Arg_1 ( CMD_OUTPUT_RUN ) ;
2006-02-26 06:26:56 +00:00
2006-06-27 22:04:03 +00:00
// Read in script
// could be made global, to cache last run.
// Opens up the possibility of:
// CHEAT [ON | OFF] -> re-run script
// with conditional logic
// IF @ON ....
MemoryTextFile_t script ;
2006-02-25 20:50:29 +00:00
2006-06-27 22:04:03 +00:00
TCHAR * pFileName = g_aArgs [ 1 ] . sArg ;
TCHAR sFileName [ MAX_PATH ] ;
TCHAR sMiniFileName [ CONSOLE_WIDTH ] ;
// if (g_aArgs[1].bType & TYPE_QUOTED_2)
strcpy ( sMiniFileName , pFileName ) ;
// strcat( sMiniFileName, ".aws" ); // HACK: MAGIC STRING
_tcscpy ( sFileName , g_sCurrentDir ) ; //
_tcscat ( sFileName , sMiniFileName ) ;
if ( script . Read ( sFileName ) )
{
int iLine = 0 ;
int nLine = script . GetNumLines ( ) ;
Update_t bUpdateDisplay = UPDATE_NOTHING ;
for ( int iLine = 0 ; iLine < nLine ; iLine + + )
{
script . GetLine ( iLine , g_pConsoleInput , CONSOLE_WIDTH - 2 ) ;
g_nConsoleInputChars = strlen ( g_pConsoleInput ) ;
bUpdateDisplay | = DebuggerProcessCommand ( false ) ;
}
}
else
{
2006-07-09 04:53:08 +00:00
char sText [ CONSOLE_WIDTH ] ;
sprintf ( sText , " %sCouldn't load filename: %s%s "
, CHC_ERROR
, CHC_STRING
, sFileName
) ;
ConsolePrint ( sText ) ;
2006-06-27 22:04:03 +00:00
}
return ConsoleUpdate ( ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
// Source Level Debugging _________________________________________________________________________
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-08-16 18:58:56 +00:00
bool BufferAssemblyListing ( char * pFileName )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
bool bStatus = false ; // true = loaded
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( ! pFileName )
return bStatus ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
g_AssemblerSourceBuffer . Reset ( ) ;
g_AssemblerSourceBuffer . Read ( pFileName ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( g_AssemblerSourceBuffer . GetNumLines ( ) )
{
g_bSourceLevelDebugging = true ;
bStatus = true ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return bStatus ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
int FindSourceLine ( WORD nAddress )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
int iAddress = 0 ;
int iLine = 0 ;
int iSourceLine = NO_SOURCE_LINE ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// iterate of <address,line>
// probably should be sorted by address
// then can do binary search
// iSourceLine = g_aSourceDebug.find( nAddress );
#if 0 // _DEBUG
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
TCHAR sText [ CONSOLE_WIDTH ] ;
for ( int i = 0 ; i < g_vSourceLines . size ( ) ; i + + )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
wsprintf ( sText , " %d: %s \n " , i , g_vSourceLines [ i ] ) ;
OutputDebugString ( sText ) ;
2006-02-25 20:50:29 +00:00
}
}
2006-02-26 06:26:56 +00:00
# endif
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
SourceAssembly_t : : iterator iSource = g_aSourceDebug . begin ( ) ;
while ( iSource ! = g_aSourceDebug . end ( ) )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
iAddress = iSource - > first ;
iLine = iSource - > second ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
#if 0 // _DEBUG
TCHAR sText [ CONSOLE_WIDTH ] ;
wsprintf ( sText , " %04X -> %d line \n " , iAddress , iLine ) ;
OutputDebugString ( sText ) ;
# endif
if ( iAddress = = nAddress )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
iSourceLine = iLine ;
2006-02-25 20:50:29 +00:00
break ;
2006-02-26 06:26:56 +00:00
}
iSource + + ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
// not found
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return iSourceLine ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
bool ParseAssemblyListing ( bool bBytesToMemory , bool bAddSymbols )
{
bool bStatus = false ; // true = loaded
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// Assembler source listing file:
//
// xxxx:_b1_[b2]_[b3]__n_[label]_[opcode]_[param]
// char sByte1[ 2 ];
// char sByte2[ 2 ];
// char sByte3[ 2 ];
// char sLineN[ W ];
char sName [ MAX_SYMBOLS_LEN ] ;
// char sAsm [ W ];
// char sParam[ W ];
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
const int MAX_LINE = 256 ;
char sLine [ MAX_LINE ] ;
char sText [ MAX_LINE ] ;
// char sLabel[ MAX_LINE ];
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
g_nSourceAssembleBytes = 0 ;
g_nSourceAssemblySymbols = 0 ;
2006-02-25 20:50:29 +00:00
2006-06-25 03:43:49 +00:00
const DWORD INVALID_ADDRESS = _6502_MEM_END + 1 ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
bool bPrevSymbol = false ;
bool bFourBytes = false ;
BYTE nByte4 = 0 ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
int nLines = g_AssemblerSourceBuffer . GetNumLines ( ) ;
for ( int iLine = 0 ; iLine < nLines ; iLine + + )
{
g_AssemblerSourceBuffer . GetLine ( iLine , sText , MAX_LINE - 1 ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
DWORD nAddress = INVALID_ADDRESS ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
_tcscpy ( sLine , sText ) ;
char * p = sLine ;
p = strstr ( sLine , " : " ) ;
if ( p )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
* p = 0 ;
// sscanf( sLine, "%s %s %s %s %s %s %s %s", sAddr1, sByte1, sByte2, sByte3, sLineN, sLabel, sAsm, sParam );
sscanf ( sLine , " %X " , & nAddress ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( nAddress > = INVALID_ADDRESS ) // || (sName[0] == 0) )
continue ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( bBytesToMemory )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
char * pEnd = p + 1 ;
char * pStart ;
2006-02-28 16:37:25 +00:00
int iByte ;
for ( iByte = 0 ; iByte < 4 ; iByte + + ) // BUG: Some assemblers also put 4 bytes on a line
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
// xx xx xx
// ^ ^
// | |
// | end
// start
pStart = pEnd + 1 ;
pEnd = const_cast < char * > ( SkipUntilWhiteSpace ( pStart ) ) ;
int nLen = ( pEnd - pStart ) ;
if ( nLen ! = 2 )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
break ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
* pEnd = 0 ;
2006-02-28 16:37:25 +00:00
if ( TextIsHexByte ( pStart ) )
{
BYTE nByte = TextConvert2CharsToByte ( pStart ) ;
* ( mem + ( ( WORD ) nAddress ) + iByte ) = nByte ;
}
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
g_nSourceAssembleBytes + = iByte ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
g_aSourceDebug [ ( WORD ) nAddress ] = iLine ; // g_nSourceAssemblyLines;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
_tcscpy ( sLine , sText ) ;
if ( bAddSymbols )
{
// Add user symbol: symbolname EQU $address
// or user symbol: address: symbolname DFB #bytes
char * pEQU = strstr ( sLine , " EQU " ) ; // EQUal / EQUate
char * pDFB = strstr ( sLine , " DFB " ) ; // DeFine Byte
char * pLabel = NULL ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( pEQU )
pLabel = pEQU ;
if ( pDFB )
pLabel = pDFB ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( pLabel )
{
char * pLabelEnd = pLabel - 1 ;
pLabelEnd = const_cast < char * > ( SkipWhiteSpaceReverse ( pLabelEnd , & sLine [ 0 ] ) ) ;
char * pLabelStart = NULL ; // SkipWhiteSpaceReverse( pLabelEnd, &sLine[ 0 ] );
if ( pLabelEnd )
{
pLabelStart = const_cast < char * > ( SkipUntilWhiteSpaceReverse ( pLabelEnd , & sLine [ 0 ] ) ) ;
pLabelEnd + + ;
pLabelStart + + ;
int nLen = pLabelEnd - pLabelStart ;
nLen = MIN ( nLen , MAX_SYMBOLS_LEN ) ;
strncpy ( sName , pLabelStart , nLen ) ;
sName [ nLen ] = 0 ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
char * pAddressEQU = strstr ( pLabel , " $ " ) ;
char * pAddressDFB = strstr ( sLine , " : " ) ; // Get address from start of line
char * pAddress = NULL ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( pAddressEQU )
pAddress = pAddressEQU + 1 ;
if ( pAddressDFB )
{
* pAddressDFB = 0 ;
pAddress = sLine ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( pAddress )
{
char * pAddressEnd ;
nAddress = ( DWORD ) strtol ( pAddress , & pAddressEnd , 16 ) ;
g_aSymbols [ SYMBOLS_SRC ] [ ( WORD ) nAddress ] = sName ;
g_nSourceAssemblySymbols + + ;
}
}
}
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
} // for
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
bStatus = true ;
return bStatus ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdSource ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( ! nArgs )
{
g_bSourceLevelDebugging = false ;
}
else
{
g_bSourceAddMemory = false ;
g_bSourceAddSymbols = false ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
for ( int iArg = 1 ; iArg < = nArgs ; iArg + + )
{
TCHAR * pFileName = g_aArgs [ iArg ] . sArg ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
int iParam ;
bool bFound = FindParam ( pFileName , MATCH_EXACT , iParam , _PARAM_SOURCE_BEGIN , _PARAM_SOURCE_END ) > 0 ? true : false ;
if ( bFound & & ( iParam = = PARAM_SRC_SYMBOLS ) )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
g_bSourceAddSymbols = true ;
}
else
if ( bFound & & ( iParam = = PARAM_SRC_MEMORY ) )
{
g_bSourceAddMemory = true ;
}
else
{
TCHAR sFileName [ MAX_PATH ] ;
2006-06-25 03:43:49 +00:00
_tcscpy ( sFileName , g_sProgramDir ) ;
2006-02-26 06:26:56 +00:00
_tcscat ( sFileName , pFileName ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
const int MAX_MINI_FILENAME = 20 ;
TCHAR sMiniFileName [ MAX_MINI_FILENAME + 1 ] ;
_tcsncpy ( sMiniFileName , pFileName , MAX_MINI_FILENAME - 1 ) ;
sMiniFileName [ MAX_MINI_FILENAME ] = 0 ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( BufferAssemblyListing ( sFileName ) )
{
_tcscpy ( g_aSourceFileName , pFileName ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( ! ParseAssemblyListing ( g_bSourceAddMemory , g_bSourceAddSymbols ) )
{
wsprintf ( sFileName , " Couldn't load filename: %s " , sMiniFileName ) ;
ConsoleBufferPush ( sFileName ) ;
}
else
{
TCHAR sText [ CONSOLE_WIDTH ] ;
wsprintf ( sFileName , " Read: %d lines, %d symbols "
, g_AssemblerSourceBuffer . GetNumLines ( ) // g_nSourceAssemblyLines
, g_nSourceAssemblySymbols ) ;
if ( g_nSourceAssembleBytes )
{
wsprintf ( sText , " , %d bytes " , g_nSourceAssembleBytes ) ;
_tcscat ( sFileName , sText ) ;
}
ConsoleBufferPush ( sFileName ) ;
}
}
else
{
wsprintf ( sFileName , " Error reading: %s " , sMiniFileName ) ;
ConsoleBufferPush ( sFileName ) ;
}
2006-02-25 20:50:29 +00:00
}
}
2006-02-26 06:26:56 +00:00
return ConsoleUpdate ( ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
return UPDATE_CONSOLE_DISPLAY ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdSync ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
// TODO
return UPDATE_CONSOLE_DISPLAY ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// Stack __________________________________________________________________________________________
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdStackPush ( int nArgs )
2006-02-25 20:50:29 +00:00
{
return UPDATE_CONSOLE_DISPLAY ;
}
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdStackPop ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
return UPDATE_CONSOLE_DISPLAY ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdStackPopPseudo ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
return UPDATE_CONSOLE_DISPLAY ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
// Symbols ________________________________________________________________________________________
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdSymbols ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( ! nArgs )
return CmdSymbolsInfo ( 0 ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
Update_t iUpdate = _CmdSymbolsUpdate ( nArgs ) ;
if ( iUpdate ! = UPDATE_NOTHING )
return iUpdate ;
// return CmdSymbolsList( nArgs );
int bSymbolTables = SYMBOL_TABLE_MAIN | SYMBOL_TABLE_USER | SYMBOL_TABLE_SRC ;
return _CmdSymbolsListTables ( nArgs , bSymbolTables ) ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdSymbolsClear ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
Symbols_e eSymbolsTable = SYMBOLS_USER ;
_CmdSymbolsClear ( eSymbolsTable ) ;
return ( UPDATE_DISASM | UPDATE_SYMBOLS ) ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdSymbolsInfo ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-07-09 04:53:08 +00:00
char sText [ CONSOLE_WIDTH ] ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
bool bDisplayMain = false ;
bool bDisplayUser = false ;
bool bDisplaySrc = false ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( ! nArgs )
{
bDisplayMain = true ;
bDisplayUser = true ;
bDisplaySrc = true ;
}
else
if ( CMD_SYMBOLS_MAIN = = g_iCommand )
bDisplayMain = true ;
else
if ( CMD_SYMBOLS_USER = = g_iCommand )
bDisplayUser = true ;
else
if ( CMD_SYMBOLS_SRC = = g_iCommand )
bDisplaySrc = true ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
int nSymbolsMain = g_aSymbols [ SYMBOLS_MAIN ] . size ( ) ;
int nSymbolsUser = g_aSymbols [ SYMBOLS_USER ] . size ( ) ;
int nSymbolsSrc = g_aSymbols [ SYMBOLS_SRC ] . size ( ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( bDisplayMain & & bDisplayUser & & bDisplaySrc )
2006-02-25 20:50:29 +00:00
{
2006-07-09 04:53:08 +00:00
sprintf ( sText , " Symbols Main: %s%d%s User: %s%d%s Source: %s%d%s "
2006-08-16 18:58:56 +00:00
, CHC_NUM_DEC
2006-07-09 04:53:08 +00:00
, nSymbolsMain
, CHC_DEFAULT
2006-08-16 18:58:56 +00:00
, CHC_NUM_DEC
2006-07-09 04:53:08 +00:00
, nSymbolsUser
, CHC_DEFAULT
2006-08-16 18:58:56 +00:00
, CHC_NUM_DEC
2006-07-09 04:53:08 +00:00
, nSymbolsSrc
, CHC_DEFAULT
) ;
ConsolePrint ( sText ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
else
if ( bDisplayMain )
2006-02-25 20:50:29 +00:00
{
2006-07-09 04:53:08 +00:00
sprintf ( sText , " Main symbols: %s%d%s "
2006-08-16 18:58:56 +00:00
, CHC_NUM_DEC
2006-07-09 04:53:08 +00:00
, nSymbolsMain
, CHC_DEFAULT
) ;
ConsolePrint ( sText ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
else
if ( bDisplayUser )
2006-02-25 20:50:29 +00:00
{
2006-07-09 04:53:08 +00:00
sprintf ( sText , " User symbols: %s%d%s "
2006-08-16 18:58:56 +00:00
, CHC_NUM_DEC
2006-07-09 04:53:08 +00:00
, nSymbolsUser
, CHC_DEFAULT
) ;
ConsolePrint ( sText ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
else
if ( bDisplaySrc )
2006-02-25 20:50:29 +00:00
{
2006-07-09 04:53:08 +00:00
sprintf ( sText , " Source symbols: %s%d%s "
2006-08-16 18:58:56 +00:00
, CHC_NUM_DEC
2006-07-09 04:53:08 +00:00
, nSymbolsSrc
, CHC_DEFAULT
) ;
ConsolePrint ( sText ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
if ( bDisplayMain | | bDisplayUser | | bDisplaySrc )
return ConsoleUpdate ( ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return UPDATE_CONSOLE_DISPLAY ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
void _CmdPrintSymbol ( LPCTSTR pSymbol , WORD nAddress , int iTable )
2006-02-25 20:50:29 +00:00
{
2006-07-09 04:53:08 +00:00
char sText [ CONSOLE_WIDTH ] ;
sprintf ( sText , " %s$%s%04X%s (%s%s%s) %s%s "
, CHC_ARG_SEP
, CHC_ADDRESS
, nAddress
, CHC_DEFAULT
2006-08-16 18:58:56 +00:00
, CHC_STRING
2006-07-09 04:53:08 +00:00
, g_aSymbolTableNames [ iTable ]
, CHC_DEFAULT
, CHC_SYMBOL
, pSymbol ) ;
// ConsoleBufferPush( sText );
ConsolePrint ( sText ) ;
2006-02-26 06:26:56 +00:00
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//=========================================================================== */
bool _FindSymbolTable ( int bSymbolTables , int iTable )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
// iTable is enumeration
// bSymbolTables is bit-flags of enabled tables to search
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( bSymbolTables & SYMBOL_TABLE_MAIN )
if ( iTable = = SYMBOLS_MAIN )
return true ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( bSymbolTables & SYMBOL_TABLE_USER )
if ( iTable = = SYMBOLS_USER )
return true ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( bSymbolTables & SYMBOL_TABLE_SRC )
if ( iTable = = SYMBOLS_SRC )
return true ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return false ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
//=========================================================================== */
int _GetSymbolTableFromFlag ( int bSymbolTables )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
int iTable = NUM_SYMBOL_TABLES ;
if ( bSymbolTables & SYMBOL_TABLE_MAIN )
iTable = SYMBOLS_MAIN ;
else
if ( bSymbolTables & SYMBOL_TABLE_USER )
iTable = SYMBOLS_USER ;
else
if ( bSymbolTables & SYMBOL_TABLE_SRC )
iTable = SYMBOLS_SRC ;
return iTable ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
/**
@ param bSymbolTables Bit Flags of which symbol tables to search
//=========================================================================== */
bool _CmdSymbolList_Address2Symbol ( int nAddress , int bSymbolTables )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
int iTable ;
LPCTSTR pSymbol = FindSymbolFromAddress ( nAddress , & iTable ) ;
if ( pSymbol )
{
if ( _FindSymbolTable ( bSymbolTables , iTable ) )
{
_CmdPrintSymbol ( pSymbol , nAddress , iTable ) ;
return true ;
}
}
return false ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
bool _CmdSymbolList_Symbol2Address ( LPCTSTR pSymbol , int bSymbolTables )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
int iTable ;
WORD nAddress ;
bool bFoundSymbol = FindAddressFromSymbol ( pSymbol , & nAddress , & iTable ) ;
if ( bFoundSymbol )
{
if ( _FindSymbolTable ( bSymbolTables , iTable ) )
{
_CmdPrintSymbol ( pSymbol , nAddress , iTable ) ;
}
}
return bFoundSymbol ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
bool String2Address ( LPCTSTR pText , WORD & nAddress_ )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
TCHAR sHexApple [ CONSOLE_WIDTH ] ;
2006-02-25 20:50:29 +00:00
2006-07-09 04:53:08 +00:00
if ( pText [ 0 ] = = ' $ ' )
2006-02-26 06:26:56 +00:00
{
2006-02-28 16:37:25 +00:00
if ( ! TextIsHexString ( pText + 1 ) )
2006-02-26 06:26:56 +00:00
return false ;
2006-02-25 20:50:29 +00:00
2006-07-09 04:53:08 +00:00
_tcscpy ( sHexApple , " 0x " ) ;
2006-02-26 06:26:56 +00:00
_tcsncpy ( sHexApple + 2 , pText + 1 , MAX_SYMBOLS_LEN - 3 ) ;
pText = sHexApple ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( pText [ 0 ] = = TEXT ( ' 0 ' ) )
{
if ( ( pText [ 1 ] = = TEXT ( ' X ' ) ) | | pText [ 1 ] = = TEXT ( ' x ' ) )
{
2006-02-28 16:37:25 +00:00
if ( ! TextIsHexString ( pText + 2 ) )
2006-02-26 06:26:56 +00:00
return false ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
TCHAR * pEnd ;
nAddress_ = ( WORD ) _tcstol ( pText , & pEnd , 16 ) ;
return true ;
}
2006-02-28 16:37:25 +00:00
if ( TextIsHexString ( pText ) )
2006-02-26 06:26:56 +00:00
{
TCHAR * pEnd ;
nAddress_ = ( WORD ) _tcstol ( pText , & pEnd , 16 ) ;
return true ;
}
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return false ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// LIST is normally an implicit "LIST *", but due to the numbers of symbols
// only look up symbols the user specifies
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdSymbolsList ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
int bSymbolTables = SYMBOL_TABLE_MAIN | SYMBOL_TABLE_USER | SYMBOL_TABLE_SRC ;
return _CmdSymbolsListTables ( nArgs , bSymbolTables ) ;
}
//===========================================================================
Update_t _CmdSymbolsListTables ( int nArgs , int bSymbolTables )
{
if ( ! nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
return Help_Arg_1 ( CMD_SYMBOLS_LIST ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
/*
Test Cases
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
SYM 0 RESET FA6F $ FA59
$ 0000 LOC0
$ FA6F RESET
$ FA6F INITAN
$ FA59 OLDBRK
SYM B
SYMBOL B = $ 2000
SYM B
*/
TCHAR sText [ CONSOLE_WIDTH ] ;
for ( int iArgs = 1 ; iArgs < = nArgs ; iArgs + + )
{
2006-06-27 02:33:40 +00:00
WORD nAddress = g_aArgs [ iArgs ] . nValue ;
2006-02-26 06:26:56 +00:00
LPCTSTR pSymbol = g_aArgs [ iArgs ] . sArg ;
if ( nAddress )
{ // Have address, do symbol lookup first
if ( ! _CmdSymbolList_Symbol2Address ( pSymbol , bSymbolTables ) )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
// nope, ok, try as address
if ( ! _CmdSymbolList_Address2Symbol ( nAddress , bSymbolTables ) )
{
wsprintf ( sText , TEXT ( " Address not found: %04X " ) , nAddress ) ;
ConsoleBufferPush ( sText ) ;
}
}
}
else
{ // Have symbol, do address lookup
if ( ! _CmdSymbolList_Symbol2Address ( pSymbol , bSymbolTables ) )
{ // nope, ok, try as address
if ( String2Address ( pSymbol , nAddress ) )
{
if ( ! _CmdSymbolList_Address2Symbol ( nAddress , bSymbolTables ) )
{
wsprintf ( sText , TEXT ( " Symbol not found: %s " ) , pSymbol ) ;
ConsoleBufferPush ( sText ) ;
}
}
else
{
wsprintf ( sText , TEXT ( " Symbol not found: %s " ) , pSymbol ) ;
ConsoleBufferPush ( sText ) ;
}
2006-02-25 20:50:29 +00:00
}
}
}
2006-02-26 06:26:56 +00:00
return ConsoleUpdate ( ) ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
int ParseSymbolTable ( TCHAR * pFileName , Symbols_e eWhichTableToLoad )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
int nSymbolsLoaded = 0 ;
2006-02-25 20:50:29 +00:00
if ( ! pFileName )
2006-02-26 06:26:56 +00:00
return nSymbolsLoaded ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//#if _UNICODE
// TCHAR sFormat1[ MAX_SYMBOLS_LEN ];
// TCHAR sFormat2[ MAX_SYMBOLS_LEN ];
// wsprintf( sFormat1, "%%x %%%ds", MAX_SYMBOLS_LEN ); // i.e. "%x %13s"
// wsprintf( sFormat2, "%%%ds %%x", MAX_SYMBOLS_LEN ); // i.e. "%13s %x"
// ascii
char sFormat1 [ MAX_SYMBOLS_LEN ] ;
char sFormat2 [ MAX_SYMBOLS_LEN ] ;
sprintf ( sFormat1 , " %%x %%%ds " , MAX_SYMBOLS_LEN ) ; // i.e. "%x %13s"
sprintf ( sFormat2 , " %%%ds %%x " , MAX_SYMBOLS_LEN ) ; // i.e. "%13s %x"
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
FILE * hFile = fopen ( pFileName , " rt " ) ;
while ( hFile & & ! feof ( hFile ) )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
// Support 2 types of symbols files:
// 1) AppleWin:
// . 0000 SYMBOL
// . FFFF SYMBOL
// 2) ACME:
// . SYMBOL =$0000; Comment
// . SYMBOL =$FFFF; Comment
//
DWORD INVALID_ADDRESS = 0xFFFF + 1 ;
DWORD nAddress = INVALID_ADDRESS ;
char sName [ MAX_SYMBOLS_LEN + 1 ] = " " ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
const int MAX_LINE = 256 ;
char szLine [ MAX_LINE ] ;
fgets ( szLine , MAX_LINE - 1 , hFile ) ; // Get next line
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( strstr ( szLine , " $ " ) = = NULL )
{
sscanf ( szLine , sFormat1 , & nAddress , sName ) ;
}
else
{
char * p = strstr ( szLine , " = " ) ; // Optional
if ( p ) * p = ' ' ;
p = strstr ( szLine , " $ " ) ;
if ( p ) * p = ' ' ;
p = strstr ( szLine , " ; " ) ; // Optional
if ( p ) * p = 0 ;
p = strstr ( szLine , " " ) ; // 1st space between name & value
int nLen = p - szLine ;
if ( nLen > MAX_SYMBOLS_LEN )
memset ( & szLine [ MAX_SYMBOLS_LEN ] , ' ' , nLen - MAX_SYMBOLS_LEN ) ; // sscanf fails for nAddress if string too long
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
sscanf ( szLine , sFormat2 , sName , & nAddress ) ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( ( nAddress > = INVALID_ADDRESS ) | | ( sName [ 0 ] = = 0 ) )
continue ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
g_aSymbols [ eWhichTableToLoad ] [ ( WORD ) nAddress ] = sName ;
nSymbolsLoaded + + ;
2006-02-25 20:50:29 +00:00
}
2006-07-09 04:53:08 +00:00
if ( hFile )
2006-02-26 06:26:56 +00:00
fclose ( hFile ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return nSymbolsLoaded ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdSymbolsLoad ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
TCHAR sFileName [ MAX_PATH ] ;
2006-06-25 03:43:49 +00:00
_tcscpy ( sFileName , g_sProgramDir ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
int iWhichTable = ( g_iCommand - CMD_SYMBOLS_MAIN ) ;
if ( ( iWhichTable < 0 ) | | ( iWhichTable > = NUM_SYMBOL_TABLES ) )
{
wsprintf ( sFileName , " Only %d symbol tables supported! " , NUM_SYMBOL_TABLES ) ;
return ConsoleDisplayError ( sFileName ) ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( ! nArgs )
{
// Default to main table
if ( g_iCommand = = CMD_SYMBOLS_MAIN )
2006-07-01 06:45:50 +00:00
_tcscat ( sFileName , g_sFileNameSymbolsMain ) ;
2006-02-26 06:26:56 +00:00
else
{
2006-07-01 06:45:50 +00:00
if ( ! _tcslen ( g_sFileNameSymbolsUser ) )
2006-02-26 06:26:56 +00:00
{
return ConsoleDisplayError ( TEXT ( " No user symbol file to reload. " ) ) ;
}
// load user symbols
2006-07-01 06:45:50 +00:00
_tcscat ( sFileName , g_sFileNameSymbolsUser ) ;
2006-02-26 06:26:56 +00:00
}
g_nSymbolsLoaded = ParseSymbolTable ( sFileName , ( Symbols_e ) iWhichTable ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return ( UPDATE_DISASM | | UPDATE_SYMBOLS ) ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
int iArg = 0 ;
while ( iArg + + < = nArgs )
{
TCHAR * pFileName = g_aArgs [ iArg ] . sArg ;
2006-02-25 20:50:29 +00:00
2006-06-25 03:43:49 +00:00
_tcscpy ( sFileName , g_sProgramDir ) ;
2006-02-26 06:26:56 +00:00
_tcscat ( sFileName , pFileName ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// Remember File ame of symbols loaded
2006-07-01 06:45:50 +00:00
_tcscpy ( g_sFileNameSymbolsUser , pFileName ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
g_nSymbolsLoaded = ParseSymbolTable ( sFileName , ( Symbols_e ) iWhichTable ) ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return ( UPDATE_DISASM | | UPDATE_SYMBOLS ) ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
bool FindAddressFromSymbol ( LPCTSTR pSymbol , WORD * pAddress_ , int * iTable_ )
{
// Bugfix/User feature: User symbols should be searched first
for ( int iTable = NUM_SYMBOL_TABLES ; iTable - - > 0 ; )
{
if ( ! g_aSymbols [ iTable ] . size ( ) )
continue ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// map<WORD, string>::iterator iSymbol = g_aSymbols[iTable].begin();
SymbolTable_t : : iterator iSymbol = g_aSymbols [ iTable ] . begin ( ) ;
while ( iSymbol ! = g_aSymbols [ iTable ] . end ( ) )
{
if ( ! _tcsicmp ( iSymbol - > second . c_str ( ) , pSymbol ) )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( pAddress_ )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
* pAddress_ = iSymbol - > first ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
if ( iTable_ )
{
* iTable_ = iTable ;
}
return true ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
iSymbol + + ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
}
return false ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
LPCTSTR FindSymbolFromAddress ( WORD nAddress , int * iTable_ )
{
// Bugfix/User feature: User symbols should be searched first
int iTable = NUM_SYMBOL_TABLES ;
while ( iTable - - > 0 )
{
if ( g_aSymbols [ iTable ] . size ( ) )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
map < WORD , string > : : iterator iSymbols = g_aSymbols [ iTable ] . find ( nAddress ) ;
if ( g_aSymbols [ iTable ] . find ( nAddress ) ! = g_aSymbols [ iTable ] . end ( ) )
{
if ( iTable_ )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
* iTable_ = iTable ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
return iSymbols - > second . c_str ( ) ;
2006-02-25 20:50:29 +00:00
}
}
2006-02-26 06:26:56 +00:00
}
return NULL ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
WORD GetAddressFromSymbol ( LPCTSTR pSymbol )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
WORD nAddress ;
bool bFoundSymbol = FindAddressFromSymbol ( pSymbol , & nAddress ) ;
if ( ! bFoundSymbol )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
nAddress = 0 ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
return nAddress ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
Update_t _CmdSymbolsClear ( Symbols_e eSymbolTable )
{
g_aSymbols [ eSymbolTable ] . clear ( ) ;
return UPDATE_SYMBOLS ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
void SymbolUpdate ( Symbols_e eSymbolTable , char * pSymbolName , WORD nAddress , bool bRemoveSymbol , bool bUpdateSymbol )
{
if ( bRemoveSymbol )
pSymbolName = g_aArgs [ 2 ] . sArg ;
if ( _tcslen ( pSymbolName ) < MAX_SYMBOLS_LEN )
{
WORD nAddressPrev ;
int iTable ;
bool bExists = FindAddressFromSymbol ( pSymbolName , & nAddressPrev , & iTable ) ;
if ( bExists )
{
if ( iTable = = eSymbolTable )
{
if ( bRemoveSymbol )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
ConsoleBufferPush ( TEXT ( " Removing symbol. " ) ) ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
g_aSymbols [ eSymbolTable ] . erase ( nAddressPrev ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( bUpdateSymbol )
{
ConsoleBufferPush ( TEXT ( " Updating symbol to new address. " ) ) ;
2006-02-25 20:50:29 +00:00
}
}
2006-02-26 06:26:56 +00:00
}
else
{
if ( bRemoveSymbol )
{
ConsoleBufferPush ( TEXT ( " Symbol not in table. " ) ) ;
}
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
if ( bUpdateSymbol )
{
# if _DEBUG
LPCTSTR pSymbol = FindSymbolFromAddress ( nAddress , & iTable ) ;
{
// Found another symbol for this address. Harmless.
// TODO: Probably should check if same name?
}
# endif
g_aSymbols [ eSymbolTable ] [ nAddress ] = pSymbolName ;
}
}
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t _CmdSymbolsUpdate ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
bool bRemoveSymbol = false ;
bool bUpdateSymbol = false ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( ( nArgs = = 2 ) & & ( g_aArgs [ 1 ] . eToken = = TOKEN_EXCLAMATION ) )
bRemoveSymbol = true ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( ( nArgs = = 3 ) & & ( g_aArgs [ 2 ] . eToken = = TOKEN_EQUAL ) )
bUpdateSymbol = true ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( bRemoveSymbol | | bUpdateSymbol )
{
TCHAR * pSymbolName = g_aArgs [ 1 ] . sArg ;
2006-06-27 02:33:40 +00:00
WORD nAddress = g_aArgs [ 3 ] . nValue ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
SymbolUpdate ( SYMBOLS_USER , pSymbolName , nAddress , bRemoveSymbol , bUpdateSymbol ) ;
return ConsoleUpdate ( ) ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return UPDATE_NOTHING ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t _CmdSymbolsCommon ( int nArgs , int bSymbolTables )
2006-02-25 20:50:29 +00:00
{
if ( ! nArgs )
2006-02-26 06:26:56 +00:00
{
return Help_Arg_1 ( g_iCommand ) ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
Update_t iUpdate = _CmdSymbolsUpdate ( nArgs ) ;
2006-02-25 20:50:29 +00:00
if ( iUpdate ! = UPDATE_NOTHING )
return iUpdate ;
TCHAR sText [ CONSOLE_WIDTH ] ;
2006-02-26 06:26:56 +00:00
int iArg = 0 ;
while ( iArg + + < = nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
int iParam ;
int nParams = FindParam ( g_aArgs [ iArg ] . sArg , MATCH_EXACT , iParam ) ; // MATCH_FUZZY
if ( nParams )
{
if ( iParam = = PARAM_CLEAR )
{
int iTable = _GetSymbolTableFromFlag ( bSymbolTables ) ;
if ( iTable ! = NUM_SYMBOL_TABLES )
{
Update_t iUpdate = _CmdSymbolsClear ( ( Symbols_e ) iTable ) ;
wsprintf ( sText , TEXT ( " Cleared symbol table: %s " ) ,
g_aSymbolTableNames [ iTable ]
) ;
ConsoleBufferPush ( sText ) ;
iUpdate | = ConsoleUpdate ( ) ;
return iUpdate ;
}
else
{
ConsoleBufferPush ( TEXT ( " Error: Unknown Symbol Table Type " ) ) ;
return ConsoleUpdate ( ) ;
}
// if (bSymbolTable & SYMBOL_TABLE_MAIN)
// return _CmdSymbolsClear( SYMBOLS_MAIN );
// else
// if (bSymbolsTable & SYMBOL_TABLE_USER)
// return _CmdSymbolsClear( SYMBOLS_USER );
// else
// Shouldn't have multiple symbol tables selected
// nArgs = _Arg_1( eSymbolsTable );
}
else
if ( iParam = = PARAM_LOAD )
{
nArgs = _Arg_Shift ( iArg , nArgs ) ;
CmdSymbolsLoad ( nArgs ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
int iTable = _GetSymbolTableFromFlag ( bSymbolTables ) ;
if ( iTable ! = NUM_SYMBOL_TABLES )
{
wsprintf ( sText , " Symbol Table: %s, loaded symbols: %d " ,
g_aSymbolTableNames [ iTable ] , g_nSymbolsLoaded ) ;
ConsoleBufferPush ( sText ) ;
}
else
{
ConsoleBufferPush ( TEXT ( " Error: Unknown Symbol Table Type " ) ) ;
}
return ConsoleUpdate ( ) ;
}
else
if ( iParam = = PARAM_SAVE )
{
nArgs = _Arg_Shift ( iArg , nArgs ) ;
return CmdSymbolsSave ( nArgs ) ;
}
}
else
{
return _CmdSymbolsListTables ( nArgs , bSymbolTables ) ;
}
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
return ConsoleUpdate ( ) ;
}
//===========================================================================
Update_t CmdSymbolsMain ( int nArgs )
{
if ( ! nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
return CmdSymbolsInfo ( nArgs ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
return _CmdSymbolsCommon ( nArgs , SYMBOL_TABLE_MAIN ) ; // SYMBOLS_MAIN );
}
//===========================================================================
Update_t CmdSymbolsUser ( int nArgs )
{
if ( ! nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
return CmdSymbolsInfo ( nArgs ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
return _CmdSymbolsCommon ( nArgs , SYMBOL_TABLE_USER ) ; // SYMBOLS_USER );
}
//===========================================================================
Update_t CmdSymbolsSource ( int nArgs )
{
if ( ! nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
return CmdSymbolsInfo ( nArgs ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
return _CmdSymbolsCommon ( nArgs , SYMBOL_TABLE_SRC ) ; // SYMBOLS_SRC );
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
//===========================================================================
LPCTSTR GetSymbol ( WORD nAddress , int nBytes )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
LPCSTR pSymbol = FindSymbolFromAddress ( nAddress ) ;
if ( pSymbol )
return pSymbol ;
return FormatAddress ( nAddress , nBytes ) ;
}
//===========================================================================
Update_t CmdSymbolsSave ( int nArgs )
{
return UPDATE_CONSOLE_DISPLAY ;
2006-02-25 20:50:29 +00:00
}
2006-07-01 06:45:50 +00:00
// Watches ________________________________________________________________________________________
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-07-01 06:45:50 +00:00
Update_t CmdWatch ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
return CmdWatchAdd ( nArgs ) ;
2006-02-26 06:26:56 +00:00
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
Update_t CmdWatchAdd ( int nArgs )
{
2006-07-01 06:45:50 +00:00
// WA [adddress]
// WA # address
if ( ! nArgs )
2006-02-26 06:26:56 +00:00
{
2006-06-27 22:04:03 +00:00
return CmdWatchList ( 0 ) ;
}
2006-07-01 06:45:50 +00:00
int iArg = 1 ;
int iWatch = NO_6502_TARGET ;
if ( nArgs > 1 )
2006-06-27 22:04:03 +00:00
{
2006-07-01 06:45:50 +00:00
iWatch = g_aArgs [ 1 ] . nValue ;
iArg + + ;
}
bool bAdded = false ;
for ( ; iArg < = nArgs ; iArg + + )
{
WORD nAddress = g_aArgs [ iArg ] . nValue ;
// Make sure address isn't an IO address
if ( ( nAddress > = _6502_IO_BEGIN ) & & ( nAddress < = _6502_IO_END ) )
return ConsoleDisplayError ( TEXT ( " You may not watch an I/O location. " ) ) ;
if ( iWatch = = NO_6502_TARGET )
2006-02-26 06:26:56 +00:00
{
2006-07-01 06:45:50 +00:00
iWatch = 0 ;
2006-07-05 21:23:13 +00:00
while ( ( iWatch < MAX_ZEROPAGE_POINTERS ) & & ( g_aWatches [ iWatch ] . bSet ) )
2006-06-27 22:04:03 +00:00
{
2006-07-01 06:45:50 +00:00
iWatch + + ;
2006-02-25 20:50:29 +00:00
}
}
2006-07-01 06:45:50 +00:00
if ( ( iWatch > = MAX_WATCHES ) & & ! bAdded )
{
char sText [ CONSOLE_WIDTH ] ;
sprintf ( sText , " All watches are currently in use. (Max: %d) " , MAX_WATCHES ) ;
ConsoleDisplayPush ( sText ) ;
return ConsoleUpdate ( ) ;
}
if ( ( iWatch < MAX_WATCHES ) & & ( g_nWatches < MAX_WATCHES ) )
{
g_aWatches [ iWatch ] . bSet = true ;
g_aWatches [ iWatch ] . bEnabled = true ;
g_aWatches [ iWatch ] . nAddress = ( WORD ) nAddress ;
bAdded = true ;
g_nWatches + + ;
iWatch + + ;
}
2006-06-27 22:04:03 +00:00
}
2006-07-01 06:45:50 +00:00
if ( ! bAdded )
goto _Help ;
return UPDATE_WATCH ;
2006-06-27 22:04:03 +00:00
2006-07-01 06:45:50 +00:00
_Help :
return Help_Arg_1 ( CMD_WATCH_ADD ) ;
2006-02-26 06:26:56 +00:00
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
Update_t CmdWatchClear ( int nArgs )
{
if ( ! g_nWatches )
return ConsoleDisplayError ( TEXT ( " There are no watches defined. " ) ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( ! nArgs )
return Help_Arg_1 ( CMD_WATCH_CLEAR ) ;
2006-02-25 20:50:29 +00:00
2006-07-05 21:23:13 +00:00
_BWZ_ClearViaArgs ( nArgs , g_aWatches , MAX_WATCHES , g_nWatches ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// if (! g_nWatches)
// {
// UpdateDisplay(UPDATE_BACKGROUND); // 1
// return UPDATE_NOTHING; // 0
// }
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
return UPDATE_CONSOLE_DISPLAY | UPDATE_WATCH ; // 1
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdWatchDisable ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( ! g_nWatches )
return ConsoleDisplayError ( TEXT ( " There are no watches defined. " ) ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( ! nArgs )
return Help_Arg_1 ( CMD_WATCH_DISABLE ) ;
2006-02-25 20:50:29 +00:00
2006-07-05 21:23:13 +00:00
_BWZ_EnableDisableViaArgs ( nArgs , g_aWatches , MAX_WATCHES , false ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return UPDATE_WATCH ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdWatchEnable ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( ! g_nWatches )
return ConsoleDisplayError ( TEXT ( " There are no watches defined. " ) ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( ! nArgs )
return Help_Arg_1 ( CMD_WATCH_ENABLE ) ;
2006-02-25 20:50:29 +00:00
2006-07-05 21:23:13 +00:00
_BWZ_EnableDisableViaArgs ( nArgs , g_aWatches , MAX_WATCHES , true ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return UPDATE_WATCH ;
}
//===========================================================================
Update_t CmdWatchList ( int nArgs )
{
2006-06-27 22:04:03 +00:00
if ( ! g_nWatches )
{
TCHAR sText [ CONSOLE_WIDTH ] ;
wsprintf ( sText , TEXT ( " There are no current watches. (Max: %d) " ) , MAX_WATCHES ) ;
ConsoleBufferPush ( sText ) ;
}
else
2006-02-25 20:50:29 +00:00
{
2006-07-05 21:23:13 +00:00
_BWZ_List ( g_aWatches , MAX_WATCHES ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
return ConsoleUpdate ( ) ;
}
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
/*
2006-02-26 06:26:56 +00:00
//===========================================================================
Update_t CmdWatchLoad ( int nArgs )
{
if ( ! nArgs )
return Help_Arg_1 ( CMD_WATCH_LOAD ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return UPDATE_CONSOLE_DISPLAY ;
2006-02-25 20:50:29 +00:00
}
2006-07-01 06:45:50 +00:00
*/
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdWatchSave ( int nArgs )
{
if ( ! nArgs )
return Help_Arg_1 ( CMD_WATCH_SAVE ) ;
return UPDATE_CONSOLE_DISPLAY ;
}
// Window _________________________________________________________________________________________
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
void _WindowJoin ( )
{
g_aWindowConfig [ g_iWindowThis ] . bSplit = false ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
void _WindowSplit ( Window_e eNewBottomWindow )
{
g_aWindowConfig [ g_iWindowThis ] . bSplit = true ;
g_aWindowConfig [ g_iWindowThis ] . eBot = eNewBottomWindow ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
void _WindowLast ( )
{
int eNew = g_iWindowLast ;
g_iWindowLast = g_iWindowThis ;
g_iWindowThis = eNew ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
void _WindowSwitch ( int eNewWindow )
{
g_iWindowLast = g_iWindowThis ;
g_iWindowThis = eNewWindow ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
Update_t _CmdWindowViewCommon ( int iNewWindow )
{
// Switching to same window, remove split
if ( g_iWindowThis = = iNewWindow )
{
g_aWindowConfig [ iNewWindow ] . bSplit = false ;
}
else
{
_WindowSwitch ( iNewWindow ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
// WindowUpdateConsoleDisplayedSize();
WindowUpdateSizes ( ) ;
return UPDATE_ALL ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
Update_t _CmdWindowViewFull ( int iNewWindow )
{
if ( g_iWindowThis ! = iNewWindow )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
g_aWindowConfig [ iNewWindow ] . bSplit = false ;
_WindowSwitch ( iNewWindow ) ;
WindowUpdateConsoleDisplayedSize ( ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
return UPDATE_ALL ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
void WindowUpdateConsoleDisplayedSize ( )
2006-02-25 20:50:29 +00:00
{
2006-07-05 21:23:13 +00:00
g_nConsoleDisplayLines = MIN_DISPLAY_CONSOLE_LINES ;
# if USE_APPLE_FONT
2006-07-01 06:45:50 +00:00
g_bConsoleFullWidth = true ;
g_nConsoleDisplayWidth = CONSOLE_WIDTH - 1 ;
if ( g_iWindowThis = = WINDOW_CONSOLE )
{
2006-07-05 21:23:13 +00:00
g_nConsoleDisplayLines = MAX_DISPLAY_LINES ;
2006-07-01 06:45:50 +00:00
g_nConsoleDisplayWidth = CONSOLE_WIDTH - 1 ;
g_bConsoleFullWidth = true ;
}
# else
2006-07-05 21:23:13 +00:00
g_nConsoleDisplayWidth = ( CONSOLE_WIDTH / 2 ) + 10 ;
2006-07-01 06:45:50 +00:00
g_bConsoleFullWidth = false ;
2006-06-27 22:04:03 +00:00
// g_bConsoleFullWidth = false;
2006-07-01 06:45:50 +00:00
// g_nConsoleDisplayWidth = CONSOLE_WIDTH - 10;
2006-02-26 06:26:56 +00:00
if ( g_iWindowThis = = WINDOW_CONSOLE )
2006-02-25 20:50:29 +00:00
{
2006-07-05 21:23:13 +00:00
g_nConsoleDisplayLines = MAX_DISPLAY_LINES ;
2006-07-01 06:45:50 +00:00
g_nConsoleDisplayWidth = CONSOLE_WIDTH - 1 ;
g_bConsoleFullWidth = true ;
2006-02-26 06:26:56 +00:00
}
2006-07-01 06:45:50 +00:00
# endif
2006-02-26 06:26:56 +00:00
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
int WindowGetHeight ( int iWindow )
{
// if (iWindow == WINDOW_CODE)
return g_nDisasmWinHeight ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
void WindowUpdateDisasmSize ( )
{
if ( g_aWindowConfig [ g_iWindowThis ] . bSplit )
{
2006-07-05 21:23:13 +00:00
g_nDisasmWinHeight = ( MAX_DISPLAY_LINES - g_nConsoleDisplayLines ) / 2 ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
else
2006-02-25 20:50:29 +00:00
{
2006-07-05 21:23:13 +00:00
g_nDisasmWinHeight = MAX_DISPLAY_LINES - g_nConsoleDisplayLines ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
g_nDisasmCurLine = MAX ( 0 , ( g_nDisasmWinHeight - 1 ) / 2 ) ;
# if _DEBUG
# endif
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
void WindowUpdateSizes ( )
{
WindowUpdateDisasmSize ( ) ;
WindowUpdateConsoleDisplayedSize ( ) ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdWindowCycleNext ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
g_iWindowThis + + ;
if ( g_iWindowThis > = NUM_WINDOWS )
g_iWindowThis = 0 ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
WindowUpdateSizes ( ) ;
return UPDATE_ALL ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdWindowCyclePrev ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
g_iWindowThis - - ;
if ( g_iWindowThis < 0 )
g_iWindowThis = NUM_WINDOWS - 1 ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
WindowUpdateSizes ( ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return UPDATE_ALL ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
Update_t CmdWindowShowCode ( int nArgs )
{
if ( g_iWindowThis = = WINDOW_CODE )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
g_aWindowConfig [ g_iWindowThis ] . bSplit = false ;
g_aWindowConfig [ g_iWindowThis ] . eBot = WINDOW_CODE ; // not really needed, but SAFE HEX ;-)
}
else
if ( g_iWindowThis = = WINDOW_DATA )
{
g_aWindowConfig [ g_iWindowThis ] . bSplit = true ;
g_aWindowConfig [ g_iWindowThis ] . eBot = WINDOW_CODE ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
WindowUpdateSizes ( ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return UPDATE_CONSOLE_DISPLAY ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdWindowShowCode1 ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
/*
if ( ( g_iWindowThis = = WINDOW_CODE ) | | ( g_iWindowThis ! = WINDOW_CODE ) )
{
g_aWindowConfig [ g_iWindowThis ] . bSplit = true ;
g_aWindowConfig [ g_iWindowThis ] . eTop = WINDOW_CODE ;
Window_e eWindow = WINDOW_CODE ;
if ( g_iWindowThis = = WINDOW_DATA )
eWindow = WINDOW_DATA ;
g_aWindowConfig [ g_iWindowThis ] . eBot = eWindow ;
return UPDATE_ALL ;
}
*/
return UPDATE_CONSOLE_DISPLAY ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdWindowShowCode2 ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( ( g_iWindowThis = = WINDOW_CODE ) | | ( g_iWindowThis = = WINDOW_CODE ) )
{
if ( g_iWindowThis = = WINDOW_CODE )
{
_WindowJoin ( ) ;
WindowUpdateDisasmSize ( ) ;
}
else
if ( g_iWindowThis = = WINDOW_DATA )
{
_WindowSplit ( WINDOW_CODE ) ;
WindowUpdateDisasmSize ( ) ;
}
return UPDATE_DISASM ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
}
return UPDATE_CONSOLE_DISPLAY ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdWindowShowData ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( g_iWindowThis = = WINDOW_CODE )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
g_aWindowConfig [ g_iWindowThis ] . bSplit = true ;
g_aWindowConfig [ g_iWindowThis ] . eBot = WINDOW_DATA ;
return UPDATE_ALL ;
}
else
if ( g_iWindowThis = = WINDOW_DATA )
{
g_aWindowConfig [ g_iWindowThis ] . bSplit = false ;
g_aWindowConfig [ g_iWindowThis ] . eBot = WINDOW_DATA ; // not really needed, but SAFE HEX ;-)
return UPDATE_ALL ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
return UPDATE_CONSOLE_DISPLAY ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdWindowShowData1 ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
/*
if ( g_iWindowThis ! = PARAM_CODE_1 )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
g_iWindowLast = g_iWindowThis ;
g_iWindowThis = PARAM_DATA_1 ;
return UPDATE_ALL ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
*/
return UPDATE_CONSOLE_DISPLAY ;
}
//===========================================================================
Update_t CmdWindowShowData2 ( int nArgs )
{
if ( ( g_iWindowThis = = WINDOW_CODE ) | | ( g_iWindowThis = = WINDOW_CODE ) )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( g_iWindowThis = = WINDOW_CODE )
{
_WindowJoin ( ) ;
}
else
if ( g_iWindowThis = = WINDOW_DATA )
{
_WindowSplit ( WINDOW_DATA ) ;
}
return UPDATE_DISASM ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
}
return UPDATE_CONSOLE_DISPLAY ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
Update_t CmdWindowShowSource ( int nArgs )
{
return UPDATE_CONSOLE_DISPLAY ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
Update_t CmdWindowShowSource1 ( int nArgs )
{
return UPDATE_CONSOLE_DISPLAY ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
Update_t CmdWindowShowSource2 ( int nArgs )
{
_WindowSplit ( WINDOW_SOURCE ) ;
WindowUpdateSizes ( ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return UPDATE_CONSOLE_DISPLAY ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
Update_t CmdWindowViewCode ( int nArgs )
{
return _CmdWindowViewCommon ( WINDOW_CODE ) ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
Update_t CmdWindowViewConsole ( int nArgs )
{
return _CmdWindowViewFull ( WINDOW_CONSOLE ) ;
return UPDATE_ALL ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
Update_t CmdWindowViewData ( int nArgs )
{
return _CmdWindowViewCommon ( WINDOW_DATA ) ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
Update_t CmdWindowViewOutput ( int nArgs )
{
VideoRedrawScreen ( ) ;
g_bDebuggerViewingAppleOutput = true ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return UPDATE_NOTHING ; // intentional
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
Update_t CmdWindowViewSource ( int nArgs )
{
return _CmdWindowViewFull ( WINDOW_CONSOLE ) ;
return UPDATE_ALL ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
Update_t CmdWindowViewSymbols ( int nArgs )
{
return _CmdWindowViewFull ( WINDOW_CONSOLE ) ;
return UPDATE_ALL ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
Update_t CmdWindow ( int nArgs )
{
if ( ! nArgs )
return Help_Arg_1 ( CMD_WINDOW ) ;
int iParam ;
TCHAR * pName = g_aArgs [ 1 ] . sArg ;
int nFound = FindParam ( pName , MATCH_EXACT , iParam , _PARAM_WINDOW_BEGIN , _PARAM_WINDOW_END ) ;
if ( nFound )
{
switch ( iParam )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
case PARAM_CODE : return CmdWindowViewCode ( 0 ) ; break ;
case PARAM_CONSOLE : return CmdWindowViewConsole ( 0 ) ; break ;
case PARAM_DATA : return CmdWindowViewData ( 0 ) ; break ;
// case PARAM_INFO : CmdWindowInfo(); break;
case PARAM_SOURCE : return CmdWindowViewSource ( 0 ) ; break ;
case PARAM_SYMBOLS : return CmdWindowViewSymbols ( 0 ) ; break ;
default :
return Help_Arg_1 ( CMD_WINDOW ) ;
break ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
WindowUpdateConsoleDisplayedSize ( ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return UPDATE_ALL ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
Update_t CmdWindowLast ( int nArgs )
{
_WindowLast ( ) ;
WindowUpdateConsoleDisplayedSize ( ) ;
return UPDATE_ALL ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// ZeroPage _______________________________________________________________________________________
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
2006-07-01 06:45:50 +00:00
Update_t CmdZeroPage ( int nArgs )
2006-02-26 06:26:56 +00:00
{
2006-07-01 06:45:50 +00:00
// ZP [address]
// ZP # address
return CmdZeroPageAdd ( nArgs ) ;
2006-02-26 06:26:56 +00:00
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
Update_t CmdZeroPageAdd ( int nArgs )
{
2006-07-01 06:45:50 +00:00
// ZP [address]
// ZP # address [address...]
2006-06-27 22:04:03 +00:00
if ( ! nArgs )
2006-02-26 06:26:56 +00:00
{
2006-06-27 22:04:03 +00:00
return CmdZeroPageList ( 0 ) ;
}
2006-07-01 06:45:50 +00:00
int iArg = 1 ;
int iZP = NO_6502_TARGET ;
if ( nArgs > 1 )
{
iZP = g_aArgs [ 1 ] . nValue ;
iArg + + ;
}
bool bAdded = false ;
for ( ; iArg < = nArgs ; iArg + + )
2006-06-27 22:04:03 +00:00
{
2006-07-01 06:45:50 +00:00
WORD nAddress = g_aArgs [ iArg ] . nValue ;
if ( iZP = = NO_6502_TARGET )
2006-02-25 20:50:29 +00:00
{
2006-07-01 06:45:50 +00:00
iZP = 0 ;
while ( ( iZP < MAX_ZEROPAGE_POINTERS ) & & ( g_aZeroPagePointers [ iZP ] . bSet ) )
2006-02-26 06:26:56 +00:00
{
2006-07-01 06:45:50 +00:00
iZP + + ;
2006-02-26 06:26:56 +00:00
}
}
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
if ( ( iZP > = MAX_ZEROPAGE_POINTERS ) & & ! bAdded )
{
char sText [ CONSOLE_WIDTH ] ;
sprintf ( sText , " All zero page pointers are currently in use. (Max: %d) " , MAX_ZEROPAGE_POINTERS ) ;
ConsoleDisplayPush ( sText ) ;
return ConsoleUpdate ( ) ;
}
if ( ( iZP < MAX_ZEROPAGE_POINTERS ) & & ( g_nZeroPagePointers < MAX_ZEROPAGE_POINTERS ) )
{
g_aZeroPagePointers [ iZP ] . bSet = true ;
g_aZeroPagePointers [ iZP ] . bEnabled = true ;
g_aZeroPagePointers [ iZP ] . nAddress = ( BYTE ) nAddress ;
bAdded = true ;
g_nZeroPagePointers + + ;
iZP + + ;
}
2006-06-27 22:04:03 +00:00
}
2006-07-01 06:45:50 +00:00
if ( ! bAdded )
goto _Help ;
2006-06-27 22:04:03 +00:00
return UPDATE_ZERO_PAGE | ConsoleUpdate ( ) ;
2006-07-01 06:45:50 +00:00
_Help :
return Help_Arg_1 ( CMD_ZEROPAGE_POINTER_ADD ) ;
2006-02-25 20:50:29 +00:00
}
2006-08-16 18:58:56 +00:00
Update_t _ZeroPage_Error ( )
{
// return ConsoleDisplayError( "There are no (ZP) pointers defined." );
char sText [ CONSOLE_WIDTH ] ;
sprintf ( sText , " There are no current (ZP) pointers. (Max: %d) " , MAX_ZEROPAGE_POINTERS ) ;
// ConsoleBufferPush( sText );
return ConsoleDisplayError ( sText ) ;
}
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdZeroPageClear ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( ! g_nBreakpoints )
2006-08-16 18:58:56 +00:00
return _ZeroPage_Error ( ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// CHECK FOR ERRORS
if ( ! nArgs )
return Help_Arg_1 ( CMD_ZEROPAGE_POINTER_CLEAR ) ;
2006-02-25 20:50:29 +00:00
2006-07-05 21:23:13 +00:00
_BWZ_ClearViaArgs ( nArgs , g_aZeroPagePointers , MAX_ZEROPAGE_POINTERS , g_nZeroPagePointers ) ;
2006-02-26 06:26:56 +00:00
if ( ! g_nZeroPagePointers )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
UpdateDisplay ( UPDATE_BACKGROUND ) ;
return UPDATE_CONSOLE_DISPLAY ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
2006-07-01 06:45:50 +00:00
return UPDATE_CONSOLE_DISPLAY | UPDATE_ZERO_PAGE ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
//===========================================================================
2006-07-01 06:45:50 +00:00
Update_t CmdZeroPageDisable ( int nArgs )
2006-02-26 06:26:56 +00:00
{
if ( ! nArgs )
return Help_Arg_1 ( CMD_ZEROPAGE_POINTER_DISABLE ) ;
if ( ! g_nZeroPagePointers )
2006-08-16 18:58:56 +00:00
return _ZeroPage_Error ( ) ;
2006-02-26 06:26:56 +00:00
2006-07-05 21:23:13 +00:00
_BWZ_EnableDisableViaArgs ( nArgs , g_aZeroPagePointers , MAX_ZEROPAGE_POINTERS , false ) ;
2006-02-26 06:26:56 +00:00
return UPDATE_ZERO_PAGE ;
}
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-07-01 06:45:50 +00:00
Update_t CmdZeroPageEnable ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( ! g_nZeroPagePointers )
2006-08-16 18:58:56 +00:00
return _ZeroPage_Error ( ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( ! nArgs )
return Help_Arg_1 ( CMD_ZEROPAGE_POINTER_ENABLE ) ;
2006-02-25 20:50:29 +00:00
2006-07-05 21:23:13 +00:00
_BWZ_EnableDisableViaArgs ( nArgs , g_aZeroPagePointers , MAX_ZEROPAGE_POINTERS , true ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return UPDATE_ZERO_PAGE ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdZeroPageList ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-06-27 22:04:03 +00:00
if ( ! g_nZeroPagePointers )
2006-02-26 06:26:56 +00:00
{
2006-08-16 18:58:56 +00:00
_ZeroPage_Error ( ) ;
2006-06-27 22:04:03 +00:00
}
else
{
2006-07-05 21:23:13 +00:00
_BWZ_ListAll ( g_aZeroPagePointers , MAX_ZEROPAGE_POINTERS ) ;
2006-02-26 06:26:56 +00:00
}
return ConsoleUpdate ( ) ;
2006-02-25 20:50:29 +00:00
}
2006-07-01 06:45:50 +00:00
/*
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdZeroPageLoad ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
return UPDATE_CONSOLE_DISPLAY ;
2006-02-25 20:50:29 +00:00
}
2006-07-01 06:45:50 +00:00
*/
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdZeroPageSave ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
return UPDATE_CONSOLE_DISPLAY ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t CmdZeroPagePointer ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
// p[0..4] : disable
// p[0..4] <ZeroPageAddr> : enable
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( ( nArgs ! = 0 ) & & ( nArgs ! = 1 ) )
return Help_Arg_1 ( g_iCommand ) ;
// return DisplayHelp(CmdZeroPagePointer);
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// int nPtrNum = g_aArgs[0].sArg[1] - '0'; // HACK: hard-coded to command length
int iZP = g_iCommand - CMD_ZEROPAGE_POINTER_0 ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( ( iZP < 0 ) | | ( iZP > MAX_ZEROPAGE_POINTERS ) )
return Help_Arg_1 ( g_iCommand ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( nArgs = = 0 )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
g_aZeroPagePointers [ iZP ] . bEnabled = false ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
else
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
g_aZeroPagePointers [ iZP ] . bSet = true ;
g_aZeroPagePointers [ iZP ] . bEnabled = true ;
2006-02-25 20:50:29 +00:00
2006-06-27 02:33:40 +00:00
WORD nAddress = g_aArgs [ 1 ] . nValue ;
2006-02-26 06:26:56 +00:00
g_aZeroPagePointers [ iZP ] . nAddress = ( BYTE ) nAddress ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
return UPDATE_ZERO_PAGE ;
}
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
// Command Input __________________________________________________________________________________
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// Note: Range is [iParamBegin,iParamEnd], not the usually (STL) expected [iParamBegin,iParamEnd)
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
int FindParam ( LPTSTR pLookupName , Match_e eMatch , int & iParam_ , int iParamBegin , int iParamEnd )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
int nFound = 0 ;
int nLen = _tcslen ( pLookupName ) ;
int iParam = 0 ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( ! nLen )
return nFound ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
# if ALLOW_INPUT_LOWERCASE
eMatch = MATCH_FUZZY ;
# endif
2006-02-26 06:26:56 +00:00
if ( eMatch = = MATCH_EXACT )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
// while (iParam < NUM_PARAMS )
for ( iParam = iParamBegin ; iParam < = iParamEnd ; iParam + + )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
TCHAR * pParamName = g_aParameters [ iParam ] . m_sName ;
2006-07-01 06:45:50 +00:00
int eCompare = _tcsicmp ( pLookupName , pParamName ) ;
2006-02-26 06:26:56 +00:00
if ( ! eCompare ) // exact match?
{
nFound + + ;
iParam_ = g_aParameters [ iParam ] . iCommand ;
break ;
}
2006-02-25 20:50:29 +00:00
}
}
else
2006-02-26 06:26:56 +00:00
if ( eMatch = = MATCH_FUZZY )
{
2006-07-01 06:45:50 +00:00
# if ALLOW_INPUT_LOWERCASE
TCHAR aLookup [ 256 ] = " " ;
for ( int i = 0 ; i < nLen ; i + + )
{
aLookup [ i ] = toupper ( pLookupName [ i ] ) ;
}
# endif
2006-02-26 06:26:56 +00:00
for ( iParam = iParamBegin ; iParam < = iParamEnd ; iParam + + )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
TCHAR * pParamName = g_aParameters [ iParam ] . m_sName ;
2006-07-01 06:45:50 +00:00
// _tcsnccmp
# if ALLOW_INPUT_LOWERCASE
if ( ! _tcsncmp ( aLookup , pParamName , nLen ) )
# else
2006-02-26 06:26:56 +00:00
if ( ! _tcsncmp ( pLookupName , pParamName , nLen ) )
2006-07-01 06:45:50 +00:00
# endif
2006-02-26 06:26:56 +00:00
{
nFound + + ;
2006-07-01 06:45:50 +00:00
iParam_ = g_aParameters [ iParam ] . iCommand ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
if ( ! _tcsicmp ( pLookupName , pParamName ) ) // exact match?
2006-02-26 06:26:56 +00:00
{
nFound = 1 ; // Exact match takes precidence over fuzzy matches
break ;
}
}
}
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
return nFound ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
int FindCommand ( LPTSTR pName , CmdFuncPtr_t & pFunction_ , int * iCommand_ )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
g_vPotentialCommands . erase ( g_vPotentialCommands . begin ( ) , g_vPotentialCommands . end ( ) ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
int nFound = 0 ;
int nLen = _tcslen ( pName ) ;
int iCommand = 0 ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( ! nLen )
return nFound ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
char sCommand [ CONSOLE_WIDTH ] ;
strcpy ( sCommand , pName ) ;
strupr ( sCommand ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
while ( ( iCommand < NUM_COMMANDS_WITH_ALIASES ) ) // && (name[0] >= g_aCommands[iCommand].aName[0])) Command no longer in Alphabetical order
{
TCHAR * pCommandName = g_aCommands [ iCommand ] . m_sName ;
// int iCmp = strcasecmp( sCommand, pCommandName, nLen )
if ( ! _tcsncmp ( sCommand , pCommandName , nLen ) )
{
pFunction_ = g_aCommands [ iCommand ] . pFunction ;
if ( pFunction_ )
{
g_iCommand = g_aCommands [ iCommand ] . iCommand ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
// Don't push the same comamnd/alias if already on the list
if ( find ( g_vPotentialCommands . begin ( ) , g_vPotentialCommands . end ( ) , g_iCommand ) = = g_vPotentialCommands . end ( ) )
2006-02-26 06:26:56 +00:00
{
2006-07-01 06:45:50 +00:00
nFound + + ;
g_vPotentialCommands . push_back ( g_iCommand ) ;
2006-02-25 20:50:29 +00:00
2006-07-01 06:45:50 +00:00
if ( iCommand_ )
* iCommand_ = iCommand ;
// !_tcscmp
if ( ! _tcsicmp ( pName , pCommandName ) ) // exact match?
{
// if (iCommand_)
// *iCommand_ = iCommand;
nFound = 1 ; // Exact match takes precidence over fuzzy matches
g_vPotentialCommands . erase ( g_vPotentialCommands . begin ( ) , g_vPotentialCommands . end ( ) ) ;
break ;
}
2006-02-26 06:26:56 +00:00
}
}
}
iCommand + + ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// if (nFound == 1)
2006-02-25 20:50:29 +00:00
// {
2006-02-26 06:26:56 +00:00
//
2006-02-25 20:50:29 +00:00
// }
2006-02-26 06:26:56 +00:00
return nFound ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
void DisplayAmbigiousCommands ( int nFound )
2006-02-25 20:50:29 +00:00
{
2006-07-09 04:53:08 +00:00
char sText [ CONSOLE_WIDTH * 2 ] ;
sprintf ( sText , " Ambiguous %s%d%s Commands: "
2006-08-16 18:58:56 +00:00
, CHC_NUM_DEC
2006-07-09 04:53:08 +00:00
, g_vPotentialCommands . size ( )
, CHC_DEFAULT
) ;
ConsolePrint ( sText ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
int iCommand = 0 ;
while ( iCommand < nFound )
2006-02-25 20:50:29 +00:00
{
2006-07-09 04:53:08 +00:00
char sPotentialCommands [ CONSOLE_WIDTH ] ;
sprintf ( sPotentialCommands , " %s " , CHC_COMMAND ) ;
int iWidth = strlen ( sPotentialCommands ) ;
2006-02-26 06:26:56 +00:00
while ( ( iCommand < nFound ) & & ( iWidth < g_nConsoleDisplayWidth ) )
{
2006-07-09 04:53:08 +00:00
int nCommand = g_vPotentialCommands [ iCommand ] ;
char * pName = g_aCommands [ nCommand ] . m_sName ;
int nLen = strlen ( pName ) ;
2006-02-25 20:50:29 +00:00
2006-07-09 04:53:08 +00:00
if ( ( iWidth + nLen ) > = ( CONSOLE_WIDTH - 1 ) )
break ;
sprintf ( sText , " %s " , pName ) ;
strcat ( sPotentialCommands , sText ) ;
2006-02-26 06:26:56 +00:00
iWidth + = nLen + 1 ;
iCommand + + ;
}
2006-07-09 04:53:08 +00:00
ConsolePrint ( sPotentialCommands ) ;
2006-02-26 06:26:56 +00:00
}
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
Update_t ExecuteCommand ( int nArgs )
2006-02-25 20:50:29 +00:00
{
2006-02-27 03:36:36 +00:00
Arg_t * pArg = & g_aArgs [ 0 ] ;
2006-07-09 04:53:08 +00:00
char * pCommand = & pArg - > sArg [ 0 ] ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
CmdFuncPtr_t pFunction = NULL ;
int nFound = FindCommand ( pCommand , pFunction ) ;
2006-02-25 20:50:29 +00:00
2006-07-09 04:53:08 +00:00
// int nCookMask = (1 << NUM_TOKENS) - 1; // ArgToken_e used as bit mask!
2006-03-09 21:46:47 +00:00
2006-02-27 03:36:36 +00:00
if ( ! nFound )
{
2006-07-09 04:53:08 +00:00
int nLen = strlen ( pCommand ) ;
2006-02-27 03:36:36 +00:00
if ( nLen < 6 )
{
// verify pCommand[ 0 .. (nLen-1) ] is hex digit
bool bIsHex = true ;
for ( int iChar = 0 ; iChar < ( nLen - 1 ) ; iChar + + )
{
if ( isdigit ( pCommand [ iChar ] ) )
continue ;
else
if ( pCommand [ iChar ] > = ' A ' & & pCommand [ iChar ] < = ' F ' )
continue ;
else
2006-07-01 06:45:50 +00:00
if ( pCommand [ iChar ] > = ' a ' & & pCommand [ iChar ] < = ' f ' )
continue ;
else
2006-02-27 03:36:36 +00:00
{
bIsHex = false ;
break ;
}
}
if ( bIsHex )
{
WORD nAddress = 0 ;
// Support Apple Monitor commands
// ####G -> JMP $adress
2006-07-01 06:45:50 +00:00
if ( ( pCommand [ nLen - 1 ] = = ' G ' ) | |
( pCommand [ nLen - 1 ] = = ' g ' ) )
2006-02-27 03:36:36 +00:00
{
pCommand [ nLen - 1 ] = 0 ;
ArgsGetValue ( pArg , & nAddress ) ;
regs . pc = nAddress ;
2006-06-12 22:06:50 +00:00
g_nAppMode = MODE_RUNNING ; // exit the debugger
2006-03-09 21:46:47 +00:00
nFound = 1 ;
2006-06-27 22:04:03 +00:00
g_iCommand = CMD_OUTPUT_ECHO ; // hack: don't cook args
2006-02-27 03:36:36 +00:00
}
2006-03-09 21:46:47 +00:00
2006-02-27 03:36:36 +00:00
// ####L -> Unassemble $address
2006-07-01 06:45:50 +00:00
if ( ( pCommand [ nLen - 1 ] = = ' L ' ) | |
( pCommand [ nLen - 1 ] = = ' l ' ) )
2006-02-27 03:36:36 +00:00
{
pCommand [ nLen - 1 ] = 0 ;
ArgsGetValue ( pArg , & nAddress ) ;
2006-03-09 21:46:47 +00:00
g_iCommand = CMD_UNASSEMBLE ;
// replace: addrL
// with: comamnd addr
pArg [ 1 ] = pArg [ 0 ] ;
strcpy ( pArg - > sArg , g_aCommands [ g_iCommand ] . m_sName ) ;
pArg - > nArgLen = strlen ( pArg - > sArg ) ;
2006-02-27 03:36:36 +00:00
pArg + + ;
2006-06-27 02:33:40 +00:00
pArg - > nValue = nAddress ;
2006-02-27 03:36:36 +00:00
nArgs + + ;
2006-03-09 21:46:47 +00:00
pFunction = g_aCommands [ g_iCommand ] . pFunction ;
2006-02-27 03:36:36 +00:00
nFound = 1 ;
}
2006-03-09 21:46:47 +00:00
// address: byte ...
if ( ( pArg + 1 ) - > eToken = = TOKEN_COLON )
{
g_iCommand = CMD_MEMORY_ENTER_BYTE ;
// replace: addr :
2006-08-16 18:58:56 +00:00
// with: command addr
2006-03-09 21:46:47 +00:00
pArg [ 1 ] = pArg [ 0 ] ;
strcpy ( pArg - > sArg , g_aCommands [ g_iCommand ] . m_sName ) ;
pArg - > nArgLen = strlen ( pArg - > sArg ) ;
// nCookMask &= ~ (1 << TOKEN_COLON);
// nArgs++;
pFunction = g_aCommands [ g_iCommand ] . pFunction ;
nFound = 1 ;
}
// TODO: display memory at address
// addr1 [addr2] -> display byte at address
// MDB memory display byte (is deprecated, so can be re-used)
2006-02-27 03:36:36 +00:00
}
}
}
2006-02-26 06:26:56 +00:00
if ( nFound > 1 )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
// ASSERT (nFound == g_vPotentialCommands.size() );
DisplayAmbigiousCommands ( nFound ) ;
return ConsoleUpdate ( ) ;
// return ConsoleDisplayError( gaPotentialCommands );
}
2006-02-27 23:12:16 +00:00
if ( nFound )
{
bool bCook = true ;
2006-06-27 22:04:03 +00:00
if ( g_iCommand = = CMD_OUTPUT_ECHO )
2006-02-27 23:12:16 +00:00
bCook = false ;
int nArgsCooked = nArgs ;
if ( bCook )
2006-07-09 04:53:08 +00:00
nArgsCooked = ArgsCook ( nArgs ) ; // nCookMask
2006-02-27 23:12:16 +00:00
2006-06-27 22:04:03 +00:00
if ( nArgsCooked = = ARG_SYNTAX_ERROR )
2006-08-16 18:58:56 +00:00
return ConsoleDisplayError ( " Syntax Error " ) ;
2006-06-27 22:04:03 +00:00
2006-02-27 23:12:16 +00:00
if ( pFunction )
return pFunction ( nArgsCooked ) ; // Eat them
return UPDATE_CONSOLE_DISPLAY ;
}
2006-02-26 06:26:56 +00:00
else
2006-08-16 18:58:56 +00:00
return ConsoleDisplayError ( " Illegal Command " ) ;
2006-02-26 06:26:56 +00:00
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// ________________________________________________________________________________________________
2006-02-25 20:50:29 +00:00
2006-05-10 22:00:27 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
bool InternalSingleStep ( )
{
2006-03-09 21:46:47 +00:00
static DWORD dwCyclesThisFrame = 0 ;
2006-02-26 06:26:56 +00:00
bool bResult = false ;
_try
{
BYTE nOpcode = * ( mem + regs . pc ) ;
int nOpmode = g_aOpcodes [ nOpcode ] . nAddressMode ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
g_aProfileOpcodes [ nOpcode ] . m_nCount + + ;
g_aProfileOpmodes [ nOpmode ] . m_nCount + + ;
2006-02-25 20:50:29 +00:00
2006-03-09 21:46:47 +00:00
DWORD dwExecutedCycles = CpuExecute ( g_nDebugStepCycles ) ;
dwCyclesThisFrame + = dwExecutedCycles ;
if ( dwCyclesThisFrame > = dwClksPerFrame )
{
dwCyclesThisFrame - = dwClksPerFrame ;
}
VideoUpdateVbl ( dwCyclesThisFrame ) ;
2006-02-26 06:26:56 +00:00
bResult = true ;
}
_except ( EXCEPTION_EXECUTE_HANDLER )
{
bResult = false ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return bResult ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
void OutputTraceLine ( )
{
2006-08-16 18:58:56 +00:00
DisasmLine_t line ;
GetDisassemblyLine ( regs . pc , line ) ;
char sDisassembly [ CONSOLE_WIDTH ] ; // DrawDisassemblyLine( 0,regs.pc, sDisassembly); // Get Disasm String
FormatDisassemblyLine ( line , sDisassembly , CONSOLE_WIDTH ) ;
2006-07-09 04:53:08 +00:00
char sFlags [ _6502_NUM_FLAGS + 1 ] ; DrawFlags ( 0 , regs . ps , sFlags ) ; // Get Flags String
2006-02-25 20:50:29 +00:00
2006-08-16 18:58:56 +00:00
if ( g_hTraceFile )
{
if ( g_bTraceHeader )
{
g_bTraceHeader = false ;
fprintf ( g_hTraceFile ,
2007-03-24 05:10:51 +00:00
// "00 00 00 0000 -------- 0000:90 90 90 NOP"
" A: X: Y: SP: Flags Addr:Opcode Mnemonic \n "
2006-08-16 18:58:56 +00:00
) ;
}
char sTarget [ 16 ] ;
if ( line . bTargetValue )
{
sprintf ( sTarget , " %s:%s "
, line . sTargetPointer
, line . sTargetValue
) ;
}
fprintf ( g_hTraceFile ,
// "a=%02x x=%02x y=%02x sp=%03x ps=%s %s\n",
" %02X %02X %02X %04X %s %s \n " ,
( unsigned ) regs . a ,
( unsigned ) regs . x ,
( unsigned ) regs . y ,
( unsigned ) regs . sp ,
( char * ) sFlags
, sDisassembly
, sTarget
) ;
}
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
int ParseInput ( LPTSTR pConsoleInput , bool bCook )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
int nArg = 0 ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// TODO: need to check for non-quoted command seperator ';', and buffer input
RemoveWhiteSpaceReverse ( pConsoleInput ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
ArgsClear ( ) ;
nArg = ArgsGet ( pConsoleInput ) ; // Get the Raw Args
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
int iArg ;
for ( iArg = 0 ; iArg < = nArg ; iArg + + )
{
g_aArgs [ iArg ] = g_aArgRaw [ iArg ] ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
return nArg ;
}
//===========================================================================
void ParseParameter ( )
{
}
// Return address of next line to write to.
//===========================================================================
char * ProfileLinePeek ( int iLine )
{
char * pText = NULL ;
if ( iLine < 0 )
iLine = 0 ;
if ( ! g_nProfileLine )
pText = & g_aProfileLine [ iLine ] [ 0 ] ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( iLine < = g_nProfileLine )
pText = & g_aProfileLine [ iLine ] [ 0 ] ;
return pText ;
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
char * ProfileLinePush ( )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( g_nProfileLine < NUM_PROFILE_LINES )
{
g_nProfileLine + + ;
}
return ProfileLinePeek ( g_nProfileLine ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
void ProfileLineReset ( )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
g_nProfileLine = 0 ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
# define DELIM "%s"
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
void ProfileFormat ( bool bExport , ProfileFormat_e eFormatMode )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
char sSeperator7 [ 32 ] = " \t " ;
char sSeperator2 [ 32 ] = " \t " ;
char sSeperator1 [ 32 ] = " \t " ;
char sOpcode [ 8 ] ; // 2 chars for opcode in hex, plus quotes on either side
char sAddress [ MAX_OPMODE_NAME ] ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( eFormatMode = = PROFILE_FORMAT_COMMA )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
sSeperator7 [ 0 ] = ' , ' ;
sSeperator2 [ 0 ] = ' , ' ;
sSeperator1 [ 0 ] = ' , ' ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
else
if ( eFormatMode = = PROFILE_FORMAT_SPACE )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
sprintf ( sSeperator7 , " " ) ; // 7
sprintf ( sSeperator2 , " " ) ; // 2
sprintf ( sSeperator1 , " " ) ; // 1
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
ProfileLineReset ( ) ;
char * pText = ProfileLinePeek ( 0 ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
int iOpcode ;
int iOpmode ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
bool bOpcodeGood = true ;
bool bOpmodeGood = true ;
vector < ProfileOpcode_t > vProfileOpcode ( & g_aProfileOpcodes [ 0 ] , & g_aProfileOpcodes [ NUM_OPCODES ] ) ;
vector < ProfileOpmode_t > vProfileOpmode ( & g_aProfileOpmodes [ 0 ] , & g_aProfileOpmodes [ NUM_OPMODES ] ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// sort >
sort ( vProfileOpcode . begin ( ) , vProfileOpcode . end ( ) , ProfileOpcode_t ( ) ) ;
sort ( vProfileOpmode . begin ( ) , vProfileOpmode . end ( ) , ProfileOpmode_t ( ) ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
Profile_t nOpcodeTotal = 0 ;
Profile_t nOpmodeTotal = 0 ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
for ( iOpcode = 0 ; iOpcode < NUM_OPCODES ; + + iOpcode )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
nOpcodeTotal + = vProfileOpcode [ iOpcode ] . m_nCount ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
for ( iOpmode = 0 ; iOpmode < NUM_OPMODES ; + + iOpmode )
{
nOpmodeTotal + = vProfileOpmode [ iOpmode ] . m_nCount ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( nOpcodeTotal < 1. )
{
nOpcodeTotal = 1 ;
bOpcodeGood = false ;
}
2006-08-16 18:58:56 +00:00
char * pColorOperator = " " ;
char * pColorNumber = " " ;
char * pColorOpcode = " " ;
char * pColorMnemonic = " " ;
char * pColorOpmode = " " ;
char * pColorTotal = " " ;
if ( ! bExport )
{
pColorOperator = CHC_ARG_SEP ; // grey
pColorNumber = CHC_NUM_DEC ; // cyan
pColorOpcode = CHC_NUM_HEX ; // yellow
pColorMnemonic = CHC_COMMAND ; // green
pColorOpmode = CHC_USAGE ; // yellow
pColorTotal = CHC_DEFAULT ; // white
}
2006-02-26 06:26:56 +00:00
// Opcode
if ( bExport ) // Export = SeperateColumns
sprintf ( pText
, " \" Percent \" " DELIM " \" Count \" " DELIM " \" Opcode \" " DELIM " \" Mnemonic \" " DELIM " \" Addressing Mode \" \n "
, sSeperator7 , sSeperator2 , sSeperator1 , sSeperator1 ) ;
else
sprintf ( pText
, " Percent " DELIM " Count " DELIM " Mnemonic " DELIM " Addressing Mode \n "
, sSeperator7 , sSeperator2 , sSeperator1 ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
pText = ProfileLinePush ( ) ;
for ( iOpcode = 0 ; iOpcode < NUM_OPCODES ; + + iOpcode )
{
ProfileOpcode_t tProfileOpcode = vProfileOpcode . at ( iOpcode ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
Profile_t nCount = tProfileOpcode . m_nCount ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// Don't spam with empty data if dumping to the console
if ( ( ! nCount ) & & ( ! bExport ) )
continue ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
int nOpcode = tProfileOpcode . m_iOpcode ;
int nOpmode = g_aOpcodes [ nOpcode ] . nAddressMode ;
double nPercent = ( 100. * nCount ) / nOpcodeTotal ;
char sOpmode [ MAX_OPMODE_FORMAT ] ;
sprintf ( sOpmode , g_aOpmodes [ nOpmode ] . m_sFormat , 0 ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( bExport )
{
// Excel Bug: Quoted numbers are NOT treated as strings in .csv! WTF?
// @reference: http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q214233
//
// Workaround: Prefix with (') apostrophe -- this doesn't break HEX2DEC()
// This works properly in Openoffice.
// In Excel, this ONLY works IF you TYPE it in!
//
// Solution: Quote the numbers, but you must select the "TEXT" Column data format for the "Opcode" column.
// We don't use .csv, since you aren't given the Import Dialog in Excel!
sprintf ( sOpcode , " \" %02X \" " , nOpcode ) ; // Works with Excel, IF using Import dialog & choose Text. (also works with OpenOffice)
// sprintf( sOpcode, "'%02X", nOpcode ); // SHOULD work with Excel, but only works with OpenOffice.
sprintf ( sAddress , " \" %s \" " , g_aOpmodes [ nOpmode ] . m_sName ) ;
}
else // not qouted if dumping to console
{
sprintf ( sOpcode , " %02X " , nOpcode ) ;
strcpy ( sAddress , g_aOpmodes [ nOpmode ] . m_sName ) ;
}
// BUG: Yeah 100% is off by 1 char. Profiling only one opcode isn't worth fixing this visual alignment bug.
sprintf ( pText ,
2006-08-16 18:58:56 +00:00
" %s%7.4f%s%% " DELIM " %s%9u " DELIM " %s%s " DELIM " %s%s " DELIM " %s%s \n "
, pColorNumber
, nPercent
, pColorOperator
, sSeperator2
, pColorNumber
2006-02-26 06:26:56 +00:00
, static_cast < unsigned int > ( nCount ) , sSeperator2
2006-08-16 18:58:56 +00:00
, pColorOpcode
2006-02-26 06:26:56 +00:00
, sOpcode , sSeperator2
2006-08-16 18:58:56 +00:00
, pColorMnemonic
2006-02-26 06:26:56 +00:00
, g_aOpcodes [ nOpcode ] . sMnemonic , sSeperator2
2006-08-16 18:58:56 +00:00
, pColorOpmode
2006-02-26 06:26:56 +00:00
, sAddress
) ;
pText = ProfileLinePush ( ) ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( ! bOpcodeGood )
nOpcodeTotal = 0 ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
sprintf ( pText
2006-08-16 18:58:56 +00:00
, " Total: " DELIM " %s%9u \n "
2006-02-26 06:26:56 +00:00
, sSeperator2
2006-08-16 18:58:56 +00:00
, pColorTotal
2006-02-26 06:26:56 +00:00
, static_cast < unsigned int > ( nOpcodeTotal ) ) ;
pText = ProfileLinePush ( ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
sprintf ( pText , " \n " ) ;
pText = ProfileLinePush ( ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// Opmode
// "Percent Count Adressing Mode\n" );
if ( bExport )
// Note: 2 extra dummy columns are inserted to keep Addressing Mode in same column
sprintf ( pText
, " \" Percent \" " DELIM " \" Count \" " DELIM DELIM DELIM " \" Addressing Mode \" \n "
, sSeperator7 , sSeperator2 , sSeperator2 , sSeperator2 ) ;
2006-02-25 20:50:29 +00:00
else
2006-07-09 04:53:08 +00:00
{
2006-02-26 06:26:56 +00:00
sprintf ( pText
, " Percent " DELIM " Count " DELIM " Addressing Mode \n "
, sSeperator7 , sSeperator2 ) ;
2006-07-09 04:53:08 +00:00
}
2006-02-26 06:26:56 +00:00
pText = ProfileLinePush ( ) ;
if ( nOpmodeTotal < 1 )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
nOpmodeTotal = 1. ;
bOpmodeGood = false ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
for ( iOpmode = 0 ; iOpmode < NUM_OPMODES ; + + iOpmode )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
ProfileOpmode_t tProfileOpmode = vProfileOpmode . at ( iOpmode ) ;
Profile_t nCount = tProfileOpmode . m_nCount ;
// Don't spam with empty data if dumping to the console
if ( ( ! nCount ) & & ( ! bExport ) )
continue ;
int nOpmode = tProfileOpmode . m_iOpmode ;
double nPercent = ( 100. * nCount ) / nOpmodeTotal ;
if ( bExport )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
// Note: 2 extra dummy columns are inserted to keep Addressing Mode in same column
sprintf ( sAddress , " %s%s \" %s \" " , sSeperator1 , sSeperator1 , g_aOpmodes [ nOpmode ] . m_sName ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
else // not qouted if dumping to console
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
strcpy ( sAddress , g_aOpmodes [ nOpmode ] . m_sName ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
// BUG: Yeah 100% is off by 1 char. Profiling only one opcode isn't worth fixing this visual alignment bug.
sprintf ( pText
2006-08-16 18:58:56 +00:00
, " %s%7.4f%s%% " DELIM " %s%9u " DELIM " %s%s \n "
, pColorNumber
, nPercent
, pColorOperator
, sSeperator2
, pColorNumber
2006-02-26 06:26:56 +00:00
, static_cast < unsigned int > ( nCount ) , sSeperator2
2006-08-16 18:58:56 +00:00
, pColorOpmode
2006-02-26 06:26:56 +00:00
, sAddress
) ;
pText = ProfileLinePush ( ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
if ( ! bOpmodeGood )
nOpmodeTotal = 0 ;
sprintf ( pText
2006-08-16 18:58:56 +00:00
, " Total: " DELIM " %s%9u \n "
2006-02-26 06:26:56 +00:00
, sSeperator2
2006-08-16 18:58:56 +00:00
, pColorTotal
2006-02-26 06:26:56 +00:00
, static_cast < unsigned int > ( nOpmodeTotal ) ) ;
pText = ProfileLinePush ( ) ;
sprintf ( pText , " \n " ) ;
pText = ProfileLinePush ( ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
# undef DELIM
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
void ProfileReset ( )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
int iOpcode ;
int iOpmode ;
for ( iOpcode = 0 ; iOpcode < NUM_OPCODES ; iOpcode + + )
{
g_aProfileOpcodes [ iOpcode ] . m_iOpcode = iOpcode ;
g_aProfileOpcodes [ iOpcode ] . m_nCount = 0 ;
}
for ( iOpmode = 0 ; iOpmode < NUM_OPMODES ; iOpmode + + )
{
g_aProfileOpmodes [ iOpmode ] . m_iOpmode = iOpmode ;
g_aProfileOpmodes [ iOpmode ] . m_nCount = 0 ;
}
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
bool ProfileSave ( )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
bool bStatus = false ;
2006-08-16 18:58:56 +00:00
char sFilename [ MAX_PATH ] ;
strcpy ( sFilename , g_sProgramDir ) ; // TODO: Allow user to decide?
strcat ( sFilename , g_FileNameProfile ) ;
2006-02-25 20:50:29 +00:00
2006-08-16 18:58:56 +00:00
FILE * hFile = fopen ( sFilename , " wt " ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( hFile )
{
char * pText ;
int nLine = g_nProfileLine ;
int iLine ;
for ( iLine = 0 ; iLine < nLine ; iLine + + )
{
pText = ProfileLinePeek ( iLine ) ;
if ( pText )
{
fputs ( pText , hFile ) ;
}
}
fclose ( hFile ) ;
bStatus = true ;
}
return bStatus ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
// _____________________________________________________________________________________
// | |
// | Public Functions |
// | |
// |_____________________________________________________________________________________|
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
void DebugBegin ( )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
// This is called every time the emulator is reset.
2006-02-27 03:36:36 +00:00
// And everytime the debugger is entered.
2006-02-25 20:50:29 +00:00
2006-06-12 22:06:50 +00:00
g_nAppMode = MODE_DEBUG ;
2006-02-26 06:26:56 +00:00
FrameRefreshStatus ( DRAW_TITLE ) ;
2006-02-25 20:50:29 +00:00
2006-06-25 03:43:49 +00:00
if ( g_bApple2e )
2006-02-26 06:26:56 +00:00
g_aOpcodes = & g_aOpcodes65C02 [ 0 ] ; // Enhanced Apple //e
else
2006-05-10 22:00:27 +00:00
g_aOpcodes = & g_aOpcodes6502 [ 0 ] ; // Original Apple ][ ][+
2006-02-25 20:50:29 +00:00
2006-06-25 03:43:49 +00:00
g_aOpmodes [ AM_2 ] . m_nBytes = g_bApple2e ? 2 : 1 ;
g_aOpmodes [ AM_3 ] . m_nBytes = g_bApple2e ? 3 : 1 ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
g_nDisasmCurAddress = regs . pc ;
DisasmCalcTopBotAddress ( ) ;
2006-02-25 20:50:29 +00:00
2006-02-27 15:58:01 +00:00
g_bDebuggerViewingAppleOutput = false ;
2006-02-27 03:36:36 +00:00
UpdateDisplay ( UPDATE_ALL ) ;
2006-07-02 09:57:26 +00:00
# if DEBUG_APPLE_FONT
int iFG = 7 ;
int iBG = 4 ;
// DebuggerSetColorFG( aColors[ iFG ] );
// DebuggerSetColorBG( aColors[ iBG ] );
int iChar = 0 ;
int x = 0 ;
int y = 0 ;
for ( iChar = 0 ; iChar < 256 ; iChar + + )
{
x = ( iChar % 16 ) ;
y = ( iChar / 16 ) ;
iFG = ( x > > 1 ) ; // (iChar % 8);
iBG = ( y > > 1 ) & 7 ; // (iChar / 8) & 7;
2006-07-03 15:27:49 +00:00
DebuggerSetColorFG ( aConsoleColors [ iFG ] ) ;
DebuggerSetColorBG ( aConsoleColors [ iBG ] ) ;
2006-07-02 09:57:26 +00:00
DebuggerPrintChar ( x * ( APPLE_FONT_WIDTH / 2 ) , y * ( APPLE_FONT_HEIGHT / 2 ) , iChar ) ;
}
# endif
2006-02-25 20:50:29 +00:00
}
//===========================================================================
2006-02-26 06:26:56 +00:00
void DebugContinueStepping ( )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
static unsigned nStepsTaken = 0 ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( g_nDebugSkipLen > 0 )
{
if ( ( regs . pc > = g_nDebugSkipStart ) & & ( regs . pc < ( g_nDebugSkipStart + g_nDebugSkipLen ) ) )
{
2006-06-12 22:06:50 +00:00
// Enter turbo debugger g_nAppMode -- UI not updated, etc.
2006-02-26 06:26:56 +00:00
g_nDebugSteps = - 1 ;
2006-06-12 22:06:50 +00:00
g_nAppMode = MODE_STEPPING ;
2006-02-26 06:26:56 +00:00
}
else
{
2006-06-12 22:06:50 +00:00
// Enter normal debugger g_nAppMode -- UI updated every instruction, etc.
2006-02-26 06:26:56 +00:00
g_nDebugSteps = 1 ;
2006-06-12 22:06:50 +00:00
g_nAppMode = MODE_STEPPING ;
2006-02-26 06:26:56 +00:00
}
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( g_nDebugSteps )
{
if ( g_hTraceFile )
OutputTraceLine ( ) ;
lastpc = regs . pc ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
InternalSingleStep ( ) ;
2006-02-25 20:50:29 +00:00
2006-02-27 00:41:52 +00:00
bool bBreak = CheckBreakpointsIO ( ) ;
2006-02-26 06:26:56 +00:00
if ( CheckBreakpointsReg ( ) )
bBreak = true ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
if ( ( regs . pc = = g_nDebugStepUntil ) | | bBreak )
g_nDebugSteps = 0 ;
else if ( g_nDebugSteps > 0 )
g_nDebugSteps - - ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
if ( g_nDebugSteps )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( ! ( ( + + nStepsTaken ) & 0xFFFF ) )
2006-02-25 20:50:29 +00:00
{
2006-02-26 06:26:56 +00:00
if ( nStepsTaken = = 0x10000 )
VideoRedrawScreen ( ) ;
else
VideoRefreshScreen ( ) ;
2006-02-25 20:50:29 +00:00
}
}
2006-02-26 06:26:56 +00:00
else
2006-02-25 20:50:29 +00:00
{
2006-06-12 22:06:50 +00:00
g_nAppMode = MODE_DEBUG ;
2006-02-26 06:26:56 +00:00
FrameRefreshStatus ( DRAW_TITLE ) ;
// BUG: PageUp, Trace - doesn't center cursor
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// if ((g_nDebugStepStart < regs.pc) && (g_nDebugStepStart+3 >= regs.pc))
// Still within current disasm "window"?
/*
if ( ( regs . pc > = g_nDisasmTopAddress ) & & ( regs . pc < = g_nDisasmBotAddress ) )
{
int eMode = g_aOpcodes [ * ( mem + g_nDisasmCurAddress ) ] . addrmode ;
int nBytes = g_aOpmodes [ eMode ] . _nBytes ;
g_nDisasmCurAddress + = nBytes ;
// g_nDisasmTopAddress += nBytes;
// g_nDisasmBotAddress += nBytes;
}
else
*/
{
g_nDisasmCurAddress = regs . pc ;
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
DisasmCalcTopBotAddress ( ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
// g_nDisasmCurAddress += g_aOpmodes[g_aOpcodes[*(mem+g_nDisasmCurAddress)].addrmode]._nBytes;
// DisasmCalcTopBotAddress();
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
Update_t bUpdate = UPDATE_ALL ;
// if (nStepsTaken >= 0x10000) // HACK_MAGIC_NUM
// bUpdate = UPDATE_ALL;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
UpdateDisplay ( bUpdate ) ; // nStepsTaken >= 0x10000);
nStepsTaken = 0 ;
}
}
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
//===========================================================================
void DebugDestroy ( )
{
DebugEnd ( ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
for ( int iFont = 0 ; iFont < NUM_FONTS ; iFont + + )
{
DeleteObject ( g_aFontConfig [ iFont ] . _hFont ) ;
g_aFontConfig [ iFont ] . _hFont = NULL ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
// DeleteObject(g_hFontDisasm );
// DeleteObject(g_hFontDebugger);
// DeleteObject(g_hFontWebDings);
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
for ( int iTable = 0 ; iTable < NUM_SYMBOL_TABLES ; iTable + + )
{
_CmdSymbolsClear ( ( Symbols_e ) iTable ) ;
}
2006-07-02 09:57:26 +00:00
2006-07-05 21:23:13 +00:00
SelectObject ( g_hFrameDC , GetStockObject ( NULL_BRUSH ) ) ;
2006-07-02 09:57:26 +00:00
2006-07-03 15:27:49 +00:00
DeleteObject ( g_hConsoleBrushFG ) ;
DeleteObject ( g_hConsoleBrushBG ) ;
2006-07-02 09:57:26 +00:00
2006-07-03 15:27:49 +00:00
DeleteDC ( g_hConsoleFontDC ) ;
DeleteObject ( g_hConsoleFontBitmap ) ;
2006-07-02 09:57:26 +00:00
2006-07-05 21:23:13 +00:00
// ReleaseDC( g_hFrameWindow, g_hFrameDC );
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
2006-02-25 20:50:29 +00:00
//===========================================================================
void DebugEnd ( )
{
// Stepping ... calls us when key hit?! FrameWndProc() ProcessButtonClick() DebugEnd()
if ( g_bProfiling )
{
// See: .csv / .txt note in CmdProfile()
ProfileFormat ( true , PROFILE_FORMAT_TAB ) ; // Export in Excel-ready text format.
ProfileSave ( ) ;
}
if ( g_hTraceFile )
{
fclose ( g_hTraceFile ) ;
g_hTraceFile = NULL ;
}
2006-05-10 22:00:27 +00:00
g_vMemorySearchResults . erase ( g_vMemorySearchResults . begin ( ) , g_vMemorySearchResults . end ( ) ) ;
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
2006-02-25 20:50:29 +00:00
# if _DEBUG
# define DEBUG_COLOR_RAMP 0
2006-07-02 09:57:26 +00:00
//===========================================================================
2006-02-25 20:50:29 +00:00
void _SetupColorRamp ( const int iPrimary , int & iColor_ )
{
TCHAR sRamp [ CONSOLE_WIDTH * 2 ] = TEXT ( " " ) ;
# if DEBUG_COLOR_RAMP
TCHAR sText [ CONSOLE_WIDTH ] ;
# endif
bool bR = ( iPrimary & 1 ) ? true : false ;
bool bG = ( iPrimary & 2 ) ? true : false ;
bool bB = ( iPrimary & 4 ) ? true : false ;
int dStep = 32 ;
int nLevels = 256 / dStep ;
for ( int iLevel = nLevels ; iLevel > 0 ; iLevel - - )
{
int nC = ( ( iLevel * dStep ) - 1 ) ;
int nR = bR ? nC : 0 ;
int nG = bG ? nC : 0 ;
int nB = bB ? nC : 0 ;
DWORD nColor = RGB ( nR , nG , nB ) ;
gaColorPalette [ iColor_ ] = nColor ;
# if DEBUG_COLOR_RAMP
wsprintf ( sText , TEXT ( " RGB(%3d,%3d,%3d), " ) , nR , nG , nB ) ;
_tcscat ( sRamp , sText ) ;
# endif
iColor_ + + ;
}
# if DEBUG_COLOR_RAMP
wsprintf ( sText , TEXT ( " // %d%d%d \n " ) , bB , bG , bR ) ;
_tcscat ( sRamp , sText ) ;
OutputDebugString ( sRamp ) ;
sRamp [ 0 ] = 0 ;
# endif
}
# endif // _DEBUG
2006-07-02 09:57:26 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
void _ConfigColorsReset ( )
2006-02-25 20:50:29 +00:00
{
// int iColor = 1; // black only has one level, skip it, since black levels same as white levels
// for (int iPrimary = 1; iPrimary < 8; iPrimary++ )
// {
// _SetupColorRamp( iPrimary, iColor );
// }
// Setup default colors
int iColor ;
for ( iColor = 0 ; iColor < NUM_COLORS ; iColor + + )
{
COLORREF nColor = gaColorPalette [ g_aColorIndex [ iColor ] ] ;
int R = ( nColor > > 0 ) & 0xFF ;
int G = ( nColor > > 8 ) & 0xFF ;
int B = ( nColor > > 16 ) & 0xFF ;
// There are many, many ways of shifting the color domain to the monochrome domain
// NTSC uses 3x3 matrix, could map RGB -> wavelength, etc.
int M = ( R + G + B ) / 3 ; // Monochrome component
2006-02-26 06:26:56 +00:00
int nThreshold = 64 ;
int BW ;
if ( M < nThreshold )
BW = 0 ;
else
BW = 255 ;
2006-02-25 20:50:29 +00:00
COLORREF nMono = RGB ( M , M , M ) ;
2006-02-26 06:26:56 +00:00
COLORREF nBW = RGB ( BW , BW , BW ) ;
2006-02-25 20:50:29 +00:00
2006-02-26 06:26:56 +00:00
DebuggerSetColor ( SCHEME_COLOR , iColor , nColor ) ;
DebuggerSetColor ( SCHEME_MONO , iColor , nMono ) ;
DebuggerSetColor ( SCHEME_BW , iColor , nBW ) ;
2006-02-25 20:50:29 +00:00
}
}
//===========================================================================
void DebugInitialize ( )
{
2006-06-27 22:04:03 +00:00
AssemblerOff ( ) ; // update prompt
2006-07-02 09:57:26 +00:00
# if _DEBUG
DWORD nError = 0 ;
# endif
2006-07-05 21:23:13 +00:00
// g_hDstDC = g_hFrameDC; //GetDC( g_hFrameWindow );
2006-07-02 09:57:26 +00:00
# if _DEBUG
nError = GetLastError ( ) ;
# endif
// Must select a bitmap into the temp DC !
2006-07-05 21:23:13 +00:00
HDC hTmpDC = CreateCompatibleDC ( g_hFrameDC ) ;
2006-07-02 09:57:26 +00:00
# if _DEBUG
nError = GetLastError ( ) ;
# endif
2006-07-05 21:23:13 +00:00
g_hConsoleFontDC = CreateCompatibleDC ( g_hFrameDC ) ;
2006-07-02 09:57:26 +00:00
# if _DEBUG
nError = GetLastError ( ) ;
# endif
# if APPLE_FONT_NEW
// Pre-scaled bitmap
2006-07-03 15:27:49 +00:00
g_hConsoleFontBitmap = LoadBitmap ( g_hInstance , TEXT ( " IDB_DEBUG_FONT_7x8 " ) ) ;
SelectObject ( g_hConsoleFontDC , g_hConsoleFontBitmap ) ;
2006-07-02 09:57:26 +00:00
# else
// Scale at run-time
// Black = Transparent
// White = Opaque
HBITMAP hTmpBitamp = LoadBitmap ( g_hInstance , TEXT ( " CHARSET40 " ) ) ;
# if _DEBUG
nError = GetLastError ( ) ;
# endif
SelectObject ( hTmpDC , hTmpBitamp ) ;
# if _DEBUG
nError = GetLastError ( ) ;
# endif
2006-07-03 15:27:49 +00:00
g_hConsoleFontBrush = GetStockBrush ( WHITE_BRUSH ) ;
SelectObject ( g_hConsoleFontDC , g_hConsoleFontBrush ) ;
2006-07-02 09:57:26 +00:00
// SelectObject(hTmpDC, g_hDebugFontBrush );
# if _DEBUG
nError = GetLastError ( ) ;
# endif
2006-07-03 15:27:49 +00:00
g_hConsoleFontBitmap = CreateCompatibleBitmap (
2006-07-02 09:57:26 +00:00
hTmpDC ,
APPLE_FONT_X_REGIONSIZE / 2 , APPLE_FONT_Y_REGIONSIZE / 2
) ;
# if _DEBUG
nError = GetLastError ( ) ;
# endif
2006-07-03 15:27:49 +00:00
SelectObject ( g_hConsoleFontDC , g_hConsoleFontBitmap ) ;
2006-07-02 09:57:26 +00:00
StretchBlt (
2006-07-03 15:27:49 +00:00
g_hConsoleFontDC , // HDC hdcDest, // handle to destination DC
2006-07-02 09:57:26 +00:00
0 , 0 , // int nXOriginDest, int nYOriginDest, // y-coord of destination upper-left corner
APPLE_FONT_X_REGIONSIZE / 2 , APPLE_FONT_Y_REGIONSIZE / 2 , // int nWidthDest, int nHeightDest,
hTmpDC , // HDC hdcSrc, // handle to source DC
0 , APPLE_FONT_Y_APPLE_80COL , // int nXOriginSrc, int nYOriginSrc,
APPLE_FONT_X_REGIONSIZE , APPLE_FONT_Y_REGIONSIZE , // int nWidthSrc, int nHeightSrc,
SRCCOPY // DWORD dwRop // raster operation code
) ;
DeleteObject ( hTmpBitamp ) ;
DeleteObject ( hTmpDC ) ;
# endif
2006-07-05 21:23:13 +00:00
// DeleteDC( g_hFrameDC ); g_hDstDC = NULL;
2006-07-02 09:57:26 +00:00
2006-02-25 20:50:29 +00:00
ZeroMemory ( g_aConsoleDisplay , sizeof ( g_aConsoleDisplay ) ) ; // CONSOLE_WIDTH * CONSOLE_HEIGHT );
ConsoleInputReset ( ) ;
for ( int iWindow = 0 ; iWindow < NUM_WINDOWS ; iWindow + + )
{
WindowSplit_t * pWindow = & g_aWindowConfig [ iWindow ] ;
pWindow - > bSplit = false ;
pWindow - > eTop = ( Window_e ) iWindow ;
pWindow - > eBot = ( Window_e ) iWindow ;
}
g_iWindowThis = WINDOW_CODE ;
g_iWindowLast = WINDOW_CODE ;
WindowUpdateDisasmSize ( ) ;
2006-02-26 06:26:56 +00:00
_ConfigColorsReset ( ) ;
2006-02-25 20:50:29 +00:00
WindowUpdateConsoleDisplayedSize ( ) ;
// CLEAR THE BREAKPOINT AND WATCH TABLES
2006-06-26 16:59:48 +00:00
ZeroMemory ( g_aBreakpoints , MAX_BREAKPOINTS * sizeof ( Breakpoint_t ) ) ;
2006-02-25 20:50:29 +00:00
ZeroMemory ( g_aWatches , MAX_WATCHES * sizeof ( Watches_t ) ) ;
ZeroMemory ( g_aZeroPagePointers , MAX_ZEROPAGE_POINTERS * sizeof ( ZeroPagePointers_t ) ) ;
g_iCommand = CMD_SYMBOLS_MAIN ;
CmdSymbolsLoad ( 0 ) ;
2006-07-09 04:53:08 +00:00
# if OLD_FONT
2006-02-25 20:50:29 +00:00
// CREATE A FONT FOR THE DEBUGGING SCREEN
int nArgs = _Arg_1 ( g_sFontNameDefault ) ;
2006-07-09 04:53:08 +00:00
# endif
2006-02-25 20:50:29 +00:00
for ( int iFont = 0 ; iFont < NUM_FONTS ; iFont + + )
{
g_aFontConfig [ iFont ] . _hFont = NULL ;
2006-07-02 22:59:08 +00:00
# if USE_APPLE_FONT
2006-07-03 15:27:49 +00:00
g_aFontConfig [ iFont ] . _nFontHeight = CONSOLE_FONT_HEIGHT ;
g_aFontConfig [ iFont ] . _nFontWidthAvg = CONSOLE_FONT_WIDTH ;
g_aFontConfig [ iFont ] . _nFontWidthMax = CONSOLE_FONT_WIDTH ;
g_aFontConfig [ iFont ] . _nLineHeight = CONSOLE_FONT_HEIGHT ;
2006-07-02 22:59:08 +00:00
# endif
2006-02-25 20:50:29 +00:00
}
2006-07-09 04:53:08 +00:00
# if OLD_FONT
2006-02-25 20:50:29 +00:00
_CmdConfigFont ( FONT_INFO , g_sFontNameInfo , FIXED_PITCH | FF_MODERN , g_nFontHeight ) ; // DEFAULT_CHARSET
_CmdConfigFont ( FONT_CONSOLE , g_sFontNameConsole , FIXED_PITCH | FF_MODERN , g_nFontHeight ) ; // DEFAULT_CHARSET
_CmdConfigFont ( FONT_DISASM_DEFAULT , g_sFontNameDisasm , FIXED_PITCH | FF_MODERN , g_nFontHeight ) ; // OEM_CHARSET
2006-02-26 06:26:56 +00:00
_CmdConfigFont ( FONT_DISASM_BRANCH , g_sFontNameBranch , DEFAULT_PITCH | FF_DECORATIVE , g_nFontHeight + 3 ) ; // DEFAULT_CHARSET
2006-07-09 04:53:08 +00:00
# endif
_UpdateWindowFontHeights ( g_aFontConfig [ FONT_DISASM_DEFAULT ] . _nFontHeight ) ;
2006-02-25 20:50:29 +00:00
2006-07-03 15:27:49 +00:00
int iColor ;
iColor = FG_CONSOLE_OUTPUT ;
COLORREF nColor = gaColorPalette [ g_aColorIndex [ iColor ] ] ;
2006-07-05 21:23:13 +00:00
g_anConsoleColor [ CONSOLE_COLOR_x ] = nColor ;
2006-07-03 15:27:49 +00:00
2006-02-25 20:50:29 +00:00
/*
g_hFontDebugger = CreateFont (
g_nFontHeight // Height
, 0 // Width
, 0 // Escapement
, 0 // Orientatin
, FW_MEDIUM // Weight
, 0 // Italic
, 0 // Underline
, 0 // Strike Out
, DEFAULT_CHARSET // "OEM_CHARSET" DEFAULT_CHARSET
, OUT_DEFAULT_PRECIS
, CLIP_DEFAULT_PRECIS
, ANTIALIASED_QUALITY // DEFAULT_QUALITY
, FIXED_PITCH | FF_MODERN // HACK: MAGIC #: 4 // FIXED_PITCH
, g_sFontNameDefault ) ;
g_hFontWebDings = CreateFont (
g_nFontHeight // Height
, 0 // Width
, 0 // Escapement
, 0 // Orientatin
, FW_MEDIUM // Weight
, 0 // Italic
, 0 // Underline
, 0 // Strike Out
, DEFAULT_CHARSET // ANSI_CHARSET // OEM_CHARSET DEFAULT_CHARSET
, OUT_DEFAULT_PRECIS
, CLIP_DEFAULT_PRECIS
, ANTIALIASED_QUALITY // DEFAULT_QUALITY
, DEFAULT_PITCH | FF_DECORATIVE // FIXED_PITCH | 4 | FF_MODERN
, g_sFontNameBranch ) ;
*/
// if (g_hFontWebDings)
2006-07-05 21:23:13 +00:00
# if !USE_APPLE_FONT
2006-02-25 20:50:29 +00:00
if ( g_aFontConfig [ FONT_DISASM_BRANCH ] . _hFont )
{
2006-02-26 06:26:56 +00:00
g_iConfigDisasmBranchType = DISASM_BRANCH_FANCY ;
2006-02-25 20:50:29 +00:00
}
else
{
2006-02-26 06:26:56 +00:00
g_iConfigDisasmBranchType = DISASM_BRANCH_PLAIN ;
2006-02-25 20:50:29 +00:00
}
2006-07-05 21:23:13 +00:00
# endif
2006-02-26 06:26:56 +00:00
// ConsoleInputReset(); already called in DebugInitialize()
TCHAR sText [ CONSOLE_WIDTH ] ;
if ( _tcscmp ( g_aCommands [ NUM_COMMANDS ] . m_sName , TEXT ( __COMMANDS_VERIFY_TXT__ ) ) )
{
wsprintf ( sText , " *** ERROR *** Commands mis-matched! " ) ;
2006-05-14 00:43:19 +00:00
MessageBox ( g_hFrameWindow , sText , TEXT ( " ERROR " ) , MB_OK ) ;
2006-02-26 06:26:56 +00:00
}
if ( _tcscmp ( g_aParameters [ NUM_PARAMS ] . m_sName , TEXT ( __PARAMS_VERIFY_TXT__ ) ) )
{
wsprintf ( sText , " *** ERROR *** Parameters mis-matched! " ) ;
2006-05-14 00:43:19 +00:00
MessageBox ( g_hFrameWindow , sText , TEXT ( " ERROR " ) , MB_OK ) ;
2006-02-26 06:26:56 +00:00
}
// Check all summary help to see if it fits within the console
for ( int iCmd = 0 ; iCmd < NUM_COMMANDS ; iCmd + + )
{
char * pHelp = g_aCommands [ iCmd ] . pHelpSummary ;
if ( pHelp )
{
int nLen = _tcslen ( pHelp ) + 2 ;
2006-07-01 06:45:50 +00:00
if ( nLen > ( CONSOLE_WIDTH - 1 ) )
2006-02-26 06:26:56 +00:00
{
wsprintf ( sText , TEXT ( " Warning: %s help is %d chars " ) ,
pHelp , nLen ) ;
ConsoleBufferPush ( sText ) ;
}
}
}
# if _DEBUG
//g_bConsoleBufferPaused = true;
# endif
2006-06-26 16:59:48 +00:00
_Bookmark_Reset ( ) ;
2006-02-26 06:26:56 +00:00
CmdMOTD ( 0 ) ;
2006-02-25 20:50:29 +00:00
}
2006-05-14 05:02:08 +00:00
// wparam = 0x16
// lparam = 0x002f 0x0001
// insert = VK_INSERT
2006-02-25 20:50:29 +00:00
// Add character to the input line
//===========================================================================
2006-02-26 06:26:56 +00:00
void DebuggerInputConsoleChar ( TCHAR ch )
2006-02-25 20:50:29 +00:00
{
2006-06-12 22:06:50 +00:00
if ( ( g_nAppMode = = MODE_STEPPING ) & & ( ch = = DEBUG_EXIT_KEY ) )
{
2006-02-27 03:36:36 +00:00
g_nDebugSteps = 0 ; // Exit Debugger
2006-06-12 22:06:50 +00:00
}
2006-02-25 20:50:29 +00:00
2006-06-12 22:06:50 +00:00
if ( g_nAppMode ! = MODE_DEBUG )
2006-02-25 20:50:29 +00:00
return ;
if ( g_bConsoleBufferPaused )
return ;
2006-06-26 16:59:48 +00:00
if ( g_bIgnoreNextKey )
{
g_bIgnoreNextKey = false ;
return ;
}
2006-07-05 21:23:13 +00:00
if ( ch = = CONSOLE_COLOR_ESCAPE_CHAR )
return ;
if ( g_nConsoleInputSkip = = ch )
return ;
2006-02-26 06:26:56 +00:00
if ( ch = = CHAR_SPACE )
{
// If don't have console input, don't pass space to the input line
// exception: pass to assembler
if ( ( ! g_nConsoleInputChars ) & & ( ! g_bAssemblerInput ) )
return ;
}
2006-02-25 20:50:29 +00:00
if ( g_nConsoleInputChars > ( g_nConsoleDisplayWidth - 1 ) )
return ;
2006-02-26 06:26:56 +00:00
if ( ( ch > = CHAR_SPACE ) & & ( ch < = 126 ) ) // HACK MAGIC # 32 -> ' ', # 126
2006-02-25 20:50:29 +00:00
{
2006-06-29 05:41:04 +00:00
if ( ( ch = = TCHAR_QUOTE_DOUBLE ) | | ( ch = = TCHAR_QUOTE_SINGLE ) )
2006-02-25 20:50:29 +00:00
g_bConsoleInputQuoted = ! g_bConsoleInputQuoted ;
if ( ! g_bConsoleInputQuoted )
{
2006-06-26 16:59:48 +00:00
// TODO: must fix param matching to ignore case
2006-07-01 06:45:50 +00:00
# if ALLOW_INPUT_LOWERCASE
# else
2006-02-25 20:50:29 +00:00
ch = ( TCHAR ) CharUpper ( ( LPTSTR ) ch ) ;
2006-07-01 06:45:50 +00:00
# endif
2006-02-25 20:50:29 +00:00
}
ConsoleInputChar ( ch ) ;
2006-07-05 21:23:13 +00:00
DebuggerCursorNext ( ) ;
FrameGetDC ( ) ;
DrawConsoleInput ( ) ;
2006-02-25 20:50:29 +00:00
FrameReleaseDC ( ) ;
}
2006-05-14 05:02:08 +00:00
else
if ( ch = = 0x16 ) // HACK: Ctrl-V. WTF!?
{
2006-06-26 16:59:48 +00:00
// Support Clipboard (paste)
if ( ! IsClipboardFormatAvailable ( CF_TEXT ) )
return ;
2006-05-14 05:02:08 +00:00
2006-06-26 16:59:48 +00:00
if ( ! OpenClipboard ( g_hFrameWindow ) )
return ;
2006-05-14 05:02:08 +00:00
HGLOBAL hClipboard ;
LPTSTR pData ;
2006-06-26 16:59:48 +00:00
hClipboard = GetClipboardData ( CF_TEXT ) ;
if ( hClipboard ! = NULL )
{
pData = ( char * ) GlobalLock ( hClipboard ) ;
if ( pData ! = NULL )
{
2006-05-14 05:02:08 +00:00
LPTSTR pSrc = pData ;
char c ;
while ( true )
{
c = * pSrc + + ;
if ( ! c )
break ;
if ( c = = CHAR_CR )
{
# if WIN32
// Eat char
# endif
# if MACOSX
# pragma error( "TODO: Mac port - handle CR / LF")
# endif
}
else
if ( c = = CHAR_LF )
{
# if WIN32
DebuggerProcessCommand ( true ) ;
# endif
# if MACOSX
# pragma error( "TODO: Mac port - handle CR / LF")
# endif
}
else
{
// If we didn't want verbatim, we could do:
// DebuggerInputConsoleChar( c );
if ( ( c > = CHAR_SPACE ) & & ( c < = 126 ) ) // HACK MAGIC # 32 -> ' ', # 126
ConsoleInputChar ( c ) ;
}
}
2006-06-26 16:59:48 +00:00
GlobalUnlock ( hClipboard ) ;
}
}
CloseClipboard ( ) ;
2006-05-14 05:02:08 +00:00
UpdateDisplay ( UPDATE_CONSOLE_DISPLAY ) ;
}
2006-02-25 20:50:29 +00:00
}
2006-02-26 06:26:56 +00:00
// Triggered when ENTER is pressed, or via script
//===========================================================================
Update_t DebuggerProcessCommand ( const bool bEchoConsoleInput )
{
Update_t bUpdateDisplay = UPDATE_NOTHING ;
2006-07-09 04:53:08 +00:00
char sText [ CONSOLE_WIDTH ] ;
2006-02-26 06:26:56 +00:00
if ( bEchoConsoleInput )
ConsoleDisplayPush ( ConsoleInputPeek ( ) ) ;
if ( g_bAssemblerInput )
{
if ( g_nConsoleInputChars )
{
ParseInput ( g_pConsoleInput , false ) ; // Don't cook the args
bUpdateDisplay | = _CmdAssemble ( g_nAssemblerAddress , 0 , g_nArgRaw ) ;
}
else
{
AssemblerOff ( ) ;
int nDelayedTargets = AssemblerDelayedTargetsSize ( ) ;
if ( nDelayedTargets )
{
2006-07-09 04:53:08 +00:00
sprintf ( sText , " Asm: %d sym declared, not defined " , nDelayedTargets ) ;
2006-02-26 06:26:56 +00:00
ConsoleDisplayPush ( sText ) ;
bUpdateDisplay | = UPDATE_CONSOLE_DISPLAY ;
}
}
ConsoleInputReset ( ) ;
2006-07-05 21:23:13 +00:00
bUpdateDisplay | = UPDATE_CONSOLE_DISPLAY | UPDATE_CONSOLE_INPUT ;
2006-02-26 06:26:56 +00:00
ConsoleUpdate ( ) ; // udpate console, don't pause
}
else
if ( g_nConsoleInputChars )
{
// BufferedInputPush(
// Handle Buffered Input
// while ( BufferedInputPeek() )
int nArgs = ParseInput ( g_pConsoleInput ) ;
if ( nArgs = = ARG_SYNTAX_ERROR )
{
2006-07-09 04:53:08 +00:00
sprintf ( sText , " Syntax error: %s " , g_aArgs [ 0 ] . sArg ) ;
2006-02-26 06:26:56 +00:00
bUpdateDisplay | = ConsoleDisplayError ( sText ) ;
}
else
{
bUpdateDisplay | = ExecuteCommand ( nArgs ) ; // ParseInput());
}
if ( ! g_bConsoleBufferPaused )
{
ConsoleInputReset ( ) ;
}
}
return bUpdateDisplay ;
}
2006-02-25 20:50:29 +00:00
//===========================================================================
2006-02-26 06:26:56 +00:00
void DebuggerProcessKey ( int keycode )
//void DebugProcessCommand (int keycode)
2006-02-25 20:50:29 +00:00
{
2006-06-12 22:06:50 +00:00
if ( g_nAppMode ! = MODE_DEBUG )
2006-02-25 20:50:29 +00:00
return ;
if ( g_bDebuggerViewingAppleOutput )
{
2006-06-12 22:06:50 +00:00
// Normally any key press takes us out of "Viewing Apple Output" g_nAppMode
// VK_F# are already processed, so we can't use them to cycle next video g_nAppMode
// if ((g_nAppMode != MODE_LOGO) && (g_nAppMode != MODE_DEBUG))
2006-02-25 20:50:29 +00:00
g_bDebuggerViewingAppleOutput = false ;
UpdateDisplay ( UPDATE_ALL ) ; // 1
return ;
}
Update_t bUpdateDisplay = UPDATE_NOTHING ;
// For long output, allow user to read it
if ( g_nConsoleBuffer )
{
if ( ( VK_SPACE = = keycode ) | | ( VK_RETURN = = keycode ) | | ( VK_TAB = = keycode ) | | ( VK_ESCAPE = = keycode ) )
{
2006-07-05 21:23:13 +00:00
int nLines = MIN ( g_nConsoleBuffer , g_nConsoleDisplayLines - 1 ) ; // was -2
2006-02-25 20:50:29 +00:00
if ( VK_ESCAPE = = keycode ) // user doesn't want to read all this stu
{
nLines = g_nConsoleBuffer ;
}
ConsoleBufferTryUnpause ( nLines ) ;
// don't really need since 'else if (keycode = VK_BACK)' but better safe then sorry
keycode = 0 ; // don't single-step
}
2006-07-05 21:23:13 +00:00
bUpdateDisplay | = UPDATE_CONSOLE_DISPLAY | UPDATE_CONSOLE_INPUT ;
2006-02-25 20:50:29 +00:00
ConsoleDisplayPause ( ) ;
}
else
2006-07-05 21:23:13 +00:00
// If have console input, don't invoke curmovement
2006-06-12 22:06:50 +00:00
// TODO: Probably should disable all "movement" keys to map them to line editing g_nAppMode
2006-02-25 20:50:29 +00:00
if ( ( keycode = = VK_SPACE ) & & g_nConsoleInputChars )
return ;
else if ( keycode = = VK_ESCAPE )
{
2006-06-29 05:41:04 +00:00
g_bConsoleInputQuoted = false ;
2006-07-05 21:23:13 +00:00
ConsoleInputReset ( ) ;
2006-02-25 20:50:29 +00:00
bUpdateDisplay | = UPDATE_CONSOLE_INPUT ;
}
else if ( keycode = = VK_BACK )
{
2006-06-29 05:41:04 +00:00
// Note: Checks prev char if QUTOE - SINGLE or DOUBLE
2006-07-05 21:23:13 +00:00
// ConsoleUpdateCursor( CHAR_SPACE );
2006-02-25 20:50:29 +00:00
if ( ! ConsoleInputBackSpace ( ) )
{
// CmdBeep();
}
bUpdateDisplay | = UPDATE_CONSOLE_INPUT ;
}
else if ( keycode = = VK_RETURN )
{
2006-07-05 21:23:13 +00:00
// ConsoleUpdateCursor( 0 );
ConsoleScrollEnd ( ) ;
2006-02-26 06:26:56 +00:00
bUpdateDisplay | = DebuggerProcessCommand ( true ) ; // copy console input to console output
2006-07-05 21:23:13 +00:00
bUpdateDisplay | = UPDATE_CONSOLE_DISPLAY ;
2006-02-25 20:50:29 +00:00
}
2007-03-31 14:45:44 +00:00
else if ( ( keycode = = VK_OEM_3 ) | | // US: Tilde ~ (key to the immediate left of numeral 1)
( keycode = = VK_OEM_8 ) ) // UK: Logical NOT <20> (key to the immediate left of numeral 1)
2006-02-25 20:50:29 +00:00
{
2006-07-05 21:23:13 +00:00
if ( KeybGetCtrlStatus ( ) )
2006-02-25 20:50:29 +00:00
{
2006-07-05 21:23:13 +00:00
// Switch to Console Window
if ( g_iWindowThis ! = WINDOW_CONSOLE )
{
CmdWindowViewConsole ( 0 ) ;
}
else // switch back to last window
{
CmdWindowLast ( 0 ) ;
}
bUpdateDisplay | = UPDATE_ALL ;
2006-02-25 20:50:29 +00:00
}
2006-07-05 21:23:13 +00:00
else
2006-02-25 20:50:29 +00:00
{
2006-07-05 21:23:13 +00:00
g_nConsoleInputSkip = 0 ; // VK_OEM_3; // don't pass to DebugProcessChar()
DebuggerInputConsoleChar ( ' ~ ' ) ;
2006-02-25 20:50:29 +00:00
}
2006-07-05 21:23:13 +00:00
g_nConsoleInputSkip = ' ~ ' ; // VK_OEM_3; // don't pass to DebugProcessChar()
2006-02-25 20:50:29 +00:00
}
else
{
switch ( keycode )
{
case VK_TAB :
{
if ( g_nConsoleInputChars )
{
// TODO: TabCompletionCommand()
// TODO: TabCompletionSymbol()
bUpdateDisplay | = ConsoleInputTabCompletion ( ) ;
}
else
if ( KeybGetCtrlStatus ( ) & & KeybGetShiftStatus ( ) )
bUpdateDisplay | = CmdWindowCyclePrev ( 0 ) ;
else
if ( KeybGetCtrlStatus ( ) )
bUpdateDisplay | = CmdWindowCycleNext ( 0 ) ;
else
bUpdateDisplay | = CmdCursorJumpPC ( CURSOR_ALIGN_CENTER ) ;
break ;
}
case VK_SPACE :
2006-02-26 06:26:56 +00:00
if ( g_bAssemblerInput )
{
// if (g_nConsoleInputChars)
// {
// ParseInput( g_pConsoleInput, false ); // Don't cook the args
// bUpdateDisplay |= _CmdAssemble( g_nAssemblerAddress, 0, g_nArgRaw );
// }
}
2006-02-25 20:50:29 +00:00
else
2006-02-26 06:26:56 +00:00
{
if ( KeybGetShiftStatus ( ) )
bUpdateDisplay | = CmdStepOut ( 0 ) ;
else
if ( KeybGetCtrlStatus ( ) )
bUpdateDisplay | = CmdStepOver ( 0 ) ;
else
bUpdateDisplay | = CmdTrace ( 0 ) ;
}
2006-02-25 20:50:29 +00:00
break ;
case VK_HOME :
if ( g_iWindowThis = = WINDOW_CONSOLE )
{
ConsoleScrollHome ( ) ;
}
else
if ( g_nConsoleInputChars > 0 )
{
if ( KeybGetShiftStatus ( ) )
{
bUpdateDisplay | = ConsoleScrollHome ( ) ;
}
else
{
// Move cursor to start of console input
}
}
else
{
// If you really want $000 at the top of the screen...
2006-06-25 03:43:49 +00:00
// g_nDisasmTopAddress = _6502_MEM_BEGIN;
2006-02-25 20:50:29 +00:00
// DisasmCalcCurFromTopAddress();
// DisasmCalcBotFromTopAddress();
2006-06-25 03:43:49 +00:00
g_nDisasmCurAddress = _6502_MEM_BEGIN ;
2006-02-25 20:50:29 +00:00
DisasmCalcTopBotAddress ( ) ;
}
bUpdateDisplay | = UPDATE_DISASM ;
break ;
case VK_END :
if ( g_iWindowThis = = WINDOW_CONSOLE )
{
ConsoleScrollEnd ( ) ;
}
else
if ( g_nConsoleInputChars > 0 )
{
if ( KeybGetShiftStatus ( ) )
{
bUpdateDisplay | = ConsoleScrollEnd ( ) ;
}
else
{
// Move cursor to end of console input
}
}
else
{
// If you really want $8000 at the top of the screen...
2006-06-25 03:43:49 +00:00
// g_nDisasmTopAddress = (_6502_MEM_END / 2) + 1;
2006-02-25 20:50:29 +00:00
// DisasmCalcCurFromTopAddress();
// DisasmCalcTopBotAddress();
2006-06-25 03:43:49 +00:00
g_nDisasmCurAddress = ( _6502_MEM_END / 2 ) + 1 ;
2006-02-25 20:50:29 +00:00
DisasmCalcTopBotAddress ( ) ;
}
bUpdateDisplay | = UPDATE_DISASM ;
break ;
case VK_PRIOR : // VK_PAGE_UP
if ( g_iWindowThis = = WINDOW_CONSOLE )
{
bUpdateDisplay | = ConsoleScrollPageUp ( ) ;
}
else
if ( g_nConsoleInputChars > 0 )
{
if ( KeybGetShiftStatus ( ) )
{
bUpdateDisplay | = ConsoleScrollPageUp ( ) ;
}
else
{
// Scroll through console input history
}
}
else
{
if ( KeybGetShiftStatus ( ) )
bUpdateDisplay | = CmdCursorPageUp256 ( 0 ) ;
else
if ( KeybGetCtrlStatus ( ) )
bUpdateDisplay | = CmdCursorPageUp4K ( 0 ) ;
else
bUpdateDisplay | = CmdCursorPageUp ( 0 ) ;
}
break ;
case VK_NEXT : // VK_PAGE_DN
if ( g_iWindowThis = = WINDOW_CONSOLE )
{
bUpdateDisplay | = ConsoleScrollPageDn ( ) ;
}
else
if ( g_nConsoleInputChars > 0 )
{
if ( KeybGetShiftStatus ( ) )
{
bUpdateDisplay | = ConsoleScrollPageDn ( ) ;
}
else
{
// Scroll through console input history
}
}
else
{
if ( KeybGetShiftStatus ( ) )
bUpdateDisplay | = CmdCursorPageDown256 ( 0 ) ;
else
if ( KeybGetCtrlStatus ( ) )
bUpdateDisplay | = CmdCursorPageDown4K ( 0 ) ;
else
bUpdateDisplay | = CmdCursorPageDown ( 0 ) ;
}
break ;
case VK_UP :
if ( g_iWindowThis = = WINDOW_CONSOLE )
{
bUpdateDisplay | = ConsoleScrollUp ( 1 ) ;
}
else
if ( g_nConsoleInputChars > 0 )
{
if ( KeybGetShiftStatus ( ) )
{
bUpdateDisplay | = ConsoleScrollUp ( 1 ) ;
}
else
{
// Scroll through console input history
}
}
else
{
// Shift the Top offset up by 1 byte
// i.e. no smart disassembly like LineUp()
2006-06-26 16:59:48 +00:00
// Normally UP moves to the previous "line" which may be multiple bytes.
2006-02-25 20:50:29 +00:00
if ( KeybGetShiftStatus ( ) )
bUpdateDisplay | = CmdCursorLineUp ( 1 ) ;
else
2006-06-26 16:59:48 +00:00
bUpdateDisplay | = CmdCursorLineUp ( 0 ) ; // smart disassembly
2006-02-25 20:50:29 +00:00
}
break ;
case VK_DOWN :
if ( g_iWindowThis = = WINDOW_CONSOLE )
{
bUpdateDisplay | = ConsoleScrollDn ( 1 ) ;
}
else
if ( g_nConsoleInputChars > 0 )
{
if ( KeybGetShiftStatus ( ) )
{
bUpdateDisplay | = ConsoleScrollDn ( 1 ) ;
}
else
{
// Scroll through console input history
}
}
else
{
if ( KeybGetCtrlStatus ( ) )
bUpdateDisplay | = CmdCursorRunUntil ( 0 ) ;
else
if ( KeybGetShiftStatus ( ) )
// Shift the Offest down by 1 byte
// i.e. no smart disassembly like LineDown()
bUpdateDisplay | = CmdCursorLineDown ( 1 ) ;
else
bUpdateDisplay | = CmdCursorLineDown ( 0 ) ;
}
break ;
case VK_RIGHT :
if ( KeybGetCtrlStatus ( ) )
bUpdateDisplay | = CmdCursorSetPC ( g_nDisasmCurAddress ) ;
else
if ( KeybGetShiftStatus ( ) )
bUpdateDisplay | = CmdCursorJumpPC ( CURSOR_ALIGN_TOP ) ;
else
2006-06-26 16:59:48 +00:00
if ( KeybGetAltStatus ( ) )
2006-02-25 20:50:29 +00:00
bUpdateDisplay | = CmdCursorJumpPC ( CURSOR_ALIGN_CENTER ) ;
2006-06-26 16:59:48 +00:00
else
bUpdateDisplay | = CmdCursorFollowTarget ( CURSOR_ALIGN_TOP ) ;
2006-02-25 20:50:29 +00:00
break ;
case VK_LEFT :
if ( KeybGetShiftStatus ( ) )
bUpdateDisplay | = CmdCursorJumpRetAddr ( CURSOR_ALIGN_TOP ) ; // Jump to Caller
else
bUpdateDisplay | = CmdCursorJumpRetAddr ( CURSOR_ALIGN_CENTER ) ;
break ;
2006-06-26 16:59:48 +00:00
default :
if ( ( keycode > = ' 0 ' ) & & ( keycode < = ' 9 ' ) )
{
2006-07-01 06:45:50 +00:00
int nArgs = 1 ;
2006-06-26 16:59:48 +00:00
int iBookmark = keycode - ' 0 ' ;
if ( KeybGetCtrlStatus ( ) & & KeybGetShiftStatus ( ) )
{
2006-07-01 06:45:50 +00:00
nArgs = 2 ;
g_aArgs [ 1 ] . nValue = iBookmark ;
g_aArgs [ 2 ] . nValue = g_nDisasmCurAddress ;
bUpdateDisplay | = CmdBookmarkAdd ( nArgs ) ;
2006-06-26 16:59:48 +00:00
g_bIgnoreNextKey = true ;
}
else
if ( KeybGetCtrlStatus ( ) )
{
2006-07-01 06:45:50 +00:00
nArgs = 1 ;
g_aArgs [ 1 ] . nValue = iBookmark ;
bUpdateDisplay | = CmdBookmarkGoto ( nArgs ) ;
2006-06-26 16:59:48 +00:00
g_bIgnoreNextKey = true ;
}
}
break ;
2006-02-25 20:50:29 +00:00
} // switch
}
2007-03-31 14:45:44 +00:00
if ( bUpdateDisplay & & ! g_bDebuggerViewingAppleOutput ) // & UPDATE_BACKGROUND)
2006-02-25 20:50:29 +00:00
UpdateDisplay ( bUpdateDisplay ) ;
}
// Still called from external file
void DebugDisplay ( BOOL bDrawBackground )
{
Update_t bUpdateFlags = UPDATE_ALL ;
// if (! bDrawBackground)
// bUpdateFlags &= ~UPDATE_BACKGROUND;
UpdateDisplay ( bUpdateFlags ) ;
}
2006-07-05 21:23:13 +00:00
//===========================================================================
void DebuggerUpdate ( )
{
DebuggerCursorUpdate ( ) ;
}
//===========================================================================
void DebuggerCursorUpdate ( )
{
if ( g_nAppMode ! = MODE_DEBUG )
return ;
2006-09-14 20:11:38 +00:00
const int nUpdatesPerSecond = 4 ;
2007-03-23 22:26:35 +00:00
const DWORD nUpdateInternal_ms = 1000 / nUpdatesPerSecond ;
2006-07-05 21:23:13 +00:00
static DWORD nBeg = GetTickCount ( ) ; // timeGetTime();
DWORD nNow = GetTickCount ( ) ; // timeGetTime();
2007-03-31 14:45:44 +00:00
if ( ( ( nNow - nBeg ) > = nUpdateInternal_ms ) & & ! g_bDebuggerViewingAppleOutput )
2006-07-05 21:23:13 +00:00
{
nBeg = nNow ;
DebuggerCursorNext ( ) ;
FrameGetDC ( ) ;
DrawConsoleCursor ( ) ;
FrameReleaseDC ( ) ;
}
2007-03-23 22:26:35 +00:00
else
{
Sleep ( 10 ) ; // Stop process hogging CPU
}
2006-07-05 21:23:13 +00:00
}
//===========================================================================
void DebuggerCursorNext ( )
{
g_bInputCursor ^ = true ;
if ( g_bInputCursor )
ConsoleUpdateCursor ( g_aInputCursor [ g_iInputCursor ] ) ;
else
ConsoleUpdateCursor ( 0 ) ; // show char under cursor
}
//===========================================================================
//char DebuggerCursorGet()
//{
// return g_aInputCursor[ g_iInputCursor ];
//}
//===========================================================================
void DebuggerMouseClick ( int x , int y )
{
2006-07-09 15:43:17 +00:00
if ( g_nAppMode ! = MODE_DEBUG )
return ;
2006-07-05 21:23:13 +00:00
int nFontWidth = g_aFontConfig [ FONT_DISASM_DEFAULT ] . _nFontWidthAvg ;
int nFontHeight = g_aFontConfig [ FONT_DISASM_DEFAULT ] . _nLineHeight ;
// do picking
FrameGetDC ( ) ;
int cx = ( x - VIEWPORTX ) / nFontWidth ;
int cy = ( y - VIEWPORTY ) / nFontHeight ;
# if _DEBUG
char sText [ CONSOLE_WIDTH ] ;
sprintf ( sText , " x:%d y:%d cx:%d cy:%d " , x , y , cx , cy ) ;
ConsoleDisplayPush ( sText ) ;
DebugDisplay ( UPDATE_CONSOLE_DISPLAY ) ;
# endif
if ( g_iWindowThis = = WINDOW_CODE )
{
// Display_AssemblyLine -- need Tabs
if ( cx = = 4 )
{
g_bConfigDisasmAddressColon ^ = true ;
DebugDisplay ( UPDATE_DISASM ) ;
}
else
if ( ( cx > 4 ) & ( cx < = 13 ) )
{
g_bConfigDisasmOpcodesView ^ = true ;
DebugDisplay ( UPDATE_DISASM ) ;
}
else
if ( ( cx > = 51 ) & & ( cx < = 60 ) & & ( cy = = 3 ) )
{
CmdCursorJumpPC ( CURSOR_ALIGN_CENTER ) ;
DebugDisplay ( UPDATE_DISASM ) ;
}
}
FrameReleaseDC ( ) ;
}