Update Cpu
This commit is contained in:
@@ -3,7 +3,6 @@
|
||||
namespace yaze {
|
||||
namespace app {
|
||||
namespace emu {
|
||||
// addressing modes
|
||||
|
||||
void Cpu::AdrImp() {
|
||||
// only for 2-cycle implied opcodes
|
||||
@@ -17,125 +16,175 @@ void Cpu::AdrImp() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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));
|
||||
uint32_t Cpu::Immediate(uint32_t* low, bool xFlag) {
|
||||
if ((xFlag && GetIndexSize()) || (!xFlag && GetAccumulatorSize())) {
|
||||
*low = (PB << 16) | PC++;
|
||||
return 0;
|
||||
} else {
|
||||
*low = (PB << 16) | PC++;
|
||||
return (PB << 16) | PC++;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t Cpu::AdrDpx(uint32_t* low) {
|
||||
uint8_t adr = ReadOpcode();
|
||||
if (D & 0xff) callbacks_.idle(false); // dpr not 0: 1 extra cycle
|
||||
callbacks_.idle(false);
|
||||
*low = (D + adr + X) & 0xffff;
|
||||
return (D + adr + X + 1) & 0xffff;
|
||||
}
|
||||
|
||||
uint32_t Cpu::AdrDpy(uint32_t* low) {
|
||||
uint8_t adr = ReadOpcode();
|
||||
if (D & 0xff) callbacks_.idle(false); // dpr not 0: 1 extra cycle
|
||||
callbacks_.idle(false);
|
||||
*low = (D + adr + Y) & 0xffff;
|
||||
return (D + adr + Y + 1) & 0xffff;
|
||||
}
|
||||
|
||||
uint32_t Cpu::AdrIdp(uint32_t* low) {
|
||||
uint8_t adr = ReadOpcode();
|
||||
if (D & 0xff) callbacks_.idle(false); // dpr not 0: 1 extra cycle
|
||||
uint16_t pointer = ReadWord((D + adr) & 0xffff, false);
|
||||
*low = (DB << 16) + pointer;
|
||||
return ((DB << 16) + pointer + 1) & 0xffffff;
|
||||
}
|
||||
|
||||
uint32_t Cpu::AdrIdy(uint32_t* low, bool write) {
|
||||
uint8_t adr = ReadOpcode();
|
||||
if (D & 0xff) callbacks_.idle(false); // dpr not 0: 1 extra cycle
|
||||
uint16_t pointer = ReadWord((D + adr) & 0xffff, false);
|
||||
// writing opcode or x = 0 or page crossed: 1 extra cycle
|
||||
if (write || !GetIndexSize() || ((pointer >> 8) != ((pointer + Y) >> 8)))
|
||||
callbacks_.idle(false);
|
||||
*low = ((DB << 16) + pointer + Y) & 0xffffff;
|
||||
return ((DB << 16) + pointer + Y + 1) & 0xffffff;
|
||||
}
|
||||
|
||||
uint32_t Cpu::AdrIdl(uint32_t* low) {
|
||||
uint8_t adr = ReadOpcode();
|
||||
if (D & 0xff) callbacks_.idle(false); // dpr not 0: 1 extra cycle
|
||||
uint32_t pointer = ReadWord((D + adr) & 0xffff, false);
|
||||
pointer |= ReadByte((D + adr + 2) & 0xffff) << 16;
|
||||
*low = pointer;
|
||||
return (pointer + 1) & 0xffffff;
|
||||
}
|
||||
|
||||
uint32_t Cpu::AdrIly(uint32_t* low) {
|
||||
uint8_t adr = ReadOpcode();
|
||||
if (D & 0xff) callbacks_.idle(false); // dpr not 0: 1 extra cycle
|
||||
uint32_t pointer = ReadWord((D + adr) & 0xffff, false);
|
||||
pointer |= ReadByte((D + adr + 2) & 0xffff) << 16;
|
||||
*low = (pointer + Y) & 0xffffff;
|
||||
return (pointer + Y + 1) & 0xffffff;
|
||||
}
|
||||
|
||||
uint32_t Cpu::AdrSr(uint32_t* low) {
|
||||
uint8_t adr = ReadOpcode();
|
||||
callbacks_.idle(false);
|
||||
*low = (SP() + adr) & 0xffff;
|
||||
return (SP() + adr + 1) & 0xffff;
|
||||
}
|
||||
|
||||
uint32_t Cpu::AdrIsy(uint32_t* low) {
|
||||
uint8_t adr = ReadOpcode();
|
||||
callbacks_.idle(false);
|
||||
uint16_t pointer = ReadWord((SP() + adr) & 0xffff, false);
|
||||
callbacks_.idle(false);
|
||||
*low = ((DB << 16) + pointer + Y) & 0xffffff;
|
||||
return ((DB << 16) + pointer + Y + 1) & 0xffffff;
|
||||
}
|
||||
|
||||
uint32_t Cpu::Absolute(uint32_t* low) {
|
||||
uint16_t adr = ReadOpcodeWord(false);
|
||||
*low = (DB << 16) + adr;
|
||||
return ((DB << 16) + adr + 1) & 0xffffff;
|
||||
}
|
||||
|
||||
uint32_t Cpu::AdrAbx(uint32_t* low, bool write) {
|
||||
uint16_t adr = ReadOpcodeWord(false);
|
||||
// writing opcode or x = 0 or page crossed: 1 extra cycle
|
||||
if (write || !GetIndexSize() || ((adr >> 8) != ((adr + X) >> 8)))
|
||||
callbacks_.idle(false);
|
||||
*low = ((DB << 16) + adr + X) & 0xffffff;
|
||||
return ((DB << 16) + adr + X + 1) & 0xffffff;
|
||||
}
|
||||
|
||||
uint32_t Cpu::AdrAby(uint32_t* low, bool write) {
|
||||
uint16_t adr = ReadOpcodeWord(false);
|
||||
// writing opcode or x = 0 or page crossed: 1 extra cycle
|
||||
if (write || !GetIndexSize() || ((adr >> 8) != ((adr + Y) >> 8)))
|
||||
callbacks_.idle(false);
|
||||
*low = ((DB << 16) + adr + Y) & 0xffffff;
|
||||
return ((DB << 16) + adr + Y + 1) & 0xffffff;
|
||||
}
|
||||
|
||||
uint32_t Cpu::AdrAbl(uint32_t* low) {
|
||||
uint32_t adr = ReadOpcodeWord(false);
|
||||
adr |= ReadOpcode() << 16;
|
||||
*low = adr;
|
||||
return (adr + 1) & 0xffffff;
|
||||
}
|
||||
|
||||
uint32_t Cpu::AdrAlx(uint32_t* low) {
|
||||
uint32_t adr = ReadOpcodeWord(false);
|
||||
adr |= ReadOpcode() << 16;
|
||||
*low = (adr + X) & 0xffffff;
|
||||
return (adr + X + 1) & 0xffffff;
|
||||
}
|
||||
|
||||
uint32_t Cpu::AdrDp(uint32_t* low) {
|
||||
uint8_t adr = ReadOpcode();
|
||||
if (D & 0xff) callbacks_.idle(false); // dpr not 0: 1 extra cycle
|
||||
*low = (D + adr) & 0xffff;
|
||||
return (D + adr + 1) & 0xffff;
|
||||
}
|
||||
|
||||
uint16_t Cpu::DirectPage() {
|
||||
uint8_t dp = FetchByte();
|
||||
uint8_t dp = ReadOpcode();
|
||||
return D + dp;
|
||||
}
|
||||
|
||||
uint16_t Cpu::DirectPageIndexedX() {
|
||||
uint8_t operand = FetchByte();
|
||||
uint8_t operand = ReadOpcode();
|
||||
uint16_t x_by_mode = GetAccumulatorSize() ? X : X & 0xFF;
|
||||
return D + operand + x_by_mode;
|
||||
}
|
||||
|
||||
uint16_t Cpu::DirectPageIndexedY() {
|
||||
uint8_t operand = FetchByte();
|
||||
uint8_t operand = ReadOpcode();
|
||||
return (operand + Y) & 0xFF;
|
||||
}
|
||||
|
||||
uint16_t Cpu::DirectPageIndexedIndirectX() {
|
||||
uint8_t operand = FetchByte();
|
||||
if (D & 0xFF) {
|
||||
callbacks_.idle(false); // dpr not 0: 1 extra cycle
|
||||
}
|
||||
uint32_t Cpu::AdrIdx(uint32_t* low) {
|
||||
uint8_t adr = ReadOpcode();
|
||||
if (D & 0xff) callbacks_.idle(false);
|
||||
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);
|
||||
uint16_t pointer = ReadWord((D + adr + X) & 0xffff, false);
|
||||
*low = (DB << 16) + pointer;
|
||||
return ((DB << 16) + pointer + 1) & 0xffffff;
|
||||
}
|
||||
|
||||
uint32_t Cpu::DirectPageIndirectLong() {
|
||||
uint8_t dp = FetchByte();
|
||||
uint8_t dp = ReadOpcode();
|
||||
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();
|
||||
uint8_t operand = ReadOpcode();
|
||||
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();
|
||||
uint8_t sr = ReadOpcode();
|
||||
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
|
||||
Reference in New Issue
Block a user