Merge common function LoadHexFile() to file.c.
\fB\-h\fR
display usage and exit
.TP
-\fB\-v\fR
+\fB\-version\fR
output version information and exit
.SH CREDITS
-// EmuConsole.cpp
+/* EmuConsole.cpp */
#include <stdio.h>
#include <iostream>
#include "Reg8051.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 )
{
}
+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 constructor
CPU = mCPU;
CPU->Reset( );
NbBreakpoints = 0;
- if ( argc > 1 ) LoadHexFile( argv[ 1 ] );
+
+ EmuConsolePtr = this;
+
+ ParseCommandLineOptions( argc, argv );
+
+ if( GetHexFileName() != NULL ) {
+ LoadHexFile( GetHexFileName(), cpu_write_pgm );
+ }
}
//////////////////////////////////////////////////////////////////////////////
if ( Parameter1.empty() || Parameter2.empty() )
throw MissingParameter();
else if ( Command == "ME" ) {
- unsigned int adresse = Ascii2Hex( Parameter1, 4 );
- unsigned char valeur = Ascii2Hex( Parameter2, 2 );
+ unsigned int adresse = Ascii2Hex_TEMP( Parameter1, 4 );
+ unsigned char valeur = Ascii2Hex_TEMP( Parameter2, 2 );
CPU->WriteExt( adresse, valeur );
}
else if ( Command == "MI" ) {
- unsigned char adresse = Ascii2Hex( Parameter1, 2 );
- unsigned char valeur = Ascii2Hex( Parameter2, 2 );
+ unsigned char adresse = Ascii2Hex_TEMP( Parameter1, 2 );
+ unsigned char valeur = Ascii2Hex_TEMP( Parameter2, 2 );
CPU->WriteInt( adresse, valeur );
}
else if ( Command == "MP" ) {
- unsigned int adresse = Ascii2Hex( Parameter1, 4 );
- unsigned char valeur = Ascii2Hex( Parameter2, 2 );
+ unsigned int adresse = Ascii2Hex_TEMP( Parameter1, 4 );
+ unsigned char valeur = Ascii2Hex_TEMP( Parameter2, 2 );
CPU->WritePGM( adresse, valeur );
}
else if ( Command == "MR" )
if ( Parameter1.empty( ) )
ClearBreakpoint( CPU->GetPC( ) );
else
- ClearBreakpoint( Ascii2Hex( Parameter1, 4 ) );
+ ClearBreakpoint( Ascii2Hex_TEMP( Parameter1, 4 ) );
}
else
throw SyntaxError( );
if ( Parameter1.empty( ) )
SetBreakpoint( CPU->GetPC( ) );
else
- SetBreakpoint( Ascii2Hex( Parameter1, 4 ) );
+ SetBreakpoint( Ascii2Hex_TEMP( Parameter1, 4 ) );
}
else
throw SyntaxError( );
//////////////////////////////////////////////////////////////////////////////
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( );
ShowRegisters( );
DisasmN( CPU->GetPC( ), 1 );
int NbInst = -1; // -1 is infinity
if ( !Address.empty( ) ) {
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( );
unsigned int MemAddress, NbInst;
Capitalize( &Address );
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";
- NbInst = Ascii2Hex( NumberInst, NumberInst.size( ) );
+ NbInst = Ascii2Hex_TEMP( NumberInst, NumberInst.size( ) );
DisasmN( MemAddress, NbInst );
}
if ( Address == "PC" )
MemAddress = CPU->GetPC( );
else
- MemAddress = Ascii2Hex( Address, Address.size( ) );
+ MemAddress = Ascii2Hex_TEMP( Address, Address.size( ) );
}
for ( Offset = 0; Offset < 256; Offset += 16 ) {
printf( "%.4X ", MemAddress + Offset );
unsigned int MemAddress = 0;
int Offset, Column;
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 ) {
printf( "%.4X ", MemAddress + Offset );
for ( Column = 0; Column < 16; Column++ )
int Offset, Column;
unsigned char Byte;
if ( !Address.empty( ) )
- MemAddress = Ascii2Hex( Address, 4 );
+ MemAddress = Ascii2Hex_TEMP( Address, 4 );
for ( Offset = 0; Offset < 256; Offset += 16 ) {
printf( "%.4X ", MemAddress + Offset );
for ( Column = 0; Column < 16; Column++ )
int Offset, Column;
unsigned char Byte;
if ( !Address.empty( ) )
- MemAddress = Ascii2Hex( Address, 4 );
+ MemAddress = Ascii2Hex_TEMP( Address, 4 );
for ( Offset = 0; Offset < 256; Offset += 16 ) {
printf( "%.4X ", MemAddress + Offset );
for ( Column = 0; Column < 16; Column++ )
unsigned int MemAddress = 0;
int Offset, Column;
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 ) {
printf( "%.4X ", MemAddress + Offset );
for ( Column = 0; Column < 16; Column++ )
void EmuConsole::SetRegister( string Register, string NewValue )
{
Capitalize( &Register );
- if ( Register == "PC" ) CPU->SetPC( Ascii2Hex( NewValue, 4 ) );
- else if ( Register == "A" ) CPU->WriteD( _ACC_, Ascii2Hex( NewValue, 2 ) );
- else if ( Register == "B" ) CPU->WriteD( _B_, Ascii2Hex( NewValue, 2 ) );
- else if ( Register == "SP" ) CPU->WriteD( _SP_, Ascii2Hex( NewValue, 2 ) );
+ if ( Register == "PC" ) CPU->SetPC( Ascii2Hex_TEMP( NewValue, 4 ) );
+ else if ( Register == "A" ) CPU->WriteD( _ACC_, Ascii2Hex_TEMP( NewValue, 2 ) );
+ else if ( Register == "B" ) CPU->WriteD( _B_, Ascii2Hex_TEMP( NewValue, 2 ) );
+ else if ( Register == "SP" ) CPU->WriteD( _SP_, Ascii2Hex_TEMP( NewValue, 2 ) );
else throw InvalidRegister( );
}
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;
-}
-
-
-
-
-
-
-
EmuConsole( int argc, char **argv, CPU8051 *mCPU );
~EmuConsole( );
+ CPU8051 *CPU;
+
void Main( );
void Reset( );
private:
- CPU8051 *CPU;
int NbBreakpoints;
unsigned int Breakpoints[ MAXBP ];
- void LoadHexFile( string Filename );
- unsigned int Ascii2Hex( string istring, unsigned int length );
void Capitalize( string *InputString );
void RemoveSpaces( string *InputString );
#include "stop.xpm"
#include "step.xpm"
+extern "C" {
+#include "options.h"
+#include "file.h"
+}
+
int EmuGtkNumber = 0;
int NbSignals = 0;
};
+static void
+cpu_write_pgm( unsigned int Address, unsigned char Value )
+{
+ EmuGtkPtr->CPU->WritePGM( Address, Value );
+}
+
+
int main( int argc, char **argv )
{
CPU8051 *maincpu = new CPU8051;
return 0;
}
+
//////////////////////////////////////////////////////////////////////////////
// EmuGtk::EmuGtk( )
// EmuGtk constructor
CPU = mCPU;
RunningState = 0;
+ ParseCommandLineOptions( argc, argv );
+
g_print( "\n" );
gtk_init( &argc, &argv );
EmuGtkNumber++;
}
- if ( argc > 1 )
- LoadHexFile( argv[1] );
+ if( GetHexFileName() != NULL ) {
+ LoadHexFile( GetHexFileName(), cpu_write_pgm );
+ }
}
-
//////////////////////////////////////////////////////////////////////////////
// void AddButtons()
// Create and show the Reset, Run, Stop, Trace and Step buttons
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 );
EmuGtkPtr->StopRunning( );
- EmuGtkPtr->LoadHexFile( SelectedFile );
+ LoadHexFile( SelectedFile, cpu_write_pgm );
gtk_widget_destroy( GTK_WIDGET( data ) );
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 )
public:
EmuGtk( int argc , char **argv, CPU8051 *mCPU );
~EmuGtk( );
+
+ CPU8051 *CPU; /* Test */
void Main( );
void StopRunning( );
void Running( );
- void LoadHexFile( string Filename );
void UpdateDisplay();
private:
int EmuGtkID;
- CPU8051 *CPU;
+
int RunningState;
int RunFuncTag;
MemWin *memwin;
GdkPixmap *STEP_pixmap;
GtkWidget *STEP_widget;
GtkWidget *ButtonStep;
-
- unsigned int Ascii2Hex( string istring, int length );
};
void EmuGtkSignalStub3( GtkWidget *widget, GdkEvent *event, gpointer data );
bin_PROGRAMS = emu8051 emu8051_console
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 \
- 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
# installed by 'make install'
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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 );
+ }
+}
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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 */
+
+}
--- /dev/null
+/* options.h */
+
+#ifndef OPTIONS_H
+#define OPTIONS_H 1
+
+
+char *
+GetHexFileName( void );
+
+void
+ParseCommandLineOptions( int argc, char *argv[] );
+
+
+#endif /* OPTIONS_H */