// Rowley AVR C Compiler, runtime support.
//
// Copyright (c) 2004, 2010 Rowley Associates Limited.
//
// This file may be distributed under the terms of the License Agreement
// provided with this software.
//
// THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

#ifndef __inavr_H
#define __inavr_H

// Status register
sfrb __sr = 0x5f;


/*! \brief Swap nibble order within a byte \ingroup Byte order manipulation

    \description \b \this  swaps the high and low nibbles of \a x
    and returns that as its result.
    \b \this is an intrinsic function and produces inline code.
*/
unsigned char __swap_nibbles(unsigned char __x);
#pragma intrinsic(__swap_nibbles)

/*! \brief Swap order of bytes in a word \ingroup Byte order manipulation \synopsis

  \description \b \this swaps the order of high and low bytes of \a x
  and returns that as its result.

  \b \this is an intrinsic function and produces inline code.
*/
unsigned __swap_bytes(unsigned __x);
#pragma intrinsic(__swap_bytes)

/*! \brief Swap order of bytes in a long \ingroup Byte order manipulation \synopsis

  \description \b \this swaps the order of all bytes of \a x
  and returns that as its result.

  \b \this is an intrinsic function and produces inline code.
*/
unsigned long __swap_bytes_long(unsigned long __x);
#pragma intrinsic(__swap_bytes_long)

/*! \brief Swap order of words in a long \ingroup Byte order manipulation \synopsis

  \description \b \this swaps the order of the high and low words of \a x
  and returns that as its result.

  \b \this is an intrinsic function and produces inline code.
*/
unsigned long __swap_words(unsigned long);
#pragma intrinsic(__swap_words)

/*! \brief Insert an opcode \ingroup Miscellaneous functions \synopsis

  \description \b \this inserts \a op into the code stream and can be
  used to insert special instructions directly into function code.
  \a op must be a compile-time constant.

  \b \this is an intrinsic function and produces inline code.
*/
void __insert_opcode(unsigned short __op);
#pragma intrinsic(__insert_opcode)

/*! \brief Put processor to sleep \ingroup Miscellaneous functions \synopsis

  \description \b \this inserts a \b SLEEP opcode into the code stream.

   \b \this is an intrinsic function and produces inline code.
*/
#define __sleep() __insert_opcode(0x9588);

/*! \brief Reset the watchdog \ingroup Miscellaneous functions \synopsis

   \description \b \this inserts a \b WDR opcode into the code stream.

   \b \this is an intrinsic function and produces inline code.
*/
#define __watchdog_reset() __insert_opcode(0x95a8);

/*! \brief Programmed breakpoint \ingroup Miscellaneous functions \synopsis

   \description \b \this inserts a \b BREAKPOINT opcode into the code stream.

   \b \this is an intrinsic function and produces inline code.
*/
#define __breakpoint() __insert_opcode(0x9598);

/*! \brief  Set bits in status register and return original status register \ingroup Status register manipulation \synopsis

  \description \b \this sets the bits specified in \a mask in the
  AVR status register (i.e. it bitwise ors \a mask into the status register)
  and  returns the value of the AVR status register
  before the update.

  \b \this is an intrinsic function and produces inline code.
*/
unsigned char __bis_SR_register(unsigned char __mask);
#pragma intrinsic(__bis_SR_register)

/*! \brief Clear bits in status register and return original status register \ingroup Status register manipulation \synopsis

  \description \b \this clears the bits specified in \a mask in
  the AVR status register (i.e. it bitwise ands the complement of \a mask into
  the status register) and  returns the value of the AVR status register
  before the update.

  \b \this is an intrinsic function and produces inline code.
*/
unsigned char __bic_SR_register(unsigned char __mask);
#pragma intrinsic(__bic_SR_register)

/*! \brief Disable interrupts and return original status register \ingroup Status register manipulation \synopsis

  \description \b \this disables global interrupts by clearing the \b I bit
  in the status register and  returns the value of the status register before
  the \b I bit
  is cleared. You can restore the state of the \b I bit from the
  value returned from \this by using the  \ref __restore_interrupt intrinsic
  function.

  \b \this is an intrinsic function and produces inline code.
*/
#define __disable_interrupt() __bic_SR_register(0x80)

/*! \brief Enable interrupts and return original status register \ingroup Status register manipulation \synopsis

  \description \b \this enables global interrupts by setting the \b I bit
  in the status register and  returns the value of the
  status register before the \b I bit
  is set. You can restore the state of the \b I bit from the value
  returned from \this by using the \ref __restore_interrupt intrinsic
  function.

  \b \this is an intrinsic function and produces inline code.
*/
#define __enable_interrupt()  __bis_SR_register(0x80)

/*! \brief Return the status register \ingroup Status register manipulation \synopsis

  \description \b \this returns the current value of the AVR status register,
  including the \b I  bit,
  without changing the status register. You can restore the state of the interrupt
  flag using the \ref __restore_interrupt intrinsic
  function.

  \b \this is an intrinsic function and produces inline code.
*/
#define __save_interrupt() (__sr)

/*! \brief Restore the interrupt enables \ingroup Status register manipulation

   \description \b \this restores the state of the \b I bit in the status register 
   to the value saved in \a x.

    The value of \a x is
    returned from the \ref __disable_interrupt, \ref __enable_interrupt,
    and \ref __save_interrupt intrinsic functions and is simply the
    previous value of the status register.

  \b \this is an intrinsic function and produces inline code.
*/
#define __restore_interrupt(x) do { if (x & 0x80) __enable_interrupt(); else __disable_interrupt(); } while (0)

/*! \brief NOP \ingroup Miscellaneous functions \synopsis

   \description \b \this inserts a \b NOP opcode into the code stream.

   \b \this is an intrinsic function and produces inline code.
*/
#define __no_operation() __insert_opcode(0x0000);

/*! \brief Delay execution for a number of cycles \ingroup Miscellaneous functions \synopsis

  \description \b \this delays program execution for exactly \a n
  processor cycles. n must be a compile-time constant.

  \b \this is an intrinsic function and produces inline code.
*/
void __delay_cycles(unsigned long n);
#pragma intrinsic(__delay_cycles)

// Get high 16 bits of 32-bit value
unsigned _H16(unsigned long);
#pragma intrinsic(_H16)

// Get low 16 bits of 64-bit value
unsigned _L16(unsigned long);
#pragma intrinsic(_L16)

// Get high 32 bits of 64-bit value
unsigned long _H32(unsigned long long);
#pragma intrinsic(_H32)

// Get low 32 bits of 64-bit value
unsigned long _L32(unsigned long long);
#pragma intrinsic(_L32)

// Get high 16 bits 64-bit value
unsigned _HH16(unsigned long long);
#pragma intrinsic(_HH16)

// Get low 16 bits 64-bit value
unsigned _LL16(unsigned long long);
#pragma intrinsic(_LL16)

#endif