OpenCores
URL https://opencores.org/ocsvn/w11/w11/trunk

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.6/] [tools/] [src/] [librwxxtpp/] [RtclRw11Cpu.cpp] - Blame information for rev 21

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 21 wfjm
// $Id: RtclRw11Cpu.cpp 513 2013-05-01 14:02:06Z mueller $
2 19 wfjm
//
3
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4
//
5
// This program is free software; you may redistribute and/or modify it under
6
// the terms of the GNU General Public License as published by the Free
7
// Software Foundation, either version 2, or at your option any later version.
8
//
9
// This program is distributed in the hope that it will be useful, but
10
// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
11
// or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
// for complete details.
13
// 
14
// Revision History: 
15
// Date         Rev Version  Comment
16 20 wfjm
// 2013-04-26   511   1.0.1  add M_show
17 19 wfjm
// 2013-04-02   502   1.0    Initial version
18
// 2013-02-02   480   0.1    First draft
19
// ---------------------------------------------------------------------------
20
 
21
/*!
22
  \file
23 21 wfjm
  \version $Id: RtclRw11Cpu.cpp 513 2013-05-01 14:02:06Z mueller $
24 19 wfjm
  \brief   Implemenation of RtclRw11Cpu.
25
*/
26
 
27
#include <unistd.h>
28
#include <errno.h>
29
#include <stdio.h>
30
#include <stdlib.h>
31
#include <sys/wait.h>
32
 
33
#include <vector>
34
#include <memory>
35
#include <sstream>
36
 
37
#include "boost/bind.hpp"
38 20 wfjm
#include "boost/thread/locks.hpp"
39 19 wfjm
 
40
#include "librtools/RerrMsg.hpp"
41
#include "librtools/RlogMsg.hpp"
42
#include "librtools/RosPrintf.hpp"
43
#include "librtools/RosPrintBvi.hpp"
44
#include "librtcltools/Rtcl.hpp"
45
#include "librtcltools/RtclStats.hpp"
46
#include "librtcltools/RtclOPtr.hpp"
47
#include "librtcltools/RtclNameSet.hpp"
48
#include "librlink/RlinkCommandList.hpp"
49
 
50
#include "RtclRw11.hpp"
51
 
52
#include "RtclRw11CntlFactory.hpp"
53
#include "librw11/Rw11Cntl.hpp"
54
 
55
#include "RtclRw11Cpu.hpp"
56
 
57
using namespace std;
58
 
59
/*!
60
  \class Retro::RtclRw11Cpu
61
  \brief FIXME_docs
62
*/
63
 
64
// all method definitions in namespace Retro
65
namespace Retro {
66
 
67
//------------------------------------------+-----------------------------------
68
//! Default constructor
69
 
70
RtclRw11Cpu::RtclRw11Cpu(const std::string& type)
71
  : RtclProxyBase(type),
72
    fGets()
73
{
74
  AddMeth("add",      boost::bind(&RtclRw11Cpu::M_add,     this, _1));
75
  AddMeth("cp",       boost::bind(&RtclRw11Cpu::M_cp,      this, _1));
76
  AddMeth("wtcpu",    boost::bind(&RtclRw11Cpu::M_wtcpu,   this, _1));
77
  AddMeth("deposit",  boost::bind(&RtclRw11Cpu::M_deposit, this, _1));
78
  AddMeth("examine",  boost::bind(&RtclRw11Cpu::M_examine, this, _1));
79
  AddMeth("lsmem",    boost::bind(&RtclRw11Cpu::M_lsmem,   this, _1));
80
  AddMeth("ldabs",    boost::bind(&RtclRw11Cpu::M_ldabs,   this, _1));
81
  AddMeth("ldasm",    boost::bind(&RtclRw11Cpu::M_ldasm,   this, _1));
82
  AddMeth("boot",     boost::bind(&RtclRw11Cpu::M_boot,    this, _1));
83
  AddMeth("get",      boost::bind(&RtclRw11Cpu::M_get,     this, _1));
84
  AddMeth("set",      boost::bind(&RtclRw11Cpu::M_set,     this, _1));
85
  AddMeth("stats",    boost::bind(&RtclRw11Cpu::M_stats,   this, _1));
86 20 wfjm
  AddMeth("show",     boost::bind(&RtclRw11Cpu::M_show,    this, _1));
87 19 wfjm
  AddMeth("dump",     boost::bind(&RtclRw11Cpu::M_dump,    this, _1));
88
  AddMeth("$default", boost::bind(&RtclRw11Cpu::M_default, this, _1));
89
}
90
 
91
//------------------------------------------+-----------------------------------
92
//! Destructor
93
 
94
RtclRw11Cpu::~RtclRw11Cpu()
95
{}
96
 
97
//------------------------------------------+-----------------------------------
98
//! FIXME_docs
99
 
100
int RtclRw11Cpu::M_add(RtclArgs& args)
101
{
102
  return RtclRw11CntlFactory(args, *this);
103
}
104
 
105
//------------------------------------------+-----------------------------------
106
//! FIXME_docs
107
 
108
int RtclRw11Cpu::M_cp(RtclArgs& args)
109
{
110
  static RtclNameSet optset("-rr|-rr0|-rr1|-rr2|-rr3|-rr4|-rr5|-rr6|-rr7|"
111
                            "-wr|-wr0|-wr1|-wr2|-wr3|-wr4|-wr5|-wr6|-wr7|"
112
                            "-rsp|-rpc|-wsp|-wpc|"
113
                            "-rps|-wps|"
114
                            "-wal|-wah|-rm|-rmi|-wm|-wmi|-brm|-bwm|"
115
                            "-stapc|-start|-stop|-continue|-step|-reset|"
116
                            "-ribrb|-wibrb|-wibrbbe|-ribr|-wibr|"
117
                            "-rconf|-rstat|"
118
                            "-edata|-estat|-estatdef"
119
                            );
120
 
121
  Tcl_Interp* interp = args.Interp();
122
 
123
  RlinkCommandList clist;
124
  string opt;
125
  uint16_t base = Obj().Base();
126
 
127
  vector<string> vardata;
128
  vector<string> varstat;
129
 
130
  uint8_t estatdef_val = 0x00;
131
  uint8_t estatdef_msk = 0xff;
132
 
133
  bool setcpugo = false;
134
 
135
  while (args.NextOpt(opt, optset)) {
136
    size_t lsize = clist.Size();
137
 
138
    // map register read/write
139
    if (opt == "-rsp") opt = "-rr6";
140
    if (opt == "-rpc") opt = "-rr7";
141
    if (opt == "-wsp") opt = "-wr6";
142
    if (opt == "-wpc") opt = "-wr7";
143
 
144
    int regnum = 0;
145
    if (opt.substr(0,3) == "-rr" || opt.substr(0,3) == "-wr" ) {
146
      if (opt.length() == 3) {
147
        if (!args.GetArg("regnum", regnum, 0, 7)) return kERR;
148
      } else {
149
        regnum = opt[3] - '0';
150
        regnum &= 0x7;                      // to be sure...
151
      }
152
      opt = opt.substr(0,3);
153
    }
154
 
155
    if        (opt == "-rr") {              // -rr* ?varData ?varStat --------
156
      if (!GetVarName(args, "??varData", lsize, vardata)) return kERR;
157
      if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
158
      clist.AddRreg(base + Rw11Cpu::kCp_addr_r0 + regnum);
159
 
160
    } else if (opt == "-wr") {              // -wr* data ?varStat ------------
161
      uint16_t data;
162
      if (!args.GetArg("data", data)) return kERR;
163
      if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
164
      clist.AddWreg(base + Rw11Cpu::kCp_addr_r0 + regnum, data);
165
 
166
    } else if (opt == "-rps") {             // -rps ?varData ?varStat --------
167
      if (!GetVarName(args, "??varData", lsize, vardata)) return kERR;
168
      if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
169
      clist.AddRreg(base + Rw11Cpu::kCp_addr_psw);
170
 
171
    } else if (opt == "-wps") {             // -wps data ?varStat ------------
172
      uint16_t data;
173
      if (!args.GetArg("data", data)) return kERR;
174
      if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
175
      clist.AddWreg(base + Rw11Cpu::kCp_addr_psw, data);
176
 
177
    } else if (opt == "-wal") {             // -wal data ?varStat ------------
178
      uint16_t data;
179
      if (!args.GetArg("al", data)) return kERR;
180
      if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
181
      clist.AddWreg(base + Rw11Cpu::kCp_addr_al, data);
182
 
183
    } else if (opt == "-wah") {             // -wah data ?varStat ------------
184
      uint16_t data;
185
      if (!args.GetArg("ah", data)) return kERR;
186
      if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
187
      clist.AddWreg(base + Rw11Cpu::kCp_addr_ah, data);
188
 
189
    } else if (opt == "-rm" ||              // -rm(i) ?varData ?varStat ------
190
               opt == "-rmi") {
191
      uint16_t addr = opt=="-rm" ? Rw11Cpu::kCp_addr_mem : Rw11Cpu::kCp_addr_memi;
192
      if (!GetVarName(args, "??varData", lsize, vardata)) return kERR;
193
      if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
194
      clist.AddRreg(base + addr);
195
 
196
    } else if (opt == "-wm" ||              // -wm(i) data ?varStat -
197
               opt == "-wmi") {
198
      uint16_t addr = opt=="-wm" ? Rw11Cpu::kCp_addr_mem :
199
                                   Rw11Cpu::kCp_addr_memi;
200
      uint16_t data;
201
      if (!args.GetArg("data", data)) return kERR;
202
      if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
203
      clist.AddWreg(base + addr, data);
204
 
205
    } else if (opt == "-brm") {             // -brm size ?varData ?varStat ---
206
      int32_t bsize;
207
      if (!args.GetArg("bsize", bsize, 1, 256)) return kERR;
208
      if (!GetVarName(args, "??varData", lsize, vardata)) return kERR;
209
      if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
210
      clist.AddRblk(base + Rw11Cpu::kCp_addr_memi, (size_t) bsize);
211
 
212
    } else if (opt == "-bwm") {             // -bwm block ?varStat -----------
213
      vector<uint16_t> block;
214
      if (!args.GetArg("data", block, 1, 256)) return kERR;
215
      if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
216
      clist.AddWblk(base + Rw11Cpu::kCp_addr_memi, block);
217
 
218
    } else if (opt == "-stapc") {           // -stapc addr ?varStat ----------
219
      uint16_t data;
220
      if (!args.GetArg("data", data)) return kERR;
221
      if (!GetVarName(args, "??varStat", lsize+1, varstat)) return kERR;
222
      clist.AddWreg(base + Rw11Cpu::kCp_addr_pc, data);
223
      clist.AddWreg(base + Rw11Cpu::kCp_addr_cntl, Rw11Cpu::kCp_func_start);
224
      setcpugo = true;
225
 
226
    } else if (opt == "-start") {           // -start ?varStat ---------------
227
      if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
228
      clist.AddWreg(base + Rw11Cpu::kCp_addr_cntl, Rw11Cpu::kCp_func_start);
229
      setcpugo = true;
230
 
231
    } else if (opt == "-stop") {            // -stop ?varStat ----------------
232
      if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
233
      clist.AddWreg(base + Rw11Cpu::kCp_addr_cntl, Rw11Cpu::kCp_func_stop);
234
 
235
    } else if (opt == "-continue") {        // -continue ?varStat ------------
236
      if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
237
      clist.AddWreg(base + Rw11Cpu::kCp_addr_cntl, Rw11Cpu::kCp_func_cont);
238
      setcpugo = true;
239
 
240
    } else if (opt == "-step") {            // -step ?varStat ----------------
241
      if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
242
      clist.AddWreg(base + Rw11Cpu::kCp_addr_cntl, Rw11Cpu::kCp_func_step);
243
 
244
    } else if (opt == "-reset") {           // -reset ?varStat ---------------
245
      if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
246
      clist.AddWreg(base + Rw11Cpu::kCp_addr_cntl, Rw11Cpu::kCp_func_reset);
247
 
248
    } else if (opt == "-ribrb") {           // -ribrb ?varData ?varStat ------
249
      if (!GetVarName(args, "??varData", lsize, vardata)) return kERR;
250
      if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
251
      clist.AddRreg(base + Rw11Cpu::kCp_addr_ibrb);
252
 
253
    } else if (opt == "-wibrb") {           // -wibrb base ?varStat ----------
254
      uint16_t data;
255
      if (!args.GetArg("base", data)) return kERR;
256
      if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
257
      data &= 0177700;                        // clear byte enables 
258
      clist.AddWreg(base + Rw11Cpu::kCp_addr_ibrb, data);
259
 
260
    } else if (opt == "-wibrbbe") {         // -wibrbbe base be ?varStat -----
261
      uint16_t data;
262
      uint16_t be;
263
      if (!args.GetArg("base", data)) return kERR;
264
      if (!args.GetArg("be", be, 0x3)) return kERR;
265
      if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
266
      data &= 0177700;                        // clear byte enables from base
267
      if (be == 0) be = 0x3;                  // map be 0 -> be 3
268
      data |= be;                             // set byte enables 
269
      clist.AddWreg(base + Rw11Cpu::kCp_addr_ibrb, data);
270
 
271
    } else if (opt == "-ribr") {           // -ribr off ?varData ?varStat ----
272
      uint16_t off;
273
      if (!args.GetArg("off",  off, 63)) return kERR;
274
      if (!GetVarName(args, "??varData", lsize, vardata)) return kERR;
275
      if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
276
      clist.AddRreg(base + Rw11Cpu::kCp_addr_ibr + off/2);
277
 
278
    } else if (opt == "-wibr") {           // -wibrb off data ?varStat --------
279
      uint16_t off;
280
      uint16_t data;
281
      if (!args.GetArg("off",  off, 63)) return kERR;
282
      if (!args.GetArg("data", data)) return kERR;
283
      if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
284
      clist.AddWreg(base + Rw11Cpu::kCp_addr_ibr + off/2, data);
285
 
286
    } else if (opt == "-rconf") {           // -rconf ?varData ?varStat ------
287
      if (!GetVarName(args, "??varData", lsize, vardata)) return kERR;
288
      if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
289
      clist.AddRreg(base + Rw11Cpu::kCp_addr_conf);
290
 
291
    } else if (opt == "-rstat") {           // -rstat ?varData ?varStat ------
292
      if (!GetVarName(args, "??varData", lsize, vardata)) return kERR;
293
      if (!GetVarName(args, "??varStat", lsize, varstat)) return kERR;
294
      clist.AddRreg(base + Rw11Cpu::kCp_addr_stat);
295
 
296
    } else if (opt == "-edata") {           // -edata data ?mask --------------
297
      if (lsize == 0)
298
        return args.Quit("-E: -edata not allowed on empty command list");
299
      if (clist[lsize-1].Expect()==0) {
300
        clist.LastExpect(new RlinkCommandExpect());
301
      }
302
      if (clist[lsize-1].Command() == RlinkCommand::kCmdRblk) {
303
        vector<uint16_t> data;
304
        vector<uint16_t> mask;
305
        size_t bsize = clist[lsize-1].BlockSize();
306
        if (!args.GetArg("data", data, 0, bsize)) return kERR;
307
        if (!args.GetArg("??mask", mask, 0, bsize)) return kERR;
308
        clist[lsize-1].Expect()->SetBlock(data, mask);
309
      } else {
310
        uint16_t data=0;
311
        uint16_t mask=0;
312
        if (!args.GetArg("data", data)) return kERR;
313
        if (!args.GetArg("??mask", mask)) return kERR;
314
        clist[lsize-1].Expect()->SetData(data, mask);
315
      }
316
 
317
    } else if (opt == "-estat") {           // -estat ?stat ?mask -------------
318
      if (lsize == 0)
319
        return args.Quit("-E: -estat not allowed on empty command list");
320
      uint8_t stat=0;
321
      uint8_t mask=0;
322
      if (!args.GetArg("??stat", stat)) return kERR;
323
      if (!args.GetArg("??mask", mask)) return kERR;
324
      if (args.NOptMiss() == 2)  mask = 0xff;
325
      if (clist[lsize-1].Expect()==0) {
326
        clist.LastExpect(new RlinkCommandExpect());
327
      }
328
      clist[lsize-1].Expect()->SetStatus(stat, mask);
329
 
330
    } else if (opt == "-estatdef") {        // -estatdef ?stat ?mask -----------
331
      uint8_t stat=0;
332
      uint8_t mask=0;
333
      if (!args.GetArg("??stat", stat)) return kERR;
334
      if (!args.GetArg("??mask", mask)) return kERR;
335
      if (args.NOptMiss() == 2)  mask = 0xff;
336
      estatdef_val = stat;
337
      estatdef_msk = mask;
338
 
339
    }
340
 
341
    if (lsize != clist.Size()) {            // cmd added to clist (ind=lsize!)
342
      if (estatdef_msk != 0xff) {           // estatdef defined
343
        if (clist[lsize].Expect()==0) {
344
          clist.LastExpect(new RlinkCommandExpect());
345
        }
346
        clist[lsize].Expect()->SetStatus(estatdef_val, estatdef_msk);
347
      }
348
    }
349
 
350
  }
351
 
352
  if (!args.AllDone()) return kERR;
353
  if (clist.Size() == 0) return kOK;
354
 
355
  // signal cpugo up before clist executed to prevent races
356
  if (setcpugo) Obj().SetCpuGoUp();
357
 
358
  RerrMsg emsg;
359
  // this one intentionally on Connect() to allow mixing of rlc + w11 commands
360
  // FIXME_code: is this a good idea ??
361
  if (!Connect().Exec(clist, emsg)) return args.Quit(emsg);
362
 
363
  for (size_t icmd=0; icmd<clist.Size(); icmd++) {
364
    RlinkCommand& cmd = clist[icmd];
365
 
366
    if (icmd<vardata.size() && !vardata[icmd].empty()) {
367
      RtclOPtr pres;
368
      vector<uint16_t> retstat;
369
      RtclOPtr pele;
370
      switch (cmd.Command()) {
371
        case RlinkCommand::kCmdRreg:
372
          pres = Tcl_NewIntObj((int)cmd.Data());
373
          break;
374
 
375
        case RlinkCommand::kCmdRblk:
376
          pres = Rtcl::NewListIntObj(cmd.Block());
377
          break;
378
      }
379
      if(!Rtcl::SetVar(interp, vardata[icmd], pres)) return kERR;
380
    }
381
 
382
    if (icmd<varstat.size() && !varstat[icmd].empty()) {
383
      RtclOPtr pres = Tcl_NewIntObj((int)cmd.Status());
384
      if (!Rtcl::SetVar(interp, varstat[icmd], pres)) return kERR;
385
    }
386
  }
387
 
388
  return kOK;
389
}
390
 
391
//------------------------------------------+-----------------------------------
392
//! FIXME_docs
393
 
394
int RtclRw11Cpu::M_wtcpu(RtclArgs& args)
395
{
396
  static RtclNameSet optset("-reset");
397
 
398
  string opt;
399
  bool reset = false;
400
  double tout;
401
 
402
  while (args.NextOpt(opt, optset)) {
403
    if (opt == "-reset") reset = true;
404
  }
405
  if (!args.GetArg("tout", tout, 0.001)) return kERR;
406
  if (!args.AllDone()) return kERR;
407
 
408
  double twait = -1;
409
 
410
  if (!Server().IsActive()) {               // server is not active
411
    RerrMsg emsg;
412
    twait = Connect().WaitAttn(tout, emsg);
413
    if (twait == -2.) {                     // wait failed, quit
414
      return args.Quit(emsg);
415
    }
416
    if (twait >= 0.) {                      // wait succeeded
417
      RlinkCommandList clist;                 // get and discard attn pattern 
418
      clist.AddAttn();
419
      if (!Connect().Exec(clist, emsg)) return args.Quit(emsg);
420
    }
421
 
422
  } else {                                  // server is active
423
    twait = Obj().WaitCpuGoDown(tout);
424
  }
425
 
426
  if (twait < 0.) {                         // timeout
427
    if (Connect().GetLogOpts().printlevel >= 1) {
428
      RlogMsg lmsg(Connect().LogFile());
429
      lmsg << "-- wtcpu to=" << RosPrintf(tout, "f", 0,3) << " FAIL timeout";
430
    }
431
    Connect().Context().IncErrorCount();
432
    if (reset) {                            // reset requested 
433
      uint16_t base = Obj().Base();
434
      RlinkCommandList clist;
435
      clist.AddWreg(base + Rw11Cpu::kCp_addr_cntl, Rw11Cpu::kCp_func_stop);
436
      RerrMsg emsg;
437
      if (!Connect().Exec(clist, emsg)) return args.Quit(emsg);
438
    }
439
  } else {                                  // no timeout
440
    if (Connect().GetLogOpts().printlevel >= 3) {
441
      RlogMsg lmsg(Connect().LogFile());
442
      lmsg << "-- wtcpu to=" << RosPrintf(tout, "f", 0,3)
443
           << "  T=" << RosPrintf(twait, "f", 0,3)
444
           << "  OK";
445
    }
446
  }
447
 
448
  args.SetResult(twait);
449
  return kOK;
450
}
451
 
452
//------------------------------------------+-----------------------------------
453
//! FIXME_docs
454
 
455
int RtclRw11Cpu::M_deposit(RtclArgs& args)
456
{
457
  uint16_t  addr;
458
  vector<uint16_t> data;
459
  if (!args.GetArg("addr", addr)) return kERR;
460
  if (!args.GetArg("data", data, 1)) return kERR;
461
  if (!args.AllDone()) return kERR;
462
 
463
  RerrMsg emsg;
464
  // FIXME_code: handle memory read/write error
465
  if (!Obj().MemWrite(addr, data, emsg)) return args.Quit(emsg);
466
 
467
  return kOK;
468
}
469
 
470
//------------------------------------------+-----------------------------------
471
//! FIXME_docs
472
 
473
int RtclRw11Cpu::M_examine(RtclArgs& args)
474
{
475
  uint16_t  addr;
476
  if (!args.GetArg("addr", addr)) return kERR;
477
  if (!args.AllDone()) return kERR;
478
 
479
  RerrMsg emsg;
480
  vector<uint16_t> data;
481
  // FIXME_code: handle memory read/write error
482
  if (!Obj().MemRead(addr, data, 1, emsg)) return args.Quit(emsg);
483
 
484
  args.SetResult(Rtcl::NewListIntObj(data));
485
 
486
  return kOK;
487
}
488
 
489
//------------------------------------------+-----------------------------------
490
//! FIXME_docs
491
 
492
int RtclRw11Cpu::M_lsmem(RtclArgs& args)
493
{
494
  uint16_t  abeg;
495
  if (!args.GetArg("abeg", abeg)) return kERR;
496
  uint16_t  aend = abeg;
497
  if (!args.GetArg("?aend", aend, 0xffff, abeg)) return kERR;
498
  if (!args.AllDone()) return kERR;
499
 
500
  RerrMsg emsg;
501
  vector<uint16_t> data;
502
  size_t nword = 1+(aend-abeg)/2;
503
  // FIXME_code: handle memory read/write error
504
  if (!Obj().MemRead(abeg, data, nword, emsg)) return args.Quit(emsg);
505
 
506
  ostringstream sos;
507
  for (size_t i=0; i<nword; i++) {
508
    sos << RosPrintBvi(uint16_t(abeg+i*2), 8)
509
        << " : " <<  RosPrintBvi(data[i], 8) << endl;
510
  }
511
 
512
  args.SetResult(sos);
513
 
514
  return kOK;
515
}
516
 
517
//------------------------------------------+-----------------------------------
518
//! FIXME_docs
519
 
520
int RtclRw11Cpu::M_ldabs(RtclArgs& args)
521
{
522
  string file;
523
  if (!args.GetArg("file", file)) return kERR;
524
  if (!args.AllDone()) return kERR;
525
  RerrMsg emsg;
526
  // FIXME_code: handle memory read/write error
527
  if (!Obj().LoadAbs(file, emsg, true)) return args.Quit(emsg);
528
  return kOK;
529
}
530
 
531
//------------------------------------------+-----------------------------------
532
//! FIXME_docs
533
 
534
int RtclRw11Cpu::M_ldasm(RtclArgs& args)
535
{
536
  static RtclNameSet optset("-lst|-sym|-opt|-file");
537
  Tcl_Interp* interp = args.Interp();
538
 
539
  string varlst;
540
  string varsym;
541
  string asmopt;
542
  string file;
543
  string code;
544
 
545
  string opt;
546
  while (args.NextOpt(opt, optset)) {
547
    if (opt == "-lst") {
548
      if (!args.GetArg("??varLst", varlst)) return kERR;
549
    } else if (opt == "-sym") {
550
      if (!args.GetArg("??varSym", varsym)) return kERR;
551
    } else if (opt == "-opt") {
552
      // don't use ?? because the argument will look like an option...
553
      if (!args.GetArg("opts", asmopt)) return kERR;
554
    } else if (opt == "-file") {
555
      if (!args.GetArg("??file", file)) return kERR;
556
    }
557
  }
558
 
559
  if (file.length() == 0) {
560
    if (!args.GetArg("code", code)) return kERR;
561
  }
562
  if (!args.AllDone()) return kERR;
563
 
564
  // delete sym array, otherwise old entries are preserved
565
  if (varsym.length())
566
    Tcl_UnsetVar(interp, varsym.c_str(), 0);
567
 
568
  int pipe_tcl2asm[2];                      // [0] read, [1] write end
569
  int pipe_asm2tcl[2];
570
 
571
  if (::pipe(pipe_tcl2asm) < 0)
572
    return args.Quit(RerrMsg("RtclRw11Cpu::M_ldasm" ,
573
                             "1st pipe() failed: ", errno));
574
  if (::pipe(pipe_asm2tcl) < 0)
575
    return args.Quit(RerrMsg("RtclRw11Cpu::M_ldasm" ,
576
                             "2nd pipe() failed: ", errno));
577
 
578
  pid_t pid = ::fork();
579
  if (pid == (pid_t) 0) {                   // in child here
580
    vector<const char*> argv;
581
    vector<string>      opts;
582
 
583
    argv.push_back("asm-11");
584
    if (varlst.length()>0) argv.push_back("--olst=-");
585
    argv.push_back("--ocof=-");
586
    if (asmopt.length()) {
587
      istringstream optstream(asmopt);
588
      string tok;
589
      while (optstream >> tok) {
590
        opts.push_back(tok);
591
        argv.push_back(opts[opts.size()-1].c_str());
592
      }
593
    }
594
    if (file.length()) {
595
      argv.push_back(file.c_str());
596
    } else {
597
      argv.push_back("-");
598
    }
599
    argv.push_back(NULL);
600
 
601
    ::dup2(pipe_tcl2asm[0], STDIN_FILENO);
602
    ::dup2(pipe_asm2tcl[1], STDOUT_FILENO);
603
    ::dup2(STDOUT_FILENO, STDERR_FILENO);
604
    ::close(pipe_tcl2asm[1]);
605
    ::close(pipe_asm2tcl[0]);
606
    ::execvp("asm-11", (char* const*) argv.data());
607
    ::perror("execvp() for asm-11 failed");
608
    ::exit(EXIT_FAILURE);
609
 
610
  } else {                                  // in parent here
611
    ::close(pipe_tcl2asm[0]);
612
    ::close(pipe_asm2tcl[1]);
613
    if (pid < (pid_t) 0)
614
      return args.Quit(RerrMsg("RtclRw11Cpu::M_ldasm" ,
615
                               "fork() failed: ", errno));
616
  }
617
 
618
  // if first line empty, drop it (created often by using {)
619
  if (code.length() && code[0] == '\n') code = code.substr(1);
620
 
621
  istringstream ostream(code);
622
  string oline;
623
  while (std::getline(ostream, oline)) {
624
    oline += '\n';
625
    //cout << "+++1:" << oline;
626
    if (::write(pipe_tcl2asm[1], oline.data(), oline.length()) < 0) break;
627
  }
628
  ::close(pipe_tcl2asm[1]);
629
 
630
  FILE* fp = ::fdopen(pipe_asm2tcl[0], "r");
631
  if (fp == NULL) {
632
    ::close(pipe_asm2tcl[0]);
633
    return args.Quit(RerrMsg("RtclRw11Cpu::M_ldasm" ,
634
                             "fdopen() failed: ", errno));
635
  }
636
 
637
  vector<string> ilines;
638
  while(true) {
639
    char* pline = NULL;
640
    size_t nchar;
641
    if (::getline(&pline, &nchar, fp) < 0) break;
642
    //cout << "+++2:" << pline;
643
    string line(pline);
644
    if (line.length() && line[line.length()-1] =='\n')
645
      line.resize(line.length()-1);
646
    ilines.push_back(line);
647
    ::free(pline);
648
  }
649
  ::fclose(fp);
650
  ::close(pipe_asm2tcl[0]);
651
 
652
  int wstat;
653
  int wexit = -1;
654
  waitpid(pid, &wstat, 0);
655
  if (WIFEXITED(wstat)) wexit = WEXITSTATUS(wstat);
656
 
657
  bool insym = false;
658
  bool indat = false;
659
  char dtyp = ' ';
660
 
661
  ostringstream los;                        // list stream
662
  ostringstream eos;                        // error stream
663
  bool lstbodyseen = false;
664
 
665
  typedef map<uint16_t, uint16_t>  cmap_t;
666
  typedef cmap_t::iterator         cmap_it_t;
667
  typedef cmap_t::value_type       cmap_val_t;
668
 
669
  cmap_t   cmap;
670
  uint16_t dot = 0;
671
 
672
  for (size_t i=0; i<ilines.size(); i++) {
673
    string& line = ilines[i];
674
    if (line == "sym {") {
675
      insym = true;
676
      continue;
677
    } else if (line == "dat {") {
678
      indat = true;
679
      continue;
680
    } else if (dtyp == ' ' && line == "}") {
681
      insym = false;
682
      indat = false;
683
      continue;
684
    }
685
 
686
    // handle symbol table
687
    if (insym) {
688
      if (varsym.length() == 0) continue;
689
      size_t dpos = line.find(" => ");
690
      if (dpos != std::string::npos) {
691
        string key = line.substr(0,dpos);
692
        string val= line.substr(dpos+4);
693
        if (!Tcl_SetVar2Ex(interp, varsym.c_str(), key.c_str(),
694
                           Tcl_NewIntObj((int)strtol(val.c_str(),NULL,8)),
695
                           TCL_LEAVE_ERR_MSG)) return kERR;
696
      } else {
697
        return args.Quit(string("bad sym spec: ") + line);
698
      }
699
 
700
    // handle data part
701
    } else if (indat) {
702
      if (dtyp == ' ') {
703
        if (line.length() != 10)
704
          return args.Quit(string("bad dat spec: ") + line);
705
        dtyp = line[0];
706
        dot  = (uint16_t)strtol(line.c_str()+2,NULL,8);
707
      } else if (line[0] == '}') {
708
        dtyp = ' ';
709
      } else {
710
        istringstream datstream(line);
711
        string dat;
712
        while (datstream >> dat) {
713
          //cout << "+++1 " << dtyp << ":" << dat << endl;
714
          uint16_t val = (uint16_t)strtol(dat.c_str(),NULL,8);
715
          if (dtyp == 'w') {
716
            cmap[dot] = val;
717
            dot += 2;
718
          } else {
719
            uint16_t tmp = cmap[dot&0xfffe];
720
            if (dot & 01) {
721
              tmp = (val&0xff)<<8 | (tmp&0xff); // odd (high) byte
722
            } else {
723
              tmp = (tmp&0xff00)  | (val&0xff); // even (low) byte
724
            }
725
            cmap[dot&0xfffe] = tmp;
726
            dot += 1;
727
          }
728
        }
729
      }
730
 
731
    // handle listing part (everything not sym{} or dat{}
732
    } else {
733
      los << line << endl;
734
      // put lines into error stream if
735
      //  1. before 'Input file list:' and not starting with '--'
736
      //  2. after  'Input file list:' and starting with uppercase letter
737
      if (line == "; Input file list:") lstbodyseen = true;
738
      bool etake = false;
739
      if (lstbodyseen) {
740
        if (line.length() && (line[0]>'A' && line[0]<'Z')) etake = true;
741
      } else {
742
        if (line.substr(0,2) != "--") etake = true;
743
      }
744
      if (line.substr(0,6) == "asm-11") etake = true;
745
      if (etake) eos << line << endl;
746
    }
747
  }
748
 
749
  if (varlst.length()) {
750
    if (!Rtcl::SetVar(interp, varlst, Rtcl::NewLinesObj(los))) return kERR;
751
  }
752
 
753
  // now, finally, iterate of cmap and write code to memory
754
 
755
  vector<uint16_t> block;
756
  uint16_t base = 0;
757
  dot = 0;
758
  RerrMsg emsg;
759
 
760
  for (cmap_it_t it=cmap.begin(); it!=cmap.end(); it++) {
761
    //cout << "+++2 mem[" << RosPrintf(it->first, "o0", 6)
762
    //     << "]=" << RosPrintf(it->second, "o0", 6) << endl;
763
    if (dot != it->first || block.size() == 256) {
764
      if (block.size()) {
765
        if (!Obj().MemWrite(base, block, emsg)) return args.Quit(emsg);
766
        block.clear();
767
      }
768
      base = dot = it->first;
769
    }
770
    block.push_back(it->second);
771
    dot += 2;
772
  }
773
 
774
  if (block.size()) {
775
    if (!Obj().MemWrite(base, block, emsg)) return args.Quit(emsg);
776
    block.clear();
777
  }
778
 
779
  if (wexit != 0) {
780
    args.AppendResultLines("asm-11 compilation failed with:");
781
    args.AppendResultLines(eos);
782
    return kERR;
783
  }
784
 
785
  return kOK;
786
}
787
 
788
//------------------------------------------+-----------------------------------
789
//! FIXME_docs
790
 
791
int RtclRw11Cpu::M_boot(RtclArgs& args)
792
{
793
  string uname;
794
  if (!args.GetArg("uname", uname)) return kERR;
795
  if (!args.AllDone()) return kERR;
796
  RerrMsg emsg;
797
  if (!Obj().Boot(uname, emsg)) return args.Quit(emsg);
798
  return kOK;
799
}
800
 
801
//------------------------------------------+-----------------------------------
802
//! FIXME_docs
803
 
804
int RtclRw11Cpu::M_get(RtclArgs& args)
805
{
806
  // synchronize with server thread
807
  boost::lock_guard<RlinkConnect> lock(Obj().Connect());
808
  return fGets.M_get(args);
809
}
810
 
811
//------------------------------------------+-----------------------------------
812
//! FIXME_docs
813
 
814
int RtclRw11Cpu::M_set(RtclArgs& args)
815
{
816
  // synchronize with server thread
817
  boost::lock_guard<RlinkConnect> lock(Obj().Connect());
818
  return fSets.M_set(args);
819
}
820
 
821
//------------------------------------------+-----------------------------------
822
//! FIXME_docs
823
 
824 20 wfjm
int RtclRw11Cpu::M_show(RtclArgs& args)
825
{
826 21 wfjm
  static RtclNameSet optset("-pcps|-r0ps|-mmu|-ubmap"
827 20 wfjm
                            );
828
 
829
  string opt;
830
  uint16_t base = Obj().Base();
831
  ostringstream sos;
832
  RerrMsg emsg;
833
 
834
  const char* mode[4]  = {"k","s","?","u"};
835
  const char* rust[16] = {"init",     "HALTed",   "reset",   "stopped",
836
                          "stepped",  "suspend",  "0110",    "..run..",
837
                          "F:vecfet", "F:redstk", "1010",    "1011",
838
                          "F:seq",    "F:vmbox" , "1101",    "1111"};
839
 
840
  while (args.NextOpt(opt, optset)) {
841 21 wfjm
    if (opt == "-pcps" || opt == "-r0ps") {
842 20 wfjm
      RlinkCommandList clist;
843
      size_t i_pc   = clist.AddRreg(base + Rw11Cpu::kCp_addr_pc);
844
      size_t i_psw  = clist.AddRreg(base + Rw11Cpu::kCp_addr_psw);
845
      size_t i_stat = clist.AddRreg(base + Rw11Cpu::kCp_addr_stat);
846
      if (!Server().Exec(clist, emsg)) return args.Quit(emsg);
847
      uint16_t psw  = clist[i_psw].Data();
848
      uint16_t stat = clist[i_stat].Data();
849
      uint16_t psw_cm    = (psw>>14) & 003;
850
      uint16_t psw_pm    = (psw>>12) & 003;
851
      uint16_t psw_set   = (psw>>11) & 001;
852
      uint16_t psw_pri   = (psw>>5)  & 007;
853
      uint16_t psw_tbit  = (psw>>4)  & 001;
854
      uint16_t psw_nzvc  = (psw)     & 017;
855
      uint16_t stat_rust = (stat>>4) & 017;
856 21 wfjm
      uint16_t regs[8];
857
      regs[7] = clist[i_pc].Data();
858
      bool r0ps = opt == "-r0ps";
859
 
860
      if (r0ps) {
861
        clist.Clear();
862
        for (size_t i=0; i<7; i++) clist.AddRreg(base + Rw11Cpu::kCp_addr_r0+i);
863
        if (!Server().Exec(clist, emsg)) return args.Quit(emsg);
864
        for (size_t i=0; i<7; i++) regs[i] = clist[i].Data();
865
      }
866
 
867
      if (r0ps)  sos << "Processor registers and status:" << endl;
868
      if (!r0ps) sos << "  PC: " << RosPrintBvi(regs[7],8);
869
      sos << "  PS: " << RosPrintBvi(psw,8)
870 20 wfjm
          << " cm,pm=" << mode[psw_cm] << "," << mode[psw_pm]
871
          << " s,p,t=" << psw_set << "," << psw_pri << "," << psw_tbit
872
          << " NZVC=" << RosPrintBvi(psw_nzvc,2,4)
873 21 wfjm
          << "  rust: " << RosPrintBvi(stat_rust,8,4) << " " << rust[stat_rust]
874 20 wfjm
          << endl;
875
 
876 21 wfjm
      if (r0ps) {
877
        sos << "  R0: " << RosPrintBvi(regs[0],8)
878
            << "  R1: " << RosPrintBvi(regs[1],8)
879
            << "  R2: " << RosPrintBvi(regs[2],8)
880
            << "  R3: " << RosPrintBvi(regs[3],8) << endl;
881
        sos << "  R4: " << RosPrintBvi(regs[4],8)
882
            << "  R5: " << RosPrintBvi(regs[5],8)
883
            << "  SP: " << RosPrintBvi(regs[6],8)
884
            << "  PC: " << RosPrintBvi(regs[7],8) << endl;
885
      }
886
 
887 20 wfjm
    } else if (opt == "-r0r5") {
888
      RlinkCommandList clist;
889
      for (size_t i=0; i<6; i++) clist.AddRreg(base + Rw11Cpu::kCp_addr_r0+i);
890
      if (!Server().Exec(clist, emsg)) return args.Quit(emsg);
891
      sos << "R0-R5:";
892
      for (size_t i=0; i<6; i++) sos << "  " << RosPrintBvi(clist[i].Data(),8);
893
      sos << endl;
894
 
895
    } else if (opt == "-mmu") {
896
      uint16_t mmr[4];
897
      uint16_t asr[3][32];
898
      const char* pmode[3] = {"km","sm","um"};
899
      const char* acf[8] = {"nres ",
900
                            "r -r ",
901
                            "r    ",
902
                            "011  ",
903
                            "rw-rw",
904
                            "rw- w",
905
                            "rw   ",
906
                            "111  "};
907
      {
908
        boost::lock_guard<RlinkConnect> lock(Connect());
909
        RlinkCommandList clist;
910
        clist.AddWreg(base + Rw11Cpu::kCp_addr_al, 0177572);
911
        clist.AddRblk(base + Rw11Cpu::kCp_addr_memi, mmr, 3);
912
        clist.AddWreg(base + Rw11Cpu::kCp_addr_al, 0172516);
913
        clist.AddRblk(base + Rw11Cpu::kCp_addr_memi, mmr+3, 1);
914
        if (!Server().Exec(clist, emsg)) return args.Quit(emsg);
915
        clist.Clear();
916
        clist.AddWreg(base + Rw11Cpu::kCp_addr_al, 0172300);
917
        clist.AddRblk(base + Rw11Cpu::kCp_addr_memi, asr[0], 32);
918
        clist.AddWreg(base + Rw11Cpu::kCp_addr_al, 0172200);
919
        clist.AddRblk(base + Rw11Cpu::kCp_addr_memi, asr[1], 32);
920
        clist.AddWreg(base + Rw11Cpu::kCp_addr_al, 0177600);
921
        clist.AddRblk(base + Rw11Cpu::kCp_addr_memi, asr[2], 32);
922
        if (!Server().Exec(clist, emsg)) return args.Quit(emsg);
923
      }
924
      uint16_t mmr1_0_reg = (mmr[1]    ) & 07;
925
       int16_t mmr1_0_val = (mmr[1]>> 3) & 37;
926
      uint16_t mmr1_1_reg = (mmr[1]>> 8) & 07;
927
       int16_t mmr1_1_val = (mmr[1]>>11) & 37;
928
      uint16_t mmr3_ubmap = (mmr[3]>> 5) & 01;
929
      uint16_t mmr3_22bit = (mmr[3]>> 4) & 01;
930
      uint16_t mmr3_d_km  = (mmr[3]>> 2) & 01;
931
      uint16_t mmr3_d_sm  = (mmr[3]>> 1) & 01;
932
      uint16_t mmr3_d_um  = (mmr[3]    ) & 01;
933
      sos << "mmu:" << endl;
934
      sos << "mmr0=" << RosPrintBvi(mmr[0],8) << endl;
935
      if (mmr1_0_val & 020) mmr1_0_val |= 0177740;
936
      if (mmr1_1_val & 020) mmr1_1_val |= 0177740;
937
      sos << "mmr1=" << RosPrintBvi(mmr[1],8);
938
      if (mmr1_0_val) sos << "  r" << mmr1_0_reg
939
                          << ":" << RosPrintf(mmr1_0_val,"d",3);
940
      if (mmr1_1_val) sos << "  r" << mmr1_1_reg
941
                          << ":" << RosPrintf(mmr1_1_val,"d",3);
942
      sos << endl;
943
      sos << "mmr2=" << RosPrintBvi(mmr[2],8) << endl;
944
      sos << "mmr3=" << RosPrintBvi(mmr[3],8)
945
          << "  ubmap=" << mmr3_ubmap
946
          << "  22bit=" << mmr3_22bit
947
          << "  d-space k,s,u=" << mmr3_d_km
948
          << "," << mmr3_d_sm << "," << mmr3_d_um << endl;
949
      for (size_t m=0; m<3; m++) {
950
        sos << pmode[m] << "   "
951
            << " I pdr slf aw d acf     I par"
952
            << "    "
953
            << " D pdr slf aw d acf     D par" << endl;
954
        for (size_t i=0; i<=7; i++) {
955
          sos << "   " << i << " ";
956
          for (size_t s=0; s<=1; s++) {
957
            if (s!=0) sos << "    ";
958
            uint16_t pdr = asr[m][i   +8*s];
959
            uint16_t par = asr[m][i+16+8*s];
960
            uint16_t pdr_slf = (pdr>>8) & 0177;
961
            uint16_t pdr_a   = (pdr>>7) & 01;
962
            uint16_t pdr_w   = (pdr>>6) & 01;
963
            uint16_t pdr_e   = (pdr>>3) & 01;
964
            uint16_t pdr_acf = (pdr)    & 07;
965
            sos<< RosPrintBvi(pdr,8)
966
               << " " << RosPrintf(pdr_slf,"d",3)
967
               << " " << pdr_a << pdr_w
968
               << " " << (pdr_e ? "d" : "u")
969
               << " " << acf[pdr_acf]
970
               << "  " << RosPrintBvi(par,8);
971
          }
972
          sos << endl;
973
        }
974
      }
975
 
976
    } else if (opt == "-ubmap") {
977
      uint16_t ubmap[64];
978
      RlinkCommandList clist;
979
      clist.AddWreg(base + Rw11Cpu::kCp_addr_al, 0170200);
980
      clist.AddRblk(base + Rw11Cpu::kCp_addr_memi, ubmap, 64);
981
      if (!Server().Exec(clist, emsg)) return args.Quit(emsg);
982
      sos << "unibus map:" << endl;
983
      for (size_t i = 0; i<=7; i++) {
984
        for (size_t j = 0; j <= 030; j+=010) {
985
          size_t k = 2*(i+j);
986
          uint32_t data = uint32_t(ubmap[k]) | (uint32_t(ubmap[k+1]))<<16;
987
          if (j!=0) sos << "  ";
988 21 wfjm
          sos << RosPrintBvi(uint32_t(j+i),8,5) << " "
989 20 wfjm
              << RosPrintBvi(data,8,22);
990
        }
991
        sos << endl;
992
      }
993
    }
994
  }
995
 
996
  if (!args.AllDone()) return kERR;
997
  args.SetResult(sos);
998
 
999
  return kOK;
1000
}
1001
 
1002
//------------------------------------------+-----------------------------------
1003
//! FIXME_docs
1004
 
1005 19 wfjm
int RtclRw11Cpu::M_stats(RtclArgs& args)
1006
{
1007
  RtclStats::Context cntx;
1008
  if (!RtclStats::GetArgs(args, cntx)) return kERR;
1009
  if (!RtclStats::Collect(args, cntx, Obj().Stats())) return kERR;
1010
  return kOK;
1011
}
1012
 
1013
//------------------------------------------+-----------------------------------
1014
//! FIXME_docs
1015
 
1016
int RtclRw11Cpu::M_dump(RtclArgs& args)
1017
{
1018
  if (!args.AllDone()) return kERR;
1019
 
1020
  ostringstream sos;
1021
  Obj().Dump(sos, 0);
1022
  args.SetResult(sos);
1023
  return kOK;
1024
}
1025
 
1026
//------------------------------------------+-----------------------------------
1027
//! FIXME_docs
1028
 
1029
int RtclRw11Cpu::M_default(RtclArgs& args)
1030
{
1031
  if (!args.AllDone()) return kERR;
1032
  ostringstream sos;
1033
 
1034
  vector<string> cntlnames;
1035
  Obj().ListCntl(cntlnames);
1036
 
1037
  sos << "name type ibbase lam" << endl;
1038
 
1039
  for (size_t i=0; i<cntlnames.size(); i++) {
1040
    Rw11Cntl& cntl(Obj().Cntl(cntlnames[i]));
1041
    sos << RosPrintf(cntl.Name().c_str(),"-s",4)
1042
        << " " << RosPrintf(cntl.Type().c_str(),"-s",4)
1043
        << " " << RosPrintf(cntl.Base(),"o",6)
1044
        << " " << RosPrintf(cntl.Lam(),"d",3)
1045
        << endl;
1046
  }
1047
 
1048
  args.AppendResultLines(sos);
1049
  return kOK;
1050
}
1051
 
1052
//------------------------------------------+-----------------------------------
1053
//! FIXME_docs
1054
 
1055
void RtclRw11Cpu::SetupGetSet()
1056
{
1057
  Rw11Cpu* pobj = &Obj();
1058
  fGets.Add<const string&>("type",  boost::bind(&Rw11Cpu::Type, pobj));
1059
  fGets.Add<size_t>       ("index", boost::bind(&Rw11Cpu::Index, pobj));
1060
  fGets.Add<uint16_t>     ("base",  boost::bind(&Rw11Cpu::Base, pobj));
1061
  return;
1062
}
1063
 
1064
//------------------------------------------+-----------------------------------
1065
//! FIXME_docs
1066
 
1067
bool RtclRw11Cpu::GetVarName(RtclArgs& args, const char* argname,
1068
                             size_t nind,
1069
                             std::vector<std::string>& varname)
1070
{
1071
  while (varname.size() < nind+1) varname.push_back(string());
1072
  string name;
1073
  if (!args.GetArg(argname, name)) return false;
1074
  if (name.length()) {                      // if variable defined
1075
    char c = name[0];
1076
    if (isdigit(c) || c=='+' || c=='-' ) {  // check for mistaken number
1077
      args.AppendResult("-E: invalid variable name '", name.c_str(),
1078
                        "': looks like a number", NULL);
1079
      return false;
1080
    }
1081
  }
1082
 
1083
  varname[nind] = name;
1084
  return true;
1085
}
1086
 
1087
} // end namespace Retro

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.