/*
Copyright (C) 1999 T. Scott Dattalo
This file is part of gpsim.
gpsim 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, or (at your option)
any later version.
gpsim 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 gpsim; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <iostream>
#include <iomanip>
#include <string>
#include "command.h"
#include "cmd_x.h"
#include "cmd_dump.h"
#include "../src/cmd_gpsim.h"
#include "../src/pic-processor.h"
#include "../src/symbol.h"
cmd_x c_x;
static cmd_options cmd_x_options[] =
{
{0,0,0}
};
cmd_x::cmd_x(void)
{
name = "x";
brief_doc = string("[deprecated] examine and/or modify memory");
long_doc = string ("\nx examine command -- deprecated\n\
\tInstead of the using a special command to examine and modify\n\
\tvariables, it's possible to directly access them using gpsim's\n\
\texpression parsing. For example, to examine a variable:\n\
gpsim> my_variable\n\
my_variable [0x27] = 0x00 = 0b00000000\n\
\tTo modify a variable\n\
gpsim> my_variable = 10\n\
\tIt's also possible to assign the value of register to another\n\
gpsim> my_variable = porta\n\
\tOr to assign the results of an expression:\n\
gpsim> my_variable = (porta ^ portc) & 0x0f\n");
/*
long_doc = string ("\nx [file_register] [new_value]\n\
\toptions:\n\
\t\tfile_register - ram location to be examined or modified.\n\
\t\tnew_value - the new value written to the file_register.\n\
\t\tif no options are specified, then the entire contents\n\
\t\tof the file registers will be displayed (dump).\n\
");
*/
op = cmd_x_options;
}
void cmd_x::x(void)
{
dump.dump(cmd_dump::DUMP_RAM);
if(GetActiveCPU())
GetActiveCPU()->dump_registers();
}
void cmd_x::x(int reg, Expression *pExpr)
{
if(!GetActiveCPU())
return;
if(reg<0 || (reg >= (int)GetActiveCPU()->register_memory_size()) )
{
GetUserInterface().DisplayMessage("bad file register\n");
return;
}
Register *pReg = GetActiveCPU()->registers[reg];
RegisterValue rvCurrent(pReg->getRVN());
if(pExpr == NULL) {
char str[33];
// Display value
const char * pAddr = GetUserInterface().FormatRegisterAddress(
reg, GetActiveCPU()->m_uAddrMask);
const char * pValue = GetUserInterface().FormatValue(
rvCurrent.data, GetActiveCPU()->register_mask());
GetUserInterface().DisplayMessage("%s[%s] = %s = 0b%s\n",
pReg->name().c_str(), pAddr, pValue,
pReg->toBitStr(str,sizeof(str)));
}
else {
// Assign value
Value *pValue = pExpr->evaluate();
if(pValue != NULL) {
Integer * pInt = dynamic_cast<Integer*>(pValue);
if(pValue != NULL) {
char str[33];
pReg->toBitStr(str,sizeof(str));
RegisterValue value(
GetActiveCPU()->register_mask() & (unsigned int)pInt->getVal(), 0);
pReg->putRV(value);
// Notify listeners
pReg->update();
// Display new value
x(reg);
// Display old value
const char * pValue = GetUserInterface().FormatValue(
(gint64)rvCurrent.get(), GetActiveCPU()->register_mask());
GetUserInterface().DisplayMessage("was %s = 0b%s\n",
pValue, str);
}
else {
GetUserInterface().DisplayMessage(
"Error: the expression did not evaluate to on integer");
}
delete pValue;
}
else {
GetUserInterface().DisplayMessage("Error evaluating the expression");
}
delete pExpr;
}
}
void cmd_x::x(char *reg_name)
{
get_symbol_table().dump_one(reg_name);
}
void cmd_x::x(char *reg_name, int val)
{
cout << "this command is deprecated. use: \n symbol_name = value\n\ninstead\n";
// update_symbol_value(reg_name,val);
}
void cmd_x::x(Expression *expr)
{
try {
Value *v = toValue(expr);
cout << v->toString() << endl;
if(typeid(register_symbol) == typeid(*v) ||
(typeid(LiteralSymbol) == typeid(*expr) &&
!((LiteralSymbol*)expr)->toString().empty() )) {
// v->toString() dumped the value to cout
}
else if(typeid(Integer) == typeid(*v)) {
int i;
v->get(i);
x(i);
}
else if(typeid(AbstractRange) == typeid(*v)) {
unsigned int i = v->get_leftVal();
while (i<=v->get_rightVal()) {
x(i);
i++;
}
}
delete v;
delete expr;
}
catch (Error *err) {
if(err)
cout << "ERROR:" << err->toString() << endl;
delete err;
}
}
syntax highlighted by Code2HTML, v. 0.9.1