/**
 * @brief Register Editing Interface
 * @details This file is an abstraction to all the bitwise operations
 * @author Jake G
 * @date 2024
 * @copyright None
 * @file MockRegEdit.h
 */

#ifndef REGEDIT_H
#define REGEDIT_H

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

// Template of function signitures.
// XX: RegEdit_uxx
// REGTYPE: fixed width type.
/*
void XX_SetRegister(void *reg);
void XX_ClearRegister(void *reg);
void XX_SetBit(void *reg, uint8_t bit_num);
void XX_ClearBit(void *reg, uint8_t bit_num);
bool XX_IsBitSet(void *reg, uint8_t bit_num);
void XX_OR_Num(void *reg, REGTYPE num);
void XX_AND_Num(void *reg, REGTYPE num);
void XX_SetNum(void *reg, REGTYPE num);
REGTYPE XX_ReadReg(void *reg);
*/

// For 64-Bit systems and register access.

/**
 * @brief Sets all the bits in pointed register.
 * @param reg The register address.
 */
void RegEdit_u64_SetRegister(void *reg);

/**
 * @brief Clears all the bits in pointed register.
 * @param reg The register address.
 */
void RegEdit_u64_ClearRegister(void *reg);

/**
 * @brief Set's a specific bit in a register.
 * @param reg The register address.
 * @param bit_num The bit location.
 */
void     RegEdit_u64_SetBit(void *reg, uint8_t bit_num);
void     RegEdit_u64_ClearBit(void *reg, uint8_t bit_num);
bool     RegEdit_u64_IsBitSet(void *reg, uint8_t bit_num);
void     RegEdit_u64_OR_Num(void *reg, uint64_t num);
void     RegEdit_u64_AND_Num(void *reg, uint64_t num);
void     RegEdit_u64_SetNum(void *reg, uint64_t num);
uint64_t RegEdit_u64_ReadReg(void *reg);

// For 32-Bit systems and register access.

void     RegEdit_u32_SetRegister(void *reg);
void     RegEdit_u32_ClearRegister(void *reg);
void     RegEdit_u32_SetBit(void *reg, uint8_t bit_num);
void     RegEdit_u32_ClearBit(void *reg, uint8_t bit_num);
bool     RegEdit_u32_IsBitSet(void *reg, uint8_t bit_num);
void     RegEdit_u32_OR_Num(void *reg, uint32_t num);
void     RegEdit_u32_AND_Num(void *reg, uint32_t num);
void     RegEdit_u32_SetNum(void *reg, uint32_t num);
uint32_t RegEdit_u32_ReadReg(void *reg);

// For 16-Bit systems and register access.

void     RegEdit_u16_SetRegister(void *reg);
void     RegEdit_u16_ClearRegister(void *reg);
void     RegEdit_u16_SetBit(void *reg, uint8_t bit_num);
void     RegEdit_u16_ClearBit(void *reg, uint8_t bit_num);
bool     RegEdit_u16_IsBitSet(void *reg, uint8_t bit_num);
void     RegEdit_u16_OR_Num(void *reg, uint16_t num);
void     RegEdit_u16_AND_Num(void *reg, uint16_t num);
void     RegEdit_u16_SetNum(void *reg, uint16_t num);
uint16_t RegEdit_u16_ReadReg(void *reg);

// For 8-Bit systems and register access.

void    RegEdit_u8_SetRegister(void *reg);
void    RegEdit_u8_ClearRegister(void *reg);
void    RegEdit_u8_SetBit(void *reg, uint8_t bit_num);
void    RegEdit_u8_ClearBit(void *reg, uint8_t bit_num);
bool    RegEdit_u8_IsBitSet(void *reg, uint8_t bit_num);
void    RegEdit_u8_OR_Num(void *reg, uint8_t num);
void    RegEdit_u8_AND_Num(void *reg, uint8_t num);
void    RegEdit_u8_SetNum(void *reg, uint8_t num);
uint8_t RegEdit_u8_ReadReg(void *reg);

#endif // REGEDIT_H
