beebasm
changeset 10:ff3105395e34 v0.05
BeebASM v0.05 - first released Jan 10 2008 10:55:42
| author | Samwise <samwise@bagshot-row.org> |
|---|---|
| date | Sun May 02 12:15:51 2010 +0100 |
| parents | eff10c20561e |
| children | ba36b411d841 |
| files | about.txt beebasm.exe demo.ssd src/Makefile src/Makefile.inc src/commands.cpp src/globaldata.cpp src/globaldata.h src/lineparser.cpp src/lineparser.h src/main.cpp src/objectcode.cpp src/objectcode.h src/sourcefile.cpp |
| diffstat | 14 files changed, 291 insertions(+), 100 deletions(-) [+] |
line diff
1.1 --- a/about.txt Sun May 02 12:12:52 2010 +0100 1.2 +++ b/about.txt Sun May 02 12:15:51 2010 +0100 1.3 @@ -1,6 +1,6 @@ 1.4 ******************************************************************************* 1.5 * * 1.6 -* BeebAsm V0.04 * 1.7 +* BeebAsm V0.05 * 1.8 * * 1.9 * A portable 6502 assembler with BBC Micro style syntax * 1.10 * * 1.11 @@ -156,7 +156,8 @@ 1.12 1.13 -d 1.14 1.15 -Dumps all symbols in Swift-compatible format after assembly 1.16 +Dumps all global symbols in Swift-compatible format after assembly. 1.17 +This is used internally by Swift, and is just documented for completeness. 1.18 1.19 1.20 1.21 @@ -243,93 +244,118 @@ 1.22 1.23 ORG <addr> 1.24 1.25 -Set the address to be assembled from. This can be changed multiple times 1.26 -during a source file if you wish (for example) to assemble two separate blocks 1.27 -of code at different addresses, but share the labels between both blocks. 1.28 -This is exactly equivalent to BBC BASIC's 'P%=<addr>'. 1.29 + Set the address to be assembled from. This can be changed multiple times 1.30 + during a source file if you wish (for example) to assemble two separate 1.31 + blocks of code at different addresses, but share the labels between both 1.32 + blocks. This is exactly equivalent to BBC BASIC's 'P%=<addr>'. 1.33 1.34 1.35 SKIP <bytes> 1.36 1.37 -Moves the address pointer on by the specified number of bytes. Use this to 1.38 -reserve a space of a fixed size in the code. 1.39 + Moves the address pointer on by the specified number of bytes. Use this to 1.40 + reserve a space of a fixed size in the code. 1.41 1.42 1.43 SKIPTO <addr> 1.44 1.45 -Moves the address pointer to the specified address. An error is generated if 1.46 -this address is behind the current address pointer. 1.47 + Moves the address pointer to the specified address. An error is generated 1.48 + if this address is behind the current address pointer. 1.49 1.50 1.51 ALIGN <alignment> 1.52 1.53 -Used to align the address pointer to the next boundary, e.g. use ALIGN &100 to 1.54 -move to the next page (useful perhaps for positioning a table at a page 1.55 -boundary so that index accesses don't incur a "page crossed" penalty. 1.56 + Used to align the address pointer to the next boundary, e.g. use ALIGN &100 1.57 + to move to the next page (useful perhaps for positioning a table at a page 1.58 + boundary so that index accesses don't incur a "page crossed" penalty. 1.59 1.60 1.61 INCLUDE "filename" 1.62 1.63 -Includes the specified source file in the code at this point. 1.64 + Includes the specified source file in the code at this point. 1.65 1.66 1.67 INCBIN "filename" 1.68 1.69 -Includes the specified binary file in the object code at this point. 1.70 + Includes the specified binary file in the object code at this point. 1.71 1.72 1.73 EQUB a [, b, c, ...] 1.74 1.75 -Insert the specified byte(s) into the code. Note, unlike BBC BASIC, that a 1.76 -comma-separated sequence can be inserted. 1.77 + Insert the specified byte(s) into the code. Note, unlike BBC BASIC, that a 1.78 + comma-separated sequence can be inserted. 1.79 1.80 1.81 EQUW a [, b, c, ...] 1.82 1.83 -Insert the specified 16-bit word(s) into the code. 1.84 + Insert the specified 16-bit word(s) into the code. 1.85 1.86 1.87 EQUS "string" [, "string", byte, ...] 1.88 1.89 -Inserts the specified string into the code. Note that this can take a comma- 1.90 -separated list of parameters which may also include bytes. So, to zero- 1.91 -terminate a string, you can write: 1.92 + Inserts the specified string into the code. Note that this can take a comma- 1.93 + separated list of parameters which may also include bytes. So, to zero- 1.94 + terminate a string, you can write: 1.95 1.96 EQUS "My string", 0 1.97 1.98 -In fact, under the surface, there is no difference between EQUS and EQUB, 1.99 -which is also able to take strings! 1.100 + In fact, under the surface, there is no difference between EQUS and EQUB, 1.101 + which is also able to take strings! 1.102 + 1.103 + 1.104 +MAPCHAR <ascii code>, <remapped code> 1.105 +MAPCHAR <start ascii code>, <end ascii code>, <remapped code> 1.106 + 1.107 + By default, when EQUS "string" is assembled, the ASCII codes of each 1.108 + character are written into the object code. MAPCHAR allows you to specify 1.109 + which value should be written to the object code for each character. 1.110 + Suppose you have a font which contains the following symbols - space, 1.111 + followed by A-Z, followed by digits 0-9, followed by .,!?-' 1.112 + 1.113 + You could specify this with MAPCHAR as follows: 1.114 + 1.115 + MAPCHAR ' ', 0 1.116 + MAPCHAR 'A','Z', 1 1.117 + MAPCHAR '0','9', 27 1.118 + MAPCHAR '.', 37 1.119 + MAPCHAR ',', 38 1.120 + MAPCHAR '!', 39 1.121 + MAPCHAR '?', 40 1.122 + MAPCHAR '-', 41 1.123 + MAPCHAR ''', 42 1.124 + 1.125 + Now, when writing strings with EQUS, these codes will be written out instead 1.126 + of the default ASCII codes. 1.127 1.128 1.129 GUARD <addr> 1.130 1.131 -Puts a 'guard' on the specified address which will cause an error if you 1.132 -attempt to assemble code over this address. 1.133 + Puts a 'guard' on the specified address which will cause an error if you 1.134 + attempt to assemble code over this address. 1.135 1.136 1.137 CLEAR <start>, <end> 1.138 1.139 -Clears all guards between the <start> and <end> addresses specified. This can 1.140 -also be used to reset a section of memory which has had code assembled in it 1.141 -previously. BeebAsm will complain if you attempt to assemble code over 1.142 -previously assembled code at the same address without having saved the previous 1.143 -code. 1.144 + Clears all guards between the <start> and <end> addresses specified. This 1.145 + can also be used to reset a section of memory which has had code assembled 1.146 + in it previously. BeebAsm will complain if you attempt to assemble code 1.147 + over previously assembled code at the same address without having CLEARed 1.148 + it first. 1.149 1.150 1.151 SAVE "filename", start, end [, exec] 1.152 1.153 -Saves out object code to either a DFS disc image (if one has been specified), 1.154 -or to the current directory as a standalone file. 'exec' specifies the 1.155 -execution address of the file when saved to a disc image. A source file must 1.156 -have at least one SAVE statement in it, otherwise nothing will be output. 1.157 -BeebAsm will warn if this is the case. 1.158 + Saves out object code to either a DFS disc image (if one has been 1.159 + specified), or to the current directory as a standalone file. 'exec' 1.160 + specifies the execution address of the file when saved to a disc image. A 1.161 + source file must have at least one SAVE statement in it, otherwise nothing 1.162 + will be output. BeebAsm will warn if this is the case. 1.163 1.164 1.165 PRINT 1.166 1.167 -Displays some text. PRINT takes a comma-separated list of strings or values. 1.168 -To print a value in hex, prefix the expression with a '~' character. 1.169 -Examples: 1.170 + Displays some text. PRINT takes a comma-separated list of strings or values. 1.171 + To print a value in hex, prefix the expression with a '~' character. 1.172 + Examples: 1.173 1.174 PRINT "Value of label 'start' =", ~start 1.175 PRINT "numdots =", numdots, "dottable size =", dotend-dotstart 1.176 @@ -337,10 +363,10 @@ 1.177 1.178 FOR <var>, start, end [, step] ... NEXT 1.179 1.180 -I wanted this to have exactly the same syntax as BASIC, but I couldn't without 1.181 -rewriting my expression parser, so we're stuck with this for now. 1.182 + I wanted this to have exactly the same syntax as BASIC, but I couldn't 1.183 + without rewriting my expression parser, so we're stuck with this for now. 1.184 1.185 -It works exactly like BASIC's FOR...NEXT. For example: 1.186 + It works exactly like BASIC's FOR...NEXT. For example: 1.187 1.188 FOR n, 0, 10, 2 ; loop with n = 0, 2, 4, 6, 8, 10 1.189 PRINT n 1.190 @@ -348,11 +374,12 @@ 1.191 LDA #n:STA &901+n 1.192 NEXT 1.193 1.194 -The variable n only exists for the scope of the FOR...NEXT loop. 1.195 -Also, any labels or variables defined within the loop are only visible within 1.196 -it. However, unlike BBC BASIC, forward references to labels inside the loop 1.197 -will work properly, so, for example, this little multiply routine is perfectly 1.198 -ok: 1.199 + The variable n only exists for the scope of the FOR...NEXT loop. 1.200 + Also, any labels or variables defined within the loop are only visible within 1.201 + it. However, unlike BBC BASIC, forward references to labels inside the loop 1.202 + will work properly, so, for example, this little multiply routine is 1.203 + perfectly ok: 1.204 + 1.205 .multiply 1.206 \\ multiplies A*X, puts result in product/product+1 1.207 CPX #0:BEQ zero 1.208 @@ -369,11 +396,12 @@ 1.209 1.210 IF...ELSE...ENDIF 1.211 1.212 -Use to assemble conditionally. Like anything else in BeebAsm, these statements 1.213 -can be placed on one line, separated by colons, but even if they are, ENDIF 1.214 -must be present to denote the end of the IF block (unlike BBC BASIC). 1.215 + Use to assemble conditionally. Like anything else in BeebAsm, these 1.216 + statements can be placed on one line, separated by colons, but even if they 1.217 + are, ENDIF must be present to denote the end of the IF block (unlike BBC 1.218 + BASIC). 1.219 1.220 -Examples of use: 1.221 + Examples of use: 1.222 1.223 \\ build a rather strange table 1.224 FOR n, 0, 9 1.225 @@ -390,36 +418,37 @@ 1.226 1.227 { ... } 1.228 1.229 -Curly braces can be used to specify a block of code in which all symbols and 1.230 -labels defined will exist only within this block. Effectively, this is a 1.231 -mechanism for providing 'local labels' without the slightly cumbersome syntax 1.232 -demanded by some other assemblers. These can be nested. Any symbols defined 1.233 -within a block will override any of the same name outside of the block, exactly 1.234 -like C/C++ - not sure if I like this behaviour, but for now it will stay. 1.235 + Curly braces can be used to specify a block of code in which all symbols and 1.236 + labels defined will exist only within this block. Effectively, this is a 1.237 + mechanism for providing 'local labels' without the slightly cumbersome syntax 1.238 + demanded by some other assemblers. These can be nested. Any symbols defined 1.239 + within a block will override any of the same name outside of the block, 1.240 + exactly like C/C++ - not sure if I like this behaviour, but for now it will 1.241 + stay. 1.242 1.243 -Example of use: 1.244 + Example of use: 1.245 1.246 - .initialise 1.247 - { 1.248 - LDY #31 1.249 - LDA #0 1.250 - .loop ; label visible only within the braces 1.251 - STA buffer,Y 1.252 - DEY 1.253 - BPL loop 1.254 - RTS 1.255 - } 1.256 - 1.257 - .copy 1.258 - { 1.259 - LDY #31 1.260 - .loop ; perfectly ok to define .loop again in a new block 1.261 - LDA source,Y 1.262 - STA dest,Y 1.263 - DEY 1.264 - BPL loop 1.265 - RTS 1.266 - } 1.267 + .initialise 1.268 + { 1.269 + LDY #31 1.270 + LDA #0 1.271 + .loop ; label visible only within the braces 1.272 + STA buffer,Y 1.273 + DEY 1.274 + BPL loop 1.275 + RTS 1.276 + } 1.277 + 1.278 + .copy 1.279 + { 1.280 + LDY #31 1.281 + .loop ; perfectly ok to define .loop again in a new block 1.282 + LDA source,Y 1.283 + STA dest,Y 1.284 + DEY 1.285 + BPL loop 1.286 + RTS 1.287 + } 1.288 1.289 1.290 1.291 @@ -523,10 +552,16 @@ 1.292 1.293 9. VERSION HISTORY 1.294 1.295 +09/01/2008 0.05 Added MAPCHAR. Fixed SKIPTO (see, told you I was doing 1.296 + it quickly!). Enforce '%' as an end-of-symbol 1.297 + character. Fixed bug in overlayed assembly. Warns if 1.298 + there is no SAVE command in the source file. 1.299 06/01/2008 0.04 Added braces for scoping labels. Added INCBIN, SKIPTO. 1.300 Added some missing functions (NOT, LOG, LN, EXP). 1.301 Tightened up error checking on assembling out of range 1.302 - addresses (negative, or greater than &FFFF). 1.303 + addresses (negative, or greater than &FFFF). Now 1.304 + distinguishes internally between labels and other 1.305 + symbols. 1.306 05/01/2008 0.03 Added symbol dump for use with Swift. 1.307 20/12/2007 0.02 Fixed small bug which withheld filename and line number 1.308 display in error messages.
2.1 Binary file beebasm.exe has changed
3.1 Binary file demo.ssd has changed
4.1 --- a/src/Makefile Sun May 02 12:12:52 2010 +0100 4.2 +++ b/src/Makefile Sun May 02 12:15:51 2010 +0100 4.3 @@ -35,7 +35,7 @@ 4.4 4.5 # Parameters to the executable 4.6 4.7 -PARAMS := -i ..\demo.asm -do ..\demo.ssd -boot Code -d 4.8 +PARAMS := -i ..\demo.asm -do ..\demo.ssd -boot Code 4.9 4.10 4.11
5.1 --- a/src/Makefile.inc Sun May 02 12:12:52 2010 +0100 5.2 +++ b/src/Makefile.inc Sun May 02 12:15:51 2010 +0100 5.3 @@ -57,9 +57,9 @@ 5.4 CC := C:/MinGW/bin/gcc 5.5 CXX := C:/MinGW/bin/gcc 5.6 LD := C:/MinGW/bin/gcc 5.7 -MKDIR := C:/Utilities/mkdir -p 5.8 -RM := C:/Utilities/rm -f 5.9 -ECHO := @@C:/Utilities/echo -e 5.10 +MKDIR := C:/Cygwin/bin/mkdir -p 5.11 +RM := C:/Cygwin/bin/rm -f 5.12 +ECHO := @@C:/Cygwin/bin/echo -e 5.13 5.14 5.15 # Declare default number of CPUs
6.1 --- a/src/commands.cpp Sun May 02 12:12:52 2010 +0100 6.2 +++ b/src/commands.cpp Sun May 02 12:15:51 2010 +0100 6.3 @@ -41,13 +41,14 @@ 6.4 { "ELSE", &LineParser::HandleElse }, 6.5 { "ENDIF", &LineParser::HandleEndif }, 6.6 { "ALIGN", &LineParser::HandleAlign }, 6.7 + { "SKIPTO", &LineParser::HandleSkipTo }, 6.8 { "SKIP", &LineParser::HandleSkip }, 6.9 { "GUARD", &LineParser::HandleGuard }, 6.10 { "CLEAR", &LineParser::HandleClear }, 6.11 - { "SKIPTO", &LineParser::HandleSkipTo }, 6.12 { "INCBIN", &LineParser::HandleIncBin }, 6.13 { "{", &LineParser::HandleOpenBrace }, 6.14 - { "}", &LineParser::HandleCloseBrace } 6.15 + { "}", &LineParser::HandleCloseBrace }, 6.16 + { "MAPCHAR", &LineParser::HandleMapChar } 6.17 }; 6.18 6.19 6.20 @@ -269,6 +270,84 @@ 6.21 6.22 /*************************************************************************************************/ 6.23 /** 6.24 + LineParser::HandleMapChar() 6.25 +*/ 6.26 +/*************************************************************************************************/ 6.27 +void LineParser::HandleMapChar() 6.28 +{ 6.29 + // get parameters - either 2 or 3 6.30 + 6.31 + int param3 = -1; 6.32 + int param1 = EvaluateExpressionAsInt(); 6.33 + 6.34 + if ( m_line[ m_column ] != ',' ) 6.35 + { 6.36 + // did not find a comma 6.37 + throw AsmException_SyntaxError_InvalidCharacter( m_line, m_column ); 6.38 + } 6.39 + 6.40 + m_column++; 6.41 + 6.42 + int param2 = EvaluateExpressionAsInt(); 6.43 + 6.44 + if ( m_line[ m_column ] == ',' ) 6.45 + { 6.46 + m_column++; 6.47 + 6.48 + param3 = EvaluateExpressionAsInt(); 6.49 + } 6.50 + 6.51 + if ( m_line[ m_column ] == ',' ) 6.52 + { 6.53 + // Unexpected comma (remembering that an expression can validly end with a comma) 6.54 + throw AsmException_SyntaxError_UnexpectedComma( m_line, m_column ); 6.55 + } 6.56 + 6.57 + // range checks 6.58 + 6.59 + if ( param1 < 32 || param1 > 126 ) 6.60 + { 6.61 + throw AsmException_SyntaxError_OutOfRange( m_line, m_column ); 6.62 + } 6.63 + 6.64 + if ( param3 == -1 ) 6.65 + { 6.66 + // two parameters 6.67 + 6.68 + if ( param2 < 0 || param2 > 255 ) 6.69 + { 6.70 + throw AsmException_SyntaxError_OutOfRange( m_line, m_column ); 6.71 + } 6.72 + 6.73 + // do single character remapping 6.74 + ObjectCode::Instance().SetMapping( param1, param2 ); 6.75 + } 6.76 + else 6.77 + { 6.78 + // three parameters 6.79 + 6.80 + if ( param2 < 32 || param2 > 126 || param2 < param1 ) 6.81 + { 6.82 + throw AsmException_SyntaxError_OutOfRange( m_line, m_column ); 6.83 + } 6.84 + 6.85 + if ( param3 < 0 || param3 > 255 ) 6.86 + { 6.87 + throw AsmException_SyntaxError_OutOfRange( m_line, m_column ); 6.88 + } 6.89 + 6.90 + // remap a block 6.91 + for ( int i = param1; i <= param2; i++ ) 6.92 + { 6.93 + ObjectCode::Instance().SetMapping( i, param3 + i - param1 ); 6.94 + } 6.95 + } 6.96 +} 6.97 + 6.98 + 6.99 + 6.100 +/*************************************************************************************************/ 6.101 +/** 6.102 LineParser::HandleAlign() 6.103 */ 6.104 /*************************************************************************************************/ 6.105 @@ -525,11 +604,13 @@ 6.106 6.107 for ( size_t i = 0; i < equs.length(); i++ ) 6.108 { 6.109 + int mappedchar = ObjectCode::Instance().GetMapping( equs[ i ] ); 6.110 + 6.111 if ( GlobalData::Instance().ShouldOutputAsm() ) 6.112 { 6.113 if ( i < 3 ) 6.114 { 6.115 - cout << setw(2) << static_cast< int >( equs[ i ] ) << " "; 6.116 + cout << setw(2) << mappedchar << " "; 6.117 } 6.118 else if ( i == 3 ) 6.119 { 6.120 @@ -539,7 +620,8 @@ 6.121 6.122 try 6.123 { 6.124 - ObjectCode::Instance().PutByte( equs[ i ] ); 6.125 + // remap character from string as per character mapping table 6.126 + ObjectCode::Instance().PutByte( mappedchar ); 6.127 } 6.128 catch ( AsmException_AssembleError& e ) 6.129 { 6.130 @@ -849,6 +931,8 @@ 6.131 6.132 objFile.close(); 6.133 } 6.134 + 6.135 + GlobalData::Instance().SetSaved(); 6.136 } 6.137 } 6.138
7.1 --- a/src/globaldata.cpp Sun May 02 12:12:52 2010 +0100 7.2 +++ b/src/globaldata.cpp Sun May 02 12:15:51 2010 +0100 7.3 @@ -54,7 +54,8 @@ 7.4 : m_pBootFile( NULL ), 7.5 m_bVerbose( false ), 7.6 m_bUseDiscImage( false ), 7.7 - m_pDiscImage( NULL ) 7.8 + m_pDiscImage( NULL ), 7.9 + m_bSaved( false ) 7.10 { 7.11 } 7.12
8.1 --- a/src/globaldata.h Sun May 02 12:12:52 2010 +0100 8.2 +++ b/src/globaldata.h Sun May 02 12:15:51 2010 +0100 8.3 @@ -27,6 +27,7 @@ 8.4 inline void SetUseDiscImage( bool b ) { m_bUseDiscImage = b; } 8.5 inline void SetDiscImage( DiscImage* d ) { m_pDiscImage = d; } 8.6 inline void ResetForId() { m_forId = 0; } 8.7 + inline void SetSaved() { m_bSaved = true; } 8.8 8.9 inline int GetPass() const { return m_pass; } 8.10 inline bool IsFirstPass() const { return ( m_pass == 0 ); } 8.11 @@ -36,6 +37,7 @@ 8.12 inline bool UsesDiscImage() const { return m_bUseDiscImage; } 8.13 inline DiscImage* GetDiscImage() const { return m_pDiscImage; } 8.14 inline int GetNextForId() { return m_forId++; } 8.15 + inline bool IsSaved() const { return m_bSaved; } 8.16 8.17 8.18 private: 8.19 @@ -52,6 +54,7 @@ 8.20 DiscImage* m_pDiscImage; 8.21 int m_forId; 8.22 int m_randomSeed; 8.23 + bool m_bSaved; 8.24 }; 8.25 8.26
9.1 --- a/src/lineparser.cpp Sun May 02 12:12:52 2010 +0100 9.2 +++ b/src/lineparser.cpp Sun May 02 12:15:51 2010 +0100 9.3 @@ -343,10 +343,11 @@ 9.4 { 9.5 symbolName += m_line[ m_column++ ]; 9.6 9.7 - } while ( isalpha( m_line[ m_column ] ) || 9.8 - isdigit( m_line[ m_column ] ) || 9.9 - m_line[ m_column ] == '_' || 9.10 - m_line[ m_column ] == '%' ); 9.11 + } while ( ( isalpha( m_line[ m_column ] ) || 9.12 + isdigit( m_line[ m_column ] ) || 9.13 + m_line[ m_column ] == '_' || 9.14 + m_line[ m_column ] == '%' ) && 9.15 + m_line[ m_column - 1 ] != '%' ); 9.16 9.17 return symbolName; 9.18 }
10.1 --- a/src/lineparser.h Sun May 02 12:12:52 2010 +0100 10.2 +++ b/src/lineparser.h Sun May 02 12:15:51 2010 +0100 10.3 @@ -124,6 +124,7 @@ 10.4 void HandleSkipTo(); 10.5 void HandleGuard(); 10.6 void HandleClear(); 10.7 + void HandleMapChar(); 10.8 10.9 // expression evaluating methods 10.10
11.1 --- a/src/main.cpp Sun May 02 12:12:52 2010 +0100 11.2 +++ b/src/main.cpp Sun May 02 12:15:51 2010 +0100 11.3 @@ -23,7 +23,7 @@ 11.4 using namespace std; 11.5 11.6 11.7 -#define VERSION "0.03" 11.8 +#define VERSION "0.05" 11.9 11.10 11.11 /*************************************************************************************************/ 11.12 @@ -207,6 +207,11 @@ 11.13 SymbolTable::Instance().Dump(); 11.14 } 11.15 11.16 + if ( !GlobalData::Instance().IsSaved() ) 11.17 + { 11.18 + cerr << "warning: no SAVE command in source file." << endl; 11.19 + } 11.20 + 11.21 ObjectCode::Destroy(); 11.22 SymbolTable::Destroy(); 11.23 GlobalData::Destroy();
12.1 --- a/src/objectcode.cpp Sun May 02 12:12:52 2010 +0100 12.2 +++ b/src/objectcode.cpp Sun May 02 12:15:51 2010 +0100 12.3 @@ -65,6 +65,13 @@ 12.4 { 12.5 memset( m_aMemory, 0, sizeof m_aMemory ); 12.6 memset( m_aFlags, 0, sizeof m_aFlags ); 12.7 + 12.8 + // initialise ascii mapping table 12.9 + 12.10 + for ( int i = 0; i < 96; i++ ) 12.11 + { 12.12 + m_aMapChar[ i ] = i + 32; 12.13 + } 12.14 } 12.15 12.16 12.17 @@ -86,7 +93,7 @@ 12.18 /** 12.19 ObjectCode::PutByte() 12.20 12.21 - Puts one byte to memory image 12.22 + Puts one byte to memory image, never doing pass consistency checks 12.23 */ 12.24 /*************************************************************************************************/ 12.25 void ObjectCode::PutByte( unsigned int byte ) 12.26 @@ -135,6 +142,8 @@ 12.27 assert( opcode < 0x100 ); 12.28 12.29 if ( GlobalData::Instance().IsSecondPass() && 12.30 + ( m_aFlags[ m_PC ] & CHECK ) && 12.31 + !( m_aFlags[ m_PC ] & DONT_CHECK ) && 12.32 m_aMemory[ m_PC ] != opcode ) 12.33 { 12.34 throw AsmException_AssembleError_InconsistentCode(); 12.35 @@ -150,7 +159,7 @@ 12.36 throw AsmException_AssembleError_Overlap(); 12.37 } 12.38 12.39 - m_aFlags[ m_PC ] |= USED; 12.40 + m_aFlags[ m_PC ] |= ( USED | CHECK ); 12.41 m_aMemory[ m_PC++ ] = opcode; 12.42 12.43 SymbolTable::Instance().ChangeSymbol( "P%", m_PC ); 12.44 @@ -177,6 +186,8 @@ 12.45 assert( val < 0x100 ); 12.46 12.47 if ( GlobalData::Instance().IsSecondPass() && 12.48 + ( m_aFlags[ m_PC ] & CHECK ) && 12.49 + !( m_aFlags[ m_PC ] & DONT_CHECK ) && 12.50 m_aMemory[ m_PC ] != opcode ) 12.51 { 12.52 throw AsmException_AssembleError_InconsistentCode(); 12.53 @@ -194,7 +205,7 @@ 12.54 throw AsmException_AssembleError_Overlap(); 12.55 } 12.56 12.57 - m_aFlags[ m_PC ] |= USED; 12.58 + m_aFlags[ m_PC ] |= ( USED | CHECK ); 12.59 m_aMemory[ m_PC++ ] = opcode; 12.60 m_aFlags[ m_PC ] |= USED; 12.61 m_aMemory[ m_PC++ ] = val; 12.62 @@ -223,6 +234,8 @@ 12.63 assert( addr < 0x10000 ); 12.64 12.65 if ( GlobalData::Instance().IsSecondPass() && 12.66 + ( m_aFlags[ m_PC ] & CHECK ) && 12.67 + !( m_aFlags[ m_PC ] & DONT_CHECK ) && 12.68 m_aMemory[ m_PC ] != opcode ) 12.69 { 12.70 throw AsmException_AssembleError_InconsistentCode(); 12.71 @@ -242,7 +255,7 @@ 12.72 throw AsmException_AssembleError_Overlap(); 12.73 } 12.74 12.75 - m_aFlags[ m_PC ] |= USED; 12.76 + m_aFlags[ m_PC ] |= ( USED | CHECK ); 12.77 m_aMemory[ m_PC++ ] = opcode; 12.78 m_aFlags[ m_PC ] |= USED; 12.79 m_aMemory[ m_PC++ ] = addr & 0xFF; 12.80 @@ -280,9 +293,22 @@ 12.81 12.82 if ( bAll ) 12.83 { 12.84 + // via CLEAR command 12.85 + // as soon as we force a block to be cleared, we can no longer do inconsistency checks on 12.86 + // the object code, so we flag the whole block as DONT_CHECK 12.87 memset( m_aMemory + start, 0, end - start ); 12.88 + memset( m_aFlags + start, DONT_CHECK, end - start ); 12.89 } 12.90 - memset( m_aFlags + start, 0, end - start ); 12.91 + else 12.92 + { 12.93 + // between first and second pass 12.94 + // we preserve the memory image and the CHECK flags so that we can test for inconsistencies 12.95 + // in the assembled code between first and second passes 12.96 + for ( unsigned char* i = m_aFlags + start; i < m_aFlags + end; i++ ) 12.97 + { 12.98 + (*i) &= ( CHECK | DONT_CHECK ); 12.99 + } 12.100 + } 12.101 } 12.102 12.103 12.104 @@ -318,3 +344,31 @@ 12.105 12.106 binfile.close(); 12.107 } 12.108 + 12.109 + 12.110 + 12.111 +/*************************************************************************************************/ 12.112 +/** 12.113 + ObjectCode::SetMapping() 12.114 +*/ 12.115 +/*************************************************************************************************/ 12.116 +void ObjectCode::SetMapping( int ascii, int mapped ) 12.117 +{ 12.118 + assert( ascii > 31 && ascii < 127 ); 12.119 + assert( mapped >= 0 && mapped < 256 ); 12.120 + 12.121 + m_aMapChar[ ascii - 32 ] = mapped; 12.122 +} 12.123 + 12.124 + 12.125 + 12.126 +/*************************************************************************************************/ 12.127 +/** 12.128 + ObjectCode::SetMapping() 12.129 +*/ 12.130 +/*************************************************************************************************/ 12.131 +int ObjectCode::GetMapping( int ascii ) const 12.132 +{ 12.133 + assert( ascii > 31 && ascii < 127 ); 12.134 + return m_aMapChar[ ascii - 32 ]; 12.135 +}
13.1 --- a/src/objectcode.h Sun May 02 12:12:52 2010 +0100 13.2 +++ b/src/objectcode.h Sun May 02 12:15:51 2010 +0100 13.3 @@ -33,13 +33,18 @@ 13.4 void SetGuard( int i ); 13.5 void Clear( int start, int end, bool bAll = true ); 13.6 13.7 + void SetMapping( int ascii, int mapped ); 13.8 + int GetMapping( int ascii ) const; 13.9 + 13.10 13.11 private: 13.12 13.13 enum FLAGS 13.14 { 13.15 USED = (1 << 0), 13.16 - GUARD = (1 << 1) 13.17 + GUARD = (1 << 1), 13.18 + CHECK = (1 << 2), 13.19 + DONT_CHECK = (1 << 3) 13.20 }; 13.21 13.22 13.23 @@ -50,6 +55,8 @@ 13.24 unsigned char m_aFlags[ 0x10000 ]; 13.25 int m_PC; 13.26 13.27 + unsigned char m_aMapChar[ 96 ]; 13.28 + 13.29 static ObjectCode* m_gInstance; 13.30 }; 13.31
14.1 --- a/src/sourcefile.cpp Sun May 02 12:12:52 2010 +0100 14.2 +++ b/src/sourcefile.cpp Sun May 02 12:15:51 2010 +0100 14.3 @@ -163,7 +163,7 @@ 14.4 14.5 if ( GlobalData::Instance().IsFirstPass() ) 14.6 { 14.7 - cerr << "Processed file '" << m_pFilename << "' ok" << endl << endl; 14.8 + cerr << "Processed file '" << m_pFilename << "' ok" << endl; 14.9 } 14.10 } 14.11
