/*BEGIN_MODULE********************************************************* ** *M proc1 This is a simple math processor with 16 instructions *F *F Public: *F 1. main Main program for proc1 program *F ** *********************************************************************** ** ** ** PURPOSE ** *P The purpose of this module is to emulate a simple math processor. *P *P Processor Diagram: *P *P +=================+========+======================+ *P | | | ^ *P | | | | *P V V | V data *P +--------+ +--------+ | +-------------+ *P | Reg A | | Reg B | | | | *P +--------+ +--------+ | | | Address *P | | | | Memory |<=====+ *P +=+===============+ | | | 256 words | | *P | | | | | | | *P | +===============+=+ | +-------------+ | *P | | | | | | *P V V V V | | *P +--------+ +--------+ | | *P | | | | | +-------------+ | *P | Mult | | Add | +==============>| PC Reg |=====>+ *P | | | | | +-------------+ | *P +--------+ +--------+ +==============>| Reg I |=====>+ *P | | | +-------------+ | *P +========+========+ +==============>| Inst. Reg |=====>+ *P | | +-------------+ *P | | | Controller | *P | | +-------------+ *P V | | *P +-------+ | <--Control----+ *P | Reg C | | *P +-------+ | *P | | *P +================>+ *P *P Except for comments there can be only one compiler directive or *P processor instruction per line and the directive/instruction must *P be contained in that one line. Comment directives can appear on *P the same line as any other instruction. As the program is compiled *P the address is incremented after each data directive or processor *P instruction. *P *P Compiler Directive: *P *P Directive | Syntax | Description *P ============+===========+======================================= *P Origin | org: 0xXX | Fixes memory address of next processor *P | | instruction or data statement. *P Label | label: | A label that is translated to an *P | | address during compile time for use in *P | | load, call and jmp statements. *P Data | 0xXXXX | Load data at current memory address. *P Comment | ! | Begins a comment to end of line and *P | | can appear anywhere. *P *P Processor Instructions: *P *P Instructions 0 through 3 are memory/register transfers *P Instructions 4 is a register to register transfer *P Instructions 5 through 8 are math instructions *P Instruction 9 through B are processor control instruction *P *P | Instruction | *P Code | Syntax | Operation *P ========+=================+================================= *P 0x00XX | load RA=[XX+RI] | Load RA from M[XX+RI(7:0)] *P 0x01XX | load RB=[XX+RI] | Load RB from M[XX+RI(7:0)] *P 0x02XX | load RI=[XX] | Load RI from M[XX] *P 0x03XX | load [XX+RI]=RC | Load M[XX+RI(7:0)] From RC *P 0x04XX | mov RB=RC | Move RC to RB *P 0x05XX | add | Add *P 0x06XX | mult | Multiply *P 0x07XX | inc | Increment RA *P 0x08XX | dec | Decrement RA *P 0x09XX | jmp XX | Jump to XX *P 0x0AXX | jz XX | Jump to XX if RI == 0 *P 0x0BXX | halt | Halt *P 0x0CXX | | No operation *P 0x0DXX | | No operation *P 0x0EXX | | No operation *P 0x0FXX | | No operation *P *P Possible RTL microinstructions *P *P PC <- 0x00 *P PC <- IR(7:0) *P PC <- PC + 1 *P RA <- M[IR(7:0)+RI(7:0))^0xff] *P RB <- M[IR(7:0)+RI(7:0))^0xff] *P RB <- RC *P RC <- RA - 1 *P RC <- RA + 1 *P RC <- RA * RB *P RC <- RA + RB *P RI <- M[IR(7:0)] *P IR <- M[PC(7:0)] *P M[(IR(7:0)+RI(7:0))^0xff] <- RC *P ** ** **END_MODULE**********************************************************/ #include #include #include #include #include #include using namespace std; class Statement { public: Statement(); Statement( const string& str ); ~Statement() {} enum { st_unknown, st_origin, st_label, st_data, st_comment, st_instruction, st_error }; void SetLine( const string& newLine ); const string& GetLine(); int GetType() { return type; } unsigned short GetValue() { return value; } const string& GetLabel() { return label; } void SetLabelAddress( unsigned short add ); void SetAddress( unsigned short add ) { address = add; } unsigned short GetAddress( ) { return address; } void SetLineNumber( int number ); int GetLineNumber(); private: bool GetValue( const char** cPtr ); bool GetRaRbType( const char** cPtr ); bool GetRiType( const char** cPtr ); bool GetRcType( const char** cPtr ); bool GetXXRiType( const char** cPtr ); bool GetXXType( const char** cPtr ); bool IsOrg( const char* strPtr ); bool IsData( const char* strPtr ); bool IsComment( const char* strPtr ); bool IsLoad( const char* strPtr ); bool IsMov( const char* strPtr ); bool IsInc( const char* strPtr ); bool IsDec( const char* strPtr ); bool IsAdd( const char* strPtr ); bool IsMult( const char* strPtr ); bool IsJmp( const char* strPtr ); bool IsJz( const char* strPtr ); bool IsHalt( const char* strPtr ); bool IsLabel( const char* strPtr ); void SkipWhiteSpace( const char** cPtr ) const { while( **cPtr && isspace(**cPtr) ) { ++(*cPtr); } } void PrintError( const char* rPtr, const char* strPtr ) const { cout << strPtr << endl; int i; size_t length = rPtr - strPtr; for( i=0; i> 8; xx = memory[reg_pc] & 0x00ff; switch( instruction ) { case load_a: reg_a = memory[(xx+reg_i)&0x00ff]; reg_pc++; break; case load_b: reg_b = memory[(xx+reg_i)&0x00ff]; reg_pc++; break; case load_i: reg_i = memory[xx]; reg_pc++; break; case load_c: memory[(xx+reg_i)&0x00ff] = reg_c; reg_pc++; break; case mov_b_c: reg_b = reg_c; reg_pc++; break; case add: reg_c = reg_a + reg_b; reg_pc++; break; case mult: reg_c = reg_a * reg_b; reg_pc++; break; case inc: reg_c = reg_a + 1; reg_pc++; break; case dec_i: reg_c = reg_a - 1; reg_pc++; break; case jmp_xx: reg_pc = xx; break; case jmp_0_xx: reg_pc = reg_i ? reg_pc + 1 : xx; break; case halt: break; default: cerr << hex << "Unknown instruction 0x" << setw(2) << setfill('0') << instruction << " at memory location 0x" << setw(4) << setfill('0') << reg_pc << dec << endl; reg_pc++; break; } } void print_instruction( int temp=-1 ) { unsigned short instruction; unsigned short xx; if( temp < 0 ) { instruction = memory[reg_pc] >> 8; xx = memory[reg_pc] & 0x00ff; } else { instruction = (temp >> 8) & 0x00ff; xx = temp & 0x00ff; } switch( instruction ) { case load_a: cout << hex << "load RA=[0x" << setw(2) << setfill('0') << xx << "+RI] " << dec; break; case load_b: cout << hex << "load RB=[0x" << setw(2) << setfill('0') << xx << "+RI] " << dec; break; case load_i: cout << hex << "load RI=[0x" << setw(2) << setfill('0') << xx << "] " << dec; break; case load_c: cout << hex << "load [0x" << setw(2) << setfill('0') << xx << "+RI]=RC " << dec; break; case mov_b_c: cout << "mov RB=RC "; break; case inc: cout << "inc "; break; case dec_i: cout << "dec "; break; case add: cout << "add "; break; case mult: cout << "mult "; break; case jmp_xx: cout << hex << "jmp 0x" << setw(2) << setfill('0') << xx << " " << dec; break; case jmp_0_xx: cout << hex << "jz 0x" << setw(2) << setfill('0') << xx << " " << dec; break; case halt: cout << "halt "; break; default: cout << hex << "Unknown instruction 0x" << setw(2) << setfill('0') << instruction << dec << endl; reg_pc++; break; } if( temp < 0 ) { cout << hex << " IR = 0x" << setw(4) << setfill('0') << memory[reg_pc] << " PC = 0x" << setw(2) << setfill('0') << reg_pc << " RI = 0x" << setw(2) << setfill('0') << reg_i << dec << endl; } else { cout << hex << " 0x" << setw(4) << setfill('0') << (temp & 0xffff) << dec << endl; } } bool load_memory( const char *filename ) { ifstream input; char line[256]; string str; bool errorFlag = false; unsigned short count = 0; unsigned short value; input.open( filename ); if( !input ) { cout << "Error opening file " << filename << endl; } else { while( input.getline(line, 256) ) { str = line; statementVec.push_back( str ); } input.close(); vector::iterator i; // ....Set labels and look for errors. for( i=statementVec.begin(); i != statementVec.end(); ++i ) { int type = i->GetType(); switch( type ) { case Statement::st_origin: count = i->GetValue(); break; case Statement::st_label: i->SetAddress( count ); break; case Statement::st_data: i->SetAddress( count ); count++; break; case Statement::st_instruction: i->SetAddress( count ); count++; break; case Statement::st_error: errorFlag = true; break; } if( errorFlag ) break; } if( !errorFlag ) { for( i=statementVec.begin(); i != statementVec.end(); ++i ) { int type = i->GetType(); switch( type ) { case Statement::st_origin: count = i->GetValue(); break; case Statement::st_label: break; case Statement::st_data: memory[count] = i->GetValue(); count++; break; case Statement::st_instruction: value = i->GetValue(); if( (i->GetLabel()).length() ) { vector::iterator j; for( j=statementVec.begin(); j != statementVec.end(); ++j ) { int localType = j->GetType(); if( localType == Statement::st_label ) { if( i->GetLabel() == j->GetLabel() ) { value = (value & 0xff00) | ((value + j->GetAddress()) & 0x00ff); break; } } } } memory[count] = value; count++; break; case Statement::st_error: break; } } } } return !errorFlag; } void print_memory( int start=0, int length=-1 ) { int i; if( length < 0 ) // default, print all of memory { length = 256; } else { length += start; length = ((length + 7)/8)*8; } start = start - (start % 8); for( i=start; i 255 ) return; memory[address] = value; } void set_reg_pc( unsigned short value ) { reg_pc = value & 0xffff; } void set_reg_a( unsigned short value ) { reg_a = value; } void set_reg_b( unsigned short value ) { reg_b = value; } void set_reg_c( unsigned short value ) { reg_c = value; } void set_reg_i( unsigned short value ) { reg_i = value; } unsigned short get_instruction( void ) { return memory[reg_pc] >> 8; } unsigned short get_memory( unsigned short address ) { if( address > 255 ) return 0; return memory[address]; } unsigned short get_reg_pc( void ) { return reg_pc; } unsigned short get_reg_a( void ) { return reg_a; } unsigned short get_reg_b( void ) { return reg_b; } unsigned short get_reg_c( void ) { return reg_c; } unsigned short get_reg_i( void ) { return reg_i; } private: unsigned short memory[256]; unsigned short reg_pc; unsigned short reg_a; unsigned short reg_b; unsigned short reg_c; unsigned short reg_i; vector statementVec; }; /*BEGIN_HEADER*01****************************************************** ** *f 01. main Description ** *********************************************************************** ** ** CALL METHOD ** *c int main( argc, argv ); *c int argc; Argument count *c char** argv; Pointer to array of command line arguments ** **END_HEADER*01*******************************************************/ int main( int argc, char *argv[] ) { m_proc processor; unsigned short instruction; unsigned short xx; int count; /* number of instructions */ int max_count = 200; /* avoid infinite loop */ if( argc == 2 ) { if( !processor.load_memory(argv[1]) ) return 0; } else { cout << "Please provide a special math processor program file name" << endl; return 1; } for( count=0; count= 'a') && (**cPtr <= 'f') ) { value = value*16 + (**cPtr - 'a') + 10; } else if( (**cPtr >= 'A') && (**cPtr <= 'F') ) { value = value*16 + (**cPtr - 'A') + 10; } else { value = value*16 + (**cPtr - '0'); } } } else if( **cPtr && ((**cPtr >= '0') && (**cPtr <= '7')) ) { for( ;**cPtr && (**cPtr >= '0') && (**cPtr <= '7'); ++(*cPtr) ) { value = value*8 + (**cPtr - '0'); } } } else if( isdigit(**cPtr) ) { for( ;**cPtr && isdigit(**cPtr); ++(*cPtr) ) { value = value*10 + (**cPtr - '0'); } } else { errorFlag = true; } } else { errorFlag = true; } return errorFlag; } bool Statement::GetRiType( const char** cPtr ) { bool errorFlag = true; type = st_error; // error unless proven otherwise SkipWhiteSpace( cPtr ); // ..Check for '=' sign. if( **cPtr && (**cPtr == '=' ) ) { ++(*cPtr); SkipWhiteSpace( cPtr ); // ....Look for opening [. if( **cPtr && (**cPtr == '[') ) { ++(*cPtr); value = 0; SkipWhiteSpace( cPtr ); errorFlag = GetXXType( cPtr ); if( !errorFlag ) { errorFlag = true; // must prove there is no error SkipWhiteSpace( cPtr ); if( **cPtr && (**cPtr == ']') ) { ++(*cPtr); SkipWhiteSpace( cPtr ); if( !**cPtr || (**cPtr == '!') ) { type = st_instruction; errorFlag = false; } } } } } return errorFlag; } bool Statement::GetRaRbType( const char** cPtr ) { bool errorFlag = true; type = st_error; // error unless proven otherwise SkipWhiteSpace( cPtr ); // ..Check for '=' sign. if( **cPtr && (**cPtr == '=' ) ) { ++(*cPtr); SkipWhiteSpace( cPtr ); // ....Look for opening [. if( **cPtr && (**cPtr == '[') ) { ++(*cPtr); value = 0; SkipWhiteSpace( cPtr ); errorFlag = GetXXRiType( cPtr ); if( !errorFlag ) { errorFlag = true; // must prove it is false SkipWhiteSpace( cPtr ); if( **cPtr && (**cPtr == ']') ) { ++(*cPtr); SkipWhiteSpace( cPtr ); if( !**cPtr || (**cPtr == '!') ) { type = st_instruction; errorFlag = false; } } } } } return errorFlag; } bool Statement::GetRcType( const char** cPtr ) { bool errorFlag = true; value = 0; SkipWhiteSpace( cPtr ); errorFlag = GetXXRiType( cPtr ); if( !errorFlag ) { errorFlag = true; // must prove it is false SkipWhiteSpace( cPtr ); if( **cPtr && (**cPtr == ']') ) { ++(*cPtr); SkipWhiteSpace( cPtr ); if( **cPtr && (**cPtr == '=') ) { ++(*cPtr); SkipWhiteSpace( cPtr ); if( **cPtr && ((**cPtr == 'r') || (**cPtr == 'R')) ) { ++(*cPtr); if( **cPtr && ((**cPtr == 'c') || (**cPtr == 'C')) ) { ++(*cPtr); SkipWhiteSpace( cPtr ); if( !**cPtr || (**cPtr == '!') ) { errorFlag = false; } } } } } } return errorFlag; } bool Statement::GetXXRiType( const char** cPtr ) { bool errorFlag = true; value = 0; label = ""; SkipWhiteSpace( cPtr ); // ..Look for constant. if( **cPtr && isdigit(**cPtr) ) { errorFlag = GetValue( cPtr ); if( !errorFlag ) { errorFlag = true; // must prove it is false SkipWhiteSpace( cPtr ); // ......Look for constant+. if( **cPtr && (**cPtr == '+') ) { ++(*cPtr); SkipWhiteSpace( cPtr ); // ........Look for constant+RB. if( **cPtr && ((**cPtr == 'r') || (**cPtr == 'R')) && *(*cPtr + 1) && ((*(*cPtr + 1) == 'i') || (*(*cPtr + 1) == 'I')) && *(*cPtr + 2) && !isalnum(*(*cPtr + 2)) ) { *cPtr += 2; errorFlag = false; } else if( **cPtr && isalpha(**cPtr) ) // Look for constant+label. { label = **cPtr; ++(*cPtr); for( ;**cPtr && isalnum(**cPtr); ++(*cPtr) ) { label += **cPtr; } SkipWhiteSpace( cPtr ); // ..........Look for constant+label+. if( **cPtr && (**cPtr == '+') ) { ++(*cPtr); SkipWhiteSpace( cPtr ); // ............Look for constant+label+RB. if( **cPtr && ((**cPtr == 'r') || (**cPtr == 'R')) && *(*cPtr + 1) && ((*(*cPtr + 1) == 'i') || (*(*cPtr + 1) == 'I')) && *(*cPtr + 2) && !isalnum(*(*cPtr + 2)) ) { *cPtr += 2; errorFlag = false; } } else { errorFlag = false; } } } } // ..Else look for label. } else if( **cPtr && isalpha(**cPtr) ) { label = **cPtr; ++(*cPtr); for( ;**cPtr && isalnum(**cPtr); ++(*cPtr) ) { label += **cPtr; } SkipWhiteSpace( cPtr ); errorFlag = false; // ....Look for label+. if( **cPtr && (**cPtr == '+') ) { ++(*cPtr); SkipWhiteSpace( cPtr ); // ......Look for label+RB. if( **cPtr && ((**cPtr == 'r') || (**cPtr == 'R')) && *(*cPtr + 1) && ((*(*cPtr + 1) == 'i') || (*(*cPtr + 1) == 'I')) && *(*cPtr + 2) && !isalnum(*(*cPtr + 2)) ) { *cPtr += 2; errorFlag = false; // ......Look for label+constant. } else { errorFlag = GetValue( cPtr ); if( !errorFlag ) { SkipWhiteSpace( cPtr ); // ..........Look for label+constant+. if( **cPtr && (**cPtr == '+') ) { ++(*cPtr); SkipWhiteSpace( cPtr ); // ............Look for constant+label+RB. if( **cPtr && ((**cPtr == 'r') || (**cPtr == 'R')) && *(*cPtr + 1) && ((*(*cPtr + 1) == 'i') || (*(*cPtr + 1) == 'I')) && *(*cPtr + 2) && !isalnum(*(*cPtr + 2)) ) { *cPtr += 2; errorFlag = false; } } else { errorFlag = false; } } } } } return errorFlag; } bool Statement::GetXXType( const char** cPtr ) { bool errorFlag = true; value = 0; label = ""; SkipWhiteSpace( cPtr ); // ..Look for constant. if( **cPtr && isdigit(**cPtr) ) { errorFlag = GetValue( cPtr ); if( !errorFlag ) { SkipWhiteSpace( cPtr ); // ......Look for constant+. if( **cPtr && (**cPtr == '+') ) { ++(*cPtr); SkipWhiteSpace( cPtr ); // ........Look for constant+label. if( **cPtr && isalpha(**cPtr) ) { label = **cPtr; ++(*cPtr); for( ;**cPtr && isalnum(**cPtr); ++(*cPtr) ) { label += **cPtr; } SkipWhiteSpace( cPtr ); } else { errorFlag = true; } } } // ..Else look for label. } else if( **cPtr && isalpha(**cPtr) ) { label = **cPtr; ++(*cPtr); for( ;**cPtr && isalnum(**cPtr); ++(*cPtr) ) { label += **cPtr; } SkipWhiteSpace( cPtr ); errorFlag = false; // ....Look for label+. if( **cPtr && (**cPtr == '+') ) { ++(*cPtr); SkipWhiteSpace( cPtr ); // ......Look for label+constant. errorFlag = GetValue( cPtr ); if( !errorFlag ) { SkipWhiteSpace( cPtr ); } } } return errorFlag; } bool Statement::IsOrg( const char* strPtr ) { const char* rPtr = strPtr; bool returnFlag = false; bool errorFlag; // ..Check for NULL string. if( !strPtr ) return returnFlag; SkipWhiteSpace( &rPtr ); // ..Look for org:. if( *rPtr && ((*rPtr == 'o') || (*rPtr == 'O')) ) { ++rPtr; if( *rPtr && ((*rPtr == 'r') || (*rPtr == 'R')) ) { ++rPtr; if( *rPtr && ((*rPtr == 'g') || (*rPtr == 'G')) ) { ++rPtr; if( *rPtr && (*rPtr == ':') ) { ++rPtr; // ..........Found org:. returnFlag = true; type = st_error; SkipWhiteSpace( &rPtr ); // ..........Get origin address. errorFlag = GetValue( &rPtr ); // ..........If address looks good, check for trailing characters. if( !errorFlag ) { SkipWhiteSpace( &rPtr ); if( !*rPtr || (*rPtr == '!') ) { type = st_origin; } } } } } } if( type == st_error ) PrintError( rPtr, strPtr ); return returnFlag; } bool Statement::IsData( const char* strPtr ) { const char* rPtr = strPtr; bool returnFlag = false; bool errorFlag; // ..Check for NULL string. if( !strPtr ) return returnFlag; SkipWhiteSpace( &rPtr ); // ..Get data value. errorFlag = GetValue( &rPtr ); // ..If data looks good, check for trailing characters. if( !errorFlag ) { returnFlag = true; type = st_error; SkipWhiteSpace( &rPtr ); if( !*rPtr || (*rPtr == '!') ) { type = st_data; } } if( type == st_error ) PrintError( rPtr, strPtr ); return returnFlag; } bool Statement::IsComment( const char* strPtr ) { const char* rPtr = strPtr; bool returnFlag = false; bool errorFlag; // ..Check for NULL string. if( !strPtr ) return returnFlag; SkipWhiteSpace( &rPtr ); if( !*rPtr || (*rPtr == '!') ) { returnFlag = true; type = st_comment; } return returnFlag; } bool Statement::IsLoad( const char* strPtr ) { const char* rPtr = strPtr; bool returnFlag = false; bool errorFlag; // ..Check for NULL string. if( !strPtr ) return returnFlag; SkipWhiteSpace( &rPtr ); // ..Look for load. if( *rPtr && ((*rPtr == 'l') || (*rPtr == 'L')) ) { ++rPtr; if( *rPtr && ((*rPtr == 'o') || (*rPtr == 'O')) ) { ++rPtr; if( *rPtr && ((*rPtr == 'a') || (*rPtr == 'A')) ) { ++rPtr; if( *rPtr && ((*rPtr == 'd') || (*rPtr == 'D')) ) { ++rPtr; if( *rPtr && isspace(*rPtr) ) { ++rPtr; // ............Found load. returnFlag = true; type = st_error; if( *rPtr && ((*rPtr == 'r') || (*rPtr == 'R')) ) { ++rPtr; if( *rPtr && ((*rPtr == 'a') || (*rPtr == 'A')) ) { ++rPtr; errorFlag = GetRaRbType( &rPtr ); if( !errorFlag ) { type = st_instruction; value = (value & 0x00ff) | (m_proc::load_a << 8); } } else if( *rPtr && ((*rPtr == 'b') || (*rPtr == 'B')) ) { ++rPtr; errorFlag = GetRaRbType( &rPtr ); if( !errorFlag ) { type = st_instruction; value = (value & 0x00ff) | (m_proc::load_b << 8); } } else if( *rPtr && ((*rPtr == 'i') || (*rPtr == 'I')) ) { ++rPtr; errorFlag = GetRiType( &rPtr ); if( !errorFlag ) { type = st_instruction; value = (value & 0x00ff) | (m_proc::load_i << 8); } } } else if( *rPtr && (*rPtr == '[') ) { ++rPtr; SkipWhiteSpace( &rPtr ); errorFlag = GetRcType( &rPtr ); if( !errorFlag ) { type = st_instruction; value = (value & 0x00ff) | (m_proc::load_c << 8); } } } } } } } if( type == st_error ) PrintError( rPtr, strPtr ); return returnFlag; } bool Statement::IsMov( const char* strPtr ) { const char* rPtr = strPtr; bool returnFlag = false; // ..Check for NULL string. if( !strPtr ) return returnFlag; SkipWhiteSpace( &rPtr ); // ..Look for mov. if( *rPtr && ((*rPtr == 'm') || (*rPtr == 'M')) ) { ++rPtr; if( *rPtr && ((*rPtr == 'o') || (*rPtr == 'O')) ) { ++rPtr; if( *rPtr && ((*rPtr == 'v') || (*rPtr == 'V')) ) { ++rPtr; if( *rPtr && isspace(*rPtr) ) { ++rPtr; // ..........Found mov. returnFlag = true; type = st_error; SkipWhiteSpace( &rPtr ); if( *rPtr && ((*rPtr == 'r') || (*rPtr == 'R')) ) { ++rPtr; if( *rPtr && ((*rPtr == 'b') || (*rPtr == 'B')) ) { ++rPtr; SkipWhiteSpace( &rPtr ); if( *rPtr && (*rPtr == '=') ) { ++rPtr; SkipWhiteSpace( &rPtr ); if( *rPtr && ((*rPtr == 'r') || (*rPtr == 'R')) ) { ++rPtr; if( *rPtr && ((*rPtr == 'c') || (*rPtr == 'C')) ) { ++rPtr; SkipWhiteSpace( &rPtr ); if( !*rPtr || (*rPtr == '!') ) { type = st_instruction; value = m_proc::mov_b_c << 8; } } } } } } } } } } if( type == st_error ) PrintError( rPtr, strPtr ); return returnFlag; } bool Statement::IsInc( const char* strPtr ) { const char* rPtr = strPtr; bool returnFlag = false; // ..Check for NULL string. if( !strPtr ) return returnFlag; SkipWhiteSpace( &rPtr ); // ..Look for inc. if( *rPtr && ((*rPtr == 'i') || (*rPtr == 'I')) ) { ++rPtr; if( *rPtr && ((*rPtr == 'n') || (*rPtr == 'N')) ) { ++rPtr; if( *rPtr && ((*rPtr == 'c') || (*rPtr == 'C')) ) { ++rPtr; if( *rPtr && isspace(*rPtr) ) { ++rPtr; // ........Found inc. returnFlag = true; type = st_error; SkipWhiteSpace( &rPtr ); if( !*rPtr || (*rPtr == '!') ) { type = st_instruction; value = m_proc::inc << 8; } } } } } if( type == st_error ) PrintError( rPtr, strPtr ); return returnFlag; } bool Statement::IsDec( const char* strPtr ) { const char* rPtr = strPtr; bool returnFlag = false; // ..Check for NULL string. if( !strPtr ) return returnFlag; SkipWhiteSpace( &rPtr ); // ..Look for dec. if( *rPtr && ((*rPtr == 'd') || (*rPtr == 'D')) ) { ++rPtr; if( *rPtr && ((*rPtr == 'e') || (*rPtr == 'E')) ) { ++rPtr; if( *rPtr && ((*rPtr == 'c') || (*rPtr == 'C')) ) { ++rPtr; if( *rPtr && isspace(*rPtr) ) { ++rPtr; // ........Found dec. returnFlag = true; type = st_error; SkipWhiteSpace( &rPtr ); if( !*rPtr || (*rPtr == '!') ) { type = st_instruction; value = m_proc::dec_i << 8; } } } } } if( type == st_error ) PrintError( rPtr, strPtr ); return returnFlag; } bool Statement::IsAdd( const char* strPtr ) { const char* rPtr = strPtr; bool returnFlag = false; // ..Check for NULL string. if( !strPtr ) return returnFlag; SkipWhiteSpace( &rPtr ); // ..Look for add. if( *rPtr && ((*rPtr == 'a') || (*rPtr == 'D')) ) { ++rPtr; if( *rPtr && ((*rPtr == 'd') || (*rPtr == 'D')) ) { ++rPtr; if( *rPtr && ((*rPtr == 'd') || (*rPtr == 'D')) ) { ++rPtr; if( !*rPtr || (*rPtr && (isspace(*rPtr) || (*rPtr == '!')) ) ) { // ........Found add. returnFlag = true; type = st_error; SkipWhiteSpace( &rPtr ); if( !*rPtr || (*rPtr == '!') ) { type = st_instruction; value = m_proc::add << 8; } } } } } if( type == st_error ) PrintError( rPtr, strPtr ); return returnFlag; } bool Statement::IsMult( const char* strPtr ) { const char* rPtr = strPtr; bool returnFlag = false; // ..Check for NULL string. if( !strPtr ) return returnFlag; SkipWhiteSpace( &rPtr ); // ..Look for mult. if( *rPtr && ((*rPtr == 'm') || (*rPtr == 'M')) ) { ++rPtr; if( *rPtr && ((*rPtr == 'u') || (*rPtr == 'U')) ) { ++rPtr; if( *rPtr && ((*rPtr == 'l') || (*rPtr == 'L')) ) { ++rPtr; if( *rPtr && ((*rPtr == 't') || (*rPtr == 'T')) ) { ++rPtr; if( !*rPtr || (*rPtr && (isspace(*rPtr) || (*rPtr == '!')) ) ) { // ........Found mult. returnFlag = true; type = st_error; SkipWhiteSpace( &rPtr ); if( !*rPtr || (*rPtr == '!') ) { type = st_instruction; value = m_proc::mult << 8; } } } } } } if( type == st_error ) PrintError( rPtr, strPtr ); return returnFlag; } bool Statement::IsJmp( const char* strPtr ) { const char* rPtr = strPtr; bool returnFlag = false; bool errorFlag; // ..Check for NULL string. if( !strPtr ) return returnFlag; SkipWhiteSpace( &rPtr ); // ..Look for jmp. if( *rPtr && ((*rPtr == 'j') || (*rPtr == 'J')) ) { ++rPtr; if( *rPtr && ((*rPtr == 'm') || (*rPtr == 'M')) ) { ++rPtr; if( *rPtr && ((*rPtr == 'p') || (*rPtr == 'P')) ) { ++rPtr; if( *rPtr && isspace(*rPtr) ) { ++rPtr; // ..........Found jmp. returnFlag = true; type = st_error; SkipWhiteSpace( &rPtr ); errorFlag = GetXXType( &rPtr ); if( !errorFlag ) { SkipWhiteSpace( &rPtr ); if( !*rPtr || (*rPtr == '!') ) { type = st_instruction; value = (value & 0x00ff) | (m_proc::jmp_xx << 8); } } } } } } if( type == st_error ) PrintError( rPtr, strPtr ); return returnFlag; } bool Statement::IsJz( const char* strPtr ) { const char* rPtr = strPtr; bool returnFlag = false; bool errorFlag; // ..Check for NULL string. if( !strPtr ) return returnFlag; SkipWhiteSpace( &rPtr ); // ..Look for jz. if( *rPtr && ((*rPtr == 'j') || (*rPtr == 'J')) ) { ++rPtr; if( *rPtr && ((*rPtr == 'z') || (*rPtr == 'Z')) ) { ++rPtr; if( *rPtr && isspace(*rPtr) ) { ++rPtr; // ........Found jz. returnFlag = true; type = st_error; SkipWhiteSpace( &rPtr ); errorFlag = GetXXType( &rPtr ); if( !errorFlag ) { SkipWhiteSpace( &rPtr ); if( !*rPtr || (*rPtr == '!') ) { type = st_instruction; value = (value & 0x00ff) | (m_proc::jmp_0_xx << 8); } } } } } if( type == st_error ) PrintError( rPtr, strPtr ); return returnFlag; } bool Statement::IsHalt( const char* strPtr ) { const char* rPtr = strPtr; bool returnFlag = false; // ..Check for NULL string. if( !strPtr ) return returnFlag; SkipWhiteSpace( &rPtr ); // ..Look for halt. if( *rPtr && ((*rPtr == 'h') || (*rPtr == 'H')) ) { ++rPtr; if( *rPtr && ((*rPtr == 'a') || (*rPtr == 'A')) ) { ++rPtr; if( *rPtr && ((*rPtr == 'l') || (*rPtr == 'L')) ) { ++rPtr; if( *rPtr && ((*rPtr == 't') || (*rPtr == 'T')) ) { ++rPtr; if( !*rPtr || (*rPtr && (isspace(*rPtr) || (*rPtr == '!')) ) ) { // ........Found halt. returnFlag = true; type = st_error; SkipWhiteSpace( &rPtr ); if( !*rPtr || (*rPtr == '!') ) { type = st_instruction; value = m_proc::halt << 8; } } } } } } if( type == st_error ) PrintError( rPtr, strPtr ); return returnFlag; } bool Statement::IsLabel( const char* strPtr ) { const char* rPtr = strPtr; bool returnFlag = false; // ..Check for NULL string. if( !strPtr ) return returnFlag; SkipWhiteSpace( &rPtr ); if( *rPtr && isalpha(*rPtr) ) { label = *rPtr; ++rPtr; for( ;*rPtr && isalnum(*rPtr); ++rPtr ) { label += *rPtr; } if( *rPtr && (*rPtr == ':') ) { returnFlag = true; type = st_label; } else { label = ""; } } return returnFlag; }