Update Cpu
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -116,8 +116,19 @@ class Cpu : public Loggable, public core::ExperimentFlags {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetZN(uint16_t value, bool byte) {
|
||||||
|
if (byte) {
|
||||||
|
SetZeroFlag((value & 0xff) == 0);
|
||||||
|
SetNegativeFlag(value & 0x80);
|
||||||
|
} else {
|
||||||
|
SetZeroFlag(value == 0);
|
||||||
|
SetNegativeFlag(value & 0x8000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Setting flags in the status register
|
// Setting flags in the status register
|
||||||
bool m() { return GetAccumulatorSize() ? 1 : 0; }
|
bool m() { return GetAccumulatorSize() ? 1 : 0; }
|
||||||
|
bool xf() { return GetIndexSize() ? 1 : 0; }
|
||||||
int GetAccumulatorSize() const { return status & 0x20; }
|
int GetAccumulatorSize() const { return status & 0x20; }
|
||||||
int GetIndexSize() const { return status & 0x10; }
|
int GetIndexSize() const { return status & 0x10; }
|
||||||
void SetAccumulatorSize(bool set) { SetFlag(0x20, set); }
|
void SetAccumulatorSize(bool set) { SetFlag(0x20, set); }
|
||||||
@@ -152,15 +163,15 @@ class Cpu : public Loggable, public core::ExperimentFlags {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Memory access routines
|
// Memory access routines
|
||||||
uint8_t ReadByte(uint32_t address) const {
|
uint8_t ReadByte(uint32_t address) { return callbacks_.read_byte(address); }
|
||||||
return callbacks_.read_byte(address);
|
uint16_t ReadWord(uint32_t address, uint32_t address_high,
|
||||||
}
|
bool int_check = false) {
|
||||||
uint16_t ReadWord(uint32_t address) const {
|
|
||||||
uint8_t value = ReadByte(address);
|
uint8_t value = ReadByte(address);
|
||||||
uint8_t value2 = ReadByte(address + 1);
|
if (int_check) CheckInt();
|
||||||
|
uint8_t value2 = ReadByte(address_high);
|
||||||
return value | (value2 << 8);
|
return value | (value2 << 8);
|
||||||
}
|
}
|
||||||
uint32_t ReadWordLong(uint32_t address) const {
|
uint32_t ReadWordLong(uint32_t address) {
|
||||||
uint8_t value = ReadByte(address);
|
uint8_t value = ReadByte(address);
|
||||||
uint8_t value2 = ReadByte(address + 1);
|
uint8_t value2 = ReadByte(address + 1);
|
||||||
uint8_t value3 = ReadByte(address + 2);
|
uint8_t value3 = ReadByte(address + 2);
|
||||||
@@ -171,9 +182,17 @@ class Cpu : public Loggable, public core::ExperimentFlags {
|
|||||||
callbacks_.write_byte(address, value);
|
callbacks_.write_byte(address, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteWord(uint32_t address, uint16_t value) {
|
void WriteWord(uint32_t address, uint32_t address_high, uint16_t value,
|
||||||
|
bool reversed = false, bool int_check = false) {
|
||||||
|
if (reversed) {
|
||||||
|
WriteByte(address_high, value >> 8);
|
||||||
|
if (int_check) CheckInt();
|
||||||
WriteByte(address, value & 0xFF);
|
WriteByte(address, value & 0xFF);
|
||||||
WriteByte(address + 1, value >> 8);
|
} else {
|
||||||
|
WriteByte(address, value & 0xFF);
|
||||||
|
if (int_check) CheckInt();
|
||||||
|
WriteByte(address_high, value >> 8);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void WriteLong(uint32_t address, uint32_t value) {
|
void WriteLong(uint32_t address, uint32_t value) {
|
||||||
WriteByte(address, value & 0xFF);
|
WriteByte(address, value & 0xFF);
|
||||||
@@ -181,54 +200,6 @@ class Cpu : public Loggable, public core::ExperimentFlags {
|
|||||||
WriteByte(address + 2, value >> 16);
|
WriteByte(address + 2, value >> 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t FetchByte() {
|
|
||||||
uint32_t address = (PB << 16) | PC + 1;
|
|
||||||
uint8_t byte = ReadByte(address);
|
|
||||||
return byte;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t FetchWord() {
|
|
||||||
uint32_t address = (PB << 16) | PC + 1;
|
|
||||||
uint16_t value = ReadWord(address);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t FetchLong() {
|
|
||||||
uint32_t value = ReadWordLong((PB << 16) | PC + 1);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
int8_t FetchSignedByte() { return static_cast<int8_t>(FetchByte()); }
|
|
||||||
|
|
||||||
int16_t FetchSignedWord() {
|
|
||||||
auto offset = static_cast<int16_t>(FetchWord());
|
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t FetchByteDirectPage(uint8_t operand) {
|
|
||||||
uint16_t distance = D * 0x100;
|
|
||||||
|
|
||||||
// Calculate the effective address in the Direct Page
|
|
||||||
uint16_t effectiveAddress = operand + distance;
|
|
||||||
|
|
||||||
// Fetch the byte from memory
|
|
||||||
uint8_t fetchedByte = ReadByte(effectiveAddress);
|
|
||||||
|
|
||||||
next_pc_ = PC + 1;
|
|
||||||
|
|
||||||
return fetchedByte;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t ReadByteOrWord(uint32_t address) {
|
|
||||||
if (GetAccumulatorSize()) {
|
|
||||||
// 8-bit mode
|
|
||||||
return ReadByte(address) & 0xFF;
|
|
||||||
} else {
|
|
||||||
// 16-bit mode
|
|
||||||
return ReadWord(address);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PushByte(uint8_t value) {
|
void PushByte(uint8_t value) {
|
||||||
WriteByte(SP(), value);
|
WriteByte(SP(), value);
|
||||||
SetSP(SP() - 1);
|
SetSP(SP() - 1);
|
||||||
@@ -272,11 +243,8 @@ class Cpu : public Loggable, public core::ExperimentFlags {
|
|||||||
|
|
||||||
void set_int_delay(bool delay) { int_delay_ = delay; }
|
void set_int_delay(bool delay) { int_delay_ = delay; }
|
||||||
|
|
||||||
// ==========================================================================
|
|
||||||
// Addressing Modes
|
// Addressing Modes
|
||||||
|
|
||||||
void AdrImp();
|
|
||||||
|
|
||||||
// Effective Address:
|
// Effective Address:
|
||||||
// Bank: Data Bank Register if locating data
|
// Bank: Data Bank Register if locating data
|
||||||
// Program Bank Register if transferring control
|
// Program Bank Register if transferring control
|
||||||
@@ -284,7 +252,7 @@ class Cpu : public Loggable, public core::ExperimentFlags {
|
|||||||
// Low: First operand byte
|
// Low: First operand byte
|
||||||
//
|
//
|
||||||
// LDA addr
|
// LDA addr
|
||||||
uint32_t Absolute(AccessType access_type = AccessType::Data);
|
uint32_t Absolute(uint32_t* low);
|
||||||
|
|
||||||
// Effective Address:
|
// Effective Address:
|
||||||
// The Data Bank Register is concatened with the 16-bit operand
|
// The Data Bank Register is concatened with the 16-bit operand
|
||||||
@@ -293,6 +261,7 @@ class Cpu : public Loggable, public core::ExperimentFlags {
|
|||||||
//
|
//
|
||||||
// LDA addr, X
|
// LDA addr, X
|
||||||
uint32_t AbsoluteIndexedX();
|
uint32_t AbsoluteIndexedX();
|
||||||
|
uint32_t AdrAbx(uint32_t* low, bool write);
|
||||||
|
|
||||||
// Effective Address:
|
// Effective Address:
|
||||||
// The Data Bank Register is concatened with the 16-bit operand
|
// The Data Bank Register is concatened with the 16-bit operand
|
||||||
@@ -301,6 +270,17 @@ class Cpu : public Loggable, public core::ExperimentFlags {
|
|||||||
//
|
//
|
||||||
// LDA addr, Y
|
// LDA addr, Y
|
||||||
uint32_t AbsoluteIndexedY();
|
uint32_t AbsoluteIndexedY();
|
||||||
|
uint32_t AdrAby(uint32_t* low, bool write);
|
||||||
|
|
||||||
|
void AdrImp();
|
||||||
|
uint32_t AdrIdx(uint32_t* low);
|
||||||
|
|
||||||
|
uint32_t AdrIdp(uint32_t* low);
|
||||||
|
uint32_t AdrIdy(uint32_t* low, bool write);
|
||||||
|
uint32_t AdrIdl(uint32_t* low);
|
||||||
|
uint32_t AdrIly(uint32_t* low);
|
||||||
|
uint32_t AdrIsy(uint32_t* low);
|
||||||
|
uint32_t Immediate(uint32_t* low, bool xFlag);
|
||||||
|
|
||||||
// Effective Address:
|
// Effective Address:
|
||||||
// Bank: Program Bank Register (PBR)
|
// Bank: Program Bank Register (PBR)
|
||||||
@@ -333,12 +313,14 @@ class Cpu : public Loggable, public core::ExperimentFlags {
|
|||||||
//
|
//
|
||||||
// LDA long
|
// LDA long
|
||||||
uint32_t AbsoluteLong();
|
uint32_t AbsoluteLong();
|
||||||
|
uint32_t AdrAbl(uint32_t* low);
|
||||||
|
|
||||||
// Effective Address:
|
// Effective Address:
|
||||||
// The 24-bit operand is added to X based on the emulation mode
|
// The 24-bit operand is added to X based on the emulation mode
|
||||||
//
|
//
|
||||||
// LDA long, X
|
// LDA long, X
|
||||||
uint32_t AbsoluteLongIndexedX();
|
uint32_t AbsoluteLongIndexedX();
|
||||||
|
uint32_t AdrAlx(uint32_t* low);
|
||||||
|
|
||||||
// Source Effective Address:
|
// Source Effective Address:
|
||||||
// Bank: Second operand byte
|
// Bank: Second operand byte
|
||||||
@@ -360,6 +342,7 @@ class Cpu : public Loggable, public core::ExperimentFlags {
|
|||||||
//
|
//
|
||||||
// LDA dp
|
// LDA dp
|
||||||
uint16_t DirectPage();
|
uint16_t DirectPage();
|
||||||
|
uint32_t AdrDp(uint32_t* low);
|
||||||
|
|
||||||
// Effective Address:
|
// Effective Address:
|
||||||
// Bank: Zero
|
// Bank: Zero
|
||||||
@@ -368,6 +351,7 @@ class Cpu : public Loggable, public core::ExperimentFlags {
|
|||||||
//
|
//
|
||||||
// LDA dp, X
|
// LDA dp, X
|
||||||
uint16_t DirectPageIndexedX();
|
uint16_t DirectPageIndexedX();
|
||||||
|
uint32_t AdrDpx(uint32_t* low);
|
||||||
|
|
||||||
// Effective Address:
|
// Effective Address:
|
||||||
// Bank: Zero
|
// Bank: Zero
|
||||||
@@ -375,6 +359,7 @@ class Cpu : public Loggable, public core::ExperimentFlags {
|
|||||||
// based on the emulation mode
|
// based on the emulation mode
|
||||||
// LDA dp, Y
|
// LDA dp, Y
|
||||||
uint16_t DirectPageIndexedY();
|
uint16_t DirectPageIndexedY();
|
||||||
|
uint32_t AdrDpy(uint32_t* low);
|
||||||
|
|
||||||
// Effective Address:
|
// Effective Address:
|
||||||
// Bank: Data bank register
|
// Bank: Data bank register
|
||||||
@@ -432,6 +417,7 @@ class Cpu : public Loggable, public core::ExperimentFlags {
|
|||||||
uint16_t Immediate(bool index_size = false);
|
uint16_t Immediate(bool index_size = false);
|
||||||
|
|
||||||
uint16_t StackRelative();
|
uint16_t StackRelative();
|
||||||
|
uint32_t AdrSr(uint32_t* low);
|
||||||
|
|
||||||
// Effective Address:
|
// Effective Address:
|
||||||
// The Data Bank Register is concatenated to the Indirect Address;
|
// The Data Bank Register is concatenated to the Indirect Address;
|
||||||
@@ -572,7 +558,7 @@ class Cpu : public Loggable, public core::ExperimentFlags {
|
|||||||
void NOP();
|
void NOP();
|
||||||
|
|
||||||
// ORA: Logical inclusive OR
|
// ORA: Logical inclusive OR
|
||||||
void ORA(uint16_t address, bool immediate = false);
|
void ORA(uint32_t low, uint32_t high);
|
||||||
|
|
||||||
// PEA: Push effective absolute address
|
// PEA: Push effective absolute address
|
||||||
void PEA();
|
void PEA();
|
||||||
@@ -724,7 +710,30 @@ class Cpu : public Loggable, public core::ExperimentFlags {
|
|||||||
// XCE: Exchange carry and emulation bits
|
// XCE: Exchange carry and emulation bits
|
||||||
void XCE();
|
void XCE();
|
||||||
|
|
||||||
// ==========================================================================
|
void And(uint32_t low, uint32_t high);
|
||||||
|
void Eor(uint32_t low, uint32_t high);
|
||||||
|
void Adc(uint32_t low, uint32_t high);
|
||||||
|
void Sbc(uint32_t low, uint32_t high);
|
||||||
|
void Cmp(uint32_t low, uint32_t high);
|
||||||
|
void Cpx(uint32_t low, uint32_t high);
|
||||||
|
void Cpy(uint32_t low, uint32_t high);
|
||||||
|
void Bit(uint32_t low, uint32_t high);
|
||||||
|
void Lda(uint32_t low, uint32_t high);
|
||||||
|
void Ldx(uint32_t low, uint32_t high);
|
||||||
|
void Ldy(uint32_t low, uint32_t high);
|
||||||
|
void Sta(uint32_t low, uint32_t high);
|
||||||
|
void Stx(uint32_t low, uint32_t high);
|
||||||
|
void Sty(uint32_t low, uint32_t high);
|
||||||
|
void Stz(uint32_t low, uint32_t high);
|
||||||
|
void Ror(uint32_t low, uint32_t high);
|
||||||
|
void Rol(uint32_t low, uint32_t high);
|
||||||
|
void Lsr(uint32_t low, uint32_t high);
|
||||||
|
void Asl(uint32_t low, uint32_t high);
|
||||||
|
void Inc(uint32_t low, uint32_t high);
|
||||||
|
void Dec(uint32_t low, uint32_t high);
|
||||||
|
void Tsb(uint32_t low, uint32_t high);
|
||||||
|
void Trb(uint32_t low, uint32_t high);
|
||||||
|
|
||||||
uint16_t SP() const { return memory.SP(); }
|
uint16_t SP() const { return memory.SP(); }
|
||||||
void SetSP(uint16_t value) { memory.SetSP(value); }
|
void SetSP(uint16_t value) { memory.SetSP(value); }
|
||||||
|
|
||||||
@@ -745,7 +754,8 @@ class Cpu : public Loggable, public core::ExperimentFlags {
|
|||||||
auto GetBreakpoints() { return breakpoints_; }
|
auto GetBreakpoints() { return breakpoints_; }
|
||||||
|
|
||||||
void CheckInt() {
|
void CheckInt() {
|
||||||
int_wanted_ = (nmi_wanted_ || (irq_wanted_ && !GetInterruptFlag()))&& !int_delay_;
|
int_wanted_ =
|
||||||
|
(nmi_wanted_ || (irq_wanted_ && !GetInterruptFlag())) && !int_delay_;
|
||||||
int_delay_ = false;
|
int_delay_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -790,7 +800,6 @@ class Cpu : public Loggable, public core::ExperimentFlags {
|
|||||||
bool int_wanted_ = false;
|
bool int_wanted_ = false;
|
||||||
bool int_delay_ = false;
|
bool int_delay_ = false;
|
||||||
|
|
||||||
|
|
||||||
memory::CpuCallbacks callbacks_;
|
memory::CpuCallbacks callbacks_;
|
||||||
memory::Memory& memory;
|
memory::Memory& memory;
|
||||||
Clock& clock;
|
Clock& clock;
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace app {
|
namespace app {
|
||||||
namespace emu {
|
namespace emu {
|
||||||
// addressing modes
|
|
||||||
|
|
||||||
void Cpu::AdrImp() {
|
void Cpu::AdrImp() {
|
||||||
// only for 2-cycle implied opcodes
|
// only for 2-cycle implied opcodes
|
||||||
@@ -17,125 +16,175 @@ void Cpu::AdrImp() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t Cpu::Immediate(uint32_t* low, bool xFlag) {
|
||||||
uint32_t Cpu::Absolute(Cpu::AccessType access_type) {
|
if ((xFlag && GetIndexSize()) || (!xFlag && GetAccumulatorSize())) {
|
||||||
auto operand = FetchWord();
|
*low = (PB << 16) | PC++;
|
||||||
uint32_t bank =
|
return 0;
|
||||||
(access_type == Cpu::AccessType::Data) ? (DB << 16) : (PB << 16);
|
} else {
|
||||||
return bank | (operand & 0xFFFF);
|
*low = (PB << 16) | PC++;
|
||||||
}
|
return (PB << 16) | PC++;
|
||||||
|
|
||||||
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::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() {
|
uint16_t Cpu::DirectPage() {
|
||||||
uint8_t dp = FetchByte();
|
uint8_t dp = ReadOpcode();
|
||||||
return D + dp;
|
return D + dp;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t Cpu::DirectPageIndexedX() {
|
uint16_t Cpu::DirectPageIndexedX() {
|
||||||
uint8_t operand = FetchByte();
|
uint8_t operand = ReadOpcode();
|
||||||
uint16_t x_by_mode = GetAccumulatorSize() ? X : X & 0xFF;
|
uint16_t x_by_mode = GetAccumulatorSize() ? X : X & 0xFF;
|
||||||
return D + operand + x_by_mode;
|
return D + operand + x_by_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t Cpu::DirectPageIndexedY() {
|
uint16_t Cpu::DirectPageIndexedY() {
|
||||||
uint8_t operand = FetchByte();
|
uint8_t operand = ReadOpcode();
|
||||||
return (operand + Y) & 0xFF;
|
return (operand + Y) & 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t Cpu::DirectPageIndexedIndirectX() {
|
uint32_t Cpu::AdrIdx(uint32_t* low) {
|
||||||
uint8_t operand = FetchByte();
|
uint8_t adr = ReadOpcode();
|
||||||
if (D & 0xFF) {
|
if (D & 0xff) callbacks_.idle(false);
|
||||||
callbacks_.idle(false); // dpr not 0: 1 extra cycle
|
|
||||||
}
|
|
||||||
callbacks_.idle(false);
|
callbacks_.idle(false);
|
||||||
uint16_t indirect_address = D + operand + X;
|
uint16_t pointer = ReadWord((D + adr + X) & 0xffff, false);
|
||||||
uint16_t effective_address = ReadWord(indirect_address & 0xFFFF);
|
*low = (DB << 16) + pointer;
|
||||||
return effective_address;
|
return ((DB << 16) + pointer + 1) & 0xffffff;
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t Cpu::DirectPageIndirect() {
|
|
||||||
uint8_t dp = FetchByte();
|
|
||||||
uint16_t effective_address = D + dp;
|
|
||||||
return ReadWord(effective_address);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Cpu::DirectPageIndirectLong() {
|
uint32_t Cpu::DirectPageIndirectLong() {
|
||||||
uint8_t dp = FetchByte();
|
uint8_t dp = ReadOpcode();
|
||||||
uint16_t effective_address = D + dp;
|
uint16_t effective_address = D + dp;
|
||||||
return ReadWordLong((0x00 << 0x10) | effective_address);
|
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() {
|
uint32_t Cpu::DirectPageIndirectLongIndexedY() {
|
||||||
uint8_t operand = FetchByte();
|
uint8_t operand = ReadOpcode();
|
||||||
uint16_t indirect_address = D + operand;
|
uint16_t indirect_address = D + operand;
|
||||||
uint16_t y_by_mode = GetAccumulatorSize() ? Y : Y & 0xFF;
|
uint16_t y_by_mode = GetAccumulatorSize() ? Y : Y & 0xFF;
|
||||||
uint32_t effective_address = ReadWordLong(indirect_address) + y_by_mode;
|
uint32_t effective_address = ReadWordLong(indirect_address) + y_by_mode;
|
||||||
return effective_address;
|
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() {
|
uint16_t Cpu::StackRelative() {
|
||||||
uint8_t sr = FetchByte();
|
uint8_t sr = ReadOpcode();
|
||||||
uint16_t effective_address = SP() + sr;
|
uint16_t effective_address = SP() + sr;
|
||||||
return effective_address;
|
return effective_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Cpu::StackRelativeIndirectIndexedY() {
|
|
||||||
uint8_t sr = FetchByte();
|
|
||||||
return (DB << 0x10) | (ReadWord(SP() + sr) + Y);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace emu
|
} // namespace emu
|
||||||
} // namespace app
|
} // namespace app
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user