1
0
mirror of https://git.code.sf.net/p/fuse-emulator/fuse synced 2026-01-27 01:41:34 +03:00
Files
fuse/debugger/command.c
Philip Kendall f5e7fd470c Fix gcc 4.4 warnings.
Legacy-ID: 4125
2010-05-06 22:18:50 +00:00

287 lines
7.0 KiB
C

/* command.c: Parse a debugger command
Copyright (c) 2002-2008 Philip Kendall
$Id$
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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
Author contact information:
E-mail: philip-fuse@shadowmagic.org.uk
*/
#include <config.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include "debugger.h"
#include "debugger_internals.h"
#include "mempool.h"
#include "ui/ui.h"
#include "z80/z80.h"
#include "z80/z80_macros.h"
/* The last debugger command we were given to execute */
static char *command_buffer = NULL;
/* And a pointer as to how much we've parsed */
static char *command_ptr;
int yyparse( void );
int yywrap( void );
/* Evaluate the debugger command given in 'command' */
int
debugger_command_evaluate( const char *command )
{
if( !command ) return 0;
if( command_buffer ) free( command_buffer );
command_buffer = strdup( command );
if( !command_buffer ) {
ui_error( UI_ERROR_ERROR, "Out of memory at %s:%d", __FILE__, __LINE__ );
return 1;
}
/* Start parsing at the start of the given command */
command_ptr = command_buffer;
/* Parse the command */
yyparse();
/* And free any memory we allocated while parsing */
mempool_free( debugger_memory_pool );
ui_debugger_update();
return 0;
}
/* Utility functions called from the flex scanner */
int
yywrap( void )
{
return 1;
}
/* Called to get up to 'max_size' bytes of the command to be parsed */
int
debugger_command_input( char *buf, int *result, int max_size )
{
size_t length = strlen( command_ptr );
if( !length ) {
return 0;
} else if( length < (size_t)max_size ) {
memcpy( buf, command_ptr, length );
*result = length; command_ptr += length;
return 1;
} else {
memcpy( buf, command_ptr, max_size );
*result = max_size; command_ptr += max_size;
return 1;
}
}
/* Convert a register name to a useful index value */
int
debugger_register_hash( const char *name )
{
int hash = 0x0000, primed = 0;
size_t length;
const char *ptr;
length = strlen( name );
if( name[ length - 1 ] == '\'' ) { primed = 1; length--; }
for( ptr = name; ptr < name + length; ptr++ ) {
hash <<= 8; hash |= tolower( *ptr );
}
if( primed ) hash |= 0x8000;
switch( hash ) {
case 0x0061: case 0x8061: /* A, A' */
case 0x0066: case 0x8066: /* F, F' */
case 0x0062: case 0x8062: /* B, B' */
case 0x0063: case 0x8063: /* C, C' */
case 0x0064: case 0x8064: /* D, D' */
case 0x0065: case 0x8065: /* E, E' */
case 0x0068: case 0x8068: /* H, H' */
case 0x006c: case 0x806c: /* L, L' */
case 0x6166: case 0xe166: /* AF, AF' */
case 0x6263: case 0xe263: /* BC, BC' */
case 0x6465: case 0xe465: /* DE, DE' */
case 0x686c: case 0xe86c: /* HL, HL' */
case 0x7370: /* SP */
case 0x7063: /* PC */
case 0x6978: /* IX */
case 0x6979: /* IY */
return hash;
default: return -1;
}
}
/* Utility functions called by the bison parser */
/* The error callback if yyparse finds an error */
void
yyerror( const char *s )
{
ui_error( UI_ERROR_ERROR, "Invalid debugger command: %s", s );
}
/* Get the value of a register */
libspectrum_word
debugger_register_get( int which )
{
switch( which ) {
/* 8-bit registers */
case 0x0061: return A;
case 0x8061: return A_;
case 0x0066: return F;
case 0x8066: return F_;
case 0x0062: return B;
case 0x8062: return B_;
case 0x0063: return C;
case 0x8063: return C_;
case 0x0064: return D;
case 0x8064: return D_;
case 0x0065: return E;
case 0x8065: return E_;
case 0x0068: return H;
case 0x8068: return H_;
case 0x006c: return L;
case 0x806c: return L_;
/* 16-bit registers */
case 0x6166: return AF;
case 0xe166: return AF_;
case 0x6263: return BC;
case 0xe263: return BC_;
case 0x6465: return DE;
case 0xe465: return DE_;
case 0x686c: return HL;
case 0xe86c: return HL_;
case 0x7370: return SP;
case 0x7063: return PC;
case 0x6978: return IX;
case 0x6979: return IY;
default:
ui_error( UI_ERROR_ERROR, "attempt to get unknown register '%d'", which );
return 0;
}
}
/* Set the value of a register */
void
debugger_register_set( int which, libspectrum_word value )
{
switch( which ) {
/* 8-bit registers */
case 0x0061: A = value; break;
case 0x8061: A_ = value; break;
case 0x0066: F = value; break;
case 0x8066: F_ = value; break;
case 0x0062: B = value; break;
case 0x8062: B_ = value; break;
case 0x0063: C = value; break;
case 0x8063: C_ = value; break;
case 0x0064: D = value; break;
case 0x8064: D_ = value; break;
case 0x0065: E = value; break;
case 0x8065: E_ = value; break;
case 0x0068: H = value; break;
case 0x8068: H_ = value; break;
case 0x006c: L = value; break;
case 0x806c: L_ = value; break;
/* 16-bit registers */
case 0x6166: AF = value; break;
case 0xe166: AF_ = value; break;
case 0x6263: BC = value; break;
case 0xe263: BC_ = value; break;
case 0x6465: DE = value; break;
case 0xe465: DE_ = value; break;
case 0x686c: HL = value; break;
case 0xe86c: HL_ = value; break;
case 0x7370: SP = value; break;
case 0x7063: PC = value; break;
case 0x6978: IX = value; break;
case 0x6979: IY = value; break;
default:
ui_error( UI_ERROR_ERROR, "attempt to set unknown register '%d'", which );
break;
}
}
/* Get the textual representation of a register */
const char *
debugger_register_text( int which )
{
switch( which ) {
/* 8-bit registers */
case 0x0061: return "A";
case 0x8061: return "A'";
case 0x0066: return "F";
case 0x8066: return "F'";
case 0x0062: return "B";
case 0x8062: return "B'";
case 0x0063: return "C";
case 0x8063: return "C'";
case 0x0064: return "D";
case 0x8064: return "D'";
case 0x0065: return "E";
case 0x8065: return "E'";
case 0x0068: return "H";
case 0x8068: return "H'";
case 0x006c: return "L";
case 0x806c: return "L'";
/* 16-bit registers */
case 0x6166: return "AF";
case 0xe166: return "AF'";
case 0x6263: return "BC";
case 0xe263: return "BC'";
case 0x6465: return "DE";
case 0xe465: return "DE'";
case 0x686c: return "HL";
case 0xe86c: return "HL'";
case 0x7370: return "SP";
case 0x7063: return "PC";
case 0x6978: return "IX";
case 0x6979: return "IY";
default:
ui_error( UI_ERROR_ERROR, "attempt to get unknown register '%d'", which );
return "(invalid)";
}
}