/**
	@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;
}
예제 #2
0
//===========================================================================
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();
}