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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.6/] [tools/] [src/] [librw11/] [Rw11Cpu.cpp] - Blame information for rev 24

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 22 wfjm
// $Id: Rw11Cpu.cpp 521 2013-05-20 22:16:45Z 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-14   506   1.0.1  add AddLalh(),AddRMem(),AddWMem()
17 19 wfjm
// 2013-04-12   504   1.0    Initial version
18
// 2013-01-27   478   0.1    First draft
19
// ---------------------------------------------------------------------------
20
 
21
/*!
22
  \file
23 22 wfjm
  \version $Id: Rw11Cpu.cpp 521 2013-05-20 22:16:45Z mueller $
24 19 wfjm
  \brief   Implemenation of Rw11Cpu.
25
*/
26
#include <stdlib.h>
27
#include <fcntl.h>
28
#include <errno.h>
29
 
30
#include <vector>
31
#include <map>
32
#include <algorithm>
33
 
34
#include "boost/date_time/posix_time/posix_time_types.hpp"
35
 
36
#include "librtools/Rexception.hpp"
37
#include "librtools/RlogMsg.hpp"
38
#include "librtools/RosFill.hpp"
39
#include "librtools/RosPrintf.hpp"
40
#include "librtools/RosPrintBvi.hpp"
41
#include "Rw11Cntl.hpp"
42
 
43
#include "Rw11Cpu.hpp"
44
 
45
using namespace std;
46
 
47
/*!
48
  \class Retro::Rw11Cpu
49
  \brief FIXME_docs
50
*/
51
 
52
// all method definitions in namespace Retro
53
namespace Retro {
54
 
55
//------------------------------------------+-----------------------------------
56
// constants definitions
57
 
58
const uint16_t  Rw11Cpu::kCp_addr_conf;
59
const uint16_t  Rw11Cpu::kCp_addr_cntl;
60
const uint16_t  Rw11Cpu::kCp_addr_stat;
61
const uint16_t  Rw11Cpu::kCp_addr_psw;
62
const uint16_t  Rw11Cpu::kCp_addr_al;
63
const uint16_t  Rw11Cpu::kCp_addr_ah;
64
const uint16_t  Rw11Cpu::kCp_addr_mem;
65
const uint16_t  Rw11Cpu::kCp_addr_memi;
66
const uint16_t  Rw11Cpu::kCp_addr_r0;
67
const uint16_t  Rw11Cpu::kCp_addr_pc;
68
const uint16_t  Rw11Cpu::kCp_addr_ibrb;
69
const uint16_t  Rw11Cpu::kCp_addr_ibr;
70
 
71
const uint16_t  Rw11Cpu::kCp_func_noop;
72
const uint16_t  Rw11Cpu::kCp_func_start;
73
const uint16_t  Rw11Cpu::kCp_func_stop;
74
const uint16_t  Rw11Cpu::kCp_func_cont;
75
const uint16_t  Rw11Cpu::kCp_func_step;
76
const uint16_t  Rw11Cpu::kCp_func_reset;
77
 
78
const uint16_t  Rw11Cpu::kCp_stat_m_cpurust;
79
const uint16_t  Rw11Cpu::kCp_stat_v_cpurust;
80
const uint16_t  Rw11Cpu::kCp_stat_b_cpurust;
81
const uint16_t  Rw11Cpu::kCp_stat_m_cpuhalt;
82
const uint16_t  Rw11Cpu::kCp_stat_m_cpugo;
83
const uint16_t  Rw11Cpu::kCp_stat_m_cmdmerr;
84
const uint16_t  Rw11Cpu::kCp_stat_m_cmderr;
85
 
86
const uint16_t  Rw11Cpu::kCp_cpurust_init;
87
const uint16_t  Rw11Cpu::kCp_cpurust_halt;
88
const uint16_t  Rw11Cpu::kCp_cpurust_reset;
89
const uint16_t  Rw11Cpu::kCp_cpurust_stop;
90
const uint16_t  Rw11Cpu::kCp_cpurust_step;
91
const uint16_t  Rw11Cpu::kCp_cpurust_susp;
92
const uint16_t  Rw11Cpu::kCp_cpurust_runs;
93
const uint16_t  Rw11Cpu::kCp_cpurust_vecfet;
94
const uint16_t  Rw11Cpu::kCp_cpurust_recrsv;
95
const uint16_t  Rw11Cpu::kCp_cpurust_sfail;
96
const uint16_t  Rw11Cpu::kCp_cpurust_vfail;
97
 
98 20 wfjm
const uint16_t  Rw11Cpu::kCp_ah_m_addr;
99
const uint16_t  Rw11Cpu::kCp_ah_m_22bit;
100
const uint16_t  Rw11Cpu::kCp_ah_m_ubmap;
101
 
102 19 wfjm
//------------------------------------------+-----------------------------------
103
//! Constructor
104
 
105
Rw11Cpu::Rw11Cpu(const std::string& type)
106
  : fpW11(0),
107
    fType(type),
108
    fIndex(0),
109
    fBase(0),
110
    fCpuGo(0),
111
    fCpuStat(0),
112
    fCpuGoMutex(),
113
    fCpuGoCond(),
114
    fCntlMap(),
115
    fStats()
116
{}
117
 
118
//------------------------------------------+-----------------------------------
119
//! Destructor
120
 
121
Rw11Cpu::~Rw11Cpu()
122
{}
123
 
124
//------------------------------------------+-----------------------------------
125
//! FIXME_docs
126
 
127
void Rw11Cpu::Setup(Rw11* pw11)
128
{
129
  fpW11 = pw11;
130
  // command base: 'cn.', where n is cpu index
131
  string cbase = "c";
132
  cbase += '0'+Index();
133
  cbase += '.';
134
  Connect().AddrMapInsert(cbase+"conf", Base()+kCp_addr_conf);
135
  Connect().AddrMapInsert(cbase+"cntl", Base()+kCp_addr_cntl);
136
  Connect().AddrMapInsert(cbase+"stat", Base()+kCp_addr_stat);
137
  Connect().AddrMapInsert(cbase+"psw" , Base()+kCp_addr_psw);
138
  Connect().AddrMapInsert(cbase+"al"  , Base()+kCp_addr_al);
139
  Connect().AddrMapInsert(cbase+"ah"  , Base()+kCp_addr_ah);
140
  Connect().AddrMapInsert(cbase+"mem" , Base()+kCp_addr_mem);
141
  Connect().AddrMapInsert(cbase+"memi", Base()+kCp_addr_memi);
142
  Connect().AddrMapInsert(cbase+"r0"  , Base()+kCp_addr_r0);
143
  Connect().AddrMapInsert(cbase+"r1"  , Base()+kCp_addr_r0+1);
144
  Connect().AddrMapInsert(cbase+"r2"  , Base()+kCp_addr_r0+2);
145
  Connect().AddrMapInsert(cbase+"r3"  , Base()+kCp_addr_r0+3);
146
  Connect().AddrMapInsert(cbase+"r4"  , Base()+kCp_addr_r0+4);
147
  Connect().AddrMapInsert(cbase+"r5"  , Base()+kCp_addr_r0+5);
148
  Connect().AddrMapInsert(cbase+"sp"  , Base()+kCp_addr_r0+6);
149
  Connect().AddrMapInsert(cbase+"pc"  , Base()+kCp_addr_r0+7);
150
  Connect().AddrMapInsert(cbase+"ibrb", Base()+kCp_addr_ibrb);
151
  // create names for ib window, line c0.ib00, c0.ib02,.., c0.ib76
152
  for (int i=0; i<32; i++) {
153
    string rname = cbase + "ib";
154
    rname += '0' + ((i>>2)&07);
155
    rname += '0' + ((i<<1)&07);
156
    Connect().AddrMapInsert(rname , Base()+kCp_addr_ibr+i);
157
  }
158
  return;
159
}
160
 
161
//------------------------------------------+-----------------------------------
162
//! FIXME_docs
163
 
164
void Rw11Cpu::AddCntl(const boost::shared_ptr<Rw11Cntl>& spcntl)
165
{
166
  if (!spcntl)
167
    throw Rexception("Rw11Cpu::AddCntl","Bad args: spcntl == 0");
168
 
169
  string name(spcntl->Name());
170
  if (fCntlMap.find(name) != fCntlMap.end())
171
    throw Rexception("Rw11Cpu::AddCntl",
172
                     "Bad state: duplicate controller name");;
173
 
174
  fCntlMap.insert(cmap_val_t(name, spcntl));
175
  spcntl->SetCpu(this);
176
  return;
177
}
178
 
179
//------------------------------------------+-----------------------------------
180
//! FIXME_docs
181
 
182
bool Rw11Cpu::TestCntl(const std::string& name) const
183
{
184
  return fCntlMap.find(name) != fCntlMap.end();
185
}
186
 
187
//------------------------------------------+-----------------------------------
188
//! FIXME_docs
189
 
190
void Rw11Cpu::ListCntl(std::vector<std::string>& list) const
191
{
192
  list.clear();
193
  for (cmap_cit_t it=fCntlMap.begin(); it!=fCntlMap.end(); it++) {
194
    list.push_back((it->second)->Name());
195
  }
196
  return;
197
}
198
 
199
//------------------------------------------+-----------------------------------
200
//! FIXME_docs
201
 
202
Rw11Cntl& Rw11Cpu::Cntl(const std::string& name) const
203
{
204
  cmap_cit_t it=fCntlMap.find(name);
205
  if (it == fCntlMap.end())
206
    throw Rexception("Rw11Cpu::Cntl()",
207
                     "Bad args: controller name '" + name + "' unknown");
208
  return *(it->second);
209
}
210
 
211
//------------------------------------------+-----------------------------------
212
//! FIXME_docs
213
 
214
void Rw11Cpu::Start()
215
{
216
  for (cmap_cit_t it=fCntlMap.begin(); it!=fCntlMap.end(); it++) {
217
    Rw11Cntl& cntl(*(it->second));
218
    cntl.Probe();
219
    if (cntl.ProbeStatus().Found() && cntl.Enable()) {
220
      cntl.Start();
221
    }
222
  }
223
  return;
224
}
225
 
226
 
227
//------------------------------------------+-----------------------------------
228
//! FIXME_docs
229
 
230
std::string Rw11Cpu::NextCntlName(const std::string& base) const
231
{
232
  for (char let='a'; let<='z'; let++) {
233
    string name = base + let;
234
    if (fCntlMap.find(name) == fCntlMap.end()) return name;
235
  }
236
  throw Rexception("Rw11Cpu::NextCntlName",
237
                   "Bad args: all controller letters used for '" + base + "'");
238
  return "";
239
}
240
 
241
//------------------------------------------+-----------------------------------
242
//! FIXME_docs
243
 
244
int Rw11Cpu::AddIbrb(RlinkCommandList& clist, uint16_t ibaddr)
245
{
246
  return clist.AddWreg(fBase+kCp_addr_ibrb, ibaddr & ~(077));
247
}
248
 
249
//------------------------------------------+-----------------------------------
250
//! FIXME_docs
251
 
252
int Rw11Cpu::AddRibr(RlinkCommandList& clist, uint16_t ibaddr)
253
{
254
  uint16_t ibroff = (ibaddr & 077)/2;
255
  return clist.AddRreg(fBase+kCp_addr_ibr + ibroff);
256
}
257
 
258
//------------------------------------------+-----------------------------------
259
//! FIXME_docs
260
 
261
int Rw11Cpu::AddWibr(RlinkCommandList& clist, uint16_t ibaddr, uint16_t data)
262
{
263
  uint16_t ibroff = (ibaddr & 077)/2;
264
  return clist.AddWreg(fBase+kCp_addr_ibr + ibroff, data);
265
}
266
 
267
//------------------------------------------+-----------------------------------
268
//! FIXME_docs
269
 
270 20 wfjm
int Rw11Cpu::AddLalh(RlinkCommandList& clist, uint32_t addr, uint16_t mode)
271
{
272
  uint16_t al = uint16_t(addr);
273
  uint16_t ah = uint16_t(addr>>16) & kCp_ah_m_addr;
274
  ah |= mode & (kCp_ah_m_22bit|kCp_ah_m_ubmap);
275
  int ind = clist.AddWreg(fBase+kCp_addr_al, al);
276
  clist.AddWreg(fBase+kCp_addr_ah, ah);
277
  return ind;
278
}
279
 
280
//------------------------------------------+-----------------------------------
281
//! FIXME_docs
282
 
283
int Rw11Cpu::AddRMem(RlinkCommandList& clist, uint32_t addr,
284
                     uint16_t* buf, size_t size, uint16_t mode)
285
{
286
  int ind = AddLalh(clist, addr, mode);
287
  while (size > 0) {
288
    size_t bsize = (size>256) ? 256 : size;
289
    clist.AddRblk(fBase+kCp_addr_memi, buf, bsize);
290
    buf  += bsize;
291
    size -= bsize;
292
  }
293
  return ind;
294
}
295
 
296
//------------------------------------------+-----------------------------------
297
//! FIXME_docs
298
 
299
int Rw11Cpu::AddWMem(RlinkCommandList& clist, uint32_t addr,
300
                     const uint16_t* buf, size_t size, uint16_t mode)
301
{
302
  int ind = AddLalh(clist, addr, mode);
303
  while (size > 0) {
304
    size_t bsize = (size>256) ? 256 : size;
305
    clist.AddWblk(fBase+kCp_addr_memi, buf, bsize);
306
    buf  += bsize;
307
    size -= bsize;
308
  }
309
  return ind;
310
}
311
 
312
//------------------------------------------+-----------------------------------
313
//! FIXME_docs
314
 
315 19 wfjm
bool Rw11Cpu::MemRead(uint16_t addr, std::vector<uint16_t>& data,
316
                      size_t nword, RerrMsg& emsg)
317
{
318
  data.resize(nword);
319
  size_t ndone = 0;
320
  while (nword>ndone) {
321
    size_t nblk = min(size_t(256), nword-ndone);
322
    RlinkCommandList clist;
323
    clist.AddWreg(fBase+kCp_addr_al, addr+2*ndone);
324
    clist.AddRblk(fBase+kCp_addr_memi, data.data()+ndone, nblk);
325
    if (!Server().Exec(clist, emsg)) return false;
326
    ndone += nblk;
327
  }
328
  return true;
329
}
330
 
331
//------------------------------------------+-----------------------------------
332
//! FIXME_docs
333
 
334
bool Rw11Cpu::MemWrite(uint16_t addr, const std::vector<uint16_t>& data,
335
                       RerrMsg& emsg)
336
{
337
  size_t nword = data.size();
338
  size_t ndone = 0;
339
  while (nword>ndone) {
340
    size_t nblk = min(size_t(256), nword-ndone);
341
    RlinkCommandList clist;
342
    clist.AddWreg(fBase+kCp_addr_al, addr+2*ndone);
343
    clist.AddWblk(fBase+kCp_addr_memi, data.data()+ndone, nblk);
344
    if (!Server().Exec(clist, emsg)) return false;
345
    ndone += nblk;
346
  }
347
  return true;
348
}
349
 
350
//------------------------------------------+-----------------------------------
351
//! FIXME_docs
352
 
353
bool Rw11Cpu::ProbeCntl(Rw11Probe& dsc)
354
{
355
  if (!(dsc.fProbeInt | dsc.fProbeRem) || dsc.fAddr == 0)
356
    throw Rexception("Rw11Cpu::Probe",
357
                     "Bad args: fAddr == 0 or fProbeInt|fProbeRem == false");
358
 
359
  if (!dsc.fProbeDone) {
360
    RlinkCommandList clist;
361
    int iib = -1;
362
    int irb = -1;
363
    if (dsc.fProbeInt) {
364
      clist.AddWreg(fBase+kCp_addr_al,  dsc.fAddr);
365
      iib = clist.AddRreg(fBase+kCp_addr_mem);
366
      clist.LastExpect(new RlinkCommandExpect(0,0xff)); // disable stat checking
367
    }
368
    if (dsc.fProbeRem) {
369
      AddIbrb(clist, dsc.fAddr);
370
      irb = AddRibr(clist, dsc.fAddr);
371
      clist.LastExpect(new RlinkCommandExpect(0,0xff)); // disable stat checking
372
    }
373
 
374
    Server().Exec(clist);
375
    // FIXME_code: handle errors
376
 
377
    if (dsc.fProbeInt) {
378
      dsc.fFoundInt = (clist[iib].Status() & (RlinkCommand::kStat_M_RbNak |
379
                                              RlinkCommand::kStat_M_RbErr)) ==0;
380
    }
381
    if (dsc.fProbeRem) {
382
      dsc.fFoundRem = (clist[irb].Status() & (RlinkCommand::kStat_M_RbNak |
383
                                              RlinkCommand::kStat_M_RbErr)) ==0;
384
    }
385
    dsc.fProbeDone = true;
386
  }
387
 
388
  return dsc.Found();
389
}
390
 
391
//------------------------------------------+-----------------------------------
392
//! FIXME_docs
393
 
394
// absolute binary format described in notes_ptape.txt
395
 
396
bool Rw11Cpu::LoadAbs(const std::string& fname, RerrMsg& emsg, bool trace)
397
{
398
  int fd = open(fname.c_str(), O_RDONLY);
399
 
400
  if (fd < 0) {
401
    emsg.InitErrno("Rw11Cpu::LoadAbs()", string("open() for '") + fname +
402 21 wfjm
                   "' failed: ", errno);
403 19 wfjm
    return false;
404
  }
405
 
406
  enum states {
407
    s_chr0,
408
    s_chr1,
409
    s_cntlow,
410
    s_cnthgh,
411
    s_adrlow,
412
    s_adrhgh,
413
    s_data,
414
    s_chksum
415
  };
416
 
417
  typedef std::map<uint16_t, uint16_t> obmap_t;
418
  typedef obmap_t::iterator         obmap_it_t;
419
  typedef obmap_t::const_iterator   obmap_cit_t;
420
  typedef obmap_t::value_type       obmap_val_t;
421
 
422
  obmap_t oddbyte;                          // odd byte cache
423
 
424
  vector<uint16_t> data;
425
  data.reserve(256);
426
 
427
  int chrnum = -1;                          // char number in block
428
  int blknum = 0;                           // block number
429
  int bytcnt = 0;                           // byte count
430
  uint16_t ldaddr = 0;                      // load address
431
  uint8_t chksum = 0;                       // check sum
432
  uint16_t addr = 0;                        // current address
433
  uint16_t word = 0;                        // current word
434
 
435
  bool ok = false;
436
  bool go = true;
437
  enum states state = s_chr0;
438
 
439
  while (go) {
440
    uint8_t byte;
441
    int irc = read(fd, &byte, 1);
442
    if (irc == 0) {
443
      if (state == s_chr0) {
444
        ok = true;
445
      } else {
446
        emsg.Init("Rw11Cpu::LoadAbs()", "unexpected EOF");
447
      }
448
      break;
449
    } else if (irc < 0) {
450
      emsg.InitErrno("Rw11Cpu::LoadAbs()", "read() failed: ", errno);
451
      break;
452
    }
453
 
454
    chrnum += 1;
455
    chksum += byte;
456
 
457
    //cout << "+++1 " << blknum << "," << chrnum << " s=" << state << " : " 
458
    //     << RosPrintBvi(byte,8) << endl;
459
 
460
    switch (state) {
461
    case s_chr0:
462
      if (byte == 0) {
463
        chrnum = -1;
464
        state = s_chr0;
465
      } else if (byte == 1) {
466
        state = s_chr1;
467
      } else {
468
        emsg.InitPrintf("Rw11Cpu::LoadAbs()",
469
                        "unexpected start-of-block %3.3o", byte);
470
        go = false;
471
      }
472
      break;
473
 
474
    case s_chr1:
475
      if (byte == 0) {
476
        state = s_cntlow;
477
      } else {
478
        emsg.InitPrintf("Rw11Cpu::LoadAbs()",
479
                        "unexpected 2nd char %3.3o", byte);
480
        go = false;
481
      }
482
      break;
483
 
484
    case s_cntlow:
485
      bytcnt = byte;
486
      state  = s_cnthgh;
487
      break;
488
 
489
    case s_cnthgh:
490
      bytcnt |= uint16_t(byte) << 8;
491
      state  = s_adrlow;
492
      break;
493
 
494
    case s_adrlow:
495
      ldaddr = byte;
496
      state = s_adrhgh;
497
      break;
498
 
499
    case s_adrhgh:
500
      ldaddr |= uint16_t(byte) << 8;
501
      addr = ldaddr;
502
      word = 0;
503
      if ((addr & 0x01) == 1 && bytcnt > 6) {
504
        obmap_cit_t it = oddbyte.find(addr);
505
        if (it != oddbyte.end()) {
506
          word = it->second;
507
        } else {
508
          if (trace) {
509
            RlogMsg lmsg(LogFile());
510
            lmsg << "LoadAbs-W: no low byte data for " << RosPrintBvi(addr,8);
511
          }
512
        }
513
      }
514
 
515
      if (trace) {
516
        RlogMsg lmsg(Connect().LogFile());
517
        lmsg << "LoadAbs-I: block " << RosPrintf(blknum,"d",3)
518
             << ", length " << RosPrintf(bytcnt-6,"d",5)
519
             << " byte, address " << RosPrintBvi(ldaddr,8)
520
             << ":" << RosPrintBvi(uint16_t(ldaddr+(bytcnt-6)-1),8);
521
      }
522
      state = (bytcnt == 6) ? s_chksum : s_data;
523
      break;
524
 
525
    case s_data:
526
      if ((addr & 0x01) == 0) {             // even (low) byte
527
        word = byte;
528
      } else {                              // odd (high) byte
529
        word |= uint16_t(byte) << 8;
530
        data.push_back(word);
531
      }
532
      addr += 1;
533
      if (chrnum == bytcnt-1) state = s_chksum;
534
      break;
535
 
536
    case s_chksum:
537
      if (chksum != 0) {
538
        emsg.InitPrintf("Rw11Cpu::LoadAbs()", "check sum error %3.3o", chksum);
539
        go = false;
540
      } else if (bytcnt == 6) {
541
        if (trace) {
542
          RlogMsg lmsg(Connect().LogFile());
543
          lmsg << "LoadAbs-I: start address " << RosPrintBvi(ldaddr,8);
544
        }
545
        go = false;
546
        ok = true;
547
      } else {
548
        if ((addr & 0x01) == 1) {           // high byte not yet seen
549
          data.push_back(word);             // zero fill high byte
550
          oddbyte.insert(obmap_val_t(addr,word)); // store even byte for later
551
        }
552
 
553
        //cout << "+++2 " << RosPrintBvi(ldaddr,8) 
554
        //     << " " << data.size() << endl;
555
 
556
        if (!MemWrite(ldaddr, data, emsg)) {
557
          go = false;
558
        }
559
        data.clear();
560
      }
561
      chrnum = -1;
562
      blknum += 1;
563
      state = s_chr0;
564
      break;
565
 
566
    } // switch(state)
567
  } // while(go)
568
 
569
  close(fd);
570
 
571
  return ok;
572
}
573
 
574
//------------------------------------------+-----------------------------------
575
//! FIXME_docs
576
 
577
bool Rw11Cpu::Boot(const std::string& uname, RerrMsg& emsg)
578
{
579
  string cname;
580
  size_t uind=0;
581
  for (size_t i=0; i<uname.length(); i++) {
582
    char c = uname[i];
583
    if (c >= '0' && c <= '9') {
584
      string unum = cname.substr(i);
585 22 wfjm
      uind = ::atoi(unum.c_str());
586 19 wfjm
      break;
587
    } else {
588
      cname.push_back(c);
589
    }
590
  }
591
 
592
  if (!TestCntl(cname)) {
593 21 wfjm
    emsg.Init("Rw11Cpu::Boot", string("controller '") + cname + "' not known");
594 19 wfjm
    return false;
595
  }
596
 
597
  // FIXME_code: unit number not checked. Cntl doesn't even know about ...
598
 
599
  Rw11Cntl& cntl = Cntl(cname);
600
 
601
  vector<uint16_t> code;
602
  uint16_t aload = 0;
603
  uint16_t astart = 0;
604
 
605
  if (!cntl.BootCode(uind, code, aload, astart) || code.size()==0) {
606
    emsg.Init("Rw11Cpu::Boot", string("boot not supported for controller '")
607 21 wfjm
              + cname + "'");
608 19 wfjm
    return false;
609
  }
610
 
611
  if (!MemWrite(aload, code, emsg)) return false;
612
 
613
  RlinkCommandList clist;
614
  clist.AddWreg(fBase+kCp_addr_pc, astart);
615
  clist.AddWreg(fBase+kCp_addr_cntl, kCp_func_start);
616
  SetCpuGoUp();
617
  if (!Server().Exec(clist, emsg)) return false;
618
 
619
  return true;
620
}
621
 
622
//------------------------------------------+-----------------------------------
623
//! FIXME_docs
624
 
625
void Rw11Cpu::SetCpuGoUp()
626
{
627
  boost::lock_guard<boost::mutex> lock(fCpuGoMutex);
628
  fCpuGo   = true;
629
  fCpuStat = 0;
630
  fCpuGoCond.notify_all();
631
  return;
632
}
633
 
634
//------------------------------------------+-----------------------------------
635
//! FIXME_docs
636
 
637
void Rw11Cpu::SetCpuGoDown(uint16_t stat)
638
{
639
  if ((stat & kCp_stat_m_cpugo) == 0) {
640
    boost::lock_guard<boost::mutex> lock(fCpuGoMutex);
641
    fCpuGo   = false;
642
    fCpuStat = stat;
643
    fCpuGoCond.notify_all();
644
  }
645
  return;
646
}
647
 
648
//------------------------------------------+-----------------------------------
649
//! FIXME_docs
650
 
651
double Rw11Cpu::WaitCpuGoDown(double tout)
652
{
653
  boost::system_time t0(boost::get_system_time());
654
  boost::system_time timeout(boost::posix_time::max_date_time);
655
  if (tout > 0.)
656
    timeout = t0 + boost::posix_time::microseconds((long)1E6 * tout);
657
  boost::unique_lock<boost::mutex> lock(fCpuGoMutex);
658
  while (fCpuGo) {
659
    if (!fCpuGoCond.timed_wait(lock, timeout)) return -1.;
660
  }
661
  boost::posix_time::time_duration dt = boost::get_system_time() - t0;
662
  return double(dt.ticks()) / dt.ticks_per_second();
663
}
664
 
665
//------------------------------------------+-----------------------------------
666
//! FIXME_docs
667
 
668
void Rw11Cpu::W11AttnHandler()
669
{
670
  RlinkCommandList clist;
671
  clist.AddRreg(fBase+kCp_addr_stat);
672
  if (Server().Exec(clist))
673
    SetCpuGoDown(clist[0].Data());
674
  return;
675
}
676
 
677
//------------------------------------------+-----------------------------------
678
//! FIXME_docs
679
 
680
void Rw11Cpu::Dump(std::ostream& os, int ind, const char* text) const
681
{
682
  RosFill bl(ind);
683
  os << bl << (text?text:"--") << "Rw11Cpu @ " << this << endl;
684
 
685
  os << bl << "  fpW11:           " << fpW11 << endl;
686
  os << bl << "  fType:           " << fType << endl;
687
  os << bl << "  fIndex:          " << fIndex << endl;
688
  os << bl << "  fBase:           " << RosPrintf(fBase,"$x0",4) << endl;
689
  os << bl << "  fCpuGo:          " << fCpuGo << endl;
690
  os << bl << "  fCpuStat:        " << RosPrintf(fCpuStat,"$x0",4) << endl;
691
  os << bl << "  fCntlMap:        " << endl;
692
  for (cmap_cit_t it=fCntlMap.begin(); it!=fCntlMap.end(); it++) {
693
    os << bl << "    " << RosPrintf((it->first).c_str(), "-s",8)
694
       << " : " << it->second << endl;
695
  }
696
  fStats.Dump(os, ind+2, "fStats: ");
697
  return;
698
}
699
 
700
} // end namespace Retro

powered by: WebSVN 2.1.0

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