/** @param nArgs Number of raw args. @param bProcessMask Bit-flags of which arg operators to process. Note: The number of args can be changed via: address1,length Length address1:address2 Range address1+delta Delta address1-delta Delta //=========================================================================== */ int ArgsCook ( const int nArgs, const int bProcessMask ) { const int BASE = 16; // hex TCHAR *pSrc = NULL; TCHAR *pEnd2 = NULL; int nArg = nArgs; int iArg = 1; Arg_t *pArg = NULL; Arg_t *pPrev = NULL; Arg_t *pNext = NULL; WORD nAddressArg; WORD nAddressRHS; WORD nAddressSym; WORD nAddressVal; int nParamLen = 0; int nArgsLeft = 0; while (iArg <= nArg) { pArg = & (g_aArgs[ iArg ]); pSrc = & (pArg->sArg[ 0 ]); if (bProcessMask & (1 << TOKEN_DOLLAR)) if (pArg->eToken == TOKEN_DOLLAR) // address { // TODO: Need to flag was a DOLLAR token for assembler pNext = NULL; nArgsLeft = (nArg - iArg); if (nArgsLeft > 0) { pNext = pArg + 1; _Arg_Shift( iArg + 1, nArgs, iArg ); nArg--; iArg--; // inc for start of next loop // Don't do register lookup pArg->bType |= TYPE_NO_REG; } else return ARG_SYNTAX_ERROR; } if (pArg->bType & TYPE_OPERATOR) // prev op type == address? { pPrev = NULL; // pLHS pNext = NULL; // pRHS nParamLen = 0; if (pArg->eToken == TOKEN_HASH) // HASH # immediate nParamLen = 1; nArgsLeft = (nArg - iArg); if (nArgsLeft < nParamLen) { return ARG_SYNTAX_ERROR; } pPrev = pArg - 1; if (nArgsLeft > 0) // These ops take at least 1 argument { pNext = pArg + 1; pSrc = &pNext->sArg[0]; nAddressVal = 0; if (ArgsGetValue( pNext, & nAddressRHS )) nAddressVal = nAddressRHS; bool bFound = FindAddressFromSymbol( pSrc, & nAddressSym ); if (bFound) { nAddressVal = nAddressSym; pArg->bSymbol = true; } if (bProcessMask & (1 << TOKEN_COMMA)) if (pArg->eToken == TOKEN_COMMA) // COMMMA , length { pPrev->nVal2 = nAddressVal; pPrev->eToken = TOKEN_COMMA; pPrev->bType |= TYPE_ADDRESS; pPrev->bType |= TYPE_LENGTH; nParamLen = 2; } if (bProcessMask & (1 << TOKEN_COLON)) if (pArg->eToken == TOKEN_COLON) // COLON : range { pPrev->nVal2 = nAddressVal; pPrev->eToken = TOKEN_COLON; pPrev->bType |= TYPE_ADDRESS; pPrev->bType |= TYPE_RANGE; nParamLen = 2; } if (bProcessMask & (1 << TOKEN_AMPERSAND)) if (pArg->eToken == TOKEN_AMPERSAND) // AND & delta { if (! ArgsGetImmediateValue( pNext, & nAddressRHS )) { ArgsGetRegisterValue( pNext, & nAddressRHS ); } pPrev->nVal1 &= nAddressRHS; pPrev->bType |= TYPE_VALUE; // signal already up to date nParamLen = 2; } if (bProcessMask & (1 << TOKEN_PIPE)) if (pArg->eToken == TOKEN_PIPE) // OR | delta { if (! ArgsGetImmediateValue( pNext, & nAddressRHS )) { ArgsGetRegisterValue( pNext, & nAddressRHS ); } pPrev->nVal1 |= nAddressRHS; pPrev->bType |= TYPE_VALUE; // signal already up to date nParamLen = 2; } if (bProcessMask & (1 << TOKEN_CARET)) if (pArg->eToken == TOKEN_CARET) // XOR ^ delta { if (! ArgsGetImmediateValue( pNext, & nAddressRHS )) { ArgsGetRegisterValue( pNext, & nAddressRHS ); } pPrev->nVal1 ^= nAddressRHS; pPrev->bType |= TYPE_VALUE; // signal already up to date nParamLen = 2; } if (bProcessMask & (1 << TOKEN_PLUS)) if (pArg->eToken == TOKEN_PLUS) // PLUS + delta { if (! ArgsGetImmediateValue( pNext, & nAddressRHS )) { ArgsGetRegisterValue( pNext, & nAddressRHS ); } pPrev->nVal1 += nAddressRHS; pPrev->bType |= TYPE_VALUE; // signal already up to date nParamLen = 2; } if (bProcessMask & (1 << TOKEN_MINUS)) if (pArg->eToken == TOKEN_MINUS) // MINUS - delta { if (! ArgsGetImmediateValue( pNext, & nAddressRHS )) { ArgsGetRegisterValue( pNext, & nAddressRHS ); } pPrev->nVal1 -= nAddressRHS; pPrev->bType |= TYPE_VALUE; // signal already up to date nParamLen = 2; } if (bProcessMask & (1 << TOKEN_PERCENT)) if (pArg->eToken == TOKEN_PERCENT) // PERCENT % delta { if (! ArgsGetImmediateValue( pNext, & nAddressRHS )) { ArgsGetRegisterValue( pNext, & nAddressRHS ); } pPrev->nVal1 %= nAddressRHS; pPrev->bType |= TYPE_VALUE; // signal already up to date nParamLen = 2; } if (bProcessMask & (1 << TOKEN_FSLASH)) if (pArg->eToken == TOKEN_FSLASH) // FORWARD SLASH / delta { if (pNext->eToken == TOKEN_FSLASH) // Comment { nArg = iArg - 1; return nArg; } if (! ArgsGetImmediateValue( pNext, & nAddressRHS )) { ArgsGetRegisterValue( pNext, & nAddressRHS ); } if (! nAddressRHS) nAddressRHS = 1; // divide by zero bug pPrev->nVal1 /= nAddressRHS; pPrev->bType |= TYPE_VALUE; // signal already up to date nParamLen = 2; } if (bProcessMask & (1 << TOKEN_EQUAL)) if (pArg->eToken == TOKEN_EQUAL) // EQUAL = assign { pPrev->nVal1 = nAddressRHS; pPrev->bType |= TYPE_VALUE; // signal already up to date nParamLen = 0; // need token for Smart BreakPoints } if (bProcessMask & (1 << TOKEN_HASH)) if (pArg->eToken == TOKEN_HASH) // HASH # immediate { _Arg_Shift( iArg + nParamLen, nArgs, iArg ); nArg--; pArg->nVal1 = nAddressRHS; pArg->bSymbol = false; pArg->bType = TYPE_VALUE | TYPE_ADDRESS | TYPE_NO_REG | TYPE_NO_SYM; nParamLen = 0; } if (bProcessMask & (1 << TOKEN_LESS_THAN)) if (pArg->eToken == TOKEN_LESS_THAN) // < { nParamLen = 0; } if (bProcessMask & (1 << TOKEN_GREATER_THAN)) if (pArg->eToken == TOKEN_GREATER_THAN) // > { nParamLen = 0; } if (bProcessMask & (1 << TOKEN_EXCLAMATION)) if (pArg->eToken == TOKEN_EXCLAMATION) // NOT_EQUAL ! { if (! ArgsGetImmediateValue( pNext, & nAddressRHS )) { if (! ArgsGetRegisterValue( pNext, & nAddressRHS )) { nAddressRHS = nAddressVal; } } pArg->nVal1 = ~nAddressRHS; pArg->bType |= TYPE_VALUE; // signal already up to date // Don't remove, since "SYM ! symbol" needs token to remove symbol } if (nParamLen) { _Arg_Shift( iArg + nParamLen, nArgs, iArg ); nArg -= nParamLen; iArg = 0; // reset args, to handle multiple operators } } else return ARG_SYNTAX_ERROR; } else // not an operator, try (1) address, (2) symbol lookup { nAddressArg = (WORD)(_tcstoul( pSrc, &pEnd2, BASE) & _6502_END_MEM_ADDRESS); if (! (pArg->bType & TYPE_NO_REG)) { ArgsGetRegisterValue( pArg, & nAddressArg ); } nAddressVal = nAddressArg; bool bFound = false; if (! (pArg->bType & TYPE_NO_SYM)) { bFound = FindAddressFromSymbol( pSrc, & nAddressSym ); if (bFound) { nAddressVal = nAddressSym; pArg->bSymbol = true; } } if (! (pArg->bType & TYPE_VALUE)) // already up to date? pArg->nVal1 = nAddressVal; pArg->bType |= TYPE_ADDRESS; } iArg++; } return nArg; }
//=========================================================================== Update_t _CmdSymbolsCommon ( int nArgs, int bSymbolTables ) { if (! nArgs) { return Help_Arg_1( g_iCommand ); } Update_t iUpdate = _CmdSymbolsUpdate( nArgs, bSymbolTables ); if (iUpdate != UPDATE_NOTHING) return iUpdate; TCHAR sText[ CONSOLE_WIDTH ]; int iArg = 0; while (iArg++ <= nArgs) { 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( (SymbolTable_Index_e) iTable ); sprintf( sText, TEXT(" Cleared symbol table: %s%s") , CHC_STRING, g_aSymbolTableNames[ iTable ] ); ConsolePrint( sText ); iUpdate |= ConsoleUpdate(); return iUpdate; } else { // Shouldn't have multiple symbol tables selected // nArgs = _Arg_1( eSymbolsTable ); ConsoleBufferPush( TEXT(" Error: Unknown Symbol Table Type") ); return ConsoleUpdate(); } } else if (iParam == PARAM_LOAD) { nArgs = _Arg_Shift( iArg, nArgs); Update_t bUpdate = CmdSymbolsLoad( nArgs ); int iTable = _GetSymbolTableFromFlag( bSymbolTables ); if (iTable != NUM_SYMBOL_TABLES) { if( bUpdate & UPDATE_SYMBOLS ) { //sprintf( sText, " Symbol Table: %s%s%s, %sloaded symbols: %s%d" // , CHC_STRING, g_aSymbolTableNames[ iTable ] // , CHC_DEFAULT, CHC_DEFAULT // , CHC_NUM_DEC, g_nSymbolsLoaded //); _CmdSymbolsInfoHeader( iTable, sText, g_nSymbolsLoaded ); ConsolePrint( 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 if (iParam == PARAM_ON) { g_bDisplaySymbolTables |= bSymbolTables; int iTable = _GetSymbolTableFromFlag( bSymbolTables ); if (iTable != NUM_SYMBOL_TABLES) { _CmdSymbolsInfoHeader( iTable, sText ); ConsolePrint( sText ); } return ConsoleUpdate() | UPDATE_DISASM; } else if (iParam == PARAM_OFF) { g_bDisplaySymbolTables &= ~bSymbolTables; int iTable = _GetSymbolTableFromFlag( bSymbolTables ); if (iTable != NUM_SYMBOL_TABLES) { _CmdSymbolsInfoHeader( iTable, sText ); ConsolePrint( sText ); } return ConsoleUpdate() | UPDATE_DISASM; } } else { return _CmdSymbolsListTables( nArgs, bSymbolTables ); } } return ConsoleUpdate(); }