/*---------------------------------------------------------------------------- * cpu 6502.c: Main file CPU 6502 (NES CPU) Emulator. * *---------------------------------------------------------------------------- * nes: Nintendo Entertainment System Emulator. * * Created by Jean-Baptiste Nadal on 12/02/08. * Copyright 2008. All rights reserved. *---------------------------------------------------------------------------- */ #include #include #include "opcodes.h" #include "cpu6502.h" #include "debug.h" /* TODO Remove this trace. */ # define PRINT_OP(a) /******************************************************* * Push the parameter on the stack. */ void Push (nes_cpu6502_t *cpu, uint8_t value) { cpu->memWrite (STACK_END + cpu->R_Stack, value); DEBUG2 (("Push a %x = %x\n", cpu->R_Stack, value)); cpu->R_Stack--; } /******************************************************* * Pop the parameter from the stack. */ uint8_t Pop (nes_cpu6502_t *cpu) { cpu->R_Stack++; return cpu->memRead (STACK_END + cpu->R_Stack); } /******************************************************* * This function reset the target Machine. */ int cpuReset (nes_cpu6502_t *cpu) { int result = 0; /* Reset the CPU. */ cpu->a = 0; cpu->x = 0; cpu->y = 0; cpu->R_Status = 0; cpu->R_Stack = STACK_START; /* Set the PC. */ /* -Low part. */ cpu->pc = cpu->memRead (0xFFFC); /* -Hight part. */ cpu->pc |= cpu->memRead (0xFFFD) << 8; return result; } /******************************************************* * This function Launch an nmi. */ void NMI_Interrupt (nes_cpu6502_t *cpu) { uint8_t param8_1, param8_2; param8_1 = cpu->memRead (0x2000); if (param8_1 & 0x80) { /*Push PC. */ param8_1 = (cpu->pc & 0xFF00) >> 8; param8_2 = (cpu->pc & 0xFF); Push (cpu, param8_1); Push (cpu, param8_2); /* Push Status. */ Push (cpu, cpu->R_Status); /* Jump to NMI function. */ DEBUG0 (("switch to NMI.\n")); /* Set the PC. */ /* -Low part. */ cpu->pc = cpu->memRead (0xFFFA); /* -Hight part. */ cpu->pc |= cpu->memRead (0xFFFB) << 8; /* The nmi switch take 7 cycles. */ cpu->nbCycles -= 7; } } /******************************************************* * Set a value to the register A. */ void SetA (nes_cpu6502_t *cpu, uint8_t val) { cpu->a = val; if (cpu->alert.active == 1) { /* Debugger Mode, we check if an alert is set on this * register, and if the value correspond to the alert. */ if (cpu->alert.a == cpu->a) { fprintf (stdout, "cpu.alert.a = val\n"); debugger_stop (); } } } /******************************************************* * Decrement the Value of the register A. */ void DecA (nes_cpu6502_t *cpu) { cpu->a--; if (cpu->alert.active == 1) { /* Debugger Mode, we check if an alert is set on this * register, and if the value correspond to the alert. */ if (cpu->alert.a == cpu->a) { fprintf (stdout, "cpu.alert.a = val\n"); debugger_stop (); } } } /******************************************************* * Increment the Value of the register A. */ void IncA (nes_cpu6502_t *cpu) { cpu->a++; if (cpu->alert.active == 1) { /* Debugger Mode, we check if an alert is set on this * register, and if the value correspond to the alert. */ if (cpu->alert.a == cpu->a) { fprintf (stdout, "cpu.alert.a = val\n"); debugger_stop (); } } } /******************************************************* * Set a value to the register X. */ void SetX (nes_cpu6502_t *cpu, uint8_t val) { cpu->x = val; if (cpu->alert.active == 1) { /* Debugger Mode, we check if an alert is set on this * register, and if the value correspond to the alert. */ if (cpu->alert.x == cpu->x) { fprintf (stdout, "cpu.alert.x = val\n"); debugger_stop (); } } } /******************************************************* * Decrement the Value of the register X. */ void DecX (nes_cpu6502_t *cpu) { cpu->x--; if (cpu->alert.active == 1) { /* Debugger Mode, we check if an alert is set on this * register, and if the value correspond to the alert. */ if (cpu->alert.x == cpu->x) { fprintf (stdout, "cpu.alert.x = val\n"); debugger_stop (); } } } /******************************************************* * Increment the Value of the register X. */ void IncX (nes_cpu6502_t *cpu) { cpu->x++; if (cpu->alert.active == 1) { /* Debugger Mode, we check if an alert is set on this * register, and if the value correspond to the alert. */ if (cpu->alert.x == cpu->x) { fprintf (stdout, "cpu.alert.x = val\n"); debugger_stop (); } } } /******************************************************* * Set a value to the register Y. */ void SetY (nes_cpu6502_t *cpu, uint8_t val) { cpu->y = val; if (cpu->alert.active == 1) { /* Debugger Mode, we check if an alert is set on this * register, and if the value correspond to the alert. */ if (cpu->alert.y == cpu->y) { fprintf (stdout, "cpu.alert.y = val\n"); debugger_stop (); } } } /******************************************************* * Decrement the Value of the register Y. */ void DecY (nes_cpu6502_t *cpu) { cpu->y--; if (cpu->alert.active == 1) { /* Debugger Mode, we check if an alert is set on this * register, and if the value correspond to the alert. */ if (cpu->alert.y == cpu->y) { fprintf (stdout, "cpu.alert.y = val\n"); debugger_stop (); } } } /******************************************************* * Increment the Value of the register Y. */ void IncY (nes_cpu6502_t *cpu) { cpu->y++; if (cpu->alert.active == 1) { /* Debugger Mode, we check if an alert is set on this * register, and if the value correspond to the alert. */ if (cpu->alert.y == cpu->y) { fprintf (stdout, "cpu.alert.y = val\n"); debugger_stop (); } } } /******************************************************* * Init the CPU. */ void bitset (uint8_t *reg, uint8_t flag, uint8_t val) { if (val == 0) { *reg &= ~(1 << flag); } else { *reg |= (1 << flag); } } /******************************************************* * This function used to DEBUG to show the registers. */ void printRegs (nes_cpu6502_t *cpu) { char buffer[11]; sprintf (buffer, "[........]"); if (((cpu->R_Status >> STATUS_FLAG_N) & 0x1) == 1) buffer[1] = 'N'; if (((cpu->R_Status >> STATUS_FLAG_V) & 0x1) == 1) buffer[2] = 'V'; if (((cpu->R_Status >> STATUS_FLAG_B) & 0x1) == 1) buffer[4] = 'B'; if (((cpu->R_Status >> STATUS_FLAG_D) & 0x1) == 1) buffer[5] = 'D'; if (((cpu->R_Status >> STATUS_FLAG_I) & 0x1) == 1) buffer[6] = 'I'; if (((cpu->R_Status >> STATUS_FLAG_Z) & 0x1) == 1) buffer[7] = 'Z'; if (((cpu->R_Status >> STATUS_FLAG_C) & 0x1) == 1) buffer[8] = 'C'; fprintf (stdout, "A:%2.2x X:%2.2x Y:%2.2x S:%4.4x, PC:%4.4x Flags:%s," " Stack[%2.2x, %2.2x, %2.2x]\n", cpu->a, cpu->x, cpu->y, cpu->R_Stack + 0x100, cpu->pc, buffer, cpu->memRead (STACK_END + (uint8_t)(cpu->R_Stack+1)), cpu->memRead (STACK_END + (uint8_t)(cpu->R_Stack+2)), cpu->memRead (STACK_END + (uint8_t)(cpu->R_Stack+3))); #if 0 fprintf (stdout, "A:%2.2x X:%2.2x Y:%2.2x S:%4.4x, PC:%4.4x Flags:%s," " Stack[%2.2x, %2.2x, %2.2x], %.3d, %.3d\n", emul.cpu.a, emul.cpu.x, emul.cpu.y, emul.cpu.R_Stack + 0x100, emul.cpu.pc, buffer, emul.memory.segment1 [STACK_END + (uint8_t)(emul.cpu.R_Stack+1)], emul.memory.segment1 [STACK_END + (uint8_t)(emul.cpu.R_Stack+2)], emul.memory.segment1 [STACK_END + (uint8_t)(emul.cpu.R_Stack+3)], emul.nbCycles, emul.nbLines); #endif } /******************************************************* * Init the CPU. */ int cpu6502_init (nes_cpu6502_t *cpu) { int result = 0; return result; } /******************************************************* * Update Flag N and Z of the Status. */ void UpdateFlagsN_Z (nes_cpu6502_t *cpu, uint8_t reg) { uint8_t val; /* Update Flag N. */ if (reg & 0x80) { DEBUG2 (("val 1 donc %x est negatif\n", reg)); val = 1; } else { DEBUG2 (("val 0 donc %x est positif\n", reg)); val = 0; } /* And update. */ bitset (&cpu->R_Status, STATUS_FLAG_N, val); /* Update Flag Z. */ if (reg == 0) { val = 1; } else { val = 0; } /* And update. */ bitset (&cpu->R_Status, STATUS_FLAG_Z, val); DEBUG2 (("Update FlagN et Z-Done (%d)\n", cpu->R_Status)); } /******************************************************* * Update Flag C of the Status. */ void UpdateFlagsC_L (nes_cpu6502_t *cpu, uint8_t reg) { if (reg & 0x80) { bitset (&cpu->R_Status, STATUS_FLAG_C, 1); } else { bitset (&cpu->R_Status, STATUS_FLAG_C, 0); } } /*******************************************************/ void UpdateFlagsC_R (nes_cpu6502_t *cpu, uint8_t reg) { if (reg & 0x01) { bitset (&cpu->R_Status, STATUS_FLAG_C, 1); } else { bitset (&cpu->R_Status, STATUS_FLAG_C, 0); } } /******************************************************* * Update Flag I of the Status. */ void UpdateFlagsI (nes_cpu6502_t *cpu, uint8_t value) { bitset (&cpu->R_Status, STATUS_FLAG_I, value); DEBUG2 (("Update FlagI-Done (%d)\n", cpu->R_Status)); } /******************************************************* * Update Flag D of the Status. */ void UpdateFlagsD (nes_cpu6502_t *cpu, uint8_t value) { bitset (&cpu->R_Status, STATUS_FLAG_D, value); DEBUG2 (("Update FlagD-Done (%d)\n", cpu->R_Status)); } /******************************************************* * Make a Jump to the specified address if the status * bit N is equal to 0. OtherWise go to the next instruction. */ void BranchOnPlus (nes_cpu6502_t *cpu, int8_t index) { if (((cpu->R_Status >> STATUS_FLAG_N) & 0x1) == 0) { DEBUG2 (("On doit brancher\n a :%x(%d)\n", cpu->pc + (int8_t)index, index)); cpu->pc += (int8_t)index; cpu->nbCycles--; } else { DEBUG2 (("Pas la peine de brancher N vaut 1\n")); } } /******************************************************* * Make a Jump to the specified address if the status * bit N is equal to 1. OtherWise go to the next instruction. */ void BranchIfMinus (nes_cpu6502_t *cpu, int8_t index) { if (((cpu->R_Status >> STATUS_FLAG_N) & 0x1) == 1) { DEBUG2 (("On doit brancher\n a :%x(%d)\n", cpu->pc + (int8_t)index, index)); cpu->pc += (int8_t)index; cpu->nbCycles--; } else { DEBUG2 (("Pas la peine de brancher N vaut 0\n")); } } /******************************************************* * Compare A and the Operande and save the result in the * Status flags like that: * * If A < opérande -> N=1, Z=0, C=0 * If A = opérande -> N=0, Z=1, C=1 * If A > opérande -> N=0, Z=0, C=1 */ void CompareReg (nes_cpu6502_t *cpu, uint8_t regValue, uint8_t operande) { DEBUG2 (("Compare %d et %d\n", regValue, operande)); int16_t result; /* Substract the two operande to make know the result of the compare. */ result = regValue - operande; /* And Update N and Z Flags. */ UpdateFlagsN_Z (cpu, result); /* Update Carry status. */ if (result & 0xff00) { /* Carry Set. */ bitset (&cpu->R_Status, STATUS_FLAG_C, 0); } else { bitset (&cpu->R_Status, STATUS_FLAG_C, 1); } } /******************************************************* * Branch to the Address given as parameter if the Carry is set. * */ void BranchIfCarrySet (nes_cpu6502_t *cpu, uint8_t index) { if (((cpu->R_Status >> STATUS_FLAG_C) & 0x1) == 1) { DEBUG2 (("Carry is set, Jump to :%x\n", cpu->pc + (int8_t)index)); cpu->pc += (int8_t)index; cpu->nbCycles--; } else { DEBUG2 (("Pas la peine de brancher C vaut 0\n")); } } /******************************************************* * Branch to the Address given as parameter if the Carry is clear. * */ void BranchIfCarryClear (nes_cpu6502_t *cpu, uint8_t index) { if (((cpu->R_Status >> STATUS_FLAG_C) & 0x1) == 0) { DEBUG2 (("Carry is set, Jump to :%x\n", cpu->pc + (int8_t)index)); cpu->pc += (int8_t)index; cpu->nbCycles--; } else { DEBUG2 (("Pas la peine de brancher C vaut 1\n")); } } /******************************************************* * Branch to the Address given as parameter if the Overflow * flag is clear. */ void BranchIfOverflowClear (nes_cpu6502_t *cpu, uint8_t index) { if (((cpu->R_Status >> STATUS_FLAG_V) & 0x1) == 0) { DEBUG2 (("Overflow is Clear, Jump to :%x\n", cpu->pc + (int8_t)index)); cpu->pc += (int8_t)index; cpu->nbCycles--; } else { DEBUG2 (("Pas la peine de brancher V vaut 1\n")); } } /******************************************************* * Branch to the Address given as parameter if the Overflow is set. * */ void BranchIfOverflowSet (nes_cpu6502_t *cpu, uint8_t index) { if (((cpu->R_Status >> STATUS_FLAG_V) & 0x1) == 1) { DEBUG2 (("Overflow is set, Jump to :%x\n", cpu->pc + (int8_t)index)); cpu->pc += (int8_t)index; cpu->nbCycles--; } else { DEBUG2 (("Pas la peine de brancher V vaut 0\n")); } } /******************************************************* * Branch to the Address given as parameter if the * Zero status is equal to 0. */ void BranchIfNotEqual (nes_cpu6502_t *cpu, uint8_t index) { if (((cpu->R_Status >> STATUS_FLAG_Z) & 0x1) == 0) { DEBUG2 (("status Zero = 0, Jump to :%x\n", cpu->pc + (int8_t)index)); cpu->pc += (int8_t)index; cpu->nbCycles--; } else { DEBUG2 (("Pas la peine de brancher Z vaut 1\n")); } } /******************************************************* * Branch to the Address given as parameter if the * Zero status is equal to 1. */ void BranchIfEqual (nes_cpu6502_t *cpu, uint8_t index) { if (((cpu->R_Status >> STATUS_FLAG_Z) & 0x1) == 1) { DEBUG2 (("status Zero = 1, Jump to :%x\n", cpu->pc + (int8_t)index)); cpu->pc += (int8_t)index; cpu->nbCycles--; } } /******************************************************* * Add with Carry. */ void AddWithCarry (nes_cpu6502_t *cpu, uint8_t operande) { uint16_t value; uint8_t value2, value3; value = cpu->a + operande + (cpu->R_Status & FLAG_C); value2 = cpu->a ^ operande; /* Update Carry status. */ if (value & 0xff00) { /* Carry Set. */ bitset (&cpu->R_Status, STATUS_FLAG_C, 1); } else { bitset (&cpu->R_Status, STATUS_FLAG_C, 0); } /* Update V */ value2 = ~value2; value3 = cpu->a ^ (value & 0xFF); /* Overflow */ bitset (&cpu->R_Status, STATUS_FLAG_V, ((value2 & value3) & 0x80)>>7); /* Update the register. */ SetA (cpu, value & 0xff); /* And Update N and Z Flags. */ UpdateFlagsN_Z (cpu, cpu->a); } /******************************************************* * Substract with Carry. */ void SubstractWithCarry (nes_cpu6502_t *cpu, uint8_t operande) { uint16_t value; uint8_t value2, value3; value = cpu->a - operande - (~cpu->R_Status & (1 << STATUS_FLAG_C)); value2 = cpu->a ^ operande; DEBUG2 (("value = a(%x) - (%x) - (%x)\n", cpu->a, operande, (~cpu->R_Status & (1 << STATUS_FLAG_C)))); /* Update Carry status. */ if (value & 0xff00) { /* Carry Set. */ bitset (&cpu->R_Status, STATUS_FLAG_C, 0); } else { bitset (&cpu->R_Status, STATUS_FLAG_C, 1); } /* Update V */ value3 = cpu->a ^ (value & 0xFF); /* Overflow */ bitset (&cpu->R_Status, STATUS_FLAG_V, ((value2 & value3) & 0x80)>>7); /* Update the register. */ SetA (cpu, value & 0xff); /* And Update N and Z Flags. */ UpdateFlagsN_Z (cpu, cpu->a); } /******************************************************* * Make a Logical AND test between the data at the adress * given as parameter and the A register. * * Affected Flags: N,V,Z */ void Bit_Test (nes_cpu6502_t *cpu, uint16_t addr) { uint8_t RegValue = cpu->memRead (addr); DEBUG2 (("BITest: %d & %d \n", cpu->a, value)); /* Update Z */ if ((cpu->a & RegValue) == 0) { bitset (&cpu->R_Status, STATUS_FLAG_Z, 1); } else { bitset (&cpu->R_Status, STATUS_FLAG_Z, 0); } /* Update N */ if (RegValue & 0x80) { /* Negative */ bitset (&cpu->R_Status, STATUS_FLAG_N, 1); } else { bitset (&cpu->R_Status, STATUS_FLAG_N, 0); } /* Update V */ if (RegValue & 0x40) { /* Overflow */ bitset (&cpu->R_Status, STATUS_FLAG_V, 1); } else { bitset (&cpu->R_Status, STATUS_FLAG_V, 0); } } /******************************************************* * Execute the OpCode. */ int cpu6502_execOpCode (nes_cpu6502_t *cpu, uint8_t opcode) { int result = 0; uint16_t param16, param16_2, value; uint8_t param8_1, param8_2, param8_3, tmp; switch (opcode) { case OP_CODE_BRK: /* 0x00 - Break. Soft Interrupt. */ if (((cpu->R_Status >> STATUS_FLAG_I) & 0x1) == 0) { /*Push PC. */ param8_1 = (cpu->pc & 0xFF00) >> 8; param8_2 = (cpu->pc & 0xFF); Push (cpu, param8_1); Push (cpu, param8_2); /* Push Status. */ Push (cpu, cpu->R_Status|B_FLAG); /* Jump to NMI function. */ DEBUG0 (("switch to NMI.\n")); /* -Low part. */ cpu->pc = cpu->memRead (0xFFFF); /* -Hight part. */ cpu->pc |= cpu->memRead (0xFFFE) << 8; } PRINT_OP (("AT PC: [%.2x - BRK]\n", opcode)); cpu->pc++; break; case OP_CODE_SEI: /* 0x78 - SEI - Set Interrupt disable. */ UpdateFlagsI (cpu, 1); PRINT_OP (("AT PC: [%.2x - SEI]\n", opcode)); cpu->pc++; break; case OP_CODE_SED: /* 0xf8 - SED - Set Decimal Mode. */ bitset (&cpu->R_Status, STATUS_FLAG_D, 1); PRINT_OP (("AT PC: [%.2x - SED]\n", opcode)); cpu->pc++; break; case OP_CODE_SEC: /* 0x38 - SEC - Set Carry Flag. */ bitset (&cpu->R_Status, STATUS_FLAG_C, 1); PRINT_OP (("AT PC: [%.2x - SEC]\n", opcode)); cpu->pc++; break; case OP_CODE_CLC: /* 0x18 - CLC - Clear Carry. */ bitset (&cpu->R_Status, STATUS_FLAG_C, 0); PRINT_OP (("AT PC: [%.2x - CLC]\n", opcode)); cpu->pc++; break; case OP_CODE_CLD: /* 0xd8 - Clear Decimal Mode. */ UpdateFlagsD (cpu, 0); PRINT_OP (("AT PC: [%.2x - CLD]\n", opcode)); cpu->pc++; break; case OP_CODE_CLV: /* 0xb8 - Clear Overflow Flag. */ bitset (&cpu->R_Status, STATUS_FLAG_V, 0); PRINT_OP (("AT PC: [%.2x - CLV]\n", opcode)); cpu->pc++; break; case OP_CODE_LDA_1: /* 0xa9 - LDA #aa */ SetA (cpu, cpu->memRead (++cpu->pc)); UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - LDA #$%.2x]\n", opcode, cpu->a)); cpu->pc++; break; case OP_CODE_LDA_2: /* 0xa5 - LDA $aa */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Read Value. */ SetA (cpu, cpu->memRead (param8_1)); UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - LDA $%.2x]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_LDA_3: /* 0xb5 - LDA $aa,X */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Read Value. */ SetA (cpu, cpu->memRead ((cpu->x + param8_1) & 0xFF)); UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - LDA $%.2x,X]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_LDA_4: /* 0xad - LDA $aaaa */ /* Read 16 bits Parameter. */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; SetA (cpu, cpu->memRead (param16)); UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - LDA $%.4x]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_LDA_5: /* 0xbd - LDA $aaaa, X */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; SetA (cpu, cpu->memRead (cpu->x + param16)); UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - LDA $%.4x,X]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_LDA_6: /* 0xb9 - LDA $aaaa, Y */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; SetA (cpu, cpu->memRead (cpu->y + param16)); UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - LDA $%.4x,Y]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_LDA_7: /* 0xa1 - LDA ($aa,X) */ /* Read Parameter */ param8_1 = cpu->memRead (++cpu->pc); /* -Low part. */ param16 = cpu->memRead ((param8_1 + cpu->x) & 0xFF); /* -Hight part. */ param16 |= cpu->memRead ((param8_1 + cpu->x + 1) & 0xFF) << 8; SetA (cpu, cpu->memRead (param16)); UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - LDA ($%.2x,X)]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_LDA_8: /* 0xb1 - LDA ($aa),Y */ /* Read Parameter */ param8_1 = cpu->memRead (++cpu->pc); /* -Low part. */ param16 = cpu->memRead (param8_1); /* -Hight part. */ param16 |= cpu->memRead ((param8_1 + 1) & 0xFF) << 8; SetA (cpu, cpu->memRead (param16 + cpu->y)); UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - LDA ($%.2x),Y]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_LDX_1: /* 0xa2 - LDX #aa */ SetX (cpu, cpu->memRead (++cpu->pc)); UpdateFlagsN_Z (cpu, cpu->x); PRINT_OP (("AT PC: [%.2x - LDX #$%.2x]\n", opcode, cpu->x)); cpu->pc++; break; case OP_CODE_LDX_2: /* 0xa6 - LDX $aa */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Read Value. */ SetX (cpu, cpu->memRead (param8_1)); UpdateFlagsN_Z (cpu, cpu->x); PRINT_OP (("AT PC: [%.2x - LDX $%.2x]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_LDX_3: /* 0xb6 - LDX $aa,Y */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Read Value. */ SetX (cpu, cpu->memRead ((param8_1 + cpu->y) & 0xFF)); UpdateFlagsN_Z (cpu, cpu->x); PRINT_OP (("AT PC: [%.2x - LDX $%.2x,Y]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_LDX_4: /* 0xae - LDX $aaaa */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read the value. */ SetX (cpu, cpu->memRead (param16)); UpdateFlagsN_Z (cpu, cpu->x); PRINT_OP (("AT PC: [%.2x - LDX $%.4x]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_LDX_5: /* 0xbe - LDX $aaaa,Y */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; SetX (cpu, cpu->memRead (param16 + cpu->y)); UpdateFlagsN_Z (cpu, cpu->x); PRINT_OP (("AT PC: [%.2x - LDX $%.4x,Y]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_LDY_1: /* 0xa0 - LDY #aa */ SetY (cpu, cpu->memRead (++cpu->pc)); UpdateFlagsN_Z (cpu, cpu->y); PRINT_OP (("AT PC: [%.2x - LDY #$%.2x]\n", opcode, cpu->y)); cpu->pc++; break; case OP_CODE_LDY_2: /* 0xa4 - LDY $aa */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Read Value. */ SetY (cpu, cpu->memRead (param8_1)); UpdateFlagsN_Z (cpu, cpu->y); PRINT_OP (("AT PC: [%.2x - LDY $%.2x]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_LDY_3: /* 0xb4 - LDY $aa,X */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Add the Value of Reg Y. */ param8_2 = (param8_1 + cpu->x) & 0xFF; /* Read Value. */ SetY (cpu, cpu->memRead (param8_2)); UpdateFlagsN_Z (cpu, cpu->y); PRINT_OP (("AT PC: [%.2x - LDY $%.2x]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_LDY_4: /* 0xac - LDY $aaaa */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read the value. */ SetY (cpu, cpu->memRead (param16)); UpdateFlagsN_Z (cpu, cpu->y); PRINT_OP (("AT PC: [%.2x - LDY $%.4x]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_LDY_5: /* 0xbc - LDY $aaaa,X */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read the value. */ SetY (cpu, cpu->memRead (param16 + cpu->x)); UpdateFlagsN_Z (cpu, cpu->y); PRINT_OP (("AT PC: [%.2x - LDY $%.4x,X]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_STA_1: /* 0x85 - STA $aa */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); cpu->memWrite (param8_1, cpu->a); PRINT_OP (("AT PC: [%.2x - STA $%.2x]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_STA_2: /* 0x95 - STA $aa,X */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Add the Register X. */ param8_2 = (param8_1 + cpu->x) & 0xFF; cpu->memWrite (param8_2, cpu->a); PRINT_OP (("AT PC: [%.2x - STA $%.2x,X]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_STA_3: /* 0x8d - STA $aaaa */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; cpu->memWrite (param16, cpu->a); PRINT_OP (("AT PC: [%.2x - STA $%.4x]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_STA_4: /* 0x9d - STA $aaaa,X */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; cpu->memWrite (param16 + cpu->x, cpu->a); PRINT_OP (("AT PC: [%.2x - STA $%.4x,X]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_STA_5: /* 0x99 - STA $aaaa,Y */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; cpu->memWrite (param16 + cpu->y, cpu->a); PRINT_OP (("AT PC: [%.2x - STA $%.4x,Y]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_STA_6: /* 0x81 - LDA ($aa,X) */ /* Read Parameter */ param8_1 = cpu->memRead (++cpu->pc); /* -Low part. */ param16 = cpu->memRead ((param8_1 + cpu->x) & 0xFF); /* -Hight part. */ param16 |= cpu->memRead ((param8_1 + cpu->x + 1) & 0xFF) << 8; cpu->memWrite (param16, cpu->a); PRINT_OP (("AT PC: [%.2x - STA ($%.2x,X)]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_STA_7: /* 0x91 - STA ($aa),Y */ /* Read Parameter */ param8_1 = cpu->memRead (++cpu->pc); /* -Low part. */ param16 = cpu->memRead (param8_1); /* -Hight part. */ param16 |= cpu->memRead ((param8_1 + 1) & 0xFF) << 8; cpu->memWrite (param16 + cpu->y, cpu->a); PRINT_OP (("AT PC: [%.2x - STA ($%.2x),Y]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_STX_1: /* 0x86 - STX $aa */ /* Read Parameter */ param8_1 = cpu->memRead (++cpu->pc); cpu->memWrite (param8_1, cpu->x); PRINT_OP (("AT PC: [%.2x - STX $%.2x]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_STX_2: /* 0x96 - STX $aa,Y */ /* Read Parameter */ param8_1 = cpu->memRead (++cpu->pc); cpu->memWrite ((param8_1 + cpu->y) & 0xFF, cpu->x); PRINT_OP (("AT PC: [%.2x - STX $%.2x,Y]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_STX_3: /* 0x8e - STX $aaaa */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; cpu->memWrite (param16, cpu->x); PRINT_OP (("AT PC: [%.2x - STX $%.4x]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_STY_1: /* 0x84 - STY $aa */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); cpu->memWrite (param8_1, cpu->y); PRINT_OP (("AT PC: [%.2x - STY $%.2x]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_STY_2: /* 0x94 - STY $aa,X */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); cpu->memWrite ((param8_1 + cpu->x) & 0xFF, cpu->y); PRINT_OP (("AT PC: [%.2x - STY $%.2x,X]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_STY_3: /* 0x8c - STY $aaaa */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; cpu->memWrite (param16, cpu->y); PRINT_OP (("AT PC: [%.2x - STY $%.4x]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_TXS: /* 0x9a - Transfert X to Stack. */ cpu->R_Stack = cpu->x; PRINT_OP (("AT PC: [%.2x - TXS]\n", opcode)); cpu->pc++; break; case OP_CODE_TXA: /* 0x8a - TXA - Transfer X to Register A */ SetA (cpu, cpu->x); UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - TXA]\n", opcode)); cpu->pc++; break; case OP_CODE_TAX: /* 0xaa - TAX - Transfer Accumulator to X */ SetX (cpu, cpu->a); UpdateFlagsN_Z (cpu, cpu->x); PRINT_OP (("AT PC: [%.2x - TAX]\n", opcode)); cpu->pc++; break; case OP_CODE_TYA: /* 0x98 - TYA - Transfer Y to Register A */ SetA (cpu, cpu->y); UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - TYA]\n", opcode)); cpu->pc++; break; case OP_CODE_TAY: /* 0xa8 - TAY - Transfer Accumulator to Y */ SetY (cpu, cpu->a); UpdateFlagsN_Z (cpu, cpu->y); PRINT_OP (("AT PC: [%.2x - TAY]\n", opcode)); cpu->pc++; break; case OP_CODE_TSX: /* 0xba - TSX - Transfer Stack To X */ SetX (cpu, cpu->R_Stack); UpdateFlagsN_Z (cpu, cpu->x); PRINT_OP (("AT PC: [%.2x - TSX]\n", opcode)); cpu->pc++; break; case OP_CODE_BPL: /* 0x10 - BPL - Branch on Plus */ /* Read parameter. */ param8_1 = cpu->memRead (++cpu->pc); cpu->pc++; PRINT_OP (("AT PC: [%.2x - BPL $%.2x]\n", opcode, cpu->pc + (int8_t)param8_1)); BranchOnPlus (cpu, param8_1); break; case OP_CODE_BMI: /* 0x30 - BMI - Branch if Minus */ /* Read parameter. */ param8_1 = cpu->memRead (++cpu->pc); cpu->pc++; PRINT_OP (("AT PC: [%.2x - BMI $%x]\n", opcode, cpu->pc + (int8_t)param8_1)); BranchIfMinus (cpu, param8_1); break; case OP_CODE_CMP_1: /* 0xc9 - CMP #aa */ /* Read parameter. */ param8_1 = cpu->memRead (++cpu->pc); CompareReg (cpu, cpu->a, param8_1); PRINT_OP (("AT PC: [%.2x - CMP #$%.2x]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_CMP_2: /* 0xc5 - CMP $aa */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Read Value. */ param8_2 = cpu->memRead (param8_1); /* Compare value. */ CompareReg (cpu, cpu->a, param8_2); PRINT_OP (("AT PC: [%.2x - CMP $%x]\n", opcode, param8_1)); cpu-> pc++; break; case OP_CODE_CMP_3: /* 0xd5 - CMP $aa,X */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Read Value. */ param8_2 = cpu->memRead ((param8_1 + cpu->x) & 0xFF); /* Compare value. */ CompareReg (cpu, cpu->a, param8_2); PRINT_OP (("AT PC: [%.2x - CMP $%x,X]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_CMP_4: /* 0xcd - CMP $aaaa */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read Value. */ param8_1 = cpu->memRead (param16); /* Compare value. */ CompareReg (cpu, cpu->a, param8_1); PRINT_OP (("AT PC: [%.2x - CMP $%.4x]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_CMP_5: /* 0xdd - CMP $aaaa,X */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read Value. */ param8_1 = cpu->memRead (param16 + cpu->x); /* Compare value. */ CompareReg (cpu, cpu->a, param8_1); PRINT_OP (("AT PC: [%.2x - CMP $%.4x,X]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_CMP_6: /* 0xd9 - CMP $aaaa,Y */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read Value. */ param8_1 = cpu->memRead (param16 + cpu->y); /* Compare value. */ CompareReg (cpu, cpu->a, param8_1); PRINT_OP (("AT PC: [%.2x - CMP $%.4x,Y]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_CMP_7: /* 0xc1 - CMP ($aa,X) */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* -Low part. */ param16 = cpu->memRead ((param8_1 + cpu->x) & 0xFF); /* -Hight part. */ param16 |= cpu->memRead ((param8_1 + cpu->x + 1) & 0xFF) << 8; /* Read Value. */ param8_2 = cpu->memRead (param16); /* Compare value. */ CompareReg (cpu, cpu->a, param8_2); PRINT_OP (("AT PC: [%.2x - CMP ($%x,X)]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_CMP_8: /* 0xd1 - CMP ($aa),Y */ /* Read Parameter */ param8_1 = cpu->memRead (++cpu->pc); /* -Low part. */ param16 = cpu->memRead (param8_1); /* -Hight part. */ param16 |= cpu->memRead ((param8_1 + 1) & 0xFF) << 8; /* Read Value. */ param8_2 = cpu->memRead (param16 + cpu->y); /* Compare value. */ CompareReg (cpu, cpu->a, param8_2); PRINT_OP (("AT PC: [%.2x - CMP ($%x),Y]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_CPX_1: /* 0xe0 - CPX #aa */ param8_1 = cpu->memRead (++cpu->pc); CompareReg (cpu, cpu->x, param8_1); PRINT_OP (("AT PC: [%.2x - CPX #$%.2x]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_CPX_2: /* 0xe4 - CPX $aa */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Read Value. */ param8_2 = cpu->memRead (param8_1); CompareReg (cpu, cpu->x, param8_2); PRINT_OP (("AT PC: [%.2x - CPX $%.2x]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_CPX_3: /* 0xec - CPX $aaaa */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read Value. */ param8_2 = cpu->memRead (param16); CompareReg (cpu, cpu->x, param8_2); PRINT_OP (("AT PC: [%.2x - CPX $%.4x]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_CPY_1: /* 0xc0 - CPY #aa */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); CompareReg (cpu, cpu->y, param8_1); PRINT_OP (("AT PC: [%.2x - CPY #$%.2x]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_CPY_2: /* 0xc4 - CPY $aa */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Read Value. */ param8_2 = cpu->memRead (param8_1); CompareReg (cpu, cpu->y, param8_2); PRINT_OP (("AT PC: [%.2x - CPY $%.2x]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_CPY_3: /* 0xcc - CPY $aaaa */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read Value. */ param8_2 = cpu->memRead (param16); CompareReg (cpu, cpu->y, param8_2); PRINT_OP (("AT PC: [%.2x - CPY $%.4x]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_ORA_1: /* 0x09 - ORA #aa */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); value = cpu->a; value |= param8_1; SetA (cpu, value); UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - ORA #$%.2x]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_ORA_2: /* 0x05 - ORA $aa */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Read Value. */ param8_2 = cpu->memRead (param8_1); value = cpu->a; value |= param8_2; SetA (cpu, value); UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - ORA $%.2x]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_ORA_3: /* 0x15 - ORA $aa,X */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Read Value. */ param8_2 = cpu->memRead ((param8_1 + cpu->x) & 0xFF); value = cpu->a; value |= param8_2; SetA (cpu, value); UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - ORA $%.2x,X]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_ORA_4: /* 0x0d - ORA $aaaa */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read the operande. */ param8_1 = cpu->memRead (param16); value = cpu->a; value |= param8_2; SetA (cpu, value); UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - ORA $%.4x]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_ORA_5: /* 0x1d - ORA $aaaa,X */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read the operande. */ param8_1 = cpu->memRead (param16 + cpu->x); value = cpu->a; value |= param8_2; SetA (cpu, value); UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - ORA $%.4x,X]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_ORA_6: /* 0x19 - ORA $aaaa,Y */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read the operande. */ param8_1 = cpu->memRead (param16 + cpu->y); value = cpu->a; value |= param8_2; SetA (cpu, value); UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - ORA $%.4x,Y]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_ORA_7: /* 0x01 - ORA ($aa,X) */ param8_1 = cpu->memRead (++cpu->pc); /* -Low part. */ param16 = cpu->memRead ((param8_1 + cpu->x) & 0xFF); /* -Hight part. */ param16 |= cpu->memRead ((param8_1 + cpu->x + 1) & 0xFF) << 8; /* Read Value. */ param8_2 = cpu->memRead (param16); value = cpu->a; value |= param8_2; SetA (cpu, value); UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - ORA ($%.2x,X)]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_ORA_8: /* 0x11 - ORA ($aa),Y */ /* Read Parameter */ param8_1 = cpu->memRead (++cpu->pc); /* -Low part. */ param16 = cpu->memRead (param8_1); /* -Hight part. */ param16 |= cpu->memRead ((param8_1 + 1) & 0xFF) << 8; /* Read Value. */ param8_2 = cpu->memRead (param16 + cpu->y); value = cpu->a; value |= param8_2; SetA (cpu, value); UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - ORA ($%.2x),Y]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_AND_1: /* 0x29 - AND #aa */ /* Read Parameter */ param8_1 = cpu->memRead (++cpu->pc); value = cpu->a & param8_1; SetA (cpu, value); UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - AND #$%.2x]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_AND_2: /* 0x25 - AND $aa */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Read Value. */ param8_2 = cpu->memRead (param8_1); /* Make the Addition. */ value = cpu->a & param8_2; SetA (cpu, value); UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - AND $%.2x]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_AND_3: /* 0x35 - AND $aa,X */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Read Value. */ param8_2 = cpu->memRead ((param8_1 + cpu->x) & 0xFF); /* Make the Addition. */ value = cpu->a & param8_2; SetA (cpu, value); UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - AND $%.2x,X]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_AND_4: /* 0x2d - AND $aaaa */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read the operande. */ param8_1 = cpu->memRead (param16); value = cpu->a & param8_1; SetA (cpu, value); UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - AND $%.4x]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_AND_5: /* 0x3d - AND $aaaa,X */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read the operande. */ param8_1 = cpu->memRead (param16 + cpu->x); value = cpu->a & param8_1; SetA (cpu, value); UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - AND $%.4x,X]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_AND_6: /* 0x39 - AND $aaaa,Y */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read the operande. */ param8_1 = cpu->memRead (param16 + cpu->y); value = cpu->a & param8_1; SetA (cpu, value); UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - AND $%.4x,Y]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_AND_7: /*0x21 - AND ($aa,X) */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* -Low part. */ param16 = cpu->memRead ((param8_1 + cpu->x) & 0xFF); /* -Hight part. */ param16 |= cpu->memRead ((param8_1 + cpu->x + 1) & 0xFF) << 8; /* Read Value. */ param8_2 = cpu->memRead (param16); /* Make the Addition. */ value = cpu->a & param8_2; SetA (cpu, value); UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - AND ($%.2x,X)]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_AND_8: /* 0x31 - AND ($aa),Y */ /* Read Parameter */ param8_1 = cpu->memRead (++cpu->pc); /* -Low part. */ param16 = cpu->memRead (param8_1); /* -Hight part. */ param16 |= cpu->memRead ((param8_1 + 1) & 0xFF) << 8; /* Read Value. */ param8_2 = cpu->memRead (param16 + cpu->y); /* Make the Addition. */ value = cpu->a & param8_2; SetA (cpu, value); UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - AND ($%.2x),Y]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_BCS: /* 0xb0 - BCS - Branch if Carry Set */ /* Read parameter. */ param8_1 = cpu->memRead (++cpu->pc); cpu->pc++; PRINT_OP (("AT PC: [%.2x - BCS $%.4x]\n", opcode, cpu->pc + (int8_t)param8_1)); BranchIfCarrySet (cpu, param8_1); break; case OP_CODE_BCC: /* 0x90 - BCC - Branch if Carry Clear */ /* Read parameter. */ param8_1 = cpu->memRead (++cpu->pc); cpu->pc++; PRINT_OP (("AT PC: [%.2x - BCC $%.4x]\n", opcode, cpu->pc + (int8_t)param8_1)); BranchIfCarryClear (cpu, param8_1); break; case OP_CODE_BVC: /* 0x50 - BVC - Branch if Overflow Clear */ /* Read parameter. */ param8_1 = cpu->memRead (++cpu->pc); cpu->pc++; PRINT_OP (("AT PC: [%.2x - BVC $%.4x]\n", opcode, cpu->pc + (int8_t)param8_1)); BranchIfOverflowClear (cpu, param8_1); break; case OP_CODE_BVS: /* 0x70 - BVS - Branch if Overflow Set */ /* Read parameter. */ param8_1 = cpu->memRead (++cpu->pc); cpu->pc++; PRINT_OP (("AT PC: [%.2x - BVS $%.4x]\n", opcode, cpu->pc + (int8_t)param8_1)); BranchIfOverflowSet (cpu, param8_1); break; case OP_CODE_BNE: /* 0xd0 - BNE - Branch if not Equal */ /* Read parameter. */ param8_1 = cpu->memRead (++cpu->pc); cpu->pc++; PRINT_OP (("AT PC: [%.2x - BNE $%.4x]\n", opcode, cpu->pc + (int8_t)param8_1)); BranchIfNotEqual (cpu, param8_1); break; case OP_CODE_BEQ: /* 0xf0 - BEQ - Branch if Equal */ /* Read parameter. */ param8_1 = cpu->memRead (++cpu->pc); cpu->pc++; PRINT_OP (("AT PC: [%.2x - BEQ $%.4x]\n", opcode, cpu->pc + (int8_t)param8_1)); BranchIfEqual (cpu, param8_1); break; case OP_CODE_JSR: /* 0x20 - JSR - Jump to SubRoutine */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Save the Current PC in the Stack. */ param8_1 = (cpu->pc & 0xFF00) >> 8; param8_2 = (cpu->pc & 0xFF); Push (cpu, param8_1); Push (cpu, param8_2); PRINT_OP (("AT PC: [%.2x - JSR $%.4x]\n", opcode, param16)); /* Jump to Sub Routine. */ cpu->pc = param16; break; case OP_CODE_JMP_1: /* 0x4c - JMP $aaaa */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; PRINT_OP (("AT PC: [%.2x - JMP $%.4x]\n", opcode, param16)); /* Jump to the adress. */ cpu->pc = param16; break; case OP_CODE_JMP_2: /* 0x6c - JMP ($aaaa) */ /* Le 6502 a un bug sur les sauts de pages indirect. * Si on fait un faut sur une fin de page (02ff) * La retenue sur le mot suivant n'est pas reporte. * Donc plutot que de lire 02ff et 0300 on lit 02FF et 0200. */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read the indexed pointer. */ /* -Low part. */ value = cpu->memRead (param16); /* -Hight part. */ param16_2 = (param16 & 0xFF00) | ((param16 + 1) &0xFF); value |= cpu->memRead (param16_2) << 8; PRINT_OP (("AT PC: [%.2x - JMP ($%.4x)]\n", opcode, param16)); /* Jump to the adress. */ cpu->pc = value; break; case OP_CODE_DEY: /* 0x88 - DEY - Decrement Y */ DecY(cpu); UpdateFlagsN_Z (cpu, cpu->y); PRINT_OP (("AT PC: [%.2x - DEY]\n", opcode)); cpu->pc++; break; case OP_CODE_DEX: /* 0xca - DEX - Decrement X */ DecX(cpu); UpdateFlagsN_Z (cpu, cpu->x); PRINT_OP (("AT PC: [%.2x - DEX]\n", opcode)); cpu->pc++; break; case OP_CODE_INY: /* 0xc8 - INY - Increment Y */ IncY(cpu); UpdateFlagsN_Z (cpu, cpu->y); PRINT_OP (("AT PC: [%.2x - INY]\n", opcode)); cpu->pc++; break; case OP_CODE_INX: /* 0xe8 - INX - Increment X */ IncX(cpu); UpdateFlagsN_Z (cpu, cpu->x); PRINT_OP (("AT PC: [%.2x - INX]\n", opcode)); cpu->pc++; break; case OP_CODE_INC_1: /* 0xe6 - INC $aa */ /* Read parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Read Memory Value */ param8_2 = cpu->memRead (param8_1); /* Increment the value. */ param8_2++; /* Save the New Value. */ cpu->memWrite (param8_1, param8_2); /* And Update N and Z Flags. */ UpdateFlagsN_Z (cpu, param8_2); PRINT_OP (("AT PC: [%.2x - INC $%.2x]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_INC_2: /* 0xf6 - INC $aa,X */ /* Read parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Read Memory Value */ param8_2 = cpu->memRead ((param8_1 + cpu->x) & 0xFF); /* Increment the value. */ param8_2++; /* Save the New Value. */ cpu->memWrite ((param8_1 + cpu->x) & 0xFF, param8_2); /* And Update N and Z Flags. */ UpdateFlagsN_Z (cpu, param8_2); PRINT_OP (("AT PC: [%.2x - INC $%.2x,X]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_INC_3: /* 0xee - INC $aaaa */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read Memory Value */ param8_1 = cpu->memRead (param16); /* Increment the value. */ param8_1++; /* Save the New Value. */ cpu->memWrite (param16, param8_1); /* And Update N and Z Flags. */ UpdateFlagsN_Z (cpu, param8_1); PRINT_OP (("AT PC: [%.2x - INC $%.4x]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_INC_4: /* 0xfe - INC $aaaa,X */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read Memory Value */ param8_1 = cpu->memRead (param16 + cpu->x); /* Increment the value. */ param8_1++; /* Save the New Value. */ cpu->memWrite (param16 + cpu->x, param8_1); /* And Update N and Z Flags. */ UpdateFlagsN_Z (cpu, param8_1); PRINT_OP (("AT PC: [%.2x - INC $%.4x,X]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_DEC_1: /* 0xc6 - DEC $aa */ /* Read parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Read Memory Value */ param8_2 = cpu->memRead (param8_1); /* Decrement the value. */ param8_2--; /* Save the New Value. */ cpu->memWrite (param8_1, param8_2); /* And Update N and Z Flags. */ UpdateFlagsN_Z (cpu, param8_2); PRINT_OP (("AT PC: [%.2x - DEC $%.2x]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_DEC_2: /* 0xd6 - DEC $aa,X */ /* Read parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Read Memory Value */ param8_2 = cpu->memRead ((param8_1 + cpu->x) & 0xFF); /* Decrement the value. */ param8_2--; /* Save the New Value. */ cpu->memWrite ((param8_1 + cpu->x) & 0xFF, param8_2); /* And Update N and Z Flags. */ UpdateFlagsN_Z (cpu, param8_2); PRINT_OP (("AT PC: [%.2x - DEC $%.2x,X]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_DEC_3: /* 0xce - DEC $aaaa */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read Memory Value */ param8_1 = cpu->memRead (param16); /* decrement the value. */ param8_1--; /* Save the New Value. */ cpu->memWrite (param16, param8_1); /* And Update N and Z Flags. */ UpdateFlagsN_Z (cpu, param8_1); PRINT_OP (("AT PC: [%.2x - DEC $%.4x]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_DEC_4: /* 0xde - DEC $aaaa,X */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read Memory Value */ param8_1 = cpu->memRead (param16 + cpu->x); /* Decrement the value. */ param8_1--; /* Save the New Value. */ cpu->memWrite (param16 + cpu->x, param8_1); /* And Update N and Z Flags. */ UpdateFlagsN_Z (cpu, param8_1); PRINT_OP (("AT PC: [%.2x - DEC $%.4x,X]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_ADC_1: /* 0x69 - ADC #aa */ /* Read parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Make the Addition. */ AddWithCarry (cpu, param8_1); PRINT_OP (("AT PC: [%.2x - ADC #$%.2x]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_ADC_2: /* 0x65 - ADC $aa */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Read Value. */ param8_2 = cpu->memRead (param8_1); /* Make the Addition. */ AddWithCarry (cpu, param8_2); PRINT_OP (("AT PC: [%.2x - ADC $%.2x]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_ADC_3: /* 0x75 - ADC $aa,X */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Read Value. */ param8_2 = cpu->memRead ((param8_1 + cpu->x) & 0xFF); /* Make the Addition. */ AddWithCarry (cpu, param8_2); PRINT_OP (("AT PC: [%.2x - ADC $%.2x,X]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_ADC_4: /* 0x6d - ADC $aaaa */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read Value. */ param8_1 = cpu->memRead (param16); /* Make the Addition. */ AddWithCarry (cpu, param8_1); PRINT_OP (("AT PC: [%.2x - ADC $%.4x]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_ADC_5: /* 0x7d - ADC $aaaa,X */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read Value. */ param8_1 = cpu->memRead (param16 + cpu->x); /* Make the Addition. */ AddWithCarry (cpu, param8_1); PRINT_OP (("AT PC: [%.2x - ADC $%.4x,Y]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_ADC_6: /* 0x79 - ADC $aaaa,Y */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read Value. */ param8_1 = cpu->memRead (param16 + cpu->y); /* Make the Addition. */ AddWithCarry (cpu, param8_1); PRINT_OP (("AT PC: [%.2x - ADC $%.4x,Y]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_ADC_7: /* 0x61 - ADC ($aa,X) */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* -Low part. */ param16 = cpu->memRead ((param8_1 + cpu->x) & 0xFF); /* -Hight part. */ param16 |= cpu->memRead ((param8_1 + cpu->x + 1) & 0xFF) << 8; /* Read Value. */ param8_2 = cpu->memRead (param16); /* Make the Addition. */ AddWithCarry (cpu, param8_2); PRINT_OP (("AT PC: [%.2x - ADC ($%.2x,X)]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_ADC_8: /* 0x71 - ADC ($aa),Y */ /* Read Parameter */ param8_1 = cpu->memRead (++cpu->pc); /* -Low part. */ param16 = cpu->memRead (param8_1); /* -Hight part. */ param16 |= cpu->memRead ((param8_1 + 1) & 0xFF) << 8; /* Read Value. */ param8_2 = cpu->memRead (param16 + cpu->y); /* Make the Addition. */ AddWithCarry (cpu, param8_2); PRINT_OP (("AT PC: [%.2x - ADC ($%.2x),Y]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_SBC_1: /* 0xe9 - SBC #aa */ /* Read Parameter */ param8_1 = cpu->memRead (++cpu->pc); /* Make the subtract. */ SubstractWithCarry (cpu, param8_1); PRINT_OP (("AT PC: [%.2x - SBC #$%.2x]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_SBC_2: /* 0xe5 - SBC $aa */ /* Read Parameter */ param8_1 = cpu->memRead (++cpu->pc); /* Read Operande. */ param8_2 = cpu->memRead (param8_1); /* Make the subtract. */ SubstractWithCarry (cpu, param8_2); PRINT_OP (("AT PC: [%.2x - SBC $%.2x]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_SBC_3: /* 0xf5 - SBC $aa,X */ /* Read Parameter */ param8_1 = cpu->memRead (++cpu->pc); /* Read Operande. */ param8_2 = cpu->memRead ((param8_1 + cpu->x) & 0xFF); /* Make the subtract. */ SubstractWithCarry (cpu, param8_2); PRINT_OP (("AT PC: [%.2x - SBC $%.2x,X]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_SBC_4: /* 0xed - SBC $aaaa */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read Operande. */ param8_1 = cpu->memRead (param16); /* Make the subtract. */ SubstractWithCarry (cpu, param8_1); PRINT_OP (("AT PC: [%.2x - SBC $%.4x]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_SBC_5: /* SBC $aaaa,X */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read Operande. */ param8_1 = cpu->memRead (param16 + cpu->x); /* Make the subtract. */ SubstractWithCarry (cpu, param8_1); PRINT_OP (("AT PC: [%.2x - SBC $%.4x,X]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_SBC_6: /* 0xfd - SBC $aaaa,Y */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read Operande. */ param8_1 = cpu->memRead (param16 + cpu->y); /* Make the subtract. */ SubstractWithCarry (cpu, param8_1); PRINT_OP (("AT PC: [%.2x - SBC $%.4x,Y]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_SBC_7: /* 0xe1 - SBC ($aa,X) */ /* Read Parameter */ param8_1 = cpu->memRead (++cpu->pc); /* -Low part. */ param16 = cpu->memRead ((param8_1 + cpu->x) & 0xFF); /* -Hight part. */ param16 |= cpu->memRead ((param8_1 + cpu->x + 1) & 0xFF) << 8; /* Read Operande. */ param8_2 = cpu->memRead (param16); /* Make the subtract. */ SubstractWithCarry (cpu, param8_2); PRINT_OP (("AT PC: [%.2x - SBC ($%.2x,X)]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_SBC_8: /* 0xf1 - SBC ($aa),Y */ /* Read Parameter */ param8_1 = cpu->memRead (++cpu->pc); /* -Low part. */ param16 = cpu->memRead (param8_1); /* -Hight part. */ param16 |= cpu->memRead ((param8_1 + 1) & 0xFF) << 8; /* Read Operande. */ param8_2 = cpu->memRead (param16 + cpu->y); /* Make the subtract. */ SubstractWithCarry (cpu, param8_2); PRINT_OP (("AT PC: [%.2x - SBC ($%.2x),Y]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_BIT_1: /* 0x24 - BIT $aa */ /* Read Parameter */ param8_1 = cpu->memRead (++cpu->pc); PRINT_OP (("AT PC: [%.2x - BIT $%.2x]\n", opcode, param8_1)); Bit_Test (cpu, param8_1); cpu->pc++; break; case OP_CODE_BIT_2: /* 0x2c - BIT $aaaa */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; PRINT_OP (("AT PC: [%.2x - BIT $%.4x]\n", opcode, param16)); Bit_Test (cpu, param16); cpu->pc++; break; case OP_CODE_ASL_1: /* 0x0a - ASL A */ /* Make the shift Left. */ UpdateFlagsC_L (cpu, cpu->a); SetA (cpu, (cpu->a << 1) & 0xFF); UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - ASL A]\n", opcode)); cpu->pc++; break; case OP_CODE_ASL_2: /* 0x06 - ASL $aa */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Read Value. */ param8_2 = cpu->memRead (param8_1); /* If the bit 8 is 1, Then we Put Carry Status to 1. */ UpdateFlagsC_L (cpu, param8_2); /* Make the shift Left. */ SetA (cpu, (param8_2 << 1) & 0xFF); UpdateFlagsN_Z (cpu, param8_2); /* Save the result of the right shift */ cpu->memWrite (param8_1, param8_2); PRINT_OP (("AT PC: [%.2x - ASL $%.2x]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_ASL_3: /* 0x16 - ASL $aa,X */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Read Value. */ param8_2 = cpu->memRead ((param8_1 + cpu->x) & 0xFF); /* If the bit 8 is 1, Then we Put Carry Status to 1. */ UpdateFlagsC_L (cpu, param8_2); /* Make the shift Left. */ SetA (cpu, (param8_2 << 1) & 0xFF); UpdateFlagsN_Z (cpu, param8_2); /* Save the result of the right shift */ cpu->memWrite ((param8_1 + cpu->x) & 0xFF, param8_2); PRINT_OP (("AT PC: [%.2x - ASL $%.2x,X]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_ASL_4: /* 0x0e - ASL $aaaa */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read Value. */ param8_2 = cpu->memRead (param16); /* If the bit 8 is 1, Then we Put Carry Status to 1. */ UpdateFlagsC_L (cpu, param8_2); /* Make the shift Left. */ SetA (cpu, (param8_2 << 1) & 0xFF); UpdateFlagsN_Z (cpu, param8_2); /* Save the result of the right shift */ cpu->memWrite (param16, param8_2); PRINT_OP (("AT PC: [%.2x - ASL $%.4x]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_ASL_5: /* 0x1e - ASL $aaaa,X */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read Value. */ param8_2 = cpu->memRead (param16 + cpu->x); /* If the bit 8 is 1, Then we Put Carry Status to 1. */ UpdateFlagsC_L (cpu, param8_2); /* Make the shift Left. */ SetA (cpu, (param8_2 << 1) & 0xFF); UpdateFlagsN_Z (cpu, param8_2); /* Save the result of the right shift */ cpu->memWrite (param16 + cpu->x, param8_2); PRINT_OP (("AT PC: [%.2x - ASL $%.4x,X]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_LSR_1: /* 0x4a - LSR A */ /* If the bit 0 is 1, Then we Put Carry Status to 0. */ if (cpu->a & 0x1) { bitset (&cpu->R_Status, STATUS_FLAG_C, 1); } else { bitset (&cpu->R_Status, STATUS_FLAG_C, 0); } /* Make the shift Right. */ SetA (cpu, (cpu->a >> 1) & 0xFF); UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - LSR A]\n", opcode)); cpu->pc++; break; case OP_CODE_LSR_2: /* 0x46 - LSR $aa */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Read Value. */ param8_2 = cpu->memRead (param8_1); /* If the bit 0 is 1, Then we Put Carry Status to 0. */ if (param8_2 & 0x1) { bitset (&cpu->R_Status, STATUS_FLAG_C, 1); } else { bitset (&cpu->R_Status, STATUS_FLAG_C, 0); } /* Make the shift Right. */ param8_2 = (param8_2 >> 1) & 0xFF; UpdateFlagsN_Z (cpu, param8_2); /* Save the result of the right shift */ cpu->memWrite (param8_1, param8_2); PRINT_OP (("AT PC: [%.2x - LSR $%.2x]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_LSR_3: /* 0x56 - LSR $aa,X */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Read Value. */ param8_2 = cpu->memRead ((param8_1 + cpu->x) & 0xFF); /* If the bit 0 is 1, Then we Put Carry Status to 0. */ if (param8_2 & 0x1) { bitset (&cpu->R_Status, STATUS_FLAG_C, 1); } else { bitset (&cpu->R_Status, STATUS_FLAG_C, 0); } /* Make the shift Right. */ param8_2 = (param8_2 >> 1) & 0xFF; UpdateFlagsN_Z (cpu, param8_2); /* Save the result of the right shift */ cpu->memWrite ((param8_1 + cpu->x) & 0xFF, param8_2); PRINT_OP (("AT PC: [%.2x - LSR $%.2x,X]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_LSR_4: /* 0x4e - LSR $aaaa */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read Value. */ param8_2 = cpu->memRead (param16); /* If the bit 0 is 1, Then we Put Carry Status to 0. */ if (param8_2 & 0x1) { bitset (&cpu->R_Status, STATUS_FLAG_C, 1); } else { bitset (&cpu->R_Status, STATUS_FLAG_C, 0); } /* Make the shift Right. */ param8_2 = (param8_2 >> 1) & 0xFF; UpdateFlagsN_Z (cpu, param8_2); /* Save the result of the right shift */ cpu->memWrite (param16, param8_2); PRINT_OP (("AT PC: [%.2x - LSR $%.4x]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_LSR_5: /* 0x5e - LSR $aaaa,X */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read Value. */ param8_2 = cpu->memRead (param16 + cpu->x); /* If the bit 0 is 1, Then we Put Carry Status to 0. */ if (param8_2 & 0x1) { bitset (&cpu->R_Status, STATUS_FLAG_C, 1); } else { bitset (&cpu->R_Status, STATUS_FLAG_C, 0); } /* Make the shift Right. */ param8_2 = (param8_2 >> 1) & 0xFF; UpdateFlagsN_Z (cpu, param8_2); /* Save the result of the right shift */ cpu->memWrite (param16 + cpu->x, param8_2); PRINT_OP (("AT PC: [%.2x - LSR $%.4x,X]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_ROL_1: /* 0x2a - ROL A */ param8_2 = 0; /* Get Carry. */ if (cpu->R_Status & FLAG_C) { param8_2 = 1; } /* Update the new CFlags. */ UpdateFlagsC_L (cpu, cpu->a); /* Shift A. */ value = (cpu->a << 1) & 0xFF; value |= param8_2; SetA (cpu, value); /* Update Flag N & Z */ UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - ROL A]\n", opcode)); cpu->pc++; break; case OP_CODE_ROL_2: /* 0x26 - ROL $aa */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Read Value. */ param8_2 = cpu->memRead (param8_1); tmp = 0; /* Get Carry. */ if (cpu->R_Status & FLAG_C) { tmp = 1; } /* Update the new CFlags. */ UpdateFlagsC_L (cpu, param8_2); /* Shift A. */ param8_2 = (param8_2 << 1) & 0xFF; param8_2 |= tmp; /* Update Flag N & Z */ UpdateFlagsN_Z (cpu, param8_2); /* Save the result of the rotation */ cpu->memWrite (param8_1, param8_2); PRINT_OP (("AT PC: [%.2x - ROL $%.2x]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_ROL_3: /* 0x36 - ROL $aa,X */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Read Value. */ param8_2 = cpu->memRead ((param8_1 + cpu->x) & 0xFF); tmp = 0; /* Get Carry. */ if (cpu->R_Status & FLAG_C) { tmp = 1; } /* Update the new CFlags. */ UpdateFlagsC_L (cpu, param8_2); /* Shift A. */ param8_2 = (param8_2 << 1) & 0xFF; param8_2 |= tmp; /* Update Flag N & Z */ UpdateFlagsN_Z (cpu, param8_2); /* Save the result of the rotation */ cpu->memWrite ((param8_1 + cpu->x) & 0xFF, param8_2); PRINT_OP (("AT PC: [%.2x - ROL $%.2x,X]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_ROL_4: /* 0x2e - ROL $aaaa */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read Value. */ param8_2 = cpu->memRead (param16); tmp = 0; /* Get Carry. */ if (cpu->R_Status & FLAG_C) { tmp = 1; } /* Update the new CFlags. */ UpdateFlagsC_L (cpu, param8_2); /* Shift A. */ param8_2 = (param8_2 << 1) & 0xFF; param8_2 |= tmp; /* Update Flag N & Z */ UpdateFlagsN_Z (cpu, param8_2); /* Save the result of the rotation */ cpu->memWrite (param16, param8_2); PRINT_OP (("AT PC: [%.2x - ROL $%.4x]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_ROL_5: /* 0x3e - ROL $aaaa,X */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read Value. */ param8_2 = cpu->memRead (param16 + cpu->x); tmp = 0; /* Get Carry. */ if (cpu->R_Status & FLAG_C) { tmp = 1; } /* Update the new CFlags. */ UpdateFlagsC_L (cpu, param8_2); /* Shift A. */ param8_2 = (param8_2 << 1) & 0xFF; param8_2 += tmp; /* Update Flag N & Z */ UpdateFlagsN_Z (cpu, param8_2); /* Save the result of the rotation */ cpu->memWrite (param16 + cpu->x, param8_2); PRINT_OP (("AT PC: [%.2x - ROL $%.4x,X]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_ROR_1: /* 0x6a - ROR A */ param8_2 = 0; /* Get Carry. */ if (cpu->R_Status & FLAG_C) { param8_2 = 0x80; } /* Update the new CFlags. */ UpdateFlagsC_R (cpu, cpu->a); /* Shift A. */ value = (cpu->a >> 1) & 0xFF; value += param8_2; SetA (cpu, value); /* Update Flag N & Z */ UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - ROR A]\n", opcode)); cpu->pc++; break; case OP_CODE_ROR_2: /* 0x66 - ROR $aa */ /* Read 8 bits Parameter */ param8_1 = cpu->memRead (++cpu->pc); /* Read Value. */ param8_3 = cpu->memRead (param8_1); param8_2 = 0; /* Get Carry. */ if (cpu->R_Status & FLAG_C) { param8_2 = 0x80; } /* Update the new CFlags. */ UpdateFlagsC_R (cpu, param8_3); /* Shift param8_1. */ param8_3 = (param8_3 >> 1) & 0xFF; param8_3 += (param8_2 << 7); UpdateFlagsN_Z (cpu, param8_3); cpu->memWrite (param8_1, param8_3); PRINT_OP (("AT PC: [%.2x - ROR $%.2x]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_ROR_3: /* 0x76 - ROR $aa,X */ /* Read 8 bits Parameter */ param8_1 = cpu->memRead (++cpu->pc); /* Read Value. */ param8_3 = cpu->memRead (param8_1 + cpu->x); param8_2 = 0; /* Get Carry. */ if (cpu->R_Status & FLAG_C) { param8_2 = 0x80; } /* Update the new CFlags. */ UpdateFlagsC_R (cpu, param8_3); /* Shift param8_1. */ param8_3 = (param8_3 >> 1) & 0xFF; param8_3 += (param8_2 << 7); UpdateFlagsN_Z (cpu, param8_3); cpu->memWrite (param8_1 + cpu->x, param8_3); PRINT_OP (("AT PC: [%.2x - ROR $%.2x,X]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_ROR_4: /* 0x6e - ROR $aaaa */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read Value. */ param8_1 = cpu->memRead (param16); param8_2 = 0; /* Get Carry. */ if (cpu->R_Status & FLAG_C) { param8_2 = 0x80; } /* Update the new CFlags. */ UpdateFlagsC_R (cpu, param8_1); /* Shift param8_1. */ param8_1 = (param8_1 >> 1) & 0xFF; param8_1 += (param8_2 << 7); UpdateFlagsN_Z (cpu, param8_1); cpu->memWrite (param16, param8_1); PRINT_OP (("AT PC: [%.2x - ROR $%.4x]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_ROR_5: /* 0x7e - ROR $aaaa,X */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read Value. */ param8_1 = cpu->memRead (param16 + cpu->x); param8_2 = 0; /* Get Carry. */ if (cpu->R_Status & FLAG_C) { param8_2 = 0x80; } /* Update the new CFlags. */ UpdateFlagsC_R (cpu, param8_1); /* Shift param8_1. */ param8_1 = (param8_1 >> 1) & 0xFF; param8_1 += (param8_2 << 7); UpdateFlagsN_Z (cpu, param8_1); cpu->memWrite (param16 + cpu->x, param8_1); PRINT_OP (("AT PC: [%.2x - ROR $%.4x,X]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_PHA: /* 0x68 - PLA - Pull A (Pop) */ Push (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - PHA]\n", opcode)); cpu->pc++; break; case OP_CODE_PLA: /* 0x68 - PLA - Pull A (Pop) */ SetA (cpu, Pop (cpu)); UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - PLA]\n", opcode)); cpu->pc++; break; case OP_CODE_PHP: /* 0x08 - PHP - Push Processor Status Register */ param8_1 = cpu->R_Status; bitset (¶m8_1, STATUS_FLAG_R, 1); bitset (¶m8_1, STATUS_FLAG_B, 1); Push (cpu, param8_1); PRINT_OP (("AT PC: [%.2x - PHP]\n", opcode)); cpu->pc++; break; case OP_CODE_PLP: /* 0x28 - PLP - Pull Processor Status Register */ param8_1 = Pop (cpu); /* Remove Flags. */ bitset (¶m8_1, STATUS_FLAG_R, 0); bitset (¶m8_1, STATUS_FLAG_B, 0); cpu->R_Status = param8_1; PRINT_OP (("AT PC: [%.2x - PLP]\n", opcode)); cpu->pc++; break; case OP_CODE_EOR_1: /* 0x49 - EOR #aa */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* a XOR b */ /* a xor b = (a et ! b) ou (! a et b) */ value = cpu->a ^ param8_1; SetA (cpu, value); /* And Update N and Z Flags. */ UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - EOR #$%.2x]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_EOR_2: /* 0x45 - EOR $aa */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Read Memory Value */ param8_2 = cpu->memRead (param8_1); /* a XOR b */ /* a xor b = (a et ! b) ou (! a et b) */ value = cpu->a ^ param8_2; SetA (cpu, value); /* And Update N and Z Flags. */ UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - EOR $%.2x]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_EOR_3: /* 0x55 - EOR $aa,X */ /* Read Parameter. */ param8_1 = cpu->memRead (++cpu->pc); /* Read Memory Value */ param8_2 = cpu->memRead ((param8_1 + cpu->x) & 0xFF); /* a XOR b */ /* a xor b = (a et ! b) ou (! a et b) */ value = cpu->a ^ param8_2; SetA (cpu, value); /* And Update N and Z Flags. */ UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - EOR $%.2x,X]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_EOR_4: /* 0x4d - EOR $aaaa */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read Value. */ param8_1 = cpu->memRead (param16); /* a XOR b */ /* a xor b = (a et ! b) ou (! a et b) */ value = cpu->a ^ param8_1; SetA (cpu, value); /* And Update N and Z Flags. */ UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - EOR $%.4x]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_EOR_5: /* 0x5d - EOR $aaaa,X */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read Value. */ param8_1 = cpu->memRead (param16 + cpu->x); /* a XOR b */ /* a xor b = (a et ! b) ou (! a et b) */ value = cpu->a ^ param8_1; SetA (cpu, value); /* And Update N and Z Flags. */ UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - EOR $%.4x,X]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_EOR_6: /* 0x59 - EOR $aaaa,Y */ /* Read 16 bits Parameter */ /* -Low part. */ param16 = cpu->memRead (++cpu->pc); /* -Hight part. */ param16 |= cpu->memRead (++cpu->pc) << 8; /* Read Value. */ param8_1 = cpu->memRead (param16 + cpu->y); /* a XOR b */ /* a xor b = (a et ! b) ou (! a et b) */ value = cpu->a ^ param8_1; SetA (cpu, value); /* And Update N and Z Flags. */ UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - EOR $%.4x,Y]\n", opcode, param16)); cpu->pc++; break; case OP_CODE_EOR_7: /* 0x41 - EOR ($aa,X) */ /* Read Memory Value */ param8_1 = cpu->memRead (++cpu->pc); /* -Low part. */ param16 = cpu->memRead ((param8_1 + cpu->x) & 0xFF); /* -Hight part. */ param16 |= cpu->memRead ((param8_1 + cpu->x + 1) & 0xFF) << 8; /* Read Value. */ param8_2 = cpu->memRead (param16); /* a XOR b */ /* a xor b = (a et ! b) ou (! a et b) */ value = cpu->a ^ param8_2; SetA (cpu, value); /* And Update N and Z Flags. */ UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - EOR ($%.2x,X)]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_EOR_8: /* 0x51 - EOR ($aa),Y */ /* Read Parameter */ param8_1 = cpu->memRead (++cpu->pc); /* -Low part. */ param16 = cpu->memRead (param8_1); /* -Hight part. */ param16 |= cpu->memRead ((param8_1 + 1) & 0xFF) << 8; /* Read Value. */ param8_2 = cpu->memRead (param16 + cpu->y); /* a XOR b */ /* a xor b = (a et ! b) ou (! a et b) */ value = cpu->a ^ param8_2; SetA (cpu, value); /* And Update N and Z Flags. */ UpdateFlagsN_Z (cpu, cpu->a); PRINT_OP (("AT PC: [%.2x - EOR ($%.2x),Y]\n", opcode, param8_1)); cpu->pc++; break; case OP_CODE_RTS: /* 0x60 - RTS - Return from SubRoutine */ /* Get the PC saved on the stack. */ /* -Low part. */ param8_2 = Pop (cpu); /* -Hight part. */ param8_1 = Pop (cpu); /* Save param in a 16 bit parameter. */ param16 = param8_2; param16 |= param8_1 << 8; PRINT_OP (("AT PC: [%x - RTS]\n", opcode)); /* Return to last instruction (before the jump). */ cpu->pc = param16; /* And go to the next instruction. */ cpu->pc++; break; case OP_CODE_RTI: /* 0x40 - RTI - Return from Interrupt */ /* Get the Status */ cpu->R_Status = Pop (cpu); /* Get the PC saved on the stack. */ /* -Low part. */ param8_2 = Pop (cpu); /* -Hight part. */ param8_1 = Pop (cpu); /* Save param in a 16 bit parameter. */ param16 = param8_2; param16 |= param8_1 << 8; PRINT_OP (("AT PC: [%.2x - RTI]\n", opcode)); /* Now we accept New NMI. */ cpu->pc = param16; break; case OP_CODE_NOP: /* 0xea - NOP - No Operation */ PRINT_OP (("AT PC: [%x - NOP]\n", opcode)); /* Go to the next instruction. */ cpu->pc++; break; default: DEBUG0 (("Unknown OPCODE: (0x%x)\n", opcode)); result = -1; } return result; }