mirror of
http://git.hugovil.com/git/emu8051.git
synced 2025-05-09 00:51:03 +08:00
Add options -h and -version
Merge common function LoadHexFile() to file.c.
This commit is contained in:
parent
69b536c338
commit
ec415e2315
@ -20,7 +20,7 @@ It is written in C++, and uses Perl scripts to generate automatically C++ functi
|
|||||||
\fB\-h\fR
|
\fB\-h\fR
|
||||||
display usage and exit
|
display usage and exit
|
||||||
.TP
|
.TP
|
||||||
\fB\-v\fR
|
\fB\-version\fR
|
||||||
output version information and exit
|
output version information and exit
|
||||||
|
|
||||||
.SH CREDITS
|
.SH CREDITS
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// EmuConsole.cpp
|
/* EmuConsole.cpp */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -9,6 +9,21 @@
|
|||||||
#include "Reg8051.hpp"
|
#include "Reg8051.hpp"
|
||||||
#include "Keyboard.hpp"
|
#include "Keyboard.hpp"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "options.h"
|
||||||
|
#include "file.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EmuConsole *EmuConsolePtr;
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
cpu_write_pgm( unsigned int Address, unsigned char Value )
|
||||||
|
{
|
||||||
|
EmuConsolePtr->CPU->WritePGM( Address, Value );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main( int argc, char **argv )
|
int main( int argc, char **argv )
|
||||||
{
|
{
|
||||||
@ -26,6 +41,37 @@ int main( int argc, char **argv )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
Ascii2Hex_TEMP( string istring, unsigned int length )
|
||||||
|
{
|
||||||
|
if ( !length || ( length > istring.size() ) )
|
||||||
|
length = istring.size();
|
||||||
|
|
||||||
|
if ( istring.empty() )
|
||||||
|
throw MissingParameter();
|
||||||
|
|
||||||
|
unsigned int result = 0;
|
||||||
|
unsigned int i, ascii_code;
|
||||||
|
for ( i = 0; i < length; i++ ) {
|
||||||
|
ascii_code = istring[ i ];
|
||||||
|
if ( ascii_code > 0x39 )
|
||||||
|
ascii_code &= 0xDF;
|
||||||
|
if ( ( ascii_code >= 0x30 && ascii_code <= 0x39 ) || ( ascii_code >= 0x41 && ascii_code <= 0x46 ) ) {
|
||||||
|
ascii_code -= 0x30;
|
||||||
|
if ( ascii_code > 9 )
|
||||||
|
ascii_code -= 7;
|
||||||
|
result <<= 4;
|
||||||
|
result += ascii_code;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw SyntaxError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// EmuConsole::EmuConsole( int argc, char **argv, CPU8051 *mCPU )
|
// EmuConsole::EmuConsole( int argc, char **argv, CPU8051 *mCPU )
|
||||||
// EmuConsole constructor
|
// EmuConsole constructor
|
||||||
@ -35,7 +81,14 @@ EmuConsole::EmuConsole( int argc, char **argv, CPU8051 *mCPU )
|
|||||||
CPU = mCPU;
|
CPU = mCPU;
|
||||||
CPU->Reset( );
|
CPU->Reset( );
|
||||||
NbBreakpoints = 0;
|
NbBreakpoints = 0;
|
||||||
if ( argc > 1 ) LoadHexFile( argv[ 1 ] );
|
|
||||||
|
EmuConsolePtr = this;
|
||||||
|
|
||||||
|
ParseCommandLineOptions( argc, argv );
|
||||||
|
|
||||||
|
if( GetHexFileName() != NULL ) {
|
||||||
|
LoadHexFile( GetHexFileName(), cpu_write_pgm );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@ -183,18 +236,18 @@ void EmuConsole::Main( )
|
|||||||
if ( Parameter1.empty() || Parameter2.empty() )
|
if ( Parameter1.empty() || Parameter2.empty() )
|
||||||
throw MissingParameter();
|
throw MissingParameter();
|
||||||
else if ( Command == "ME" ) {
|
else if ( Command == "ME" ) {
|
||||||
unsigned int adresse = Ascii2Hex( Parameter1, 4 );
|
unsigned int adresse = Ascii2Hex_TEMP( Parameter1, 4 );
|
||||||
unsigned char valeur = Ascii2Hex( Parameter2, 2 );
|
unsigned char valeur = Ascii2Hex_TEMP( Parameter2, 2 );
|
||||||
CPU->WriteExt( adresse, valeur );
|
CPU->WriteExt( adresse, valeur );
|
||||||
}
|
}
|
||||||
else if ( Command == "MI" ) {
|
else if ( Command == "MI" ) {
|
||||||
unsigned char adresse = Ascii2Hex( Parameter1, 2 );
|
unsigned char adresse = Ascii2Hex_TEMP( Parameter1, 2 );
|
||||||
unsigned char valeur = Ascii2Hex( Parameter2, 2 );
|
unsigned char valeur = Ascii2Hex_TEMP( Parameter2, 2 );
|
||||||
CPU->WriteInt( adresse, valeur );
|
CPU->WriteInt( adresse, valeur );
|
||||||
}
|
}
|
||||||
else if ( Command == "MP" ) {
|
else if ( Command == "MP" ) {
|
||||||
unsigned int adresse = Ascii2Hex( Parameter1, 4 );
|
unsigned int adresse = Ascii2Hex_TEMP( Parameter1, 4 );
|
||||||
unsigned char valeur = Ascii2Hex( Parameter2, 2 );
|
unsigned char valeur = Ascii2Hex_TEMP( Parameter2, 2 );
|
||||||
CPU->WritePGM( adresse, valeur );
|
CPU->WritePGM( adresse, valeur );
|
||||||
}
|
}
|
||||||
else if ( Command == "MR" )
|
else if ( Command == "MR" )
|
||||||
@ -215,7 +268,7 @@ void EmuConsole::Main( )
|
|||||||
if ( Parameter1.empty( ) )
|
if ( Parameter1.empty( ) )
|
||||||
ClearBreakpoint( CPU->GetPC( ) );
|
ClearBreakpoint( CPU->GetPC( ) );
|
||||||
else
|
else
|
||||||
ClearBreakpoint( Ascii2Hex( Parameter1, 4 ) );
|
ClearBreakpoint( Ascii2Hex_TEMP( Parameter1, 4 ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw SyntaxError( );
|
throw SyntaxError( );
|
||||||
@ -227,7 +280,7 @@ void EmuConsole::Main( )
|
|||||||
if ( Parameter1.empty( ) )
|
if ( Parameter1.empty( ) )
|
||||||
SetBreakpoint( CPU->GetPC( ) );
|
SetBreakpoint( CPU->GetPC( ) );
|
||||||
else
|
else
|
||||||
SetBreakpoint( Ascii2Hex( Parameter1, 4 ) );
|
SetBreakpoint( Ascii2Hex_TEMP( Parameter1, 4 ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw SyntaxError( );
|
throw SyntaxError( );
|
||||||
@ -299,7 +352,7 @@ void EmuConsole::Reset( )
|
|||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
void EmuConsole::Trace( string Address )
|
void EmuConsole::Trace( string Address )
|
||||||
{
|
{
|
||||||
if ( !Address.empty( ) ) CPU->SetPC( Ascii2Hex( Address, Address.size( ) ) );
|
if ( !Address.empty( ) ) CPU->SetPC( Ascii2Hex_TEMP( Address, Address.size( ) ) );
|
||||||
CPU->Exec( );
|
CPU->Exec( );
|
||||||
ShowRegisters( );
|
ShowRegisters( );
|
||||||
DisasmN( CPU->GetPC( ), 1 );
|
DisasmN( CPU->GetPC( ), 1 );
|
||||||
@ -315,10 +368,10 @@ void EmuConsole::Exec( string Address, string NumberInst )
|
|||||||
int NbInst = -1; // -1 is infinity
|
int NbInst = -1; // -1 is infinity
|
||||||
if ( !Address.empty( ) ) {
|
if ( !Address.empty( ) ) {
|
||||||
Capitalize( &Address );
|
Capitalize( &Address );
|
||||||
if ( Address != "PC" ) CPU->SetPC( Ascii2Hex( Address, Address.size( ) ) );
|
if ( Address != "PC" ) CPU->SetPC( Ascii2Hex_TEMP( Address, Address.size( ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !NumberInst.empty( ) ) NbInst = Ascii2Hex( NumberInst, NumberInst.size( ) );
|
if ( !NumberInst.empty( ) ) NbInst = Ascii2Hex_TEMP( NumberInst, NumberInst.size( ) );
|
||||||
|
|
||||||
InitUnixKB( );
|
InitUnixKB( );
|
||||||
|
|
||||||
@ -392,9 +445,9 @@ void EmuConsole::Disasm( string Address, string NumberInst )
|
|||||||
unsigned int MemAddress, NbInst;
|
unsigned int MemAddress, NbInst;
|
||||||
Capitalize( &Address );
|
Capitalize( &Address );
|
||||||
if ( Address.empty( ) || ( Address == "PC" ) ) MemAddress = CPU->GetPC( );
|
if ( Address.empty( ) || ( Address == "PC" ) ) MemAddress = CPU->GetPC( );
|
||||||
else MemAddress = Ascii2Hex( Address, Address.size( ) );
|
else MemAddress = Ascii2Hex_TEMP( Address, Address.size( ) );
|
||||||
if ( NumberInst.empty( ) ) NumberInst = "10";
|
if ( NumberInst.empty( ) ) NumberInst = "10";
|
||||||
NbInst = Ascii2Hex( NumberInst, NumberInst.size( ) );
|
NbInst = Ascii2Hex_TEMP( NumberInst, NumberInst.size( ) );
|
||||||
DisasmN( MemAddress, NbInst );
|
DisasmN( MemAddress, NbInst );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -426,7 +479,7 @@ void EmuConsole::DumpPGM( string Address )
|
|||||||
if ( Address == "PC" )
|
if ( Address == "PC" )
|
||||||
MemAddress = CPU->GetPC( );
|
MemAddress = CPU->GetPC( );
|
||||||
else
|
else
|
||||||
MemAddress = Ascii2Hex( Address, Address.size( ) );
|
MemAddress = Ascii2Hex_TEMP( Address, Address.size( ) );
|
||||||
}
|
}
|
||||||
for ( Offset = 0; Offset < 256; Offset += 16 ) {
|
for ( Offset = 0; Offset < 256; Offset += 16 ) {
|
||||||
printf( "%.4X ", MemAddress + Offset );
|
printf( "%.4X ", MemAddress + Offset );
|
||||||
@ -456,7 +509,7 @@ void EmuConsole::DumpI( string Address )
|
|||||||
unsigned int MemAddress = 0;
|
unsigned int MemAddress = 0;
|
||||||
int Offset, Column;
|
int Offset, Column;
|
||||||
unsigned char Byte;
|
unsigned char Byte;
|
||||||
if ( !Address.empty( ) ) MemAddress = Ascii2Hex( Address, Address.size( ) );
|
if ( !Address.empty( ) ) MemAddress = Ascii2Hex_TEMP( Address, Address.size( ) );
|
||||||
for ( Offset = 0; Offset < 256; Offset += 16 ) {
|
for ( Offset = 0; Offset < 256; Offset += 16 ) {
|
||||||
printf( "%.4X ", MemAddress + Offset );
|
printf( "%.4X ", MemAddress + Offset );
|
||||||
for ( Column = 0; Column < 16; Column++ )
|
for ( Column = 0; Column < 16; Column++ )
|
||||||
@ -482,7 +535,7 @@ void EmuConsole::DumpInt( string Address )
|
|||||||
int Offset, Column;
|
int Offset, Column;
|
||||||
unsigned char Byte;
|
unsigned char Byte;
|
||||||
if ( !Address.empty( ) )
|
if ( !Address.empty( ) )
|
||||||
MemAddress = Ascii2Hex( Address, 4 );
|
MemAddress = Ascii2Hex_TEMP( Address, 4 );
|
||||||
for ( Offset = 0; Offset < 256; Offset += 16 ) {
|
for ( Offset = 0; Offset < 256; Offset += 16 ) {
|
||||||
printf( "%.4X ", MemAddress + Offset );
|
printf( "%.4X ", MemAddress + Offset );
|
||||||
for ( Column = 0; Column < 16; Column++ )
|
for ( Column = 0; Column < 16; Column++ )
|
||||||
@ -509,7 +562,7 @@ void EmuConsole::DumpExt( string Address )
|
|||||||
int Offset, Column;
|
int Offset, Column;
|
||||||
unsigned char Byte;
|
unsigned char Byte;
|
||||||
if ( !Address.empty( ) )
|
if ( !Address.empty( ) )
|
||||||
MemAddress = Ascii2Hex( Address, 4 );
|
MemAddress = Ascii2Hex_TEMP( Address, 4 );
|
||||||
for ( Offset = 0; Offset < 256; Offset += 16 ) {
|
for ( Offset = 0; Offset < 256; Offset += 16 ) {
|
||||||
printf( "%.4X ", MemAddress + Offset );
|
printf( "%.4X ", MemAddress + Offset );
|
||||||
for ( Column = 0; Column < 16; Column++ )
|
for ( Column = 0; Column < 16; Column++ )
|
||||||
@ -534,7 +587,7 @@ void EmuConsole::DumpD( string Address )
|
|||||||
unsigned int MemAddress = 0;
|
unsigned int MemAddress = 0;
|
||||||
int Offset, Column;
|
int Offset, Column;
|
||||||
unsigned char Byte;
|
unsigned char Byte;
|
||||||
if ( !Address.empty( ) ) MemAddress = Ascii2Hex( Address, Address.size( ) );
|
if ( !Address.empty( ) ) MemAddress = Ascii2Hex_TEMP( Address, Address.size( ) );
|
||||||
for ( Offset = 0; Offset < 256; Offset += 16 ) {
|
for ( Offset = 0; Offset < 256; Offset += 16 ) {
|
||||||
printf( "%.4X ", MemAddress + Offset );
|
printf( "%.4X ", MemAddress + Offset );
|
||||||
for ( Column = 0; Column < 16; Column++ )
|
for ( Column = 0; Column < 16; Column++ )
|
||||||
@ -557,10 +610,10 @@ void EmuConsole::DumpD( string Address )
|
|||||||
void EmuConsole::SetRegister( string Register, string NewValue )
|
void EmuConsole::SetRegister( string Register, string NewValue )
|
||||||
{
|
{
|
||||||
Capitalize( &Register );
|
Capitalize( &Register );
|
||||||
if ( Register == "PC" ) CPU->SetPC( Ascii2Hex( NewValue, 4 ) );
|
if ( Register == "PC" ) CPU->SetPC( Ascii2Hex_TEMP( NewValue, 4 ) );
|
||||||
else if ( Register == "A" ) CPU->WriteD( _ACC_, Ascii2Hex( NewValue, 2 ) );
|
else if ( Register == "A" ) CPU->WriteD( _ACC_, Ascii2Hex_TEMP( NewValue, 2 ) );
|
||||||
else if ( Register == "B" ) CPU->WriteD( _B_, Ascii2Hex( NewValue, 2 ) );
|
else if ( Register == "B" ) CPU->WriteD( _B_, Ascii2Hex_TEMP( NewValue, 2 ) );
|
||||||
else if ( Register == "SP" ) CPU->WriteD( _SP_, Ascii2Hex( NewValue, 2 ) );
|
else if ( Register == "SP" ) CPU->WriteD( _SP_, Ascii2Hex_TEMP( NewValue, 2 ) );
|
||||||
else throw InvalidRegister( );
|
else throw InvalidRegister( );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -617,121 +670,3 @@ void EmuConsole::ShowRegisters( )
|
|||||||
printf( "----------------------------------------------------------------------%s", ENDLINE );
|
printf( "----------------------------------------------------------------------%s", ENDLINE );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
// void EmuConsole::LoadHexFile( string Filename )
|
|
||||||
//
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
void EmuConsole::LoadHexFile( string Filename )
|
|
||||||
{
|
|
||||||
|
|
||||||
printf("LoadHex\n");
|
|
||||||
int i, j, RecLength, LoadOffset, RecType, Data, Checksum;
|
|
||||||
char Line[ 250 ];
|
|
||||||
|
|
||||||
ifstream HexFile( Filename.c_str() );
|
|
||||||
try {
|
|
||||||
if ( ! HexFile )
|
|
||||||
throw ErrorOpeningFile();
|
|
||||||
|
|
||||||
while( ! HexFile.eof() ) {
|
|
||||||
i = 0;
|
|
||||||
Checksum = 0;
|
|
||||||
HexFile.getline( Line, 250, '\n' );
|
|
||||||
|
|
||||||
if ( Line[ i++ ] != ':' )
|
|
||||||
throw ErrorHexFileFormat();
|
|
||||||
|
|
||||||
RecLength = Ascii2Hex( &Line[ i ], 2 );
|
|
||||||
i += 2;
|
|
||||||
Checksum += RecLength;
|
|
||||||
|
|
||||||
LoadOffset = Ascii2Hex( &Line[i], 4 );
|
|
||||||
Checksum += LoadOffset / 256;
|
|
||||||
Checksum += LoadOffset % 256;
|
|
||||||
i += 4;
|
|
||||||
|
|
||||||
RecType = Ascii2Hex( &Line[i],2);
|
|
||||||
i += 2;
|
|
||||||
Checksum += RecType;
|
|
||||||
|
|
||||||
if ( RecType == 1 ) {
|
|
||||||
Checksum += Ascii2Hex( &Line[ i ], 2 );
|
|
||||||
if ( Checksum &= 0x000000FF )
|
|
||||||
throw ErrorHexFileFormat();
|
|
||||||
throw FinishedLoading();
|
|
||||||
}
|
|
||||||
if ( RecType )
|
|
||||||
throw ErrorHexFileFormat();
|
|
||||||
|
|
||||||
for ( j = 0; j < RecLength; j++ ) {
|
|
||||||
Data = Ascii2Hex( &Line[ i ], 2 );
|
|
||||||
CPU->WritePGM( (unsigned int)(LoadOffset + j), (unsigned char)Data );
|
|
||||||
i += 2;
|
|
||||||
Checksum += Data;
|
|
||||||
}
|
|
||||||
RecType = Ascii2Hex( &Line[ i ], 2 );
|
|
||||||
Checksum += RecType;
|
|
||||||
|
|
||||||
if ( Checksum &= 0x000000FF )
|
|
||||||
throw ErrorHexFileFormat();
|
|
||||||
}
|
|
||||||
throw ErrorHexFileFormat();
|
|
||||||
}
|
|
||||||
catch ( ErrorOpeningFile ) {
|
|
||||||
cout << "Error opening file " << Filename << endl;
|
|
||||||
}
|
|
||||||
catch ( ErrorHexFileFormat ) {
|
|
||||||
cout << "Invalid format for " << Filename << " file..." << endl;
|
|
||||||
}
|
|
||||||
catch ( SyntaxError ) {
|
|
||||||
cout << "Invalid format for " << Filename << " file..." << endl;
|
|
||||||
}
|
|
||||||
catch ( MissingParameter ) {
|
|
||||||
cout << "Invalid format for " << Filename << " file..." << endl;
|
|
||||||
}
|
|
||||||
catch ( FinishedLoading ) {
|
|
||||||
cout << "Using file " << Filename << " as input program." << endl;
|
|
||||||
}
|
|
||||||
HexFile.close();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
// unsigned int EmuConsole::Ascii2Hex( string istring, int length )
|
|
||||||
//
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
unsigned int EmuConsole::Ascii2Hex( string istring, unsigned int length )
|
|
||||||
{
|
|
||||||
if ( !length || ( length > istring.size() ) )
|
|
||||||
length = istring.size();
|
|
||||||
|
|
||||||
if ( istring.empty() )
|
|
||||||
throw MissingParameter();
|
|
||||||
|
|
||||||
unsigned int result = 0;
|
|
||||||
unsigned int i, ascii_code;
|
|
||||||
for ( i = 0; i < length; i++ ) {
|
|
||||||
ascii_code = istring[ i ];
|
|
||||||
if ( ascii_code > 0x39 )
|
|
||||||
ascii_code &= 0xDF;
|
|
||||||
if ( ( ascii_code >= 0x30 && ascii_code <= 0x39 ) || ( ascii_code >= 0x41 && ascii_code <= 0x46 ) ) {
|
|
||||||
ascii_code -= 0x30;
|
|
||||||
if ( ascii_code > 9 )
|
|
||||||
ascii_code -= 7;
|
|
||||||
result <<= 4;
|
|
||||||
result += ascii_code;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw SyntaxError();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,6 +24,8 @@ public:
|
|||||||
EmuConsole( int argc, char **argv, CPU8051 *mCPU );
|
EmuConsole( int argc, char **argv, CPU8051 *mCPU );
|
||||||
~EmuConsole( );
|
~EmuConsole( );
|
||||||
|
|
||||||
|
CPU8051 *CPU;
|
||||||
|
|
||||||
void Main( );
|
void Main( );
|
||||||
|
|
||||||
void Reset( );
|
void Reset( );
|
||||||
@ -46,12 +48,9 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CPU8051 *CPU;
|
|
||||||
int NbBreakpoints;
|
int NbBreakpoints;
|
||||||
unsigned int Breakpoints[ MAXBP ];
|
unsigned int Breakpoints[ MAXBP ];
|
||||||
|
|
||||||
void LoadHexFile( string Filename );
|
|
||||||
unsigned int Ascii2Hex( string istring, unsigned int length );
|
|
||||||
void Capitalize( string *InputString );
|
void Capitalize( string *InputString );
|
||||||
void RemoveSpaces( string *InputString );
|
void RemoveSpaces( string *InputString );
|
||||||
|
|
||||||
|
133
src/EmuGtk.cpp
133
src/EmuGtk.cpp
@ -11,6 +11,11 @@
|
|||||||
#include "stop.xpm"
|
#include "stop.xpm"
|
||||||
#include "step.xpm"
|
#include "step.xpm"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "options.h"
|
||||||
|
#include "file.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int EmuGtkNumber = 0;
|
int EmuGtkNumber = 0;
|
||||||
int NbSignals = 0;
|
int NbSignals = 0;
|
||||||
@ -32,6 +37,13 @@ enum
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
cpu_write_pgm( unsigned int Address, unsigned char Value )
|
||||||
|
{
|
||||||
|
EmuGtkPtr->CPU->WritePGM( Address, Value );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main( int argc, char **argv )
|
int main( int argc, char **argv )
|
||||||
{
|
{
|
||||||
CPU8051 *maincpu = new CPU8051;
|
CPU8051 *maincpu = new CPU8051;
|
||||||
@ -46,6 +58,7 @@ int main( int argc, char **argv )
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// EmuGtk::EmuGtk( )
|
// EmuGtk::EmuGtk( )
|
||||||
// EmuGtk constructor
|
// EmuGtk constructor
|
||||||
@ -55,6 +68,8 @@ EmuGtk::EmuGtk( int argc, char **argv, CPU8051 *mCPU )
|
|||||||
CPU = mCPU;
|
CPU = mCPU;
|
||||||
RunningState = 0;
|
RunningState = 0;
|
||||||
|
|
||||||
|
ParseCommandLineOptions( argc, argv );
|
||||||
|
|
||||||
g_print( "\n" );
|
g_print( "\n" );
|
||||||
|
|
||||||
gtk_init( &argc, &argv );
|
gtk_init( &argc, &argv );
|
||||||
@ -161,12 +176,12 @@ EmuGtk::EmuGtk( int argc, char **argv, CPU8051 *mCPU )
|
|||||||
EmuGtkNumber++;
|
EmuGtkNumber++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( argc > 1 )
|
if( GetHexFileName() != NULL ) {
|
||||||
LoadHexFile( argv[1] );
|
LoadHexFile( GetHexFileName(), cpu_write_pgm );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// void AddButtons()
|
// void AddButtons()
|
||||||
// Create and show the Reset, Run, Stop, Trace and Step buttons
|
// Create and show the Reset, Run, Stop, Trace and Step buttons
|
||||||
@ -411,13 +426,13 @@ void FileOpenDialog_OK( GtkButton *button, gpointer data )
|
|||||||
|
|
||||||
const gchar *SelectedFile;
|
const gchar *SelectedFile;
|
||||||
|
|
||||||
SelectedFile = gtk_file_selection_get_filename ( GTK_FILE_SELECTION ( data ) );
|
SelectedFile = (const gchar *) gtk_file_selection_get_filename ( GTK_FILE_SELECTION ( data ) );
|
||||||
|
|
||||||
g_print( "EmuGtk::File = %s\n", SelectedFile );
|
g_print( "EmuGtk::File = %s\n", SelectedFile );
|
||||||
|
|
||||||
EmuGtkPtr->StopRunning( );
|
EmuGtkPtr->StopRunning( );
|
||||||
|
|
||||||
EmuGtkPtr->LoadHexFile( SelectedFile );
|
LoadHexFile( SelectedFile, cpu_write_pgm );
|
||||||
|
|
||||||
gtk_widget_destroy( GTK_WIDGET( data ) );
|
gtk_widget_destroy( GTK_WIDGET( data ) );
|
||||||
|
|
||||||
@ -505,114 +520,6 @@ void EmuGtk::StepEvent( GtkWidget *widget, GdkEvent *event, gpointer data )
|
|||||||
Step( );
|
Step( );
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
// unsigned int EmuGtk::Ascii2Hex( string istring, int length = 0 )
|
|
||||||
// Convert an ascii string to an hexadecimal number
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
unsigned int EmuGtk::Ascii2Hex( string istring, int length = 0 )
|
|
||||||
{
|
|
||||||
if ( !length || ( length > (int) istring.size() ) )
|
|
||||||
length = istring.size();
|
|
||||||
|
|
||||||
if ( istring.empty() )
|
|
||||||
throw MissingParameter();
|
|
||||||
|
|
||||||
unsigned int result = 0;
|
|
||||||
int i, ascii_code;
|
|
||||||
for ( i = 0; i < length; i++ ) {
|
|
||||||
ascii_code = istring[ i ];
|
|
||||||
if ( ascii_code > 0x39 )
|
|
||||||
ascii_code &= 0xDF;
|
|
||||||
if ( ( ascii_code >= 0x30 && ascii_code <= 0x39 ) || ( ascii_code >= 0x41 && ascii_code <= 0x46 ) ) {
|
|
||||||
ascii_code -= 0x30;
|
|
||||||
if ( ascii_code > 9 )
|
|
||||||
ascii_code -= 7;
|
|
||||||
result <<= 4;
|
|
||||||
result += ascii_code;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw SyntaxError();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
// void EmuGtk::LoadHexFile( string Filename )
|
|
||||||
// Load an HEX file into program memory
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
void EmuGtk::LoadHexFile( string Filename )
|
|
||||||
{
|
|
||||||
printf("LoadHex\n");
|
|
||||||
int i, j, RecLength, LoadOffset, RecType, Data, Checksum;
|
|
||||||
char Line[ 250 ];
|
|
||||||
|
|
||||||
ifstream HexFile( Filename.c_str() );
|
|
||||||
try {
|
|
||||||
if ( ! HexFile )
|
|
||||||
throw ErrorOpeningFile();
|
|
||||||
|
|
||||||
while( ! HexFile.eof() ) {
|
|
||||||
i = 0;
|
|
||||||
Checksum = 0;
|
|
||||||
HexFile.getline( Line, 250, '\n' );
|
|
||||||
|
|
||||||
if ( Line[ i++ ] != ':' )
|
|
||||||
throw ErrorHexFileFormat();
|
|
||||||
|
|
||||||
RecLength = Ascii2Hex( &Line[ i ], 2 );
|
|
||||||
i += 2;
|
|
||||||
Checksum += RecLength;
|
|
||||||
|
|
||||||
LoadOffset = Ascii2Hex( &Line[i], 4 );
|
|
||||||
Checksum += LoadOffset / 256;
|
|
||||||
Checksum += LoadOffset % 256;
|
|
||||||
i += 4;
|
|
||||||
|
|
||||||
RecType = Ascii2Hex( &Line[i],2);
|
|
||||||
i += 2;
|
|
||||||
Checksum += RecType;
|
|
||||||
|
|
||||||
if ( RecType == 1 ) {
|
|
||||||
Checksum += Ascii2Hex( &Line[ i ], 2 );
|
|
||||||
if ( Checksum &= 0x000000FF )
|
|
||||||
throw ErrorHexFileFormat();
|
|
||||||
throw FinishedLoading();
|
|
||||||
}
|
|
||||||
if ( RecType )
|
|
||||||
throw ErrorHexFileFormat();
|
|
||||||
|
|
||||||
for ( j = 0; j < RecLength; j++ ) {
|
|
||||||
Data = Ascii2Hex( &Line[ i ], 2 );
|
|
||||||
CPU->WritePGM( (unsigned int)(LoadOffset + j), (unsigned char)Data );
|
|
||||||
i += 2;
|
|
||||||
Checksum += Data;
|
|
||||||
}
|
|
||||||
RecType = Ascii2Hex( &Line[ i ], 2 );
|
|
||||||
Checksum += RecType;
|
|
||||||
|
|
||||||
if ( Checksum &= 0x000000FF )
|
|
||||||
throw ErrorHexFileFormat();
|
|
||||||
}
|
|
||||||
throw ErrorHexFileFormat();
|
|
||||||
}
|
|
||||||
catch ( ErrorOpeningFile ) {
|
|
||||||
cout << "Error opening file " << Filename << endl;
|
|
||||||
}
|
|
||||||
catch ( ErrorHexFileFormat ) {
|
|
||||||
cout << "Invalid format for " << Filename << " file..." << endl;
|
|
||||||
}
|
|
||||||
catch ( SyntaxError ) {
|
|
||||||
cout << "Invalid format for " << Filename << " file..." << endl;
|
|
||||||
}
|
|
||||||
catch ( MissingParameter ) {
|
|
||||||
cout << "Invalid format for " << Filename << " file..." << endl;
|
|
||||||
}
|
|
||||||
catch ( FinishedLoading ) {
|
|
||||||
cout << "Using file " << Filename << " as input program." << endl;
|
|
||||||
}
|
|
||||||
HexFile.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// gint EmuGtkSignalStub2( GtkWidget *widget, gpointer data )
|
// gint EmuGtkSignalStub2( GtkWidget *widget, gpointer data )
|
||||||
|
@ -22,6 +22,8 @@ class EmuGtk {
|
|||||||
public:
|
public:
|
||||||
EmuGtk( int argc , char **argv, CPU8051 *mCPU );
|
EmuGtk( int argc , char **argv, CPU8051 *mCPU );
|
||||||
~EmuGtk( );
|
~EmuGtk( );
|
||||||
|
|
||||||
|
CPU8051 *CPU; /* Test */
|
||||||
|
|
||||||
void Main( );
|
void Main( );
|
||||||
|
|
||||||
@ -49,12 +51,11 @@ public:
|
|||||||
void StopRunning( );
|
void StopRunning( );
|
||||||
void Running( );
|
void Running( );
|
||||||
|
|
||||||
void LoadHexFile( string Filename );
|
|
||||||
void UpdateDisplay();
|
void UpdateDisplay();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int EmuGtkID;
|
int EmuGtkID;
|
||||||
CPU8051 *CPU;
|
|
||||||
int RunningState;
|
int RunningState;
|
||||||
int RunFuncTag;
|
int RunFuncTag;
|
||||||
MemWin *memwin;
|
MemWin *memwin;
|
||||||
@ -96,8 +97,6 @@ private:
|
|||||||
GdkPixmap *STEP_pixmap;
|
GdkPixmap *STEP_pixmap;
|
||||||
GtkWidget *STEP_widget;
|
GtkWidget *STEP_widget;
|
||||||
GtkWidget *ButtonStep;
|
GtkWidget *ButtonStep;
|
||||||
|
|
||||||
unsigned int Ascii2Hex( string istring, int length );
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void EmuGtkSignalStub3( GtkWidget *widget, GdkEvent *event, gpointer data );
|
void EmuGtkSignalStub3( GtkWidget *widget, GdkEvent *event, gpointer data );
|
||||||
|
@ -5,10 +5,11 @@ INCLUDES = -I$(top_srcdir)/pixmaps
|
|||||||
bin_PROGRAMS = emu8051 emu8051_console
|
bin_PROGRAMS = emu8051 emu8051_console
|
||||||
|
|
||||||
emu8051_SOURCES = EmuGtk.hpp EmuGtk.cpp CPU8051.hpp CPU8051.cpp Memory.hpp Memory.cpp \
|
emu8051_SOURCES = EmuGtk.hpp EmuGtk.cpp CPU8051.hpp CPU8051.cpp Memory.hpp Memory.cpp \
|
||||||
MemWin.hpp MemWin.cpp PgmWin.hpp PgmWin.cpp RegWin.hpp RegWin.cpp
|
MemWin.hpp MemWin.cpp PgmWin.hpp PgmWin.cpp RegWin.hpp RegWin.cpp options.c \
|
||||||
|
common.h file.c
|
||||||
|
|
||||||
emu8051_console_SOURCES = EmuConsole.hpp EmuConsole.cpp CPU8051.hpp CPU8051.cpp Memory.hpp \
|
emu8051_console_SOURCES = EmuConsole.hpp EmuConsole.cpp CPU8051.hpp CPU8051.cpp Memory.hpp \
|
||||||
Memory.cpp Keyboard.hpp
|
Memory.cpp Keyboard.hpp options.c common.h file.c
|
||||||
|
|
||||||
# These headers will be included in the distribution tarball, but will not be
|
# These headers will be included in the distribution tarball, but will not be
|
||||||
# installed by 'make install'
|
# installed by 'make install'
|
||||||
|
46
src/common.h
Normal file
46
src/common.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/* common.h */
|
||||||
|
|
||||||
|
#ifndef COMMON_H
|
||||||
|
#define COMMON_H 1
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#if STDC_HEADERS
|
||||||
|
# include <string.h>
|
||||||
|
#elif HAVE_STRINGS_H
|
||||||
|
# include <strings.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Common constants. */
|
||||||
|
#ifndef EXIT_SUCCESS
|
||||||
|
# define EXIT_SUCCESS 0
|
||||||
|
# define EXIT_FAILURE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef int bool;
|
||||||
|
#ifndef FALSE
|
||||||
|
# define FALSE 0
|
||||||
|
# define TRUE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Returns TRUE if the strings 'a' and 'b' are equal. */
|
||||||
|
#define STREQ(a, b) (strcmp((a), (b)) == 0)
|
||||||
|
|
||||||
|
/* Returns TRUE if the first 'c' characters of strings 'a' and 'b' are equal. */
|
||||||
|
#define STREQ_LEN(a, b, c) (strncmp((a), (b), (c)) == 0)
|
||||||
|
|
||||||
|
|
||||||
|
inline void
|
||||||
|
ErrorLocation( const char *file, int line );
|
||||||
|
|
||||||
|
/*@out@*/ /*@only@*/
|
||||||
|
void *
|
||||||
|
xmalloc( size_t size, const char *filename, int line_number );
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* COMMON_H */
|
138
src/file.c
Normal file
138
src/file.c
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
/* file.c -- functions for loading an Intel HEX file
|
||||||
|
Copyright (C) 2004 Hugo Villeneuve */
|
||||||
|
|
||||||
|
|
||||||
|
#if HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#if STDC_HEADERS
|
||||||
|
# include <string.h>
|
||||||
|
#elif HAVE_STRINGS_H
|
||||||
|
# include <strings.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Convert an ascii string to an hexadecimal number. */
|
||||||
|
static unsigned int
|
||||||
|
Ascii2Hex( char *istring, int length )
|
||||||
|
{
|
||||||
|
unsigned int result = 0;
|
||||||
|
int i, ascii_code;
|
||||||
|
|
||||||
|
if ( !length || ( length > (int) strlen(istring) ) ) {
|
||||||
|
length = strlen(istring);
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( i = 0; i < length; i++ ) {
|
||||||
|
ascii_code = istring[ i ];
|
||||||
|
if ( ascii_code > 0x39 ) {
|
||||||
|
ascii_code &= 0xDF;
|
||||||
|
}
|
||||||
|
if ( ( ascii_code >= 0x30 && ascii_code <= 0x39 ) ||
|
||||||
|
( ascii_code >= 0x41 && ascii_code <= 0x46 ) ) {
|
||||||
|
ascii_code -= 0x30;
|
||||||
|
if ( ascii_code > 9 ) {
|
||||||
|
ascii_code -= 7;
|
||||||
|
}
|
||||||
|
result <<= 4;
|
||||||
|
result += ascii_code;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf( "%s: In Ascii2Hex(), syntax error.\n", PACKAGE );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LoadHexFile( const char *filename, void (* cpu_write_pgm)( unsigned int Address, unsigned char Value ) )
|
||||||
|
{
|
||||||
|
int i, j, RecLength, LoadOffset, RecType, Data, Checksum;
|
||||||
|
|
||||||
|
#define LINE_BUFFER_LEN 256
|
||||||
|
FILE *fp;
|
||||||
|
int status;
|
||||||
|
char line[LINE_BUFFER_LEN];
|
||||||
|
|
||||||
|
if( filename != NULL ) {
|
||||||
|
/* Trying to open the file. */
|
||||||
|
fp = fopen( filename, "r" );
|
||||||
|
if( fp == NULL ) {
|
||||||
|
perror( PACKAGE );
|
||||||
|
/*ErrorLocation( __FILE__, __LINE__ );*/
|
||||||
|
exit( EXIT_FAILURE );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reading one line of data from the configuration file. */
|
||||||
|
/* char *fgets(char *s, int size, FILE *stream);
|
||||||
|
Reading stops after an EOF or a newline. If a newline is read, it is
|
||||||
|
stored into the buffer. A '\0' is stored after the last character in
|
||||||
|
the buffer. */
|
||||||
|
while( fgets( line, LINE_BUFFER_LEN, fp ) != NULL ) {
|
||||||
|
i = 0;
|
||||||
|
Checksum = 0;
|
||||||
|
|
||||||
|
if ( line[ i++ ] != ':' ) {
|
||||||
|
printf( "%s: line not beginning with \":\"\n", PACKAGE );
|
||||||
|
goto close_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
RecLength = Ascii2Hex( &line[ i ], 2 );
|
||||||
|
i += 2;
|
||||||
|
Checksum += RecLength;
|
||||||
|
|
||||||
|
LoadOffset = Ascii2Hex( &line[i], 4 );
|
||||||
|
Checksum += LoadOffset / 256;
|
||||||
|
Checksum += LoadOffset % 256;
|
||||||
|
i += 4;
|
||||||
|
|
||||||
|
RecType = Ascii2Hex( &line[i],2);
|
||||||
|
i += 2;
|
||||||
|
Checksum += RecType;
|
||||||
|
|
||||||
|
if ( RecType == 1 ) {
|
||||||
|
Checksum += Ascii2Hex( &line[ i ], 2 );
|
||||||
|
if ( Checksum &= 0x000000FF ) {
|
||||||
|
/* Error. */
|
||||||
|
printf( "%s: Invalid format\n", PACKAGE );
|
||||||
|
goto close_file;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* OK */
|
||||||
|
goto close_file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( j = 0; j < RecLength; j++ ) {
|
||||||
|
Data = Ascii2Hex( &line[ i ], 2 );
|
||||||
|
(*cpu_write_pgm)( (unsigned int)(LoadOffset + j), (unsigned char)Data );
|
||||||
|
i += 2;
|
||||||
|
Checksum += Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
RecType = Ascii2Hex( &line[ i ], 2 );
|
||||||
|
Checksum += RecType;
|
||||||
|
|
||||||
|
if ( Checksum &= 0x000000FF ) {
|
||||||
|
printf( "%s: Invalid format\n", PACKAGE );
|
||||||
|
goto close_file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close_file:
|
||||||
|
status = fclose( fp );
|
||||||
|
if( status != EXIT_SUCCESS ) {
|
||||||
|
fprintf( stderr, "%s: Error closing configuration file.\n", PACKAGE );
|
||||||
|
/*ErrorLocation( __FILE__, __LINE__ );*/
|
||||||
|
exit( EXIT_FAILURE );
|
||||||
|
}
|
||||||
|
}
|
11
src/file.h
Normal file
11
src/file.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
/* file.h */
|
||||||
|
|
||||||
|
#ifndef FILE_H
|
||||||
|
#define FILE_H 1
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LoadHexFile( const char *filename, void (* cpu_write_pgm)( unsigned int Address, unsigned char Value ) );
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* FILE_H */
|
119
src/options.c
Normal file
119
src/options.c
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
/* options.c -- functions for processing command-line options and arguments
|
||||||
|
Copyright (C) 2003 Hugo Villeneuve */
|
||||||
|
|
||||||
|
|
||||||
|
#if HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#if STDC_HEADERS
|
||||||
|
# include <string.h>
|
||||||
|
#elif HAVE_STRINGS_H
|
||||||
|
# include <strings.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "options.h"
|
||||||
|
|
||||||
|
|
||||||
|
char *hex_file;
|
||||||
|
|
||||||
|
|
||||||
|
char *
|
||||||
|
GetHexFileName( void )
|
||||||
|
{
|
||||||
|
return hex_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Display the help message and exit
|
||||||
|
******************************************************************************/
|
||||||
|
static void
|
||||||
|
DisplayUsage( void )
|
||||||
|
{
|
||||||
|
printf( "Usage: %s [OPTION]... [FILENAME]\n", PACKAGE );
|
||||||
|
printf( "Simulator/emulator for 8051 family microcontrollers.\n\n" );
|
||||||
|
printf( " -h display this help and exit\n" );
|
||||||
|
printf( " -version display version information and exit\n");
|
||||||
|
printf( "\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Display version information and exit
|
||||||
|
******************************************************************************/
|
||||||
|
static void
|
||||||
|
DisplayVersion( void )
|
||||||
|
{
|
||||||
|
printf( "\n" );
|
||||||
|
printf( " %s, version %s\n", PACKAGE, VERSION );
|
||||||
|
printf( " Written by Hugo Villeneuve, Jonathan St-André and Pascal Fecteau.\n\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
InvalidOption( const char *message, /*@null@*/ const char *string )
|
||||||
|
{
|
||||||
|
if( string == NULL ) {
|
||||||
|
fprintf(stderr, "%s: %s\n", PACKAGE, message );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf(stderr, "%s: %s %s\n", PACKAGE, message, string );
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "Try `%s -h' for more information.\n", PACKAGE );
|
||||||
|
|
||||||
|
exit( EXIT_FAILURE );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Initializes the different options passed as arguments on the command line.
|
||||||
|
******************************************************************************/
|
||||||
|
void
|
||||||
|
ParseCommandLineOptions( int argc, char *argv[] )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char *token;
|
||||||
|
|
||||||
|
for( i = 1; i < argc; i++ ) {
|
||||||
|
token = argv[i];
|
||||||
|
switch( token[0] ) {
|
||||||
|
case '-':
|
||||||
|
/* Processing options names */
|
||||||
|
switch( token[1] ) {
|
||||||
|
case 'h':
|
||||||
|
if( strlen( &token[1] ) == 1 ) {
|
||||||
|
DisplayUsage();
|
||||||
|
exit( EXIT_SUCCESS );
|
||||||
|
}
|
||||||
|
InvalidOption( "invalid option", token );
|
||||||
|
break;
|
||||||
|
case 'v' :
|
||||||
|
if( STREQ( "version", &token[1] ) ) {
|
||||||
|
DisplayVersion();
|
||||||
|
exit( EXIT_SUCCESS );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
InvalidOption( "invalid option", token );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
InvalidOption( "invalid option", token );
|
||||||
|
break;
|
||||||
|
} /* end switch( token[1] ) */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Processing options arguments */
|
||||||
|
/* Must be the filename... */
|
||||||
|
hex_file = token;
|
||||||
|
break;
|
||||||
|
} /* end switch( token[0] ) */
|
||||||
|
} /* end for */
|
||||||
|
|
||||||
|
}
|
14
src/options.h
Normal file
14
src/options.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
/* options.h */
|
||||||
|
|
||||||
|
#ifndef OPTIONS_H
|
||||||
|
#define OPTIONS_H 1
|
||||||
|
|
||||||
|
|
||||||
|
char *
|
||||||
|
GetHexFileName( void );
|
||||||
|
|
||||||
|
void
|
||||||
|
ParseCommandLineOptions( int argc, char *argv[] );
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* OPTIONS_H */
|
Loading…
x
Reference in New Issue
Block a user