You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
piklab/src/devices/base/register.cpp

157 lines
4.5 KiB

/***************************************************************************
* 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. *
***************************************************************************/
#include "register.h"
//----------------------------------------------------------------------------
namespace Register
{
List *_list = 0;
}
Register::List &Register::list()
{
if ( _list==0 ) _list = new List;
return *_list;
}
//----------------------------------------------------------------------------
Register::TypeData::TypeData(Address address, uint nbChars)
: _nbChars(nbChars), _address(address)
{
Q_ASSERT( address.isValid() && nbChars!=0 );
}
Register::TypeData::TypeData(const TQString &name, uint nbChars)
: _nbChars(nbChars), _name(name)
{
Q_ASSERT( !name.isEmpty() && nbChars!=0 );
}
Register::TypeData::TypeData(const TQString &name, Address address, uint nbChars)
: _nbChars(nbChars), _address(address), _name(name)
{
Q_ASSERT( address.isValid() && nbChars!=0 && !name.isEmpty() );
}
Register::Type Register::TypeData::type() const
{
if ( !_address.isValid() ) {
if ( _name.isEmpty() ) return Invalid;
return Special;
}
if ( _name.isEmpty() ) return Regular;
return Combined;
}
TQString Register::TypeData::toString() const
{
return TQString("%1 %2 %3").tqarg(toLabel(_address)).tqarg(_nbChars).tqarg(_name);
}
Register::TypeData Register::TypeData::fromString(const TQString &s)
{
TQStringList list = TQStringList::split(" ", s);
if ( list.count()<2 || list.count()>3 ) return TypeData();
bool ok;
Address address = list[0].toUInt(&ok);
if ( !ok ) return TypeData();
uint nbChars = list[1].toUInt(&ok);
if ( !ok || nbChars==0 || (nbChars%2)!=0 ) return TypeData();
TQString name;
if ( list.count()==3 ) name = list[2];
if ( !address.isValid() ) {
if ( name.isEmpty() ) return TypeData();
return TypeData(name, nbChars);
}
if ( name.isEmpty() ) return TypeData(address, nbChars);
return TypeData(name, address, nbChars);
}
//----------------------------------------------------------------------------
void Register::List::init()
{
_regulars.clear();
_specials.clear();
_watched.clear();
_portDatas.clear();
delayedChanged();
}
void Register::List::setWatched(const TypeData &data, bool watched)
{
if (watched) {
if ( _watched.contains(data) ) return;
_watched.append(data);
} else _watched.remove(data);
delayedChanged();
}
void Register::List::clearWatched()
{
_watched.clear();
delayedChanged();
}
void Register::List::setValue(const TypeData &data, BitValue value)
{
if ( !data.address().isValid() ) {
_specials[data.name()].old = _specials[data.name()].current;
_specials[data.name()].current = value;
} else {
Q_ASSERT( (data.nbChars()%2)==0 );
uint nb = data.nbChars()/2;
for (uint i=0; i<nb; i++) {
Address address = data.address() + i;
_regulars[address].old = _regulars[address].current;
_regulars[address].current = value.byte(i);
}
}
delayedChanged();
}
void Register::List::setPortData(uint index, const TQMap<uint, Device::PortBitData> &data)
{
_portDatas[index].old = _portDatas[index].current;
_portDatas[index].current = data;
delayedChanged();
}
BitValue Register::List::value(const TypeData &data) const
{
if ( !data.address().isValid() ) {
if ( !_specials.contains(data.name()) ) return BitValue();
return _specials[data.name()].current;
}
Q_ASSERT( (data.nbChars()%2)==0 );
uint nb = data.nbChars()/2;
BitValue value = 0;
for (int i=nb-1; i>=0; i--) {
value <<= 8;
BitValue v = _regulars[data.address() + i].current;
if ( !v.isInitialized() ) return BitValue();
value += v;
}
return value;
}
BitValue Register::List::oldValue(const TypeData &data) const
{
if ( !data.address().isValid() ) {
if ( !_specials.contains(data.name()) ) return BitValue();
return _specials[data.name()].old;
}
Q_ASSERT( (data.nbChars()%2)==0 );
uint nb = data.nbChars()/2;
BitValue value = 0;
for (int i=nb-1; i>=0; i--) {
value <<= 8;
BitValue v = _regulars[data.address() + i].old;
if ( !v.isInitialized() ) return BitValue();
value += v;
}
return value;
}