Michael Hennebry:
> Would something like this help:
[snip]

To me this looks a bit like reinventing std::function/std::bind.

But I'd do something similar to your proposal, using std::function that
was added in C++11. GCC in current Debian stable is 6.3.0. Since GCC/g++
6, -std= defaults to c++14, so the feature is available for free:

http://en.cppreference.com/w/cpp/utility/functional


Step 1:
------
In IOReg class remove the template parameter and change the
getter_t/setter_t to:

  typedef std::function<unsigned char(void)> getter_t;
  typedef std::function<void(unsigned char)> setter_t;


Step 2:
------
Peripherals then need to be updated like this:
    ddr_reg(this, "DDR",
-           this, &HWPort::GetDdr, &HWPort::SetDdr),
+           std::bind(&HWPort::GetDdr, this),
+           std::bind(&HWPort::SetDdr, this, std::placeholders::_1))

Up to here, I've already implemented it. Testsuite runs through mostly
fine*. A patch is attached.

Step 3:
------
Add a set_bit(unsigned char bitpos, bool val) to IOReg, provide RMW
default implementation if no specific callback for Set_bit was given.
Then fix the insn decoder in AvrDevice.


Discussion:
----------
The syntax could be simpified if the IOReg itself (or RWMemoryMember)
handled their unsigned char value themselves, instead of being a wrapper
to get/set callbacks. We could then change the implementation of IOReg
to just trigger "OnWrite" or "OnRead" callbacks that don't need any
parameters, thus, we could omit the std::placeholders::_1.
The IOReg/RWMemoryMember would then also make sure that the tracers are
updated, which should avoid bugs related to wrong/forgotten tracing as
it already happend multiple times.


Cheers,
panic


*:
I'm getting a testsuite error with the normal HEAD that also appears
with my patch. To me, the test case seems to have a one-off issue. When
I add round() to the testcase, they run fine:

> ----------------------- regress/modtest/adc_diff_t25.py 
> -----------------------
> @@@ -46,7 -46,7 +46,7 @@@ class TestCase(SimTestCase)
>      else:
>        rng = 512
>      v = self.sim.getWordByName(self.dev, "adc_value")
> -    e = int(((pValue - nValue) / refValue) * rng) & 0x3ff
> +    e = int(round((pValue - nValue) / refValue)) * rng) & 0x3ff
>      self.assertEqual(v, e, "expected adc value is 0x%x, got 0x%x" % (e, v))
>  
>    def test_00(self):

Since the upgrade to GCC 6, I see another testsuite error (already
occurs when run on HEAD, independent of my changes):

> ======================================================================
> FAIL: test_00 (eeprom.TestCase)
> eeprom_atmega16::check read and write eeprom data
> ----------------------------------------------------------------------
> Traceback (most recent call last):
>   File "eeprom.py", line 70, in test_00
>     self.assertValue(0x66)
>   File "eeprom.py", line 19, in assertValue
>     self.assertComplete()
>   File "eeprom.py", line 16, in assertComplete
>     self.assertEqual(c, 1, "function isn't complete (complete=%d)" % c)
> AssertionError: function isn't complete (complete=2)
> 
> ======================================================================
> FAIL: test_00 (eeprom.TestCase)
> eeprom_atmega128::check read and write eeprom data
> ----------------------------------------------------------------------
> Traceback (most recent call last):
>   File "eeprom.py", line 54, in test_00
>     self.assertValue(0x33)
>   File "eeprom.py", line 19, in assertValue
>     self.assertComplete()
>   File "eeprom.py", line 16, in assertComplete
>     self.assertEqual(c, 1, "function isn't complete (complete=%d)" % c)
> AssertionError: function isn't complete (complete=2)
> 
> ----------------------------------------------------------------------
>From 98fad9ff5e430a4cb03dad2e4703661098de66e4 Mon Sep 17 00:00:00 2001
From: panic <li...@xandea.de>
Date: Sun, 18 Jun 2017 00:10:51 +0200
Subject: [PATCH 3/3] use std::function instead of template class for IOReg

---
 src/flashprog.cpp       |  3 ++-
 src/flashprog.h         |  2 +-
 src/hwacomp.cpp         |  2 +-
 src/hwacomp.h           |  2 +-
 src/hwad.cpp            | 10 +++----
 src/hwad.h              | 10 +++----
 src/hweeprom.cpp        |  8 +++---
 src/hweeprom.h          |  2 +-
 src/hwpinchange.cpp     | 14 +++++-----
 src/hwpinchange.h       |  4 +--
 src/hwport.cpp          |  9 ++++---
 src/hwport.h            |  2 +-
 src/hwspi.cpp           |  6 ++---
 src/hwspi.h             |  6 ++---
 src/hwstack.cpp         |  4 +--
 src/hwstack.h           |  4 +--
 src/hwtimer/hwtimer.cpp | 70 ++++++++++++++++++++++++-------------------------
 src/hwtimer/hwtimer.h   | 70 ++++++++++++++++++++++++-------------------------
 src/hwuart.cpp          | 27 ++++++++++++-------
 src/hwuart.h            |  8 +++---
 src/hwusi.cpp           |  8 +++---
 src/hwusi.h             |  8 +++---
 src/hwwado.cpp          |  2 +-
 src/hwwado.h            |  2 +-
 src/ioregs.cpp          |  3 ++-
 src/ioregs.h            |  2 +-
 src/rwmem.h             | 23 +++++++---------
 27 files changed, 160 insertions(+), 151 deletions(-)

diff --git a/src/flashprog.cpp b/src/flashprog.cpp
index 9f98e5e..8dd562a 100644
--- a/src/flashprog.cpp
+++ b/src/flashprog.cpp
@@ -58,7 +58,8 @@ FlashProgramming::FlashProgramming(AvrDevice *c,
     nrww_addr(nrww),
     core(c),
     spmcr_reg(c, "SPMCR",
-              this, &FlashProgramming::GetSpmcr, &FlashProgramming::SetSpmcr)
+              std::bind(&FlashProgramming::GetSpmcr, this),
+              std::bind(&FlashProgramming::SetSpmcr, this, std::placeholders::_1))
 {
     // initialize hidden buffer
     tempBuffer = avr_new(unsigned char, pgsz * 2);
diff --git a/src/flashprog.h b/src/flashprog.h
index 595358c..5eec49a 100644
--- a/src/flashprog.h
+++ b/src/flashprog.h
@@ -92,7 +92,7 @@ class FlashProgramming: public Hardware {
         void SetSpmcr(unsigned char v);
         unsigned char GetSpmcr() { return spmcr_val; }
 
-        IOReg<FlashProgramming> spmcr_reg;
+        IOReg spmcr_reg;
         
 };
 
diff --git a/src/hwacomp.cpp b/src/hwacomp.cpp
index 9ed3271..cd343c6 100644
--- a/src/hwacomp.cpp
+++ b/src/hwacomp.cpp
@@ -52,7 +52,7 @@ HWAcomp::HWAcomp(AvrDevice *core,
     timerB(_timerB),
     ad(_ad),
     sfior(_sfior),
-    acsr_reg(this, "ACSR", this, &HWAcomp::GetAcsr, &HWAcomp::SetAcsr)
+    acsr_reg(this, "ACSR", std::bind(&HWAcomp::GetAcsr, this), std::bind(&HWAcomp::SetAcsr, this, std::placeholders::_1))
 {
     // just check right assignment of IRQ vector number
     irqSystem->DebugVerifyInterruptVector(irqVec, this);
diff --git a/src/hwacomp.h b/src/hwacomp.h
index 8b387fc..c7456bc 100644
--- a/src/hwacomp.h
+++ b/src/hwacomp.h
@@ -79,7 +79,7 @@ class HWAcomp: public Hardware,
             ACIS0 = 0x01
         };
 
-        IOReg<HWAcomp> acsr_reg; //!< ACSR IO register
+        IOReg acsr_reg; //!< ACSR IO register
 
         //! constructor to instantiate a analog comparator peripheral
         HWAcomp(AvrDevice *core,
diff --git a/src/hwad.cpp b/src/hwad.cpp
index cd45a40..968e68c 100644
--- a/src/hwad.cpp
+++ b/src/hwad.cpp
@@ -308,11 +308,11 @@ HWAd::HWAd(AvrDevice *c, int _typ, HWIrqSystem *i, unsigned int iv, HWAdmux *a,
     irqSystem(i),
     irqVec(iv),
     notifyClient(NULL),
-    adch_reg(this, "ADCH",  this, &HWAd::GetAdch, 0),
-    adcl_reg(this, "ADCL",  this, &HWAd::GetAdcl, 0),
-    adcsra_reg(this, "ADCSRA", this, &HWAd::GetAdcsrA, &HWAd::SetAdcsrA),
-    adcsrb_reg(this, "ADCSRB", this, &HWAd::GetAdcsrB, &HWAd::SetAdcsrB),
-    admux_reg(this, "ADMUX", this, &HWAd::GetAdmux, &HWAd::SetAdmux) {
+    adch_reg(this, "ADCH",      std::bind(&HWAd::GetAdch, this)),
+    adcl_reg(this, "ADCL",      std::bind(&HWAd::GetAdcl, this)),
+    adcsra_reg(this, "ADCSRA",  std::bind(&HWAd::GetAdcsrA, this), std::bind(&HWAd::SetAdcsrA, this, std::placeholders::_1)),
+    adcsrb_reg(this, "ADCSRB",  std::bind(&HWAd::GetAdcsrB, this), std::bind(&HWAd::SetAdcsrB, this, std::placeholders::_1)),
+    admux_reg(this, "ADMUX",    std::bind(&HWAd::GetAdmux, this),  std::bind(&HWAd::SetAdmux, this, std::placeholders::_1)) {
     mux->RegisterNotifyClient(this);
     irqSystem->DebugVerifyInterruptVector(irqVec, this);
     core->AddToCycleList(this);
diff --git a/src/hwad.h b/src/hwad.h
index c0a4a1e..6e85604 100644
--- a/src/hwad.h
+++ b/src/hwad.h
@@ -240,11 +240,11 @@ class HWAd: public Hardware, public TraceValueRegister, public AnalogSignalChang
             AD_T25   //!< ADC type T25: ADC on attiny25/45/85
         };
 
-        IOReg<HWAd> adch_reg,
-                    adcl_reg,
-                    adcsra_reg,
-                    adcsrb_reg,
-                    admux_reg;
+        IOReg adch_reg,
+              adcl_reg,
+              adcsra_reg,
+              adcsrb_reg,
+              admux_reg;
 
         HWAd(AvrDevice *c, int _typ, HWIrqSystem *i, unsigned int iv, HWAdmux *a, HWARef *r);
         virtual ~HWAd() { mux->UnregisterNotifyClient(); }
diff --git a/src/hweeprom.cpp b/src/hweeprom.cpp
index cd34d76..bb938c5 100644
--- a/src/hweeprom.cpp
+++ b/src/hweeprom.cpp
@@ -44,13 +44,13 @@ HWEeprom::HWEeprom(AvrDevice *_core,
     irqSystem(_irqSystem),
     irqVectorNo(irqVec),
     eearh_reg(this, "EEARH",
-              this, &HWEeprom::GetEearh, &HWEeprom::SetEearh),
+              std::bind(&HWEeprom::GetEearh, this), std::bind(&HWEeprom::SetEearh, this, std::placeholders::_1)),
     eearl_reg(this, "EEARL",
-              this, &HWEeprom::GetEearl, &HWEeprom::SetEearl),
+              std::bind(&HWEeprom::GetEearl, this), std::bind(&HWEeprom::SetEearl, this, std::placeholders::_1)),
     eedr_reg(this, "EEDR",
-             this, &HWEeprom::GetEedr, &HWEeprom::SetEedr),
+             std::bind(&HWEeprom::GetEedr, this), std::bind(&HWEeprom::SetEedr, this, std::placeholders::_1)),
     eecr_reg(this, "EECR",
-             this, &HWEeprom::GetEecr, &HWEeprom::SetEecr)
+             std::bind(&HWEeprom::GetEecr, this), std::bind(&HWEeprom::SetEecr, this, std::placeholders::_1))
 {
     if(irqSystem)
         irqSystem->DebugVerifyInterruptVector(irqVectorNo, this);
diff --git a/src/hweeprom.h b/src/hweeprom.h
index df50308..de7b4cb 100644
--- a/src/hweeprom.h
+++ b/src/hweeprom.h
@@ -97,7 +97,7 @@ class HWEeprom: public Hardware, public Memory, public TraceValueRegister {
         unsigned char GetEecr() { return eecr; }
         unsigned char GetEedr() { return eedr; }
 
-        IOReg<HWEeprom>
+        IOReg
             eearh_reg,
             eearl_reg,
             eedr_reg,
diff --git a/src/hwpinchange.cpp b/src/hwpinchange.cpp
index 43e4e3a..be398c2 100644
--- a/src/hwpinchange.cpp
+++ b/src/hwpinchange.cpp
@@ -28,10 +28,12 @@ HWPcir::HWPcir(	AvrDevice*		avr,
 		_vector5(vector5),
 		_vector6(vector6),
 		_vector7(vector7),
-        pcicr_reg(avr, "PINCHANGE.PCICR", this, &HWPcir::getPcicrMask,
-                  &HWPcir::setPcicrMask),
-        pcifr_reg(avr, "PINCHANGE.PCIFR", this, &HWPcir::getPcifrMask,
-                  &HWPcir::setPcifrMask)
+        pcicr_reg(avr, "PINCHANGE.PCICR",
+                  std::bind(&HWPcir::getPcicrMask, this),
+                  std::bind(&HWPcir::setPcicrMask, this, std::placeholders::_1)),
+        pcifr_reg(avr, "PINCHANGE.PCIFR",
+                  std::bind(&HWPcir::getPcifrMask, this),
+                  std::bind(&HWPcir::setPcifrMask, this, std::placeholders::_1))
 {
 	assert(false);  // Unreachable. No code ever constructs this class.
 	irqSystem.DebugVerifyInterruptVector(_vector0, this);
@@ -211,8 +213,8 @@ HWPcmsk::HWPcmsk(
 		_pcmsk(0),
 		_pcifrBit(pcifrBit),
         pcmsk_reg(core, "PINCHANGE.PCMSK",
-                  this, &HWPcmsk::getPcmskMask,
-                  &HWPcmsk::setPcmskMask)
+                  std::bind(&HWPcmsk::getPcmskMask, this),
+                  std::bind(&HWPcmsk::setPcmskMask, this, std::placeholders::_1))
 		{
 			assert(false);  // Unreachable. No code ever constructs this class.
 	}
diff --git a/src/hwpinchange.h b/src/hwpinchange.h
index 0ab86d7..288a7c0 100644
--- a/src/hwpinchange.h
+++ b/src/hwpinchange.h
@@ -95,7 +95,7 @@ class HWPcir : public HWPcifrApi , public HWPcirMaskApi , public Hardware {
 		unsigned char	getPcicrMask() throw();
 
         
-        IOReg<HWPcir>
+        IOReg
             pcicr_reg,
             pcifr_reg;
         
@@ -128,7 +128,7 @@ class HWPcmsk : public HWPcmskApi , public HWPcmskPinApi {
 	public: // HWPcmskPinApi
 		void			pinChanged(unsigned bit) throw();
 
-        IOReg<HWPcmsk> pcmsk_reg;
+        IOReg pcmsk_reg;
 	};
 
 // This class monitors a single pin for changes
diff --git a/src/hwport.cpp b/src/hwport.cpp
index 662a47a..3f7e5a0 100644
--- a/src/hwport.cpp
+++ b/src/hwport.cpp
@@ -38,11 +38,14 @@ HWPort::HWPort(AvrDevice *core, const string &name, bool portToggle, int size):
     portSize(size),
     portToggleFeature(portToggle),
     port_reg(this, "PORT",
-             this, &HWPort::GetPort, &HWPort::SetPort),
+             std::bind(&HWPort::GetPort, this),
+             std::bind(&HWPort::SetPort, this, std::placeholders::_1)),
     pin_reg(this, "PIN",
-            this, &HWPort::GetPin, &HWPort::SetPin),
+            std::bind(static_cast<unsigned char(HWPort::*)()>(&HWPort::GetPin), this),
+            std::bind(&HWPort::SetPin, this, std::placeholders::_1)),
     ddr_reg(this, "DDR",
-            this, &HWPort::GetDdr, &HWPort::SetDdr)
+            std::bind(&HWPort::GetDdr, this),
+            std::bind(&HWPort::SetDdr, this, std::placeholders::_1))
 {
     assert((portSize >= 1) && (portSize <= sizeof(p)/sizeof(p[0])));
     portMask = (unsigned char)((1 << portSize) - 1);
diff --git a/src/hwport.h b/src/hwport.h
index eeeebd8..595f2a5 100644
--- a/src/hwport.h
+++ b/src/hwport.h
@@ -75,7 +75,7 @@ class HWPort: public Hardware, public TraceValueRegister {
 
         friend class PinAtPort;
 
-        IOReg<HWPort>
+        IOReg
             port_reg,
             pin_reg,
             ddr_reg;
diff --git a/src/hwspi.cpp b/src/hwspi.cpp
index 450e2e6..15a5bb2 100644
--- a/src/hwspi.cpp
+++ b/src/hwspi.cpp
@@ -175,9 +175,9 @@ HWSpi::HWSpi(AvrDevice *_c,
     core(_c), irq(_irq),
     MOSI(mosi), MISO(miso), SCK(sck), SS(ss),
     irq_vector(ivec), mega_mode(mm),
-    spdr_reg(this, "SPDR", this, &HWSpi::GetSPDR, &HWSpi::SetSPDR),
-    spsr_reg(this, "SPSR", this, &HWSpi::GetSPSR, &HWSpi::SetSPSR),
-    spcr_reg(this, "SPCR", this, &HWSpi::GetSPCR, &HWSpi::SetSPCR)
+    spdr_reg(this, "SPDR", std::bind(&HWSpi::GetSPDR, this), std::bind(&HWSpi::SetSPDR, this, std::placeholders::_1)),
+    spsr_reg(this, "SPSR", std::bind(&HWSpi::GetSPSR, this), std::bind(&HWSpi::SetSPSR, this, std::placeholders::_1)),
+    spcr_reg(this, "SPCR", std::bind(&HWSpi::GetSPCR, this), std::bind(&HWSpi::SetSPCR, this, std::placeholders::_1))
 {
     irq->DebugVerifyInterruptVector(ivec, this);
     bitcnt=8;
diff --git a/src/hwspi.h b/src/hwspi.h
index d0487cf..3cb3015 100644
--- a/src/hwspi.h
+++ b/src/hwspi.h
@@ -121,9 +121,9 @@ class HWSpi: public Hardware, public TraceValueRegister {
     
         void ClearIrqFlag(unsigned int);
     
-        IOReg<HWSpi> spdr_reg,
-                     spsr_reg,
-                     spcr_reg;
+        IOReg spdr_reg,
+              spsr_reg,
+              spcr_reg;
 };
 
 #endif
diff --git a/src/hwstack.cpp b/src/hwstack.cpp
index 892f4c6..de23eae 100644
--- a/src/hwstack.cpp
+++ b/src/hwstack.cpp
@@ -65,9 +65,9 @@ HWStackSram::HWStackSram(AvrDevice *c, int bs, bool initRE):
     TraceValueRegister(c, "STACK"),
     initRAMEND(initRE),
     sph_reg(this, "SPH",
-            this, &HWStackSram::GetSph, &HWStackSram::SetSph),
+            std::bind(&HWStackSram::GetSph, this), std::bind(&HWStackSram::SetSph, this, std::placeholders::_1)),
     spl_reg(this, "SPL",
-            this, &HWStackSram::GetSpl, &HWStackSram::SetSpl)
+            std::bind(&HWStackSram::GetSpl, this), std::bind(&HWStackSram::SetSpl, this, std::placeholders::_1))
 {
     stackCeil = 1 << bs;  // TODO: The number of bits is unable to acurately represent 0x460 ceiling of ATmega8: has 1024 B RAM (0x400) and 32+64 (0x60) registers.
     Reset();
diff --git a/src/hwstack.h b/src/hwstack.h
index a9db9e1..dbafe17 100644
--- a/src/hwstack.h
+++ b/src/hwstack.h
@@ -151,8 +151,8 @@ class HWStackSram: public HWStack, public TraceValueRegister {
 
         virtual void Reset();
         
-        IOReg<HWStackSram> sph_reg;
-        IOReg<HWStackSram> spl_reg;
+        IOReg sph_reg;
+        IOReg spl_reg;
 };
 
 //! Implements a stack with 3 levels deep (used as returnstack by ATtiny15 an other)
diff --git a/src/hwtimer/hwtimer.cpp b/src/hwtimer/hwtimer.cpp
index 4db1342..ce2a523 100644
--- a/src/hwtimer/hwtimer.cpp
+++ b/src/hwtimer/hwtimer.cpp
@@ -590,11 +590,11 @@ HWTimer8::HWTimer8(AvrDevice *core,
                    PinAtPort* outB):
     BasicTimerUnit(core, p, unit, tov, NULL, NULL, 8),
     tcnt_reg(this, "TCNT",
-             this, &HWTimer8::Get_TCNT, &HWTimer8::Set_TCNT),
+             std::bind(&HWTimer8::Get_TCNT, this), std::bind(&HWTimer8::Set_TCNT, this, std::placeholders::_1)),
     ocra_reg(this, "OCRA",
-             this, &HWTimer8::Get_OCRA, &HWTimer8::Set_OCRA),
+             std::bind(&HWTimer8::Get_OCRA, this), std::bind(&HWTimer8::Set_OCRA, this, std::placeholders::_1)),
     ocrb_reg(this, "OCRB",
-             this, &HWTimer8::Get_OCRB, &HWTimer8::Set_OCRB)
+             std::bind(&HWTimer8::Get_OCRB, this), std::bind(&HWTimer8::Set_OCRB, this, std::placeholders::_1))
 {
     // enable OC units and disable registers
     if(tcompA) {
@@ -699,25 +699,25 @@ HWTimer16::HWTimer16(AvrDevice *core,
                      ICaptureSource* icapsrc):
     BasicTimerUnit(core, p, unit, tov, ticap, icapsrc, 16),
     tcnt_h_reg(this, "TCNTH",
-               this, &HWTimer16::Get_TCNTH, &HWTimer16::Set_TCNTH),
+               std::bind(&HWTimer16::Get_TCNTH, this), std::bind(&HWTimer16::Set_TCNTH, this, std::placeholders::_1)),
     tcnt_l_reg(this, "TCNTL",
-               this, &HWTimer16::Get_TCNTL, &HWTimer16::Set_TCNTL),
+               std::bind(&HWTimer16::Get_TCNTL, this), std::bind(&HWTimer16::Set_TCNTL, this, std::placeholders::_1)),
     ocra_h_reg(this, "OCRAH",
-               this, &HWTimer16::Get_OCRAH, &HWTimer16::Set_OCRAH),
+               std::bind(&HWTimer16::Get_OCRAH, this), std::bind(&HWTimer16::Set_OCRAH, this, std::placeholders::_1)),
     ocra_l_reg(this, "OCRAL",
-               this, &HWTimer16::Get_OCRAL, &HWTimer16::Set_OCRAL),
+               std::bind(&HWTimer16::Get_OCRAL, this), std::bind(&HWTimer16::Set_OCRAL, this, std::placeholders::_1)),
     ocrb_h_reg(this, "OCRBH",
-               this, &HWTimer16::Get_OCRBH, &HWTimer16::Set_OCRBH),
+               std::bind(&HWTimer16::Get_OCRBH, this), std::bind(&HWTimer16::Set_OCRBH, this, std::placeholders::_1)),
     ocrb_l_reg(this, "OCRBL",
-               this, &HWTimer16::Get_OCRBL, &HWTimer16::Set_OCRBL),
+               std::bind(&HWTimer16::Get_OCRBL, this), std::bind(&HWTimer16::Set_OCRBL, this, std::placeholders::_1)),
     ocrc_h_reg(this, "OCRCH",
-               this, &HWTimer16::Get_OCRCH, &HWTimer16::Set_OCRCH),
+               std::bind(&HWTimer16::Get_OCRCH, this), std::bind(&HWTimer16::Set_OCRCH, this, std::placeholders::_1)),
     ocrc_l_reg(this, "OCRCL",
-               this, &HWTimer16::Get_OCRCL, &HWTimer16::Set_OCRCL),
+               std::bind(&HWTimer16::Get_OCRCL, this), std::bind(&HWTimer16::Set_OCRCL, this, std::placeholders::_1)),
     icr_h_reg(this, "ICRH",
-              this, &HWTimer16::Get_ICRH, &HWTimer16::Set_ICRH),
+              std::bind(&HWTimer16::Get_ICRH, this), std::bind(&HWTimer16::Set_ICRH, this, std::placeholders::_1)),
     icr_l_reg(this, "ICRL",
-              this, &HWTimer16::Get_ICRL, &HWTimer16::Set_ICRL)
+              std::bind(&HWTimer16::Get_ICRL, this), std::bind(&HWTimer16::Set_ICRL, this, std::placeholders::_1))
 {
     // enable OC units and disable registers
     if(tcompA) {
@@ -923,7 +923,7 @@ HWTimer8_0C::HWTimer8_0C(AvrDevice *core,
                          IRQLine* tov):
     HWTimer8(core, p, unit, tov, NULL, NULL, NULL, NULL),
     tccr_reg(this, "TCCR",
-             this, &HWTimer8_0C::Get_TCCR, &HWTimer8_0C::Set_TCCR)
+             std::bind(&HWTimer8_0C::Get_TCCR, this), std::bind(&HWTimer8_0C::Set_TCCR, this, std::placeholders::_1))
 {
     ChangeWGM(WGM_NORMAL);
 }
@@ -946,7 +946,7 @@ HWTimer8_1C::HWTimer8_1C(AvrDevice *core,
                          PinAtPort* outA):
     HWTimer8(core, p, unit, tov, tcompA, outA, NULL, NULL),
     tccr_reg(this, "TCCR",
-             this, &HWTimer8_1C::Get_TCCR, &HWTimer8_1C::Set_TCCR) {}
+             std::bind(&HWTimer8_1C::Get_TCCR, this), std::bind(&HWTimer8_1C::Set_TCCR, this, std::placeholders::_1)) {}
 
 void HWTimer8_1C::Set_TCCR(unsigned char val) {
     WGMtype temp;
@@ -983,9 +983,9 @@ HWTimer8_2C::HWTimer8_2C(AvrDevice *core,
                          PinAtPort* outB):
     HWTimer8(core, p, unit, tov, tcompA, outA, tcompB, outB),
     tccra_reg(this, "TCCRA",
-             this, &HWTimer8_2C::Get_TCCRA, &HWTimer8_2C::Set_TCCRA),
+             std::bind(&HWTimer8_2C::Get_TCCRA, this), std::bind(&HWTimer8_2C::Set_TCCRA, this, std::placeholders::_1)),
     tccrb_reg(this, "TCCRB",
-             this, &HWTimer8_2C::Get_TCCRB, &HWTimer8_2C::Set_TCCRB) {}
+             std::bind(&HWTimer8_2C::Get_TCCRB, this), std::bind(&HWTimer8_2C::Set_TCCRB, this, std::placeholders::_1)) {}
 
 void HWTimer8_2C::Set_WGM(int val) {
     WGMtype w;
@@ -1053,9 +1053,9 @@ HWTimer16_1C::HWTimer16_1C(AvrDevice *core,
                            ICaptureSource* icapsrc):
     HWTimer16(core, p, unit, tov, tcompA, outA, NULL, NULL, NULL, NULL, ticap, icapsrc),
     tccra_reg(this, "TCCRA",
-              this, &HWTimer16_1C::Get_TCCRA, &HWTimer16_1C::Set_TCCRA),
+              std::bind(&HWTimer16_1C::Get_TCCRA, this), std::bind(&HWTimer16_1C::Set_TCCRA, this, std::placeholders::_1)),
     tccrb_reg(this, "TCCRB",
-              this, &HWTimer16_1C::Get_TCCRB, &HWTimer16_1C::Set_TCCRB) {}
+              std::bind(&HWTimer16_1C::Get_TCCRB, this), std::bind(&HWTimer16_1C::Set_TCCRB, this, std::placeholders::_1)) {}
 
 void HWTimer16_1C::Set_WGM(int val) {
     WGMtype w;
@@ -1120,9 +1120,9 @@ HWTimer16_2C2::HWTimer16_2C2(AvrDevice *core,
     HWTimer16(core, p, unit, tov, tcompA, outA, tcompB, outB, NULL, NULL, ticap, icapsrc),
     at8515_mode(is_at8515),
     tccra_reg(this, "TCCRA",
-              this, &HWTimer16_2C2::Get_TCCRA, &HWTimer16_2C2::Set_TCCRA),
+              std::bind(&HWTimer16_2C2::Get_TCCRA, this), std::bind(&HWTimer16_2C2::Set_TCCRA, this, std::placeholders::_1)),
     tccrb_reg(this, "TCCRB",
-              this, &HWTimer16_2C2::Get_TCCRB, &HWTimer16_2C2::Set_TCCRB)
+              std::bind(&HWTimer16_2C2::Get_TCCRB, this), std::bind(&HWTimer16_2C2::Set_TCCRB, this, std::placeholders::_1))
 {}
 
 void HWTimer16_2C2::Set_WGM(int val) {
@@ -1199,11 +1199,11 @@ HWTimer16_2C3::HWTimer16_2C3(AvrDevice *core,
                              ICaptureSource* icapsrc):
     HWTimer16(core, p, unit, tov, tcompA, outA, tcompB, outB, NULL, NULL, ticap, icapsrc),
     tccra_reg(this, "TCCRA",
-              this, &HWTimer16_2C3::Get_TCCRA, &HWTimer16_2C3::Set_TCCRA),
+              std::bind(&HWTimer16_2C3::Get_TCCRA, this), std::bind(&HWTimer16_2C3::Set_TCCRA, this, std::placeholders::_1)),
     tccrb_reg(this, "TCCRB",
-              this, &HWTimer16_2C3::Get_TCCRB, &HWTimer16_2C3::Set_TCCRB),
+              std::bind(&HWTimer16_2C3::Get_TCCRB, this), std::bind(&HWTimer16_2C3::Set_TCCRB, this, std::placeholders::_1)),
     tccrc_reg(this, "TCCRC",
-              this, &HWTimer16_2C3::Get_TCCRC, &HWTimer16_2C3::Set_TCCRC) {}
+              std::bind(&HWTimer16_2C3::Get_TCCRC, this), std::bind(&HWTimer16_2C3::Set_TCCRC, this, std::placeholders::_1)) {}
 
 void HWTimer16_2C3::Set_TCCRA(unsigned char val) {
     int temp = (int)wgm;
@@ -1261,11 +1261,11 @@ HWTimer16_3C::HWTimer16_3C(AvrDevice *core,
                            ICaptureSource* icapsrc):
     HWTimer16(core, p, unit, tov, tcompA, outA, tcompB, outB, tcompC, outC, ticap, icapsrc),
     tccra_reg(this, "TCCRA",
-              this, &HWTimer16_3C::Get_TCCRA, &HWTimer16_3C::Set_TCCRA),
+              std::bind(&HWTimer16_3C::Get_TCCRA, this), std::bind(&HWTimer16_3C::Set_TCCRA, this, std::placeholders::_1)),
     tccrb_reg(this, "TCCRB",
-              this, &HWTimer16_3C::Get_TCCRB, &HWTimer16_3C::Set_TCCRB),
+              std::bind(&HWTimer16_3C::Get_TCCRB, this), std::bind(&HWTimer16_3C::Set_TCCRB, this, std::placeholders::_1)),
     tccrc_reg(this, "TCCRC",
-              this, &HWTimer16_3C::Get_TCCRC, &HWTimer16_3C::Set_TCCRC) {}
+              std::bind(&HWTimer16_3C::Get_TCCRC, this), std::bind(&HWTimer16_3C::Set_TCCRC, this, std::placeholders::_1)) {}
 
 void HWTimer16_3C::Set_TCCRA(unsigned char val) {
     int temp = (int)wgm;
@@ -1340,21 +1340,21 @@ HWTimerTinyX5::HWTimerTinyX5(AvrDevice *core,
     timerOCRAInt(tocra),
     timerOCRBInt(tocrb),
     tccr_reg(this, "TCCR1",
-             this, &HWTimerTinyX5::Get_TCCR, &HWTimerTinyX5::Set_TCCR),
+             std::bind(&HWTimerTinyX5::Get_TCCR, this), std::bind(&HWTimerTinyX5::Set_TCCR, this, std::placeholders::_1)),
     tcnt_reg(this, "TCNT1",
-             this, &HWTimerTinyX5::Get_TCNT, &HWTimerTinyX5::Set_TCNT),
+             std::bind(&HWTimerTinyX5::Get_TCNT, this), std::bind(&HWTimerTinyX5::Set_TCNT, this, std::placeholders::_1)),
     tocra_reg(this, "OCR1A",
-              this, &HWTimerTinyX5::Get_OCRA, &HWTimerTinyX5::Set_OCRA),
+              std::bind(&HWTimerTinyX5::Get_OCRA, this), std::bind(&HWTimerTinyX5::Set_OCRA, this, std::placeholders::_1)),
     tocrb_reg(this, "OCR1B",
-              this, &HWTimerTinyX5::Get_OCRB, &HWTimerTinyX5::Set_OCRB),
+              std::bind(&HWTimerTinyX5::Get_OCRB, this), std::bind(&HWTimerTinyX5::Set_OCRB, this, std::placeholders::_1)),
     tocrc_reg(this, "OCR1C",
-              this, &HWTimerTinyX5::Get_OCRC, &HWTimerTinyX5::Set_OCRC),
+              std::bind(&HWTimerTinyX5::Get_OCRC, this), std::bind(&HWTimerTinyX5::Set_OCRC, this, std::placeholders::_1)),
     dtps1_reg(this, "DTPS1",
-              this, &HWTimerTinyX5::Get_DTPS1, &HWTimerTinyX5::Set_DTPS1),
+              std::bind(&HWTimerTinyX5::Get_DTPS1, this), std::bind(&HWTimerTinyX5::Set_DTPS1, this, std::placeholders::_1)),
     dt1a_reg(this, "DT1A",
-             this, &HWTimerTinyX5::Get_DT1A, &HWTimerTinyX5::Set_DT1A),
+             std::bind(&HWTimerTinyX5::Get_DT1A, this), std::bind(&HWTimerTinyX5::Set_DT1A, this, std::placeholders::_1)),
     dt1b_reg(this, "DT1B",
-             this, &HWTimerTinyX5::Get_DT1B, &HWTimerTinyX5::Set_DT1B)
+             std::bind(&HWTimerTinyX5::Get_DT1B, this), std::bind(&HWTimerTinyX5::Set_DT1B, this, std::placeholders::_1))
 {
     // gtccr and pllcsr register
     gtccrRegister = gtccr;
diff --git a/src/hwtimer/hwtimer.h b/src/hwtimer/hwtimer.h
index 8596e74..36e6b2d 100644
--- a/src/hwtimer/hwtimer.h
+++ b/src/hwtimer/hwtimer.h
@@ -226,9 +226,9 @@ class HWTimer8: public BasicTimerUnit {
         unsigned char Get_OCRB() { return GetCompareRegister(1); }
         
     public:
-        IOReg<HWTimer8> tcnt_reg; //!< counter register
-        IOReg<HWTimer8> ocra_reg; //!< output compare A register
-        IOReg<HWTimer8> ocrb_reg; //!< output compare B register
+        IOReg tcnt_reg; //!< counter register
+        IOReg ocra_reg; //!< output compare A register
+        IOReg ocrb_reg; //!< output compare B register
         
         HWTimer8(AvrDevice *core,
                  PrescalerMultiplexer *p,
@@ -307,16 +307,16 @@ class HWTimer16: public BasicTimerUnit {
         unsigned char Get_ICRL() { return GetComplexRegister(true, false); }
         
     public:
-        IOReg<HWTimer16> tcnt_h_reg; //!< counter register, high byte
-        IOReg<HWTimer16> tcnt_l_reg; //!< counter register, low byte
-        IOReg<HWTimer16> ocra_h_reg; //!< output compare A register, high byte
-        IOReg<HWTimer16> ocra_l_reg; //!< output compare A register, low byte
-        IOReg<HWTimer16> ocrb_h_reg; //!< output compare B register, high byte
-        IOReg<HWTimer16> ocrb_l_reg; //!< output compare B register, low byte
-        IOReg<HWTimer16> ocrc_h_reg; //!< output compare C register, high byte
-        IOReg<HWTimer16> ocrc_l_reg; //!< output compare C register, low byte
-        IOReg<HWTimer16> icr_h_reg; //!< input capture register, high byte
-        IOReg<HWTimer16> icr_l_reg; //!< input capture register, low byte
+        IOReg tcnt_h_reg; //!< counter register, high byte
+        IOReg tcnt_l_reg; //!< counter register, low byte
+        IOReg ocra_h_reg; //!< output compare A register, high byte
+        IOReg ocra_l_reg; //!< output compare A register, low byte
+        IOReg ocrb_h_reg; //!< output compare B register, high byte
+        IOReg ocrb_l_reg; //!< output compare B register, low byte
+        IOReg ocrc_h_reg; //!< output compare C register, high byte
+        IOReg ocrc_l_reg; //!< output compare C register, low byte
+        IOReg icr_h_reg; //!< input capture register, high byte
+        IOReg icr_l_reg; //!< input capture register, low byte
         
         HWTimer16(AvrDevice *core,
                   PrescalerMultiplexer *p,
@@ -355,7 +355,7 @@ class HWTimer8_0C: public HWTimer8 {
         unsigned char Get_TCCR() { return tccr_val; }
         
     public:
-        IOReg<HWTimer8_0C> tccr_reg; //!< control register
+        IOReg tccr_reg; //!< control register
         
         HWTimer8_0C(AvrDevice *core,
                     PrescalerMultiplexer *p,
@@ -385,7 +385,7 @@ class HWTimer8_1C: public HWTimer8 {
         unsigned char Get_TCCR() { return tccr_val; }
         
     public:
-        IOReg<HWTimer8_1C> tccr_reg; //!< control register
+        IOReg tccr_reg; //!< control register
         
         HWTimer8_1C(AvrDevice *core,
                     PrescalerMultiplexer *p,
@@ -436,8 +436,8 @@ class HWTimer8_2C: public HWTimer8 {
         unsigned char Get_TCCRB() { return tccrb_val; }
         
     public:
-        IOReg<HWTimer8_2C> tccra_reg; //!< control register A
-        IOReg<HWTimer8_2C> tccrb_reg; //!< control register B
+        IOReg tccra_reg; //!< control register A
+        IOReg tccrb_reg; //!< control register B
         
         HWTimer8_2C(AvrDevice *core,
                     PrescalerMultiplexer *p,
@@ -490,8 +490,8 @@ class HWTimer16_1C: public HWTimer16 {
         unsigned char Get_TCCRB() { return tccrb_val; }
         
     public:
-        IOReg<HWTimer16_1C> tccra_reg; //!< control register A
-        IOReg<HWTimer16_1C> tccrb_reg; //!< control register B
+        IOReg tccra_reg; //!< control register A
+        IOReg tccrb_reg; //!< control register B
         
         HWTimer16_1C(AvrDevice *core,
                      PrescalerMultiplexer *p,
@@ -549,8 +549,8 @@ class HWTimer16_2C2: public HWTimer16 {
         unsigned char Get_TCCRB() { return tccrb_val; }
         
     public:
-        IOReg<HWTimer16_2C2> tccra_reg; //!< control register A
-        IOReg<HWTimer16_2C2> tccrb_reg; //!< control register B
+        IOReg tccra_reg; //!< control register A
+        IOReg tccrb_reg; //!< control register B
         
         HWTimer16_2C2(AvrDevice *core,
                       PrescalerMultiplexer *p,
@@ -612,9 +612,9 @@ class HWTimer16_2C3: public HWTimer16 {
         unsigned char Get_TCCRC() { return 0; } // will be read allways 0!
         
     public:
-        IOReg<HWTimer16_2C3> tccra_reg; //!< control register A
-        IOReg<HWTimer16_2C3> tccrb_reg; //!< control register B
-        IOReg<HWTimer16_2C3> tccrc_reg; //!< control register C
+        IOReg tccra_reg; //!< control register A
+        IOReg tccrb_reg; //!< control register B
+        IOReg tccrc_reg; //!< control register C
         
         HWTimer16_2C3(AvrDevice *core,
                       PrescalerMultiplexer *p,
@@ -675,9 +675,9 @@ class HWTimer16_3C: public HWTimer16 {
         unsigned char Get_TCCRC() { return 0; } // will be read allways 0!
         
     public:
-        IOReg<HWTimer16_3C> tccra_reg; //!< control register A
-        IOReg<HWTimer16_3C> tccrb_reg; //!< control register B
-        IOReg<HWTimer16_3C> tccrc_reg; //!< control register C
+        IOReg tccra_reg; //!< control register A
+        IOReg tccrb_reg; //!< control register B
+        IOReg tccrc_reg; //!< control register C
         
         HWTimer16_3C(AvrDevice *core,
                      PrescalerMultiplexer *p,
@@ -910,14 +910,14 @@ class HWTimerTinyX5: public Hardware,
         void TransferOutputValues(void);
 
     public:
-        IOReg<HWTimerTinyX5> tccr_reg;  //!< control register
-        IOReg<HWTimerTinyX5> tcnt_reg;  //!< counter register
-        IOReg<HWTimerTinyX5> tocra_reg; //!< OCR register channel A
-        IOReg<HWTimerTinyX5> tocrb_reg; //!< OCR register channel B
-        IOReg<HWTimerTinyX5> tocrc_reg; //!< OCR register channel C
-        IOReg<HWTimerTinyX5> dtps1_reg; //!< dead time generator prescaler register
-        IOReg<HWTimerTinyX5> dt1a_reg;  //!< dead time generator register channel A
-        IOReg<HWTimerTinyX5> dt1b_reg;  //!< dead time generator register channel B
+        IOReg tccr_reg;  //!< control register
+        IOReg tcnt_reg;  //!< counter register
+        IOReg tocra_reg; //!< OCR register channel A
+        IOReg tocrb_reg; //!< OCR register channel B
+        IOReg tocrc_reg; //!< OCR register channel C
+        IOReg dtps1_reg; //!< dead time generator prescaler register
+        IOReg dt1a_reg;  //!< dead time generator register channel A
+        IOReg dt1b_reg;  //!< dead time generator register channel B
 
         HWTimerTinyX5(AvrDevice *core,
                       IOSpecialReg *gtccr,
diff --git a/src/hwuart.cpp b/src/hwuart.cpp
index acd2eb9..79f327d 100644
--- a/src/hwuart.cpp
+++ b/src/hwuart.cpp
@@ -539,19 +539,26 @@ HWUart::HWUart(AvrDevice *core,
     vectorUdre(udre_interrupt),
     vectorTx(tx_interrupt),
     udr_reg(this, "UDR",
-            this, &HWUart::GetUdr, &HWUart::SetUdr),
+            std::bind(&HWUart::GetUdr, this),
+            std::bind(&HWUart::SetUdr, this, std::placeholders::_1)),
     usr_reg(this, "USR",
-            this, &HWUart::GetUsr, &HWUart::SetUsr),
+            std::bind(&HWUart::GetUsr, this),
+            std::bind(&HWUart::SetUsr, this, std::placeholders::_1)),
     ucr_reg(this, "UCR",
-            this, &HWUart::GetUcr, &HWUart::SetUcr),
+             std::bind(&HWUart::GetUcr, this),
+             std::bind(&HWUart::SetUcr, this, std::placeholders::_1)),
     ucsra_reg(this, "UCSRA",
-              this, &HWUart::GetUsr, &HWUart::SetUsr),
+             std::bind(&HWUart::GetUsr, this),
+             std::bind(&HWUart::SetUsr, this, std::placeholders::_1)),
     ucsrb_reg(this, "UCSRB",
-              this, &HWUart::GetUcr, &HWUart::SetUcr),
+             std::bind(&HWUart::GetUcr, this),
+             std::bind(&HWUart::SetUcr, this, std::placeholders::_1)),
     ubrr_reg(this, "UBRR",
-             this, &HWUart::GetUbrr, &HWUart::SetUbrr),
+             std::bind(&HWUart::GetUbrr, this),
+             std::bind(&HWUart::SetUbrr, this, std::placeholders::_1)),
     ubrrhi_reg(this, "UBRRHI",
-               this, &HWUart::GetUbrrhi, &HWUart::SetUbrrhi)
+               std::bind(&HWUart::GetUbrrhi, this),
+               std::bind(&HWUart::SetUbrrhi, this, std::placeholders::_1))
 {
     irqSystem->DebugVerifyInterruptVector(vectorRx, this);
     irqSystem->DebugVerifyInterruptVector(vectorUdre, this);
@@ -661,11 +668,11 @@ HWUsart::HWUsart(AvrDevice *core,
     HWUart(core, s, tx, rx, vrx, vudre, vtx, instance_id),
     pinXck(xck),
     ucsrc_reg(this, "UCSRC",
-              this, &HWUsart::GetUcsrc, &HWUsart::SetUcsrc),
+              std::bind(&HWUsart::GetUcsrc, this), std::bind(&HWUsart::SetUcsrc, this, std::placeholders::_1)),
     ubrrh_reg(this, "UBRRH",
-              this, &HWUsart::GetUbrrhi, &HWUsart::SetUbrrhi),
+              std::bind(&HWUsart::GetUbrrhi, this), std::bind(&HWUsart::SetUbrrhi, this, std::placeholders::_1)),
     ucsrc_ubrrh_reg(this, "UCSRC_UBRRH",
-                    this, &HWUsart::GetUcsrcUbrrh, &HWUsart::SetUcsrcUbrrh)
+                    std::bind(&HWUsart::GetUcsrcUbrrh, this), std::bind(&HWUsart::SetUcsrcUbrrh, this, std::placeholders::_1))
 {
     if(mxReg) {
         ucsrc_reg.releaseTraceValue();
diff --git a/src/hwuart.h b/src/hwuart.h
index 2ce2674..ad83726 100644
--- a/src/hwuart.h
+++ b/src/hwuart.h
@@ -132,7 +132,7 @@ class HWUart: public Hardware, public TraceValueRegister {
         void CheckForNewSetIrq(unsigned char);
         void CheckForNewClearIrq(unsigned char);
 
-        IOReg<HWUart>
+        IOReg
             udr_reg,
             usr_reg,
             ucr_reg,
@@ -170,9 +170,9 @@ class HWUsart: public HWUart {
         unsigned char GetUcsrc();
         unsigned char GetUcsrcUbrrh();
 
-        IOReg<HWUsart> ucsrc_reg,
-                       ubrrh_reg,
-                       ucsrc_ubrrh_reg;
+        IOReg ucsrc_reg,
+              ubrrh_reg,
+              ucsrc_ubrrh_reg;
 };
 
 #endif
diff --git a/src/hwusi.cpp b/src/hwusi.cpp
index 06880d2..7a95ac9 100644
--- a/src/hwusi.cpp
+++ b/src/hwusi.cpp
@@ -212,9 +212,9 @@ HWUSI::HWUSI(AvrDevice *_c,
     core(_c), irq(_irq),
     DI(din), DO(dout), SCK(sck),
     irq_start(ivec_start), irq_ovr(ivec_ovr),
-    usidr_reg(this, "USIDR", this, &HWUSI::GetUSIDR, &HWUSI::SetUSIDR),
-    usisr_reg(this, "USISR", this, &HWUSI::GetUSISR, &HWUSI::SetUSISR),
-    usicr_reg(this, "USICR", this, &HWUSI::GetUSICR, &HWUSI::SetUSICR)
+    usidr_reg(this, "USIDR", std::bind(&HWUSI::GetUSIDR, this), std::bind(&HWUSI::SetUSIDR, this, std::placeholders::_1)),
+    usisr_reg(this, "USISR", std::bind(&HWUSI::GetUSISR, this), std::bind(&HWUSI::SetUSISR, this, std::placeholders::_1)),
+    usicr_reg(this, "USICR", std::bind(&HWUSI::GetUSICR, this), std::bind(&HWUSI::SetUSICR, this, std::placeholders::_1))
 {
     irq->DebugVerifyInterruptVector(ivec_start, this);
     irq->DebugVerifyInterruptVector(ivec_ovr, this);
@@ -366,7 +366,7 @@ HWUSI_BR::HWUSI_BR(AvrDevice *_c,
          unsigned int ivec_start,
          unsigned int ivec_ovr):
     HWUSI(_c, _irq, din, dout, sck, ivec_start, ivec_ovr),
-    usibr_reg(this, "USIBR", this, &HWUSI_BR::GetUSIBR, &HWUSI_BR::SetUSIBR)
+    usibr_reg(this, "USIBR", std::bind(&HWUSI_BR::GetUSIBR, this), std::bind(&HWUSI_BR::SetUSIBR, this, std::placeholders::_1))
 {
     Reset();
 }
diff --git a/src/hwusi.h b/src/hwusi.h
index b8c5573..231a9ac 100644
--- a/src/hwusi.h
+++ b/src/hwusi.h
@@ -167,9 +167,9 @@ class HWUSI: public Hardware, public SimulationMember, public TraceValueRegister
         unsigned char GetUSICR(void) { return control_data; }
     
         /* IO registers connected with USI */
-        IOReg<HWUSI> usidr_reg,
-                     usisr_reg,
-                     usicr_reg;
+        IOReg usidr_reg,
+              usisr_reg,
+              usicr_reg;
 };
 
 class HWUSI_BR: public HWUSI {
@@ -200,7 +200,7 @@ class HWUSI_BR: public HWUSI {
         unsigned char GetUSIBR(void) { return buffer_data; }
 
         /* IO registers connected with USI */
-        IOReg<HWUSI_BR> usibr_reg;
+        IOReg usibr_reg;
 };
 
 #endif
diff --git a/src/hwwado.cpp b/src/hwwado.cpp
index 3057553..20ac725 100644
--- a/src/hwwado.cpp
+++ b/src/hwwado.cpp
@@ -70,7 +70,7 @@ HWWado::HWWado(AvrDevice *c):
     TraceValueRegister(c, "WADO"),
     core(c),
     wdtcr_reg(this, "WDTCR",
-              this, &HWWado::GetWdtcr, &HWWado::SetWdtcr) {
+              std::bind(&HWWado::GetWdtcr, this), std::bind(&HWWado::SetWdtcr, this, std::placeholders::_1)) {
 	core->AddToCycleList(this);
 	Reset();
 }
diff --git a/src/hwwado.h b/src/hwwado.h
index 8f7a170..ae7dc16 100644
--- a/src/hwwado.h
+++ b/src/hwwado.h
@@ -51,7 +51,7 @@ class HWWado: public Hardware, public TraceValueRegister {
 		void Wdr(); //reset the wado counter
 		void Reset();
 
-        IOReg<HWWado> wdtcr_reg;
+        IOReg wdtcr_reg;
 };
 
 
diff --git a/src/ioregs.cpp b/src/ioregs.cpp
index dae40f4..24be530 100644
--- a/src/ioregs.cpp
+++ b/src/ioregs.cpp
@@ -32,7 +32,8 @@ AddressExtensionRegister::AddressExtensionRegister(AvrDevice *core,
     TraceValueRegister(core, regname),
     reg_mask((1 << bitsize) - 1),
     ext_reg(this, regname,
-            this, &AddressExtensionRegister::GetRegVal, &AddressExtensionRegister::SetRegVal)
+            std::bind(&AddressExtensionRegister::GetRegVal, this),
+            std::bind(&AddressExtensionRegister::SetRegVal, this, std::placeholders::_1))
 {
     Reset();
 }
diff --git a/src/ioregs.h b/src/ioregs.h
index d684765..391b0e4 100644
--- a/src/ioregs.h
+++ b/src/ioregs.h
@@ -42,7 +42,7 @@ class AddressExtensionRegister: public Hardware, public TraceValueRegister {
         unsigned char GetRegVal() { return reg_val; }
         void SetRegVal(unsigned char val) { reg_val = val & reg_mask; }
 
-        IOReg<AddressExtensionRegister> ext_reg;
+        IOReg ext_reg;
 };
 
 #endif
diff --git a/src/rwmem.h b/src/rwmem.h
index c948d7a..52e2f5c 100644
--- a/src/rwmem.h
+++ b/src/rwmem.h
@@ -29,6 +29,7 @@
 
 #include <string>       // std::string
 #include <vector>
+#include <functional>
 
 #include "traceval.h"
 #include "avrerror.h"
@@ -224,26 +225,21 @@ class NotSimulatedRegister : public RWMemoryMember {
         void set(unsigned char);
 };
 
-//! IO register to be specialized for a certain class/hardware
-/*! The template parameter class P specifies the class type in which
-  the io register resides. */
-template<class P>
+//! IO register to be owned by a certain class/hardware
 class IOReg: public RWMemoryMember {
     
     public:
-        typedef unsigned char(P::*getter_t)();
-        typedef void (P::*setter_t)(unsigned char);
+        typedef std::function<unsigned char(void)> getter_t;
+        typedef std::function<void(unsigned char)> setter_t;
         /*! Creates an IO control register for controlling hardware units
-          \param _p: pointer to object this will be part of
+          \param _o: pointer to object this will be part of
           \param _g: pointer to get method
           \param _s: pointer to set method */
         IOReg(TraceValueRegister *registry,
               const std::string &tracename,
-              P *_p,
-              getter_t _g=0,
-              setter_t _s=0):
+              getter_t _g=nullptr,
+              setter_t _s=nullptr):
             RWMemoryMember(registry, tracename),
-            p(_p),
             g(_g),
             s(_s)
         {
@@ -267,7 +263,7 @@ class IOReg: public RWMemoryMember {
     protected:
         unsigned char get() const {
             if (g)
-                return (p->*g)();
+                return g();
             else if (tv) {
                 avr_warning("Reading of '%s' is not supported.", tv->name().c_str());
             }
@@ -275,14 +271,13 @@ class IOReg: public RWMemoryMember {
         }
         void set(unsigned char val) {
             if (s)
-                (p->*s)(val);
+                s(val);
             else if (tv) {
                 avr_warning("Writing of '%s' (with %d) is not supported.", tv->name().c_str(), val);
             }
         }
         
     private:
-        P *p;
         getter_t g;
         setter_t s;
 };
-- 
2.11.0

_______________________________________________
Simulavr-devel mailing list
Simulavr-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/simulavr-devel

Reply via email to