summaryrefslogtreecommitdiffstats
path: root/src/devices/base/register.h
blob: 5e89f91e3d1912dbe6e8615f0fd360abcf0a9526 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/***************************************************************************
 *   Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org>                  *
 *                                                                         *
 *   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.                                   *
 ***************************************************************************/
#ifndef REGISTER_H
#define REGISTER_H

#include "common/common/storage.h"
#include "devices/base/generic_device.h"
namespace Register { class TypeData; }

namespace Device
{
enum RegisterProperty { NotAccessible = 0x0, Readable = 0x1, Writable = 0x2 };
TQ_DECLARE_FLAGS(RegisterProperties, RegisterProperty)
TQ_DECLARE_OPERATORS_FOR_FLAGS(RegisterProperties)

enum { MAX_NB_PORTS = 8 };
enum { MAX_NB_PORT_BITS = 16 };
enum BitState { Low = 0, High, WeakPullUp, WeakPullDown, HighImpedance, Unknown };
enum IoState { IoLow = 0, IoHigh, IoUnknown };
class PortBitData {
public:
  PortBitData() : state(Unknown), driving(false), drivenState(IoUnknown), drivingState(IoUnknown) {}
  BitState state;
  bool driving;
  IoState drivenState, drivingState;
  bool operator !=(const PortBitData &pdb) const {
    return ( state!=pdb.state || driving!=pdb.driving || drivenState!=pdb.drivenState || drivingState!=pdb.drivingState );
  }
};

} // namespace

namespace Register
{
//----------------------------------------------------------------------------
enum Type { Regular, Special, Combined, Invalid };
class TypeData {
public:
  TypeData() : _nbChars(0) {}
  TypeData(Address address, uint nbChars);
  TypeData(const TQString &name, uint nbChars);
  TypeData(const TQString &name, Address address, uint nbChars);
  bool operator ==(const TypeData &data) const { return _name==data._name && _address==data._address && _nbChars==data._nbChars; }
  Type type() const;
  TQString name() const { return _name; }
  Address address() const { return _address; }
  uint nbChars() const { return _nbChars; }
  TQString toString() const;
  static TypeData fromString(const TQString &s);

private:
  uint    _nbChars;
  Address _address;
  TQString _name;
};

} // namespace

namespace Device
{
//----------------------------------------------------------------------------
class RegistersData
{
public:
  RegistersData() {}
  virtual ~RegistersData() {}
  virtual uint nbRegisters() const = 0;
  virtual uint nbBits() const = 0;
  uint nbBytes() const { return nbBitsToNbBytes(nbBits()); }
  uint nbChars() const { return nbBitsToNbChars(nbBits()); }
  virtual uint addressFromIndex(uint i) const = 0;
  virtual uint indexFromAddress(Address address) const = 0;
  virtual RegisterProperties properties(Address address) const = 0;
  virtual TQValueList<Register::TypeData> relatedRegisters(const Register::TypeData &data) const = 0;
  virtual bool hasPort(uint index) const = 0;
  virtual int portIndex(Address address) const = 0;
  virtual TQString portName(uint index) const = 0;
  virtual bool hasPortBit(uint index, uint bit) const = 0;
  virtual TQString portBitName(uint index, uint bit) const = 0;
};

} // namespace

namespace Register
{
//----------------------------------------------------------------------------
class List;
extern List &list();

class List : public GenericStorage
{
Q_OBJECT
  TQ_OBJECT
public:
  List() : GenericStorage(0, "register_list") {}
  void init();
  void setWatched(const TypeData &data, bool watched);
  void clearWatched();
  const TQValueList<TypeData> &watched() const { return _watched; }
  bool isWatched(const TypeData &data) const { return _watched.tqcontains(data); }
  void setValue(const TypeData &data, BitValue value);
  BitValue value(const TypeData &data) const;
  BitValue oldValue(const TypeData &data) const;
  void setPortData(uint index, const TQMap<uint, Device::PortBitData> &data);
  TQMap<uint, Device::PortBitData> portData(uint index) const { return _portDatas[index].current; }
  TQMap<uint, Device::PortBitData> oldPortData(uint index) const { return _portDatas[index].old; }

private:
  class StateData {
  public:
    BitValue current, old;
  };
  TQMap<Address, StateData> _regulars; // registers with address
  TQMap<TQString, StateData> _specials; // registers with no address
  class PortData {
  public:
    TQMap<uint, Device::PortBitData> current, old;
  };
  TQMap<uint, PortData> _portDatas; // port index
  TQValueList<TypeData> _watched;
};

} // namespace

#endif