From a78a174393ff9c8dbc0d5212576507f25d7e9bf1 Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Fri, 19 Mar 2010 23:24:12 +0000 Subject: [PATCH] Reintroduce command line mode --- Makefile.am | 12 +- configure.ac | 36 +- src/EmuConsole.cpp | 691 ------------------------ src/EmuConsole.hpp | 6 - src/Makefile.am | 24 +- src/common.h | 4 +- src/cpu8051.c | 866 ++++++++++++++----------------- src/cpu8051.h | 31 +- src/emuconsole.c | 570 ++++++++++++++++++++ src/emugtk.c | 31 +- src/hexfile.c | 190 +++---- src/hexfile.h | 3 +- src/{Keyboard.hpp => keyboard.c} | 80 ++- src/{hexfile.h => keyboard.h} | 17 +- src/memory.c | 151 +++--- src/memory.h | 5 - src/options.c | 11 +- src/options.h | 6 +- 18 files changed, 1242 insertions(+), 1492 deletions(-) delete mode 100644 src/EmuConsole.cpp create mode 100644 src/emuconsole.c rename src/{Keyboard.hpp => keyboard.c} (56%) copy src/{hexfile.h => keyboard.h} (84%) diff --git a/Makefile.am b/Makefile.am index 83b08f2..c8cfbc0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,6 +4,7 @@ AUTOMAKE_OPTIONS = gnu SUBDIRS = src doc +## We want these in the dist tarball EXTRA_DIST = autogen.sh \ $(ac_aux_dir)/debug.m4 \ pixmaps \ @@ -15,10 +16,9 @@ CLEANFILES = *~ DISTCLEANFILES = .deps/*.P -MAINTAINERCLEANFILES = Makefile.in aclocal.m4 configure config-h.in stamp-h.in \ - $(ac_aux_dir)/depcomp $(ac_aux_dir)/install-sh $(ac_aux_dir)/missing \ +MAINTAINERCLEANFILES = Makefile.in aclocal.m4 configure config-h.in \ + stamp-h.in $(ac_aux_dir)/depcomp \ + $(ac_aux_dir)/install-sh $(ac_aux_dir)/missing \ $(ac_aux_dir)/mkinstalldirs $(ac_aux_dir)/config.guess \ - $(ac_aux_dir)/config.sub $(ac_aux_dir)/ltmain.sh - - - + $(ac_aux_dir)/config.sub $(ac_aux_dir)/ltmain.sh \ + $(ac_aux_dir)/compile diff --git a/configure.ac b/configure.ac index 2381fc9..f2b2da9 100644 --- a/configure.ac +++ b/configure.ac @@ -1,15 +1,16 @@ # configure.ac -- Process this file with autoconf to produce configure dnl Initialization stuff. -AC_INIT(emu8051, 1.0.2) +AC_INIT(emu8051, 1.1.0) AC_CONFIG_AUX_DIR(config) AC_CONFIG_SRCDIR(src/cpu8051.c) AM_CONFIG_HEADER(config.h:config-h.in) dnl Checking if the NEWS file has been updated to reflect the current version. AM_INIT_AUTOMAKE(check-news) +AM_SILENT_RULES([yes]) -dnl Tests the C compiler -AC_PROG_CC +dnl Testing the C compiler. +AM_PROG_CC_C_O AC_LANG_C dnl Checking for header files. @@ -23,7 +24,7 @@ AC_TYPE_PID_T AC_TYPE_SIZE_T dnl Basic CFLAGS values -CFLAGS="-Wall" +CFLAGS="${CFLAGS} -Wall" dnl Checks for '--enable-debug' option HV_CHECK_FOR_DEBUG @@ -34,9 +35,23 @@ dnl -g is for GDB debugging fi dnl Checks for Gtk+-2.0 -PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.0.5) -AC_SUBST(GTK_CFLAGS) -AC_SUBST(GTK_LIBS) +AC_ARG_ENABLE(gui, + [ --enable-gui Enable building the GUI (default=yes)], + [ac_cv_enable_gui=$enableval], [ac_cv_enable_gui=yes]) +AC_MSG_CHECKING([whether to build GUI]) +if test x$ac_cv_enable_gui = xyes; then + AC_MSG_RESULT(yes) + PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.0.5, :, ac_cv_enable_gui=no) + if test x$ac_cv_enable_gui = xyes; then + AC_DEFINE([HAVE_GTK],1,[Set to 1 to enable GTK+ support for building GUI.]) + AC_SUBST(GTK_CFLAGS) + AC_SUBST(GTK_LIBS) + fi +else + AC_MSG_RESULT(no) +fi + +AM_CONDITIONAL([USE_GTK], [test x${ac_cv_enable_gui} = xyes]) AC_SUBST(CFLAGS) AC_SUBST(LIBS) @@ -54,6 +69,13 @@ Configuration: Compiler flags: ${CFLAGS} Linker flags: ${LIBS}" +echo -n " Build GUI: " +if test x"${ac_cv_enable_gui}" = xyes; then + echo "yes" +else + echo "no" +fi + echo -n " Debugging messages: " if test x"${debug_messages}" = x1; then echo "yes" diff --git a/src/EmuConsole.cpp b/src/EmuConsole.cpp deleted file mode 100644 index a260991..0000000 --- a/src/EmuConsole.cpp +++ /dev/null @@ -1,691 +0,0 @@ -/* - * EmuConsole.cpp - * - * Copyright (C) 1999 Jonathan St-André - * Copyright (C) 1999 Hugo Villeneuve - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include "config.h" -#include "EmuConsole.hpp" -#include "CPU8051.hpp" -#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 ) -{ - CPU8051 *maincpu = new CPU8051; - - EmuConsole *emuUI = new EmuConsole( argc, argv, maincpu ); - - emuUI->Main(); - printf( "End of program.\n" ); - - delete emuUI; - delete maincpu; - - return 0; -} - - -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 -////////////////////////////////////////////////////////////////////////////// -EmuConsole::EmuConsole( int argc, char **argv, CPU8051 *mCPU ) -{ - CPU = mCPU; - CPU->Reset( ); - NbBreakpoints = 0; - - EmuConsolePtr = this; - - ParseCommandLineOptions( argc, argv ); - - if( GetHexFileName() != NULL ) { - LoadHexFile( GetHexFileName(), cpu_write_pgm ); - } -} - -////////////////////////////////////////////////////////////////////////////// -// EmuConsole::~EmuConsole( ) -// EmuConsole destructor -////////////////////////////////////////////////////////////////////////////// -EmuConsole::~EmuConsole( ) -{ -} - -////////////////////////////////////////////////////////////////////////////// -// void EmuConsole::Main( ) -// EmuConsole main loop -////////////////////////////////////////////////////////////////////////////// -void EmuConsole::Main( ) -{ - /*int ASCII_Code;*/ - unsigned int Index; - - string InputString; - string Command; - string Parameter1; - string Parameter2; - char prompt[] = "-> "; - - char *Title[] = { " *******************", - " * 8051 Emulator *", - " *******************", - "", 0 }; - - char *Menu[] = { - " Available commands, [ ] = options", - "", - " Set Breakpoint.............. SB [address]", - " Remove Breakpoint........... RB [address]", - " Display Breakpoint(s)....... DB", - " Dump External Data Memory... DE [address]", - " Dump Internal Data Memory... DI [address]", - " Dump Program Memory......... DP [address]", - " Display Registers content... DR", - " Execute..................... EM [address [number of instructions]]", - " Help........................ H", - " Modify External Data Memory. ME address value", - " Modify Internal Data Memory. MI address value", - " Modify Program Memory....... MP address value", - " Modify Register............. MR register value", - " Quit Emulator............... Q", - " Trace mode.................. T [address]", - " Unassemble.................. U [address [numberof instructions]]", - " Reset processor............. Z", 0 }; - - - Index = 0; - while ( Title[ Index ] != 0 ) printf( "%s%s", Title[ Index++ ], ENDLINE ); - Index = 0; - while ( Menu[ Index ] != 0 ) printf( "%s%s", Menu[ Index++ ], ENDLINE ); - - Reset( ); - int QuitRequest = 0; - - while( !QuitRequest ) { - try { - - printf( prompt ); - getline ( cin, InputString, '\n' ); - Capitalize( &InputString ); - RemoveSpaces( &InputString ); - - for ( Index = 0; Index < InputString.size( ); Index++ ) { - if ( InputString[ Index ] < 'A' || InputString[ Index ] > 'z' ) - break; - } - - Command = InputString; - // Keep only the Command part from the input line - Command.replace( Index, Command.size( ), 0, ( char )0 ); - // Keep only the arguments - InputString.replace( 0, Index, 0, ( char )0 ); - - RemoveSpaces ( &InputString ); - Index = 0; - while ( ( Index < InputString.size( ) ) && ( InputString [ Index ] != ' ' ) ) Index++; - Parameter1 = InputString; - Parameter1.replace( Index, Parameter1.size( ), 0, ( char )0 ); - InputString.replace( 0, Index, 0, ( char )0 ); - - RemoveSpaces ( &InputString ); - Index = 0; - while ( ( Index < InputString.size( ) ) && ( InputString [ Index ] != ' ' ) ) Index++; - Parameter2 = InputString; - Parameter2.replace( Index, Parameter2.size( ), 0, ( char )0 ); - InputString.replace( 0, Index, 0, ( char )0 ); - - RemoveSpaces ( &InputString ); - if ( !InputString.empty( ) ) - throw SyntaxError( ); - - if ( Command.empty( ) && !Parameter1.empty( ) ) - throw SyntaxError( ); - - if ( ( Parameter1.size( ) > 4 ) || ( Parameter2.size( ) > 4 ) ) - throw InvalidParameter( ); - - if ( !Command.empty( ) ) { - switch ( Command [ 0 ] ) { - - case 'D' : - if ( Parameter2.empty( ) ) { - if ( Command == "DB" && Parameter1.empty( ) ) - ShowBreakpoints( ); - else if ( Command == "DE" ) - DumpExt( Parameter1 ); - else if ( Command == "DI" ) - DumpInt( Parameter1 ); - else if ( Command == "DP" ) { - if ( Parameter1.empty( ) ) - Parameter1 = "PC"; - DumpPGM( Parameter1 ); - } - else if ( Command == "DR" && Parameter1.empty( ) ) - ShowRegisters( ); - else - throw SyntaxError( ); - } - else - throw SyntaxError( ); - break; - - case 'E' : - if ( Command == "EM" ) - Exec( Parameter1, Parameter2 ); - else - throw SyntaxError( ); - break; - case 'H' : - if ( Command == "H" && Parameter1.empty( ) && Parameter2.empty( ) ) - { - Index = 0; - while ( Menu[ Index ] != 0 ) printf( "%s%s", Menu[ Index++ ], ENDLINE ); - } - else - throw SyntaxError( ); - break; - case 'M' : - if ( Parameter1.empty() || Parameter2.empty() ) - throw MissingParameter(); - else if ( Command == "ME" ) { - 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_TEMP( Parameter1, 2 ); - unsigned char valeur = Ascii2Hex_TEMP( Parameter2, 2 ); - CPU->WriteInt( adresse, valeur ); - } - else if ( Command == "MP" ) { - unsigned int adresse = Ascii2Hex_TEMP( Parameter1, 4 ); - unsigned char valeur = Ascii2Hex_TEMP( Parameter2, 2 ); - CPU->WritePGM( adresse, valeur ); - } - else if ( Command == "MR" ) - SetRegister( Parameter1, Parameter2 ); - else - throw SyntaxError(); - break; - case 'Q' : - if ( Command == "Q" && Parameter1.empty( ) && Parameter2.empty( ) ) - QuitRequest = 1; - else - throw SyntaxError( ); - break; - case 'R' : - if ( !Parameter2.empty( ) ) - throw TooMuchParameters( ); - if ( Command == "RB" ) { - if ( Parameter1.empty( ) ) - ClearBreakpoint( CPU->GetPC( ) ); - else - ClearBreakpoint( Ascii2Hex_TEMP( Parameter1, 4 ) ); - } - else - throw SyntaxError( ); - break; - case 'S' : - if ( !Parameter2.empty( ) ) - throw TooMuchParameters( ); - if ( Command == "SB" ) { - if ( Parameter1.empty( ) ) - SetBreakpoint( CPU->GetPC( ) ); - else - SetBreakpoint( Ascii2Hex_TEMP( Parameter1, 4 ) ); - } - else - throw SyntaxError( ); - break; - case 'T' : - if ( !Parameter2.empty( ) ) - throw TooMuchParameters( ); - if ( Command == "T" ) - Trace( Parameter1 ); - else - throw SyntaxError( ); - break; - case 'U' : - if ( Command == "U" ) - Disasm( Parameter1, Parameter2 ); - else - throw SyntaxError( ); - break; - case 'Z' : - if ( Command == "Z" && Parameter1.empty( ) && Parameter2.empty( ) ) - Reset( ); - else - throw SyntaxError( ); - break; - case '\n' : - break; - default : - throw SyntaxError( ); - } - } - } - catch ( SyntaxError ) { - printf( "Syntax Error!%s", ENDLINE ); - } - catch ( MissingParameter ) { - printf( "Missing Parameter!%s", ENDLINE ); - } - catch ( InvalidParameter ) { - printf( "Invalid Parameter Format!%s", ENDLINE ); - } - catch ( TooMuchParameters ) { - printf( "Wrong Number of Parameters!%s", ENDLINE ); - } - catch ( ResetRequest ) { - printf( "Resetting Microcontroler...%s", ENDLINE ); - } - catch ( InvalidRegister ) { - printf( "%sInvalid register name!%s", ENDLINE, ENDLINE ); - printf( "Valid registers are A, B, PC and SP.%s", ENDLINE ); - } - } -} - -////////////////////////////////////////////////////////////////////////////// -// void EmuConsole::Reset( ) -// CPU reset and Console UI update -////////////////////////////////////////////////////////////////////////////// -void EmuConsole::Reset( ) -{ - printf( "Resetting... " ); - CPU->Reset( ); - printf( "Done.%s", ENDLINE ); - ShowRegisters( ); -} - -////////////////////////////////////////////////////////////////////////////// -// void EmuConsole::Trace( string Address ) -// CPU trace and Console UI update -////////////////////////////////////////////////////////////////////////////// -void EmuConsole::Trace( string Address ) -{ - if ( !Address.empty( ) ) CPU->SetPC( Ascii2Hex_TEMP( Address, Address.size( ) ) ); - CPU->Exec( ); - ShowRegisters( ); - DisasmN( CPU->GetPC( ), 1 ); -} - -////////////////////////////////////////////////////////////////////////////// -// void EmuConsole::Exec( string Address, string NumberInst ) -// CPU exec and Console UI update -////////////////////////////////////////////////////////////////////////////// -void EmuConsole::Exec( string Address, string NumberInst ) -{ - char dummy; - int NbInst = -1; // -1 is infinity - if ( !Address.empty( ) ) { - Capitalize( &Address ); - if ( Address != "PC" ) CPU->SetPC( Ascii2Hex_TEMP( Address, Address.size( ) ) ); - } - - if ( !NumberInst.empty( ) ) NbInst = Ascii2Hex_TEMP( NumberInst, NumberInst.size( ) ); - - InitUnixKB( ); - - printf( "Program executing...%s", ENDLINE ); - - do { - CPU->Exec( ); - if ( NbInst > 0 ) NbInst--; - } while ( !IsBreakpoint( CPU->GetPC( ) ) && ( NbInst != 0 ) && !kbhit( ) ); - if ( kbhit( ) ) { - dummy = getch( ); // flush key - printf( "Caught break signal!%s", ENDLINE ); - } - if ( NbInst == 0 ) printf( "Number of instructions reached! Stopping!%s", ENDLINE ); - if ( IsBreakpoint( CPU->GetPC( ) ) ) printf( "Breakpoint hit at %.4X! Stopping!%s", CPU->GetPC( ), ENDLINE ); - - ResetUnixKB( ); -} - -////////////////////////////////////////////////////////////////////////////// -// void EmuConsole::ShowBreakpoints( ) -// Show Breakpoints list -////////////////////////////////////////////////////////////////////////////// -void EmuConsole::ShowBreakpoints( ) -{ - for ( int Index = 0; Index < NbBreakpoints ; Index++ ) - printf( "Breakpoint at Address = %.4X%s", Breakpoints[ Index ], ENDLINE ); -} - -////////////////////////////////////////////////////////////////////////////// -// void EmuConsole::ClearBreakpoint( unsigned int Address ) -// Clear Breakpoint at Address from list -////////////////////////////////////////////////////////////////////////////// -void EmuConsole::ClearBreakpoint( unsigned int Address ) -{ - int Index = 0; - while ( Index < NbBreakpoints && Breakpoints[ Index ] != Address ) Index++; - if ( Breakpoints[ Index ] != Address ) return; - Breakpoints[ Index ] = Breakpoints[ NbBreakpoints - 1 ]; - NbBreakpoints--; -} - -////////////////////////////////////////////////////////////////////////////// -// void EmuConsole::SetBreakpoint( unsigned int Address ) -// Set Breakpoint at Address from list -////////////////////////////////////////////////////////////////////////////// -void EmuConsole::SetBreakpoint( unsigned int Address ) -{ - if ( IsBreakpoint( Address ) ) return; - if ( NbBreakpoints < MAXBP ) Breakpoints[ NbBreakpoints++ ] = Address; -} - -////////////////////////////////////////////////////////////////////////////// -// int EmuConsole::IsBreakpoint( unsigned int Address ) -// Is the a breakpoint at Address -////////////////////////////////////////////////////////////////////////////// -int EmuConsole::IsBreakpoint( unsigned int Address ) -{ - int Index = 0; - while ( Index < NbBreakpoints && Breakpoints[ Index ] != Address ) Index++; - return ( Breakpoints[ Index ] == Address && Index < NbBreakpoints ); -} - - -////////////////////////////////////////////////////////////////////////////// -// void EmuConsole::Disasm( string Address, string NumberInst ) -// Disassemble 16 instructions at Address -////////////////////////////////////////////////////////////////////////////// -void EmuConsole::Disasm( string Address, string NumberInst ) -{ - unsigned int MemAddress, NbInst; - Capitalize( &Address ); - if ( Address.empty( ) || ( Address == "PC" ) ) MemAddress = CPU->GetPC( ); - else MemAddress = Ascii2Hex_TEMP( Address, Address.size( ) ); - if ( NumberInst.empty( ) ) NumberInst = "10"; - NbInst = Ascii2Hex_TEMP( NumberInst, NumberInst.size( ) ); - DisasmN( MemAddress, NbInst ); -} - -////////////////////////////////////////////////////////////////////////////// -// void EmuConsole::DisasmN( unsigned int Address, int NumberInst ) -// Disassemble NumberInst instructions at Address -////////////////////////////////////////////////////////////////////////////// -void EmuConsole::DisasmN( unsigned int Address, int NumberInst ) -{ -char TextTmp[255]; -int Row; - for ( Row = 0; Row < NumberInst ; Row++ ) { - Address += CPU->Disasm( Address, TextTmp ); - printf( "%s%s", TextTmp, ENDLINE ); - } -} - -////////////////////////////////////////////////////////////////////////////// -// void EmuConsole::DumpPGM( string Address ) -// Dump Program memory -////////////////////////////////////////////////////////////////////////////// -void EmuConsole::DumpPGM( string Address ) -{ - unsigned int MemAddress = 0; - int Offset, Column; - unsigned char Byte; - if ( !Address.empty( ) ) { - Capitalize( &Address ); - if ( Address == "PC" ) - MemAddress = CPU->GetPC( ); - else - MemAddress = Ascii2Hex_TEMP( Address, Address.size( ) ); - } - for ( Offset = 0; Offset < 256; Offset += 16 ) { - printf( "%.4X ", MemAddress + Offset ); - for ( Column = 0; Column < 16; Column++ ) - printf( " %.2X", ( int )CPU->ReadPGM( MemAddress + Offset + Column ) ); - printf( " " ); - for ( Column = 0; Column < 16; Column++ ) { - Byte = CPU->ReadPGM( MemAddress + Offset + Column ); - if ( ( int )Byte >= 32 && ( int )Byte <= 126 ) - printf( "%c", Byte ); - else printf( "." ); - } - printf( "%s", ENDLINE ); - } - -} - - - - -////////////////////////////////////////////////////////////////////////////// -// void EmuConsole::DumpI( string Address ) -// Dump using Indirect read access -////////////////////////////////////////////////////////////////////////////// -void EmuConsole::DumpI( string Address ) -{ - unsigned int MemAddress = 0; - int Offset, Column; - unsigned char Byte; - 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++ ) - printf( " %.2X", ( int )CPU->ReadI( MemAddress + Offset + Column ) ); - printf( " " ); - for ( Column = 0; Column < 16; Column++ ) { - Byte = CPU->ReadI( MemAddress + Offset + Column ); - if ( ( int )Byte >= 32 && ( int )Byte <= 126 ) - printf( "%c", Byte ); - else printf( "." ); - } - printf( "%s", ENDLINE ); - } -} - -////////////////////////////////////////////////////////////////////////////// -// void EmuConsole::DumpInt( string Address ) -// Dump internal Data memory -////////////////////////////////////////////////////////////////////////////// -void EmuConsole::DumpInt( string Address ) -{ - unsigned int MemAddress = 0; - int Offset, Column; - unsigned char Byte; - if ( !Address.empty( ) ) - MemAddress = Ascii2Hex_TEMP( Address, 4 ); - for ( Offset = 0; Offset < 256; Offset += 16 ) { - printf( "%.4X ", MemAddress + Offset ); - for ( Column = 0; Column < 16; Column++ ) - printf( " %.2X", ( int )CPU->ReadInt( MemAddress + Offset + Column ) ); - printf( " " ); - for ( Column = 0; Column < 16; Column++ ) { - Byte = CPU->ReadInt( MemAddress + Offset + Column ); - if ( ( int )Byte >= 32 && ( int )Byte <= 126 ) - printf( "%c", Byte ); - else printf( "." ); - } - printf( "%s", ENDLINE ); - } -} - - -////////////////////////////////////////////////////////////////////////////// -// void EmuConsole::DumpExt( string Address ) -// Dump de la memoire externe ( $00 a $FFFF) -////////////////////////////////////////////////////////////////////////////// -void EmuConsole::DumpExt( string Address ) -{ - unsigned int MemAddress = 0; - int Offset, Column; - unsigned char Byte; - if ( !Address.empty( ) ) - MemAddress = Ascii2Hex_TEMP( Address, 4 ); - for ( Offset = 0; Offset < 256; Offset += 16 ) { - printf( "%.4X ", MemAddress + Offset ); - for ( Column = 0; Column < 16; Column++ ) - printf( " %.2X", ( int )CPU->ReadExt( MemAddress + Offset + Column ) ); - printf( " " ); - for ( Column = 0; Column < 16; Column++ ) { - Byte = CPU->ReadExt( MemAddress + Offset + Column ); - if ( ( int )Byte >= 32 && ( int )Byte <= 126 ) - printf( "%c", Byte ); - else printf( "." ); - } - printf( "%s", ENDLINE ); - } -} - -////////////////////////////////////////////////////////////////////////////// -// void EmuConsole::DumpD( string Address ) -// Dump using Direct read access -////////////////////////////////////////////////////////////////////////////// -void EmuConsole::DumpD( string Address ) -{ - unsigned int MemAddress = 0; - int Offset, Column; - unsigned char Byte; - 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++ ) - printf( " %.2X", ( int )CPU->ReadD( MemAddress + Offset + Column ) ); - printf( " " ); - for ( Column = 0; Column < 16; Column++ ) { - Byte = CPU->ReadD( MemAddress + Offset + Column ); - if ( ( int )Byte >= 32 && ( int )Byte <= 126 ) - printf( "%c", Byte ); - else printf( "." ); - } - printf( "%s", ENDLINE ); - } -} - -////////////////////////////////////////////////////////////////////////////// -// void EmuConsole::SetRegister( string Register, string NewValue ) -// Set NewValue to Register -////////////////////////////////////////////////////////////////////////////// -void EmuConsole::SetRegister( string Register, string NewValue ) -{ - Capitalize( &Register ); - 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( ); -} - -////////////////////////////////////////////////////////////////////////////// -// void EmuConsole::Capitalize( string *InputString ) -// Capitalize all letters in InputString -////////////////////////////////////////////////////////////////////////////// -void EmuConsole::Capitalize( string *InputString ) -{ - for (unsigned int Index = 0; Index < InputString->size( ); Index++ ) { - { - if ( ( ( *InputString )[ Index ] >= 'a' ) && ( ( *InputString )[ Index ] <= 'z' ) ) - ( *InputString )[ Index ] -= ( ( int )'a'- ( int )'A' ); - } - } -} - -////////////////////////////////////////////////////////////////////////////// -// void EmuConsole::RemoveSpaces( string *InputString ) -// Remove spaces from InputString -////////////////////////////////////////////////////////////////////////////// -void EmuConsole::RemoveSpaces( string *InputString ) -{ - unsigned int Index = 0; - - while ( ( Index < ( *InputString ).size( ) ) && ( *InputString )[ Index ] == ' ' ) { - Index++; - } - ( *InputString ).replace( 0, Index, 0, ( char )0 ); -} - -////////////////////////////////////////////////////////////////////////////// -// void EmuConsole::ShowRegisters( ) -// Show CPU registers -////////////////////////////////////////////////////////////////////////////// -void EmuConsole::ShowRegisters( ) -{ - unsigned char PSW = CPU->ReadD( _PSW_ ); - int BankSelect = ( PSW & 0x18 ); - - printf( "----------------------------------------------------------------------%s", ENDLINE ); - printf( "| PC | SP | DPTR | ACC | B | PSW: CY AC F0 RS1 RS0 OV - P |%s", ENDLINE ); - printf( "| %.4X | %.2X | %.4X | %.2X | %.2X |", CPU->GetPC( ), CPU->ReadD( _SP_ ), ( CPU->ReadD( _DPTRHIGH_ ) << 8 ) + CPU->ReadD( _DPTRLOW_ ), CPU->ReadD( _ACC_ ), CPU->ReadD( _B_ ) ); - printf( " %d %d %d %d %d %d %d %d |", ( PSW >> 7 ) & 1, ( PSW >> 6 ) & 1, ( PSW >> 5 ) & 1, ( PSW >> 4 ) & 1, ( PSW >> 3 ) & 1, ( PSW >> 2 ) & 1, ( PSW >> 1 ) & 1, PSW & 1 ); - printf( "%s", ENDLINE ); - printf( "----------------------------------------------------------------------%s", ENDLINE ); - - printf( "| TCON | TMOD | IE | IP | R0 | R1 | R2 | R3 | R4 | R5 | R6 | R7 | |%s", ENDLINE ); - printf( "| %.2X | %.2X | %.2X | %.2X ", CPU->ReadD( _TCON_ ), CPU->ReadD( _TMOD_ ), CPU->ReadD( _IE_ ), CPU->ReadD( _IP_ ) ); - printf( "| %.2X | %.2X | %.2X | %.2X ", CPU->ReadD( BankSelect + _R0_ ), CPU->ReadD( BankSelect + _R1_ ), CPU->ReadD( BankSelect + _R2_ ), CPU->ReadD( BankSelect + _R3_ ) ); - printf( "| %.2X | %.2X | %.2X | %.2X ", CPU->ReadD( BankSelect + _R4_ ), CPU->ReadD( BankSelect + _R5_ ), CPU->ReadD( BankSelect + _R6_ ), CPU->ReadD( BankSelect + _R7_ ) ); - printf( "| |%s", ENDLINE ); - - printf( "----------------------------------------------------------------------%s", ENDLINE ); - -} diff --git a/src/EmuConsole.hpp b/src/EmuConsole.hpp index 865f9bb..42329d4 100644 --- a/src/EmuConsole.hpp +++ b/src/EmuConsole.hpp @@ -28,12 +28,6 @@ using namespace std; -// Maximum number of BreakPoints -#define MAXBP 32 - -#define ENDLINE "\n" - - ////////////////////////////////////////////////////////////////////////////// // EmuConsole diff --git a/src/Makefile.am b/src/Makefile.am index e97fce0..1c8beaf 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,20 +6,24 @@ INCLUDES = \ $(GTK_CFLAGS) bin_PROGRAMS = emu8051 -# emu8051_console # instructions_8051.c must be first, because it and other files (instructions_8051.h and # disasm.h) are automatically generated by a perl script, and other source files include # them (the .h). -emu8051_SOURCES = instructions_8051.c emugtk.c memwin.c pgmwin.c regwin.c filemenu.c \ - viewmenu.c helpmenu.c messagebox.c options.c hexfile.c cpu8051.c memory.c +emu8051_SOURCES = instructions_8051.c options.c hexfile.c cpu8051.c memory.c -emu8051_LDADD = $(GTK_LIBS) +if USE_GTK + emu8051_SOURCES += emugtk.c memwin.c pgmwin.c regwin.c filemenu.c viewmenu.c helpmenu.c messagebox.c + emu8051_LDADD = $(GTK_LIBS) +else + emu8051_SOURCES += emuconsole.c keyboard.c +endif # These headers will be included in the distribution tarball, but will not be # installed by 'make install' noinst_HEADERS = common.h emugtk.h memwin.h pgmwin.h regwin.h filemenu.h viewmenu.h helpmenu.h \ - messagebox.h options.h hexfile.h cpu8051.h memory.h reg8051.h gtksizes.h + messagebox.h options.h hexfile.h cpu8051.h memory.h reg8051.h gtksizes.h \ + keyboard.h # These files are generated automatically by a perl script. instructions_8051.c instructions_8051.h disasm.h : opcode2c.pl opcodes.lst @@ -32,13 +36,3 @@ DISTCLEANFILES = .deps/*.P MAINTAINERCLEANFILES = Makefile.in instructions_8051.c instructions_8051.h disasm.h EXTRA_DIST = opcode2c.pl opcodes.lst instructions_8051.h disasm.h - -# This rule is used to bypass the default rule which is generated by Automake, in order -# to get rid of all the cluttered informations that are displayed by Make before -# calling the compiler like in the following example: -# source='programming.c' object='programming.o' libtool=no \ -# depfile='.deps/programming.Po' tmpdepfile='.deps/programming.TPo' \ -# depmode=gcc3 /bin/sh ../config/depcomp \ -# gcc -DHAVE_CONFIG_H -I. -I. -I.. -c `test -f 'main.c' || echo './'`main.c -.c.o: - $(COMPILE) -c $< diff --git a/src/common.h b/src/common.h index 4f954c4..c9df126 100644 --- a/src/common.h +++ b/src/common.h @@ -51,10 +51,10 @@ typedef int bool; /* Returns TRUE if the strings 'a' and 'b' are equal. */ -#define STREQ(a, b) (strcmp((a), (b)) == 0) +#define STREQ(a, b) (strcasecmp((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) +#define STREQ_LEN(a, b, c) (strncasecmp((a), (b), (c)) == 0) inline void diff --git a/src/cpu8051.c b/src/cpu8051.c index 4e3a656..65a79ed 100644 --- a/src/cpu8051.c +++ b/src/cpu8051.c @@ -22,7 +22,6 @@ /* Define only here, for not having extern scope on local variables. */ #define CPU8051_M 1 - #include #include "reg8051.h" @@ -31,419 +30,329 @@ #include "disasm.h" #include "instructions_8051.h" - -void -cpu8051_init( void ) -{ - cpu8051.pc = 0; - cpu8051.clock = 0; - cpu8051.active_priority = -1; -} - - -////////////////////////////////////////////////////////////////////////////// -// Execute at address cpu8051.pc from PGMMem -////////////////////////////////////////////////////////////////////////////// void -cpu8051_Exec( void ) -{ - int i; - unsigned char opcode; - int insttiming; - - opcode = memory_read8( PGM_MEM_ID, cpu8051.pc ); - cpu8051.pc++; - insttiming = (*opcode_table[opcode])(); /* Function callback. */ - - for( i = 0; i < insttiming; i++ ) { - cpu8051_CheckInterrupts(); - cpu8051_DoTimers(); - cpu8051.clock++; - } -} - - -////////////////////////////////////////////////////////////////////////////// -// Return cpu8051.pc + size in bytes of current instruction -////////////////////////////////////////////////////////////////////////////// -unsigned int -cpu8051_GetNextAddress( void ) +cpu8051_init(void) { -#ifdef DECPP - return ( cpu8051.pc + InstSizesTbl[ memory_read8( PGM_MEM_ID, cpu8051.pc ) ] ); -#endif - return 0; /* temp */ + cpu8051.pc = 0; + cpu8051.clock = 0; + cpu8051.active_priority = -1; } - -////////////////////////////////////////////////////////////////////////////// -// Reset the registers and CPU state -////////////////////////////////////////////////////////////////////////////// +/* Reset the registers and CPU state */ void -cpu8051_Reset( void ) +cpu8051_Reset(void) { - cpu8051.pc = 0; - cpu8051.clock= 0; - cpu8051.active_priority = -1; - - // Reinitialisation des registres - int i; - for ( i = 0; i < 128; i++ ) { - - memory_write8( SFR_MEM_ID, i, 0 ); - - memory_write8( INT_MEM_ID, i, 0 ); - } + cpu8051.pc = 0; + cpu8051.clock= 0; + cpu8051.active_priority = -1; + + // Reinitialisation des registres + int i; + for ( i = 0; i < 256; i++ ) { + /* Clear IRAM nad SFR */ + memory_write8( INT_MEM_ID, i, 0 ); + } - memory_write8( SFR_MEM_ID, _P0_ - 0x80, 0xFF ); - memory_write8( SFR_MEM_ID, _P1_ - 0x80, 0xFF ); - memory_write8( SFR_MEM_ID, _P2_ - 0x80, 0xFF ); - memory_write8( SFR_MEM_ID, _P3_ - 0x80, 0xFF ); - memory_write8( SFR_MEM_ID, _SP_ - 0x80, 0x07 ); + memory_write8( INT_MEM_ID, _P0_, 0xFF ); + memory_write8( INT_MEM_ID, _P1_, 0xFF ); + memory_write8( INT_MEM_ID, _P2_, 0xFF ); + memory_write8( INT_MEM_ID, _P3_, 0xFF ); + memory_write8( INT_MEM_ID, _SP_, 0x07 ); } - -////////////////////////////////////////////////////////////////////////////// -// Write with a direct addressing mode at Address the new Value -////////////////////////////////////////////////////////////////////////////// +/* Write with a direct addressing mode at Address the new Value */ void cpu8051_WriteD( unsigned int Address, unsigned char Value ) { - if ( Address > 0x7F ) { - memory_write8( SFR_MEM_ID, Address - 0x80, Value ); - return; - } - - memory_write8( INT_MEM_ID, Address, Value ); + memory_write8( INT_MEM_ID, Address, Value ); } - -////////////////////////////////////////////////////////////////////////////// -// Ecriture d'une valeur dans la memoire interne ( Address = $00 a $FF ) -////////////////////////////////////////////////////////////////////////////// +// Write with an indirect addressing mode at Address the new Value void -cpu8051_WriteInt( unsigned int Address, unsigned char Value ) +cpu8051_WriteI( unsigned int Address, unsigned char Value ) { - if ( Address > 0x7F ) { - memory_write8( SFR_MEM_ID, Address - 0x80, Value ); - } - else { - memory_write8( INT_MEM_ID, Address, Value ); - } + if ( Address > 0x7F ) { + memory_write8( EXT_MEM_ID, Address, Value ); + return; + } - return; + memory_write8( INT_MEM_ID, Address, Value ); } - -////////////////////////////////////////////////////////////////////////////// -// Write with an indirect addressing mode at Address the new Value -////////////////////////////////////////////////////////////////////////////// +// Write with a bit addressing mode at BitAddress the new Value void -cpu8051_WriteI( unsigned int Address, unsigned char Value ) +cpu8051_WriteB( unsigned int BitAddress, unsigned char Value ) { - if ( Address > 0x7F ) { - memory_write8( EXT_MEM_ID, Address, Value ); - return; - } + unsigned int ByteAddress, BitNumber; + unsigned char ByteValue, ByteMask; - memory_write8( INT_MEM_ID, Address, Value ); + if ( BitAddress > 0x7F ) { + // SFR 80-FF + ByteAddress = BitAddress & 0xF8; + BitNumber = BitAddress & 0x07; + } + else { + // 20-2F + ByteAddress = ( BitAddress >> 3 ) + 0x20; + BitNumber = BitAddress & 0x07; + } + ByteMask = ( ( 1 << BitNumber ) ^ 0xFF ); + ByteValue = cpu8051_ReadD( ByteAddress ) & ByteMask; + ByteValue += Value << BitNumber; + cpu8051_WriteD( ByteAddress, ByteValue ); } - -////////////////////////////////////////////////////////////////////////////// // Read with a direct addressing mode at Address -////////////////////////////////////////////////////////////////////////////// unsigned char cpu8051_ReadD( unsigned int Address ) { - if ( Address > 0xFF ) { - return memory_read8( EXT_MEM_ID, Address ); - } - - if ( Address > 0x7F ) { - return memory_read8( SFR_MEM_ID, Address - 0x80 ); - } - - return memory_read8( INT_MEM_ID, Address ); -} - - -////////////////////////////////////////////////////////////////////////////// -// Read Internal data memory at Address -////////////////////////////////////////////////////////////////////////////// -unsigned char -cpu8051_ReadInt( unsigned int Address ) -{ - if ( Address > 0x7F ) { - return memory_read8( SFR_MEM_ID, Address - 0x80 ); - } - else { - return memory_read8( INT_MEM_ID, Address ); - } + if (Address > 0xFF) + return memory_read8(EXT_MEM_ID, Address); + else + return memory_read8(INT_MEM_ID, Address); } - -////////////////////////////////////////////////////////////////////////////// -// unsigned char cpu8051_ReadI( unsigned int Address ) // Read with a indirect addressing mode at Address -////////////////////////////////////////////////////////////////////////////// unsigned char cpu8051_ReadI( unsigned int Address ) { - if ( Address > 0x7F ) { - return memory_read8( EXT_MEM_ID, Address ); - } - else { - return memory_read8( INT_MEM_ID, Address ); - } -} - - -////////////////////////////////////////////////////////////////////////////// -// Write with a bit addressing mode at BitAddress the new Value -////////////////////////////////////////////////////////////////////////////// -void -cpu8051_WriteB( unsigned int BitAddress, unsigned char Value ) -{ - unsigned int ByteAddress, BitNumber; - unsigned char ByteValue, ByteMask; - - if ( BitAddress > 0x7F ) { - // SFR 80-FF - ByteAddress = BitAddress & 0xF8; - BitNumber = BitAddress & 0x07; - } - else { - // 20-2F - ByteAddress = ( BitAddress >> 3 ) + 0x20; - BitNumber = BitAddress & 0x07; - } - ByteMask = ( ( 1 << BitNumber ) ^ 0xFF ); - ByteValue = cpu8051_ReadD( ByteAddress ) & ByteMask; - ByteValue += Value << BitNumber; - cpu8051_WriteD( ByteAddress, ByteValue ); + if (Address > 0x7F) { + return memory_read8(EXT_MEM_ID, Address); + } + else { + return memory_read8(INT_MEM_ID, Address); + } } - -////////////////////////////////////////////////////////////////////////////// // Read with a bit addressing mode at BitAddress -////////////////////////////////////////////////////////////////////////////// unsigned char cpu8051_ReadB( unsigned int BitAddress ) { - unsigned int ByteAddress, BitNumber; - unsigned char BitValue; + unsigned int ByteAddress, BitNumber; + unsigned char BitValue; - if ( BitAddress > 0x7F ) { - // SFR 80-FF - ByteAddress = BitAddress & 0xF8; - BitNumber = BitAddress & 0x07; - } - else { - // 20-2F - ByteAddress = ( BitAddress >> 3 ) + 0x20; - BitNumber = BitAddress & 0x07; - } - BitValue = ( cpu8051_ReadD( ByteAddress ) >> BitNumber ); - BitValue &= 1; - return BitValue; + if ( BitAddress > 0x7F ) { + // SFR 80-FF + ByteAddress = BitAddress & 0xF8; + BitNumber = BitAddress & 0x07; + } + else { + // 20-2F + ByteAddress = ( BitAddress >> 3 ) + 0x20; + BitNumber = BitAddress & 0x07; + } + BitValue = ( cpu8051_ReadD( ByteAddress ) >> BitNumber ); + BitValue &= 1; + return BitValue; } - -////////////////////////////////////////////////////////////////////////////// // Check interrupts state and process them as needed -////////////////////////////////////////////////////////////////////////////// -void +static void cpu8051_CheckInterrupts() { - unsigned char SP; - int i; - - if ( cpu8051_ReadD( _IE_ ) & 0x80 ) { - for ( i = 1; i >= 0; i-- ) - if ( cpu8051.active_priority < i ) { - //------------------------- External interrupt 0 ---------------------------- - // if ( ( cpu8051_ReadD( _IE_ ) & 0x01 ) && ( ( cpu8051_ReadD( _IP_ ) & 0x01 ) ? i : !i ) && pin0 ) - //-------------------------- Interrupt timer 0 ------------------------------- - if ( ( cpu8051_ReadD( _IE_ ) & 0x02 ) && ( ( cpu8051_ReadD( _IP_ & 0x02 ) ? i : !i ) && ( cpu8051_ReadD( _TCON_ ) & 0x20 ) ) ){ - cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) & 0xDF ); - SP = cpu8051_ReadD( _SP_ ); - cpu8051_WriteI( ++SP, ( cpu8051.pc & 0xFF ) ); - cpu8051_WriteI( ++SP, ( cpu8051.pc >> 8 ) ); - cpu8051_WriteD( _SP_, SP ); - cpu8051.pc = 0x0B; - cpu8051.active_priority = i; - return; - } - //-------------------------- External interrupt 1 ---------------------------- - // if ( ( cpu8051_ReadD( _IE_ ) & 0x04 ) && ( ( cpu8051_ReadD( _IP_ ) & 0x04 ) ? i : !i ) && pin1 ) - //-------------------------- Interrupt timer 1 ------------------------------- - if ( ( cpu8051_ReadD( _IE_ ) & 0x08 ) && ( ( cpu8051_ReadD( _IP_ ) & 0x08 ) ? i : !i ) && ( cpu8051_ReadD( _TCON_ ) & 0x80 ) ) { - cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) & 0x7F ); - SP = cpu8051_ReadD( _SP_ ); - cpu8051_WriteI( ++SP, ( cpu8051.pc & 0xFF ) ); - cpu8051_WriteI( ++SP, ( cpu8051.pc >> 8 ) ); - cpu8051_WriteD( _SP_, SP ); - cpu8051.pc = 0x1B; - cpu8051.active_priority = i; - return; - } - //-------------------------- Serial Interrupts ------------------------------- - if ( ( cpu8051_ReadD( _IE_ ) & 0x10 ) && ( ( cpu8051_ReadD( _IP_ ) & 0x10 ) ? i : !i ) && ( cpu8051_ReadD( _SCON_ ) & 0x03 ) ) { - SP = cpu8051_ReadD( _SP_ ); - cpu8051_WriteI( ++SP, ( cpu8051.pc & 0xFF ) ); - cpu8051_WriteI( ++SP, ( cpu8051.pc >> 8 ) ); - cpu8051_WriteD( _SP_, SP ); - cpu8051.pc = 0x23; - cpu8051.active_priority = i; - return; + unsigned char SP; + int i; + + if ( cpu8051_ReadD( _IE_ ) & 0x80 ) { + for ( i = 1; i >= 0; i-- ) + if ( cpu8051.active_priority < i ) { + //------------------------- External interrupt 0 ---------------------------- + // if ( ( cpu8051_ReadD( _IE_ ) & 0x01 ) && ( ( cpu8051_ReadD( _IP_ ) & 0x01 ) ? i : !i ) && pin0 ) + //-------------------------- Interrupt timer 0 ------------------------------- + if ( ( cpu8051_ReadD( _IE_ ) & 0x02 ) && ( ( cpu8051_ReadD( _IP_ & 0x02 ) ? i : !i ) && ( cpu8051_ReadD( _TCON_ ) & 0x20 ) ) ){ + cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) & 0xDF ); + SP = cpu8051_ReadD( _SP_ ); + cpu8051_WriteI( ++SP, ( cpu8051.pc & 0xFF ) ); + cpu8051_WriteI( ++SP, ( cpu8051.pc >> 8 ) ); + cpu8051_WriteD( _SP_, SP ); + cpu8051.pc = 0x0B; + cpu8051.active_priority = i; + return; + } + //-------------------------- External interrupt 1 ---------------------------- + // if ( ( cpu8051_ReadD( _IE_ ) & 0x04 ) && ( ( cpu8051_ReadD( _IP_ ) & 0x04 ) ? i : !i ) && pin1 ) + //-------------------------- Interrupt timer 1 ------------------------------- + if ( ( cpu8051_ReadD( _IE_ ) & 0x08 ) && ( ( cpu8051_ReadD( _IP_ ) & 0x08 ) ? i : !i ) && ( cpu8051_ReadD( _TCON_ ) & 0x80 ) ) { + cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) & 0x7F ); + SP = cpu8051_ReadD( _SP_ ); + cpu8051_WriteI( ++SP, ( cpu8051.pc & 0xFF ) ); + cpu8051_WriteI( ++SP, ( cpu8051.pc >> 8 ) ); + cpu8051_WriteD( _SP_, SP ); + cpu8051.pc = 0x1B; + cpu8051.active_priority = i; + return; + } + //-------------------------- Serial Interrupts ------------------------------- + if ( ( cpu8051_ReadD( _IE_ ) & 0x10 ) && ( ( cpu8051_ReadD( _IP_ ) & 0x10 ) ? i : !i ) && ( cpu8051_ReadD( _SCON_ ) & 0x03 ) ) { + SP = cpu8051_ReadD( _SP_ ); + cpu8051_WriteI( ++SP, ( cpu8051.pc & 0xFF ) ); + cpu8051_WriteI( ++SP, ( cpu8051.pc >> 8 ) ); + cpu8051_WriteD( _SP_, SP ); + cpu8051.pc = 0x23; + cpu8051.active_priority = i; + return; + } + //-------------------------- Interrupt timer 2 ------------------------------- + if ( ( cpu8051_ReadD( _IE_ ) & 0x20 ) && ( ( cpu8051_ReadD( _IP_ ) & 0x20 ) ? i : !i ) && ( cpu8051_ReadD( _T2CON_ ) & 0x80 ) ) { + SP = cpu8051_ReadD( _SP_ ); + cpu8051_WriteI( ++SP, ( cpu8051.pc & 0xFF ) ); + cpu8051_WriteI( ++SP, ( cpu8051.pc >> 8 ) ); + cpu8051_WriteD( _SP_, SP ); + cpu8051.pc = 0x2B; + cpu8051.active_priority = i; + return; + } + } } - //-------------------------- Interrupt timer 2 ------------------------------- - if ( ( cpu8051_ReadD( _IE_ ) & 0x20 ) && ( ( cpu8051_ReadD( _IP_ ) & 0x20 ) ? i : !i ) && ( cpu8051_ReadD( _T2CON_ ) & 0x80 ) ) { - SP = cpu8051_ReadD( _SP_ ); - cpu8051_WriteI( ++SP, ( cpu8051.pc & 0xFF ) ); - cpu8051_WriteI( ++SP, ( cpu8051.pc >> 8 ) ); - cpu8051_WriteD( _SP_, SP ); - cpu8051.pc = 0x2B; - cpu8051.active_priority = i; - return; - } - } - } } - -////////////////////////////////////////////////////////////////////////////// // Execute les timers -////////////////////////////////////////////////////////////////////////////// -void +static void cpu8051_DoTimers( ) { - unsigned int tmp; - unsigned int TR; - unsigned int MODE; - unsigned int GATE; - unsigned int TimerCounter; - - // ----- Timer 0 - TR = cpu8051_ReadD( _TCON_ ) & 0x10; - MODE = cpu8051_ReadD( _TMOD_ ) & 0x03; - GATE = cpu8051_ReadD( _TMOD_ ) & 0x08; - TimerCounter = cpu8051_ReadD( _TMOD_ ) & 0x04; + unsigned int tmp; + unsigned int TR; + unsigned int MODE; + unsigned int GATE; + unsigned int TimerCounter; + + // ----- Timer 0 + TR = cpu8051_ReadD( _TCON_ ) & 0x10; + MODE = cpu8051_ReadD( _TMOD_ ) & 0x03; + GATE = cpu8051_ReadD( _TMOD_ ) & 0x08; + TimerCounter = cpu8051_ReadD( _TMOD_ ) & 0x04; - if ( ( TR && !GATE && !TimerCounter ) || ( MODE == 3 ) ) - switch( MODE ) { - // Mode 0, compteur de 13 bits. - case 0 : - tmp = cpu8051_ReadD( _TH0_ ) * 0x100 + cpu8051_ReadD( _TL0_ ); - - tmp++; - tmp &= 0x1FFF; // On ne garde que 13 bits. - - if ( tmp == 0 ) // If overflow set TF0 - cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) | 0x20 ); - cpu8051_WriteD( _TH0_, tmp / 0x100 ); - cpu8051_WriteD( _TL0_, tmp & 0xFF ); - break; + if ( ( TR && !GATE && !TimerCounter ) || ( MODE == 3 ) ) + switch( MODE ) { + // Mode 0, compteur de 13 bits. + case 0 : + tmp = cpu8051_ReadD( _TH0_ ) * 0x100 + cpu8051_ReadD( _TL0_ ); + + tmp++; + tmp &= 0x1FFF; // On ne garde que 13 bits. + + if ( tmp == 0 ) // If overflow set TF0 + cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) | 0x20 ); + cpu8051_WriteD( _TH0_, tmp / 0x100 ); + cpu8051_WriteD( _TL0_, tmp & 0xFF ); + break; - // Mode 1, compteur de 16 bits. - case 1 : - tmp = cpu8051_ReadD( _TH0_ ) * 0x100 + cpu8051_ReadD( _TL0_ ); - tmp++; - tmp &= 0xFFFF; // On ne garde que 16 bits. - if ( tmp == 0 ) // If overflow set TF0 - cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) | 0x20 ); - cpu8051_WriteD( _TH0_, ( tmp / 0x100 ) ); - cpu8051_WriteD( _TL0_, ( tmp & 0xFF ) ); - break; + // Mode 1, compteur de 16 bits. + case 1 : + tmp = cpu8051_ReadD( _TH0_ ) * 0x100 + cpu8051_ReadD( _TL0_ ); + tmp++; + tmp &= 0xFFFF; // On ne garde que 16 bits. + if ( tmp == 0 ) // If overflow set TF0 + cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) | 0x20 ); + cpu8051_WriteD( _TH0_, ( tmp / 0x100 ) ); + cpu8051_WriteD( _TL0_, ( tmp & 0xFF ) ); + break; - // Mode 2, Compteur de 8 bits avec Auto-Reload - case 2 : - tmp = cpu8051_ReadD( _TL0_ ); - tmp++; - tmp &= 0xFF; - if ( tmp == 0 ) { // If overflow -> reload et set TF0 - cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) | 0x20 ); - cpu8051_WriteD( _TL0_, cpu8051_ReadD( _TH0_ ) ); - } - else - cpu8051_WriteD( _TL0_, tmp ); - break; + // Mode 2, Compteur de 8 bits avec Auto-Reload + case 2 : + tmp = cpu8051_ReadD( _TL0_ ); + tmp++; + tmp &= 0xFF; + if ( tmp == 0 ) { // If overflow -> reload et set TF0 + cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) | 0x20 ); + cpu8051_WriteD( _TL0_, cpu8051_ReadD( _TH0_ ) ); + } + else + cpu8051_WriteD( _TL0_, tmp ); + break; - // Mode 3 : TL0 et TH0 sont 2 Timers independants de 8 bits chacuns. - case 3 : - if ( TR && !GATE && !TimerCounter ) { - tmp = cpu8051_ReadD( _TL0_ ); - tmp++; - tmp &= 0xFF; - if ( tmp == 0 ) // If TL0 overflow set TF0 - cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) | 0x20 ); - cpu8051_WriteD( _TL0_, tmp ); - } // TH0 utilise TR1 et TF1. - TR = cpu8051_ReadD( _TCON_ ) & 0x40; - if ( TR ) { - tmp = cpu8051_ReadD( _TH0_ ); - tmp++; - tmp &= 0xFF; - if ( tmp == 0 ) // If TH0 overflow set TF1 - cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) | 0x80 ); // TF1 = 1. - cpu8051_WriteD( _TH0_, tmp ); - } - break; - }; + // Mode 3 : TL0 et TH0 sont 2 Timers independants de 8 bits chacuns. + case 3 : + if ( TR && !GATE && !TimerCounter ) { + tmp = cpu8051_ReadD( _TL0_ ); + tmp++; + tmp &= 0xFF; + if ( tmp == 0 ) // If TL0 overflow set TF0 + cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) | 0x20 ); + cpu8051_WriteD( _TL0_, tmp ); + } // TH0 utilise TR1 et TF1. + TR = cpu8051_ReadD( _TCON_ ) & 0x40; + if ( TR ) { + tmp = cpu8051_ReadD( _TH0_ ); + tmp++; + tmp &= 0xFF; + if ( tmp == 0 ) // If TH0 overflow set TF1 + cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) | 0x80 ); // TF1 = 1. + cpu8051_WriteD( _TH0_, tmp ); + } + break; + }; - // ----- Timer 1 - TR = cpu8051_ReadD( _TCON_ ) & 0x40; - MODE = ( cpu8051_ReadD( _TMOD_ ) & 0x30 ) >> 4 ; - GATE = cpu8051_ReadD( _TMOD_ ) & 0x80; - TimerCounter = cpu8051_ReadD( _TMOD_ ) & 0x40; + // ----- Timer 1 + TR = cpu8051_ReadD( _TCON_ ) & 0x40; + MODE = ( cpu8051_ReadD( _TMOD_ ) & 0x30 ) >> 4 ; + GATE = cpu8051_ReadD( _TMOD_ ) & 0x80; + TimerCounter = cpu8051_ReadD( _TMOD_ ) & 0x40; - if ( TR && !GATE && !TimerCounter ) - switch( MODE ) { - // Mode 0, compteur de 13 bits. - case 0 : - tmp = cpu8051_ReadD( _TH1_ ) * 0x100 + cpu8051_ReadD( _TL1_ ); - tmp++; - tmp &= 0x1FFF; // On ne garde que 13 bits. - if ( tmp == 0 ) // If overflow set TF1 - cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) | 0x80 ); - cpu8051_WriteD( _TH1_, tmp / 0x100 ); - cpu8051_WriteD( _TL1_, tmp & 0xFF ); - break; + if ( TR && !GATE && !TimerCounter ) + switch( MODE ) { + // Mode 0, compteur de 13 bits. + case 0 : + tmp = cpu8051_ReadD( _TH1_ ) * 0x100 + cpu8051_ReadD( _TL1_ ); + tmp++; + tmp &= 0x1FFF; // On ne garde que 13 bits. + if ( tmp == 0 ) // If overflow set TF1 + cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) | 0x80 ); + cpu8051_WriteD( _TH1_, tmp / 0x100 ); + cpu8051_WriteD( _TL1_, tmp & 0xFF ); + break; - // Mode 1, compteur de 16 bits. - case 1 : - tmp = cpu8051_ReadD( _TH1_ ) * 0x100 + cpu8051_ReadD( _TL1_ ); - tmp++; - tmp &= 0xFFFF; // On ne garde que 16 bits. - if ( tmp == 0 ) // If overflow set TF1 - cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) | 0x80 ); - cpu8051_WriteD( _TH1_, ( tmp / 0x100 ) ); - cpu8051_WriteD( _TL1_, ( tmp & 0xFF ) ); - break; + // Mode 1, compteur de 16 bits. + case 1 : + tmp = cpu8051_ReadD( _TH1_ ) * 0x100 + cpu8051_ReadD( _TL1_ ); + tmp++; + tmp &= 0xFFFF; // On ne garde que 16 bits. + if ( tmp == 0 ) // If overflow set TF1 + cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) | 0x80 ); + cpu8051_WriteD( _TH1_, ( tmp / 0x100 ) ); + cpu8051_WriteD( _TL1_, ( tmp & 0xFF ) ); + break; - // Mode 2, Compteur de 8 bits avec Auto-Reload - case 2 : - tmp = cpu8051_ReadD( _TL1_ ); - tmp++; - tmp &= 0xFF; - if ( tmp == 0 ) { // If overflow -> reload et set TF1 - cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) | 0x80 ); - cpu8051_WriteD( _TL1_, cpu8051_ReadD( _TH1_ ) ); - } - else - cpu8051_WriteD( _TL1_, tmp ); - break; + // Mode 2, Compteur de 8 bits avec Auto-Reload + case 2 : + tmp = cpu8051_ReadD( _TL1_ ); + tmp++; + tmp &= 0xFF; + if ( tmp == 0 ) { // If overflow -> reload et set TF1 + cpu8051_WriteD( _TCON_, cpu8051_ReadD( _TCON_ ) | 0x80 ); + cpu8051_WriteD( _TL1_, cpu8051_ReadD( _TH1_ ) ); + } + else + cpu8051_WriteD( _TL1_, tmp ); + break; - // Mode 3 : mode inactif: retient la valeur de TH1 et TL1. - // Equivalent a TR1 = 0. - case 3 : - break; + // Mode 3 : mode inactif: retient la valeur de TH1 et TL1. + // Equivalent a TR1 = 0. + case 3 : + break; - }; + }; } +/* Execute at address cpu8051.pc from PGMMem */ +void +cpu8051_Exec(void) +{ + int i; + unsigned char opcode; + int insttiming; + + opcode = memory_read8( PGM_MEM_ID, cpu8051.pc ); + cpu8051.pc++; + insttiming = (*opcode_table[opcode])(); /* Function callback. */ + + for( i = 0; i < insttiming; i++ ) { + cpu8051_CheckInterrupts(); + cpu8051_DoTimers(); + cpu8051.clock++; + } +} // Addressing modes defined in the order as they appear in disasm.hpp // from table argstext[] @@ -476,164 +385,155 @@ cpu8051_DoTimers( ) // 80 | P0 | SP | DPL | DPH | | | | PCON | 87 // --------------------------------------------------------------- - -////////////////////////////////////////////////////////////////////////////// // Return as Text the name of the SFR register at Address if any -////////////////////////////////////////////////////////////////////////////// -int +static int cpu8051_SFRMemInfo( unsigned int Address, char *Text ) { - switch( Address ) { - case 0x80 : return sprintf( Text, "P0" ); - case 0x81 : return sprintf( Text, "SP" ); - case 0x82 : return sprintf( Text, "DPL" ); - case 0x83 : return sprintf( Text, "DPH" ); - case 0x87 : return sprintf( Text, "PCON" ); - case 0x88 : return sprintf( Text, "TCON" ); - case 0x89 : return sprintf( Text, "TMOD" ); - case 0x8A : return sprintf( Text, "TL0" ); - case 0x8B : return sprintf( Text, "TL1" ); - case 0x8C : return sprintf( Text, "TH0" ); - case 0x8D : return sprintf( Text, "TH1" ); - case 0x90 : return sprintf( Text, "P1" ); - case 0x98 : return sprintf( Text, "SCON" ); - case 0x99 : return sprintf( Text, "SBUF" ); - case 0xA0 : return sprintf( Text, "P2" ); - case 0xA8 : return sprintf( Text, "IE" ); - case 0xB0 : return sprintf( Text, "P3" ); - case 0xB8 : return sprintf( Text, "IP" ); - case 0xC8 : return sprintf( Text, "T2CON" ); - case 0xCA : return sprintf( Text, "RCAP2L" ); - case 0xCB : return sprintf( Text, "RCAP2H" ); - case 0xCC : return sprintf( Text, "TL2" ); - case 0xCD : return sprintf( Text, "TH2" ); - case 0xD0 : return sprintf( Text, "PSW" ); - case 0xE0 : return sprintf( Text, "ACC" ); - case 0xF0 : return sprintf( Text, "B" ); - default : return sprintf( Text, "%.2XH", Address ); - } + switch( Address ) { + case 0x80 : return sprintf( Text, "P0" ); + case 0x81 : return sprintf( Text, "SP" ); + case 0x82 : return sprintf( Text, "DPL" ); + case 0x83 : return sprintf( Text, "DPH" ); + case 0x87 : return sprintf( Text, "PCON" ); + case 0x88 : return sprintf( Text, "TCON" ); + case 0x89 : return sprintf( Text, "TMOD" ); + case 0x8A : return sprintf( Text, "TL0" ); + case 0x8B : return sprintf( Text, "TL1" ); + case 0x8C : return sprintf( Text, "TH0" ); + case 0x8D : return sprintf( Text, "TH1" ); + case 0x90 : return sprintf( Text, "P1" ); + case 0x98 : return sprintf( Text, "SCON" ); + case 0x99 : return sprintf( Text, "SBUF" ); + case 0xA0 : return sprintf( Text, "P2" ); + case 0xA8 : return sprintf( Text, "IE" ); + case 0xB0 : return sprintf( Text, "P3" ); + case 0xB8 : return sprintf( Text, "IP" ); + case 0xC8 : return sprintf( Text, "T2CON" ); + case 0xCA : return sprintf( Text, "RCAP2L" ); + case 0xCB : return sprintf( Text, "RCAP2H" ); + case 0xCC : return sprintf( Text, "TL2" ); + case 0xCD : return sprintf( Text, "TH2" ); + case 0xD0 : return sprintf( Text, "PSW" ); + case 0xE0 : return sprintf( Text, "ACC" ); + case 0xF0 : return sprintf( Text, "B" ); + default : return sprintf( Text, "%.2XH", Address ); + } } - -////////////////////////////////////////////////////////////////////////////// // Return as Text the decoded BitAddress -////////////////////////////////////////////////////////////////////////////// -void +static void cpu8051_IntMemBitInfo( unsigned int BitAddress, char *Text ) { - unsigned int ByteAddress, BitNumber; - int TextLength; + unsigned int ByteAddress, BitNumber; + int TextLength; - if ( BitAddress > 0x7F ) { - // SFR 80-FF - ByteAddress = BitAddress & 0xF8; - BitNumber = BitAddress & 0x07; - } - else { - // 20-2F - ByteAddress = ( BitAddress >> 3 ) + 0x20; - BitNumber = BitAddress & 0x07; - } + if ( BitAddress > 0x7F ) { + // SFR 80-FF + ByteAddress = BitAddress & 0xF8; + BitNumber = BitAddress & 0x07; + } + else { + // 20-2F + ByteAddress = ( BitAddress >> 3 ) + 0x20; + BitNumber = BitAddress & 0x07; + } - TextLength = cpu8051_SFRMemInfo( ByteAddress, Text ); - // sprintf( &Text[ TextLength ], ".%X" ); - // Modified by Hugo Villeneuve to remove compilation warning - sprintf( &Text[ TextLength ], ".%X", BitAddress ); + TextLength = cpu8051_SFRMemInfo( ByteAddress, Text ); + // sprintf( &Text[ TextLength ], ".%X" ); + // Modified by Hugo Villeneuve to remove compilation warning + sprintf( &Text[ TextLength ], ".%X", BitAddress ); } - -////////////////////////////////////////////////////////////////////////////// // Disasm one instruction at Address into a Text string -////////////////////////////////////////////////////////////////////////////// int cpu8051_Disasm( unsigned int Address, char *Text ) { - int TextLength=0; - char TextTmp[20]; - unsigned char OpCode; - int ArgTblOfs; - int InstSize; - int i; + int TextLength=0; + char TextTmp[20]; + unsigned char OpCode; + int ArgTblOfs; + int InstSize; + int i; - OpCode = memory_read8( PGM_MEM_ID, Address ); - InstSize = InstSizesTbl[ OpCode ]; - //printf("%.4X\n", Address); + OpCode = memory_read8( PGM_MEM_ID, Address ); + InstSize = InstSizesTbl[ OpCode ]; + //printf("%.4X\n", Address); - TextLength += sprintf( Text, " %.4X ", Address ); + TextLength += sprintf( Text, " %.4X ", Address ); - for (i = 0; i < InstSize; i++ ) - TextLength += sprintf( &Text[TextLength], " %.2X", memory_read8( PGM_MEM_ID, Address + i ) ); + for (i = 0; i < InstSize; i++ ) + TextLength += sprintf( &Text[TextLength], " %.2X", memory_read8( PGM_MEM_ID, Address + i ) ); - Address++; + Address++; - for (; TextLength < 17; ) TextLength += sprintf( &Text[ TextLength ], " " ); + for (; TextLength < 17; ) TextLength += sprintf( &Text[ TextLength ], " " ); - TextLength += sprintf( &Text[ TextLength ], "%s ", InstTextTbl[ InstTypesTbl[ OpCode ] ] ); - ArgTblOfs = OpCode << 2; + TextLength += sprintf( &Text[ TextLength ], "%s ", InstTextTbl[ InstTypesTbl[ OpCode ] ] ); + ArgTblOfs = OpCode << 2; - for (; TextLength < 25; ) TextLength += sprintf( &Text[ TextLength ], " " ); + for (; TextLength < 25; ) TextLength += sprintf( &Text[ TextLength ], " " ); - // MOV direct, direct (OpCode 85h) is peculiar, the operands are inverted - if ( OpCode == 0x85 ) { - cpu8051_SFRMemInfo( memory_read8( PGM_MEM_ID, Address + 1 ), TextTmp ); - TextLength += sprintf( &Text[ TextLength ], "%s,", TextTmp ); - cpu8051_SFRMemInfo( memory_read8( PGM_MEM_ID, Address ), TextTmp ); - TextLength += sprintf( &Text[ TextLength ], "%s", TextTmp ); - Address += 2; - return InstSize; - } + // MOV direct, direct (OpCode 85h) is peculiar, the operands are inverted + if ( OpCode == 0x85 ) { + cpu8051_SFRMemInfo( memory_read8( PGM_MEM_ID, Address + 1 ), TextTmp ); + TextLength += sprintf( &Text[ TextLength ], "%s,", TextTmp ); + cpu8051_SFRMemInfo( memory_read8( PGM_MEM_ID, Address ), TextTmp ); + TextLength += sprintf( &Text[ TextLength ], "%s", TextTmp ); + Address += 2; + return InstSize; + } - for ( i = 1; i <= InstArgTbl[ ArgTblOfs ]; i++ ) { - switch( InstArgTbl[ ArgTblOfs + i ] ) { - case ADDR11 : { - TextLength += sprintf( &Text[ TextLength ], "%.4XH", ( ( OpCode << 3) & 0xF00 ) + ( memory_read8( PGM_MEM_ID, Address ) ) ); - Address++; - break; - } - case ADDR16 : { - TextLength += sprintf( &Text[ TextLength ], "%.4XH", ( ( memory_read8( PGM_MEM_ID, Address ) << 8 ) + memory_read8( PGM_MEM_ID, Address + 1 ) ) ); - Address += 2; - break; - } - case DIRECT : { - cpu8051_SFRMemInfo( memory_read8( PGM_MEM_ID, Address ), TextTmp ); - TextLength += sprintf( &Text[ TextLength ], "%s", TextTmp ); - Address++; - break; - } - case BITADDR : { - cpu8051_IntMemBitInfo( ( memory_read8( PGM_MEM_ID, Address ) & 0xF8 ), TextTmp ); - TextLength += sprintf( &Text[ TextLength ], "%s.%X" , TextTmp, ( memory_read8( PGM_MEM_ID, Address ) & 7 ) ); - Address++; - break; - } - case RELADDR : { - Address++; - TextLength += sprintf( &Text[ TextLength ], "%.4XH", ( Address & 0xFF00 ) + ( ( ( Address & 0xFF ) + memory_read8( PGM_MEM_ID, Address - 1 ) ) & 0xFF ) ); - break; - } - case DATAIMM : { - TextLength += sprintf( &Text[ TextLength ], "#%.2XH", memory_read8( PGM_MEM_ID, Address ) ); - Address++; - break; - } - case DATA16 : { - TextLength += sprintf( &Text[ TextLength ],"#%.4XH", ( ( memory_read8( PGM_MEM_ID, Address ) << 8 ) + memory_read8( PGM_MEM_ID, Address+1 ) ) ); - Address += 2; - break; - } - case CBITADDR : { - cpu8051_IntMemBitInfo( ( memory_read8( PGM_MEM_ID, Address ) & 0xF8 ), TextTmp ); - TextLength += sprintf( &Text[ TextLength ], "/%s.%X", TextTmp, ( memory_read8( PGM_MEM_ID, Address ) & 7 ) ); - Address++; - break; - } - default : { - TextLength += sprintf( &Text[ TextLength ],"%s", ArgsTextTbl[ InstArgTbl[ ArgTblOfs + i ] ] ); - } - } - if (i < InstArgTbl[ ArgTblOfs ]) { TextLength += sprintf( &Text[ TextLength ], "," ); } - } + for ( i = 1; i <= InstArgTbl[ ArgTblOfs ]; i++ ) { + switch( InstArgTbl[ ArgTblOfs + i ] ) { + case ADDR11 : { + TextLength += sprintf( &Text[ TextLength ], "%.4XH", ( ( OpCode << 3) & 0xF00 ) + ( memory_read8( PGM_MEM_ID, Address ) ) ); + Address++; + break; + } + case ADDR16 : { + TextLength += sprintf( &Text[ TextLength ], "%.4XH", ( ( memory_read8( PGM_MEM_ID, Address ) << 8 ) + memory_read8( PGM_MEM_ID, Address + 1 ) ) ); + Address += 2; + break; + } + case DIRECT : { + cpu8051_SFRMemInfo( memory_read8( PGM_MEM_ID, Address ), TextTmp ); + TextLength += sprintf( &Text[ TextLength ], "%s", TextTmp ); + Address++; + break; + } + case BITADDR : { + cpu8051_IntMemBitInfo( ( memory_read8( PGM_MEM_ID, Address ) & 0xF8 ), TextTmp ); + TextLength += sprintf( &Text[ TextLength ], "%s.%X" , TextTmp, ( memory_read8( PGM_MEM_ID, Address ) & 7 ) ); + Address++; + break; + } + case RELADDR : { + Address++; + TextLength += sprintf( &Text[ TextLength ], "%.4XH", ( Address & 0xFF00 ) + ( ( ( Address & 0xFF ) + memory_read8( PGM_MEM_ID, Address - 1 ) ) & 0xFF ) ); + break; + } + case DATAIMM : { + TextLength += sprintf( &Text[ TextLength ], "#%.2XH", memory_read8( PGM_MEM_ID, Address ) ); + Address++; + break; + } + case DATA16 : { + TextLength += sprintf( &Text[ TextLength ],"#%.4XH", ( ( memory_read8( PGM_MEM_ID, Address ) << 8 ) + memory_read8( PGM_MEM_ID, Address+1 ) ) ); + Address += 2; + break; + } + case CBITADDR : { + cpu8051_IntMemBitInfo( ( memory_read8( PGM_MEM_ID, Address ) & 0xF8 ), TextTmp ); + TextLength += sprintf( &Text[ TextLength ], "/%s.%X", TextTmp, ( memory_read8( PGM_MEM_ID, Address ) & 7 ) ); + Address++; + break; + } + default : { + TextLength += sprintf( &Text[ TextLength ],"%s", ArgsTextTbl[ InstArgTbl[ ArgTblOfs + i ] ] ); + } + } + if (i < InstArgTbl[ ArgTblOfs ]) { TextLength += sprintf( &Text[ TextLength ], "," ); } + } - return InstSize; + return InstSize; } diff --git a/src/cpu8051.h b/src/cpu8051.h index 32ab375..67e684f 100644 --- a/src/cpu8051.h +++ b/src/cpu8051.h @@ -1,5 +1,5 @@ /* - * emu8051.h + * cpu8051.h * * Copyright (C) 1999 Jonathan St-André * Copyright (C) 1999 Hugo Villeneuve @@ -22,7 +22,6 @@ #ifndef CPU8051_H #define CPU8051_H 1 - typedef struct cpu8051_t { unsigned int pc; @@ -30,7 +29,6 @@ typedef struct cpu8051_t int active_priority; } cpu8051_t; - /* Exported variables */ #undef _SCOPE_ #ifdef CPU8051_M @@ -41,7 +39,6 @@ typedef struct cpu8051_t _SCOPE_ cpu8051_t cpu8051; - void cpu8051_init( void ); @@ -55,43 +52,21 @@ void cpu8051_WriteD( unsigned int Address, unsigned char Value ); void -cpu8051_WriteInt( unsigned int Address, unsigned char Value ); +cpu8051_WriteI( unsigned int Address, unsigned char Value ); void -cpu8051_WriteI( unsigned int Address, unsigned char Value ); +cpu8051_WriteB( unsigned int BitAddress, unsigned char Value ); unsigned char cpu8051_ReadD( unsigned int Address ); -unsigned char -cpu8051_ReadInt( unsigned int Address ); - unsigned char cpu8051_ReadI( unsigned int Address ); -unsigned int -cpu8051_GetNextAddress( void ); - -void -cpu8051_WriteB( unsigned int BitAddress, unsigned char Value ); - unsigned char cpu8051_ReadB( unsigned int BitAddress ); -void -cpu8051_CheckInterrupts( void ); - -void -cpu8051_DoTimers( void ); - -int -cpu8051_SFRMemInfo( unsigned int Address, char *Text ); - -void -cpu8051_IntMemBitInfo( unsigned int BitAddress, char *Text ); - int cpu8051_Disasm( unsigned int Address, char *Text ); - #endif /* CPU8051_H */ diff --git a/src/emuconsole.c b/src/emuconsole.c new file mode 100644 index 0000000..48ae43e --- /dev/null +++ b/src/emuconsole.c @@ -0,0 +1,570 @@ +/* + * emuconsole.c + * + * Copyright (C) 1999 Jonathan St-André + * Copyright (C) 1999 Hugo Villeneuve + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#define _GNU_SOURCE /* For getline() */ +#include +#include +#include /* For isblank, toupper() */ +#include "config.h" + +#include "common.h" +#include "cpu8051.h" +#include "reg8051.h" +#include "memory.h" +#include "options.h" +#include "hexfile.h" +#include "keyboard.h" + +/* Maximum number of BreakPoints */ +#define MAXBP 32 + +#define ENDLINE "\n" + +static int RunningState; +static int NbBreakpoints; +static unsigned int Breakpoints[MAXBP]; + +/* Capitalize all letters in buffer */ +static void +Capitalize(char *buffer) +{ + int k; + + for (k = 0; k < strlen(buffer); k++) + buffer[k] = toupper(buffer[k]); +} + +/* Remove leading spaces from string in buffer */ +static void +RemoveSpaces(char *buffer) +{ + int k = 0; + + while ((k < strlen(buffer)) && isblank(buffer[k])) + k++; + + if (k != 0) + strcpy(buffer, &buffer[k]); +} + +/* Is the a breakpoint at Address */ +static int +IsBreakpoint(unsigned int Address) +{ + int Index = 0; + while (Index < NbBreakpoints && (Breakpoints[Index] != Address)) + Index++; + + return ((Breakpoints[Index] == Address) && (Index < NbBreakpoints)); +} + +/* Show Breakpoints list */ +static void +ShowBreakpoints(void) +{ + int Index; + + for (Index = 0; Index < NbBreakpoints ; Index++) + printf("Breakpoint at Address = %.4X\n", Breakpoints[Index]); +} + +/* Clear Breakpoint at Address from list */ +static void +ClearBreakpoint(unsigned int Address) +{ + int Index = 0; + while ((Index < NbBreakpoints) && (Breakpoints[Index] != Address)) + Index++; + if (Breakpoints[Index] != Address) + return; + Breakpoints[Index] = Breakpoints[NbBreakpoints - 1]; + NbBreakpoints--; +} + +/* Set Breakpoint at Address from list */ +static void +SetBreakpoint(unsigned int Address) +{ + if (IsBreakpoint(Address)) + return; + if (NbBreakpoints < MAXBP) + Breakpoints[NbBreakpoints++] = Address; +} + +/* CPU exec and Console UI update */ +static void +console_exec(char *Address, char *NumberInst) +{ + char dummy; + int NbInst = -1; /* -1 is infinity */ + if (strlen(Address) == 0) { + printf("Invalid address\n"); + return; + } + + if (STREQ(Address, "PC")) + cpu8051.pc = Ascii2Hex(Address, strlen(Address)); + + if (strlen(NumberInst) != 0) + NbInst = Ascii2Hex(NumberInst, strlen(NumberInst)); + + InitUnixKB(); + + printf("Program executing...\n"); + + do { + cpu8051_Exec(); + if (NbInst > 0) + NbInst--; + } while (!IsBreakpoint(cpu8051.pc) && (NbInst != 0) && !kbhit()); + if (kbhit()) { + dummy = getch(); /* Flush key */ + printf("Caught break signal!\n"); + } + if (NbInst == 0) + printf("Number of instructions reached! Stopping!\n"); + if (IsBreakpoint(cpu8051.pc)) + printf("Breakpoint hit at %.4X! Stopping!\n", cpu8051.pc); + + ResetUnixKB(); +} + +/* Disassemble NumberInst instructions at Address */ +static void +DisasmN(unsigned int Address, int NumberInst) +{ + char TextTmp[255]; + int Row; + + for (Row = 0; Row < NumberInst ; Row++) { + Address += cpu8051_Disasm(Address, TextTmp); + printf("%s\n", TextTmp); + } +} + +/* Disassemble 16 instructions at Address */ +static void +Disasm(char *Address, char *NumberInst) +{ + unsigned int MemAddress, NbInst; + + if ((strlen(Address) == 0) || (STREQ(Address, "PC"))) + MemAddress = cpu8051.pc; + else + MemAddress = Ascii2Hex(Address, strlen(Address)); + + if (strlen(NumberInst) == 0) + NumberInst = "10"; + NbInst = Ascii2Hex(NumberInst, strlen(NumberInst)); + DisasmN(MemAddress, NbInst); +} + +/* Dump memory */ +static void +DumpMem(char *Address, int memory_id) +{ + unsigned int MemAddress; + int Offset, Column; + int size = 256; + + if (strlen(Address) != 0) { + if (STREQ(Address, "PC")) + MemAddress = cpu8051.pc; + else + MemAddress = Ascii2Hex(Address, strlen(Address)); + } else { + MemAddress = 0; + } + + for (Offset = 0; Offset < size; Offset += 16) { + unsigned char data[16]; + + printf("%.4X ", MemAddress + Offset); + for (Column = 0; Column < 16; Column++) { + data[Column] = memory_read8(memory_id, MemAddress + + Offset + Column); + printf(" %.2X", (int) data[Column]); + } + printf(" "); + + /* Display any ASCII characters */ + for (Column = 0; Column < 16; Column++) { + if ((int) data[Column] >= 32 && + (int) data[Column] <= 126) + printf("%c", data[Column]); + else + printf("."); + } + printf("\n"); + } +} + +/* Set NewValue to Register */ +static void +SetRegister(char *Register, char *NewValue) +{ + if (STREQ(Register, "PC")) + cpu8051.pc = Ascii2Hex(NewValue, 4); + else if (STREQ(Register, "A")) + cpu8051_WriteD(_ACC_, Ascii2Hex(NewValue, 2)); + else if (STREQ(Register, "B")) + cpu8051_WriteD(_B_, Ascii2Hex(NewValue, 2)); + else if (STREQ(Register, "SP")) + cpu8051_WriteD(_SP_, Ascii2Hex(NewValue, 2)); + else { + printf("%sInvalid register name!%s", ENDLINE, ENDLINE); + printf("Valid registers are A, B, PC and SP.\n"); + } +} + +/* Show CPU registers */ +static void +console_show_registers(void) +{ + unsigned char PSW = cpu8051_ReadD(_PSW_); + int BankSelect = (PSW & 0x18); + + printf("---------------------------------------------------------------" + "-------\n"); + printf("| PC | SP | DPTR | ACC | B | PSW: CY AC F0 RS1 RS0 OV" + " - P |\n"); + printf("| %.4X | %.2X | %.4X | %.2X | %.2X |", cpu8051.pc, + cpu8051_ReadD(_SP_), + (cpu8051_ReadD(_DPTRHIGH_) << 8) + cpu8051_ReadD(_DPTRLOW_), + cpu8051_ReadD(_ACC_), cpu8051_ReadD(_B_)); + printf(" %d %d %d %d %d %d %d %d |", + (PSW >> 7) & 1, (PSW >> 6) & 1, (PSW >> 5) & 1, (PSW >> 4) & 1, + (PSW >> 3) & 1, (PSW >> 2) & 1, (PSW >> 1) & 1, PSW & 1); + printf("\n"); + printf("---------------------------------------------------------------" + "-------\n"); + + printf("| TCON | TMOD | IE | IP | R0 | R1 | R2 | R3 | R4 | R5 | R6 | R7" + " | |\n"); + printf("| %.2X | %.2X | %.2X | %.2X ", cpu8051_ReadD(_TCON_), + cpu8051_ReadD(_TMOD_), cpu8051_ReadD(_IE_), cpu8051_ReadD(_IP_)); + printf("| %.2X | %.2X | %.2X | %.2X ", + cpu8051_ReadD(BankSelect + _R0_), + cpu8051_ReadD(BankSelect + _R1_), + cpu8051_ReadD(BankSelect + _R2_), + cpu8051_ReadD(BankSelect + _R3_)); + printf("| %.2X | %.2X | %.2X | %.2X ", + cpu8051_ReadD(BankSelect + _R4_), + cpu8051_ReadD(BankSelect + _R5_), + cpu8051_ReadD(BankSelect + _R6_), + cpu8051_ReadD(BankSelect + _R7_)); + printf("| |\n"); + printf("---------------------------------------------------------------" + "-------\n"); +} + +/* CPU reset and Console UI update */ +static void +console_reset(void) +{ + printf("Resetting... "); + cpu8051_Reset(); + printf("Done.\n"); + console_show_registers(); +} + +/* CPU trace and Console UI update */ +static void +console_trace(char *Address) +{ + if (strlen(Address) != 0) + cpu8051.pc = Ascii2Hex(Address, strlen(Address)); + cpu8051_Exec(); + console_show_registers(); + DisasmN(cpu8051.pc, 1); +} + +/* EmuConsole main loop */ +static void +console_main(void) +{ + unsigned int Index; + char *line = NULL; + + char prompt[] = "-> "; + + char *Title[] = { " *******************", + " * 8051 Emulator *", + " *******************", + "", 0 }; + + char *Menu[] = { + " Available commands, [ ] = options", + "", + " Set Breakpoint.............. SB [address]", + " Remove Breakpoint........... RB [address]", + " Display Breakpoint(s)....... DB", + " Dump External Data Memory... DE [address]", + " Dump Internal Data Memory... DI [address]", + " Dump Program Memory......... DP [address]", + " Display Registers content... DR", + " Execute..................... EM [address" + " [number of instructions]]", + " Help........................ H", + " Modify External Data Memory. ME address value", + " Modify Internal Data Memory. MI address value", + " Modify Program Memory....... MP address value", + " Modify Register............. MR register value", + " Quit Emulator............... Q", + " Trace mode.................. T [address]", + " Unassemble.................. U [address]" + " [number of instructions]", + " Reset processor............. Z", 0 }; + + Index = 0; + while (Title[Index] != 0) + printf("%s%s", Title[Index++], ENDLINE); + + Index = 0; + while (Menu[Index] != 0) + printf("%s%s", Menu[Index++], ENDLINE); + + console_reset(); + + int QuitRequest = 0; + + while (!QuitRequest) { + int slen; + size_t len = 0; + ssize_t bytes_read; + char Command[256]; + char Args[256]; + char Parameter1[256]; + char Parameter2[256]; + + Parameter1[0] = '\0'; + Parameter2[0] = '\0'; + + printf(prompt); + bytes_read = getline(&line, &len, stdin); + Capitalize(line); + RemoveSpaces(line); + + /* Strip trailing newline */ + slen = strlen(line); + if (line[slen - 1] == '\n') + line[slen - 1] = '\0'; + + /* Find command-arguments delimiter */ + for (Index = 0; Index < strlen(line); Index++) { + if (isblank(line[Index])) + break; + } + + /* Keep only the Command part from the input line */ + memcpy(Command, &line[0], Index); + Command[Index] = '\0'; + + /* Keep only the arguments part from the input line */ + if (Index < strlen(line)) { + slen = strlen(line) - Index; + memcpy(Args, &line[Index + 1], slen); + } else { + slen = 0; + } + Args[slen] = '\0'; + RemoveSpaces(Args); + + /* Find multi-arguments delimiter */ + for (Index = 0; Index < strlen(Args); Index++) { + if (isblank(Args[Index])) + break; + } + + memcpy(Parameter1, &Args[0], Index); + Parameter1[Index] = '\0'; + + if (Index < strlen(Args)) { + slen = strlen(Args) - Index; + memcpy(Parameter2, &Args[Index + 1], slen); + } else { + slen = 0; + } + Parameter2[slen] = '\0'; + RemoveSpaces(Parameter2); + + if (strlen(Command) == 0) { + goto syntax_error; + continue; + } + + if ((strlen(Parameter1) > 4) || (strlen(Parameter2) > 4)) { + printf("Invalid Parameter Format!\n"); + continue; + } + + switch (Command[0]) { + case 'D': + if (strlen(Parameter2) == 0) { + if (STREQ(Command, "DB") && + (strlen(Parameter1) == 0)) + ShowBreakpoints(); + else if (STREQ(Command, "DE")) + DumpMem(Parameter1, EXT_MEM_ID); + else if (STREQ(Command, "DI")) + DumpMem(Parameter1, INT_MEM_ID); + else if (STREQ(Command, "DP")) { + if ((strlen(Parameter1) == 0)) + strcpy(Parameter1, "PC"); + DumpMem(Parameter1, PGM_MEM_ID); + } else if (STREQ(Command, "DR") && + (strlen(Parameter1) == 0)) + console_show_registers(); + else + goto syntax_error; + } else + goto syntax_error; + break; + case 'E': + if (STREQ(Command, "EM")) + console_exec(Parameter1, Parameter2); + else + goto syntax_error; + break; + case 'H': + if (STREQ(Command, "H") && (strlen(Parameter1) == 0) && + (strlen(Parameter2) == 0)) { + Index = 0; + while (Menu[Index] != 0) + printf("%s\n", Menu[Index++]); + } else + goto syntax_error; + break; + case 'M': + if ((strlen(Parameter1) == 0) || + (strlen(Parameter2) == 0)) + printf("Missing Parameter!\n"); + else if (STREQ(Command, "ME")) { + unsigned int adresse = Ascii2Hex(Parameter1, 4); + unsigned char valeur = Ascii2Hex(Parameter2, 2); + memory_write8(EXT_MEM_ID, adresse, valeur); + } else if (STREQ(Command, "MI")) { + unsigned int adresse = Ascii2Hex(Parameter1, 2); + unsigned char valeur = Ascii2Hex(Parameter2, 2); + memory_write8(INT_MEM_ID, adresse, valeur); + } else if (STREQ(Command, "MP")) { + unsigned int adresse = Ascii2Hex(Parameter1, 4); + unsigned char valeur = Ascii2Hex(Parameter2, 2); + memory_write8(PGM_MEM_ID, adresse, valeur); + } else if (STREQ(Command, "MR")) + SetRegister(Parameter1, Parameter2); + else + goto syntax_error; + break; + case 'Q': + if (STREQ(Command, "Q") && (strlen(Parameter1) == 0) && + (strlen(Parameter2) == 0)) + QuitRequest = 1; + else + goto syntax_error; + break; + case 'R': + if (strlen(Parameter2) != 0) + goto TooMuchParameters; + if (STREQ(Command, "RB")) { + if (strlen(Parameter1) == 0) + ClearBreakpoint(cpu8051.pc); + else + ClearBreakpoint( + Ascii2Hex(Parameter1, 4)); + } else + goto syntax_error; + break; + case 'S': + if (strlen(Parameter2) != 0) + goto TooMuchParameters; + + if (STREQ(Command, "SB")) { + if (strlen(Parameter1) == 0) + SetBreakpoint(cpu8051.pc); + else + SetBreakpoint(Ascii2Hex(Parameter1, 4)); + } else + goto syntax_error; + break; + case 'T': + if (strlen(Parameter2) != 0) + printf("Wrong Number of Parameters!\n"); + + if (STREQ(Command, "T")) + console_trace(Parameter1); + else + goto syntax_error; + break; + case 'U': + if (STREQ(Command, "U")) + Disasm(Parameter1, Parameter2); + else + goto syntax_error; + break; + case 'Z': + if (STREQ(Command, "Z") && (strlen(Parameter1) == 0) && + (strlen(Parameter2) == 0)) + cpu8051_Reset(); + else + goto syntax_error; + break; + case '\n': + break; + default: + goto syntax_error; + } + continue; + +syntax_error: + printf("Syntax Error!\n"); + continue; +TooMuchParameters: + printf("Wrong Number of Parameters!\n"); + continue; + } + + if (line) + free(line); +} + +int +main(int argc, char **argv) +{ + char *hex_file; + + ParseCommandLineOptions(argc, argv); + + cpu8051_init(); + + RunningState = 0; + NbBreakpoints = 0; + + hex_file = get_hex_filename(); + + if (hex_file != NULL) + LoadHexFile(hex_file); + + console_main(); + printf("End of program.\n"); + + return 0; +} diff --git a/src/emugtk.c b/src/emugtk.c index e1a8e0e..7d25174 100644 --- a/src/emugtk.c +++ b/src/emugtk.c @@ -23,16 +23,17 @@ #include "config.h" #include -#include "emugtk.h" -#include "reset.xpm" -#include "run.xpm" -#include "stop.xpm" -#include "step.xpm" #include "common.h" #include "cpu8051.h" #include "options.h" #include "hexfile.h" + +#include "emugtk.h" +#include "reset.xpm" +#include "run.xpm" +#include "stop.xpm" +#include "step.xpm" #include "filemenu.h" #include "viewmenu.h" #include "helpmenu.h" @@ -40,18 +41,10 @@ #include "pgmwin.h" #include "memwin.h" - static int RunningState; static int RunFuncTag; - - static GtkWidget *mainwin; - -/* In options.c */ -extern char *hex_file; - - /* Signal DestroyEvent */ static void WindowDestroyEvent( GtkWidget *widget, gpointer data ) @@ -210,6 +203,8 @@ emugtk_window_init( void ) int main( int argc, char **argv ) { + char *hex_file; + ParseCommandLineOptions( argc, argv ); cpu8051_init(); @@ -220,6 +215,8 @@ main( int argc, char **argv ) emugtk_window_init(); + hex_file = get_hex_filename(); + if( hex_file != NULL ) { emugtk_new_file( hex_file ); } @@ -406,14 +403,9 @@ emugtk_StartRunning( void ) #ifdef EMU8051_DEBUG printf( "emugtk_StartRunning( )\n" ); #endif - /*RunFuncTag = gtk_idle_add( GtkFunction( RunningFunction ), 0 );*/ RunFuncTag = gtk_idle_add( RunningFunction, 0 ); RunningState = 1; - - // gtk_widget_hide( GTK_WIDGET( ButtonRun ) ); - // gtk_widget_show_now( GTK_WIDGET( ButtonStop ) ); - // gtk_table_attach_defaults( GTK_TABLE( ButtonTable ), ButtonStop, 3, 4, 0, 1); } } @@ -430,9 +422,6 @@ emugtk_StopRunning( ) #endif gtk_idle_remove( RunFuncTag ); RunningState = 0; - //gtk_widget_hide( GTK_WIDGET( ButtonStop ) ); - //gtk_widget_show( GTK_WIDGET( ButtonRun ) ); - // gtk_table_attach_defaults( GTK_TABLE( ButtonTable ), ButtonRun, 3, 4, 0, 1); regwin_Show(); pgmwin_Disasm(); memwin_DumpD( 0 ); diff --git a/src/hexfile.c b/src/hexfile.c index a20b27f..0f473d4 100644 --- a/src/hexfile.c +++ b/src/hexfile.c @@ -36,121 +36,123 @@ #include "common.h" #include "memory.h" - /* Convert an ascii string to an hexadecimal number. */ -static unsigned int +unsigned int Ascii2Hex( char *istring, int length ) { - unsigned int result = 0; - int i, ascii_code; + unsigned int result = 0; + int i, ascii_code; - if ( !length || ( length > (int) strlen(istring) ) ) { - length = strlen(istring); - } + 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; + 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 ) { - int i, j, RecLength, LoadOffset, RecType, Data, Checksum; + int i, j, RecLength, LoadOffset, RecType, Data, Checksum; #define LINE_BUFFER_LEN 256 - FILE *fp; - int status; - char line[LINE_BUFFER_LEN]; + 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 (filename == NULL) { + printf("%s: No file specified\n", PACKAGE); + exit(EXIT_FAILURE); + } + + /* 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 hex 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; - } + if ( line[ i++ ] != ':' ) { + printf( "%s: line not beginning with \":\"\n", PACKAGE ); + goto close_file; + } - RecLength = Ascii2Hex( &line[ i ], 2 ); - i += 2; - Checksum += RecLength; + RecLength = Ascii2Hex( &line[ i ], 2 ); + i += 2; + Checksum += RecLength; - LoadOffset = Ascii2Hex( &line[i], 4 ); - Checksum += LoadOffset / 256; - Checksum += LoadOffset % 256; - i += 4; + LoadOffset = Ascii2Hex( &line[i], 4 ); + Checksum += LoadOffset / 256; + Checksum += LoadOffset % 256; + i += 4; - RecType = Ascii2Hex( &line[i],2); - i += 2; - Checksum += RecType; + 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; - } - } + 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 ); - memory_write8( PGM_MEM_ID, (unsigned int)(LoadOffset + j), (unsigned char)Data ); - i += 2; - Checksum += Data; - } + for ( j = 0; j < RecLength; j++ ) { + Data = Ascii2Hex( &line[ i ], 2 ); + memory_write8( PGM_MEM_ID, (unsigned int)(LoadOffset + j), (unsigned char)Data ); + i += 2; + Checksum += Data; + } - RecType = Ascii2Hex( &line[ i ], 2 ); - Checksum += RecType; + RecType = Ascii2Hex( &line[ i ], 2 ); + Checksum += RecType; - if ( Checksum &= 0x000000FF ) { - printf( "%s: Invalid format\n", PACKAGE ); - goto close_file; - } - } + 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 ); - } +close_file: + status = fclose( fp ); + if( status != EXIT_SUCCESS ) { + fprintf( stderr, "%s: Error closing hex file.\n", PACKAGE ); + /*ErrorLocation( __FILE__, __LINE__ );*/ + exit( EXIT_FAILURE ); + } } diff --git a/src/hexfile.h b/src/hexfile.h index 8bfb646..4795bf8 100644 --- a/src/hexfile.h +++ b/src/hexfile.h @@ -22,9 +22,10 @@ #ifndef HEXFILE_H #define HEXFILE_H 1 +unsigned int +Ascii2Hex(char *istring, int length); void LoadHexFile( const char *filename ); - #endif /* HEXFILE_H */ diff --git a/src/Keyboard.hpp b/src/keyboard.c similarity index 56% rename from src/Keyboard.hpp rename to src/keyboard.c index bb993da..e46568a 100644 --- a/src/Keyboard.hpp +++ b/src/keyboard.c @@ -1,5 +1,5 @@ /* - * Keyboard.hpp + * keyboard.c * * Copyright (C) 1999 Jonathan St-André * Copyright (C) 1999 Hugo Villeneuve @@ -19,60 +19,58 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef _KEYBOARD_HPP_ -#define _KEYBOARD_HPP_ - #include #include static struct termios orig, newtio; static int peek = -1; -int kbhit() +int +kbhit(void) { - char ch; - int nread; - if(peek != -1) return 1; - newtio.c_cc[VMIN]=0; - tcsetattr(0, TCSANOW, &newtio); - nread = read(0,&ch,1); - newtio.c_cc[VMIN]=1; - tcsetattr(0, TCSANOW, &newtio); - if(nread == 1) { - peek = ch; - return 1; - } - return 0; + char ch; + int nread; + if(peek != -1) return 1; + newtio.c_cc[VMIN]=0; + tcsetattr(0, TCSANOW, &newtio); + nread = read(0,&ch,1); + newtio.c_cc[VMIN]=1; + tcsetattr(0, TCSANOW, &newtio); + if(nread == 1) { + peek = ch; + return 1; + } + return 0; } -int getch() +int +getch(void) { - char ch; - if(peek != -1) { - ch = peek; - peek = -1; - return ch; - } - read(0,&ch,1); - return ch; + char ch; + if(peek != -1) { + ch = peek; + peek = -1; + return ch; + } + read(0,&ch,1); + return ch; } -void InitUnixKB( ) +void +InitUnixKB(void) { - tcgetattr(0, &orig); - newtio = orig; - newtio.c_lflag &= ~ICANON; - newtio.c_lflag &= ~ECHO; - newtio.c_lflag &= ~ISIG; - newtio.c_cc[VMIN] = 1; - newtio.c_cc[VTIME] = 0; - tcsetattr(0, TCSANOW, &newtio); + tcgetattr(0, &orig); + newtio = orig; + newtio.c_lflag &= ~ICANON; + newtio.c_lflag &= ~ECHO; + newtio.c_lflag &= ~ISIG; + newtio.c_cc[VMIN] = 1; + newtio.c_cc[VTIME] = 0; + tcsetattr(0, TCSANOW, &newtio); } -void ResetUnixKB( ) +void +ResetUnixKB(void) { - tcsetattr(0,TCSANOW, &orig); + tcsetattr(0,TCSANOW, &orig); } - -#endif - diff --git a/src/hexfile.h b/src/keyboard.h similarity index 84% copy from src/hexfile.h copy to src/keyboard.h index 8bfb646..8660616 100644 --- a/src/hexfile.h +++ b/src/keyboard.h @@ -1,5 +1,5 @@ /* - * hexfile.h + * keyboard.h * * Copyright (C) 1999 Jonathan St-André * Copyright (C) 1999 Hugo Villeneuve @@ -19,12 +19,19 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef HEXFILE_H -#define HEXFILE_H 1 +#ifndef _KEYBOARD_H_ +#define _KEYBOARD_H_ +int +kbhit(void); + +int +getch(void); void -LoadHexFile( const char *filename ); +InitUnixKB(void); +void +ResetUnixKB(void); -#endif /* HEXFILE_H */ +#endif /* _KEYBOARD_H_ */ diff --git a/src/memory.c b/src/memory.c index eb2b4f3..922b9aa 100644 --- a/src/memory.c +++ b/src/memory.c @@ -19,103 +19,90 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "memory.h" +#include +#include "memory.h" -#define SFR_MEM_SIZE 128 #define PGM_MEM_SIZE 65536 -#define INT_MEM_SIZE 128 +#define INT_MEM_SIZE 256 /* IRAM = Direct addresses $00 to $7F + * SFR = Direct addresses $80 to $FF */ #define EXT_MEM_SIZE 65536 - -static u_int8_t sfr_mem[SFR_MEM_SIZE]; static u_int8_t pgm_mem[PGM_MEM_SIZE]; static u_int8_t int_mem[INT_MEM_SIZE]; static u_int8_t ext_mem[EXT_MEM_SIZE]; - void memory_write8( int memory_id, unsigned long address, u_int8_t value ) { - switch( memory_id ) { - case SFR_MEM_ID: - if( address >= SFR_MEM_SIZE ) { - return; - } - else { - sfr_mem[address] = value; - } - break; - case PGM_MEM_ID: - if( address >= PGM_MEM_SIZE ) { - return; - } - else { - pgm_mem[address] = value; - } - break; - case INT_MEM_ID: - if( address >= INT_MEM_SIZE ) { - return; - } - else { - int_mem[address] = value; - } - break; - case EXT_MEM_ID: - if( address >= EXT_MEM_SIZE ) { - return; - } - else { - ext_mem[address] = value; - } - break; - default: - /* Error. */ - break; - } + switch( memory_id ) { + case PGM_MEM_ID: + if( address >= PGM_MEM_SIZE ) { + printf("Address is greater than PGM_MEM_SIZE\n"); + return; + } + else { + pgm_mem[address] = value; + } + break; + case INT_MEM_ID: + if( address >= INT_MEM_SIZE) { + printf("Address is greater than INT_MEM_SIZE\n"); + return; + } + else { + int_mem[address] = value; + } + break; + case EXT_MEM_ID: + if( address >= EXT_MEM_SIZE ) { + printf("Address is greater than EXT_MEM_SIZE\n"); + return; + } + else { + ext_mem[address] = value; + } + break; + default: + /* Error. */ + break; + } } - u_int8_t memory_read8( int memory_id, unsigned long address ) { - switch( memory_id ) { - case SFR_MEM_ID: - if( address < SFR_MEM_SIZE ) { - return sfr_mem[address]; - } - else { - return 0; - } - break; - case PGM_MEM_ID: - if( address < PGM_MEM_SIZE ) { - return pgm_mem[address]; - } - else { - return 0; - } - break; - case INT_MEM_ID: - if( address < INT_MEM_SIZE ) { - return int_mem[address]; - } - else { - return 0; - } - break; - case EXT_MEM_ID: - if( address < EXT_MEM_SIZE ) { - return ext_mem[address]; - } - else { - return 0; - } - break; - default: - /* Error. */ - return 0; - break; - } + switch( memory_id ) { + case PGM_MEM_ID: + if( address < PGM_MEM_SIZE ) { + return pgm_mem[address]; + } + else { + printf("Address is greater than PGM_MEM_SIZE\n"); + return 0; + } + break; + case INT_MEM_ID: + if( address < INT_MEM_SIZE ) { + return int_mem[address]; + } + else { + printf("Address is greater than INT_MEM_SIZE\n"); + return 0; + } + break; + case EXT_MEM_ID: + if( address < EXT_MEM_SIZE ) { + return ext_mem[address]; + } + else { + printf("Address is greater than EXT_MEM_SIZE\n"); + return 0; + } + break; + default: + /* Error. */ + return 0; + break; + } } diff --git a/src/memory.h b/src/memory.h index 9b8fa04..76c0b86 100644 --- a/src/memory.h +++ b/src/memory.h @@ -22,23 +22,18 @@ #ifndef MEMORY_H #define MEMORY_H 1 - #include - enum { - SFR_MEM_ID, PGM_MEM_ID, INT_MEM_ID, EXT_MEM_ID }; - void memory_write8( int memory_id, unsigned long address, u_int8_t value ); u_int8_t memory_read8( int memory_id, unsigned long address ); - #endif /* MEMORY_H */ diff --git a/src/options.c b/src/options.c index 7b3b183..3caf9f6 100644 --- a/src/options.c +++ b/src/options.c @@ -35,9 +35,16 @@ #include "common.h" #include "options.h" +static char *hex_file; -char *hex_file; - +/* + * Return the hex file name + */ +char * +get_hex_filename(void) +{ + return hex_file; +} /******************************************************************************* * Display the help message and exit diff --git a/src/options.h b/src/options.h index d84a989..8e8dfde 100644 --- a/src/options.h +++ b/src/options.h @@ -21,7 +21,6 @@ #ifndef OPTIONS_H #define OPTIONS_H 1 - #define COMMAND_LINE_OPTIONS \ "Usage: " PACKAGE " [OPTION]... [FILENAME]\n" \ "Simulator/emulator for 8051 family microcontrollers.\n\n" \ @@ -37,9 +36,10 @@ "Jonathan St-André\n" \ "Pascal Fecteau" - void -ParseCommandLineOptions( int argc, char *argv[] ); +ParseCommandLineOptions(int argc, char *argv[]); +char * +get_hex_filename(void); #endif /* OPTIONS_H */ -- 2.20.1