bsnes/higan/processor/mos6502/instructions.cpp
Tim Allen 50411a17d1 Update to v102r26 release.
byuu says:

Changelog:

  - md/ym2612: initialize DAC sample to center volume [Cydrak]
  - processor/arm: add accumulate mode extra cycle to mlal [Jonas
    Quinn]
  - processor/huc6280: split off algorithms, improve naming of functions
  - processor/mos6502: split off algorithms
  - processor/spc700: major revamp of entire core (~50% completed)
  - processor/wdc65816: fixed several bugs introduced by rewrite

For the SPC700, this turns out to be very old code as well, with global
object state variables, those annoying `{Boolean,Natural}BitField` types,
`under_case` naming conventions, heavily abbreviated function names, etc.
I'm working to get the code to be in the same design as the MOS6502,
HuC6280, WDC65816 cores, since they're all extremely similar in terms of
architectural design (the SPC700 is more of an off-label
reimplementation of a 6502 core, but still.)

The main thing left is that about 90% of the actual instructions still
need to be adapted to not use the internal state (`aa`, `rd`, `dp`,
`sp`, `bit` variables.) I wanted to finish this today, but ran out of
time before work.

I wouldn't suggest too much testing just yet. We should wait until the
SPC700 core is finished for that. However, if some does want to and
spots regressions, please let me know.
2017-06-16 10:06:17 +10:00

234 lines
5.2 KiB
C++

auto MOS6502::instructionAbsoluteModify(fp alu) -> void {
uint16 absolute = operand();
absolute |= operand() << 8;
auto data = read(absolute);
write(absolute, data);
L write(absolute, ALU(data));
}
auto MOS6502::instructionAbsoluteModify(fp alu, uint8 index) -> void {
uint16 absolute = operand();
absolute |= operand() << 8;
idlePageAlways(absolute, absolute + index);
auto data = read(absolute + index);
write(absolute + index, data);
L write(absolute + index, ALU(data));
}
auto MOS6502::instructionAbsoluteRead(fp alu, uint8& data) -> void {
uint16 absolute = operand();
absolute |= operand() << 8;
L data = ALU(read(absolute));
}
auto MOS6502::instructionAbsoluteRead(fp alu, uint8& data, uint8 index) -> void {
uint16 absolute = operand();
absolute |= operand() << 8;
idlePageCrossed(absolute, absolute + index);
L data = ALU(read(absolute + index));
}
auto MOS6502::instructionAbsoluteWrite(uint8& data) -> void {
uint16 absolute = operand();
absolute |= operand() << 8;
L write(absolute, data);
}
auto MOS6502::instructionAbsoluteWrite(uint8& data, uint8 index) -> void {
uint16 absolute = operand();
absolute |= operand() << 8;
idlePageAlways(absolute, absolute + index);
L write(absolute + index, data);
}
auto MOS6502::instructionBranch(bool take) -> void {
if(!take) {
L operand();
} else {
int8 displacement = operand();
idlePageCrossed(PC, PC + displacement);
L idle();
PC = PC + displacement;
}
}
auto MOS6502::instructionClear(bool& flag) -> void {
L idle();
flag = 0;
}
auto MOS6502::instructionImmediate(fp alu, uint8& data) -> void {
L data = ALU(operand());
}
auto MOS6502::instructionImplied(fp alu, uint8& data) -> void {
L idle();
data = ALU(data);
}
auto MOS6502::instructionIndirectXRead(fp alu, uint8& data) -> void {
auto zeroPage = operand();
load(zeroPage);
uint16 absolute = load(zeroPage + X + 0);
absolute |= load(zeroPage + X + 1) << 8;
L data = ALU(read(absolute));
}
auto MOS6502::instructionIndirectXWrite(uint8& data) -> void {
auto zeroPage = operand();
load(zeroPage);
uint16 absolute = load(zeroPage + X + 0);
absolute |= load(zeroPage + X + 1) << 8;
L write(absolute, data);
}
auto MOS6502::instructionIndirectYRead(fp alu, uint8& data) -> void {
auto zeroPage = operand();
uint16 absolute = load(zeroPage + 0);
absolute |= load(zeroPage + 1) << 8;
idlePageCrossed(absolute, absolute + Y);
L data = ALU(read(absolute + Y));
}
auto MOS6502::instructionIndirectYWrite(uint8& data) -> void {
auto zeroPage = operand();
uint16 absolute = load(zeroPage + 0);
absolute |= load(zeroPage + 1) << 8;
idlePageAlways(absolute, absolute + Y);
L write(absolute + Y, data);
}
auto MOS6502::instructionPull(uint8& data) -> void {
idle();
idle();
L data = pull();
Z = data == 0;
N = data.bit(7);
}
auto MOS6502::instructionPush(uint8& data) -> void {
idle();
L push(data);
}
auto MOS6502::instructionSet(bool& flag) -> void {
L idle();
flag = 1;
}
auto MOS6502::instructionTransfer(uint8& source, uint8& target, bool flag) -> void {
L idle();
target = source;
if(!flag) return;
Z = target == 0;
N = target.bit(7);
}
auto MOS6502::instructionZeroPageModify(fp alu) -> void {
auto zeroPage = operand();
auto data = load(zeroPage);
store(zeroPage, data);
L store(zeroPage, ALU(data));
}
auto MOS6502::instructionZeroPageModify(fp alu, uint8 index) -> void {
auto zeroPage = operand();
load(zeroPage);
auto data = load(zeroPage + index);
store(zeroPage + index, data);
L store(zeroPage + index, ALU(data));
}
auto MOS6502::instructionZeroPageRead(fp alu, uint8& data) -> void {
auto zeroPage = operand();
L data = ALU(load(zeroPage));
}
auto MOS6502::instructionZeroPageRead(fp alu, uint8& data, uint8 index) -> void {
auto zeroPage = operand();
load(zeroPage);
L data = ALU(load(zeroPage + index));
}
auto MOS6502::instructionZeroPageWrite(uint8& data) -> void {
auto zeroPage = operand();
L store(zeroPage, data);
}
auto MOS6502::instructionZeroPageWrite(uint8& data, uint8 index) -> void {
auto zeroPage = operand();
read(zeroPage);
L store(zeroPage + index, data);
}
//
auto MOS6502::instructionBRK() -> void {
operand();
push(PCH);
push(PCL);
uint16 vector = 0xfffe;
nmi(vector);
push(P | 0x30);
I = 1;
PCL = read(vector++);
L PCH = read(vector++);
}
auto MOS6502::instructionJMPAbsolute() -> void {
uint16 absolute = operand();
L absolute |= operand() << 8;
PC = absolute;
}
auto MOS6502::instructionJMPIndirect() -> void {
uint16 absolute = operand();
absolute |= operand() << 8;
uint16 pc = read(absolute);
absolute.byte(0)++; //MOS6502: $00ff wraps here to $0000; not $0100
L pc |= read(absolute) << 8;
PC = pc;
}
auto MOS6502::instructionJSRAbsolute() -> void {
uint16 absolute = operand();
absolute |= operand() << 8;
idle();
PC--;
push(PCH);
L push(PCL);
PC = absolute;
}
auto MOS6502::instructionNOP() -> void {
L idle();
}
auto MOS6502::instructionPHP() -> void {
idle();
L push(P | 0x30);
}
auto MOS6502::instructionPLP() -> void {
idle();
idle();
L P = pull();
}
auto MOS6502::instructionRTI() -> void {
idle();
idle();
P = pull();
PCL = pull();
L PCH = pull();
}
auto MOS6502::instructionRTS() -> void {
idle();
idle();
PCL = pull();
PCH = pull();
L idle();
PC++;
}