// Rowley AVR C Compiler, runtime support.
//
// Copyright (c) 2004 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;

// Swap nibble order within a byte
#pragma intrinsic(__swap_nibbles)
unsigned char __swap_nibbles(unsigned char);

// Swap byte order within a word
#pragma intrinsic(__swap_bytes)
unsigned __swap_bytes(unsigned x);

// Swap byte order within a long
#pragma intrinsic(__swap_bytes_long)
unsigned long __swap_bytes_long(unsigned long x);

// Swap word order within a long
#pragma intrinsic(__swap_words)
unsigned long __swap_words(unsigned long);

// Insert op into the code sequence
#pragma intrinsic(__insert_opcode)
void __insert_opcode(unsigned short op);

// Put processor to sleep
#define __sleep() __insert_opcode(0x9588);

// Reset the watchdog
#define __watchdog_reset() __insert_opcode(0x95a8);

// Programmed breakpoint
#define __breakpoint() __insert_opcode(0x9598);

// Set bits in status register and return original status register
#pragma intrinsic(__bis_SR_register)
unsigned char __bis_SR_register(unsigned char);

// Clear bits in status register and return original status register
#pragma intrinsic(__bic_SR_register)
unsigned char __bic_SR_register(unsigned char);

// Disable interrupts and return original status register
#define __disable_interrupt() __bic_SR_register(0x80)

// Enable interrupts and return original status register
#define __enable_interrupt()  __bis_SR_register(0x80)

#define __save_interrupt() (__sr)
#define __restore_interrupt(x)  do { if (x & 0x80) __enable_interrupt(); else __disable_interrupt(); } while (0)

// Insert a NOP to code sequence.
#define __no_operation() __insert_opcode(0x0000);

// Delay for a given number of cycles.
#pragma intrinsic(__delay_cycles)
void __delay_cycles(unsigned long);

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

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

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

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

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

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

#endif