1314 lines
39 KiB
C#
1314 lines
39 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace _6502EmulatorFrontend.cpu
|
|
{
|
|
public class Disassembly
|
|
{
|
|
|
|
public struct DisassembledOpcode
|
|
{
|
|
public ushort Address;
|
|
public byte Opcode;
|
|
public String InstructionName;
|
|
public List<byte> Operands;
|
|
|
|
public override String ToString()
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.Append(String.Format("{0} - {1}", Address.ToString("X4"), InstructionName));
|
|
Operands.Reverse(); //absolute addresses are out of order
|
|
foreach(var operand in Operands)
|
|
{
|
|
List<String> branchInstructions = new List<string>() { "BCC", "BCS", "BEQ", "BMI", "BNE", "BPL", "BVC", "BVS" };
|
|
|
|
if (branchInstructions.Contains(InstructionName.Substring(0, 3)))
|
|
{
|
|
//if it's a branch instruction, use the operand to calculate the relative address destination
|
|
if((operand & 0x80) == 0x80)
|
|
{
|
|
//Relative branch backward
|
|
sb.Append(String.Format("{0}", (Address - ~operand - 0xFF).ToString("X2")));
|
|
}
|
|
else
|
|
{
|
|
//Relative branch forward
|
|
sb.Append(String.Format("{0}", (Address + operand).ToString("X2")));
|
|
}
|
|
} else
|
|
{
|
|
//Any other instruction
|
|
sb.Append(String.Format("{0}", operand.ToString("X2")));
|
|
}
|
|
|
|
}
|
|
return sb.ToString();
|
|
}
|
|
}
|
|
|
|
public byte[] debugMemory = new byte[65536];
|
|
|
|
public ushort Address;
|
|
public byte Opcode;
|
|
public String InstructionName;
|
|
public List<byte> Operands;
|
|
public ushort NextInstructionAddress;
|
|
|
|
public Disassembly(byte[] memory)
|
|
{
|
|
memory.CopyTo(debugMemory, 0);
|
|
}
|
|
|
|
public void Begin(ushort address)
|
|
{
|
|
NextInstructionAddress = address;
|
|
Next();
|
|
}
|
|
|
|
public void Next()
|
|
{
|
|
//cycle counts are inaccurate
|
|
|
|
Operands = new List<byte>();
|
|
Opcode = debugMemory[NextInstructionAddress];
|
|
Address = NextInstructionAddress;
|
|
int operandLength = 0;
|
|
int cycles = 0;
|
|
|
|
#region disassembly switch
|
|
switch (Opcode)
|
|
{
|
|
case 0x00: //BRK
|
|
{
|
|
cycles += 7;
|
|
InstructionName = "BRK"; //OK
|
|
operandLength = 0;
|
|
break;
|
|
}
|
|
|
|
case 0x01:
|
|
{
|
|
cycles += 6;
|
|
InstructionName = "ORA (ZP,X) $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x05:
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "ORA $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x06:
|
|
{
|
|
cycles += 5;
|
|
InstructionName = "ASL $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x08: //PHP
|
|
{
|
|
cycles += 3;
|
|
InstructionName = "PHP";
|
|
operandLength = 0;
|
|
break;
|
|
}
|
|
|
|
case 0x09:
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "ORA #$";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x0A:
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "ASL";
|
|
operandLength = 0;
|
|
break;
|
|
}
|
|
|
|
case 0x0D:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "ORA $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x0E:
|
|
{
|
|
cycles += 6;
|
|
InstructionName = "ASL $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x10:
|
|
{
|
|
cycles += 2; //2; +1 if dest on same page; +2 if on dest on diff page
|
|
InstructionName = "BPL $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x11:
|
|
{
|
|
cycles += 5;
|
|
InstructionName = "ORA (M),Y $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x15:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "ORA ZP,X";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x16:
|
|
{
|
|
cycles += 6;
|
|
InstructionName = "ASL ZP,X $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x18: //CLC
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "CLC";
|
|
operandLength = 0;
|
|
break;
|
|
}
|
|
|
|
case 0x19:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "ORA M,Y $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x1D:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "ORA M,X $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x1E:
|
|
{
|
|
cycles += 7;
|
|
InstructionName = "ASL M,X $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x20:
|
|
{
|
|
cycles += 6;
|
|
InstructionName = "JSR $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x21: //AND (M, X)
|
|
{
|
|
cycles += 6;
|
|
InstructionName = "AND (M,X) $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x24:
|
|
{
|
|
cycles += 3;
|
|
InstructionName = "BIT $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x25: //AND - AND zeropage
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "AND $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x26:
|
|
{
|
|
cycles += 5;
|
|
InstructionName = "ROL $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x28: //PLP
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "PLP";
|
|
operandLength = 0;
|
|
break;
|
|
}
|
|
|
|
case 0x29: //AND - AND(M, immediate)
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "AND #$";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x2A:
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "ROL A";
|
|
operandLength = 0;
|
|
break;
|
|
}
|
|
|
|
case 0x2C:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "BIT $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x2D:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "AND $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x2E:
|
|
{
|
|
cycles += 6;
|
|
InstructionName = "ROL $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x30:
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "BMI $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x31: //AND (M),Y
|
|
{
|
|
cycles += 5;
|
|
InstructionName = "AND (M),Y $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x35: //AND,X - AND(A, zeropage+X)
|
|
{
|
|
cycles += 3;
|
|
InstructionName = "AND ZP,X";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x36:
|
|
{
|
|
cycles += 6;
|
|
InstructionName = "ROL ZP,X $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x38: //SEC - set carry flag
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "SEC";
|
|
operandLength = 0;
|
|
break;
|
|
}
|
|
|
|
case 0x39: //AND M,Y
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "AND M,Y $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x3D:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "AND M,X $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x3E:
|
|
{
|
|
cycles += 7;
|
|
InstructionName = "ROL M,X $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x40:
|
|
{
|
|
cycles += 6;
|
|
InstructionName = "RTI";
|
|
operandLength = 0;
|
|
break;
|
|
}
|
|
|
|
case 0x41:
|
|
{
|
|
cycles += 6;
|
|
InstructionName = "EOR (ZP,X) $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x45:
|
|
{
|
|
cycles += 3;
|
|
InstructionName = "EOR $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x46:
|
|
{
|
|
cycles += 5;
|
|
InstructionName = "LSR $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x48:
|
|
{
|
|
cycles += 3;
|
|
InstructionName = "PHA";
|
|
operandLength = 0;
|
|
break;
|
|
}
|
|
|
|
case 0x49:
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "EOR #$";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x4A:
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "LSR";
|
|
operandLength = 0;
|
|
break;
|
|
}
|
|
|
|
case 0x4C: //JMP - unconditional branch
|
|
{
|
|
cycles += 3;
|
|
InstructionName = "JMP $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x4D:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "EOR $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x4E:
|
|
{
|
|
cycles += 6;
|
|
InstructionName = "LSR $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x50:
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "BVC";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x51:
|
|
{
|
|
cycles += 5;
|
|
InstructionName = "EOR (ZP),Y $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x55:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "EOR ZP,X";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x56:
|
|
{
|
|
cycles += 6;
|
|
InstructionName = "LSR ZP,X $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x58: //CLI
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "CLI";
|
|
operandLength = 0;
|
|
break;
|
|
}
|
|
|
|
case 0x59:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "EOR M,Y $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x5D:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "EOR M,X $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x5E:
|
|
{
|
|
cycles += 7;
|
|
InstructionName = "LSR M,X $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x60:
|
|
{
|
|
cycles += 6;
|
|
InstructionName = "RTS";
|
|
operandLength = 0;
|
|
break;
|
|
}
|
|
|
|
case 0x61:
|
|
{
|
|
cycles += 6;
|
|
InstructionName = "ADC (ZP,X) $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x65:
|
|
{
|
|
cycles += 3;
|
|
InstructionName = "ADC ZP $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x66:
|
|
{
|
|
cycles += 5;
|
|
InstructionName = "ROR $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x68: //PLA - pop accumulator from stack
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "PLA";
|
|
operandLength = 0;
|
|
break;
|
|
}
|
|
|
|
case 0x69:
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "ADC #$";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x6A:
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "ROR A";
|
|
operandLength = 0;
|
|
break;
|
|
}
|
|
|
|
case 0x6C: //JMP (M)
|
|
{
|
|
cycles += 5;
|
|
InstructionName = "JMP (M) $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x6D:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "ADC $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x6E:
|
|
{
|
|
cycles += 6;
|
|
InstructionName = "ROR $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x70:
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "BVS $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x71:
|
|
{
|
|
cycles += 5;
|
|
InstructionName = "ADC (ZP),Y $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x75:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "ADC ZP,X $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x76:
|
|
{
|
|
cycles += 6;
|
|
InstructionName = "ROR ZP,X $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x78: //SEI - set interrupt flag
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "SEI";
|
|
operandLength = 0;
|
|
break;
|
|
}
|
|
|
|
case 0x7E:
|
|
{
|
|
cycles += 7;
|
|
InstructionName = "ROR M,X $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x79:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "ADC M,Y $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x7D:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "ADC M,X $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x81:
|
|
{
|
|
cycles += 6;
|
|
InstructionName = "STA (ZP,X)";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x84: //STY - store Y into zeropage memory - OK
|
|
{
|
|
cycles += 3;
|
|
InstructionName = "STY $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x85: //STA - store A into zeropage memory - OK
|
|
{
|
|
cycles += 3;
|
|
InstructionName = "STA $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x86: //STX - store X into zeropage memory - OK
|
|
{
|
|
cycles += 3;
|
|
InstructionName = "STX $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x88: //DEY - OK
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "DEY";
|
|
operandLength = 0;
|
|
break;
|
|
}
|
|
|
|
case 0x8A: //TXA - X -> A - OK
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "TXA";
|
|
operandLength = 0;
|
|
break;
|
|
}
|
|
|
|
case 0x8C:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "STY $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x8D:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "STA $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x8E:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "STX $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x90:
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "BCC $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x91:
|
|
{
|
|
cycles += 6;
|
|
InstructionName = "STA (ZP),Y $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x94:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "STY ZP,X $"; //OK
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x95:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "STA ZP,X $"; //OK
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x96:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "STX ZP,Y $"; //OK
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0x98: //TYA - Y -> A - OK
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "TYA";
|
|
operandLength = 0;
|
|
break;
|
|
}
|
|
|
|
case 0x99:
|
|
{
|
|
cycles += 5;
|
|
InstructionName = "STA M,Y $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0x9A: //TXS - X -> SP - OK
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "TXS";
|
|
operandLength = 0;
|
|
break;
|
|
}
|
|
|
|
case 0x9D:
|
|
{
|
|
cycles += 5;
|
|
InstructionName = "STA M,X $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0xA0: //LDY - immediate - OK
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "LDY #$";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xA1:
|
|
{
|
|
cycles += 6;
|
|
InstructionName = "LDA (ZP,X)";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xA2: //LDX - immediate - OK
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "LDX #$";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xA4:
|
|
{
|
|
cycles += 3;
|
|
InstructionName = "LDY $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xA5: //LDA - Zeropage - Load A from zeropage operand.
|
|
{
|
|
cycles += 3;
|
|
InstructionName = "LDA $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xA6:
|
|
{
|
|
cycles += 3;
|
|
InstructionName = "LDX $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xA8: //TAY - OK
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "TAY";
|
|
operandLength = 0;
|
|
break;
|
|
}
|
|
|
|
case 0xA9: //LDA - Immediate - Load A from immediate value - OK
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "LDA #$";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xAA: //TAX - A -> X - OK
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "TAX";
|
|
operandLength = 0;
|
|
break;
|
|
}
|
|
|
|
case 0xAC:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "LDY $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0xAD:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "LDA $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0xAE:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "LDX $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0xB0:
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "BCS $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xB1:
|
|
{
|
|
cycles += 5;
|
|
InstructionName = "LDA (ZP),Y $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xB4:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "LDY ZP,X $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xB5: //LDA,X - Load A from Zeropage+X value
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "LDA ZP,X $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xB6:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "LDX ZP,Y $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xB8: //CLV - OK
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "CLV";
|
|
operandLength = 0;
|
|
break;
|
|
}
|
|
|
|
case 0xB9: //LDA Absolute,Y - OK
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "LDA M,Y $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0xBA: //TSX - SP -> X - OK
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "TSX";
|
|
operandLength = 0;
|
|
break;
|
|
}
|
|
|
|
case 0xBC:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "LDY M,X $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0xBD: //LDA - Absolute,X - OK
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "LDA M,X $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0xBE:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "LDX M,Y $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0xC0:
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "CPY #$";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xC1:
|
|
{
|
|
cycles += 6;
|
|
InstructionName = "CMP (ZP,X)";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xC4:
|
|
{
|
|
cycles += 3;
|
|
InstructionName = "CPY $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xC5:
|
|
{
|
|
cycles += 3;
|
|
InstructionName = "CMP $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xC6:
|
|
{
|
|
cycles += 5;
|
|
InstructionName = "DEC $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xC8: //INY - increment Y - OK
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "INY";
|
|
operandLength = 0;
|
|
break;
|
|
}
|
|
|
|
case 0xC9:
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "CMP #$";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xCA: //DEX - OK
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "DEX";
|
|
operandLength = 0;
|
|
break;
|
|
}
|
|
|
|
case 0xCC:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "CPY $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0xCD:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "CMP $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0xCE:
|
|
{
|
|
cycles += 6;
|
|
InstructionName = "DEC $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0xD0: //BNE
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "BNE $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xD1:
|
|
{
|
|
cycles += 5;
|
|
InstructionName = "CMP (ZP),Y";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xD5:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "CMP ZP,X $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xD6:
|
|
{
|
|
cycles += 6;
|
|
InstructionName = "DEC ZP,X $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xD8: //CLD - OK
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "CLD";
|
|
operandLength = 0;
|
|
break;
|
|
}
|
|
|
|
case 0xD9:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "CMP M,Y $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0xDD:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "CMP M,X $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0xDE:
|
|
{
|
|
cycles += 7;
|
|
InstructionName = "DEC M,X $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0xE0:
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "CPX #$";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xE1:
|
|
{
|
|
cycles += 6;
|
|
InstructionName = "SBC (ZP,X) $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xE4:
|
|
{
|
|
cycles += 3;
|
|
InstructionName = "CPX $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xE5:
|
|
{
|
|
cycles += 3;
|
|
InstructionName = "SBC $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xE6: //INC, increment zero-page memory address
|
|
{
|
|
cycles += 5;
|
|
InstructionName = "INC $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xE8: //INX - increment X - OK
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "INX";
|
|
operandLength = 0;
|
|
break;
|
|
}
|
|
|
|
case 0xE9:
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "SBC #$";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xEA: //NOP - OK
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "NOP";
|
|
break;
|
|
}
|
|
|
|
case 0xEC:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "CPX $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0xED:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "SBC $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0xEE:
|
|
{
|
|
cycles += 6;
|
|
InstructionName = "INC $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0xF0:
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "BEQ $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xF1:
|
|
{
|
|
cycles += 5;
|
|
InstructionName = "SBC (ZP),Y $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xF5:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "SBC ZP,X $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xF6:
|
|
{
|
|
cycles += 6;
|
|
InstructionName = "INC ZP,X $";
|
|
operandLength = 1;
|
|
break;
|
|
}
|
|
|
|
case 0xF8: //SED - set decimal flag - OK
|
|
{
|
|
cycles += 2;
|
|
InstructionName = "SED";
|
|
operandLength = 0;
|
|
break;
|
|
}
|
|
|
|
case 0xF9:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "SBC M,Y $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0xFD:
|
|
{
|
|
cycles += 4;
|
|
InstructionName = "SBC M,X $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
|
|
case 0xFE:
|
|
{
|
|
cycles += 7;
|
|
InstructionName = "INC M,X $";
|
|
operandLength = 2;
|
|
break;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
NextInstructionAddress++;
|
|
|
|
for (int i = 0; i < operandLength; i++)
|
|
{
|
|
Operands.Add(debugMemory[NextInstructionAddress]);
|
|
NextInstructionAddress++;
|
|
}
|
|
|
|
}
|
|
|
|
public DisassembledOpcode ToDisassembledOpcode()
|
|
{
|
|
DisassembledOpcode dis = new DisassembledOpcode();
|
|
dis.Address = Address;
|
|
dis.InstructionName = InstructionName;
|
|
dis.Opcode = Opcode;
|
|
dis.Operands = Operands;
|
|
return dis;
|
|
}
|
|
}
|
|
}
|