Modifed to support all of the undocumented 6502 instructions.

git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@11 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
bwmott 2001-12-29 17:55:59 +00:00
parent 848dd37c25
commit 4f214fecfa
2 changed files with 635 additions and 175 deletions

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: M6502.cxx,v 1.1.1.1 2001-12-27 19:54:30 bwmott Exp $ // $Id: M6502.cxx,v 1.2 2001-12-29 17:55:59 bwmott Exp $
//============================================================================ //============================================================================
#include "M6502.hxx" #include "M6502.hxx"
@ -180,85 +180,85 @@ uInt8 M6502::ourBCDTable[2][256];
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
M6502::AddressingMode M6502::ourAddressingModeTable[256] = { M6502::AddressingMode M6502::ourAddressingModeTable[256] = {
Implied, IndirectX, Invalid, IndirectX, // 0x0? Implied, IndirectX, Invalid, IndirectX, // 0x0?
Zero, Zero, Zero, Zero, Zero, Zero, Zero, Zero,
Implied, Immediate, Implied, Invalid, Implied, Immediate, Implied, Immediate,
Absolute, Absolute, Absolute, Absolute, Absolute, Absolute, Absolute, Absolute,
Relative, IndirectY, Invalid, IndirectY, // 0x1? Relative, IndirectY, Invalid, IndirectY, // 0x1?
ZeroX, ZeroX, ZeroX, ZeroX, ZeroX, ZeroX, ZeroX, ZeroX,
Implied, AbsoluteY, Implied, AbsoluteY, Implied, AbsoluteY, Implied, AbsoluteY,
AbsoluteX, AbsoluteX, AbsoluteX, AbsoluteX, AbsoluteX, AbsoluteX, AbsoluteX, AbsoluteX,
Absolute, IndirectX, Invalid, IndirectX, // 0x2? Absolute, IndirectX, Invalid, IndirectX, // 0x2?
Zero, Zero, Zero, Zero, Zero, Zero, Zero, Zero,
Implied, Immediate, Implied, Invalid, Implied, Immediate, Implied, Immediate,
Absolute, Absolute, Absolute, Absolute, Absolute, Absolute, Absolute, Absolute,
Relative, IndirectY, Invalid, IndirectY, // 0x3? Relative, IndirectY, Invalid, IndirectY, // 0x3?
ZeroX, ZeroX, ZeroX, ZeroX, ZeroX, ZeroX, ZeroX, ZeroX,
Implied, AbsoluteY, Implied, AbsoluteY, Implied, AbsoluteY, Implied, AbsoluteY,
AbsoluteX, AbsoluteX, AbsoluteX, AbsoluteX, AbsoluteX, AbsoluteX, AbsoluteX, AbsoluteX,
Implied, IndirectX, Invalid, Invalid, // 0x4? Implied, IndirectX, Invalid, IndirectX, // 0x4?
Zero, Zero, Zero, Invalid,
Implied, Immediate, Implied, Invalid,
Absolute, Absolute, Absolute, Invalid,
Relative, IndirectY, Invalid, Invalid, // 0x5?
ZeroX, ZeroX, ZeroX, Invalid,
Implied, AbsoluteY, Implied, Invalid,
AbsoluteX, AbsoluteX, AbsoluteX, Invalid,
Implied, IndirectX, Invalid, Invalid, // 0x6?
Zero, Zero, Zero, Invalid,
Implied, Immediate, Implied, Invalid,
Indirect, Absolute, Absolute, Invalid,
Relative, IndirectY, Invalid, Invalid, // 0x7?
ZeroX, ZeroX, ZeroX, Invalid,
Implied, AbsoluteY, Implied, Invalid,
AbsoluteX, AbsoluteX, AbsoluteX, Invalid,
Immediate, IndirectX, Immediate, IndirectX, // 0x8?
Zero, Zero, Zero, Zero, Zero, Zero, Zero, Zero,
Implied, Invalid, Implied, Invalid, Implied, Immediate, Implied, Immediate,
Absolute, Absolute, Absolute, Absolute, Absolute, Absolute, Absolute, Absolute,
Relative, IndirectY, Invalid, Invalid, // 0x9? Relative, IndirectY, Invalid, IndirectY, // 0x5?
ZeroX, ZeroX, ZeroX, ZeroX,
Implied, AbsoluteY, Implied, AbsoluteY,
AbsoluteX, AbsoluteX, AbsoluteX, AbsoluteX,
Implied, IndirectX, Invalid, IndirectX, // 0x6?
Zero, Zero, Zero, Zero,
Implied, Immediate, Implied, Immediate,
Indirect, Absolute, Absolute, Absolute,
Relative, IndirectY, Invalid, IndirectY, // 0x7?
ZeroX, ZeroX, ZeroX, ZeroX,
Implied, AbsoluteY, Implied, AbsoluteY,
AbsoluteX, AbsoluteX, AbsoluteX, AbsoluteX,
Immediate, IndirectX, Immediate, IndirectX, // 0x8?
Zero, Zero, Zero, Zero,
Implied, Immediate, Implied, Immediate,
Absolute, Absolute, Absolute, Absolute,
Relative, IndirectY, Invalid, IndirectY, // 0x9?
ZeroX, ZeroX, ZeroY, ZeroY, ZeroX, ZeroX, ZeroY, ZeroY,
Implied, AbsoluteY, Implied, Invalid, Implied, AbsoluteY, Implied, AbsoluteY,
Invalid, AbsoluteX, Invalid, Invalid, AbsoluteX, AbsoluteX, AbsoluteY, AbsoluteY,
Immediate, IndirectX, Immediate, Invalid, // 0xA? Immediate, IndirectX, Immediate, IndirectX, // 0xA?
Zero, Zero, Zero, Invalid, Zero, Zero, Zero, Zero,
Implied, Immediate, Implied, Invalid, Implied, Immediate, Implied, Immediate,
Absolute, Absolute, Absolute, Invalid, Absolute, Absolute, Absolute, Absolute,
Relative, IndirectY, Invalid, Invalid, // 0xB? Relative, IndirectY, Invalid, IndirectY, // 0xB?
ZeroX, ZeroX, ZeroY, Invalid, ZeroX, ZeroX, ZeroY, ZeroY,
Implied, AbsoluteY, Implied, Invalid, Implied, AbsoluteY, Implied, AbsoluteY,
AbsoluteX, AbsoluteX, AbsoluteY, Invalid, AbsoluteX, AbsoluteX, AbsoluteY, AbsoluteY,
Immediate, IndirectX, Immediate, Invalid, // 0xC? Immediate, IndirectX, Immediate, IndirectX, // 0xC?
Zero, Zero, Zero, Invalid, Zero, Zero, Zero, Zero,
Implied, Immediate, Implied, Invalid, Implied, Immediate, Implied, Immediate,
Absolute, Absolute, Absolute, Invalid, Absolute, Absolute, Absolute, Absolute,
Relative, IndirectY, Invalid, Invalid, // 0xD? Relative, IndirectY, Invalid, IndirectY, // 0xD?
ZeroX, ZeroX, ZeroX, Invalid, ZeroX, ZeroX, ZeroX, ZeroX,
Implied, AbsoluteY, Implied, Invalid, Implied, AbsoluteY, Implied, AbsoluteY,
AbsoluteX, AbsoluteX, AbsoluteX, Invalid, AbsoluteX, AbsoluteX, AbsoluteX, AbsoluteX,
Immediate, IndirectX, Immediate, Invalid, // 0xE? Immediate, IndirectX, Immediate, IndirectX, // 0xE?
Zero, Zero, Zero, Invalid, Zero, Zero, Zero, Zero,
Implied, Immediate, Implied, Invalid, Implied, Immediate, Implied, Immediate,
Absolute, Absolute, Absolute, Invalid, Absolute, Absolute, Absolute, Absolute,
Relative, IndirectY, Invalid, Invalid, // 0xF? Relative, IndirectY, Invalid, IndirectY, // 0xF?
ZeroX, ZeroX, ZeroX, Invalid, ZeroX, ZeroX, ZeroX, ZeroX,
Implied, AbsoluteY, Implied, Invalid, Implied, AbsoluteY, Implied, AbsoluteY,
AbsoluteX, AbsoluteX, AbsoluteX, Invalid AbsoluteX, AbsoluteX, AbsoluteX, AbsoluteX
}; };
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -268,68 +268,68 @@ uInt32 M6502::ourInstructionProcessorCycleTable[256] = {
2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, // 1 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, // 1
6, 6, 2, 8, 3, 3, 5, 5, 4, 2, 2, 2, 4, 4, 6, 6, // 2 6, 6, 2, 8, 3, 3, 5, 5, 4, 2, 2, 2, 4, 4, 6, 6, // 2
2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, // 3 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, // 3
6, 6, 2, 2, 3, 3, 5, 2, 3, 2, 2, 2, 3, 4, 6, 2, // 4 6, 6, 2, 8, 3, 3, 5, 5, 3, 2, 2, 2, 3, 4, 6, 6, // 4
2, 5, 2, 2, 4, 4, 6, 2, 2, 4, 2, 2, 4, 4, 7, 2, // 5 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, // 5
6, 6, 2, 2, 3, 3, 5, 2, 4, 2, 2, 2, 5, 4, 6, 2, // 6 6, 6, 2, 8, 3, 3, 5, 5, 4, 2, 2, 2, 5, 4, 6, 6, // 6
2, 5, 2, 2, 4, 4, 6, 2, 2, 4, 2, 2, 4, 4, 7, 2, // 7 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, // 7
2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4, // 8 2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4, // 8
2, 6, 2, 2, 4, 4, 4, 4, 2, 5, 2, 2, 2, 5, 2, 2, // 9 2, 6, 2, 6, 4, 4, 4, 4, 2, 5, 2, 5, 5, 5, 5, 5, // 9
2, 6, 2, 2, 3, 3, 3, 2, 2, 2, 2, 2, 4, 4, 4, 2, // a 2, 6, 2, 6, 3, 3, 3, 4, 2, 2, 2, 2, 4, 4, 4, 4, // a
2, 5, 2, 2, 4, 4, 4, 2, 2, 4, 2, 2, 4, 4, 4, 2, // b 2, 5, 2, 5, 4, 4, 4, 4, 2, 4, 2, 4, 4, 4, 4, 4, // b
2, 6, 2, 2, 3, 3, 5, 2, 2, 2, 2, 2, 4, 4, 6, 2, // c 2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6, // c
2, 5, 2, 2, 4, 4, 6, 2, 2, 4, 2, 2, 4, 4, 7, 2, // d 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, // d
2, 6, 2, 2, 3, 3, 5, 2, 2, 2, 2, 2, 4, 4, 6, 2, // e 2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6, // e
2, 5, 2, 2, 4, 4, 6, 2, 2, 4, 2, 2, 4, 4, 7, 2 // f 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7 // f
}; };
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const char* M6502::ourInstructionMnemonicTable[256] = { const char* M6502::ourInstructionMnemonicTable[256] = {
"BRK", "ORA", "n/a", "aso", "nop", "ORA", "ASL", "aso", // 0x0? "BRK", "ORA", "n/a", "slo", "nop", "ORA", "ASL", "slo", // 0x0?
"PHP", "ORA", "ASLA", "n/a", "nop", "ORA", "ASL", "aso", "PHP", "ORA", "ASLA", "anc", "nop", "ORA", "ASL", "slo",
"BPL", "ORA", "n/a", "aso", "nop", "ORA", "ASL", "aso", // 0x1? "BPL", "ORA", "n/a", "slo", "nop", "ORA", "ASL", "slo", // 0x1?
"CLC", "ORA", "nop", "aso", "nop", "ORA", "ASL", "aso", "CLC", "ORA", "nop", "slo", "nop", "ORA", "ASL", "slo",
"JSR", "AND", "n/a", "rla", "BIT", "AND", "ROL", "rla", // 0x2? "JSR", "AND", "n/a", "rla", "BIT", "AND", "ROL", "rla", // 0x2?
"PLP", "AND", "ROLA", "n/a", "BIT", "AND", "ROL", "rla", "PLP", "AND", "ROLA", "anc", "BIT", "AND", "ROL", "rla",
"BMI", "AND", "rla", "n/a", "nop", "AND", "ROL", "rla", // 0x3? "BMI", "AND", "n/a", "rla", "nop", "AND", "ROL", "rla", // 0x3?
"SEC", "AND", "nop", "rla", "nop", "AND", "ROL", "rla", "SEC", "AND", "nop", "rla", "nop", "AND", "ROL", "rla",
"RTI", "EOR", "n/a", "n/a", "nop", "EOR", "LSR", "n/a", // 0x4? "RTI", "EOR", "n/a", "sre", "nop", "EOR", "LSR", "sre", // 0x4?
"PHA", "EOR", "LSRA", "n/a", "JMP", "EOR", "LSR", "n/a", "PHA", "EOR", "LSRA", "asr", "JMP", "EOR", "LSR", "sre",
"BVC", "EOR", "n/a", "n/a", "nop", "EOR", "LSR", "n/a", // 0x5? "BVC", "EOR", "n/a", "sre", "nop", "EOR", "LSR", "sre", // 0x5?
"CLI", "EOR", "nop", "n/a", "nop", "EOR", "LSR", "n/a", "CLI", "EOR", "nop", "sre", "nop", "EOR", "LSR", "sre",
"RTS", "ADC", "n/a", "n/a", "nop", "ADC", "ROR", "n/a", // 0x6? "RTS", "ADC", "n/a", "rra", "nop", "ADC", "ROR", "rra", // 0x6?
"PLA", "ADC", "RORA", "n/a", "JMP", "ADC", "ROR", "n/a", "PLA", "ADC", "RORA", "arr", "JMP", "ADC", "ROR", "rra",
"BVS", "ADC", "n/a", "n/a", "nop", "ADC", "ROR", "n/a", // 0x7? "BVS", "ADC", "n/a", "rra", "nop", "ADC", "ROR", "rra", // 0x7?
"SEI", "ADC", "nop", "n/a", "nop", "ADC", "ROR", "n/a", "SEI", "ADC", "nop", "rra", "nop", "ADC", "ROR", "rra",
"nop", "STA", "nop", "axs", "STY", "STA", "STX", "axs", // 0x8? "nop", "STA", "nop", "sax", "STY", "STA", "STX", "sax", // 0x8?
"DEY", "n/a", "TXA", "n/a", "STY", "STA", "STX", "axs", "DEY", "nop", "TXA", "ane", "STY", "STA", "STX", "sax",
"BCC", "STA", "n/a", "n/a", "STY", "STA", "STX", "axs", // 0x9? "BCC", "STA", "n/a", "sha", "STY", "STA", "STX", "sax", // 0x9?
"TYA", "STA", "TXS", "n/a", "n/a", "STA", "n/a", "n/a", "TYA", "STA", "TXS", "shs", "shy", "STA", "shx", "sha",
"LDY", "LDA", "LDX", "n/a", "LDY", "LDA", "LDX", "n/a", // 0xA? "LDY", "LDA", "LDX", "lax", "LDY", "LDA", "LDX", "lax", // 0xA?
"TAY", "LDA", "TAX", "n/a", "LDY", "LDA", "LDX", "n/a", "TAY", "LDA", "TAX", "lxa", "LDY", "LDA", "LDX", "lax",
"BCS", "LDA", "n/a", "n/a", "LDY", "LDA", "LDX", "n/a", // 0xB? "BCS", "LDA", "n/a", "lax", "LDY", "LDA", "LDX", "lax", // 0xB?
"CLV", "LDA", "TSX", "n/a", "LDY", "LDA", "LDX", "n/a", "CLV", "LDA", "TSX", "las", "LDY", "LDA", "LDX", "lax",
"CPY", "CMP", "nop", "n/a", "CPY", "CMP", "DEC", "n/a", // 0xC? "CPY", "CMP", "nop", "dcp", "CPY", "CMP", "DEC", "dcp", // 0xC?
"INY", "CMP", "DEX", "n/a", "CPY", "CMP", "DEC", "n/a", "INY", "CMP", "DEX", "sbx", "CPY", "CMP", "DEC", "dcp",
"BNE", "CMP", "n/a", "n/a", "nop", "CMP", "DEC", "n/a", // 0xD? "BNE", "CMP", "n/a", "dcp", "nop", "CMP", "DEC", "dcp", // 0xD?
"CLD", "CMP", "nop", "n/a", "nop", "CMP", "DEC", "n/a", "CLD", "CMP", "nop", "dcp", "nop", "CMP", "DEC", "dcp",
"CPX", "SBC", "nop", "n/a", "CPX", "SBC", "INC", "n/a", // 0xE? "CPX", "SBC", "nop", "isb", "CPX", "SBC", "INC", "isb", // 0xE?
"INX", "SBC", "NOP", "n/a", "CPX", "SBC", "INC", "n/a", "INX", "SBC", "NOP", "sbc", "CPX", "SBC", "INC", "isb",
"BEQ", "SBC", "n/a", "n/a", "nop", "SBC", "INC", "n/a", // 0xF? "BEQ", "SBC", "n/a", "isb", "nop", "SBC", "INC", "isb", // 0xF?
"SED", "SBC", "nop", "n/a", "nop", "SBC", "INC", "n/a" "SED", "SBC", "nop", "isb", "nop", "SBC", "INC", "isb"
}; };

View File

@ -13,14 +13,14 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: M6502.m4,v 1.1.1.1 2001-12-27 19:54:30 bwmott Exp $ // $Id: M6502.m4,v 1.2 2001-12-29 17:55:59 bwmott Exp $
//============================================================================ //============================================================================
/** /**
Code and cases to emulate each of the 6502 instruction Code and cases to emulate each of the 6502 instruction
@author Bradford W. Mott @author Bradford W. Mott
@version $Id: M6502.m4,v 1.1.1.1 2001-12-27 19:54:30 bwmott Exp $ @version $Id: M6502.m4,v 1.2 2001-12-29 17:55:59 bwmott Exp $
*/ */
#ifndef NOTSAMEPAGE #ifndef NOTSAMEPAGE
@ -53,12 +53,69 @@ define(M6502_ADC, `{
} }
}') }')
define(M6502_ANC, `{
A &= operand;
notZ = A;
N = A & 0x80;
C = N;
}')
define(M6502_AND, `{ define(M6502_AND, `{
A &= operand; A &= operand;
notZ = A; notZ = A;
N = A & 0x80; N = A & 0x80;
}') }')
define(M6502_ANE, `{
// NOTE: The implementation of this instruction is based on
// information from the 64doc.txt file. This instruction is
// reported to be unstable!
A = (A | 0xee) & X & operand;
notZ = A;
N = A & 0x80;
}')
define(M6502_ARR, `{
// NOTE: The implementation of this instruction is based on
// information from the 64doc.txt file. There are mixed
// reports on its operation!
if(!D)
{
A &= operand;
A = ((A >> 1) & 0x7f) | (C ? 0x80 : 0x00);
C = A & 0x40;
V = (A & 0x40) ^ ((A & 0x20) << 1);
notZ = A;
N = A & 0x80;
}
else
{
uInt8 value = A & operand;
A = ((value >> 1) & 0x7f) | (C ? 0x80 : 0x00);
N = C;
notZ = A;
V = (value ^ A) & 0x40;
if(((value & 0x0f) + (value & 0x01)) > 0x05)
{
A = (A & 0xf0) | ((A + 0x06) & 0x0f);
}
if(((value & 0xf0) + (value & 0x10)) > 0x50)
{
A = (A + 0x60) & 0xff;
C = 1;
}
else
{
C = 0;
}
}
}')
define(M6502_ASL, `{ define(M6502_ASL, `{
// Set carry flag according to the left-most bit in value // Set carry flag according to the left-most bit in value
C = operand & 0x80; C = operand & 0x80;
@ -80,23 +137,18 @@ define(M6502_ASLA, `{
N = A & 0x80; N = A & 0x80;
}') }')
define(M6502_ASO, `{ define(M6502_ASR, `{
// Set carry flag according to the left-most bit in value A &= operand;
C = operand & 0x80;
operand <<= 1; // Set carry flag according to the right-most bit
poke(operandAddress, operand); C = A & 0x01;
A = (A >> 1) & 0x7f;
A |= operand;
notZ = A; notZ = A;
N = A & 0x80; N = A & 0x80;
}') }')
define(M6502_AXS, `{
poke(operandAddress, A & X);
}')
define(M6502_BIT, `{ define(M6502_BIT, `{
notZ = (A & operand); notZ = (A & operand);
N = operand & 0x80; N = operand & 0x80;
@ -156,6 +208,16 @@ define(M6502_CPY, `{
C = !(value & 0x0100); C = !(value & 0x0100);
}') }')
define(M6502_DCP, `{
uInt8 value = operand - 1;
poke(operandAddress, value);
uInt16 value2 = (uInt16)A - (uInt16)value;
notZ = value2;
N = value2 & 0x0080;
C = !(value2 & 0x0100);
}')
define(M6502_DEC, `{ define(M6502_DEC, `{
uInt8 value = operand - 1; uInt8 value = operand - 1;
poke(operandAddress, value); poke(operandAddress, value);
@ -164,7 +226,6 @@ define(M6502_DEC, `{
N = value & 0x80; N = value & 0x80;
}') }')
define(M6502_DEX, `{ define(M6502_DEX, `{
X--; X--;
@ -206,6 +267,41 @@ define(M6502_INY, `{
N = Y & 0x80; N = Y & 0x80;
}') }')
define(M6502_ISB, `{
operand = operand + 1;
poke(operandAddress, operand);
uInt8 oldA = A;
if(!D)
{
operand = ~operand;
Int16 difference = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0);
V = ((difference > 127) || (difference < -128));
difference = ((Int16)A) + ((Int16)operand) + (C ? 1 : 0);
A = difference;
C = (difference > 0xff);
notZ = A;
N = A & 0x80;
}
else
{
Int16 difference = ourBCDTable[0][A] - ourBCDTable[0][operand]
- (C ? 0 : 1);
if(difference < 0)
difference += 100;
A = ourBCDTable[1][difference];
notZ = A;
N = A & 0x80;
C = (oldA >= (operand + (C ? 0 : 1)));
V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80);
}
}')
define(M6502_JMP, `{ define(M6502_JMP, `{
PC = operandAddress; PC = operandAddress;
}') }')
@ -223,6 +319,19 @@ define(M6502_JSR, `{
PC = low | ((uInt16)peek(PC++) << 8); PC = low | ((uInt16)peek(PC++) << 8);
}') }')
define(M6502_LAS, `{
A = X = SP = SP & operand;
notZ = A;
N = A & 0x80;
}')
define(M6502_LAX, `{
A = operand;
X = operand;
notZ = A;
N = A & 0x80;
}')
define(M6502_LDA, `{ define(M6502_LDA, `{
A = operand; A = operand;
notZ = A; notZ = A;
@ -262,6 +371,15 @@ define(M6502_LSRA, `{
N = A & 0x80; N = A & 0x80;
}') }')
define(M6502_LXA, `{
// NOTE: The implementation of this instruction is based on
// information from the 64doc.txt file. This instruction is
// reported to be very unstable!
A = X = (A | 0xee) & operand;
notZ = A;
N = A & 0x80;
}')
define(M6502_NOP, `{ define(M6502_NOP, `{
}') }')
@ -351,6 +469,38 @@ define(M6502_RORA, `{
N = A & 0x80; N = A & 0x80;
}') }')
define(M6502_RRA, `{
uInt8 oldA = A;
bool oldC = C;
// Set carry flag according to the right-most bit
C = operand & 0x01;
operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00);
poke(operandAddress, operand);
if(!D)
{
Int16 sum = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0);
V = ((sum > 127) || (sum < -128));
sum = (Int16)A + (Int16)operand + (C ? 1 : 0);
A = sum;
C = (sum > 0xff);
notZ = A;
N = A & 0x80;
}
else
{
Int16 sum = ourBCDTable[0][A] + ourBCDTable[0][operand] + (C ? 1 : 0);
C = (sum > 99);
A = ourBCDTable[1][sum & 0xff];
notZ = A;
N = A & 0x80;
V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80);
}
}')
define(M6502_RTI, `{ define(M6502_RTI, `{
peek(0x0100 + SP++); peek(0x0100 + SP++);
@ -366,6 +516,10 @@ define(M6502_RTS, `{
peek(PC++); peek(PC++);
}') }')
define(M6502_SAX, `{
poke(operandAddress, A & X);
}')
define(M6502_SBC, `{ define(M6502_SBC, `{
uInt8 oldA = A; uInt8 oldA = A;
@ -398,6 +552,15 @@ define(M6502_SBC, `{
} }
}') }')
define(M6502_SBX, `{
uInt16 value = (uInt16)(X & A) - (uInt16)operand;
X = (value & 0xff);
notZ = X;
N = X & 0x80;
C = !(value & 0x0100);
}')
define(M6502_SEC, `{ define(M6502_SEC, `{
C = true; C = true;
}') }')
@ -410,6 +573,55 @@ define(M6502_SEI, `{
I = true; I = true;
}') }')
define(M6502_SHA, `{
// NOTE: There are mixed reports on the actual operation
// of this instruction!
poke(operandAddress, A & X & (((operandAddress >> 8) & 0xff) + 1));
}')
define(M6502_SHS, `{
// NOTE: There are mixed reports on the actual operation
// of this instruction!
SP = A & X;
poke(operandAddress, A & X & (((operandAddress >> 8) & 0xff) + 1));
}')
define(M6502_SHX, `{
// NOTE: There are mixed reports on the actual operation
// of this instruction!
poke(operandAddress, X & (((operandAddress >> 8) & 0xff) + 1));
}')
define(M6502_SHY, `{
// NOTE: There are mixed reports on the actual operation
// of this instruction!
poke(operandAddress, Y & (((operandAddress >> 8) & 0xff) + 1));
}')
define(M6502_SLO, `{
// Set carry flag according to the left-most bit in value
C = operand & 0x80;
operand <<= 1;
poke(operandAddress, operand);
A |= operand;
notZ = A;
N = A & 0x80;
}')
define(M6502_SRE, `{
// Set carry flag according to the right-most bit in value
C = operand & 0x01;
operand = (operand >> 1) & 0x7f;
poke(operandAddress, operand);
A ^= operand;
notZ = A;
N = A & 0x80;
}')
define(M6502_STA, `{ define(M6502_STA, `{
poke(operandAddress, A); poke(operandAddress, A);
}') }')
@ -472,12 +684,12 @@ M6502_ZEROX_READ
M6502_ADC M6502_ADC
break; break;
case 0x6D: case 0x6d:
M6502_ABSOLUTE_READ M6502_ABSOLUTE_READ
M6502_ADC M6502_ADC
break; break;
case 0x7D: case 0x7d:
M6502_ABSOLUTEX_READ M6502_ABSOLUTEX_READ
M6502_ADC M6502_ADC
break; break;
@ -498,6 +710,18 @@ M6502_ADC
break; break;
case 0x4b:
M6502_IMMEDIATE_READ
M6502_ASR
break;
case 0x0b:
case 0x2b:
M6502_IMMEDIATE_READ
M6502_ANC
break;
case 0x29: case 0x29:
M6502_IMMEDIATE_READ M6502_IMMEDIATE_READ
@ -514,12 +738,12 @@ M6502_ZEROX_READ
M6502_AND M6502_AND
break; break;
case 0x2D: case 0x2d:
M6502_ABSOLUTE_READ M6502_ABSOLUTE_READ
M6502_AND M6502_AND
break; break;
case 0x3D: case 0x3d:
M6502_ABSOLUTEX_READ M6502_ABSOLUTEX_READ
M6502_AND M6502_AND
break; break;
@ -540,6 +764,18 @@ M6502_AND
break; break;
case 0x8b:
M6502_IMMEDIATE_READ
M6502_ANE
break;
case 0x6b:
M6502_IMMEDIATE_READ
M6502_ARR
break;
case 0x0a: case 0x0a:
M6502_IMPLIED M6502_IMPLIED
M6502_ASLA M6502_ASLA
@ -566,63 +802,6 @@ M6502_ASL
break; break;
case 0x0f:
M6502_ABSOLUTE_READMODIFYWRITE
M6502_ASO
break;
case 0x1f:
M6502_ABSOLUTEX_READMODIFYWRITE
M6502_ASO
break;
case 0x1b:
M6502_ABSOLUTEY_READMODIFYWRITE
M6502_ASO
break;
case 0x07:
M6502_ZERO_READMODIFYWRITE
M6502_ASO
break;
case 0x17:
M6502_ZEROX_READMODIFYWRITE
M6502_ASO
break;
case 0x03:
M6502_INDIRECTX_READMODIFYWRITE
M6502_ASO
break;
case 0x13:
M6502_INDIRECTY_READMODIFYWRITE
M6502_ASO
break;
case 0x8f:
M6502_ABSOLUTE_WRITE
M6502_AXS
break;
case 0x87:
M6502_ZERO_WRITE
M6502_AXS
break;
case 0x97:
M6502_ZEROY_WRITE
M6502_AXS
break;
case 0x83:
M6502_INDIRECTX_WRITE
M6502_AXS
break;
case 0x90: case 0x90:
M6502_IMMEDIATE_READ M6502_IMMEDIATE_READ
M6502_BCC M6502_BCC
@ -784,6 +963,42 @@ M6502_CPY
break; break;
case 0xcf:
M6502_ABSOLUTE_READMODIFYWRITE
M6502_DCP
break;
case 0xdf:
M6502_ABSOLUTEX_READMODIFYWRITE
M6502_DCP
break;
case 0xdb:
M6502_ABSOLUTEY_READMODIFYWRITE
M6502_DCP
break;
case 0xc7:
M6502_ZERO_READMODIFYWRITE
M6502_DCP
break;
case 0xd7:
M6502_ZEROX_READMODIFYWRITE
M6502_DCP
break;
case 0xc3:
M6502_INDIRECTX_READMODIFYWRITE
M6502_DCP
break;
case 0xd3:
M6502_INDIRECTY_READMODIFYWRITE
M6502_DCP
break;
case 0xc6: case 0xc6:
M6502_ZERO_READMODIFYWRITE M6502_ZERO_READMODIFYWRITE
M6502_DEC M6502_DEC
@ -891,6 +1106,42 @@ M6502_INY
break; break;
case 0xef:
M6502_ABSOLUTE_READMODIFYWRITE
M6502_ISB
break;
case 0xff:
M6502_ABSOLUTEX_READMODIFYWRITE
M6502_ISB
break;
case 0xfb:
M6502_ABSOLUTEY_READMODIFYWRITE
M6502_ISB
break;
case 0xe7:
M6502_ZERO_READMODIFYWRITE
M6502_ISB
break;
case 0xf7:
M6502_ZEROX_READMODIFYWRITE
M6502_ISB
break;
case 0xe3:
M6502_INDIRECTX_READMODIFYWRITE
M6502_ISB
break;
case 0xf3:
M6502_INDIRECTY_READMODIFYWRITE
M6502_ISB
break;
case 0x4c: case 0x4c:
M6502_ABSOLUTE_WRITE M6502_ABSOLUTE_WRITE
M6502_JMP M6502_JMP
@ -907,6 +1158,43 @@ M6502_JSR
break; break;
case 0xbb:
M6502_ABSOLUTEY_READ
M6502_LAS
break;
case 0xaf:
M6502_ABSOLUTE_READ
M6502_LAX
break;
case 0xbf:
M6502_ABSOLUTEY_READ
M6502_LAX
break;
case 0xa7:
M6502_ZERO_READ
M6502_LAX
break;
case 0xb7:
M6502_ZEROY_READ
M6502_LAX
break;
case 0xa3:
M6502_INDIRECTX_READ
M6502_LAX
break;
case 0xb3:
M6502_INDIRECTY_READ
M6502_LAX
break;
case 0xa9: case 0xa9:
M6502_IMMEDIATE_READ M6502_IMMEDIATE_READ
M6502_LDA M6502_LDA
@ -1027,19 +1315,26 @@ M6502_LSR
break; break;
case 0xab:
M6502_IMMEDIATE_READ
M6502_LXA
break;
case 0x1a: case 0x1a:
case 0x3a: case 0x3a:
case 0x5a: case 0x5a:
case 0x7a: case 0x7a:
case 0xda: case 0xda:
case 0xfa:
case 0xea: case 0xea:
case 0xfa:
M6502_IMPLIED M6502_IMPLIED
M6502_NOP M6502_NOP
break; break;
case 0x80: case 0x80:
case 0x82: case 0x82:
case 0x89:
case 0xc2: case 0xc2:
case 0xe2: case 0xe2:
M6502_IMMEDIATE_READ M6502_IMMEDIATE_READ
@ -1094,12 +1389,12 @@ M6502_ZEROX_READ
M6502_ORA M6502_ORA
break; break;
case 0x0D: case 0x0d:
M6502_ABSOLUTE_READ M6502_ABSOLUTE_READ
M6502_ORA M6502_ORA
break; break;
case 0x1D: case 0x1d:
M6502_ABSOLUTEX_READ M6502_ABSOLUTEX_READ
M6502_ORA M6502_ORA
break; break;
@ -1233,6 +1528,42 @@ M6502_ROR
break; break;
case 0x6f:
M6502_ABSOLUTE_READMODIFYWRITE
M6502_RRA
break;
case 0x7f:
M6502_ABSOLUTEX_READMODIFYWRITE
M6502_RRA
break;
case 0x7b:
M6502_ABSOLUTEY_READMODIFYWRITE
M6502_RRA
break;
case 0x67:
M6502_ZERO_READMODIFYWRITE
M6502_RRA
break;
case 0x77:
M6502_ZEROX_READMODIFYWRITE
M6502_RRA
break;
case 0x63:
M6502_INDIRECTX_READMODIFYWRITE
M6502_RRA
break;
case 0x73:
M6502_INDIRECTY_READMODIFYWRITE
M6502_RRA
break;
case 0x40: case 0x40:
M6502_IMPLIED M6502_IMPLIED
M6502_RTI M6502_RTI
@ -1245,7 +1576,29 @@ M6502_RTS
break; break;
case 0x8f:
M6502_ABSOLUTE_WRITE
M6502_SAX
break;
case 0x87:
M6502_ZERO_WRITE
M6502_SAX
break;
case 0x97:
M6502_ZEROY_WRITE
M6502_SAX
break;
case 0x83:
M6502_INDIRECTX_WRITE
M6502_SAX
break;
case 0xe9: case 0xe9:
case 0xeb:
M6502_IMMEDIATE_READ M6502_IMMEDIATE_READ
M6502_SBC M6502_SBC
break; break;
@ -1286,6 +1639,12 @@ M6502_SBC
break; break;
case 0xcb:
M6502_IMMEDIATE_READ
M6502_SBX
break;
case 0x38: case 0x38:
M6502_IMPLIED M6502_IMPLIED
M6502_SEC M6502_SEC
@ -1304,6 +1663,107 @@ M6502_SEI
break; break;
case 0x9f:
M6502_ABSOLUTEY_WRITE
M6502_SHA
break;
case 0x93:
M6502_INDIRECTY_WRITE
M6502_SHA
break;
case 0x9b:
M6502_ABSOLUTEY_WRITE
M6502_SHS
break;
case 0x9e:
M6502_ABSOLUTEY_WRITE
M6502_SHX
break;
case 0x9c:
M6502_ABSOLUTEX_WRITE
M6502_SHY
break;
case 0x0f:
M6502_ABSOLUTE_READMODIFYWRITE
M6502_SLO
break;
case 0x1f:
M6502_ABSOLUTEX_READMODIFYWRITE
M6502_SLO
break;
case 0x1b:
M6502_ABSOLUTEY_READMODIFYWRITE
M6502_SLO
break;
case 0x07:
M6502_ZERO_READMODIFYWRITE
M6502_SLO
break;
case 0x17:
M6502_ZEROX_READMODIFYWRITE
M6502_SLO
break;
case 0x03:
M6502_INDIRECTX_READMODIFYWRITE
M6502_SLO
break;
case 0x13:
M6502_INDIRECTY_READMODIFYWRITE
M6502_SLO
break;
case 0x4f:
M6502_ABSOLUTE_READMODIFYWRITE
M6502_SRE
break;
case 0x5f:
M6502_ABSOLUTEX_READMODIFYWRITE
M6502_SRE
break;
case 0x5b:
M6502_ABSOLUTEY_READMODIFYWRITE
M6502_SRE
break;
case 0x47:
M6502_ZERO_READMODIFYWRITE
M6502_SRE
break;
case 0x57:
M6502_ZEROX_READMODIFYWRITE
M6502_SRE
break;
case 0x43:
M6502_INDIRECTX_READMODIFYWRITE
M6502_SRE
break;
case 0x53:
M6502_INDIRECTY_READMODIFYWRITE
M6502_SRE
break;
case 0x85: case 0x85:
M6502_ZERO_WRITE M6502_ZERO_WRITE
M6502_STA M6502_STA