mirror of
https://github.com/JorjBauer/aiie.git
synced 2024-12-26 08:29:31 +00:00
test harness improvements; updated 65C02 test; implemented missing 65C02 opcodes
This commit is contained in:
parent
a7582b5154
commit
ce41acf784
6
Makefile
6
Makefile
@ -21,9 +21,9 @@ clean:
|
||||
rm -f *.o *~ */*.o */*~ testharness.basic testharness.verbose testharness.extended apple/diskii-rom.h apple/applemmu-rom.h apple/parallel-rom.h aiie-sdl
|
||||
|
||||
test: $(TSRC)
|
||||
g++ $(CXXFLAGS) -DBASICTEST $(TSRC) -o testharness.basic
|
||||
g++ $(CXXFLAGS) -DVERBOSETEST $(TSRC) -o testharness.verbose
|
||||
g++ $(CXXFLAGS) -DEXTENDEDTEST $(TSRC) -o testharness.extended
|
||||
g++ $(CXXFLAGS) -DEXIT_ON_ILLEGAL -DVERBOSE_CPU_ERRORS -DTESTHARNESS -DBASICTEST $(TSRC) -o testharness.basic
|
||||
g++ $(CXXFLAGS) -DEXIT_ON_ILLEGAL -DVERBOSE_CPU_ERRORS -DTESTHARNESS -DVERBOSETEST $(TSRC) -o testharness.verbose
|
||||
g++ $(CXXFLAGS) -DEXIT_ON_ILLEGAL -DVERBOSE_CPU_ERRORS -DTESTHARNESS -DEXTENDEDTEST $(TSRC) -o testharness.extended
|
||||
|
||||
roms: apple2e.rom disk.rom parallel.rom
|
||||
./util/genrom.pl apple2e.rom disk.rom parallel.rom
|
||||
|
220
cpu.cpp
220
cpu.cpp
@ -7,6 +7,9 @@
|
||||
// To see calls to unimplemented opcodes, define this:
|
||||
//#define VERBOSE_CPU_ERRORS
|
||||
|
||||
// To exit on illegals:
|
||||
//#define EXIT_ON_ILLEGAL
|
||||
|
||||
// Macros to set negative and zero flags based on param, X, Y, whatever
|
||||
#define SETNZ { FLAG(F_N, param & 0x80); FLAG(F_Z, !param); }
|
||||
#define SETNZX { FLAG(F_N, x & 0x80); FLAG(F_Z, !x); }
|
||||
@ -91,6 +94,11 @@ enum optype {
|
||||
O_TXS,
|
||||
O_TYA,
|
||||
|
||||
O_BBR,
|
||||
O_BBS,
|
||||
O_RMB,
|
||||
O_SMB,
|
||||
|
||||
// and the "illegal" opcodes (those that don't officially exist for
|
||||
// the 65c02, but have repeatable results)
|
||||
O_DCP
|
||||
@ -111,9 +119,11 @@ enum addrmode {
|
||||
A_ZEY,
|
||||
A_ZIND,
|
||||
A_ABX,
|
||||
A_ABXI,
|
||||
A_ABY,
|
||||
A_INX,
|
||||
A_INY
|
||||
A_INY,
|
||||
A_ZPREL
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
@ -130,7 +140,7 @@ optype_t opcodes[256] = {
|
||||
{ O_TSB , A_ZER , 5 }, // 0x04 [2]
|
||||
{ O_ORA , A_ZER , 3 }, // 0x05 [2] i.e. "ORA $44"
|
||||
{ O_ASL , A_ZER , 5 }, // 0x06 [2]
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0x07
|
||||
{ O_RMB , A_ZER , 5 }, // 0x07
|
||||
{ O_PHP , A_IMP , 3 }, // 0x08
|
||||
{ O_ORA , A_IMM , 2 }, // 0x09 i.e. "ORA #$44"
|
||||
{ O_ASL_ACC, A_ACC , 2 }, // 0x0A
|
||||
@ -138,7 +148,7 @@ optype_t opcodes[256] = {
|
||||
{ O_TSB , A_ABS , 6 }, // 0x0C
|
||||
{ O_ORA , A_ABS , 4 }, // 0x0D i.e. "ORA $4400"
|
||||
{ O_ASL , A_ABS , 6 }, // 0x0E
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0x0F
|
||||
{ O_BBR , A_ZPREL , 5 }, // 0x0F
|
||||
{ O_BPL , A_REL , 2 }, // 0x10 [8]
|
||||
{ O_ORA , A_INY , 5 }, // 0x11 [2,3] i.e. "ORA ($44),Y"
|
||||
{ O_ORA , A_ZIND , 5 }, // 0x12 [2]
|
||||
@ -146,7 +156,7 @@ optype_t opcodes[256] = {
|
||||
{ O_TRB , A_ZER , 5 }, // 0x14 [2]
|
||||
{ O_ORA , A_ZEX , 4 }, // 0x15 [2] i.e. "ORA $44,X"
|
||||
{ O_ASL , A_ZEX , 6 }, // 0x16 [2]
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0x17
|
||||
{ O_RMB , A_ZER , 5 }, // 0x17
|
||||
{ O_CLC , A_IMP , 2 }, // 0x18
|
||||
{ O_ORA , A_ABY , 4 }, // 0x19 [3] i.e. "ORA $4400,Y"
|
||||
{ O_INC_ACC, A_ACC , 2 }, // 0x1A
|
||||
@ -154,7 +164,7 @@ optype_t opcodes[256] = {
|
||||
{ O_TRB , A_ABS , 6 }, // 0x1C [3]
|
||||
{ O_ORA , A_ABX , 4 }, // 0x1D [3] i.e. "ORA $4400,X"
|
||||
{ O_ASL , A_ABX , 6 }, // 0x1E [6]
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0x1F
|
||||
{ O_BBR , A_ZPREL , 5 }, // 0x1F
|
||||
{ O_JSR , A_ABS , 6 }, // 0x20
|
||||
{ O_AND , A_INX , 6 }, // 0x21 [2]
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0x22
|
||||
@ -162,7 +172,7 @@ optype_t opcodes[256] = {
|
||||
{ O_BIT , A_ZER , 3 }, // 0x24 [2]
|
||||
{ O_AND , A_ZER , 3 }, // 0x25 [2]
|
||||
{ O_ROL , A_ZER , 5 }, // 0x26 [2]
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0x27
|
||||
{ O_RMB , A_ZER , 5 }, // 0x27
|
||||
{ O_PLP , A_IMP , 4 }, // 0x28
|
||||
{ O_AND , A_IMM , 2 }, // 0x29
|
||||
{ O_ROL_ACC, A_ACC , 2 }, // 0x2A
|
||||
@ -170,7 +180,7 @@ optype_t opcodes[256] = {
|
||||
{ O_BIT , A_ABS , 4 }, // 0x2C
|
||||
{ O_AND , A_ABS , 4 }, // 0x2D
|
||||
{ O_ROL , A_ABS , 6 }, // 0x2E
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0x2F
|
||||
{ O_BBR , A_ZPREL , 5 }, // 0x2F
|
||||
{ O_BMI , A_REL , 2 }, // 0x30 [8]
|
||||
{ O_AND , A_INY , 5 }, // 0x31 [2,3]
|
||||
{ O_AND , A_ZIND , 5 }, // 0x32 [2]
|
||||
@ -178,7 +188,7 @@ optype_t opcodes[256] = {
|
||||
{ O_BIT , A_ZEX , 4 }, // 0x34 [2]
|
||||
{ O_AND , A_ZEX , 4 }, // 0x35 [2]
|
||||
{ O_ROL , A_ZEX , 6 }, // 0x36 [2]
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0x37
|
||||
{ O_RMB , A_ZER , 5 }, // 0x37
|
||||
{ O_SEC , A_IMP , 2 }, // 0x38
|
||||
{ O_AND , A_ABY , 4 }, // 0x39 [3]
|
||||
{ O_DEC_ACC, A_ACC , 2 }, // 0x3A [2]
|
||||
@ -186,7 +196,7 @@ optype_t opcodes[256] = {
|
||||
{ O_BIT , A_ABX , 4 }, // 0x3C [3]
|
||||
{ O_AND , A_ABX , 4 }, // 0x3D [3]
|
||||
{ O_ROL , A_ABX , 6 }, // 0x3E [6]
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0x3F
|
||||
{ O_BBR , A_ZPREL , 5 }, // 0x3F
|
||||
{ O_RTI , A_IMP , 6 }, // 0x40
|
||||
{ O_EOR , A_INX , 6 }, // 0x41 [2]
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0x42
|
||||
@ -194,7 +204,7 @@ optype_t opcodes[256] = {
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0x44
|
||||
{ O_EOR , A_ZER , 3 }, // 0x45 [2]
|
||||
{ O_LSR , A_ZER , 5 }, // 0x46 [2]
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0x47
|
||||
{ O_RMB , A_ZER , 5 }, // 0x47
|
||||
{ O_PHA , A_IMP , 3 }, // 0x48
|
||||
{ O_EOR , A_IMM , 2 }, // 0x49
|
||||
{ O_LSR_ACC, A_ACC , 2 }, // 0x4A
|
||||
@ -202,7 +212,7 @@ optype_t opcodes[256] = {
|
||||
{ O_JMP , A_ABS , 3 }, // 0x4C
|
||||
{ O_EOR , A_ABS , 4 }, // 0x4D
|
||||
{ O_LSR , A_ABS , 6 }, // 0x4E
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0x4F
|
||||
{ O_BBR , A_ZPREL , 5 }, // 0x4F
|
||||
{ O_BVC , A_REL , 2 }, // 0x50 [8]
|
||||
{ O_EOR , A_INY , 5 }, // 0x51 [2,3]
|
||||
{ O_EOR , A_ZIND , 5 }, // 0x52
|
||||
@ -210,7 +220,7 @@ optype_t opcodes[256] = {
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0x54
|
||||
{ O_EOR , A_ZEX , 4 }, // 0x55 [2]
|
||||
{ O_LSR , A_ZEX , 6 }, // 0x56 [2]
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0x57
|
||||
{ O_RMB , A_ZER , 5 }, // 0x57
|
||||
{ O_CLI , A_IMP , 2 }, // 0x58
|
||||
{ O_EOR , A_ABY , 4 }, // 0x59 [3]
|
||||
{ O_PHY , A_IMP , 3 }, // 0x5A
|
||||
@ -218,7 +228,7 @@ optype_t opcodes[256] = {
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0x5C
|
||||
{ O_EOR , A_ABX , 4 }, // 0x5D [3]
|
||||
{ O_LSR , A_ABX , 6 }, // 0x5E [6]
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0x5F
|
||||
{ O_BBR , A_ZPREL , 5 }, // 0x5F
|
||||
{ O_RTS , A_IMP , 6 }, // 0x60
|
||||
{ O_ADC , A_INX , 6 }, // 0x61 [2]
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0x62
|
||||
@ -226,7 +236,7 @@ optype_t opcodes[256] = {
|
||||
{ O_STZ , A_ZER , 3 }, // 0x64 [2]
|
||||
{ O_ADC , A_ZER , 3 }, // 0x65 [2]
|
||||
{ O_ROR , A_ZER , 5 }, // 0x66 [2]
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0x67
|
||||
{ O_RMB , A_ZER , 5 }, // 0x67
|
||||
{ O_PLA , A_IMP , 4 }, // 0x68
|
||||
{ O_ADC , A_IMM , 2 }, // 0x69
|
||||
{ O_ROR_ACC, A_ACC , 2 }, // 0x6A [2]
|
||||
@ -234,7 +244,7 @@ optype_t opcodes[256] = {
|
||||
{ O_JMP , A_ABI , 6 }, // 0x6C
|
||||
{ O_ADC , A_ABS , 4 }, // 0x6D
|
||||
{ O_ROR , A_ABS , 6 }, // 0x6E
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0x6F
|
||||
{ O_BBR , A_ZPREL , 5 }, // 0x6F
|
||||
{ O_BVS , A_REL , 2 }, // 0x70 [8]
|
||||
{ O_ADC , A_INY , 5 }, // 0x71 [2,3]
|
||||
{ O_ADC , A_ZIND , 5 }, // 0x72 [2]
|
||||
@ -242,15 +252,15 @@ optype_t opcodes[256] = {
|
||||
{ O_STZ , A_ZEX , 4 }, // 0x74 [2]
|
||||
{ O_ADC , A_ZEX , 4 }, // 0x75 [2]
|
||||
{ O_ROR , A_ZEX , 6 }, // 0x76 [2]
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0x77
|
||||
{ O_RMB , A_ZER , 5 }, // 0x77
|
||||
{ O_SEI , A_IMP , 2 }, // 0x78
|
||||
{ O_ADC , A_ABY , 4 }, // 0x79 [3]
|
||||
{ O_PLY , A_IMP , 4 }, // 0x7A
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0x7B
|
||||
{ O_JMP , A_ABX , 6 }, // 0x7C
|
||||
{ O_ADC , A_ABX , 4 }, // 0x7D [3]
|
||||
{ O_JMP , A_ABXI , 6 }, // 0x7C JMP (ABS, X)
|
||||
{ O_ADC , A_ABX , 4 }, // 0x7D [3] Absolute,X ADC $4400,X
|
||||
{ O_ROR , A_ABX , 6 }, // 0x7E [6]
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0x7F
|
||||
{ O_BBR , A_ZPREL , 5 }, // 0x7F
|
||||
{ O_BRA , A_REL , 3 }, // 0x80 [8]
|
||||
{ O_STA , A_INX , 6 }, // 0x81 [2]
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0x82
|
||||
@ -258,7 +268,7 @@ optype_t opcodes[256] = {
|
||||
{ O_STY , A_ZER , 3 }, // 0x84 [2]
|
||||
{ O_STA , A_ZER , 3 }, // 0x85 [2]
|
||||
{ O_STX , A_ZER , 3 }, // 0x86 [2]
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0x87
|
||||
{ O_SMB , A_ZER , 5 }, // 0x87
|
||||
{ O_DEY , A_IMP , 2 }, // 0x88
|
||||
{ O_BIT , A_IMM , 2 }, // 0x89
|
||||
{ O_TXA , A_IMP , 2 }, // 0x8A
|
||||
@ -266,7 +276,7 @@ optype_t opcodes[256] = {
|
||||
{ O_STY , A_ABS , 4 }, // 0x8C
|
||||
{ O_STA , A_ABS , 4 }, // 0x8D
|
||||
{ O_STX , A_ABS , 4 }, // 0x8E
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0x8F
|
||||
{ O_BBS , A_ZPREL , 5 }, // 0x8F
|
||||
{ O_BCC , A_REL , 2 }, // 0x90 [8]
|
||||
{ O_STA , A_INY , 6 }, // 0x91 [2]
|
||||
{ O_STA , A_ZIND , 5 }, // 0x92 [2]
|
||||
@ -274,7 +284,7 @@ optype_t opcodes[256] = {
|
||||
{ O_STY , A_ZEX , 4 }, // 0x94 [2]
|
||||
{ O_STA , A_ZEX , 4 }, // 0x95 [2]
|
||||
{ O_STX , A_ZEY , 4 }, // 0x96 [2]
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0x97
|
||||
{ O_SMB , A_ZER , 5 }, // 0x97
|
||||
{ O_TYA , A_IMP , 2 }, // 0x98
|
||||
{ O_STA , A_ABY , 5 }, // 0x99
|
||||
{ O_TXS , A_IMP , 2 }, // 0x9A [2]
|
||||
@ -282,7 +292,7 @@ optype_t opcodes[256] = {
|
||||
{ O_STZ , A_ABS , 4 }, // 0x9C
|
||||
{ O_STA , A_ABX , 5 }, // 0x9D
|
||||
{ O_STZ , A_ABX , 5 }, // 0x9E
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0x9F
|
||||
{ O_BBS , A_ZPREL , 5 }, // 0x9F
|
||||
{ O_LDY , A_IMM , 2 }, // 0xA0
|
||||
{ O_LDA , A_INX , 6 }, // 0xA1 [2]
|
||||
{ O_LDX , A_IMM , 2 }, // 0xA2
|
||||
@ -290,7 +300,7 @@ optype_t opcodes[256] = {
|
||||
{ O_LDY , A_ZER , 3 }, // 0xA4 [2]
|
||||
{ O_LDA , A_ZER , 3 }, // 0xA5 [2]
|
||||
{ O_LDX , A_ZER , 3 }, // 0xA6 [2]
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0xA7
|
||||
{ O_SMB , A_ZER , 5 }, // 0xA7
|
||||
{ O_TAY , A_IMP , 2 }, // 0xA8
|
||||
{ O_LDA , A_IMM , 2 }, // 0xA9
|
||||
{ O_TAX , A_IMP , 2 }, // 0xAA
|
||||
@ -298,7 +308,7 @@ optype_t opcodes[256] = {
|
||||
{ O_LDY , A_ABS , 4 }, // 0xAC
|
||||
{ O_LDA , A_ABS , 4 }, // 0xAD
|
||||
{ O_LDX , A_ABS , 4 }, // 0xAE
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0xAF
|
||||
{ O_BBS , A_ZPREL , 5 }, // 0xAF
|
||||
{ O_BCS , A_REL , 2 }, // 0xB0 [8]
|
||||
{ O_LDA , A_INY , 5 }, // 0xB1 [2,3]
|
||||
{ O_LDA , A_ZIND , 5 }, // 0xB2 [2]
|
||||
@ -306,7 +316,7 @@ optype_t opcodes[256] = {
|
||||
{ O_LDY , A_ZEX , 4 }, // 0xB4 [2]
|
||||
{ O_LDA , A_ZEX , 4 }, // 0xB5 [2]
|
||||
{ O_LDX , A_ZEY , 4 }, // 0xB6 [2]
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0xB7
|
||||
{ O_SMB , A_ZER , 5 }, // 0xB7
|
||||
{ O_CLV , A_IMP , 2 }, // 0xB8
|
||||
{ O_LDA , A_ABY , 4 }, // 0xB9 [3]
|
||||
{ O_TSX , A_IMP , 2 }, // 0xBA
|
||||
@ -314,15 +324,16 @@ optype_t opcodes[256] = {
|
||||
{ O_LDY , A_ABX , 4 }, // 0xBC [3]
|
||||
{ O_LDA , A_ABX , 4 }, // 0xBD [3]
|
||||
{ O_LDX , A_ABY , 4 }, // 0xBE [3]
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0xBF
|
||||
{ O_BBS , A_ZPREL , 5 }, // 0xBF
|
||||
{ O_CPY , A_IMM , 2 }, // 0xC0
|
||||
{ O_CMP , A_INX , 6 }, // 0xC1 [2]
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0xC2
|
||||
{ O_DCP, A_INX, 2 }, // 0xC3 -- fixme -- cycle count of this illegal instruction?
|
||||
// { O_DCP, A_INX, 2 }, // 0xC3 -- fixme -- cycle count of this illegal instruction?
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0xC3 -- as a nop for tests
|
||||
{ O_CPY , A_ZER , 3 }, // 0xC4 [2]
|
||||
{ O_CMP , A_ZER , 3 }, // 0xC5 [2]
|
||||
{ O_DEC , A_ZER , 5 }, // 0xC6 [2]
|
||||
{ O_DCP , A_ZER , 2 }, // 0xC7 -- fixme -- cycle count of this illegal instruction?
|
||||
{ O_SMB , A_ZER , 5 }, // 0xC7
|
||||
{ O_INY , A_IMP , 2 }, // 0xC8
|
||||
{ O_CMP , A_IMM , 2 }, // 0xC9
|
||||
{ O_DEX , A_IMP , 2 }, // 0xCA
|
||||
@ -330,15 +341,15 @@ optype_t opcodes[256] = {
|
||||
{ O_CPY , A_ABS , 4 }, // 0xCC
|
||||
{ O_CMP , A_ABS , 4 }, // 0xCD
|
||||
{ O_DEC , A_ABS , 6 }, // 0xCE
|
||||
{ O_DCP , A_ABS , 2 }, // 0xCF -- fixme -- cycle count of this illegal instruction?
|
||||
{ O_BBS , A_ZPREL , 5 }, // 0xCF
|
||||
{ O_BNE , A_REL , 2 }, // 0xD0 [8]
|
||||
{ O_CMP , A_INY , 5 }, // 0xD1 [2,3]
|
||||
{ O_CMP , A_ZIND , 5 }, // 0xD2 [2]
|
||||
{ O_DCP , A_INY , 2 }, // 0xD3 -- fixme -- cycle count of this illegal instruction?
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0xD3 -- as a nop for tests
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0xD4
|
||||
{ O_CMP , A_ZEX , 4 }, // 0xD5 [2]
|
||||
{ O_DEC , A_ZEX , 6 }, // 0xD6 [2]
|
||||
{ O_DCP , A_ZEX , 2 }, // 0xD7 -- fixme -- cycle count of this illegal instruction?
|
||||
{ O_SMB , A_ZER , 5 }, // 0xD7
|
||||
{ O_CLD , A_IMP , 2 }, // 0xD8
|
||||
{ O_CMP , A_ABY , 4 }, // 0xD9 [3]
|
||||
{ O_PHX , A_IMP , 3 }, // 0xDA
|
||||
@ -346,7 +357,7 @@ optype_t opcodes[256] = {
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0xDC
|
||||
{ O_CMP , A_ABX , 4 }, // 0xDD [3]
|
||||
{ O_DEC , A_ABX , 6 }, // 0xDE [6]
|
||||
{ O_DCP , A_ABX , 2 }, // 0xDF -- fixme -- cycle count of this illegal instruction?
|
||||
{ O_BBS , A_ZPREL , 5 }, // 0xDF
|
||||
{ O_CPX , A_IMM , 2 }, // 0xE0
|
||||
{ O_SBC , A_INX , 6 }, // 0xE1 [2]
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0xE2
|
||||
@ -354,7 +365,7 @@ optype_t opcodes[256] = {
|
||||
{ O_CPX , A_ZER , 3 }, // 0xE4 [2]
|
||||
{ O_SBC , A_ZER , 3 }, // 0xE5 [2]
|
||||
{ O_INC , A_ZER , 5 }, // 0xE6 [2]
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0xE7
|
||||
{ O_SMB , A_ZER , 5 }, // 0xE7
|
||||
{ O_INX , A_IMP , 2 }, // 0xE8
|
||||
{ O_SBC , A_IMM , 2 }, // 0xE9
|
||||
{ O_NOP , A_IMP , 2 }, // 0xEA
|
||||
@ -362,7 +373,7 @@ optype_t opcodes[256] = {
|
||||
{ O_CPX , A_ABS , 4 }, // 0xEC
|
||||
{ O_SBC , A_ABS , 4 }, // 0xED
|
||||
{ O_INC , A_ABS , 6 }, // 0xEE
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0xEF
|
||||
{ O_BBS , A_ZPREL , 5 }, // 0xEF
|
||||
{ O_BEQ , A_REL , 2 }, // 0xF0 [8]
|
||||
{ O_SBC , A_INY , 5 }, // 0xF1 [2,3]
|
||||
{ O_SBC , A_ZIND , 5 }, // 0xF2 [2]
|
||||
@ -370,7 +381,7 @@ optype_t opcodes[256] = {
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0xF4
|
||||
{ O_SBC , A_ZEX , 4 }, // 0xF5 [2]
|
||||
{ O_INC , A_ZEX , 6 }, // 0xF6 [2]
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0xF7
|
||||
{ O_SMB , A_ZER , 5 }, // 0xF7
|
||||
{ O_SED , A_IMP , 2 }, // 0xF8
|
||||
{ O_SBC , A_ABY , 4 }, // 0xF9 [3]
|
||||
{ O_PLX , A_IMP , 4 }, // 0xFA
|
||||
@ -378,7 +389,7 @@ optype_t opcodes[256] = {
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0xFC
|
||||
{ O_SBC , A_ABX , 4 }, // 0xFD [3]
|
||||
{ O_INC , A_ABX , 6 }, // 0xFE [6]
|
||||
{ O_ILLEGAL, A_ILLEGAL, 2 }, // 0xFF
|
||||
{ O_BBS , A_ZPREL , 5 }, // 0xFF
|
||||
};
|
||||
/* cycle count footnotes:
|
||||
2: Add 1 cycle if low byte of Direct Page Register is non-zero
|
||||
@ -500,21 +511,32 @@ uint8_t Cpu::step()
|
||||
irqPending = false;
|
||||
irq();
|
||||
}
|
||||
|
||||
|
||||
uint8_t m = readmem(pc++);
|
||||
|
||||
optype_t opcode = opcodes[m];
|
||||
if (opcode.op == O_ILLEGAL || opcode.mode == A_ILLEGAL) {
|
||||
m = 0xEA; // substitute O_NOP...
|
||||
#ifdef VERBOSE_CPU_ERRORS
|
||||
fprintf(stderr, "** Illegal opcode $%.2X at address $%.4x\n",
|
||||
m,
|
||||
pc-1);
|
||||
#endif
|
||||
// Special invalid opcodes that also have arguments...
|
||||
if (m == 0x02 || m == 0x22 || m == 0x42 || m == 0x62 || m == 0x82 ||
|
||||
m == 0xC2 || m == 0xE2 || m == 0x44 || m == 0x54 || m == 0xd4 ||
|
||||
m == 0xf4) {
|
||||
pc++;
|
||||
}
|
||||
if (m == 0x5c || m == 0xdc || m == 0xfc) {
|
||||
pc += 2;
|
||||
}
|
||||
m = 0xEA; // substitute O_NOP...
|
||||
opcode = opcodes[m];
|
||||
}
|
||||
|
||||
// Look at the addressing mode to determine the parameter
|
||||
uint16_t param = 0;
|
||||
uint16_t zprelParam2 = 0;
|
||||
switch (opcode.mode) {
|
||||
case A_ILLEGAL:
|
||||
default:
|
||||
@ -539,17 +561,29 @@ uint8_t Cpu::step()
|
||||
param = (readmem(pc) | (readmem(pc+1) << 8)) + x;
|
||||
pc += 2;
|
||||
break;
|
||||
case A_ABXI:
|
||||
param = (readmem(pc) | (readmem(pc+1) << 8));
|
||||
param += x;
|
||||
param = readmem(param) | (readmem(param+1) << 8);
|
||||
pc += 2;
|
||||
break;
|
||||
case A_REL:
|
||||
// relative
|
||||
param = (int8_t)readmem(pc++);
|
||||
param += pc; // do this in 2 steps b/c readmem(pc++) modifies PC
|
||||
break;
|
||||
case A_ZPREL:
|
||||
// Two params - zero page and relative.
|
||||
param = (int8_t) readmem(pc++); // a zero-page memory location
|
||||
zprelParam2 = (int8_t)readmem(pc++); // a relative branch destination
|
||||
zprelParam2 += pc;
|
||||
break;
|
||||
case A_ABI:
|
||||
// absolute indirect
|
||||
{
|
||||
uint16_t addr = readmem(pc) | (readmem(pc+1) << 8);
|
||||
pc += 2;
|
||||
|
||||
param = addr;
|
||||
param = readmem(addr) | (readmem(addr+1) << 8);
|
||||
}
|
||||
break;
|
||||
@ -585,6 +619,18 @@ uint8_t Cpu::step()
|
||||
param = ( mmu->read(zpL) | (mmu->read(zpH) << 8) );
|
||||
}
|
||||
break;
|
||||
case A_ZIND:
|
||||
{
|
||||
uint8_t a = mmu->read(pc);
|
||||
if (a == 0xFF) {
|
||||
// Wrap around zero-page
|
||||
param = mmu->read(0xFF) | (mmu->read(0) << 8);
|
||||
} else {
|
||||
param = mmu->read(a) | (mmu->read(a+1) << 8);
|
||||
}
|
||||
pc++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// initialize a counter for the number of cycles this run
|
||||
@ -596,6 +642,10 @@ uint8_t Cpu::step()
|
||||
case O_ILLEGAL:
|
||||
default:
|
||||
// This should never happen; we're trapping O_ILLEGAL above and substituting O_NOP.
|
||||
#ifdef EXIT_ON_ILLEGAL
|
||||
printf("Programming error: unhandled opcode $%X\n", m);
|
||||
exit(0);
|
||||
#endif
|
||||
break;
|
||||
case O_CLD:
|
||||
FLAG(F_D, 0);
|
||||
@ -630,6 +680,12 @@ uint8_t Cpu::step()
|
||||
break;
|
||||
case O_BNE:
|
||||
if (!(flags & F_Z)) {
|
||||
#ifdef TESTHARNESS
|
||||
if (pc == param+2) {
|
||||
printf("CPU halt (BNE busy loop)\n");
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
pc = param;
|
||||
cycles++;
|
||||
}
|
||||
@ -660,6 +716,12 @@ uint8_t Cpu::step()
|
||||
break;
|
||||
case O_BEQ:
|
||||
if (flags & F_Z) {
|
||||
#ifdef TESTHARNESS
|
||||
if (pc == param+2) {
|
||||
printf("CPU halt (BEQ busy loop)\n");
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
pc = param;
|
||||
cycles++;
|
||||
}
|
||||
@ -682,6 +744,12 @@ uint8_t Cpu::step()
|
||||
SETNZA;
|
||||
break;
|
||||
case O_JMP:
|
||||
#ifdef TESTHARNESS
|
||||
if (param == pc-3) {
|
||||
printf("CPU halt (JMP busy loop)\n");
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
pc = param;
|
||||
break;
|
||||
case O_DEX:
|
||||
@ -809,12 +877,32 @@ uint8_t Cpu::step()
|
||||
{
|
||||
uint8_t m = readmem(param);
|
||||
uint8_t v = a & m;
|
||||
FLAG(F_N, (v & 0x80) | (m & 0x80));
|
||||
FLAG(F_Z, v == 0);
|
||||
FLAG(F_V, m & 0x40);
|
||||
if (opcode.mode != A_IMM) {
|
||||
FLAG(F_N, (v & 0x80) | (m & 0x80));
|
||||
FLAG(F_V, m & 0x40);
|
||||
}
|
||||
// status = (status & 0x3F) | (uint8_t)(m & 0xC0);
|
||||
}
|
||||
break;
|
||||
case O_TRB:
|
||||
{
|
||||
uint8_t m = readmem(param);
|
||||
uint8_t v = a & m;
|
||||
m &= ~a;
|
||||
writemem(param, m);
|
||||
FLAG(F_Z, v == 0);
|
||||
}
|
||||
break;
|
||||
case O_TSB:
|
||||
{
|
||||
uint8_t m = readmem(param);
|
||||
uint8_t v = a & m;
|
||||
m |= a;
|
||||
writemem(param, m);
|
||||
FLAG(F_Z, v == 0);
|
||||
}
|
||||
break;
|
||||
case O_ROL_ACC:
|
||||
{
|
||||
uint8_t v = a << 1;
|
||||
@ -990,7 +1078,53 @@ uint8_t Cpu::step()
|
||||
case O_BRA:
|
||||
pc = param;
|
||||
break;
|
||||
// ***
|
||||
case O_BBR:
|
||||
{
|
||||
// The bit to test is encoded in the opcode [m].
|
||||
uint8_t btt = 1 << ((m >> 4) & 0x07);
|
||||
uint8_t v = readmem(param); // zero-page memory location to test
|
||||
if (!(v & btt)) {
|
||||
pc = zprelParam2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case O_BBS:
|
||||
{
|
||||
// The bit to test is encoded in the opcode [m].
|
||||
uint8_t btt = 1 << ((m >> 4) & 0x07);
|
||||
uint8_t v = readmem(param); // zero-page memory location to test
|
||||
if (v & btt) {
|
||||
pc = zprelParam2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case O_INC_ACC:
|
||||
a = a + 1;
|
||||
a &= 0xFF;
|
||||
SETNZA;
|
||||
break;
|
||||
case O_DEC_ACC:
|
||||
a = a - 1;
|
||||
a &= 0xFF;
|
||||
SETNZA;
|
||||
break;
|
||||
case O_STZ:
|
||||
writemem(param, 0x00);
|
||||
break;
|
||||
case O_RMB:
|
||||
{
|
||||
// The bit to test is encoded in the opcode [m].
|
||||
uint8_t btt = 1 << ((m >> 4) & 0x07);
|
||||
writemem(param, readmem(param) & ~btt);
|
||||
}
|
||||
break;
|
||||
case O_SMB:
|
||||
{
|
||||
// The bit to test is encoded in the opcode [m].
|
||||
uint8_t btt = 1 << ((m >> 4) & 0x07);
|
||||
writemem(param, readmem(param) | btt);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// And finally update our executed cycle count with the runtime
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -25,7 +25,11 @@ public:
|
||||
virtual uint8_t read(uint16_t mem) { if (mem == 0xBFF0) { return 'R'; } return ram[mem];}
|
||||
virtual void write(uint16_t mem, uint8_t val) {
|
||||
if (mem == 0xBFF0) {printf("%c", val); return;}
|
||||
#if defined(EXTENDEDTEST)
|
||||
if (mem == 0x202) {printf("Start test %d\n", val);}
|
||||
#else
|
||||
if (mem == 0x200) {printf("Start test %d\n", val);}
|
||||
#endif
|
||||
ram[mem] = val;}
|
||||
virtual uint8_t readDirect(uint16_t address, uint8_t fromPage) { return read(address);}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user