class AVRMEGA
{
public:
  typedef volatile unsigned char  Reg8;
  typedef volatile unsigned short Reg16;
  typedef volatile unsigned char  IOReg8;
  
  Reg8 r0; 
  Reg8 r1; 
  Reg8 r2; 
  Reg8 r3; 
  Reg8 r4; 
  Reg8 r5; 
  Reg8 r6; 
  Reg8 r7; 
  Reg8 r8; 
  Reg8 r9; 
  Reg8 r10; 
  Reg8 r11; 
  Reg8 r12; 
  Reg8 r13; 
  Reg8 r14; 
  Reg8 r15; 
  Reg8 r16; 
  Reg8 r17; 
  Reg8 r18; 
  Reg8 r19; 
  Reg8 r20; 
  Reg8 r21; 
  Reg8 r22; 
  Reg8 r23; 
  Reg8 r24; 
  Reg8 r25; 
  union {
    struct{Reg8 r26; Reg8 r27;};
    Reg16 x;
  };
    union {
      struct{Reg8 r28; Reg8 r29;};
      Reg16 y;
    };
    union {
        struct{Reg8 r30; Reg8 r31;};
      Reg16 z;
    };
};

class ATMEGA: public AVRMEGA
{
 public:
  static const unsigned short RAM_SIZE   = 0x0400;
  
 public:
  IOReg8 twbr;        // [0x20]
  IOReg8 twsr;        // [0x21]
  IOReg8 twar;        // [0x22]
  IOReg8 twdr;        // [0x23]
  IOReg8 adcl;        // [0x24]
  IOReg8 adch;        // [0x25]
  IOReg8 adcsra;        // [0x26]
  IOReg8 admux;        // [0x27]
  IOReg8 acsr;        // [0x28]   
  IOReg8 ubrrl;        // [0x29]
  IOReg8 ucsrb;                // [0x2A]
  IOReg8 ucsra;                // [0x2B]
  IOReg8 udr;                // [0x2C]
  IOReg8 spcr;        // [0x2D]
  IOReg8 spsr;        // [0x2E]
  IOReg8 spdr;        // [0x2F]
  IOReg8 pind;                // [0x30]
  IOReg8 ddrd;        // [0x31]
  IOReg8 portd;        // [0x32]
  IOReg8 pinc;                // [0x33]
  IOReg8 ddrc;        // [0x34]
  IOReg8 portc;        // [0x35]
  IOReg8 pinb;                // [0x36]
  IOReg8 ddrb;        // [0x37]
  IOReg8 portb;       // [0x38]
  IOReg8 pina;                // [0x39] 
  IOReg8 ddra;        // [0x3A] I/O port A direction (1->out, 0->in)
  IOReg8 porta;        // [0x3B] I/O port A data
  IOReg8 eecr;        // [0x3C] 
  IOReg8 eedr;        // [0x3D]  void __vector_5 (void) __attribute__((signal));
  void __vector_6 (void) __attribute__((signal));
  void __vector_7 (void) __attribute__((signal));
  IOReg8 eearl;        // [0x3E]
  IOReg8 eearh;        // [0x3F]
  IOReg8 ubrrh; // [0x40] **revertb
  IOReg8 wdtcr;        // [0x41]
  IOReg8 assr;        // [0x42]
  IOReg8 ocr2;        // [0x43]
  IOReg8 tcnt2;        // [0x44]
  IOReg8 tccr2;        // [0x45]
  IOReg8 icr1l;        // [0x46]
  IOReg8 icr1h;        // [0x47]
  IOReg8 ocr1bl;        // [0x48]
  IOReg8 ocr1bh;        // [0x49]
  IOReg8 ocr1al;        // [0x4A]
  IOReg8 ocr1ah;        // [0x4B]
  IOReg8 tcnt1l;        // [0x4C]
  IOReg8 tcnt1h;      // [0x4D]
  IOReg8 tccr1b;        // [0x4E]
  IOReg8 tccr1a;        // [0x4F]
  IOReg8 sfior;        // [0x50]
  IOReg8 osccal;  // [0x51] **rever se nao eh duplo
  IOReg8 tcnt0;        // [0x52]
  IOReg8 tccr0;        // [0x53]
  IOReg8 mcucsr;// [0x54]
  IOReg8 mcucr;        // [0x55]
  IOReg8 twcr;        // [0x56]
  IOReg8 spmcr;        // [0x57]
  IOReg8 tifr;        // [0x58]
  IOReg8 timsk;        // [0x59]
  IOReg8 gifr;        // [0x5A]
  IOReg8 gicr; //novo [0x5B]
  IOReg8 ocr0;        // [0x5C] OCR0
  IOReg8 spl;                // [0x5D]
  IOReg8 sph;                // [0x5E]
  IOReg8 sreg;        // [0x5F]
  
  char ram[RAM_SIZE];
};

/* Utilização de código C em C++ para referenciar as interrupções do registrador */
extern "C" {
  void __vector_0 (void) __attribute__((signal));
  void __vector_1 (void) __attribute__((signal));
  void __vector_2 (void) __attribute__((signal));
  void __vector_3 (void) __attribute__((signal));    
  void __vector_4 (void) __attribute__((signal));
  void __vector_5 (void) __attribute__((signal));
  void __vector_6 (void) __attribute__((signal));
  void __vector_7 (void) __attribute__((signal));
  void __vector_8 (void) __attribute__((signal));
  void __vector_9 (void) __attribute__((signal));
  void __vector_10 (void) __attribute__((signal));

};