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
