#ifndef _AT90S2313_
#define _AT90S2313_ 1

typedef signed   char      int8;
typedef unsigned char      uint8;
typedef int                int16;
typedef unsigned int       uint16;
typedef long               int32;
typedef unsigned long      uint32;
typedef long long          int64;
typedef unsigned long long uint64;

// Interrupt vectors

#define _VECTOR(N) __vector_## N

#define INTERRUPT0       _VECTOR(1)
#define INTERRUPT1       _VECTOR(2)
#define INPUT_CAPTURE1   _VECTOR(3)
#define OUTPUT_COMPARE1A _VECTOR(4)
#define OVERFLOW1        _VECTOR(5)
#define OVERFLOW0        _VECTOR(6)
#define UART_RECV        _VECTOR(7)
#define UART_DATA        _VECTOR(8)
#define UART_TRANS       _VECTOR(9)
#define COMPARATOR       _VECTOR(10)

#define _VECTORS_SIZE 22

#define INTERRUPT(name)                       \
void name (void) __attribute__ ((interrupt)); \
void name (void)

#define INTERRUPT_CRITICAL(name) \
void name (void);                \
void name (void)

// Pointer definition
#define XL r26
#define XH r27
#define YL r28
#define YH r29
#define ZL r30
#define ZH r31

//  The Register Bit names

// Status Register - SREG
#define SREG_I 7
#define SREG_T 6
#define SREG_H 5
#define SREG_S 4
#define SREG_V 3
#define SREG_N 2
#define SREG_Z 1
#define SREG_C 0

// General interrupt mask register - GIMSK
#define INT1 7
#define INT0 6

// General interrupt flag register - GIFR
#define INTF1 7
#define INTF0 6

// Timer/Counter interrupt mask register - TIMSK
#define TOIE1  7
#define OCIE1A 6
#define TICIE1 3
#define TOIE0  1
 
// Timer/Counter interrupt flag register - TIFR
#define TOV1  7
#define OCF1A 6
#define ICF1  3
#define TOV0  1
 
// General control register - MCUCR
#define SE    5
#define SM    4
#define ISC11 3
#define ISC10 2
#define ISC01 1
#define ISC00 0
 
// Timer/Counter 0 control register - TCCR0
#define CS02 2
#define CS01 1
#define CS00 0
 
// Timer/Counter 1 control register - TCCR1A
#define COM1A1 7
#define COM1A0 6
#define PWM11  1
#define PWM10  0
 
// Timer/Counter 1 Control and Status Register - TCCR1B
#define ICNC1 7
#define ICES1 6
#define CTC1  3
#define CS12  2
#define CS11  1
#define CS10  0

// Watchdog timer control register - WDTCR
#define WDTOE 4
#define WDE   3
#define WDP2  2
#define WDP1  1
#define WDP0  0
 
// EEPROM control register - EECR
#define EEMWE 2
#define EEWE  1
#define EERE  0
 
// Port B data register - PORTB
#define PB7 7
#define PB6 6
#define PB5 5
#define PB4 4
#define PB3 3
#define PB2 2
#define PB1 1
#define PB0 0

#define PORTB0 PB0
#define PORTB1 PB1
#define PORTB2 PB2
#define PORTB3 PB3
#define PORTB4 PB4
#define PORTB5 PB5
#define PORTB6 PB6
#define PORTB7 PB7
 
// Port B data direction register - DDRB
#define DDB7 7
#define DDB6 6
#define DDB5 5
#define DDB4 4
#define DDB3 3
#define DDB2 2
#define DDB1 1
#define DDB0 0
 
// Port B input pins - PINB
#define PINB7   7
#define PINB6   6
#define PINB5   5
#define PINB4   4
#define PINB3   3
#define PINB2   2
#define PINB1   1
#define PINB0   0
 
// Port D data register - PORTD
#define PD6 6
#define PD5 5
#define PD4 4
#define PD3 3
#define PD2 2
#define PD1 1
#define PD0 0

#define PORTD0 PD0
#define PORTD1 PD1
#define PORTD2 PD2
#define PORTD3 PD3
#define PORTD4 PD4
#define PORTD5 PD5
#define PORTD6 PD6
#define PORTD7 PD7

// Port D data direction register - DDRD
#define DDD6    6
#define DDD5    5
#define DDD4    4
#define DDD3    3
#define DDD2    2
#define DDD1    1
#define DDD0    0
 
// Port D input pins - PIND
#define PIND6   6
#define PIND5   5
#define PIND4   4
#define PIND3   3
#define PIND2   2
#define PIND1   1
#define PIND0   0
 
// UART status register - USR
#define RXC  7
#define TXC  6
#define UDRE 5
#define FE   4
#define OR   3
 
// UART control register - UCR
#define RXCIE 7
#define TXCIE 6
#define UDRIE 5
#define RXEN  4
#define TXEN  3
#define CHR9  2
#define RXB8  1
#define TXB8  0

// Analog comparator control and status register - ACSR
#define ACD   7
#define ACO   5
#define ACI   4
#define ACIE  3
#define ACIC  2
#define ACIS1 1
#define ACIS0 0

// Port Data Register (generic)
#define PORT7 7
#define PORT6 6
#define PORT5 5
#define PORT4 4
#define PORT3 3
#define PORT2 2
#define PORT1 1
#define PORT0 0

// Port Data Direction Register (generic)
#define DD7 7
#define DD6 6
#define DD5 5
#define DD4 4
#define DD3 3
#define DD2 2
#define DD1 1
#define DD0 0

// Port Input Pins (generic)
#define PIN7 7
#define PIN6 6
#define PIN5 5
#define PIN4 4
#define PIN3 3
#define PIN2 2
#define PIN1 1
#define PIN0 0

// Constants
#define RAMEND   0xDF

#define _IO_OFFSET  0x20

#define _bit(bit) (1 << (bit))

#define _IO_BYTE(io_addr) (*(volatile uint8 *) (io_addr))
#define _IO_WORD(io_addr) (*(volatile uint16 *)(io_addr))

#define _IO8(io_addr)  _IO_BYTE((io_addr + _IO_OFFSET))
#define _IO16(io_addr) _IO_WORD((io_addr + _IO_OFFSET))


#define bit_is_set(reg, bit)           (reg & _bit(bit))
#define bit_is_clear(reg, bit)         (!(reg & _bit(bit)))
#define loop_if_bit_is_set(reg, bit)   do { } while (bit_is_set(reg, bit))
#define loop_if_bit_is_clear(reg, bit) do { } while (bit_is_clear(reg, bit))

#define clear_bit(reg, bit)  (reg &= ~_bit(bit))
#define set_bit(reg, bit)    (reg |=  _bit(bit))

#define out_byte(reg, val) (reg = (val))
#define out_word(reg, val) (reg = (val))
#define inp_word(reg)       reg
#define inp_byte(reg)       reg

#define sleep() __asm__  __volatile__ ("sleep")

// Status REGister
#define SREG  _IO8(0x3F)

// Stack Pointer
#define SP     _IO16(0x3D)
#define SPL    _IO8 (0x3D)
#define SPH    _IO8 (0x3E)

// General Interrupt MaSK register
#define GIMSK  _IO8(0x3B)

// General Interrupt Flag Register
#define GIFR   _IO8(0x3A)

// Timer/Counter Interrupt MaSK register
#define TIMSK  _IO8(0x39)

// Timer/Counter Interrupt Flag register
#define TIFR	_IO8(0x38)

// MCU general Control Register
#define MCUCR	_IO8(0x35)

// Timer/Counter 0 Control Register
#define TCCR0	_IO8(0x33)

// Timer/Counter 0
#define TCNT0	_IO8(0x32)

// Timer/Counter 1 Control Register
#define TCCR1A	_IO8(0x2F)

// Timer/Counter 1 Control and Status Register
#define TCCR1B	_IO8(0x2E)

// Timer/Counter 1 - Counter Register
#define TCNT1	_IO16(0x2C)

// Timer/Counter 1 - Counter Register Low Byte
#define TCNT1L	_IO8(0x2C)

// Timer/Counter 1 - Counter Register High Byte
#define TCNT1H	_IO8(0x2D)

// Timer/Counter 1 - Compare Register
#define OCR1A	_IO16(0x2A)

// Timer/Counter 1 - Compare Register Low Byte
#define OCR1AL	_IO8(0x2A)

// Timer/Counter 1 - Compare Register High Byte
#define OCR1AH	_IO8(0x2B)

// Timer/Counter 1 - Input Capture Register
#define ICR1	_IO16(0x24)

// Timer/Counter 1 - Input Capture Register Low Byte
#define ICR1L	_IO8(0x24)

// Timer/Counter 1 - Input Capture Register High Byte
#define ICR1H	_IO8(0x25)

// Watchdog Timer Control Register
#define WDTCR	_IO8(0x21)

// EEPROM Address Register
#define EEAR	_IO8(0x1E)

// EEPROM Data Register
#define EEDR	_IO8(0x1D)

// EEPROM Control Register
#define EECR	_IO8(0x1C)

// Port B - Data Register
#define PORTB	_IO8(0x18)

// Port B - Data Direction Register
#define DDRB	_IO8(0x17)

// Port B - Input Pins
#define PINB	_IO8(0x16)

// Port D - Data Register
#define PORTD	_IO8(0x12)

// Port D - Data Direction Register
#define DDRD	_IO8(0x11)

// Port D - Input Pins
#define PIND	_IO8(0x10)

// UART I/O Data Register
#define UDR	   _IO8(0x0C)

// UART Status Register
#define USR	   _IO8(0x0B)

// UART Control Register
#define UCR	   _IO8(0x0A)

// UART Baud Rate Register
#define UBRR   _IO8(0x09)

// Analog Comparator Control and Status Register
#define ACSR   _IO8(0x08)

#endif
