From d840d6590dd33d5b295309173a270fc5c1cc6106 Mon Sep 17 00:00:00 2001 From: ArthurFerreira2 Date: Tue, 7 Sep 2021 00:01:47 +0200 Subject: [PATCH] converted tabs to spaces for better readability --- puce65c02.cpp | 3272 ++++++++++++++++++++++++------------------------- 1 file changed, 1636 insertions(+), 1636 deletions(-) diff --git a/puce65c02.cpp b/puce65c02.cpp index 6798fd5..f00f6cd 100644 --- a/puce65c02.cpp +++ b/puce65c02.cpp @@ -30,26 +30,26 @@ // functionnal and timing tests - see also bottom of file - // Theses tests require 65C02_extended_opcodes_test.bin and 6502_functional_test.bin - // from https://github.com/Klaus2m5/6502_65C02_functional_tests - // and timingtest-1.bin from http://forum.6502.org/viewtopic.php?f=8&t=3340 + // Theses tests require 65C02_extended_opcodes_test.bin and 6502_functional_test.bin + // from https://github.com/Klaus2m5/6502_65C02_functional_tests + // and timingtest-1.bin from http://forum.6502.org/viewtopic.php?f=8&t=3340 - // compile and run : + // compile and run : - // g++ -Wall -O3 -D __TESTS__ puce65c02.cpp -o puce65c02 && ./puce65c02 - // or, slower but with detailled info : - // g++ -Wall -O3 -D __TESTS__ -D VERBOSE puce65c02.cpp -o puce65c02 && ./puce65c02 - // or, if you just want to check the cycle accuracy : - // g++ -Wall -O3 -D __TESTS__ -D TIMING puce65c02.cpp -o puce65c02 && ./puce65c02 + // g++ -Wall -O3 -D __TESTS__ puce65c02.cpp -o puce65c02 && ./puce65c02 + // or, slower but with detailled info : + // g++ -Wall -O3 -D __TESTS__ -D VERBOSE puce65c02.cpp -o puce65c02 && ./puce65c02 + // or, if you just want to check the cycle accuracy : + // g++ -Wall -O3 -D __TESTS__ -D TIMING puce65c02.cpp -o puce65c02 && ./puce65c02 - uint8_t RAM[65536]; - inline uint8_t readMem(uint16_t address) { return RAM[address]; } - inline void writeMem(uint16_t address, uint8_t value8) { RAM[address] = value8; } + uint8_t RAM[65536]; + inline uint8_t readMem(uint16_t address) { return RAM[address]; } + inline void writeMem(uint16_t address, uint8_t value8) { RAM[address] = value8; } #else // user is supposed to provide these two functions - extern uint8_t readMem(uint16_t address); - extern void writeMem(uint16_t address, uint8_t value8); + extern uint8_t readMem(uint16_t address); + extern void writeMem(uint16_t address, uint8_t value8); #endif @@ -58,7 +58,7 @@ void puce65c02::RST() { PC = readMem(0xFFFC) | (readMem(0xFFFD) << 8); SP = 0xFF; P.I = 1; - P.U = 1; + P.U = 1; state = run; ticks += 7; } @@ -66,15 +66,15 @@ void puce65c02::RST() { void puce65c02::IRQ() { state = run; // always ?? - if (!P.I) return; // consume clock cycles ? - PC++; - writeMem(0x100 + SP, (PC >> 8) & 0xFF); - SP--; - writeMem(0x100 + SP, PC & 0xFF); - SP--; - writeMem(0x100 + SP, P.byte & ~BREAK); - SP--; - PC = readMem(0xFFFE) | (readMem(0xFFFF) << 8); + if (!P.I) return; // consume clock cycles ? + PC++; + writeMem(0x100 + SP, (PC >> 8) & 0xFF); + SP--; + writeMem(0x100 + SP, PC & 0xFF); + SP--; + writeMem(0x100 + SP, P.byte & ~BREAK); + SP--; + PC = readMem(0xFFFE) | (readMem(0xFFFF) << 8); ticks += 7; } @@ -82,14 +82,14 @@ void puce65c02::IRQ() { void puce65c02::NMI() { state = run; P.I = 1; // ??? - PC++; - writeMem(0x100 + SP, (PC >> 8) & 0xFF); - SP--; - writeMem(0x100 + SP, PC & 0xFF); - SP--; - writeMem(0x100 + SP, P.byte & ~BREAK); - SP--; - PC = readMem(0xFFFA) | (readMem(0xFFFB) << 8); + PC++; + writeMem(0x100 + SP, (PC >> 8) & 0xFF); + SP--; + writeMem(0x100 + SP, PC & 0xFF); + SP--; + writeMem(0x100 + SP, P.byte & ~BREAK); + SP--; + PC = readMem(0xFFFA) | (readMem(0xFFFB) << 8); ticks += 7; } @@ -97,22 +97,22 @@ void puce65c02::NMI() { /* Addressing modes abreviations used in the comments below : - IMP : Implied or Implicit : DEX, RTS, CLC - 61 instructions - ACC : Accumulator : ASL A, ROR A, DEC A - 6 instructions - IMM : Immediate : LDA #$A5 - 19 instructions - ZPG : Zero Page : LDA $81 - 41 instructions - ZPX : Zero Page Indexed with X : LDA $55,X - 21 instructions - ZPY : Zero Page Indexed with Y : LDX $55,Y - 2 instructions - REL : Relative : BEQ LABEL12 - 9 instructions - ABS : Absolute : LDA $2000 - 29 instructions - ABX : Absolute Indexed with X : LDA $2000,X - 17 instructions - ABY : Absolute Indexed with Y : LDA $2000,Y - 9 instructions - IND : Indirect : JMP ($1020) - 1 instruction - IZP : Indirect Zero Page : LDA ($55) (65c02 only) - 8 instructions - IZX : ZP Indexed Indirect with X (Preindexed) : LDA ($55,X) - 8 instructions - IZY : ZP Indirect Indexed with Y (Postindexed) : LDA ($55),Y - 8 instructions - IAX : Absolute Indexed Indirect : JMP ($2000,X) (65c02 only) - 1 instruction - ZPR : Zero Page Relative : BBS0 $23, LABEL (65c02 only) - 16 instructions + IMP : Implied or Implicit : DEX, RTS, CLC - 61 instructions + ACC : Accumulator : ASL A, ROR A, DEC A - 6 instructions + IMM : Immediate : LDA #$A5 - 19 instructions + ZPG : Zero Page : LDA $81 - 41 instructions + ZPX : Zero Page Indexed with X : LDA $55,X - 21 instructions + ZPY : Zero Page Indexed with Y : LDX $55,Y - 2 instructions + REL : Relative : BEQ LABEL12 - 9 instructions + ABS : Absolute : LDA $2000 - 29 instructions + ABX : Absolute Indexed with X : LDA $2000,X - 17 instructions + ABY : Absolute Indexed with Y : LDA $2000,Y - 9 instructions + IND : Indirect : JMP ($1020) - 1 instruction + IZP : Indirect Zero Page : LDA ($55) (65c02 only) - 8 instructions + IZX : ZP Indexed Indirect with X (Preindexed) : LDA ($55,X) - 8 instructions + IZY : ZP Indirect Indexed with Y (Postindexed) : LDA ($55),Y - 8 instructions + IAX : Absolute Indexed Indirect : JMP ($2000,X) (65c02 only) - 1 instruction + ZPR : Zero Page Relative : BBS0 $23, LABEL (65c02 only) - 16 instructions */ @@ -129,30 +129,30 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { switch(readMem(PC++)) { // fetch instruction and increment Program Counter case 0x00 : // IMP BRK - PC++; - writeMem(0x100 + SP, ((PC) >> 8) & 0xFF); - SP--; - writeMem(0x100 + SP, PC & 0xFF); - SP--; - writeMem(0x100 + SP, P.byte | BREAK); - SP--; - P.I = 1; - P.D = 0; - PC = readMem(0xFFFE) | (readMem(0xFFFF) << 8); - ticks += 7; - break; + PC++; + writeMem(0x100 + SP, ((PC) >> 8) & 0xFF); + SP--; + writeMem(0x100 + SP, PC & 0xFF); + SP--; + writeMem(0x100 + SP, P.byte | BREAK); + SP--; + P.I = 1; + P.D = 0; + PC = readMem(0xFFFE) | (readMem(0xFFFF) << 8); + ticks += 7; + break; case 0x01 : // IZX ORA - value8 = readMem(PC) + X; - PC++; - address = readMem(value8); - value8++; - address |= readMem(value8) << 8; - A |= readMem(address); - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 6; - break; + value8 = readMem(PC) + X; + PC++; + address = readMem(value8); + value8++; + address |= readMem(value8) << 8; + A |= readMem(address); + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 6; + break; case 0x02 : // IMM NOP PC++; @@ -215,7 +215,7 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { case 0x0A : // ACC ASL value16 = A << 1; - A = value16 & 0xFF; + A = value16 & 0xFF; P.C = value16 > 0xFF; P.Z = A == 0; P.S = A > 0x7F; @@ -308,8 +308,8 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { value8++; address |= readMem(value8) << 8; A |= readMem(address); - P.Z = A == 0; - P.S = A > 0x7F; + P.Z = A == 0; + P.S = A > 0x7F; ticks += 5; break; @@ -406,7 +406,7 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { case 0x1E : // ABX ASL address = readMem(PC); PC++; - ticks += address + X > 0xFF ? 7 : 6; + ticks += address + X > 0xFF ? 7 : 6; address |= readMem(PC) << 8; PC++; address += X; @@ -463,34 +463,34 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks++; break; - case 0x24 : // ZPG BIT - address = readMem(PC); - PC++; - value8 = readMem(address); - P.Z = (A & value8) == 0; - P.byte = (P.byte & 0x3F) | (value8 & 0xC0); - ticks += 3; - break; + case 0x24 : // ZPG BIT + address = readMem(PC); + PC++; + value8 = readMem(address); + P.Z = (A & value8) == 0; + P.byte = (P.byte & 0x3F) | (value8 & 0xC0); + ticks += 3; + break; - case 0x25 : // ZPG AND - A &= readMem(readMem(PC)); - PC++; - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 3; - break; + case 0x25 : // ZPG AND + A &= readMem(readMem(PC)); + PC++; + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 3; + break; - case 0x26 : // ZPG ROL - address = readMem(PC); - PC++; - value16 = (readMem(address) << 1) | P.C; - P.C = (value16 & 0x100) != 0; - value16 &= 0xFF; - writeMem(address, value16); - P.Z = value16 == 0; - P.S = value16 > 0x7F; - ticks += 5; - break; + case 0x26 : // ZPG ROL + address = readMem(PC); + PC++; + value16 = (readMem(address) << 1) | P.C; + P.C = (value16 & 0x100) != 0; + value16 &= 0xFF; + writeMem(address, value16); + P.Z = value16 == 0; + P.S = value16 > 0x7F; + ticks += 5; + break; case 0x27 : // ZPG RMB address = readMem(PC); @@ -499,68 +499,68 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 5; break; - case 0x28 : // IMP PLP - SP++; - P.byte = readMem(0x100 + SP) | UNDEF; - ticks += 4; - break; + case 0x28 : // IMP PLP + SP++; + P.byte = readMem(0x100 + SP) | UNDEF; + ticks += 4; + break; - case 0x29 : // IMM AND - A &= readMem(PC); - PC++; - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 2; - break; + case 0x29 : // IMM AND + A &= readMem(PC); + PC++; + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 2; + break; - case 0x2A : // ACC ROL - value16 = (A << 1) | P.C; - P.C = (value16 & 0x100) != 0; - A = value16 & 0xFF; - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 2; - break; + case 0x2A : // ACC ROL + value16 = (A << 1) | P.C; + P.C = (value16 & 0x100) != 0; + A = value16 & 0xFF; + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 2; + break; case 0x2B : // IMP NOP ticks++; break; - case 0x2C : // ABS BIT - address = readMem(PC); - PC++; - address |= readMem(PC) << 8; - PC++; - value8 = readMem(address); - P.Z = (A & value8) == 0; - P.byte = (P.byte & 0x3F) | (value8 & 0xC0); - ticks += 4; - break; + case 0x2C : // ABS BIT + address = readMem(PC); + PC++; + address |= readMem(PC) << 8; + PC++; + value8 = readMem(address); + P.Z = (A & value8) == 0; + P.byte = (P.byte & 0x3F) | (value8 & 0xC0); + ticks += 4; + break; - case 0x2D : // ABS AND - address = readMem(PC); - PC++; - address |= readMem(PC) << 8; - PC++; - A &= readMem(address); - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 4; - break; + case 0x2D : // ABS AND + address = readMem(PC); + PC++; + address |= readMem(PC) << 8; + PC++; + A &= readMem(address); + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 4; + break; - case 0x2E : // ABS ROL - address = readMem(PC); - PC++; - address |= readMem(PC) << 8; - PC++; - value16 = (readMem(address) << 1) | P.C; - P.C = (value16 & 0x100) != 0; - value16 &= 0xFF; - writeMem(address, value16); - P.Z = value16 == 0; - P.S = value16 > 0x7F; - ticks += 6; - break; + case 0x2E : // ABS ROL + address = readMem(PC); + PC++; + address |= readMem(PC) << 8; + PC++; + value16 = (readMem(address) << 1) | P.C; + P.C = (value16 & 0x100) != 0; + value16 &= 0xFF; + writeMem(address, value16); + P.Z = value16 == 0; + P.S = value16 > 0x7F; + ticks += 6; + break; case 0x2F : // ZPR BBR value8 = readMem(readMem(PC)); @@ -574,32 +574,32 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 5; break; - case 0x30 : // REL BMI - address = readMem(PC); - PC++; - if (P.S) { // branch taken - ticks++; - if (address & SIGN) - address |= 0xFF00; // jump backward - if (((PC & 0xFF) + address) & 0xFF00) // page crossing - ticks++; - PC += address; - } - ticks += 2; - break; + case 0x30 : // REL BMI + address = readMem(PC); + PC++; + if (P.S) { // branch taken + ticks++; + if (address & SIGN) + address |= 0xFF00; // jump backward + if (((PC & 0xFF) + address) & 0xFF00) // page crossing + ticks++; + PC += address; + } + ticks += 2; + break; - case 0x31 : // IZY AND - value8 = readMem(PC); - PC++; - address = readMem(value8); - value8++; - address |= readMem(value8) << 8; - ticks += (((address & 0xFF) + Y) & 0xFF00) ? 6 : 5; // page crossing - address += Y; - A &= readMem(address); - P.Z = A == 0; - P.S = A > 0x7F; - break; + case 0x31 : // IZY AND + value8 = readMem(PC); + PC++; + address = readMem(value8); + value8++; + address |= readMem(value8) << 8; + ticks += (((address & 0xFF) + Y) & 0xFF00) ? 6 : 5; // page crossing + address += Y; + A &= readMem(address); + P.Z = A == 0; + P.S = A > 0x7F; + break; case 0x32 : // IZP AND value8 = readMem(PC); @@ -626,26 +626,26 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 4; break; - case 0x35 : // ZPX AND - address = (readMem(PC) + X) & 0xFF; - PC++; - A &= readMem(address); - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 4; - break; + case 0x35 : // ZPX AND + address = (readMem(PC) + X) & 0xFF; + PC++; + A &= readMem(address); + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 4; + break; - case 0x36 : // ZPX ROL - address = (readMem(PC) + X) & 0xFF; - PC++; - value16 = (readMem(address) << 1) | P.C; - P.C = value16 > 0xFF; - value16 &= 0xFF; - writeMem(address, value16); - P.Z = value16 == 0; - P.S = value16 > 0x7F; - ticks += 6; - break; + case 0x36 : // ZPX ROL + address = (readMem(PC) + X) & 0xFF; + PC++; + value16 = (readMem(address) << 1) | P.C; + P.C = value16 > 0xFF; + value16 &= 0xFF; + writeMem(address, value16); + P.Z = value16 == 0; + P.S = value16 > 0x7F; + ticks += 6; + break; case 0x37 : // ZPG RMB address = readMem(PC); @@ -654,22 +654,22 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 5; break; - case 0x38 : // IMP SEC - P.C = 1; - ticks += 2; - break; + case 0x38 : // IMP SEC + P.C = 1; + ticks += 2; + break; - case 0x39 : // ABY AND - address = readMem(PC); - PC++; - ticks += ((address + Y) & 0xFF00) ? 5 : 4; // page crossing - address |= readMem(PC) << 8; - PC++; - address += Y; - A &= readMem(address); - P.Z = A == 0; - P.S = A > 0x7F; - break; + case 0x39 : // ABY AND + address = readMem(PC); + PC++; + ticks += ((address + Y) & 0xFF00) ? 5 : 4; // page crossing + address |= readMem(PC) << 8; + PC++; + address += Y; + A &= readMem(address); + P.Z = A == 0; + P.S = A > 0x7F; + break; case 0x3A : // ACC DEC --A; @@ -683,76 +683,76 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { break; case 0x3C : // ABX BIT - ticks += readMem(PC) + X > 0xFF ? 5 : 4; - address = readMem(PC); + ticks += readMem(PC) + X > 0xFF ? 5 : 4; + address = readMem(PC); PC++; address |= (readMem(PC) << 8) + X; PC++; - value8 = readMem(address); + value8 = readMem(address); P.Z = (A & value8) == 0; - P.byte = (P.byte & 0x3F) | (value8 & 0xC0); - break; + P.byte = (P.byte & 0x3F) | (value8 & 0xC0); + break; - case 0x3D : // ABX AND - address = readMem(PC); - PC++; - ticks += ((address + X) & 0xFF00) ? 5 : 4; // page crossing - address |= readMem(PC) << 8; - PC++; - address += X; - A &= readMem(address); - P.Z = A == 0; - P.S = A > 0x7F; - break; - - case 0x3E : // ABX ROL - address = readMem(PC); - PC++; - ticks += address + X > 0xFF ? 7 : 6; - address |= readMem(PC) << 8; - PC++; - address += X; - value16 = (readMem(address) << 1) | P.C; - P.C = value16 > 0xFF; - value16 &= 0xFF; - writeMem(address, value16); - P.Z = value16 == 0; - P.S = value16 > 0x7F; - break; - - case 0x3F : // ZPR BBR - value8 = readMem(readMem(PC)); + case 0x3D : // ABX AND + address = readMem(PC); PC++; - address = readMem(PC); + ticks += ((address + X) & 0xFF00) ? 5 : 4; // page crossing + address |= readMem(PC) << 8; PC++; - if (address & SIGN) - address |= 0xFF00; // jump backward - if (!(value8 & 8)) + address += X; + A &= readMem(address); + P.Z = A == 0; + P.S = A > 0x7F; + break; + + case 0x3E : // ABX ROL + address = readMem(PC); + PC++; + ticks += address + X > 0xFF ? 7 : 6; + address |= readMem(PC) << 8; + PC++; + address += X; + value16 = (readMem(address) << 1) | P.C; + P.C = value16 > 0xFF; + value16 &= 0xFF; + writeMem(address, value16); + P.Z = value16 == 0; + P.S = value16 > 0x7F; + break; + + case 0x3F : // ZPR BBR + value8 = readMem(readMem(PC)); + PC++; + address = readMem(PC); + PC++; + if (address & SIGN) + address |= 0xFF00; // jump backward + if (!(value8 & 8)) PC += address; - ticks += 5; - break; + ticks += 5; + break; - case 0x40 : // IMP RTI - SP++; - P.byte = readMem(0x100 + SP); - SP++; - PC = readMem(0x100 + SP); - SP++; - PC |= readMem(0x100 + SP) << 8; - ticks += 6; - break; + case 0x40 : // IMP RTI + SP++; + P.byte = readMem(0x100 + SP); + SP++; + PC = readMem(0x100 + SP); + SP++; + PC |= readMem(0x100 + SP) << 8; + ticks += 6; + break; - case 0x41 : // IZX EOR - value8 = readMem(PC) + X; - PC++; - address = readMem(value8); - value8++; - address |= readMem(value8) << 8; - A ^= readMem(address); - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 6; - break; + case 0x41 : // IZX EOR + value8 = readMem(PC) + X; + PC++; + address = readMem(value8); + value8++; + address |= readMem(value8) << 8; + A ^= readMem(address); + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 6; + break; case 0x42 : // IMM NOP PC++; @@ -768,26 +768,26 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 3; break; - case 0x45 : // ZPG EOR - address = readMem(PC); - PC++; - A ^= readMem(address); - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 3; - break; + case 0x45 : // ZPG EOR + address = readMem(PC); + PC++; + A ^= readMem(address); + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 3; + break; - case 0x46 : // ZPG LSR - address = readMem(PC); - PC++; - value8 = readMem(address); - P.C = (value8 & 1) != 0; - value8 = value8 >> 1; - writeMem(address, value8); - P.Z = value8 == 0; - P.S = value8 > 0x7F; - ticks += 5; - break; + case 0x46 : // ZPG LSR + address = readMem(PC); + PC++; + value8 = readMem(address); + P.C = (value8 & 1) != 0; + value8 = value8 >> 1; + writeMem(address, value8); + P.Z = value8 == 0; + P.S = value8 > 0x7F; + ticks += 5; + break; case 0x47 : // ZPG RMB address = readMem(PC); @@ -796,61 +796,61 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 5; break; - case 0x48 : // IMP PHA - writeMem(0x100 + SP, A); - SP--; - ticks += 3; - break; + case 0x48 : // IMP PHA + writeMem(0x100 + SP, A); + SP--; + ticks += 3; + break; - case 0x49 : // IMM EOR - A ^= readMem(PC); - PC++; - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 2; - break; + case 0x49 : // IMM EOR + A ^= readMem(PC); + PC++; + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 2; + break; - case 0x4A : // ACC LSR - P.C = (A & 1) != 0; - A = A >> 1; - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 2; - break; + case 0x4A : // ACC LSR + P.C = (A & 1) != 0; + A = A >> 1; + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 2; + break; case 0x4B : // IMP NOP ticks++; break; - case 0x4C : // ABS JMP - PC = readMem(PC) | (readMem(PC + 1) << 8); - ticks += 3; - break; + case 0x4C : // ABS JMP + PC = readMem(PC) | (readMem(PC + 1) << 8); + ticks += 3; + break; - case 0x4D : // ABS EOR - address = readMem(PC); - PC++; - address |= readMem(PC) << 8; - PC++; - A ^= readMem(address); - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 4; - break; + case 0x4D : // ABS EOR + address = readMem(PC); + PC++; + address |= readMem(PC) << 8; + PC++; + A ^= readMem(address); + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 4; + break; - case 0x4E : // ABS LSR - address = readMem(PC); - PC++; - address |= readMem(PC) << 8; - PC++; - value8 = readMem(address); - P.C = (value8 & 1) != 0; - value8 = value8 >> 1; - writeMem(address, value8); - P.Z = value8 == 0; - P.S = value8 > 0x7F; - ticks += 6; - break; + case 0x4E : // ABS LSR + address = readMem(PC); + PC++; + address |= readMem(PC) << 8; + PC++; + value8 = readMem(address); + P.C = (value8 & 1) != 0; + value8 = value8 >> 1; + writeMem(address, value8); + P.Z = value8 == 0; + P.S = value8 > 0x7F; + ticks += 6; + break; case 0x4F : // ZPR BBR value8 = readMem(readMem(PC)); @@ -864,31 +864,31 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 5; break; - case 0x50 : // REL BVC - address = readMem(PC); - PC++; - if (!P.V) { // branch taken - ticks++; - if (address & SIGN) - address |= 0xFF00; // jump backward - if (((PC & 0xFF) + address) & 0xFF00) // page crossing - ticks++; - PC += address; - } - ticks += 2; - break; + case 0x50 : // REL BVC + address = readMem(PC); + PC++; + if (!P.V) { // branch taken + ticks++; + if (address & SIGN) + address |= 0xFF00; // jump backward + if (((PC & 0xFF) + address) & 0xFF00) // page crossing + ticks++; + PC += address; + } + ticks += 2; + break; - case 0x51 : // IZY EOR - value8 = readMem(PC); - PC++; - address = readMem(value8); - value8++; - address |= readMem(value8) << 8; - ticks += (((address & 0xFF) + Y) & 0xFF00) ? 6 : 5; // page crossing - A ^= readMem(address + Y); - P.Z = A == 0; - P.S = A > 0x7F; - break; + case 0x51 : // IZY EOR + value8 = readMem(PC); + PC++; + address = readMem(value8); + value8++; + address |= readMem(value8) << 8; + ticks += (((address & 0xFF) + Y) & 0xFF00) ? 6 : 5; // page crossing + A ^= readMem(address + Y); + P.Z = A == 0; + P.S = A > 0x7F; + break; case 0x52 : // IZP EOR value8 = readMem(PC); @@ -911,26 +911,26 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 4; break; - case 0x55 : // ZPX EOR - address = (readMem(PC) + X) & 0xFF; - PC++; - A ^= readMem(address); - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 4; - break; + case 0x55 : // ZPX EOR + address = (readMem(PC) + X) & 0xFF; + PC++; + A ^= readMem(address); + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 4; + break; - case 0x56 : // ZPX LSR - address = (readMem(PC) + X) & 0xFF; - PC++; - value8 = readMem(address); - P.C = (value8 & 1) != 0; - value8 = value8 >> 1; - writeMem(address, value8); - P.Z = value8 == 0; - P.S = value8 > 0x7F; - ticks += 6; - break; + case 0x56 : // ZPX LSR + address = (readMem(PC) + X) & 0xFF; + PC++; + value8 = readMem(address); + P.C = (value8 & 1) != 0; + value8 = value8 >> 1; + writeMem(address, value8); + P.Z = value8 == 0; + P.S = value8 > 0x7F; + ticks += 6; + break; case 0x57 : // ZPG RMB address = readMem(PC); @@ -939,22 +939,22 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 5; break; - case 0x58 : // IMP CLI - P.I = 0; - ticks += 2; - break; + case 0x58 : // IMP CLI + P.I = 0; + ticks += 2; + break; - case 0x59 : // ABY EOR - address = readMem(PC); - PC++; - ticks += ((address + Y) & 0xFF00) ? 5 : 4; // page crossing - address |= readMem(PC) << 8; - PC++; - address += Y; - A ^= readMem(address); - P.Z = A == 0; - P.S = A > 0x7F; - break; + case 0x59 : // ABY EOR + address = readMem(PC); + PC++; + ticks += ((address + Y) & 0xFF00) ? 5 : 4; // page crossing + address |= readMem(PC) << 8; + PC++; + address += Y; + A ^= readMem(address); + P.Z = A == 0; + P.S = A > 0x7F; + break; case 0x5A : // IMP PHY writeMem(0x100 + SP, Y); @@ -971,32 +971,32 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 8; break; - case 0x5D : // ABX EOR - address = readMem(PC); - PC++; - ticks += ((address + X) & 0xFF00) ? 5 : 4; // page crossing - address |= readMem(PC) << 8; - PC++; - address += X; - A ^= readMem(address); - P.Z = A == 0; - P.S = A > 0x7F; - break; + case 0x5D : // ABX EOR + address = readMem(PC); + PC++; + ticks += ((address + X) & 0xFF00) ? 5 : 4; // page crossing + address |= readMem(PC) << 8; + PC++; + address += X; + A ^= readMem(address); + P.Z = A == 0; + P.S = A > 0x7F; + break; - case 0x5E : // ABX LSR - address = readMem(PC); - PC++; - ticks += address + X > 0xFF ? 7 : 6; - address |= readMem(PC) << 8; - PC++; - address += X; - value8 = readMem(address); - P.C = (value8 & 1) != 0; - value8 = value8 >> 1; - writeMem(address, value8); - P.Z = value8 == 0; - P.S = value8 > 0x7F; - break; + case 0x5E : // ABX LSR + address = readMem(PC); + PC++; + ticks += address + X > 0xFF ? 7 : 6; + address |= readMem(PC) << 8; + PC++; + address += X; + value8 = readMem(address); + P.C = (value8 & 1) != 0; + value8 = value8 >> 1; + writeMem(address, value8); + P.Z = value8 == 0; + P.S = value8 > 0x7F; + break; case 0x5F : // ZPR BBR value8 = readMem(readMem(PC)); @@ -1010,32 +1010,32 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 5; break; - case 0x60 : // IMP RTS - SP++; - PC = readMem(0x100 + SP); - SP++; - PC |= readMem(0x100 + SP) << 8; - PC++; - ticks += 6; - break; + case 0x60 : // IMP RTS + SP++; + PC = readMem(0x100 + SP); + SP++; + PC |= readMem(0x100 + SP) << 8; + PC++; + ticks += 6; + break; - case 0x61 : // IZX ADC - value8 = readMem(PC) + X; - PC++; - address = readMem(value8); - value8++; - address |= readMem(value8) << 8; - value8 = readMem(address); - value16 = A + value8 + P.C; - P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; - if (P.D) - value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; - P.C = value16 > 0xFF; - A = value16 & 0xFF; - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 6; - break; + case 0x61 : // IZX ADC + value8 = readMem(PC) + X; + PC++; + address = readMem(value8); + value8++; + address |= readMem(value8) << 8; + value8 = readMem(address); + value16 = A + value8 + P.C; + P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; + if (P.D) + value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; + P.C = value16 > 0xFF; + A = value16 & 0xFF; + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 6; + break; case 0x62 : // IMM NOP PC++; @@ -1052,33 +1052,33 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 3; break; - case 0x65 : // ZPG ADC - address = readMem(PC); - PC++; - value8 = readMem(address); - value16 = A + value8 + P.C; - P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; - if (P.D) - value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; - P.C = value16 > 0xFF; - A = value16 & 0xFF; - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 3; - break; + case 0x65 : // ZPG ADC + address = readMem(PC); + PC++; + value8 = readMem(address); + value16 = A + value8 + P.C; + P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; + if (P.D) + value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; + P.C = value16 > 0xFF; + A = value16 & 0xFF; + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 3; + break; - case 0x66 : // ZPG ROR - address = readMem(PC); - PC++; - value8 = readMem(address); - value16 = (value8 >> 1) | (P.C << 7); - P.C = (value8 & 0x1) != 0; - value16 &= 0xFF; - writeMem(address, value16); - P.Z = value16 == 0; - P.S = value16 > 0x7F; - ticks += 5; - break; + case 0x66 : // ZPG ROR + address = readMem(PC); + PC++; + value8 = readMem(address); + value16 = (value8 >> 1) | (P.C << 7); + P.C = (value8 & 0x1) != 0; + value16 &= 0xFF; + writeMem(address, value16); + P.Z = value16 == 0; + P.S = value16 > 0x7F; + ticks += 5; + break; case 0x67 : // ZPG RMB address = readMem(PC); @@ -1087,78 +1087,78 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 5; break; - case 0x68 : // IMP PLA - SP++; - A = readMem(0x100 + SP); - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 4; - break; + case 0x68 : // IMP PLA + SP++; + A = readMem(0x100 + SP); + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 4; + break; - case 0x69 : // IMM ADC - value8 = readMem(PC); - PC++; - value16 = A + value8 + P.C; - P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; - if (P.D) - value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; - P.C = value16 > 0xFF; - A = value16 & 0xFF; - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 2; - break; + case 0x69 : // IMM ADC + value8 = readMem(PC); + PC++; + value16 = A + value8 + P.C; + P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; + if (P.D) + value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; + P.C = value16 > 0xFF; + A = value16 & 0xFF; + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 2; + break; - case 0x6A : // ACC ROR - value16 = (A >> 1) | (P.C << 7); - P.C = (A & 0x1) != 0; - A = value16 & 0xFF; - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 2; - break; + case 0x6A : // ACC ROR + value16 = (A >> 1) | (P.C << 7); + P.C = (A & 0x1) != 0; + A = value16 & 0xFF; + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 2; + break; case 0x6B : // IMP NOP ticks++; break; - case 0x6C : // IND JMP - address = readMem(PC) | readMem(PC + 1) << 8; - PC = readMem(address) | (readMem(address + 1) << 8); - ticks += 5; - break; + case 0x6C : // IND JMP + address = readMem(PC) | readMem(PC + 1) << 8; + PC = readMem(address) | (readMem(address + 1) << 8); + ticks += 5; + break; - case 0x6D : // ABS ADC - address = readMem(PC); - PC++; - address |= readMem(PC) << 8; - PC++; - value8 = readMem(address); - value16 = A + value8 + P.C; - P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; - if (P.D) - value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; - P.C = value16 > 0xFF; - A = value16 & 0xFF; - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 4; - break; + case 0x6D : // ABS ADC + address = readMem(PC); + PC++; + address |= readMem(PC) << 8; + PC++; + value8 = readMem(address); + value16 = A + value8 + P.C; + P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; + if (P.D) + value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; + P.C = value16 > 0xFF; + A = value16 & 0xFF; + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 4; + break; - case 0x6E : // ABS ROR - address = readMem(PC); - PC++; - address |= readMem(PC) << 8; - PC++; - value8 = readMem(address); - value16 = (value8 >> 1) | (P.C << 7); - P.C = (value8 & 0x1) != 0; - value16 = value16 & 0xFF; - writeMem(address, value16); - P.Z = value16 == 0; - P.S = value16 > 0x7F; - ticks += 6; - break; + case 0x6E : // ABS ROR + address = readMem(PC); + PC++; + address |= readMem(PC) << 8; + PC++; + value8 = readMem(address); + value16 = (value8 >> 1) | (P.C << 7); + P.C = (value8 & 0x1) != 0; + value16 = value16 & 0xFF; + writeMem(address, value16); + P.Z = value16 == 0; + P.S = value16 > 0x7F; + ticks += 6; + break; case 0x6F : // ZPR BBR value8 = readMem(readMem(PC)); @@ -1172,58 +1172,58 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 5; break; - case 0x70 : // REL BVS - address = readMem(PC); - PC++; - if (P.V) { // branch taken - ticks++; - if (((PC & 0xFF) + address) & 0xFF00) // page crossing - ticks++; - if (address & SIGN) - address |= 0xFF00; // jump backward - PC += address; - } - ticks += 2; - break; + case 0x70 : // REL BVS + address = readMem(PC); + PC++; + if (P.V) { // branch taken + ticks++; + if (((PC & 0xFF) + address) & 0xFF00) // page crossing + ticks++; + if (address & SIGN) + address |= 0xFF00; // jump backward + PC += address; + } + ticks += 2; + break; - case 0x71 : // IZY ADC - value8 = readMem(PC); - PC++; - address = readMem(value8); - if ((address + Y) & 0xFF00) // page crossing - ticks++; - value8++; - address |= readMem(value8) << 8; - address += Y; - value8 = readMem(address); - value16 = A + value8 + P.C; - P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; - if (P.D) - value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; - P.C = value16 > 0xFF; - A = value16 & 0xFF; - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 5; - break; + case 0x71 : // IZY ADC + value8 = readMem(PC); + PC++; + address = readMem(value8); + if ((address + Y) & 0xFF00) // page crossing + ticks++; + value8++; + address |= readMem(value8) << 8; + address += Y; + value8 = readMem(address); + value16 = A + value8 + P.C; + P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; + if (P.D) + value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; + P.C = value16 > 0xFF; + A = value16 & 0xFF; + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 5; + break; - case 0x72 : // IZP ADC - value8 = readMem(PC); - PC++; - address = readMem(value8); - value8++; - address |= readMem(value8) << 8; - value8 = readMem(address); - value16 = A + value8 + P.C; - P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; - if (P.D) - value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; - P.C = value16 > 0xFF; - A = value16 & 0xFF; - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 5; - break; + case 0x72 : // IZP ADC + value8 = readMem(PC); + PC++; + address = readMem(value8); + value8++; + address |= readMem(value8) << 8; + value8 = readMem(address); + value16 = A + value8 + P.C; + P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; + if (P.D) + value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; + P.C = value16 > 0xFF; + A = value16 & 0xFF; + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 5; + break; case 0x73 : // IMP NOP ticks++; @@ -1236,33 +1236,33 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 4; break; - case 0x75 : // ZPX ADC - address = (readMem(PC) + X) & 0xFF; - PC++; - value8 = readMem(address); - value16 = A + value8 + P.C; - P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; - if (P.D) - value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; - P.C = value16 > 0xFF; - A = value16 & 0xFF; - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 4; - break; + case 0x75 : // ZPX ADC + address = (readMem(PC) + X) & 0xFF; + PC++; + value8 = readMem(address); + value16 = A + value8 + P.C; + P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; + if (P.D) + value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; + P.C = value16 > 0xFF; + A = value16 & 0xFF; + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 4; + break; - case 0x76 : // ZPX ROR - address = (readMem(PC) + X) & 0xFF; - PC++; - value8 = readMem(address); - value16 = (value8 >> 1) | (P.C << 7); - P.C = (value8 & 0x1) != 0; - value16 = value16 & 0xFF; - writeMem(address, value16); - P.Z = value16 == 0; - P.S = value16 > 0x7F; - ticks += 6; - break; + case 0x76 : // ZPX ROR + address = (readMem(PC) + X) & 0xFF; + PC++; + value8 = readMem(address); + value16 = (value8 >> 1) | (P.C << 7); + P.C = (value8 & 0x1) != 0; + value16 = value16 & 0xFF; + writeMem(address, value16); + P.Z = value16 == 0; + P.S = value16 > 0x7F; + ticks += 6; + break; case 0x77 : // ZPG RMB address = readMem(PC); @@ -1271,30 +1271,30 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 5; break; - case 0x78 : // IMP SEI - P.I = 1; - ticks += 2; - break; + case 0x78 : // IMP SEI + P.I = 1; + ticks += 2; + break; - case 0x79 : // ABY ADC - if ((readMem(PC) + Y) & 0xFF00) - ticks++; - address = readMem(PC); - PC++; - address |= readMem(PC) << 8; - PC++; - address += Y; - value8 = readMem(address); - value16 = A + value8 + P.C; - P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; - if (P.D) - value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; - P.C = value16 > 0xFF; - A = value16 & 0xFF; - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 4; - break; + case 0x79 : // ABY ADC + if ((readMem(PC) + Y) & 0xFF00) + ticks++; + address = readMem(PC); + PC++; + address |= readMem(PC) << 8; + PC++; + address += Y; + value8 = readMem(address); + value16 = A + value8 + P.C; + P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; + if (P.D) + value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; + P.C = value16 > 0xFF; + A = value16 & 0xFF; + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 4; + break; case 0x7A : // IMP PLY SP++; @@ -1314,41 +1314,41 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { PC = (readMem(address) | (readMem((address + 1) & 0xFFFF) << 8)); break; - case 0x7D : // ABX ADC - if ((readMem(PC) + X) & 0xFF00) - ticks++; - address = readMem(PC); - PC++; - address |= readMem(PC) << 8; - PC++; - address += X; - value8 = readMem(address); - value16 = A + value8 + P.C; - P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; - if (P.D) - value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; - P.C = value16 > 0xFF; - A = value16 & 0xFF; - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 4; - break; + case 0x7D : // ABX ADC + if ((readMem(PC) + X) & 0xFF00) + ticks++; + address = readMem(PC); + PC++; + address |= readMem(PC) << 8; + PC++; + address += X; + value8 = readMem(address); + value16 = A + value8 + P.C; + P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; + if (P.D) + value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; + P.C = value16 > 0xFF; + A = value16 & 0xFF; + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 4; + break; - case 0x7E : // ABX ROR - address = readMem(PC); - PC++; - ticks += address + X > 0xFF ? 7 : 6; - address |= readMem(PC) << 8; - PC++; - address += X; - value8 = readMem(address); - value16 = (value8 >> 1) | (P.C << 7); - P.C = (value8 & 0x1) != 0; - value16 = value16 & 0xFF; - writeMem(address, value16); - P.Z = value16 == 0; - P.S = value16 > 0x7F; - break; + case 0x7E : // ABX ROR + address = readMem(PC); + PC++; + ticks += address + X > 0xFF ? 7 : 6; + address |= readMem(PC) << 8; + PC++; + address += X; + value8 = readMem(address); + value16 = (value8 >> 1) | (P.C << 7); + P.C = (value8 & 0x1) != 0; + value16 = value16 & 0xFF; + writeMem(address, value16); + P.Z = value16 == 0; + P.S = value16 > 0x7F; + break; case 0x7F : // ZPR BBR value8 = readMem(readMem(PC)); @@ -1371,15 +1371,15 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { PC += address; break; - case 0x81 : // IZX STA - value8 = readMem(PC) + X; - PC++; - address = readMem(value8); - value8++; - address |= readMem(value8) << 8; - writeMem(address, A); - ticks += 6; - break; + case 0x81 : // IZX STA + value8 = readMem(PC) + X; + PC++; + address = readMem(value8); + value8++; + address |= readMem(value8) << 8; + writeMem(address, A); + ticks += 6; + break; case 0x82 : // IMM NOP PC++; @@ -1390,23 +1390,23 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks++; break; - case 0x84 : // ZPG STY - writeMem(readMem(PC), Y); - PC++; - ticks += 3; - break; + case 0x84 : // ZPG STY + writeMem(readMem(PC), Y); + PC++; + ticks += 3; + break; - case 0x85 : // ZPG STA - writeMem(readMem(PC), A); - PC++; - ticks += 3; - break; + case 0x85 : // ZPG STA + writeMem(readMem(PC), A); + PC++; + ticks += 3; + break; - case 0x86 : // ZPG STX - writeMem(readMem(PC), X); - PC++; - ticks += 3; - break; + case 0x86 : // ZPG STX + writeMem(readMem(PC), X); + PC++; + ticks += 3; + break; case 0x87 : // ZPG SMB address = readMem(PC); @@ -1415,56 +1415,56 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 5; break; - case 0x88 : // IMP DEY - Y--; - P.Z = (Y & 0xFF) == 0; - P.S = (Y & SIGN) != 0; - ticks += 2; - break; - - case 0x89 : // IMM BIT - P.Z = (A & readMem(PC)) == 0; - PC++; + case 0x88 : // IMP DEY + Y--; + P.Z = (Y & 0xFF) == 0; + P.S = (Y & SIGN) != 0; ticks += 2; break; - case 0x8A : // IMP TXA - A = X; - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 2; - break; + case 0x89 : // IMM BIT + P.Z = (A & readMem(PC)) == 0; + PC++; + ticks += 2; + break; + + case 0x8A : // IMP TXA + A = X; + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 2; + break; case 0x8B : // IMP NOP ticks++; break; - case 0x8C : // ABS STY - address = readMem(PC); - PC++; - address |= readMem(PC) << 8; - PC++; - writeMem(address, Y); - ticks += 4; - break; + case 0x8C : // ABS STY + address = readMem(PC); + PC++; + address |= readMem(PC) << 8; + PC++; + writeMem(address, Y); + ticks += 4; + break; - case 0x8D : // ABS STA - address = readMem(PC); - PC++; - address |= readMem(PC) << 8; - PC++; - writeMem(address, A); - ticks += 4; - break; + case 0x8D : // ABS STA + address = readMem(PC); + PC++; + address |= readMem(PC) << 8; + PC++; + writeMem(address, A); + ticks += 4; + break; - case 0x8E : // ABS STX - address = readMem(PC); - PC++; - address |= readMem(PC) << 8; - PC++; - writeMem(address, X); - ticks += 4; - break; + case 0x8E : // ABS STX + address = readMem(PC); + PC++; + address |= readMem(PC) << 8; + PC++; + writeMem(address, X); + ticks += 4; + break; case 0x8F : // ZPR BBS value8 = readMem(readMem(PC)); @@ -1478,30 +1478,30 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 5; break; - case 0x90 : // REL BCC - address = readMem(PC); - PC++; - if (!P.C) { // branch taken - ticks++; - if (((PC & 0xFF) + address) & 0xFF00) // page crossing - ticks++; - if (address & SIGN) - address |= 0xFF00; // jump backward - PC += address; - } - ticks += 2; - break; + case 0x90 : // REL BCC + address = readMem(PC); + PC++; + if (!P.C) { // branch taken + ticks++; + if (((PC & 0xFF) + address) & 0xFF00) // page crossing + ticks++; + if (address & SIGN) + address |= 0xFF00; // jump backward + PC += address; + } + ticks += 2; + break; - case 0x91 : // IZY STA - value8 = readMem(PC); - PC++; - address = readMem(value8); - value8++; - address |= readMem(value8) << 8; - address += Y; - writeMem(address, A); - ticks += 6; - break; + case 0x91 : // IZY STA + value8 = readMem(PC); + PC++; + address = readMem(value8); + value8++; + address |= readMem(value8) << 8; + address += Y; + writeMem(address, A); + ticks += 6; + break; case 0x92 : // IZP STA value8 = readMem(PC); @@ -1517,24 +1517,24 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks++; break; - case 0x94 : // ZPX STY - address = (readMem(PC) + X) & 0xFF; - PC++; - writeMem(address, Y); - ticks += 4; - break; + case 0x94 : // ZPX STY + address = (readMem(PC) + X) & 0xFF; + PC++; + writeMem(address, Y); + ticks += 4; + break; - case 0x95 : // ZPX STA - writeMem((readMem(PC) + X) & 0xFF, A); - PC++; - ticks += 4; - break; + case 0x95 : // ZPX STA + writeMem((readMem(PC) + X) & 0xFF, A); + PC++; + ticks += 4; + break; - case 0x96 : // ZPY STX - writeMem((readMem(PC) + Y) & 0xFF, X); - PC++; - ticks += 4; - break; + case 0x96 : // ZPY STX + writeMem((readMem(PC) + Y) & 0xFF, X); + PC++; + ticks += 4; + break; case 0x97 : // ZPG SMB address = readMem(PC); @@ -1543,27 +1543,27 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 5; break; - case 0x98 : // IMP TYA - A = Y; - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 2; - break; + case 0x98 : // IMP TYA + A = Y; + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 2; + break; - case 0x99 : // ABY STA - address = readMem(PC); - PC++; - address |= readMem(PC) << 8; - PC++; - address += Y; - writeMem(address, A); - ticks += 5; - break; + case 0x99 : // ABY STA + address = readMem(PC); + PC++; + address |= readMem(PC) << 8; + PC++; + address += Y; + writeMem(address, A); + ticks += 5; + break; - case 0x9A : // IMP TXS - SP = X; - ticks += 2; - break; + case 0x9A : // IMP TXS + SP = X; + ticks += 2; + break; case 0x9B : // IMP NOP ticks++; @@ -1578,15 +1578,15 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 4; break; - case 0x9D : // ABX STA - address = readMem(PC); - PC++; - address |= readMem(PC) << 8; - PC++; - address += X; - writeMem(address, A); - ticks += 5; - break; + case 0x9D : // ABX STA + address = readMem(PC); + PC++; + address |= readMem(PC) << 8; + PC++; + address += X; + writeMem(address, A); + ticks += 5; + break; case 0x9E : // ABX STZ ticks += readMem(PC) + X > 0xFF ? 6 : 5; @@ -1610,58 +1610,58 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 5; break; - case 0xA0 : // IMM LDY - Y = readMem(PC); - PC++; - P.Z = Y == 0; - P.S = Y > 0x7F; - ticks += 2; - break; + case 0xA0 : // IMM LDY + Y = readMem(PC); + PC++; + P.Z = Y == 0; + P.S = Y > 0x7F; + ticks += 2; + break; - case 0xA1 : // IZX LDA - value8 = readMem(PC) + X; - PC++; - address = readMem(value8); - value8++; - address |= readMem(value8) << 8; - A = readMem(address); - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 6; - break; + case 0xA1 : // IZX LDA + value8 = readMem(PC) + X; + PC++; + address = readMem(value8); + value8++; + address |= readMem(value8) << 8; + A = readMem(address); + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 6; + break; - case 0xA2 : // IMM LDX - address = PC; - PC++; - X = readMem(address); - P.Z = X == 0; - P.S = X > 0x7F; - ticks += 2; - break; + case 0xA2 : // IMM LDX + address = PC; + PC++; + X = readMem(address); + P.Z = X == 0; + P.S = X > 0x7F; + ticks += 2; + break; - case 0xA4 : // ZPG LDY - Y = readMem(readMem(PC)); - PC++; - P.Z = Y == 0; - P.S = Y > 0x7F; - ticks += 3; - break; + case 0xA4 : // ZPG LDY + Y = readMem(readMem(PC)); + PC++; + P.Z = Y == 0; + P.S = Y > 0x7F; + ticks += 3; + break; - case 0xA5 : // ZPG LDA - A = readMem(readMem(PC)); - PC++; - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 3; - break; + case 0xA5 : // ZPG LDA + A = readMem(readMem(PC)); + PC++; + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 3; + break; - case 0xA6 : // ZPG LDX - X = readMem(readMem(PC)); - PC++; - P.Z = X == 0; - P.S = X > 0x7F; - ticks += 3; - break; + case 0xA6 : // ZPG LDX + X = readMem(readMem(PC)); + PC++; + P.Z = X == 0; + P.S = X > 0x7F; + ticks += 3; + break; case 0xA7 : // ZPG SMB address = readMem(PC); @@ -1670,64 +1670,64 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 5; break; - case 0xA8 : // IMP TAY - Y = A; - P.Z = Y == 0; - P.S = Y > 0x7F; - ticks += 2; - break; + case 0xA8 : // IMP TAY + Y = A; + P.Z = Y == 0; + P.S = Y > 0x7F; + ticks += 2; + break; - case 0xA9 : // IMM LDA - A = readMem(PC); - PC++; - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 2; - break; + case 0xA9 : // IMM LDA + A = readMem(PC); + PC++; + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 2; + break; - case 0xAA : // IMP TAX - X = A; - P.Z = X == 0; - P.S = X > 0x7F; - ticks += 2; - break; + case 0xAA : // IMP TAX + X = A; + P.Z = X == 0; + P.S = X > 0x7F; + ticks += 2; + break; case 0xAB : // IMP NOP ticks++; break; - case 0xAC : // ABS LDY - address = readMem(PC); - PC++; - address |= readMem(PC) << 8; - PC++; - Y = readMem(address); - P.Z = Y == 0; - P.S = Y > 0x7F; - ticks += 4; - break; + case 0xAC : // ABS LDY + address = readMem(PC); + PC++; + address |= readMem(PC) << 8; + PC++; + Y = readMem(address); + P.Z = Y == 0; + P.S = Y > 0x7F; + ticks += 4; + break; - case 0xAD : // ABS LDA - address = readMem(PC); - PC++; - address |= readMem(PC) << 8; - PC++; - A = readMem(address); - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 4; - break; + case 0xAD : // ABS LDA + address = readMem(PC); + PC++; + address |= readMem(PC) << 8; + PC++; + A = readMem(address); + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 4; + break; - case 0xAE : // ABS LDX - address = readMem(PC); - PC++; - address |= readMem(PC) << 8; - PC++; - X = readMem(address); - P.Z = X == 0; - P.S = X > 0x7F; - ticks += 4; - break; + case 0xAE : // ABS LDX + address = readMem(PC); + PC++; + address |= readMem(PC) << 8; + PC++; + X = readMem(address); + P.Z = X == 0; + P.S = X > 0x7F; + ticks += 4; + break; case 0xAF : // ZPR BBS value8 = readMem(readMem(PC)); @@ -1741,31 +1741,31 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 5; break; - case 0xB0 : // REL BCS - address = readMem(PC); - PC++; - if (P.C) { // branch taken - ticks++; - if (address & SIGN) - address |= 0xFF00; // jump backward - if (((PC & 0xFF) + address) & 0xFF00) // page crossing - ticks++; - PC += address; - } - ticks += 2; - break; + case 0xB0 : // REL BCS + address = readMem(PC); + PC++; + if (P.C) { // branch taken + ticks++; + if (address & SIGN) + address |= 0xFF00; // jump backward + if (((PC & 0xFF) + address) & 0xFF00) // page crossing + ticks++; + PC += address; + } + ticks += 2; + break; - case 0xB1 : // IZY LDA - value8 = readMem(PC); - PC++; - address = readMem(value8); - value8++; - address |= readMem(value8) << 8; - A = readMem(address + Y); - ticks += (((address & 0xFF) + Y) & 0xFF00) ? 6 : 5; // page crossing - P.Z = A == 0; - P.S = A > 0x7F; - break; + case 0xB1 : // IZY LDA + value8 = readMem(PC); + PC++; + address = readMem(value8); + value8++; + address |= readMem(value8) << 8; + A = readMem(address + Y); + ticks += (((address & 0xFF) + Y) & 0xFF00) ? 6 : 5; // page crossing + P.Z = A == 0; + P.S = A > 0x7F; + break; case 0xB2 : // IZP LDA value8 = readMem(PC); @@ -1783,32 +1783,32 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks++; break; - case 0xB4 : // ZPX LDY - address = (readMem(PC) + X) & 0xFF; - PC++; - Y = readMem(address); - P.Z = Y == 0; - P.S = Y > 0x7F; - ticks += 4; - break; + case 0xB4 : // ZPX LDY + address = (readMem(PC) + X) & 0xFF; + PC++; + Y = readMem(address); + P.Z = Y == 0; + P.S = Y > 0x7F; + ticks += 4; + break; - case 0xB5 : // ZPX LDA - address = (readMem(PC) + X) & 0xFF; - PC++; - A = readMem(address); - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 4; - break; + case 0xB5 : // ZPX LDA + address = (readMem(PC) + X) & 0xFF; + PC++; + A = readMem(address); + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 4; + break; - case 0xB6 : // ZPY LDX - address = (readMem(PC) + Y) & 0xFF; - PC++; - X = readMem(address); - P.Z = X == 0; - P.S = X > 0x7F; - ticks += 4; - break; + case 0xB6 : // ZPY LDX + address = (readMem(PC) + Y) & 0xFF; + PC++; + X = readMem(address); + P.Z = X == 0; + P.S = X > 0x7F; + ticks += 4; + break; case 0xB7 : // ZPG SMB address = readMem(PC); @@ -1817,69 +1817,69 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 5; break; - case 0xB8 : // IMP CLV - P.V = 0; - ticks += 2; - break; + case 0xB8 : // IMP CLV + P.V = 0; + ticks += 2; + break; - case 0xB9 : // ABY LDA - address = readMem(PC); - PC++; - ticks += ((address + Y) & 0xFF00) ? 5 : 4; // page crossing - address |= readMem(PC) << 8; - PC++; - address += Y; - A = readMem(address); - P.Z = A == 0; - P.S = A > 0x7F; - break; + case 0xB9 : // ABY LDA + address = readMem(PC); + PC++; + ticks += ((address + Y) & 0xFF00) ? 5 : 4; // page crossing + address |= readMem(PC) << 8; + PC++; + address += Y; + A = readMem(address); + P.Z = A == 0; + P.S = A > 0x7F; + break; - case 0xBA : // IMP TSX - X = SP; - P.Z = X == 0; - P.S = X > 0x7F; - ticks += 2; - break; + case 0xBA : // IMP TSX + X = SP; + P.Z = X == 0; + P.S = X > 0x7F; + ticks += 2; + break; case 0xBB : // IMP NOP ticks++; break; - case 0xBC : // ABX LDY - address = readMem(PC); - PC++; - ticks += ((address + X) & 0xFF00) ? 5 : 4; // page crossing - address |= readMem(PC) << 8; - PC++; - address += X; - Y = readMem(address); - P.Z = Y == 0; - P.S = Y > 0x7F; - break; + case 0xBC : // ABX LDY + address = readMem(PC); + PC++; + ticks += ((address + X) & 0xFF00) ? 5 : 4; // page crossing + address |= readMem(PC) << 8; + PC++; + address += X; + Y = readMem(address); + P.Z = Y == 0; + P.S = Y > 0x7F; + break; - case 0xBD : // ABX LDA - address = readMem(PC); - PC++; - ticks += ((address + X) & 0xFF00) ? 5 : 4; // page crossing - address |= readMem(PC) << 8; - PC++; - address += X; - A = readMem(address); - P.Z = A == 0; - P.S = A > 0x7F; - break; + case 0xBD : // ABX LDA + address = readMem(PC); + PC++; + ticks += ((address + X) & 0xFF00) ? 5 : 4; // page crossing + address |= readMem(PC) << 8; + PC++; + address += X; + A = readMem(address); + P.Z = A == 0; + P.S = A > 0x7F; + break; - case 0xBE : // ABY LDX - address = readMem(PC); - PC++; - ticks += ((address + Y) & 0xFF00) ? 5 : 4; // page crossing - address |= readMem(PC) << 8; - PC++; - address += Y; - X = readMem(address); - P.Z = X == 0; - P.S = X > 0x7F; - break; + case 0xBE : // ABY LDX + address = readMem(PC); + PC++; + ticks += ((address + Y) & 0xFF00) ? 5 : 4; // page crossing + address |= readMem(PC) << 8; + PC++; + address += Y; + X = readMem(address); + P.Z = X == 0; + P.S = X > 0x7F; + break; case 0xBF : // ZPR BBS value8 = readMem(readMem(PC)); @@ -1893,27 +1893,27 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 5; break; - case 0xC0 : // IMM CPY - value8 = readMem(PC); - PC++; - P.Z = ((Y - value8) & 0xFF) == 0; - P.S = ((Y - value8) & SIGN) != 0; - P.C = (Y >= value8) != 0; - ticks += 2; - break; + case 0xC0 : // IMM CPY + value8 = readMem(PC); + PC++; + P.Z = ((Y - value8) & 0xFF) == 0; + P.S = ((Y - value8) & SIGN) != 0; + P.C = (Y >= value8) != 0; + ticks += 2; + break; - case 0xC1 : // IZX CMP - value8 = readMem(PC) + X; - PC++; - address = readMem(value8); - value8++; - address |= readMem(value8) << 8; - value8 = readMem(address); - P.Z = ((A - value8) & 0xFF) == 0; - P.S = ((A - value8) & SIGN) != 0; - P.C = (A >= value8) != 0; - ticks += 6; - break; + case 0xC1 : // IZX CMP + value8 = readMem(PC) + X; + PC++; + address = readMem(value8); + value8++; + address |= readMem(value8) << 8; + value8 = readMem(address); + P.Z = ((A - value8) & 0xFF) == 0; + P.S = ((A - value8) & SIGN) != 0; + P.C = (A >= value8) != 0; + ticks += 6; + break; case 0xC2 : // IMM NOP PC++; @@ -1924,34 +1924,34 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks++; break; - case 0xC4 : // ZPG CPY - value8 = readMem(readMem(PC)); - PC++; - P.Z = ((Y - value8) & 0xFF) == 0; - P.S = ((Y - value8) & SIGN) != 0; - P.C = (Y >= value8) != 0; - ticks += 3; - break; + case 0xC4 : // ZPG CPY + value8 = readMem(readMem(PC)); + PC++; + P.Z = ((Y - value8) & 0xFF) == 0; + P.S = ((Y - value8) & SIGN) != 0; + P.C = (Y >= value8) != 0; + ticks += 3; + break; - case 0xC5 : // ZPG CMP - value8 = readMem(readMem(PC)); - PC++; - P.Z = ((A - value8) & 0xFF) == 0; - P.S = ((A - value8) & SIGN) != 0; - P.C = (A >= value8) != 0; - ticks += 3; - break; + case 0xC5 : // ZPG CMP + value8 = readMem(readMem(PC)); + PC++; + P.Z = ((A - value8) & 0xFF) == 0; + P.S = ((A - value8) & SIGN) != 0; + P.C = (A >= value8) != 0; + ticks += 3; + break; - case 0xC6 : // ZPG DEC - address = readMem(PC); - PC++; - value8 = readMem(address); - --value8; - writeMem(address, value8); - P.Z = value8 == 0; - P.S = value8 > 0x7F; - ticks += 5; - break; + case 0xC6 : // ZPG DEC + address = readMem(PC); + PC++; + value8 = readMem(address); + --value8; + writeMem(address, value8); + P.Z = value8 == 0; + P.S = value8 > 0x7F; + ticks += 5; + break; case 0xC7 : // ZPG SMB address = readMem(PC); @@ -1960,70 +1960,70 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 5; break; - case 0xC8 : // IMP INY - Y++; - P.Z = Y == 0; - P.S = Y > 0x7F; - ticks += 2; - break; + case 0xC8 : // IMP INY + Y++; + P.Z = Y == 0; + P.S = Y > 0x7F; + ticks += 2; + break; - case 0xC9 : // IMM CMP - value8 = readMem(PC); - PC++; - P.Z = ((A - value8) & 0xFF) == 0; - P.S = ((A - value8) & SIGN) != 0; - P.C = (A >= value8) != 0; - ticks += 2; - break; + case 0xC9 : // IMM CMP + value8 = readMem(PC); + PC++; + P.Z = ((A - value8) & 0xFF) == 0; + P.S = ((A - value8) & SIGN) != 0; + P.C = (A >= value8) != 0; + ticks += 2; + break; - case 0xCA : // IMP DEX - X--; - P.Z = (X & 0xFF) == 0; - P.S = X > 0x7F; - ticks += 2; - break; + case 0xCA : // IMP DEX + X--; + P.Z = (X & 0xFF) == 0; + P.S = X > 0x7F; + ticks += 2; + break; case 0xCB : // IMP WAI state = wait; ticks += 3; break; - case 0xCC : // ABS CPY - address = readMem(PC); - PC++; - address |= readMem(PC) << 8; - PC++; - value8 = readMem(address); - P.Z = ((Y - value8) & 0xFF) == 0; - P.S = ((Y - value8) & SIGN) != 0; - P.C = (Y >= value8) != 0; - ticks += 4; - break; + case 0xCC : // ABS CPY + address = readMem(PC); + PC++; + address |= readMem(PC) << 8; + PC++; + value8 = readMem(address); + P.Z = ((Y - value8) & 0xFF) == 0; + P.S = ((Y - value8) & SIGN) != 0; + P.C = (Y >= value8) != 0; + ticks += 4; + break; - case 0xCD : // ABS CMP - address = readMem(PC); - PC++; - address |= readMem(PC) << 8; - PC++; - value8 = readMem(address); - P.Z = ((A - value8) & 0xFF) == 0; - P.S = ((A - value8) & SIGN) != 0; - P.C = (A >= value8) != 0; - ticks += 4; - break; + case 0xCD : // ABS CMP + address = readMem(PC); + PC++; + address |= readMem(PC) << 8; + PC++; + value8 = readMem(address); + P.Z = ((A - value8) & 0xFF) == 0; + P.S = ((A - value8) & SIGN) != 0; + P.C = (A >= value8) != 0; + ticks += 4; + break; - case 0xCE : // ABS DEC - address = readMem(PC); - PC++; - address |= readMem(PC) << 8; - PC++; - value8 = readMem(address); - value8--; - writeMem(address, value8); - P.Z = value8 == 0; - P.S = value8 > 0x7F; - ticks += 3; - break; + case 0xCE : // ABS DEC + address = readMem(PC); + PC++; + address |= readMem(PC) << 8; + PC++; + value8 = readMem(address); + value8--; + writeMem(address, value8); + P.Z = value8 == 0; + P.S = value8 > 0x7F; + ticks += 3; + break; case 0xCF : // ZPR BBS value8 = readMem(readMem(PC)); @@ -2037,33 +2037,33 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 5; break; - case 0xD0 : // REL BNE - address = readMem(PC); - PC++; - if (!P.Z) { // branch taken - ticks++; - if (address & SIGN) - address |= 0xFF00; // jump backward - if (((PC & 0xFF) + address) & 0xFF00) // page crossing - ticks++; - PC += address; - } - ticks += 2; - break; + case 0xD0 : // REL BNE + address = readMem(PC); + PC++; + if (!P.Z) { // branch taken + ticks++; + if (address & SIGN) + address |= 0xFF00; // jump backward + if (((PC & 0xFF) + address) & 0xFF00) // page crossing + ticks++; + PC += address; + } + ticks += 2; + break; - case 0xD1 : // IZY CMP - value8 = readMem(PC); - PC++; - address = readMem(value8); - ticks += ((address + Y) & 0xFF00) ? 6 : 5; // page crossing - value8++; - address |= readMem(value8) << 8; - address += Y; - value8 = readMem(address); - P.Z = ((A - value8) & 0xFF) == 0; - P.S = ((A - value8) & SIGN) != 0; - P.C = (A >= value8) != 0; - break; + case 0xD1 : // IZY CMP + value8 = readMem(PC); + PC++; + address = readMem(value8); + ticks += ((address + Y) & 0xFF00) ? 6 : 5; // page crossing + value8++; + address |= readMem(value8) << 8; + address += Y; + value8 = readMem(address); + P.Z = ((A - value8) & 0xFF) == 0; + P.S = ((A - value8) & SIGN) != 0; + P.C = (A >= value8) != 0; + break; case 0xD2 : // IZP CMP value8 = readMem(PC); @@ -2087,26 +2087,26 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 4; break; - case 0xD5 : // ZPX CMP - address = (readMem(PC) + X) & 0xFF; - PC++; - value8 = readMem(address); - P.Z = ((A - value8) & 0xFF) == 0; - P.S = ((A - value8) & SIGN) != 0; - P.C = (A >= value8) != 0; - ticks += 4; - break; + case 0xD5 : // ZPX CMP + address = (readMem(PC) + X) & 0xFF; + PC++; + value8 = readMem(address); + P.Z = ((A - value8) & 0xFF) == 0; + P.S = ((A - value8) & SIGN) != 0; + P.C = (A >= value8) != 0; + ticks += 4; + break; - case 0xD6 : // ZPX DEC - address = (readMem(PC) + X) & 0xFF; - PC++; - value8 = readMem(address); - value8--; - writeMem(address, value8); - P.Z = value8 == 0; - P.S = value8 > 0x7F; - ticks += 6; - break; + case 0xD6 : // ZPX DEC + address = (readMem(PC) + X) & 0xFF; + PC++; + value8 = readMem(address); + value8--; + writeMem(address, value8); + P.Z = value8 == 0; + P.S = value8 > 0x7F; + ticks += 6; + break; case 0xD7 : // ZPG SMB address = readMem(PC); @@ -2115,27 +2115,27 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 5; break; - case 0xD8 : // IMP CLD - P.D = 0; - ticks += 2; - break; + case 0xD8 : // IMP CLD + P.D = 0; + ticks += 2; + break; - case 0xD9 : // ABY CMP - address = readMem(PC); - PC++; - ticks += ((address + Y) & 0xFF00) ? 5 : 4; // page crossing - address |= readMem(PC) << 8; - PC++; - address += Y; - value8 = readMem(address); - P.Z = ((A - value8) & 0xFF) == 0; - P.S = ((A - value8) & SIGN) != 0; - P.C = (A >= value8) != 0; - break; + case 0xD9 : // ABY CMP + address = readMem(PC); + PC++; + ticks += ((address + Y) & 0xFF00) ? 5 : 4; // page crossing + address |= readMem(PC) << 8; + PC++; + address += Y; + value8 = readMem(address); + P.Z = ((A - value8) & 0xFF) == 0; + P.S = ((A - value8) & SIGN) != 0; + P.C = (A >= value8) != 0; + break; case 0xDA : // IMP PHX writeMem(0x100 + SP, X); - SP--; + SP--; ticks += 3; break; @@ -2149,32 +2149,32 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 4; break; - case 0xDD : // ABX CMP - address = readMem(PC); - PC++; - ticks += ((address + X) & 0xFF00) ? 5 : 4; // page crossing - address |= readMem(PC) << 8; - PC++; - address += X; - value8 = readMem(address); - P.Z = ((A - value8) & 0xFF) == 0; - P.S = ((A - value8) & SIGN) != 0; - P.C = (A >= value8) != 0; - break; + case 0xDD : // ABX CMP + address = readMem(PC); + PC++; + ticks += ((address + X) & 0xFF00) ? 5 : 4; // page crossing + address |= readMem(PC) << 8; + PC++; + address += X; + value8 = readMem(address); + P.Z = ((A - value8) & 0xFF) == 0; + P.S = ((A - value8) & SIGN) != 0; + P.C = (A >= value8) != 0; + break; - case 0xDE : // ABX DEC - address = readMem(PC); - PC++; - address |= readMem(PC) << 8; - PC++; - address += X; - value8 = readMem(address); - value8--; - writeMem(address, value8); - P.Z = value8 == 0; - P.S = (value8 & SIGN) != 0; - ticks += 7; - break; + case 0xDE : // ABX DEC + address = readMem(PC); + PC++; + address |= readMem(PC) << 8; + PC++; + address += X; + value8 = readMem(address); + value8--; + writeMem(address, value8); + P.Z = value8 == 0; + P.S = (value8 & SIGN) != 0; + ticks += 7; + break; case 0xDF : // ZPR BBS value8 = readMem(readMem(PC)); @@ -2188,35 +2188,35 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 5; break; - case 0xE0 : // IMM CPX - value8 = readMem(PC); - PC++; - P.Z = ((X - value8) & 0xFF) == 0; - P.S = ((X - value8) & SIGN) != 0; - P.C = (X >= value8) != 0; - ticks += 2; - break; + case 0xE0 : // IMM CPX + value8 = readMem(PC); + PC++; + P.Z = ((X - value8) & 0xFF) == 0; + P.S = ((X - value8) & SIGN) != 0; + P.C = (X >= value8) != 0; + ticks += 2; + break; - case 0xE1 : // IZX SBC - value8 = readMem(PC) + X; - PC++; - address = readMem(value8); - value8++; - address |= readMem(value8) << 8; - value8 = readMem(address); - value8 ^= 0xFF; - if (P.D) - value8 -= 0x0066; - value16 = A + value8 + P.C; - P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; - if (P.D) - value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; - P.C = value16 > 0xFF; - A = value16 & 0xFF; - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 6; - break; + case 0xE1 : // IZX SBC + value8 = readMem(PC) + X; + PC++; + address = readMem(value8); + value8++; + address |= readMem(value8) << 8; + value8 = readMem(address); + value8 ^= 0xFF; + if (P.D) + value8 -= 0x0066; + value16 = A + value8 + P.C; + P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; + if (P.D) + value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; + P.C = value16 > 0xFF; + A = value16 & 0xFF; + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 6; + break; case 0xE2 : // IMM NOP PC++; @@ -2227,42 +2227,42 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks++; break; - case 0xE4 : // ZPG CPX - value8 = readMem(readMem(PC)); - PC++; - P.Z = ((X - value8) & 0xFF) == 0; - P.S = ((X - value8) & SIGN) != 0; - P.C = (X >= value8) != 0; - ticks += 3; - break; + case 0xE4 : // ZPG CPX + value8 = readMem(readMem(PC)); + PC++; + P.Z = ((X - value8) & 0xFF) == 0; + P.S = ((X - value8) & SIGN) != 0; + P.C = (X >= value8) != 0; + ticks += 3; + break; - case 0xE5 : // ZPG SBC - value8 = readMem(readMem(PC)); - PC++; - value8 ^= 0xFF; - if (P.D) - value8 -= 0x0066; - value16 = A + value8 + P.C; - P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; - if (P.D) - value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; - P.C = value16 > 0xFF; - A = value16 & 0xFF; - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 3; - break; + case 0xE5 : // ZPG SBC + value8 = readMem(readMem(PC)); + PC++; + value8 ^= 0xFF; + if (P.D) + value8 -= 0x0066; + value16 = A + value8 + P.C; + P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; + if (P.D) + value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; + P.C = value16 > 0xFF; + A = value16 & 0xFF; + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 3; + break; - case 0xE6 : // ZPG INC - address = readMem(PC); - PC++; - value8 = readMem(address); - value8++; - writeMem(address, value8); - P.Z = value8 == 0; - P.S = value8 > 0x7F; - ticks += 5; - break; + case 0xE6 : // ZPG INC + address = readMem(PC); + PC++; + value8 = readMem(address); + value8++; + writeMem(address, value8); + P.Z = value8 == 0; + P.S = value8 > 0x7F; + ticks += 5; + break; case 0xE7 : // ZPG SMB address = readMem(PC); @@ -2271,82 +2271,82 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 5; break; - case 0xE8 : // IMP INX - X++; - P.Z = X == 0; - P.S = X > 0x7F; - ticks += 2; - break; + case 0xE8 : // IMP INX + X++; + P.Z = X == 0; + P.S = X > 0x7F; + ticks += 2; + break; - case 0xE9 : // IMM SBC - value8 = readMem(PC); - PC++; - value8 ^= 0xFF; - if (P.D) - value8 -= 0x0066; - value16 = A + value8 + (P.C); - P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; - if (P.D) - value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; - P.C = value16 > 0xFF; - A = value16 & 0xFF; - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 2; - break; + case 0xE9 : // IMM SBC + value8 = readMem(PC); + PC++; + value8 ^= 0xFF; + if (P.D) + value8 -= 0x0066; + value16 = A + value8 + (P.C); + P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; + if (P.D) + value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; + P.C = value16 > 0xFF; + A = value16 & 0xFF; + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 2; + break; - case 0xEA: // IMP NOP - ticks += 2; - break; + case 0xEA: // IMP NOP + ticks += 2; + break; case 0xEB : // IMP NOP ticks++; break; - case 0xEC : // ABS CPX - address = readMem(PC); - PC++; - address |= readMem(PC) << 8; - PC++; - value8 = readMem(address); - P.Z = ((X - value8) & 0xFF) == 0; - P.S = ((X - value8) & SIGN) != 0; - P.C = (X >= value8) != 0; - ticks += 4; - break; - - case 0xED : // ABS SBC + case 0xEC : // ABS CPX address = readMem(PC); - PC++; - address |= readMem(PC) << 8; - PC++; - value8 = readMem(address); - value8 ^= 0xFF; - if (P.D) - value8 -= 0x0066; - value16 = A + value8 + P.C; - P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; - if (P.D) - value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; - P.C = value16 > 0xFF; - A = value16 & 0xFF; - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 4; - break; + PC++; + address |= readMem(PC) << 8; + PC++; + value8 = readMem(address); + P.Z = ((X - value8) & 0xFF) == 0; + P.S = ((X - value8) & SIGN) != 0; + P.C = (X >= value8) != 0; + ticks += 4; + break; - case 0xEE : // ABS INC - address = readMem(PC); - PC++; - address |= readMem(PC) << 8; - PC++; - value8 = readMem(address); - value8++; - writeMem(address, value8); - P.Z = value8 == 0; - P.S = value8 > 0x7F; - ticks += 6; - break; + case 0xED : // ABS SBC + address = readMem(PC); + PC++; + address |= readMem(PC) << 8; + PC++; + value8 = readMem(address); + value8 ^= 0xFF; + if (P.D) + value8 -= 0x0066; + value16 = A + value8 + P.C; + P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; + if (P.D) + value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; + P.C = value16 > 0xFF; + A = value16 & 0xFF; + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 4; + break; + + case 0xEE : // ABS INC + address = readMem(PC); + PC++; + address |= readMem(PC) << 8; + PC++; + value8 = readMem(address); + value8++; + writeMem(address, value8); + P.Z = value8 == 0; + P.S = value8 > 0x7F; + ticks += 6; + break; case 0xEF : // ZPR BBS value8 = readMem(readMem(PC)); @@ -2360,64 +2360,64 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 5; break; - case 0xF0 : // REL BEQ - address = readMem(PC); - PC++; - if (P.Z) { // branch taken - ticks++; - if (address & SIGN) - address |= 0xFF00; // jump backward - if (((PC & 0xFF) + address) & 0xFF00) // page crossing - ticks++; - PC += address; - } - ticks += 2; - break; + case 0xF0 : // REL BEQ + address = readMem(PC); + PC++; + if (P.Z) { // branch taken + ticks++; + if (address & SIGN) + address |= 0xFF00; // jump backward + if (((PC & 0xFF) + address) & 0xFF00) // page crossing + ticks++; + PC += address; + } + ticks += 2; + break; - case 0xF1 : // IZY SBC - value8 = readMem(PC); - PC++; - address = readMem(value8); - if ((address + Y) & 0xFF00) // page crossing - ticks++; - value8++; - address |= readMem(value8) << 8; - address += Y; - value8 = readMem(address); - value8 ^= 0xFF; - if (P.D) - value8 -= 0x0066; - value16 = A + value8 + P.C; - P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; - if (P.D) - value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; - P.C = value16 > 0xFF; - A = value16 & 0xFF; - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 5; - break; + case 0xF1 : // IZY SBC + value8 = readMem(PC); + PC++; + address = readMem(value8); + if ((address + Y) & 0xFF00) // page crossing + ticks++; + value8++; + address |= readMem(value8) << 8; + address += Y; + value8 = readMem(address); + value8 ^= 0xFF; + if (P.D) + value8 -= 0x0066; + value16 = A + value8 + P.C; + P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; + if (P.D) + value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; + P.C = value16 > 0xFF; + A = value16 & 0xFF; + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 5; + break; case 0xF2 : // IZP SBC - value8 = readMem(PC); - PC++; - address = readMem(value8); - value8++; - address |= readMem(value8) << 8; - value8 = readMem(address); - value8 ^= 0xFF; - if (P.D) - value8 -= 0x0066; - value16 = A + value8 + P.C; - P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; - if (P.D) - value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; - P.C = value16 > 0xFF; - A = value16 & 0xFF; - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 5; - break; + value8 = readMem(PC); + PC++; + address = readMem(value8); + value8++; + address |= readMem(value8) << 8; + value8 = readMem(address); + value8 ^= 0xFF; + if (P.D) + value8 -= 0x0066; + value16 = A + value8 + P.C; + P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; + if (P.D) + value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; + P.C = value16 > 0xFF; + A = value16 & 0xFF; + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 5; + break; case 0xF3 : // IMP NOP ticks++; @@ -2428,34 +2428,34 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 4; break; - case 0xF5 : // ZPX SBC - address = (readMem(PC) + X) & 0xFF; - PC++; - value8 = readMem(address); - value8 ^= 0xFF; - if (P.D) - value8 -= 0x0066; - value16 = A + value8 + P.C; - P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; - if (P.D) - value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; - P.C = value16 > 0xFF; - A = value16 & 0xFF; - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 4; - break; + case 0xF5 : // ZPX SBC + address = (readMem(PC) + X) & 0xFF; + PC++; + value8 = readMem(address); + value8 ^= 0xFF; + if (P.D) + value8 -= 0x0066; + value16 = A + value8 + P.C; + P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; + if (P.D) + value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; + P.C = value16 > 0xFF; + A = value16 & 0xFF; + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 4; + break; - case 0xF6 : // ZPX INC - address = (readMem(PC) + X) & 0xFF; - PC++; - value8 = readMem(address); - value8++; - writeMem(address, value8); - P.Z = value8 == 0; - P.S = value8 > 0x7F; - ticks += 6; - break; + case 0xF6 : // ZPX INC + address = (readMem(PC) + X) & 0xFF; + PC++; + value8 = readMem(address); + value8++; + writeMem(address, value8); + P.Z = value8 == 0; + P.S = value8 > 0x7F; + ticks += 6; + break; case 0xF7 : // ZPG SMB address = readMem(PC); @@ -2464,33 +2464,33 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 5; break; - case 0xF8 : // IMP SED - P.D = 1; - ticks += 2; - break; + case 0xF8 : // IMP SED + P.D = 1; + ticks += 2; + break; - case 0xF9 : // ABY SBC - address = readMem(PC); - PC++; - if ((address + Y) & 0xFF00) // page crossing - ticks++; - address |= readMem(PC) << 8; - PC++; - address += Y; - value8 = readMem(address); - value8 ^= 0xFF; - if (P.D) - value8 -= 0x0066; - value16 = A + value8 + P.C; - P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; - if (P.D) - value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; - P.C = value16 > 0xFF; - A = value16 & 0xFF; - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 4; - break; + case 0xF9 : // ABY SBC + address = readMem(PC); + PC++; + if ((address + Y) & 0xFF00) // page crossing + ticks++; + address |= readMem(PC) << 8; + PC++; + address += Y; + value8 = readMem(address); + value8 ^= 0xFF; + if (P.D) + value8 -= 0x0066; + value16 = A + value8 + P.C; + P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; + if (P.D) + value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; + P.C = value16 > 0xFF; + A = value16 & 0xFF; + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 4; + break; case 0xFA : // IMP PLX SP++; @@ -2509,42 +2509,42 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { ticks += 4; break; - case 0xFD : // ABX SBC - address = readMem(PC); - PC++; - if ((address + X) & 0xFF00) // page crossing - ticks++; - address |= readMem(PC) << 8; - PC++; - address += X; - value8 = readMem(address); - value8 ^= 0xFF; - if (P.D) - value8 -= 0x0066; - value16 = A + value8 + P.C; - P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; - if (P.D) - value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; - P.C = (value16 & 0xFF00) != 0; - A = value16 & 0xFF; - P.Z = A == 0; - P.S = A > 0x7F; - ticks += 4; - break; + case 0xFD : // ABX SBC + address = readMem(PC); + PC++; + if ((address + X) & 0xFF00) // page crossing + ticks++; + address |= readMem(PC) << 8; + PC++; + address += X; + value8 = readMem(address); + value8 ^= 0xFF; + if (P.D) + value8 -= 0x0066; + value16 = A + value8 + P.C; + P.V = ((value16 ^ A) & (value16 ^ value8) & 0x0080) != 0; + if (P.D) + value16 += ((((value16 + 0x66) ^ A ^ value8) >> 3) & 0x22) * 3; + P.C = (value16 & 0xFF00) != 0; + A = value16 & 0xFF; + P.Z = A == 0; + P.S = A > 0x7F; + ticks += 4; + break; - case 0xFE : // ABX INC - address = readMem(PC); - PC++; - address |= readMem(PC) << 8; - PC++; - address += X; - value8 = readMem(address); - value8++; - writeMem(address, value8); - P.Z = value8 == 0; - P.S = value8 > 0x7F; - ticks += 7; - break; + case 0xFE : // ABX INC + address = readMem(PC); + PC++; + address |= readMem(PC) << 8; + PC++; + address += X; + value8 = readMem(address); + value8++; + writeMem(address, value8); + P.Z = value8 == 0; + P.S = value8 > 0x7F; + ticks += 7; + break; case 0xFF : // ZPR BBS value8 = readMem(readMem(PC)); @@ -2575,239 +2575,239 @@ uint16_t puce65c02::exec(unsigned long long int cycleCount) { // and http://forum.6502.org/viewtopic.php?f=8&t=3340 // // for functionnal tests : -// g++ -Wall -O3 -D __TESTS__ puce65c02.cpp -o puce65c02 && ./puce65c02 +// g++ -Wall -O3 -D __TESTS__ puce65c02.cpp -o puce65c02 && ./puce65c02 // or, for detailled info -// g++ -Wall -O3 -D __TESTS__ -D VERBOSE puce65c02.cpp -o puce65c02 && ./puce65c02 +// g++ -Wall -O3 -D __TESTS__ -D VERBOSE puce65c02.cpp -o puce65c02 && ./puce65c02 // or, if you want to check the cycle accuracy : -// g++ -Wall -O3 -D __TESTS__ -D TIMING puce65c02.cpp -o puce65c02 && ./puce65c02 +// g++ -Wall -O3 -D __TESTS__ -D TIMING puce65c02.cpp -o puce65c02 && ./puce65c02 // and see bottom of file for more info #if __TESTS__ - #include + #include - static const char* mn[256] = { - "BRK","ORA","NOP","NOP","TSB","ORA","ASL","RMB","PHP","ORA","ASL","NOP","TSB","ORA","ASL","BBR", - "BPL","ORA","ORA","NOP","TRB","ORA","ASL","RMB","CLC","ORA","INC","NOP","TRB","ORA","ASL","BBR", - "JSR","AND","NOP","NOP","BIT","AND","ROL","RMB","PLP","AND","ROL","NOP","BIT","AND","ROL","BBR", - "BMI","AND","AND","NOP","BIT","AND","ROL","RMB","SEC","AND","DEC","NOP","BIT","AND","ROL","BBR", - "RTI","EOR","NOP","NOP","NOP","EOR","LSR","RMB","PHA","EOR","LSR","NOP","JMP","EOR","LSR","BBR", - "BVC","EOR","EOR","NOP","NOP","EOR","LSR","RMB","CLI","EOR","PHY","NOP","NOP","EOR","LSR","BBR", - "RTS","ADC","NOP","NOP","STZ","ADC","ROR","RMB","PLA","ADC","ROR","NOP","JMP","ADC","ROR","BBR", - "BVS","ADC","ADC","NOP","STZ","ADC","ROR","RMB","SEI","ADC","PLY","NOP","JMP","ADC","ROR","BBR", - "BRA","STA","NOP","NOP","STY","STA","STX","SMB","DEY","BIT","TXA","NOP","STY","STA","STX","BBS", - "BCC","STA","STA","NOP","STY","STA","STX","SMB","TYA","STA","TXS","NOP","STZ","STA","STZ","BBS", - "LDY","LDA","LDX","NOP","LDY","LDA","LDX","SMB","TAY","LDA","TAX","NOP","LDY","LDA","LDX","BBS", - "BCS","LDA","LDA","NOP","LDY","LDA","LDX","SMB","CLV","LDA","TSX","NOP","LDY","LDA","LDX","BBS", - "CPY","CMP","NOP","NOP","CPY","CMP","DEC","SMB","INY","CMP","DEX","WAI","CPY","CMP","DEC","BBS", - "BNE","CMP","CMP","NOP","NOP","CMP","DEC","SMB","CLD","CMP","PHX","STP","NOP","CMP","DEC","BBS", - "CPX","SBC","NOP","NOP","CPX","SBC","INC","SMB","INX","SBC","NOP","NOP","CPX","SBC","INC","BBS", - "BEQ","SBC","SBC","NOP","NOP","SBC","INC","SMB","SED","SBC","PLX","NOP","NOP","SBC","INC","BBS" - }; + static const char* mn[256] = { + "BRK","ORA","NOP","NOP","TSB","ORA","ASL","RMB","PHP","ORA","ASL","NOP","TSB","ORA","ASL","BBR", + "BPL","ORA","ORA","NOP","TRB","ORA","ASL","RMB","CLC","ORA","INC","NOP","TRB","ORA","ASL","BBR", + "JSR","AND","NOP","NOP","BIT","AND","ROL","RMB","PLP","AND","ROL","NOP","BIT","AND","ROL","BBR", + "BMI","AND","AND","NOP","BIT","AND","ROL","RMB","SEC","AND","DEC","NOP","BIT","AND","ROL","BBR", + "RTI","EOR","NOP","NOP","NOP","EOR","LSR","RMB","PHA","EOR","LSR","NOP","JMP","EOR","LSR","BBR", + "BVC","EOR","EOR","NOP","NOP","EOR","LSR","RMB","CLI","EOR","PHY","NOP","NOP","EOR","LSR","BBR", + "RTS","ADC","NOP","NOP","STZ","ADC","ROR","RMB","PLA","ADC","ROR","NOP","JMP","ADC","ROR","BBR", + "BVS","ADC","ADC","NOP","STZ","ADC","ROR","RMB","SEI","ADC","PLY","NOP","JMP","ADC","ROR","BBR", + "BRA","STA","NOP","NOP","STY","STA","STX","SMB","DEY","BIT","TXA","NOP","STY","STA","STX","BBS", + "BCC","STA","STA","NOP","STY","STA","STX","SMB","TYA","STA","TXS","NOP","STZ","STA","STZ","BBS", + "LDY","LDA","LDX","NOP","LDY","LDA","LDX","SMB","TAY","LDA","TAX","NOP","LDY","LDA","LDX","BBS", + "BCS","LDA","LDA","NOP","LDY","LDA","LDX","SMB","CLV","LDA","TSX","NOP","LDY","LDA","LDX","BBS", + "CPY","CMP","NOP","NOP","CPY","CMP","DEC","SMB","INY","CMP","DEX","WAI","CPY","CMP","DEC","BBS", + "BNE","CMP","CMP","NOP","NOP","CMP","DEC","SMB","CLD","CMP","PHX","STP","NOP","CMP","DEC","BBS", + "CPX","SBC","NOP","NOP","CPX","SBC","INC","SMB","INX","SBC","NOP","NOP","CPX","SBC","INC","BBS", + "BEQ","SBC","SBC","NOP","NOP","SBC","INC","SMB","SED","SBC","PLX","NOP","NOP","SBC","INC","BBS" + }; - static const int am[256] = { - 0x0 , 0xC , 0x2 , 0x0 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x2 , 0x1 , 0x0 , 0x7 , 0x7 , 0x7 , 0xE , - 0x6 , 0xD , 0xB , 0x0 , 0x3 , 0x4 , 0x4 , 0x3 , 0x0 , 0x9 , 0x1 , 0x0 , 0x7 , 0x8 , 0x8 , 0xE , - 0x7 , 0xC , 0x2 , 0x0 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x2 , 0x1 , 0x0 , 0x7 , 0x7 , 0x7 , 0xE , - 0x6 , 0xD , 0xB , 0x0 , 0x4 , 0x4 , 0x4 , 0x3 , 0x0 , 0x9 , 0x1 , 0x0 , 0x8 , 0x8 , 0x8 , 0xE , - 0x0 , 0xC , 0x2 , 0x0 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x2 , 0x1 , 0x0 , 0x7 , 0x7 , 0x7 , 0xE , - 0x6 , 0xD , 0xB , 0x0 , 0x4 , 0x4 , 0x4 , 0x3 , 0x0 , 0x9 , 0x0 , 0x0 , 0x7 , 0x8 , 0x8 , 0xE , - 0x0 , 0xC , 0x2 , 0x0 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x2 , 0x1 , 0x0 , 0xA , 0x7 , 0x7 , 0xE , - 0x6 , 0xD , 0xB , 0x0 , 0x4 , 0x4 , 0x4 , 0x3 , 0x0 , 0x9 , 0x0 , 0x0 , 0xF , 0x8 , 0x8 , 0xE , - 0x6 , 0xC , 0x2 , 0x0 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x2 , 0x0 , 0x0 , 0x7 , 0x7 , 0x7 , 0xE , - 0x6 , 0xD , 0xB , 0x0 , 0x4 , 0x4 , 0x5 , 0x3 , 0x0 , 0x9 , 0x0 , 0x0 , 0x7 , 0x8 , 0x8 , 0xE , - 0x2 , 0xC , 0x2 , 0x0 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x2 , 0x0 , 0x0 , 0x7 , 0x7 , 0x7 , 0xE , - 0x6 , 0xD , 0xB , 0x0 , 0x4 , 0x4 , 0x5 , 0x3 , 0x0 , 0x9 , 0x0 , 0x0 , 0x8 , 0x8 , 0x9 , 0xE , - 0x2 , 0xC , 0x2 , 0x0 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x2 , 0x0 , 0x0 , 0x7 , 0x7 , 0x7 , 0xE , - 0x6 , 0xD , 0xB , 0x0 , 0x4 , 0x4 , 0x4 , 0x3 , 0x0 , 0x9 , 0x0 , 0x0 , 0x7 , 0x8 , 0x8 , 0xE , - 0x2 , 0xC , 0x2 , 0x0 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x2 , 0x0 , 0x0 , 0x7 , 0x7 , 0x7 , 0xE , - 0x6 , 0xD , 0xB , 0x0 , 0x4 , 0x4 , 0x4 , 0x3 , 0x0 , 0x9 , 0x0 , 0x0 , 0x7 , 0x8 , 0x8 , 0xE - }; + static const int am[256] = { + 0x0 , 0xC , 0x2 , 0x0 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x2 , 0x1 , 0x0 , 0x7 , 0x7 , 0x7 , 0xE , + 0x6 , 0xD , 0xB , 0x0 , 0x3 , 0x4 , 0x4 , 0x3 , 0x0 , 0x9 , 0x1 , 0x0 , 0x7 , 0x8 , 0x8 , 0xE , + 0x7 , 0xC , 0x2 , 0x0 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x2 , 0x1 , 0x0 , 0x7 , 0x7 , 0x7 , 0xE , + 0x6 , 0xD , 0xB , 0x0 , 0x4 , 0x4 , 0x4 , 0x3 , 0x0 , 0x9 , 0x1 , 0x0 , 0x8 , 0x8 , 0x8 , 0xE , + 0x0 , 0xC , 0x2 , 0x0 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x2 , 0x1 , 0x0 , 0x7 , 0x7 , 0x7 , 0xE , + 0x6 , 0xD , 0xB , 0x0 , 0x4 , 0x4 , 0x4 , 0x3 , 0x0 , 0x9 , 0x0 , 0x0 , 0x7 , 0x8 , 0x8 , 0xE , + 0x0 , 0xC , 0x2 , 0x0 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x2 , 0x1 , 0x0 , 0xA , 0x7 , 0x7 , 0xE , + 0x6 , 0xD , 0xB , 0x0 , 0x4 , 0x4 , 0x4 , 0x3 , 0x0 , 0x9 , 0x0 , 0x0 , 0xF , 0x8 , 0x8 , 0xE , + 0x6 , 0xC , 0x2 , 0x0 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x2 , 0x0 , 0x0 , 0x7 , 0x7 , 0x7 , 0xE , + 0x6 , 0xD , 0xB , 0x0 , 0x4 , 0x4 , 0x5 , 0x3 , 0x0 , 0x9 , 0x0 , 0x0 , 0x7 , 0x8 , 0x8 , 0xE , + 0x2 , 0xC , 0x2 , 0x0 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x2 , 0x0 , 0x0 , 0x7 , 0x7 , 0x7 , 0xE , + 0x6 , 0xD , 0xB , 0x0 , 0x4 , 0x4 , 0x5 , 0x3 , 0x0 , 0x9 , 0x0 , 0x0 , 0x8 , 0x8 , 0x9 , 0xE , + 0x2 , 0xC , 0x2 , 0x0 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x2 , 0x0 , 0x0 , 0x7 , 0x7 , 0x7 , 0xE , + 0x6 , 0xD , 0xB , 0x0 , 0x4 , 0x4 , 0x4 , 0x3 , 0x0 , 0x9 , 0x0 , 0x0 , 0x7 , 0x8 , 0x8 , 0xE , + 0x2 , 0xC , 0x2 , 0x0 , 0x3 , 0x3 , 0x3 , 0x3 , 0x0 , 0x2 , 0x0 , 0x0 , 0x7 , 0x7 , 0x7 , 0xE , + 0x6 , 0xD , 0xB , 0x0 , 0x4 , 0x4 , 0x4 , 0x3 , 0x0 , 0x9 , 0x0 , 0x0 , 0x7 , 0x8 , 0x8 , 0xE + }; - void puce65c02::dasm(uint16_t address) { // TODO : give the bit# for BBR, BSS, RMB and SMB - uint8_t op = readMem(address); - uint8_t b1 = readMem((address + 1) & 0xFFFF); - uint8_t b2 = readMem((address + 2) & 0xFFFF); - printf("%04X %02X ", address, op); - switch(am[op]) { - case 0x0: printf(" %s ", mn[op] ); break; // implied - case 0x1: printf(" %s A ", mn[op] ); break; // accumulator - case 0x2: printf("%02X %s #$%02X ", b1, mn[op],b1 ); break; // immediate - case 0x3: printf("%02X %s $%02X ", b1, mn[op],b1 ); break; // zero page - case 0x4: printf("%02X %s $%02X,X ", b1, mn[op],b1 ); break; // zero page, X indexed - case 0x5: printf("%02X %s $%02X,Y ", b1, mn[op],b1 ); break; // zero page, Y indexed - case 0x6: printf("%02X %s $%02X ", b1, mn[op],b1 ); break; // relative - case 0xB: printf("%02X %s ($%02X) ", b1, mn[op],b1 ); break; // izp ($00) - case 0xC: printf("%02X %s ($%02X,X) ", b1, mn[op],b1 ); break; // X indexed, indirect - case 0xD: printf("%02X %s ($%02X),Y ", b1, mn[op],b1 ); break; // indirect, Y indexed - case 0x7: printf("%02X%02X %s $%02X%02X ",b1,b2,mn[op],b2,b1); break; // absolute - case 0x8: printf("%02X%02X %s $%02X%02X,X ",b1,b2,mn[op],b2,b1); break; // absolute, X indexed - case 0x9: printf("%02X%02X %s $%02X%02X,Y ",b1,b2,mn[op],b2,b1); break; // absolute, Y indexed - case 0xA: printf("%02X%02X %s ($%02X%02X) ",b1,b2,mn[op],b2,b1); break; // indirect - case 0xF: printf("%02X%02X %s ($%02X%02X,X)",b1,b2,mn[op],b2,b1); break; // iax ($0000,X) - case 0xE: printf("%02X%02X %s $%02X,$%02X ",b1,b2,mn[op],b2,b1); break; // zpr $00,$00 - } - return; - } + void puce65c02::dasm(uint16_t address) { // TODO : give the bit# for BBR, BSS, RMB and SMB + uint8_t op = readMem(address); + uint8_t b1 = readMem((address + 1) & 0xFFFF); + uint8_t b2 = readMem((address + 2) & 0xFFFF); + printf("%04X %02X ", address, op); + switch(am[op]) { + case 0x0: printf(" %s ", mn[op] ); break; // implied + case 0x1: printf(" %s A ", mn[op] ); break; // accumulator + case 0x2: printf("%02X %s #$%02X ", b1, mn[op],b1 ); break; // immediate + case 0x3: printf("%02X %s $%02X ", b1, mn[op],b1 ); break; // zero page + case 0x4: printf("%02X %s $%02X,X ", b1, mn[op],b1 ); break; // zero page, X indexed + case 0x5: printf("%02X %s $%02X,Y ", b1, mn[op],b1 ); break; // zero page, Y indexed + case 0x6: printf("%02X %s $%02X ", b1, mn[op],b1 ); break; // relative + case 0xB: printf("%02X %s ($%02X) ", b1, mn[op],b1 ); break; // izp ($00) + case 0xC: printf("%02X %s ($%02X,X) ", b1, mn[op],b1 ); break; // X indexed, indirect + case 0xD: printf("%02X %s ($%02X),Y ", b1, mn[op],b1 ); break; // indirect, Y indexed + case 0x7: printf("%02X%02X %s $%02X%02X ",b1,b2,mn[op],b2,b1); break; // absolute + case 0x8: printf("%02X%02X %s $%02X%02X,X ",b1,b2,mn[op],b2,b1); break; // absolute, X indexed + case 0x9: printf("%02X%02X %s $%02X%02X,Y ",b1,b2,mn[op],b2,b1); break; // absolute, Y indexed + case 0xA: printf("%02X%02X %s ($%02X%02X) ",b1,b2,mn[op],b2,b1); break; // indirect + case 0xF: printf("%02X%02X %s ($%02X%02X,X)",b1,b2,mn[op],b2,b1); break; // iax ($0000,X) + case 0xE: printf("%02X%02X %s $%02X,$%02X ",b1,b2,mn[op],b2,b1); break; // zpr $00,$00 + } + return; + } - int puce65c02::getCode(uint16_t address, char* buffer, int size, int numLines) { - int consumed = 0; - int remaining = size; + int puce65c02::getCode(uint16_t address, char* buffer, int size, int numLines) { + int consumed = 0; + int remaining = size; - for (int i=0; iticks = 0; // we won't measure the 7 ticks the RESET took above - unsigned long long int oldticks = cpu->ticks; + puce65c02 *cpu = new puce65c02(0x1000); // instantiate, reset the cpu and set PC to 0x1000 + cpu->ticks = 0; // we won't measure the 7 ticks the RESET took above + unsigned long long int oldticks = cpu->ticks; - do { - cpu->dasm(cpu->PC); - printf(" "); - cpu->exec(1); - cpu->printRegs(); - printf(" Cycles: %llu Total: %llu\n", cpu->ticks - oldticks, cpu->ticks); + do { + cpu->dasm(cpu->PC); + printf(" "); + cpu->exec(1); + cpu->printRegs(); + printf(" Cycles: %llu Total: %llu\n", cpu->ticks - oldticks, cpu->ticks); - oldticks = cpu->ticks; - } while(cpu->ticks < 1143); + oldticks = cpu->ticks; + } while(cpu->ticks < 1143); #else - // Running the two functionnal tests : - const char *filename = "6502_functional_test.bin"; - FILE *f = fopen(filename, "rb"); - if (!f || fread(RAM, 1, 65536, f) != 65536) { - printf("ERROR : can't load Klaus Dormann's functonnal tests binary file %s\n", filename); - return(0); - } - fclose(f); + // Running the two functionnal tests : + const char *filename = "6502_functional_test.bin"; + FILE *f = fopen(filename, "rb"); + if (!f || fread(RAM, 1, 65536, f) != 65536) { + printf("ERROR : can't load Klaus Dormann's functonnal tests binary file %s\n", filename); + return(0); + } + fclose(f); - puce65c02 *cpu = new puce65c02(0x400); // instantiate, reset the cpu and set PC to 0x400 + puce65c02 *cpu = new puce65c02(0x400); // instantiate, reset the cpu and set PC to 0x400 #if VERBOSE - unsigned long long int oldticks = cpu->ticks; + unsigned long long int oldticks = cpu->ticks; #endif - uint16_t oldPC = 0x400, newPC = 0x400; // to detect loops (BNE $FE) when error occurs + uint16_t oldPC = 0x400, newPC = 0x400; // to detect loops (BNE $FE) when error occurs - while(newPC != 0x3469) { + while(newPC != 0x3469) { #if VERBOSE - cpu->dasm(newPC); - printf(" "); + cpu->dasm(newPC); + printf(" "); #endif - newPC = cpu->exec(1); + newPC = cpu->exec(1); #if VERBOSE - cpu->printRegs(); - printf(" Cycles: %llu Total: %llu\n", cpu->ticks - oldticks, cpu->ticks); - oldticks = cpu->ticks; + cpu->printRegs(); + printf(" Cycles: %llu Total: %llu\n", cpu->ticks - oldticks, cpu->ticks); + oldticks = cpu->ticks; #endif - if (newPC == oldPC ) { - printf("\n\nLoop detected @ %04X - Press ENTER to proceed with next test or CTRL to abort\n\n", newPC); - getchar(); - cpu->setPC(newPC + 2); // step out the loop - } - oldPC = newPC; - } - printf("\nSUCCESS : Reached end of 6502_functional_test @ 0x3469 after %llu clock cycles\n", cpu->ticks); + if (newPC == oldPC ) { + printf("\n\nLoop detected @ %04X - Press ENTER to proceed with next test or CTRL to abort\n\n", newPC); + getchar(); + cpu->setPC(newPC + 2); // step out the loop + } + oldPC = newPC; + } + printf("\nSUCCESS : Reached end of 6502_functional_test @ 0x3469 after %llu clock cycles\n", cpu->ticks); - const char *filename2 = "65C02_extended_opcodes_test.bin"; - f = fopen(filename2, "rb"); - if (!f || fread(RAM, 1, 65536, f) != 65536) { - printf("ERROR : can't load 65c02 Klaus Dormann's functonnal tests binary file %s\n", filename2); - return(0); - } - fclose(f); + const char *filename2 = "65C02_extended_opcodes_test.bin"; + f = fopen(filename2, "rb"); + if (!f || fread(RAM, 1, 65536, f) != 65536) { + printf("ERROR : can't load 65c02 Klaus Dormann's functonnal tests binary file %s\n", filename2); + return(0); + } + fclose(f); - cpu->RST(); - cpu->setPC(0x400); - oldPC = newPC = 0x400; + cpu->RST(); + cpu->setPC(0x400); + oldPC = newPC = 0x400; #if VERBOSE - oldticks = cpu->ticks; + oldticks = cpu->ticks; #endif - while(newPC != 0x24f1) { + while(newPC != 0x24f1) { #if VERBOSE - cpu->dasm(newPC); - printf(" "); + cpu->dasm(newPC); + printf(" "); #endif - newPC = cpu->exec(1); + newPC = cpu->exec(1); #if VERBOSE - cpu->printRegs(); - printf(" Cycles: %llu Total: %llu\n", cpu->ticks - oldticks, cpu->ticks); - oldticks = cpu->ticks; + cpu->printRegs(); + printf(" Cycles: %llu Total: %llu\n", cpu->ticks - oldticks, cpu->ticks); + oldticks = cpu->ticks; #endif - if (newPC == oldPC ) { - printf("\n\nLoop detected @ %04X - Press ENTER to proceed with next test or CTRL to abort\n\n", newPC); - getchar(); - cpu->setPC(newPC + 2); // step out the loop - } - oldPC = newPC; - } - printf("\nSUCCESS : Reached end of 65C02_extended_opcodes_test @ 0x24f1 after %llu clock cycles\n", cpu->ticks); + if (newPC == oldPC ) { + printf("\n\nLoop detected @ %04X - Press ENTER to proceed with next test or CTRL to abort\n\n", newPC); + getchar(); + cpu->setPC(newPC + 2); // step out the loop + } + oldPC = newPC; + } + printf("\nSUCCESS : Reached end of 65C02_extended_opcodes_test @ 0x24f1 after %llu clock cycles\n", cpu->ticks); #endif - return(0); - } -#endif + return(0); + } +#endif