SUBDIRS = src doc
+## We want these in the dist tarball
EXTRA_DIST = autogen.sh \
$(ac_aux_dir)/debug.m4 \
pixmaps \
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
# 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.
AC_TYPE_SIZE_T
dnl Basic CFLAGS values
-CFLAGS="-Wall"
+CFLAGS="${CFLAGS} -Wall"
dnl Checks for '--enable-debug' option
HV_CHECK_FOR_DEBUG
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)
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"
+++ /dev/null
-/*
- * EmuConsole.cpp
- *
- * Copyright (C) 1999 Jonathan St-André
- * Copyright (C) 1999 Hugo Villeneuve <hugo@hugovil.com>
- *
- * 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 <stdio.h>
-#include <iostream>
-#include <fstream>
-#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 );
-
-}
using namespace std;
-// Maximum number of BreakPoints
-#define MAXBP 32
-
-#define ENDLINE "\n"
-
-
//////////////////////////////////////////////////////////////////////////////
// EmuConsole
+++ /dev/null
-/*
- * Keyboard.hpp
- *
- * Copyright (C) 1999 Jonathan St-André
- * Copyright (C) 1999 Hugo Villeneuve <hugo@hugovil.com>
- *
- * 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.
- */
-
-#ifndef _KEYBOARD_HPP_
-#define _KEYBOARD_HPP_
-
-#include <termios.h>
-#include <unistd.h>
-
-static struct termios orig, newtio;
-static int peek = -1;
-
-int kbhit()
-{
- 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()
-{
- char ch;
- if(peek != -1) {
- ch = peek;
- peek = -1;
- return ch;
- }
- read(0,&ch,1);
- return ch;
-}
-
-void InitUnixKB( )
-{
- 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( )
-{
- tcsetattr(0,TCSANOW, &orig);
-}
-
-#endif
-
$(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
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 $<
/* 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
/* Define only here, for not having extern scope on local variables. */
#define CPU8051_M 1
-
#include <stdio.h>
#include "reg8051.h"
#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[]
// 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;
}
/*
- * emu8051.h
+ * cpu8051.h
*
* Copyright (C) 1999 Jonathan St-André
* Copyright (C) 1999 Hugo Villeneuve <hugo@hugovil.com>
#ifndef CPU8051_H
#define CPU8051_H 1
-
typedef struct cpu8051_t
{
unsigned int pc;
int active_priority;
} cpu8051_t;
-
/* Exported variables */
#undef _SCOPE_
#ifdef CPU8051_M
_SCOPE_ cpu8051_t cpu8051;
-
void
cpu8051_init( 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 */
--- /dev/null
+/*
+ * emuconsole.c
+ *
+ * Copyright (C) 1999 Jonathan St-André
+ * Copyright (C) 1999 Hugo Villeneuve <hugo@hugovil.com>
+ *
+ * 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 <stdio.h>
+#include <string.h>
+#include <ctype.h> /* 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;
+}
#include "config.h"
#include <gtk/gtk.h>
-#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"
#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 )
int
main( int argc, char **argv )
{
+ char *hex_file;
+
ParseCommandLineOptions( argc, argv );
cpu8051_init();
emugtk_window_init();
+ hex_file = get_hex_filename();
+
if( hex_file != NULL ) {
emugtk_new_file( hex_file );
}
#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);
}
}
#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 );
#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 );
+ }
}
#ifndef HEXFILE_H
#define HEXFILE_H 1
+unsigned int
+Ascii2Hex(char *istring, int length);
void
LoadHexFile( const char *filename );
-
#endif /* HEXFILE_H */
--- /dev/null
+/*
+ * keyboard.c
+ *
+ * Copyright (C) 1999 Jonathan St-André
+ * Copyright (C) 1999 Hugo Villeneuve <hugo@hugovil.com>
+ *
+ * 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 <termios.h>
+#include <unistd.h>
+
+static struct termios orig, newtio;
+static int peek = -1;
+
+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;
+}
+
+int
+getch(void)
+{
+ char ch;
+ if(peek != -1) {
+ ch = peek;
+ peek = -1;
+ return ch;
+ }
+ read(0,&ch,1);
+ return ch;
+}
+
+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);
+}
+
+void
+ResetUnixKB(void)
+{
+ tcsetattr(0,TCSANOW, &orig);
+}
--- /dev/null
+/*
+ * keyboard.h
+ *
+ * Copyright (C) 1999 Jonathan St-André
+ * Copyright (C) 1999 Hugo Villeneuve <hugo@hugovil.com>
+ *
+ * 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.
+ */
+
+#ifndef _KEYBOARD_H_
+#define _KEYBOARD_H_
+
+int
+kbhit(void);
+
+int
+getch(void);
+
+void
+InitUnixKB(void);
+
+void
+ResetUnixKB(void);
+
+#endif /* _KEYBOARD_H_ */
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#include "memory.h"
+#include <stdio.h>
+#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;
+ }
}
#ifndef MEMORY_H
#define MEMORY_H 1
-
#include <sys/types.h>
-
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 */
#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
#ifndef OPTIONS_H
#define OPTIONS_H 1
-
#define COMMAND_LINE_OPTIONS \
"Usage: " PACKAGE " [OPTION]... [FILENAME]\n" \
"Simulator/emulator for 8051 family microcontrollers.\n\n" \
"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 */