/*
 * Copyright 2016 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved.
 */

#pragma once

#include "addresses.hpp"

OX_ALLOW_UNSAFE_BUFFERS_BEGIN

namespace teagba {

inline auto bgSetSbb(volatile BgCtl &bgCtl, unsigned sbb) noexcept {
	bgCtl = static_cast<BgCtl>(bgCtl & ~0b11111'0000'0000u) | static_cast<BgCtl>(sbb << 8);
}

[[nodiscard]]
constexpr unsigned bgPri(BgCtl bgCtl) noexcept {
	return bgCtl & 1;
}

inline auto bgSetPri(volatile BgCtl &bgCtl, unsigned pri) noexcept {
	pri = pri & 0b1;
	bgCtl = static_cast<BgCtl>(bgCtl & ~0b1u) | static_cast<BgCtl>(pri << 0);
}

[[nodiscard]]
constexpr unsigned bgBpp(BgCtl bgCtl) noexcept {
	return ((bgCtl >> 7) & 1) ? 8 : 4;
}

inline auto bgSetBpp(volatile BgCtl &bgCtl, unsigned bpp) noexcept {
	constexpr auto Bpp8 = 1 << 7;
	if (bpp == 4) {
		bgCtl = bgCtl | ((bgCtl | Bpp8) ^ Bpp8); // set to use 4 bits per pixel
	} else {
		bgCtl = bgCtl | Bpp8; // set to use 8 bits per pixel
	}
}

[[nodiscard]]
constexpr auto bgCbb(BgCtl bgCtl) noexcept {
	return (bgCtl >> 2) & 0b11u;
}

inline auto bgSetCbb(volatile BgCtl &bgCtl, unsigned cbb) noexcept {
	cbb = cbb & 0b11;
	bgCtl = static_cast<BgCtl>(bgCtl & ~0b1100u) | static_cast<BgCtl>(cbb << 2);
}

constexpr void iterateBgCtl(auto cb) noexcept {
	for (auto bgCtl = &REG_BG0CTL; bgCtl <= &REG_BG3CTL; bgCtl += 2) {
		cb(*bgCtl);
	}
}

}

OX_ALLOW_UNSAFE_BUFFERS_END
