- Tots els opcodes complets, falta el reset i la gestió de les interrupcions

This commit is contained in:
2025-02-06 12:25:24 +01:00
parent e979a3d618
commit 111fe32bb9

334
6502m.cpp
View File

@@ -11,23 +11,9 @@
#define fV 0b01000000 // Overflow #define fV 0b01000000 // Overflow
#define fN 0b10000000 // Negative #define fN 0b10000000 // Negative
// Addressing modes
#define aAccumulator 0
#define aImmediate 1
#define aZeroPage 2
#define aZeroPageX 3
#define aZeroPageY 4
#define aRelative 5 // Is really needed?
#define aIndirect 6
#define aIndirectX 7
#define aIndirectY 8
#define aAbsolute 9
#define aAbsoluteX 10
#define aAbsoluteY 11
namespace m6502 namespace m6502
{ {
uint8_t interrupt_type = 0xfe; uint8_t interrupt_vector = 0xfe;
uint8_t regs[13]; uint8_t regs[13];
@@ -96,6 +82,13 @@ namespace m6502
miPushA, miPushA,
miFetchOperandAndCheckBranch, miFetchOperandAndCheckBranch,
miCheckIfPageCrossed, miCheckIfPageCrossed,
miPullPCHi,
miPullPCLo,
miPullP,
miPullA,
miIncrementPC,
miFetchAddressHiToPC,
miIndexY,
miNumMicroinstructions miNumMicroinstructions
}; };
@@ -135,52 +128,267 @@ namespace m6502
/* 0x1E ASL abs,X */ { miFetchOperandLo, miFetchOperandHiAndIndexX, miReadAddress, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode }, /* 0x1E ASL abs,X */ { miFetchOperandLo, miFetchOperandHiAndIndexX, miReadAddress, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode },
/* 0x1F --- */ { miFetchOpcode }, /* 0x1F --- */ { miFetchOpcode },
/* 0x20 JSR abs */ { }, /* 0x20 JSR abs */ { miFetchAddressLo, miFakeFetchOperand, miPushPCHi, miPushPCLo, miFetchAddressHi, miFetchOpcode },
/* 0x21 ORA X,ind */ { miFetchOperandLo, miIndexX, miFetchAddressLo, miFetchAddressHi, miReadAddress, miFetchOpcode }, /* 0x21 AND X,ind */ { miFetchOperandLo, miIndexX, miFetchAddressLo, miFetchAddressHi, miReadAddress, miFetchOpcode },
/* 0x22 --- */ { miFetchOpcode }, /* 0x22 --- */ { miFetchOpcode },
/* 0x23 --- */ { miFetchOpcode }, /* 0x23 --- */ { miFetchOpcode },
/* 0x24 --- */ { miFetchOpcode }, /* 0x24 BIT zpg */ { miFetchOperandLo, miReadAddress, miFetchOpcode },
/* 0x25 ORA zpg */ { miFetchOperandLo, miReadAddress, miFetchOpcode }, /* 0x25 AND zpg */ { miFetchOperandLo, miReadAddress, miFetchOpcode },
/* 0x26 ASL zpg */ { miFetchOperandLo, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode }, /* 0x26 ROL zpg */ { miFetchOperandLo, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode },
/* 0x27 --- */ { miFetchOpcode }, /* 0x27 --- */ { miFetchOpcode },
/* 0x28 PHP */ { miFetchOperandLo, miPushP, miFetchOpcode }, /* 0x28 PLP */ { miFetchOperandLo, miPushP, miFetchOpcode },
/* 0x29 ORA imm */ { miFetchOperandLo, miFetchOpcode }, /* 0x29 AND imm */ { miFetchOperandLo, miFetchOpcode },
/* 0x2A ASL A */ { miFakeFetchOperand, miFetchOpcode }, /* 0x2A ROL A */ { miFakeFetchOperand, miFetchOpcode },
/* 0x2B --- */ { miFetchOpcode }, /* 0x2B --- */ { miFetchOpcode },
/* 0x2C --- */ { miFetchOpcode }, /* 0x2C BIT abs */ { miFetchOperandLo, miFetchOperandHi, miReadAddress, miFetchOpcode },
/* 0x2D ORA abs */ { miFetchOperandLo, miFetchOperandHi, miReadAddress, miFetchOpcode }, /* 0x2D AND abs */ { miFetchOperandLo, miFetchOperandHi, miReadAddress, miFetchOpcode },
/* 0x2E ASL abs */ { miFetchOperandLo, miFetchOperandHi, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode }, /* 0x2E ROL abs */ { miFetchOperandLo, miFetchOperandHi, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode },
/* 0x2F --- */ { miFetchOpcode }, /* 0x2F --- */ { miFetchOpcode },
/* 0x30 BPL */ { miFetchOperandAndCheckBranch, miCheckIfPageCrossed, miFakeFetchOperand, miFetchOpcode }, /* 0x30 BMI */ { miFetchOperandAndCheckBranch, miCheckIfPageCrossed, miFakeFetchOperand, miFetchOpcode },
/* 0x31 ORA ind,Y */ { miFetchOperandLo, miFetchAddressLo, miFetchAddressHiAndIndex, miReadAddressAndSkip, miReadAddress, miFetchOpcode }, /* 0x31 AND ind,Y */ { miFetchOperandLo, miFetchAddressLo, miFetchAddressHiAndIndex, miReadAddressAndSkip, miReadAddress, miFetchOpcode },
/* 0x32 --- */ { miFetchOpcode }, /* 0x32 --- */ { miFetchOpcode },
/* 0x33 --- */ { miFetchOpcode }, /* 0x33 --- */ { miFetchOpcode },
/* 0x34 --- */ { miFetchOpcode }, /* 0x34 --- */ { miFetchOpcode },
/* 0x35 ORA zpg,X */ { miFetchOperandLo, miIndexX, miReadAddress, miFetchOpcode }, /* 0x35 AND zpg,X */ { miFetchOperandLo, miIndexX, miReadAddress, miFetchOpcode },
/* 0x36 ASL zpg,X */ { miFetchOperandLo, miIndexX, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode }, /* 0x36 ROL zpg,X */ { miFetchOperandLo, miIndexX, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode },
/* 0x37 --- */ { miFetchOpcode }, /* 0x37 --- */ { miFetchOpcode },
/* 0x38 CLC */ { miFetchOperandLo, miFetchOpcode }, /* 0x38 ESC */ { miFetchOperandLo, miFetchOpcode },
/* 0x39 ORA abs,Y */ { miFetchOperandLo, miFetchOperandHiAndIndexY, miReadAddressAndSkip, miReadAddress, miFetchOpcode }, /* 0x39 AND abs,Y */ { miFetchOperandLo, miFetchOperandHiAndIndexY, miReadAddressAndSkip, miReadAddress, miFetchOpcode },
/* 0x3A --- */ { miFetchOpcode }, /* 0x3A --- */ { miFetchOpcode },
/* 0x3B --- */ { miFetchOpcode }, /* 0x3B --- */ { miFetchOpcode },
/* 0x3C --- */ { miFetchOpcode }, /* 0x3C --- */ { miFetchOpcode },
/* 0x3D ORA abs,X */ { miFetchOperandLo, miFetchOperandHiAndIndexX, miReadAddressAndSkip, miReadAddress, miFetchOpcode }, /* 0x3D AND abs,X */ { miFetchOperandLo, miFetchOperandHiAndIndexX, miReadAddressAndSkip, miReadAddress, miFetchOpcode },
/* 0x3E ASL abs,X */ { miFetchOperandLo, miFetchOperandHiAndIndexX, miReadAddress, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode }, /* 0x3E ROL abs,X */ { miFetchOperandLo, miFetchOperandHiAndIndexX, miReadAddress, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode },
/* 0x3F --- */ { miFetchOpcode }, /* 0x3F --- */ { miFetchOpcode },
/* 0x40 RTI */ { miFetchOperandLo, miFakeFetchOperand, miPullP, miPullPCLo, miPullPCHi, miFetchOpcode },
/* 0x41 EOR X,ind */ { miFetchOperandLo, miIndexX, miFetchAddressLo, miFetchAddressHi, miReadAddress, miFetchOpcode },
/* 0x42 --- */ { miFetchOpcode },
/* 0x43 --- */ { miFetchOpcode },
/* 0x44 --- */ { miFetchOpcode },
/* 0x45 EOR zpg */ { miFetchOperandLo, miReadAddress, miFetchOpcode },
/* 0x46 LSR zpg */ { miFetchOperandLo, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode },
/* 0x47 --- */ { miFetchOpcode },
/* 0x48 PHA */ { miFetchOperandLo, miPushA, miFetchOpcode },
/* 0x49 EOR imm */ { miFetchOperandLo, miFetchOpcode },
/* 0x4A LSR A */ { miFakeFetchOperand, miFetchOpcode },
/* 0x4B --- */ { miFetchOpcode },
/* 0x4C JMP abs */ { miFetchAddressLo, miFetchAddressHi, miFetchOpcode },
/* 0x4D EOR abs */ { miFetchOperandLo, miFetchOperandHi, miReadAddress, miFetchOpcode },
/* 0x4E LSR abs */ { miFetchOperandLo, miFetchOperandHi, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode },
/* 0x4F --- */ { miFetchOpcode },
/* 0x50 BVC */ { miFetchOperandAndCheckBranch, miCheckIfPageCrossed, miFakeFetchOperand, miFetchOpcode },
/* 0x51 EOR ind,Y */ { miFetchOperandLo, miFetchAddressLo, miFetchAddressHiAndIndex, miReadAddressAndSkip, miReadAddress, miFetchOpcode },
/* 0x52 --- */ { miFetchOpcode },
/* 0x53 --- */ { miFetchOpcode },
/* 0x54 --- */ { miFetchOpcode },
/* 0x55 EOR zpg,X */ { miFetchOperandLo, miIndexX, miReadAddress, miFetchOpcode },
/* 0x56 LSR zpg,X */ { miFetchOperandLo, miIndexX, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode },
/* 0x57 --- */ { miFetchOpcode },
/* 0x58 CLI */ { miFetchOperandLo, miFetchOpcode },
/* 0x59 EOR abs,Y */ { miFetchOperandLo, miFetchOperandHiAndIndexY, miReadAddressAndSkip, miReadAddress, miFetchOpcode },
/* 0x5A --- */ { miFetchOpcode },
/* 0x5B --- */ { miFetchOpcode },
/* 0x5C --- */ { miFetchOpcode },
/* 0x5D EOR abs,X */ { miFetchOperandLo, miFetchOperandHiAndIndexX, miReadAddressAndSkip, miReadAddress, miFetchOpcode },
/* 0x5E LSR abs,X */ { miFetchOperandLo, miFetchOperandHiAndIndexX, miReadAddress, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode },
/* 0x5F --- */ { miFetchOpcode },
/* 0x60 RTS */ { miFetchOperandLo, miFakeFetchOperand, miPullPCLo, miPullPCHi, miIncrementPC, miFetchOpcode },
/* 0x61 ADC X,ind */ { miFetchOperandLo, miIndexX, miFetchAddressLo, miFetchAddressHi, miReadAddress, miFetchOpcode },
/* 0x62 --- */ { miFetchOpcode },
/* 0x63 --- */ { miFetchOpcode },
/* 0x64 --- */ { miFetchOpcode },
/* 0x65 ADC zpg */ { miFetchOperandLo, miReadAddress, miFetchOpcode },
/* 0x66 ROR zpg */ { miFetchOperandLo, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode },
/* 0x67 --- */ { miFetchOpcode },
/* 0x68 PLA */ { miFetchOperandLo, miFakeFetchOperand, miPullA, miFetchOpcode },
/* 0x69 ADC imm */ { miFetchOperandLo, miFetchOpcode },
/* 0x6A ROR A */ { miFakeFetchOperand, miFetchOpcode },
/* 0x6B --- */ { miFetchOpcode },
/* 0x6C JMP ind */ { miFetchOperandLo, miFetchOperandHi, miFetchAddressLo, miFetchAddressHiToPC, miFetchOpcode },
/* 0x6D ADC abs */ { miFetchOperandLo, miFetchOperandHi, miReadAddress, miFetchOpcode },
/* 0x6E ROR abs */ { miFetchOperandLo, miFetchOperandHi, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode },
/* 0x6F --- */ { miFetchOpcode },
/* 0x70 BVS */ { miFetchOperandAndCheckBranch, miCheckIfPageCrossed, miFakeFetchOperand, miFetchOpcode },
/* 0x71 ADC ind,Y */ { miFetchOperandLo, miFetchAddressLo, miFetchAddressHiAndIndex, miReadAddressAndSkip, miReadAddress, miFetchOpcode },
/* 0x72 --- */ { miFetchOpcode },
/* 0x73 --- */ { miFetchOpcode },
/* 0x74 --- */ { miFetchOpcode },
/* 0x75 ADC zpg,X */ { miFetchOperandLo, miIndexX, miReadAddress, miFetchOpcode },
/* 0x76 ROR zpg,X */ { miFetchOperandLo, miIndexX, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode },
/* 0x77 --- */ { miFetchOpcode },
/* 0x78 SEI */ { miFetchOperandLo, miFetchOpcode },
/* 0x79 ADC abs,Y */ { miFetchOperandLo, miFetchOperandHiAndIndexY, miReadAddressAndSkip, miReadAddress, miFetchOpcode },
/* 0x7A --- */ { miFetchOpcode },
/* 0x7B --- */ { miFetchOpcode },
/* 0x7C --- */ { miFetchOpcode },
/* 0x7D ADC abs,X */ { miFetchOperandLo, miFetchOperandHiAndIndexX, miReadAddressAndSkip, miReadAddress, miFetchOpcode },
/* 0x7E ROR abs,X */ { miFetchOperandLo, miFetchOperandHiAndIndexX, miReadAddress, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode },
/* 0x7F --- */ { miFetchOpcode },
/* 0x80 --- */ { miFetchOpcode },
/* 0x81 STA X,ind */ { miFetchOperandLo, miIndexX, miFetchAddressLo, miFetchAddressHi, miWriteRegister, miFetchOpcode },
/* 0x82 --- */ { miFetchOpcode },
/* 0x83 --- */ { miFetchOpcode },
/* 0x84 STY zpg */ { miFetchOperandLo, miWriteRegister, miFetchOpcode },
/* 0x85 STA zpg */ { miFetchOperandLo, miWriteRegister, miFetchOpcode },
/* 0x86 STX zpg */ { miFetchOperandLo, miWriteRegister, miFetchOpcode },
/* 0x87 --- */ { miFetchOpcode },
/* 0x88 DEY */ { miFetchOperandLo, miFetchOpcode },
/* 0x89 --- */ { miFetchOpcode },
/* 0x8A TXA */ { miFetchOperandLo, miFetchOpcode },
/* 0x8B --- */ { miFetchOpcode },
/* 0x8C STY abs */ { miFetchOperandLo, miFetchOperandHi, miWriteRegister, miFetchOpcode },
/* 0x8D STA abs */ { miFetchOperandLo, miFetchOperandHi, miWriteRegister, miFetchOpcode },
/* 0x8E STX abs */ { miFetchOperandLo, miFetchOperandHi, miWriteRegister, miFetchOpcode },
/* 0x8F --- */ { miFetchOpcode },
/* 0x90 BCC */ { miFetchOperandAndCheckBranch, miCheckIfPageCrossed, miFakeFetchOperand, miFetchOpcode },
/* 0x91 STA ind,Y */ { miFetchOperandLo, miFetchAddressLo, miFetchAddressHiAndIndex, miReadAddress, miWriteRegister, miFetchOpcode },
/* 0x92 --- */ { miFetchOpcode },
/* 0x93 --- */ { miFetchOpcode },
/* 0x94 STY zpg,X */ { miFetchOperandLo, miIndexX, miWriteRegister, miFetchOpcode },
/* 0x95 STA zpg,X */ { miFetchOperandLo, miIndexX, miWriteRegister, miFetchOpcode },
/* 0x96 STX zpg,X */ { miFetchOperandLo, miIndexX, miWriteRegister, miFetchOpcode },
/* 0x97 --- */ { miFetchOpcode },
/* 0x98 TYA */ { miFetchOperandLo, miFetchOpcode },
/* 0x99 STA abs,Y */ { miFetchOperandLo, miFetchOperandHiAndIndexY, miReadAddress, miWriteRegister, miFetchOpcode },
/* 0x9A TXS */ { miFetchOperandLo, miFetchOpcode },
/* 0x9B --- */ { miFetchOpcode },
/* 0x9C --- */ { miFetchOpcode },
/* 0x9D STA abs,X */ { miFetchOperandLo, miFetchOperandHiAndIndexX, miReadAddress, miWriteRegister, miFetchOpcode },
/* 0x9E --- */ { miFetchOpcode },
/* 0x9F --- */ { miFetchOpcode },
/* 0xA0 LDY imm */ { miFetchOperandLo, miFetchOpcode },
/* 0xA1 LDA X,ind */ { miFetchOperandLo, miIndexX, miFetchAddressLo, miFetchAddressHi, miReadAddress, miFetchOpcode },
/* 0xA2 LDX imm */ { miFetchOperandLo, miFetchOpcode },
/* 0xA3 --- */ { miFetchOpcode },
/* 0xA4 LDY zpg */ { miFetchOperandLo, miReadAddress, miFetchOpcode },
/* 0xA5 LDA zpg */ { miFetchOperandLo, miReadAddress, miFetchOpcode },
/* 0xA6 LDX zpg */ { miFetchOperandLo, miReadAddress, miFetchOpcode },
/* 0xA7 --- */ { miFetchOpcode },
/* 0xA8 TAY */ { miFetchOperandLo, miFetchOpcode },
/* 0xA9 LDA imm */ { miFetchOperandLo, miFetchOpcode },
/* 0xAA TAX */ { miFetchOperandLo, miFetchOpcode },
/* 0xAB --- */ { miFetchOpcode },
/* 0xAC LDY abs */ { miFetchOperandLo, miFetchOperandHi, miReadAddress, miFetchOpcode },
/* 0xAD LDA abs */ { miFetchOperandLo, miFetchOperandHi, miReadAddress, miFetchOpcode },
/* 0xAE LDX abs */ { miFetchOperandLo, miFetchOperandHi, miReadAddress, miFetchOpcode },
/* 0xAF --- */ { miFetchOpcode },
/* 0xB0 BCS */ { miFetchOperandAndCheckBranch, miCheckIfPageCrossed, miFakeFetchOperand, miFetchOpcode },
/* 0xB1 LDA ind,Y */ { miFetchOperandLo, miFetchAddressLo, miFetchAddressHiAndIndex, miReadAddressAndSkip, miReadAddress, miFetchOpcode },
/* 0xB2 --- */ { miFetchOpcode },
/* 0xB3 --- */ { miFetchOpcode },
/* 0xB4 LDY zpg,X */ { miFetchOperandLo, miIndexX, miReadAddress, miFetchOpcode },
/* 0xB5 LDA zpg,X */ { miFetchOperandLo, miIndexX, miReadAddress, miFetchOpcode },
/* 0xB6 LDX zpg,Y */ { miFetchOperandLo, miIndexY, miReadAddress, miFetchOpcode },
/* 0xB7 --- */ { miFetchOpcode },
/* 0xB8 CLV */ { miFetchOperandLo, miFetchOpcode },
/* 0xB9 LDA abs,Y */ { miFetchOperandLo, miFetchOperandHiAndIndexY, miReadAddressAndSkip, miReadAddress, miFetchOpcode },
/* 0xBA TSX */ { miFetchOperandLo, miFetchOpcode },
/* 0xBB --- */ { miFetchOpcode },
/* 0xBC LDY abs,X */ { miFetchOperandLo, miFetchOperandHiAndIndexX, miReadAddressAndSkip, miReadAddress, miFetchOpcode },
/* 0xBD LDA abs,X */ { miFetchOperandLo, miFetchOperandHiAndIndexX, miReadAddressAndSkip, miReadAddress, miFetchOpcode },
/* 0xBE LDX abs,Y */ { miFetchOperandLo, miFetchOperandHiAndIndexY, miReadAddressAndSkip, miReadAddress, miFetchOpcode },
/* 0xBF --- */ { miFetchOpcode },
/* 0xC0 CPY, imm */ { miFetchOperandLo, miFetchOpcode },
/* 0xC1 CMP X,ind */ { miFetchOperandLo, miIndexX, miFetchAddressLo, miFetchAddressHi, miReadAddress, miFetchOpcode },
/* 0xC2 --- */ { miFetchOpcode },
/* 0xC3 --- */ { miFetchOpcode },
/* 0xC4 CPY zpg */ { miFetchOperandLo, miReadAddress, miFetchOpcode },
/* 0xC5 CMP zpg */ { miFetchOperandLo, miReadAddress, miFetchOpcode },
/* 0xC6 DEC zpg */ { miFetchOperandLo, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode },
/* 0xC7 --- */ { miFetchOpcode },
/* 0xC8 INY */ { miFetchOperandLo, miFetchOpcode },
/* 0xC9 CMP imm */ { miFetchOperandLo, miFetchOpcode },
/* 0xCA DEX */ { miFetchOperandLo, miFetchOpcode },
/* 0xCB --- */ { miFetchOpcode },
/* 0xCC CPY abs */ { miFetchOperandLo, miFetchOperandHi, miReadAddress, miFetchOpcode },
/* 0xCD CMP abs */ { miFetchOperandLo, miFetchOperandHi, miReadAddress, miFetchOpcode },
/* 0xCE DEC abs */ { miFetchOperandLo, miFetchOperandHi, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode },
/* 0xCF --- */ { miFetchOpcode },
/* 0xD0 BNE */ { miFetchOperandAndCheckBranch, miCheckIfPageCrossed, miFakeFetchOperand, miFetchOpcode },
/* 0xD1 CMP ind,Y */ { miFetchOperandLo, miFetchAddressLo, miFetchAddressHiAndIndex, miReadAddressAndSkip, miReadAddress, miFetchOpcode },
/* 0xD2 --- */ { miFetchOpcode },
/* 0xD3 --- */ { miFetchOpcode },
/* 0xD4 --- */ { miFetchOpcode },
/* 0xD5 CMP zpg,X */ { miFetchOperandLo, miIndexX, miReadAddress, miFetchOpcode },
/* 0xD6 DEC zpg,X */ { miFetchOperandLo, miIndexX, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode },
/* 0xD7 --- */ { miFetchOpcode },
/* 0xD8 CLD */ { miFetchOperandLo, miFetchOpcode },
/* 0xD9 CMP abs,Y */ { miFetchOperandLo, miFetchOperandHiAndIndexY, miReadAddressAndSkip, miReadAddress, miFetchOpcode },
/* 0xDA --- */ { miFetchOpcode },
/* 0xDB --- */ { miFetchOpcode },
/* 0xDC --- */ { miFetchOpcode },
/* 0xDD CMP abs,X */ { miFetchOperandLo, miFetchOperandHiAndIndexX, miReadAddressAndSkip, miReadAddress, miFetchOpcode },
/* 0xDE DEC abs,X */ { miFetchOperandLo, miFetchOperandHiAndIndexX, miReadAddress, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode },
/* 0xDF --- */ { miFetchOpcode },
/* 0xE0 CPX, imm */ { miFetchOperandLo, miFetchOpcode },
/* 0xE1 SBC X,ind */ { miFetchOperandLo, miIndexX, miFetchAddressLo, miFetchAddressHi, miReadAddress, miFetchOpcode },
/* 0xE2 --- */ { miFetchOpcode },
/* 0xE3 --- */ { miFetchOpcode },
/* 0xE4 CPX zpg */ { miFetchOperandLo, miReadAddress, miFetchOpcode },
/* 0xE5 SBC zpg */ { miFetchOperandLo, miReadAddress, miFetchOpcode },
/* 0xE6 INC zpg */ { miFetchOperandLo, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode },
/* 0xE7 --- */ { miFetchOpcode },
/* 0xE8 INX */ { miFetchOperandLo, miFetchOpcode },
/* 0xE9 SBC imm */ { miFetchOperandLo, miFetchOpcode },
/* 0xEA NOP */ { miFetchOpcode },
/* 0xEB --- */ { miFetchOpcode },
/* 0xEC CPX abs */ { miFetchOperandLo, miFetchOperandHi, miReadAddress, miFetchOpcode },
/* 0xED SBC abs */ { miFetchOperandLo, miFetchOperandHi, miReadAddress, miFetchOpcode },
/* 0xEE INC abs */ { miFetchOperandLo, miFetchOperandHi, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode },
/* 0xEF --- */ { miFetchOpcode },
/* 0xF0 BEQ */ { miFetchOperandAndCheckBranch, miCheckIfPageCrossed, miFakeFetchOperand, miFetchOpcode },
/* 0xF1 SBC ind,Y */ { miFetchOperandLo, miFetchAddressLo, miFetchAddressHiAndIndex, miReadAddressAndSkip, miReadAddress, miFetchOpcode },
/* 0xF2 --- */ { miFetchOpcode },
/* 0xF3 --- */ { miFetchOpcode },
/* 0xF4 --- */ { miFetchOpcode },
/* 0xF5 SBC zpg,X */ { miFetchOperandLo, miIndexX, miReadAddress, miFetchOpcode },
/* 0xF6 INC zpg,X */ { miFetchOperandLo, miIndexX, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode },
/* 0xF7 --- */ { miFetchOpcode },
/* 0xF8 SED */ { miFetchOperandLo, miFetchOpcode },
/* 0xF9 SBC abs,Y */ { miFetchOperandLo, miFetchOperandHiAndIndexY, miReadAddressAndSkip, miReadAddress, miFetchOpcode },
/* 0xFA --- */ { miFetchOpcode },
/* 0xFB --- */ { miFetchOpcode },
/* 0xFC --- */ { miFetchOpcode },
/* 0xFD SBC abs,X */ { miFetchOperandLo, miFetchOperandHiAndIndexX, miReadAddressAndSkip, miReadAddress, miFetchOpcode },
/* 0xFE INC abs,X */ { miFetchOperandLo, miFetchOperandHiAndIndexX, miReadAddress, miReadAddress, miWriteAddress, miWriteAddress, miFetchOpcode },
/* 0xFF --- */ { miFetchOpcode },
}; };
void SetFlags(uint8_t flags) void SetFlags(uint8_t flags)
{ {
if (flags&fC) rP = ( rP & ~fC ) | ( rTEMP_hi & fC ); if (flags&fC) rP = ( rP & ~fC ) | ( rTEMP_hi & fC );
if (flags&fN) rP = ( rP & ~fN ) | ( rB & fN ); if (flags&fN) rP = ( rP & ~fN ) | ( rTEMP_lo & fN );
if (flags&fZ) rP = ( rB ? rP & ~fZ : rP | fZ ); if (flags&fZ) rP = ( rTEMP_lo ? rP & ~fZ : rP | fZ );
if (flags&fV) rP = ( (rTEMP_lo ^ rA) & (rTEMP_lo ^ rB) & 0x80 ) ? rP | fV : rP & ~fV; if (flags&fV) rP = ( (rTEMP_lo ^ rA) & (rTEMP_lo ^ rB) & 0x80 ) ? rP | fV : rP & ~fV;
} }
void DoOpcodeWork() void DoOpcodeWork()
{ {
if (rI==0xCA) { rX--; rB = rX; SetFlags(fN|fZ); return; } /* DEX */
if (rI==0x88) { rY--; rB = rY; SetFlags(fN|fZ); return; } /* DEY */
if (rI==0xE8) { rX++; rB = rX; SetFlags(fN|fZ); return; } /* INX */
if (rI==0xC8) { rY++; rB = rY; SetFlags(fN|fZ); return; } /* INY */
if (rI==0xA8) { rY = rA; rB = rY; SetFlags(fN|fZ); return; } /* TAY */
if (rI==0x98) { rA = rY; rB = rA; SetFlags(fN|fZ); return; } /* TYA */
if (rI==0xAA) { rX = rA; rB = rX; SetFlags(fN|fZ); return; } /* TAX */
if (rI==0x8A) { rA = rX; rB = rA; SetFlags(fN|fZ); return; } /* TXA */
if (rI==0xBA) { rX = rS; rB = rX; SetFlags(fN|fZ); return; } /* TSX */
if (rI==0x9A) { rS = rX; rB = rS; SetFlags(fN|fZ); return; } /* TXS */
switch (rI&0x03) { switch (rI&0x03) {
case 0: /* Clear/set flags*/ case 0: /* Clear/set flags*/
if ( (rI&0x1c)==0x18 ) { if ( (rI&0x1c)==0x18 ) {
@@ -193,19 +401,34 @@ namespace m6502
case 6: rP &= ~fD; break; case 6: rP &= ~fD; break;
case 7: rP |= fD; break; case 7: rP |= fD; break;
} }
} else if ( ((rI>>5)==5) && (rI!=0xB0) ) {
/* LDY */ rTEMP_lo = rB; SetFlags(fN|fZ); rY = rTEMP_lo; break;
} else if ( ((rI&0xD3)==0xC0) && (((rI>>2)&3)!=2) ) {
if ( (rI&0xf0)==0xC0 ) {
/* CPY */ rTEMP = rY + ~rB; SetFlags(fN|fZ|fC); break;
} else {
/* CPX */ rTEMP = rX + ~rB; SetFlags(fN|fZ|fC); break;
}
} }
break; break;
case 1: /* ALU */ case 1: /* ALU */
switch ((rI>>5)&0x07) { switch ((rI>>5)&0x07) {
case 0: /* ORA */ rB = rA | rB; SetFlags(fN|fZ); rA = rB; break; case 0: /* ORA */ rTEMP_lo = rA | rB; SetFlags(fN|fZ); rA = rTEMP_lo; break;
case 1: /* AND */ rB = rA & rB; SetFlags(fN|fZ); rA = rB; break; case 1: /* AND */ rTEMP_lo = rA & rB; SetFlags(fN|fZ); rA = rTEMP_lo; break;
case 2: /* EOR */ rB = rA ^ rB; SetFlags(fN|fZ); rA = rB; break; case 2: /* EOR */ rTEMP_lo = rA ^ rB; SetFlags(fN|fZ); rA = rTEMP_lo; break;
case 3: /* ADC */ rTEMP = rA + rB + fC; SetFlags(fN|fV|fZ|fC); rA = rTEMP_lo; break; case 3: /* ADC */ rTEMP = rA + rB + fC; SetFlags(fN|fV|fZ|fC); rA = rTEMP_lo; break;
case 5: /* LDA */ SetFlags(fN|fZ); rA = rB; break; case 5: /* LDA */ rTEMP_lo = rB; SetFlags(fN|fZ); rA = rTEMP_lo; break;
case 6: /* CMP */ rTEMP = rA + ~rB; SetFlags(fN|fZ|fC); break; case 6: /* CMP */ rTEMP = rA + ~rB; SetFlags(fN|fZ|fC); break;
case 7: /* SBC */ rTEMP = rA + ~rB + fC; SetFlags(fN|fV|fZ|fC); rA = rTEMP_lo; break; case 7: /* SBC */ rTEMP = rA + ~rB + fC; SetFlags(fN|fV|fZ|fC); rA = rTEMP_lo; break;
}; };
if ( (rI==0x24) || (rI==0x2C) ) /* BIT */ { rTEMP_lo = rA & rB; rP = (rP&~(fN|fV)) | (rB&(fN|fV)); SetFlags(fZ); }
break; break;
case 2:
if ( ((rI>>5)==5) ) {
/* LDX */ rTEMP_lo = rB; SetFlags(fN|fZ); rX = rTEMP_lo; break;
}
break;
}; };
} }
@@ -216,6 +439,11 @@ namespace m6502
if ((rI & 0xF)==0xA) rB = rA; if ((rI & 0xF)==0xA) rB = rA;
switch ((rI>>5)&0x07) { switch ((rI>>5)&0x07) {
case 0: /* ASL */ rP = ( rP & ~fC ) | ( (rB & 0x80)>>7 ); rB = rB << 1; SetFlags(fN|fZ); break; case 0: /* ASL */ rP = ( rP & ~fC ) | ( (rB & 0x80)>>7 ); rB = rB << 1; SetFlags(fN|fZ); break;
case 1: /* ROL */ rT = rP & fC; rP = ( rP & ~fC ) | ( (rB & 0x80)>>7 ); rB = (rB << 1) | rT; SetFlags(fN|fZ); break;
case 2: /* LSR */ rP = ( rP & ~fC ) | ( (rB & fC) ); rB = rB >> 1; SetFlags(fN|fZ); break;
case 3: /* ROR */ rT = (rP & fC) << 7; rP = ( rP & ~fC ) | ( (rB & fC) ); rB = (rB >> 1) | rT; SetFlags(fN|fZ); break;
case 6: /* DEC */ rB--; SetFlags(fN|fZ); break;
case 7: /* INC */ rB++; SetFlags(fN|fZ); break;
}; };
if ((rI & 0xF)==0xA) rA = rB; if ((rI & 0xF)==0xA) rA = rB;
break; break;
@@ -249,11 +477,11 @@ namespace m6502
void FetchOperandHiAndIndexX() { rAD_hi = mem::read(rPC++); rTEMP = rAD_lo + rX; rAD_lo = rTEMP_lo; } void FetchOperandHiAndIndexX() { rAD_hi = mem::read(rPC++); rTEMP = rAD_lo + rX; rAD_lo = rTEMP_lo; }
void FetchOperandHiAndIndexY() { rAD_hi = mem::read(rPC++); rTEMP = rAD_lo + rY; rAD_lo = rTEMP_lo; } void FetchOperandHiAndIndexY() { rAD_hi = mem::read(rPC++); rTEMP = rAD_lo + rY; rAD_lo = rTEMP_lo; }
void PushPCHi() { mem::write(0x0100+(rS++), rPC_hi); } void PushPCHi() { mem::write(0x0100+(rS--), rPC_hi); }
void PushPCLo() { mem::write(0x0100+(rS++), rPC_lo); } void PushPCLo() { mem::write(0x0100+(rS--), rPC_lo); }
void PushP() { mem::write(0x0100+(rS++), rP|f1|fB); rP |= fI; } void PushP() { mem::write(0x0100+(rS--), rP|f1|fB); rP |= fI; }
void PCLoInt() { rPC_lo = mem::read(0xff00+interrupt_type); } void PCLoInt() { rPC_lo = mem::read(0xff00+interrupt_vector); }
void PCHiInt() { rPC_hi = mem::read(0xff00+interrupt_type+1); } void PCHiInt() { rPC_hi = mem::read(0xff00+interrupt_vector+1); }
void IndexX() { rB = mem::read(rAD); rAD_lo += rX; } void IndexX() { rB = mem::read(rAD); rAD_lo += rX; }
void FetchAddressLo() { rT = mem::read(rAD++); } void FetchAddressLo() { rT = mem::read(rAD++); }
@@ -264,16 +492,26 @@ namespace m6502
void ReadAddressAndSkip() { rB = mem::read(rAD); rAD_hi += rTEMP_hi; if (rTEMP_hi) InsertFetchOpcode(); } void ReadAddressAndSkip() { rB = mem::read(rAD); rAD_hi += rTEMP_hi; if (rTEMP_hi) InsertFetchOpcode(); }
void WriteRegister() { mem::write(rAD, (rI&3)==1 ? rA : (rI&3)==2 ? rX : rY ); } void WriteRegister() { mem::write(rAD, (rI&3)==1 ? rA : (rI&3)==2 ? rX : rY ); }
void WriteAddress() { mem::write(rAD, rB); DoRMW(); } void WriteAddress() { mem::write(rAD, rB); DoRMW(); }
void PushA() { mem::write(0x0100+(rS++), rA); } void PushA() { mem::write(0x0100+(rS--), rA); }
void FetchOperandAndCheckBranch() { FetchOperandLo(); if (!BranchCondition()) InsertFetchOpcode(); else { rT = rPC_hi; rPC = rPC + (int8_t)rB; } } void FetchOperandAndCheckBranch() { FetchOperandLo(); if (!BranchCondition()) InsertFetchOpcode(); else { rT = rPC_hi; rPC = rPC + (int8_t)rB; } }
void CheckIfPageCrossed() { FakeFetchOperand(); if (rPC_hi == rT) InsertFetchOpcode(); } void CheckIfPageCrossed() { FakeFetchOperand(); if (rPC_hi == rT) InsertFetchOpcode(); }
void PullPCHi() { rPC_hi = mem::read(0x0100+(++rS)); }
void PullPCLo() { rPC_lo = mem::read(0x0100+(++rS)); }
void PullP() { rP = mem::read(0x0100+(++rS)); }
void PullA() { rA = mem::read(0x0100+(++rS)); }
void IncrementPC() { rPC++; }
void FetchAddressHiToPC() { rPC_hi = mem::read(rAD); rPC_lo = rT; }
void IndexY() { rB = mem::read(rAD); rAD_lo += rY; }
void (*microinstructions[miNumMicroinstructions])(void) { void (*microinstructions[miNumMicroinstructions])(void) {
FetchOpcode, FakeFetchOperand, FetchOperandLo, FetchOperandHi, FetchOperandHiAndIndexX, FetchOperandHiAndIndexY, FetchOpcode, FakeFetchOperand, FetchOperandLo, FetchOperandHi, FetchOperandHiAndIndexX, FetchOperandHiAndIndexY,
PushPCHi, PushPCLo, PushP, PCLoInt, PCHiInt, PushPCHi, PushPCLo, PushP, PCLoInt, PCHiInt,
IndexX, FetchAddressLo, FetchAddressHi, FetchAddressHiAndIndex, ReadAddress, IndexX, FetchAddressLo, FetchAddressHi, FetchAddressHiAndIndex, ReadAddress,
ReadAddressAndSkip, WriteRegister, WriteAddress, PushA, FetchOperandAndCheckBranch, ReadAddressAndSkip, WriteRegister, WriteAddress, PushA, FetchOperandAndCheckBranch,
CheckIfPageCrossed }; CheckIfPageCrossed, PullPCHi, PullPCLo, PullP, PullA,
IncrementPC, FetchAddressHiToPC, IndexY };
void reset() void reset()
{ {
@@ -282,7 +520,7 @@ namespace m6502
void interrupt(uint8_t type) void interrupt(uint8_t type)
{ {
interrupt_vector = type;
} }
void tick() void tick()