#include "app/emu/cpu/cpu.h" namespace yaze { namespace app { namespace emu { // addressing modes void Cpu::AdrImp() { // only for 2-cycle implied opcodes CheckInt(); if (int_wanted_) { // if interrupt detected in 2-cycle implied/accumulator opcode, // idle cycle turns into read from pc ReadByte((PB << 16) | PC); } else { callbacks_.idle(false); } } uint32_t Cpu::Absolute(Cpu::AccessType access_type) { auto operand = FetchWord(); uint32_t bank = (access_type == Cpu::AccessType::Data) ? (DB << 16) : (PB << 16); return bank | (operand & 0xFFFF); } uint32_t Cpu::AbsoluteIndexedX() { uint16_t address = ReadWord((PB << 16) | (PC + 1)); uint32_t effective_address = (DB << 16) | ((address + X) & 0xFFFF); return effective_address; } uint32_t Cpu::AbsoluteIndexedY() { uint16_t address = ReadWord((PB << 16) | (PC + 1)); uint32_t effective_address = (DB << 16) | address + Y; return effective_address; } uint16_t Cpu::AbsoluteIndexedIndirect() { uint16_t address = FetchWord() + X; callbacks_.idle(false); return ReadWord((DB << 16) | address & 0xFFFF); } uint16_t Cpu::AbsoluteIndirect() { uint16_t address = FetchWord(); return ReadWord((PB << 16) | address); } uint32_t Cpu::AbsoluteIndirectLong() { uint16_t address = FetchWord(); return ReadWordLong((PB << 16) | address); } uint32_t Cpu::AbsoluteLong() { return FetchLong(); } uint32_t Cpu::AbsoluteLongIndexedX() { return FetchLong() + X; } void Cpu::BlockMove(uint16_t source, uint16_t dest, uint16_t length) { for (int i = 0; i < length; i++) { WriteByte(dest + i, ReadByte(source + i)); } } uint16_t Cpu::DirectPage() { uint8_t dp = FetchByte(); return D + dp; } uint16_t Cpu::DirectPageIndexedX() { uint8_t operand = FetchByte(); uint16_t x_by_mode = GetAccumulatorSize() ? X : X & 0xFF; return D + operand + x_by_mode; } uint16_t Cpu::DirectPageIndexedY() { uint8_t operand = FetchByte(); return (operand + Y) & 0xFF; } uint16_t Cpu::DirectPageIndexedIndirectX() { uint8_t operand = FetchByte(); if (D & 0xFF) { callbacks_.idle(false); // dpr not 0: 1 extra cycle } callbacks_.idle(false); uint16_t indirect_address = D + operand + X; uint16_t effective_address = ReadWord(indirect_address & 0xFFFF); return effective_address; } uint16_t Cpu::DirectPageIndirect() { uint8_t dp = FetchByte(); uint16_t effective_address = D + dp; return ReadWord(effective_address); } uint32_t Cpu::DirectPageIndirectLong() { uint8_t dp = FetchByte(); uint16_t effective_address = D + dp; return ReadWordLong((0x00 << 0x10) | effective_address); } uint16_t Cpu::DirectPageIndirectIndexedY() { uint8_t operand = FetchByte(); uint16_t indirect_address = D + operand; return ReadWord(indirect_address) + Y; } uint32_t Cpu::DirectPageIndirectLongIndexedY() { uint8_t operand = FetchByte(); uint16_t indirect_address = D + operand; uint16_t y_by_mode = GetAccumulatorSize() ? Y : Y & 0xFF; uint32_t effective_address = ReadWordLong(indirect_address) + y_by_mode; return effective_address; } uint16_t Cpu::Immediate(bool index_size) { bool bit_mode = index_size ? GetIndexSize() : GetAccumulatorSize(); if (bit_mode) { return ReadByte((PB << 16) | PC + 1); } else { return ReadWord((PB << 16) | PC + 1); } } uint16_t Cpu::StackRelative() { uint8_t sr = FetchByte(); uint16_t effective_address = SP() + sr; return effective_address; } uint32_t Cpu::StackRelativeIndirectIndexedY() { uint8_t sr = FetchByte(); return (DB << 0x10) | (ReadWord(SP() + sr) + Y); } } // namespace emu } // namespace app } // namespace yaze