1 /*
2    Copyright (C) 1999 T. Scott Dattalo
3 
4 This file is part of gpsim.
5 
6 gpsim is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10 
11 gpsim is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with gpsim; see the file COPYING.  If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.  */
20 
21 
22 #include <iostream>
23 #include <typeinfo>
24 
25 #include "cmd_x.h"
26 #include "cmd_dump.h"
27 #include "misc.h"
28 
29 #include "../src/expr.h"
30 #include "../src/processor.h"
31 #include "../src/registers.h"
32 #include "../src/ui.h"
33 #include "../src/value.h"
34 
35 cmd_x c_x;
36 
37 static cmd_options cmd_x_options[] = {
38   {nullptr, 0, 0}
39 };
40 
41 
cmd_x()42 cmd_x::cmd_x()
43   : command("x", nullptr)
44 {
45   brief_doc = "[deprecated] examine and/or modify memory";
46   long_doc = "\nx examine command -- deprecated\n"
47              "\tInstead of the using a special command to examine and modify\n"
48              "\tvariables, it's possible to directly access them using gpsim's\n"
49              "\texpression parsing. For example, to examine a variable:\n"
50              "gpsim> my_variable\n"
51              "my_variable [0x27] = 0x00 = 0b00000000\n"
52              "\tTo modify a variable\n"
53              "gpsim> my_variable = 10\n"
54              "\tIt's also possible to assign the value of register to another\n"
55              "gpsim> my_variable = porta\n"
56              "\tOr to assign the results of an expression:\n"
57              "gpsim> my_variable = (porta ^ portc) & 0x0f\n";
58   /*
59   long_doc = string ("\nx [file_register] [new_value]\n\
60   \toptions:\n\
61   \t\tfile_register - ram location to be examined or modified.\n\
62   \t\tnew_value - the new value written to the file_register.\n\
63   \t\tif no options are specified, then the entire contents\n\
64   \t\tof the file registers will be displayed (dump).\n\
65   ");
66   */
67   op = cmd_x_options;
68 }
69 
70 
x()71 void cmd_x::x()
72 {
73   dump.dump(cmd_dump::DUMP_RAM);
74 
75   if (GetActiveCPU()) {
76     GetActiveCPU()->dump_registers();
77   }
78 }
79 
80 
x(int reg,Expression * pExpr)81 void cmd_x::x(int reg, Expression *pExpr)
82 {
83   if (!GetActiveCPU()) {
84     return;
85   }
86 
87   if (reg < 0 || (reg >= (int)GetActiveCPU()->register_memory_size())) {
88     GetUserInterface().DisplayMessage("bad file register\n");
89     return;
90   }
91 
92   Register *pReg = GetActiveCPU()->registers[reg];
93   RegisterValue rvCurrent(pReg->getRVN());
94 
95   if (pExpr == nullptr) {
96     char str[33];
97     // Display value
98     const char * pAddr = GetUserInterface().FormatRegisterAddress(
99                            reg, GetActiveCPU()->m_uAddrMask);
100     const char * pValue = GetUserInterface().FormatValue(
101                             rvCurrent.data, GetActiveCPU()->register_mask());
102     GetUserInterface().DisplayMessage("%s[%s] = %s = 0b%s\n",
103                                       pReg->name().c_str(), pAddr, pValue,
104                                       pReg->toBitStr(str, sizeof(str)));
105 
106   } else {
107     // Assign value
108     Value *pValue = pExpr->evaluate();
109 
110     if (pValue != nullptr) {
111       Integer * pInt = dynamic_cast<Integer*>(pValue);
112 
113       if (pValue != nullptr) {
114         char str[33];
115         pReg->toBitStr(str, sizeof(str));
116         RegisterValue value(
117           GetActiveCPU()->register_mask() & (unsigned int)pInt->getVal(), 0);
118         pReg->putRV(value);
119         // Notify listeners
120         pReg->update();
121         // Display new value
122         x(reg);
123         // Display old value
124         const char * pValue = GetUserInterface().FormatValue(
125                                 (gint64)rvCurrent.get(), GetActiveCPU()->register_mask());
126         GetUserInterface().DisplayMessage("was %s = 0b%s\n",
127                                           pValue, str);
128 
129       } else {
130         GetUserInterface().DisplayMessage(
131           "Error: the expression did not evaluate to on integer");
132       }
133 
134       delete pValue;
135 
136     } else {
137       GetUserInterface().DisplayMessage("Error evaluating the expression");
138     }
139 
140     delete pExpr;
141   }
142 }
143 
144 
x(char * reg_name)145 void cmd_x::x(char *reg_name)
146 {
147   std::cout << "this command is deprecated. "
148             << "Type '" << reg_name << "' at the command line to display the contents of a register.\n";
149   // get_symbol_table().dump_one(reg_name);
150 }
151 
152 
x(char *,int)153 void cmd_x::x(char * /* reg_name */, int /* val */)
154 {
155   std::cout << "this command is deprecated. use: \n  symbol_name = value\n\ninstead\n";
156   //  update_symbol_value(reg_name,val);
157 }
158 
159 
x(Expression * expr)160 void cmd_x::x(Expression *expr)
161 {
162   /*
163   try {
164 
165     Value *v = toValue(expr);
166     cout << v->toString() << endl;
167 
168     if(typeid(register_symbol) == typeid(*v) ||
169       (typeid(LiteralSymbol) == typeid(*expr) &&
170       !((LiteralSymbol*)expr)->toString().empty() )) {
171       // v->toString() dumped the value to cout
172     }
173     else if(typeid(Integer) == typeid(*v)) {
174         int i;
175         v->get(i);
176         x(i);
177     }
178     else if(typeid(AbstractRange) == typeid(*v)) {
179       unsigned int i = v->get_leftVal();
180       while (i<=v->get_rightVal()) {
181         x(i);
182         i++;
183       }
184     }
185 
186     delete v;
187     delete expr;
188   }
189 
190 
191   catch (Error *err) {
192     if(err)
193       cout << "ERROR:" << err->toString() << endl;
194     delete err;
195   }
196   */
197   delete expr;
198 }
199