beebasm

changeset 41:b6d9dd6812d5

Fixed EQUD bug. Created ERROR directive.
author RichTW <richtw1@gmail.com>
date Thu Jun 16 09:21:54 2011 +0200
parents 7699ee2b4db7
children 19002d99b133
files about.txt beebasm.exe src/Makefile src/asmexception.h src/assemble.cpp src/commands.cpp src/discimage.cpp src/expression.cpp src/globaldata.cpp src/globaldata.h src/lineparser.h src/main.cpp src/sourcecode.h
diffstat 13 files changed, 137 insertions(+), 13 deletions(-) [+]
line diff
     1.1 --- a/about.txt	Mon Apr 25 17:39:31 2011 +0200
     1.2 +++ b/about.txt	Thu Jun 16 09:21:54 2011 +0200
     1.3 @@ -1,6 +1,6 @@
     1.4  *******************************************************************************
     1.5  *                                                                             *
     1.6 -*                               BeebAsm V1.05                                 *
     1.7 +*                               BeebAsm V1.06                                 *
     1.8  *                                                                             *
     1.9  *             A portable 6502 assembler with BBC Micro style syntax           *
    1.10  *                                                                             *
    1.11 @@ -408,6 +408,21 @@
    1.12              PRINT "Value of label 'start' =", ~start
    1.13              PRINT "numdots =", numdots, "dottable size =", dotend-dotstart
    1.14  
    1.15 +			
    1.16 +ERROR "message"
    1.17 +
    1.18 +  Causes BeebAsm to abort assembly with the provided error message.  This can
    1.19 +  be useful for enforcing certain constraints on generated code, for example:
    1.20 +  
    1.21 +            .table
    1.22 +			    FOR n, 1, 32
    1.23 +				    EQUB 255 / n
    1.24 +			    NEXT
    1.25 +				
    1.26 +			IF HI(P%)<>HI(table)
    1.27 +			    ERROR "Table crosses page boundary"
    1.28 +			ENDIF
    1.29 +
    1.30  
    1.31  FOR <var>, start, end [, step] ... NEXT
    1.32  
    1.33 @@ -693,6 +708,8 @@
    1.34  
    1.35  9. VERSION HISTORY
    1.36  
    1.37 +16/06/2011  1.06  Fixed bug in EQUD with unsigned int values.
    1.38 +                  Added ERROR directive.
    1.39  25/04/2011  1.05  Added macros.
    1.40                    Added PUTFILE and PUTBASIC (to tokenise a plaintext BASIC
    1.41  				  file, using code by Thomas Harte).
     2.1 Binary file beebasm.exe has changed
     3.1 --- a/src/Makefile	Mon Apr 25 17:39:31 2011 +0200
     3.2 +++ b/src/Makefile	Thu Jun 16 09:21:54 2011 +0200
     3.3 @@ -52,7 +52,6 @@
     3.4  # Parameters to the executable
     3.5  
     3.6  PARAMS			:=		-i ../demo.6502 -do ../demo.ssd -boot Code -v
     3.7 -#PARAMS			:=		-i ../test.6502 -v -do ../test.ssd
     3.8  
     3.9  
    3.10  
     4.1 --- a/src/asmexception.h	Mon Apr 25 17:39:31 2011 +0200
     4.2 +++ b/src/asmexception.h	Thu Jun 16 09:21:54 2011 +0200
     4.3 @@ -45,7 +45,6 @@
     4.4  };
     4.5  
     4.6  
     4.7 -
     4.8  /*************************************************************************************************/
     4.9  /**
    4.10  	@class		AsmException_FileError
    4.11 @@ -269,4 +268,35 @@
    4.12  DEFINE_ASSEMBLE_EXCEPTION( FileOpen, "Error opening file." );
    4.13  DEFINE_ASSEMBLE_EXCEPTION( FileRead, "Error reading file." );
    4.14  
    4.15 +
    4.16 +/*************************************************************************************************/
    4.17 +/**
    4.18 +	@class		AsmException_UserError
    4.19 +
    4.20 +	Exception class used for user generated errors
    4.21 +*/
    4.22 +/*************************************************************************************************/
    4.23 +class AsmException_UserError : public AsmException_SyntaxError
    4.24 +{
    4.25 +public:
    4.26 +
    4.27 +	AsmException_UserError( std::string line, int column, std::string message )
    4.28 +		:	AsmException_SyntaxError( line, column ),
    4.29 +			m_message( message )
    4.30 +	{
    4.31 +	}
    4.32 +
    4.33 +	virtual const char* Message() const
    4.34 +	{
    4.35 +		return m_message.c_str();
    4.36 +	}
    4.37 +
    4.38 +
    4.39 +protected:
    4.40 +
    4.41 +	std::string		m_message;
    4.42 +};
    4.43 +
    4.44 +
    4.45 +
    4.46  #endif // ASMEXCEPTION_H_
     5.1 --- a/src/assemble.cpp	Mon Apr 25 17:39:31 2011 +0200
     5.2 +++ b/src/assemble.cpp	Thu Jun 16 09:21:54 2011 +0200
     5.3 @@ -114,6 +114,7 @@
     5.4  	DATA( 0, "TYA",	0x98,	 X,		 X,		 X,		 X,		 X,		 X,		 X,		 X,		 X,		 X,		 X,		 X,		 X,		 X		)
     5.5  };
     5.6  
     5.7 +#undef X
     5.8  
     5.9  
    5.10  /*************************************************************************************************/
     6.1 --- a/src/commands.cpp	Mon Apr 25 17:39:31 2011 +0200
     6.2 +++ b/src/commands.cpp	Thu Jun 16 09:21:54 2011 +0200
     6.3 @@ -72,7 +72,8 @@
     6.4  	{ "PUTFILE",	&LineParser::HandlePutFile,				0 },
     6.5  	{ "PUTBASIC",	&LineParser::HandlePutBasic,			0 },
     6.6  	{ "MACRO",		&LineParser::HandleMacro,				&SourceFile::StartMacro },
     6.7 -	{ "ENDMACRO",	&LineParser::HandleEndMacro,			&SourceFile::EndMacro }
     6.8 +	{ "ENDMACRO",	&LineParser::HandleEndMacro,			&SourceFile::EndMacro },
     6.9 +	{ "ERROR",		&LineParser::HandleError,				0 }
    6.10  };
    6.11  
    6.12  
    6.13 @@ -858,11 +859,11 @@
    6.14  {
    6.15  	do
    6.16  	{
    6.17 -		int value;
    6.18 +		unsigned int value;
    6.19  
    6.20  		try
    6.21  		{
    6.22 -			value = EvaluateExpressionAsInt();
    6.23 +			value = EvaluateExpressionAsUnsignedInt();
    6.24  		}
    6.25  		catch ( AsmException_SyntaxError_SymbolNotDefined& )
    6.26  		{
    6.27 @@ -1784,3 +1785,47 @@
    6.28  	}
    6.29  }
    6.30  
    6.31 +
    6.32 +/*************************************************************************************************/
    6.33 +/**
    6.34 +	LineParser::HandleError()
    6.35 +*/
    6.36 +/*************************************************************************************************/
    6.37 +void LineParser::HandleError()
    6.38 +{
    6.39 +	int oldColumn = m_column;
    6.40 +
    6.41 +	if ( !AdvanceAndCheckEndOfStatement() )
    6.42 +	{
    6.43 +		throw AsmException_SyntaxError_EmptyExpression( m_line, m_column );
    6.44 +	}
    6.45 +
    6.46 +	if ( m_column >= m_line.length() || m_line[ m_column ] != '\"' )
    6.47 +	{
    6.48 +		throw AsmException_SyntaxError_EmptyExpression( m_line, m_column );
    6.49 +	}
    6.50 +
    6.51 +	// string
    6.52 +	size_t endQuotePos = m_line.find_first_of( '\"', m_column + 1 );
    6.53 +
    6.54 +	if ( endQuotePos == string::npos )
    6.55 +	{
    6.56 +		throw AsmException_SyntaxError_MissingQuote( m_line, m_line.length() );
    6.57 +	}
    6.58 +	else
    6.59 +	{
    6.60 +		string errorMsg( m_line.substr( m_column + 1, endQuotePos - m_column - 1 ) );
    6.61 +
    6.62 +		// throw error
    6.63 +
    6.64 +		throw AsmException_UserError( m_line, oldColumn, errorMsg );
    6.65 +	}
    6.66 +
    6.67 +	m_column = endQuotePos + 1;
    6.68 +
    6.69 +	if ( AdvanceAndCheckEndOfStatement() )
    6.70 +	{
    6.71 +		throw AsmException_SyntaxError_InvalidCharacter( m_line, m_column );
    6.72 +	}
    6.73 +}
    6.74 +
     7.1 --- a/src/discimage.cpp	Mon Apr 25 17:39:31 2011 +0200
     7.2 +++ b/src/discimage.cpp	Thu Jun 16 09:21:54 2011 +0200
     7.3 @@ -112,7 +112,7 @@
     7.4  		// generate a blank catalog
     7.5  
     7.6  		memset( m_aCatalog, 0, 0x200 );
     7.7 -		m_aCatalog[ 0x106 ] = 0x33;
     7.8 +		m_aCatalog[ 0x106 ] = 0x03 | ( ( GlobalData::Instance().GetDiscOption() & 3 ) << 4);
     7.9  		m_aCatalog[ 0x107 ] = 0x20;
    7.10  
    7.11  		if ( !m_outputFile.write( reinterpret_cast< char* >( m_aCatalog ), 0x200 ) )
    7.12 @@ -131,6 +131,8 @@
    7.13  			strcat( pPlingBoot, "\r" );
    7.14  
    7.15  			AddFile( "!Boot", reinterpret_cast< unsigned char* >( pPlingBoot ), 0, 0xFFFFFF, strlen( pPlingBoot ) );
    7.16 +
    7.17 +			m_aCatalog[ 0x106 ] = 0x33;		// force *OPT to 3 (EXEC)
    7.18  		}
    7.19  	}
    7.20  
     8.1 --- a/src/expression.cpp	Mon Apr 25 17:39:31 2011 +0200
     8.2 +++ b/src/expression.cpp	Thu Jun 16 09:21:54 2011 +0200
     8.3 @@ -499,6 +499,19 @@
     8.4  }
     8.5  
     8.6  
     8.7 +/*************************************************************************************************/
     8.8 +/**
     8.9 +	LineParser::EvaluateExpressionAsUnsignedInt()
    8.10 +
    8.11 +	Version of EvaluateExpression which returns its result as an unsigned int
    8.12 +*/
    8.13 +/*************************************************************************************************/
    8.14 +unsigned int LineParser::EvaluateExpressionAsUnsignedInt( bool bAllowOneMismatchedCloseBracket )
    8.15 +{
    8.16 +	return static_cast< unsigned int >( EvaluateExpression( bAllowOneMismatchedCloseBracket ) );
    8.17 +}
    8.18 +
    8.19 +
    8.20  
    8.21  /*************************************************************************************************/
    8.22  /**
     9.1 --- a/src/globaldata.cpp	Mon Apr 25 17:39:31 2011 +0200
     9.2 +++ b/src/globaldata.cpp	Thu Jun 16 09:21:54 2011 +0200
     9.3 @@ -73,7 +73,8 @@
     9.4  		m_pDiscImage( NULL ),
     9.5  		m_bSaved( false ),
     9.6  		m_pOutputFile( NULL ),
     9.7 -		m_numAnonSaves( 0 )
     9.8 +		m_numAnonSaves( 0 ),
     9.9 +		m_discOption( 0 )
    9.10  {
    9.11  }
    9.12  
    10.1 --- a/src/globaldata.h	Mon Apr 25 17:39:31 2011 +0200
    10.2 +++ b/src/globaldata.h	Thu Jun 16 09:21:54 2011 +0200
    10.3 @@ -46,6 +46,7 @@
    10.4  	inline void SetSaved()						{ m_bSaved = true; }
    10.5  	inline void SetOutputFile( const char* p )	{ m_pOutputFile = p; }
    10.6  	inline void IncNumAnonSaves()				{ m_numAnonSaves++; }
    10.7 +	inline void SetDiscOption( int opt )		{ m_discOption = opt; }
    10.8  
    10.9  	inline int GetPass() const					{ return m_pass; }
   10.10  	inline bool IsFirstPass() const				{ return ( m_pass == 0 ); }
   10.11 @@ -58,7 +59,7 @@
   10.12  	inline bool IsSaved() const					{ return m_bSaved; }
   10.13  	inline const char* GetOutputFile() const	{ return m_pOutputFile; }
   10.14  	inline int GetNumAnonSaves() const			{ return m_numAnonSaves; }
   10.15 -
   10.16 +	inline int GetDiscOption() const			{ return m_discOption; }
   10.17  
   10.18  private:
   10.19  
   10.20 @@ -77,6 +78,7 @@
   10.21  	bool						m_bSaved;
   10.22  	const char*					m_pOutputFile;
   10.23  	int							m_numAnonSaves;
   10.24 +	int							m_discOption;
   10.25  };
   10.26  
   10.27  
    11.1 --- a/src/lineparser.h	Mon Apr 25 17:39:31 2011 +0200
    11.2 +++ b/src/lineparser.h	Thu Jun 16 09:21:54 2011 +0200
    11.3 @@ -153,11 +153,13 @@
    11.4  	void			HandlePutBasic();
    11.5  	void			HandleMacro();
    11.6  	void			HandleEndMacro();
    11.7 +	void			HandleError();
    11.8  
    11.9  	// expression evaluating methods
   11.10  
   11.11  	double			EvaluateExpression( bool bAllowOneMismatchedCloseBracket = false );
   11.12  	int				EvaluateExpressionAsInt( bool bAllowOneMismatchedCloseBracket = false );
   11.13 +	unsigned int	EvaluateExpressionAsUnsignedInt( bool bAllowOneMismatchedCloseBracket = false );
   11.14  	double			GetValue();
   11.15  
   11.16  	void			EvalAdd();
    12.1 --- a/src/main.cpp	Mon Apr 25 17:39:31 2011 +0200
    12.2 +++ b/src/main.cpp	Thu Jun 16 09:21:54 2011 +0200
    12.3 @@ -41,7 +41,7 @@
    12.4  using namespace std;
    12.5  
    12.6  
    12.7 -#define VERSION "1.05"
    12.8 +#define VERSION "1.06"
    12.9  
   12.10  
   12.11  /*************************************************************************************************/
   12.12 @@ -69,7 +69,8 @@
   12.13  		WAITING_FOR_OUTPUT_FILENAME,
   12.14  		WAITING_FOR_DISC_INPUT_FILENAME,
   12.15  		WAITING_FOR_DISC_OUTPUT_FILENAME,
   12.16 -		WAITING_FOR_BOOT_FILENAME
   12.17 +		WAITING_FOR_BOOT_FILENAME,
   12.18 +		WAITING_FOR_DISC_OPTION
   12.19  
   12.20  	} state = READY;
   12.21  
   12.22 @@ -105,6 +106,10 @@
   12.23  				{
   12.24  					state = WAITING_FOR_BOOT_FILENAME;
   12.25  				}
   12.26 +				else if ( strcmp( argv[i], "-opt" ) == 0 )
   12.27 +				{
   12.28 +					state = WAITING_FOR_DISC_OPTION;
   12.29 +				}
   12.30  				else if ( strcmp( argv[i], "-v" ) == 0 )
   12.31  				{
   12.32  					GlobalData::Instance().SetVerbose( true );
   12.33 @@ -122,6 +127,7 @@
   12.34  					cout << " -di <file>     Specify a disc image file to be added to" << endl;
   12.35  					cout << " -do <file>     Specify a disc image file to output" << endl;
   12.36  					cout << " -boot <file>   Specify a filename to be run by !BOOT on a new disc image" << endl;
   12.37 +					cout << " -opt <opt>     Specify the *OPT 4,n for the generated disc image" << endl;
   12.38  					cout << " -v             Verbose output" << endl;
   12.39  					cout << " -d             Dump all global symbols after assembly" << endl;
   12.40  					cout << " --help         See this help again" << endl;
   12.41 @@ -171,6 +177,12 @@
   12.42  				GlobalData::Instance().SetBootFile( argv[i] );
   12.43  				state = READY;
   12.44  				break;
   12.45 +
   12.46 +			case WAITING_FOR_DISC_OPTION:
   12.47 +
   12.48 +				GlobalData::Instance().SetDiscOption( std::strtol( argv[i], NULL, 10 ) );
   12.49 +				state = READY;
   12.50 +				break;
   12.51  		}
   12.52  	}
   12.53  
    13.1 --- a/src/sourcecode.h	Mon Apr 25 17:39:31 2011 +0200
    13.2 +++ b/src/sourcecode.h	Thu Jun 16 09:21:54 2011 +0200
    13.3 @@ -57,8 +57,8 @@
    13.4  	// For loop / if related stuff
    13.5  	// Should use a std::vector here, but I can't really be bothered to change it now
    13.6  
    13.7 -	#define MAX_FOR_LEVELS	64
    13.8 -	#define MAX_IF_LEVELS	64
    13.9 +	#define MAX_FOR_LEVELS	256
   13.10 +	#define MAX_IF_LEVELS	256
   13.11  
   13.12  protected:
   13.13