~williamvds/microlator

6984e3ce7ffcb339fdbbd92ef4ba61717095c537 — williamvds 3 years ago 2626b36
Make more CPU methods constexpr
2 files changed, 120 insertions(+), 120 deletions(-)

M src/cpu.cpp
M src/cpu.hpp
M src/cpu.cpp => src/cpu.cpp +60 -60
@@ 263,7 263,7 @@ constexpr void CPU::popFlags() noexcept {
	flags = value;
}

void CPU::calculateFlag(uint8_t value, Flags::Index flag) noexcept {
constexpr void CPU::calculateFlag(uint8_t value, Flags::Index flag) noexcept {
	bool result = false;
	assert(flag == F::Carry
		|| flag == F::Zero


@@ 284,18 284,18 @@ void CPU::calculateFlag(uint8_t value, Flags::Index flag) noexcept {
}

template<class T, class... Args>
void CPU::calculateFlag(uint8_t value, T flag, Args... flags) {
constexpr void CPU::calculateFlag(uint8_t value, T flag, Args... flags) {
	calculateFlag(value, flag);
	calculateFlag(value, flags...);
}

void CPU::compare(size_t a, size_t b) noexcept {
constexpr void CPU::compare(size_t a, size_t b) noexcept {
	flags.set(F::Zero,     a == b);
	flags.set(F::Carry,    a >= b);
	flags.set(F::Negative, isNegative(a - b));
}

void CPU::addWithCarry(uint8_t input) noexcept {
constexpr void CPU::addWithCarry(uint8_t input) noexcept {
	// TODO: implement decimal mode
	const uint8_t result = accumulator + input + (flags.test(F::Carry) ? 1 : 0);
	calculateFlag(result, F::Zero, F::Negative);


@@ 309,17 309,17 @@ void CPU::addWithCarry(uint8_t input) noexcept {
	accumulator = result;
}

void CPU::oADC(ValueStore address) noexcept {
constexpr void CPU::oADC(ValueStore address) noexcept {
	addWithCarry(address.read());
}

void CPU::oAND(ValueStore address) noexcept {
constexpr void CPU::oAND(ValueStore address) noexcept {
	const auto input = address.read();
	accumulator &= input;
	calculateFlag(accumulator, F::Zero, F::Negative);
}

void CPU::oASL(ValueStore address) noexcept {
constexpr void CPU::oASL(ValueStore address) noexcept {
	const auto input = address.read();
	flags.set(F::Carry, getBit(7, input));



@@ 328,163 328,163 @@ void CPU::oASL(ValueStore address) noexcept {
	address.write(result);
}

void CPU::oBCC(ValueStore target) noexcept {
constexpr void CPU::oBCC(ValueStore target) noexcept {
	if (!flags.test(F::Carry))
		branch(target.value);
}

void CPU::oBCS(ValueStore target) noexcept {
constexpr void CPU::oBCS(ValueStore target) noexcept {
	if (flags.test(F::Carry))
		branch(target.value);
}

void CPU::oBEQ(ValueStore target) noexcept {
constexpr void CPU::oBEQ(ValueStore target) noexcept {
	if (flags.test(F::Zero))
		branch(target.value);
}

void CPU::oBIT(ValueStore address) noexcept {
constexpr void CPU::oBIT(ValueStore address) noexcept {
	const auto input = address.read();
	flags.set(F::Zero, !toBool(input & accumulator));
	flags.set(F::Overflow, getBit(6, input));
	flags.set(F::Negative, isNegative(input));
}

void CPU::oBMI(ValueStore target) noexcept {
constexpr void CPU::oBMI(ValueStore target) noexcept {
	if (flags.test(F::Negative))
		branch(target.value);
}

void CPU::oBNE(ValueStore target) noexcept {
constexpr void CPU::oBNE(ValueStore target) noexcept {
	if (!flags.test(F::Zero))
		branch(target.value);
}

void CPU::oBPL(ValueStore target) noexcept {
constexpr void CPU::oBPL(ValueStore target) noexcept {
	if (!flags.test(F::Negative))
		branch(target.value);
}

void CPU::oBRK(ValueStore) noexcept {
constexpr void CPU::oBRK(ValueStore) noexcept {
	flags.set(F::InterruptOff, true);
	
	push2(pc);
	push(toU8(flags.get()));
}

void CPU::oBVC(ValueStore target) noexcept {
constexpr void CPU::oBVC(ValueStore target) noexcept {
	if (!flags.test(F::Overflow))
		branch(target.value);
}

void CPU::oBVS(ValueStore target) noexcept {
constexpr void CPU::oBVS(ValueStore target) noexcept {
	if (flags.test(F::Overflow))
		branch(target.value);
}

void CPU::oCLC(ValueStore) noexcept {
constexpr void CPU::oCLC(ValueStore) noexcept {
	flags.set(F::Carry, false);
}

void CPU::oCLD(ValueStore) noexcept {
constexpr void CPU::oCLD(ValueStore) noexcept {
	flags.set(F::Decimal, false);
}

void CPU::oCLI(ValueStore) noexcept {
constexpr void CPU::oCLI(ValueStore) noexcept {
	flags.set(F::InterruptOff, false);
}

void CPU::oCLV(ValueStore) noexcept {
constexpr void CPU::oCLV(ValueStore) noexcept {
	flags.set(F::Overflow, false);
}

void CPU::oCMP(ValueStore address) noexcept {
constexpr void CPU::oCMP(ValueStore address) noexcept {
	const auto input = address.read();
	compare(accumulator, input);
}

void CPU::oCPX(ValueStore address) noexcept {
constexpr void CPU::oCPX(ValueStore address) noexcept {
	const auto input = address.read();
	compare(indexX, input);
}

void CPU::oCPY(ValueStore address) noexcept {
constexpr void CPU::oCPY(ValueStore address) noexcept {
	const auto input = address.read();
	compare(indexY, input);
}

void CPU::oDEC(ValueStore address) noexcept {
constexpr void CPU::oDEC(ValueStore address) noexcept {
	const auto input = address.read();
	const auto result = input - 1;
	calculateFlag(result, F::Zero, F::Negative);
	address.write(result);
}

void CPU::oDEX(ValueStore) noexcept {
constexpr void CPU::oDEX(ValueStore) noexcept {
	const auto result = indexX - 1;
	calculateFlag(result, F::Zero, F::Negative);
	indexX = result;
}

void CPU::oDEY(ValueStore) noexcept {
constexpr void CPU::oDEY(ValueStore) noexcept {
	const auto result = indexY - 1;
	calculateFlag(result, F::Zero, F::Negative);
	indexY = result;
}

void CPU::oEOR(ValueStore address) noexcept {
constexpr void CPU::oEOR(ValueStore address) noexcept {
	const auto input = address.read();
	accumulator = accumulator ^ input;
	calculateFlag(accumulator, F::Zero, F::Negative);
}

void CPU::oINC(ValueStore address) noexcept {
constexpr void CPU::oINC(ValueStore address) noexcept {
	const auto input = address.read();
	const auto result = input + 1;
	calculateFlag(result, F::Zero, F::Negative);
	address.write(result);
}

void CPU::oINX(ValueStore) noexcept {
constexpr void CPU::oINX(ValueStore) noexcept {
	const auto result = indexX + 1;
	calculateFlag(result, F::Zero, F::Negative);
	indexX = result;
}

void CPU::oINY(ValueStore) noexcept {
constexpr void CPU::oINY(ValueStore) noexcept {
	const auto result = indexY + 1;
	calculateFlag(result, F::Zero, F::Negative);
	indexY = result;
}

void CPU::oJMP(ValueStore target) noexcept {
constexpr void CPU::oJMP(ValueStore target) noexcept {
	pc = target.value;
}

void CPU::oJSR(ValueStore target) noexcept {
constexpr void CPU::oJSR(ValueStore target) noexcept {
	push2(toU16(pc - 1));
	pc = target.value;
}

void CPU::oLDA(ValueStore address) noexcept {
constexpr void CPU::oLDA(ValueStore address) noexcept {
	const auto input = address.read();
	accumulator = input;
	calculateFlag(input, F::Zero, F::Negative);
}

void CPU::oLDX(ValueStore address) noexcept {
constexpr void CPU::oLDX(ValueStore address) noexcept {
	const auto input = address.read();
	indexX = input;
	calculateFlag(input, F::Zero, F::Negative);
}

void CPU::oLDY(ValueStore address) noexcept {
constexpr void CPU::oLDY(ValueStore address) noexcept {
	const auto input = address.read();
	indexY = input;
	calculateFlag(input, F::Zero, F::Negative);
}

void CPU::oLSR(ValueStore address) noexcept {
constexpr void CPU::oLSR(ValueStore address) noexcept {
	const auto input = address.read();
	const auto result = input >> 1U;
	calculateFlag(result, F::Zero, F::Negative);


@@ 492,34 492,34 @@ void CPU::oLSR(ValueStore address) noexcept {
	address.write(result);
}

void CPU::oNOP(ValueStore) noexcept {
constexpr void CPU::oNOP(ValueStore) noexcept {
}

void CPU::oORA(ValueStore address) noexcept {
constexpr void CPU::oORA(ValueStore address) noexcept {
	const auto input = address.read();
	const auto result = accumulator | input;
	calculateFlag(result, F::Zero, F::Negative);
	accumulator = result;
}

void CPU::oPHA(ValueStore) noexcept {
constexpr void CPU::oPHA(ValueStore) noexcept {
	push(accumulator);
}

void CPU::oPHP(ValueStore) noexcept {
constexpr void CPU::oPHP(ValueStore) noexcept {
	push(toU8(flags.get() | Flags::bitmask(F::Break)));
}

void CPU::oPLA(ValueStore) noexcept {
constexpr void CPU::oPLA(ValueStore) noexcept {
	accumulator = pop();
	calculateFlag(accumulator, F::Zero, F::Negative);
}

void CPU::oPLP(ValueStore) noexcept {
constexpr void CPU::oPLP(ValueStore) noexcept {
	popFlags();
}

void CPU::oROL(ValueStore address) noexcept {
constexpr void CPU::oROL(ValueStore address) noexcept {
	const auto input = address.read();
	const auto result = setBit(0, input << 1U, flags.test(F::Carry));



@@ 528,7 528,7 @@ void CPU::oROL(ValueStore address) noexcept {
	address.write(result);
}

void CPU::oROR(ValueStore address) noexcept {
constexpr void CPU::oROR(ValueStore address) noexcept {
	const auto input = address.read();
	const auto result = setBit(7, input >> 1U, flags.test(F::Carry));



@@ 537,68 537,68 @@ void CPU::oROR(ValueStore address) noexcept {
	address.write(result);
}

void CPU::oRTI(ValueStore) noexcept {
constexpr void CPU::oRTI(ValueStore) noexcept {
	popFlags();
	pc    = pop2();
}

void CPU::oRTS(ValueStore) noexcept {
constexpr void CPU::oRTS(ValueStore) noexcept {
	pc = pop2() + 1;
}

void CPU::oSBC(ValueStore address) noexcept {
constexpr void CPU::oSBC(ValueStore address) noexcept {
	addWithCarry(~address.read());
}

void CPU::oSEC(ValueStore) noexcept {
constexpr void CPU::oSEC(ValueStore) noexcept {
	flags.set(F::Carry, true);
}

void CPU::oSED(ValueStore) noexcept {
constexpr void CPU::oSED(ValueStore) noexcept {
	flags.set(F::Decimal, true);
}

void CPU::oSEI(ValueStore) noexcept {
constexpr void CPU::oSEI(ValueStore) noexcept {
	flags.set(F::InterruptOff, true);
}

void CPU::oSTA(ValueStore address) noexcept {
constexpr void CPU::oSTA(ValueStore address) noexcept {
	address.write(accumulator);
}

void CPU::oSTX(ValueStore address) noexcept {
constexpr void CPU::oSTX(ValueStore address) noexcept {
	address.write(indexX);
}

void CPU::oSTY(ValueStore address) noexcept {
constexpr void CPU::oSTY(ValueStore address) noexcept {
	address.write(indexY);
}

void CPU::oTAX(ValueStore) noexcept {
constexpr void CPU::oTAX(ValueStore) noexcept {
	indexX = accumulator;
	calculateFlag(indexX, F::Zero, F::Negative);
}

void CPU::oTAY(ValueStore) noexcept {
constexpr void CPU::oTAY(ValueStore) noexcept {
	indexY = accumulator;
	calculateFlag(indexY, F::Zero, F::Negative);
}

void CPU::oTSX(ValueStore) noexcept {
constexpr void CPU::oTSX(ValueStore) noexcept {
	indexX = stack;
	calculateFlag(indexX, F::Zero, F::Negative);
}

void CPU::oTXA(ValueStore) noexcept {
constexpr void CPU::oTXA(ValueStore) noexcept {
	accumulator = indexX;
	calculateFlag(accumulator, F::Zero, F::Negative);
}

void CPU::oTXS(ValueStore) noexcept {
constexpr void CPU::oTXS(ValueStore) noexcept {
	stack = indexX;
}

void CPU::oTYA(ValueStore) noexcept {
constexpr void CPU::oTYA(ValueStore) noexcept {
	accumulator = indexY;
	calculateFlag(accumulator, F::Zero, F::Negative);
}

M src/cpu.hpp => src/cpu.hpp +60 -60
@@ 174,68 174,68 @@ private:
	constexpr void branch(uint16_t) noexcept;

	template<class T, class... Args>
	void calculateFlag(uint8_t value, T flag, Args... flags);
	void calculateFlag(uint8_t value, Flags::Index flag) noexcept;
	void compare(size_t a, size_t b) noexcept;
	void addWithCarry(uint8_t value) noexcept;
	constexpr void calculateFlag(uint8_t value, T flag, Args... flags);
	constexpr void calculateFlag(uint8_t value, Flags::Index flag) noexcept;
	constexpr void compare(size_t a, size_t b) noexcept;
	constexpr void addWithCarry(uint8_t value) noexcept;

	// Instructions
	void oADC(ValueStore) noexcept;
	void oAND(ValueStore) noexcept;
	void oASL(ValueStore) noexcept;
	void oBCC(ValueStore) noexcept;
	void oBCS(ValueStore) noexcept;
	void oBEQ(ValueStore) noexcept;
	void oBIT(ValueStore) noexcept;
	void oBMI(ValueStore) noexcept;
	void oBNE(ValueStore) noexcept;
	void oBPL(ValueStore) noexcept;
	void oBRK(ValueStore) noexcept;
	void oBVC(ValueStore) noexcept;
	void oBVS(ValueStore) noexcept;
	void oCLC(ValueStore) noexcept;
	void oCLD(ValueStore) noexcept;
	void oCLI(ValueStore) noexcept;
	void oCLV(ValueStore) noexcept;
	void oCMP(ValueStore) noexcept;
	void oCPX(ValueStore) noexcept;
	void oCPY(ValueStore) noexcept;
	void oDEC(ValueStore) noexcept;
	void oDEX(ValueStore) noexcept;
	void oDEY(ValueStore) noexcept;
	void oEOR(ValueStore) noexcept;
	void oINC(ValueStore) noexcept;
	void oINX(ValueStore) noexcept;
	void oINY(ValueStore) noexcept;
	void oJMP(ValueStore) noexcept;
	void oJSR(ValueStore) noexcept;
	void oLDA(ValueStore) noexcept;
	void oLDX(ValueStore) noexcept;
	void oLDY(ValueStore) noexcept;
	void oLSR(ValueStore) noexcept;
	void oNOP(ValueStore) noexcept;
	void oORA(ValueStore) noexcept;
	void oPHA(ValueStore) noexcept;
	void oPHP(ValueStore) noexcept;
	void oPLA(ValueStore) noexcept;
	void oPLP(ValueStore) noexcept;
	void oROL(ValueStore) noexcept;
	void oROR(ValueStore) noexcept;
	void oRTI(ValueStore) noexcept;
	void oRTS(ValueStore) noexcept;
	void oSBC(ValueStore) noexcept;
	void oSEC(ValueStore) noexcept;
	void oSED(ValueStore) noexcept;
	void oSEI(ValueStore) noexcept;
	void oSTA(ValueStore) noexcept;
	void oSTX(ValueStore) noexcept;
	void oSTY(ValueStore) noexcept;
	void oTAX(ValueStore) noexcept;
	void oTAY(ValueStore) noexcept;
	void oTSX(ValueStore) noexcept;
	void oTXA(ValueStore) noexcept;
	void oTXS(ValueStore) noexcept;
	void oTYA(ValueStore) noexcept;
	constexpr void oADC(ValueStore) noexcept;
	constexpr void oAND(ValueStore) noexcept;
	constexpr void oASL(ValueStore) noexcept;
	constexpr void oBCC(ValueStore) noexcept;
	constexpr void oBCS(ValueStore) noexcept;
	constexpr void oBEQ(ValueStore) noexcept;
	constexpr void oBIT(ValueStore) noexcept;
	constexpr void oBMI(ValueStore) noexcept;
	constexpr void oBNE(ValueStore) noexcept;
	constexpr void oBPL(ValueStore) noexcept;
	constexpr void oBRK(ValueStore) noexcept;
	constexpr void oBVC(ValueStore) noexcept;
	constexpr void oBVS(ValueStore) noexcept;
	constexpr void oCLC(ValueStore) noexcept;
	constexpr void oCLD(ValueStore) noexcept;
	constexpr void oCLI(ValueStore) noexcept;
	constexpr void oCLV(ValueStore) noexcept;
	constexpr void oCMP(ValueStore) noexcept;
	constexpr void oCPX(ValueStore) noexcept;
	constexpr void oCPY(ValueStore) noexcept;
	constexpr void oDEC(ValueStore) noexcept;
	constexpr void oDEX(ValueStore) noexcept;
	constexpr void oDEY(ValueStore) noexcept;
	constexpr void oEOR(ValueStore) noexcept;
	constexpr void oINC(ValueStore) noexcept;
	constexpr void oINX(ValueStore) noexcept;
	constexpr void oINY(ValueStore) noexcept;
	constexpr void oJMP(ValueStore) noexcept;
	constexpr void oJSR(ValueStore) noexcept;
	constexpr void oLDA(ValueStore) noexcept;
	constexpr void oLDX(ValueStore) noexcept;
	constexpr void oLDY(ValueStore) noexcept;
	constexpr void oLSR(ValueStore) noexcept;
	constexpr void oNOP(ValueStore) noexcept;
	constexpr void oORA(ValueStore) noexcept;
	constexpr void oPHA(ValueStore) noexcept;
	constexpr void oPHP(ValueStore) noexcept;
	constexpr void oPLA(ValueStore) noexcept;
	constexpr void oPLP(ValueStore) noexcept;
	constexpr void oROL(ValueStore) noexcept;
	constexpr void oROR(ValueStore) noexcept;
	constexpr void oRTI(ValueStore) noexcept;
	constexpr void oRTS(ValueStore) noexcept;
	constexpr void oSBC(ValueStore) noexcept;
	constexpr void oSEC(ValueStore) noexcept;
	constexpr void oSED(ValueStore) noexcept;
	constexpr void oSEI(ValueStore) noexcept;
	constexpr void oSTA(ValueStore) noexcept;
	constexpr void oSTX(ValueStore) noexcept;
	constexpr void oSTY(ValueStore) noexcept;
	constexpr void oTAX(ValueStore) noexcept;
	constexpr void oTAY(ValueStore) noexcept;
	constexpr void oTSX(ValueStore) noexcept;
	constexpr void oTXA(ValueStore) noexcept;
	constexpr void oTXS(ValueStore) noexcept;
	constexpr void oTYA(ValueStore) noexcept;

	friend class ValueStore;
};