I have ported my old project “pNesX” game console emulator to the nucleo.

Dependencies:   SDFileSystem mbed

Intro

I have ported my old project “pNesX” to the STM32 Nucleo. The pNesX is a NES emulator for the PlayStation that I have created 16 years ago!

Emulation part was almost without change, the sound part was newly added.

Parts

STM32 Nucleo F446RE
QVGA 2.2 TFT SPI (with the SD card slot)
Audio jack(TS or TRS)
USB Connector
Register 100k, 10k, 4.7k, 100
Capacitor 0.01uF, 2.2uF
Breadboard
Wires
Computer Speakers
USB GamePad

Wiring diagram

/media/uploads/beaglescout007/nucleo_ex06_emu.png

TFT J2Nucleo
VCC3V3
GNDGND
CSPB_5(D4)
ResetPA_10(D2) Pull Up(100k)
D/CPA_8(D7)
MOSIPA_7(D11)
SCKPA_5(D13)
LEDLED-100ohm-3V3
MISOPA_6(D12)
TFT J4Nucleo
SD_CSPA_9
SD_MOSIPB_15
SD_MISOPB_14
SD_SCKPB_13
AudioNucleo
TIPPA_4(A2)
USB con.Nucleo
GNDGND
+PA_12
-PA_11
5V5V

https://youtu.be/jL24IjT6LnI

Limitations

  • Since the rest of the RAM is about 50kbyte, maximum capacity of the game ROM is about 50kbyte.
  • The length of the file name up to 32 characters.
  • The number of files in the folder is up to 100.

Used Library

Revision:
0:3dac1f1bc9e0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/K6502.cpp	Sun Apr 03 07:45:29 2016 +0000
@@ -0,0 +1,1058 @@
+/*===================================================================*/
+/*                                                                   */
+/*  K6502.cpp : 6502 Emulator                                        */
+/*                                                                   */
+/*  1999/10/19  Racoon  New preparation                              */
+/*                                                                   */
+/*===================================================================*/
+
+/*-------------------------------------------------------------------*/
+/*  Include files                                                    */
+/*-------------------------------------------------------------------*/
+#include "K6502.h"
+
+/*-------------------------------------------------------------------*/
+/*  Operation Macros                                                 */
+/*-------------------------------------------------------------------*/
+
+// Clock Op.
+#define CLK(a)   g_wPassedClocks += (a);
+
+// Addressing Op.
+// Address
+// (Indirect,X)
+#define AA_IX    K6502_ReadZpW( K6502_Read( PC++ ) + X )
+// (Indirect),Y
+#define AA_IY    K6502_ReadZpW( K6502_Read( PC++ ) ) + Y
+// Zero Page
+#define AA_ZP    K6502_Read( PC++ )
+// Zero Page,X
+#define AA_ZPX   (BYTE)( K6502_Read( PC++ ) + X )
+// Zero Page,Y
+#define AA_ZPY   (BYTE)( K6502_Read( PC++ ) + Y )
+// Absolute
+#define AA_ABS   ( K6502_Read( PC++ ) | (WORD)K6502_Read( PC++ ) << 8 )
+// Absolute2 ( PC-- )
+#define AA_ABS2  ( K6502_Read( PC++ ) | (WORD)K6502_Read( PC ) << 8 )
+// Absolute,X
+#define AA_ABSX  AA_ABS + X
+// Absolute,Y
+#define AA_ABSY  AA_ABS + Y
+
+// Data
+// (Indirect,X)
+#define A_IX    K6502_Read( AA_IX )
+// (Indirect),Y
+#define A_IY    K6502_ReadIY()
+// Zero Page
+#define A_ZP    K6502_ReadZp( AA_ZP )
+// Zero Page,X
+#define A_ZPX   K6502_ReadZp( AA_ZPX )
+// Zero Page,Y
+#define A_ZPY   K6502_ReadZp( AA_ZPY )
+// Absolute
+#define A_ABS   K6502_Read( AA_ABS )
+// Absolute,X
+#define A_ABSX  K6502_ReadAbsX()
+// Absolute,Y
+#define A_ABSY  K6502_ReadAbsY()
+// Immediate
+#define A_IMM   K6502_Read( PC++ )
+
+// Flag Op.
+#define SETF(a)  F |= (a)
+#define RSTF(a)  F &= ~(a)
+#define TEST(a)  RSTF( FLAG_N | FLAG_Z ); SETF( g_byTestTable[ a ] )
+
+// Load & Store Op.
+#define STA(a)    K6502_Write( (a), A );
+#define STX(a)    K6502_Write( (a), X );
+#define STY(a)    K6502_Write( (a), Y );
+#define LDA(a)    A = (a); TEST( A );
+#define LDX(a)    X = (a); TEST( X );
+#define LDY(a)    Y = (a); TEST( Y );
+
+// Stack Op.
+#define PUSH(a)   K6502_Write( BASE_STACK + SP--, (a) )
+#define PUSHW(a)  PUSH( (a) >> 8 ); PUSH( (a) & 0xff )
+#define POP(a)    a = K6502_Read( BASE_STACK + ++SP )
+#define POPW(a)   POP(a); a |= ( K6502_Read( BASE_STACK + ++SP ) << 8 )
+
+// Logical Op.
+#define ORA(a)  A |= (a); TEST( A )
+#define AND(a)  A &= (a); TEST( A )
+#define EOR(a)  A ^= (a); TEST( A )
+#define BIT(a)  byD0 = (a); RSTF( FLAG_N | FLAG_V | FLAG_Z ); SETF( ( byD0 & ( FLAG_N | FLAG_V ) ) | ( ( byD0 & A ) ? 0 : FLAG_Z ) );
+#define CMP(a)  wD0 = (WORD)A - (a); RSTF( FLAG_N | FLAG_Z | FLAG_C ); SETF( g_byTestTable[ wD0 & 0xff ] | ( wD0 < 0x100 ? FLAG_C : 0 ) );
+#define CPX(a)  wD0 = (WORD)X - (a); RSTF( FLAG_N | FLAG_Z | FLAG_C ); SETF( g_byTestTable[ wD0 & 0xff ] | ( wD0 < 0x100 ? FLAG_C : 0 ) );
+#define CPY(a)  wD0 = (WORD)Y - (a); RSTF( FLAG_N | FLAG_Z | FLAG_C ); SETF( g_byTestTable[ wD0 & 0xff ] | ( wD0 < 0x100 ? FLAG_C : 0 ) );
+  
+// Math Op. (A D flag isn't being supported.)
+#define ADC(a)  byD0 = (a); \
+                wD0 = A + byD0 + ( F & FLAG_C ); \
+                byD1 = (BYTE)wD0; \
+                RSTF( FLAG_N | FLAG_V | FLAG_Z | FLAG_C ); \
+                SETF( g_byTestTable[ byD1 ] | ( ( ~( A ^ byD0 ) & ( A ^ byD1 ) & 0x80 ) ? FLAG_V : 0 ) | ( wD0 > 0xff ) ); \
+                A = byD1;
+
+#define SBC(a)  byD0 = (a); \
+                wD0 = A - byD0 - ( ~F & FLAG_C ); \
+                byD1 = (BYTE)wD0; \
+                RSTF( FLAG_N | FLAG_V | FLAG_Z | FLAG_C ); \
+                SETF( g_byTestTable[ byD1 ] | ( ( ( A ^ byD0 ) & ( A ^ byD1 ) & 0x80 ) ? FLAG_V : 0 ) | ( wD0 < 0x100 ) ); \
+                A = byD1;
+
+#define DEC(a)  wA0 = a; byD0 = K6502_Read( wA0 ); --byD0; K6502_Write( wA0, byD0 ); TEST( byD0 )
+#define INC(a)  wA0 = a; byD0 = K6502_Read( wA0 ); ++byD0; K6502_Write( wA0, byD0 ); TEST( byD0 )
+
+// Shift Op.
+#define ASLA    RSTF( FLAG_N | FLAG_Z | FLAG_C ); SETF( g_ASLTable[ A ].byFlag ); A = g_ASLTable[ A ].byValue 
+#define ASL(a)  RSTF( FLAG_N | FLAG_Z | FLAG_C ); wA0 = a; byD0 = K6502_Read( wA0 ); SETF( g_ASLTable[ byD0 ].byFlag ); K6502_Write( wA0, g_ASLTable[ byD0 ].byValue )
+#define LSRA    RSTF( FLAG_N | FLAG_Z | FLAG_C ); SETF( g_LSRTable[ A ].byFlag ); A = g_LSRTable[ A ].byValue 
+#define LSR(a)  RSTF( FLAG_N | FLAG_Z | FLAG_C ); wA0 = a; byD0 = K6502_Read( wA0 ); SETF( g_LSRTable[ byD0 ].byFlag ); K6502_Write( wA0, g_LSRTable[ byD0 ].byValue ) 
+#define ROLA    byD0 = F & FLAG_C; RSTF( FLAG_N | FLAG_Z | FLAG_C ); SETF( g_ROLTable[ byD0 ][ A ].byFlag ); A = g_ROLTable[ byD0 ][ A ].byValue 
+#define ROL(a)  byD1 = F & FLAG_C; RSTF( FLAG_N | FLAG_Z | FLAG_C ); wA0 = a; byD0 = K6502_Read( wA0 ); SETF( g_ROLTable[ byD1 ][ byD0 ].byFlag ); K6502_Write( wA0, g_ROLTable[ byD1 ][ byD0 ].byValue )
+#define RORA    byD0 = F & FLAG_C; RSTF( FLAG_N | FLAG_Z | FLAG_C ); SETF( g_RORTable[ byD0 ][ A ].byFlag ); A = g_RORTable[ byD0 ][ A ].byValue 
+#define ROR(a)  byD1 = F & FLAG_C; RSTF( FLAG_N | FLAG_Z | FLAG_C ); wA0 = a; byD0 = K6502_Read( wA0 ); SETF( g_RORTable[ byD1 ][ byD0 ].byFlag ); K6502_Write( wA0, g_RORTable[ byD1 ][ byD0 ].byValue )
+
+// Jump Op.
+#define JSR     wA0 = AA_ABS2; PUSHW( PC ); PC = wA0; 
+#define BRA(a)  if ( a ) { wA0 = PC; PC += (signed char)K6502_Read( PC ); CLK( 3 + ( ( wA0 & 0x0100 ) != ( PC & 0x0100 ) ) ); ++PC; } else { ++PC; CLK( 2 ); }
+#define JMP(a)  PC = a;
+
+/*-------------------------------------------------------------------*/
+/*  Global valiables                                                 */
+/*-------------------------------------------------------------------*/
+
+// 6502 Register
+WORD PC;
+BYTE SP;
+BYTE F;
+BYTE A;
+BYTE X;
+BYTE Y;
+
+// The state of the IRQ pin
+BYTE IRQ_State;
+
+// Wiring of the IRQ pin
+BYTE IRQ_Wiring;
+
+// The state of the NMI pin
+BYTE NMI_State;
+
+// Wiring of the NMI pin
+BYTE NMI_Wiring;
+
+// The number of the clocks that it passed
+WORD g_wPassedClocks;
+
+// A table for the test
+BYTE g_byTestTable[ 256 ];
+
+// Value and Flag Data
+struct value_table_tag
+{
+  BYTE byValue;
+  BYTE byFlag;
+};
+
+// A table for ASL
+struct value_table_tag g_ASLTable[ 256 ];
+
+// A table for LSR
+struct value_table_tag g_LSRTable[ 256 ];
+
+// A table for ROL
+struct value_table_tag g_ROLTable[ 2 ][ 256 ];
+
+// A table for ROR
+struct value_table_tag g_RORTable[ 2 ][ 256 ];
+
+/*===================================================================*/
+/*                                                                   */
+/*                K6502_Init() : Initialize K6502                    */
+/*                                                                   */
+/*===================================================================*/
+void K6502_Init()
+{
+/*
+ *  Initialize K6502
+ *
+ *  You must call this function only once at first.
+ */
+
+  BYTE idx;
+  BYTE idx2;
+
+  // The establishment of the IRQ pin
+  NMI_Wiring = NMI_State = 1;
+  IRQ_Wiring = IRQ_State = 1;
+
+  // Make a table for the test
+  idx = 0;
+  do
+  {
+    if ( idx == 0 )
+      g_byTestTable[ 0 ] = FLAG_Z;
+    else
+    if ( idx > 127 )
+      g_byTestTable[ idx ] = FLAG_N;
+    else
+      g_byTestTable[ idx ] = 0;
+
+    ++idx;
+  } while ( idx != 0 );
+
+  // Make a table ASL
+  idx = 0;
+  do
+  {
+    g_ASLTable[ idx ].byValue = idx << 1;
+    g_ASLTable[ idx ].byFlag = 0;
+
+    if ( idx > 127 )
+      g_ASLTable[ idx ].byFlag = FLAG_C;
+
+    if ( g_ASLTable[ idx ].byValue == 0 )
+      g_ASLTable[ idx ].byFlag |= FLAG_Z;
+    else
+    if ( g_ASLTable[ idx ].byValue & 0x80 )
+      g_ASLTable[ idx ].byFlag |= FLAG_N;
+
+    ++idx;
+  } while ( idx != 0 );
+
+  // Make a table LSR
+  idx = 0;
+  do
+  {
+    g_LSRTable[ idx ].byValue = idx >> 1;
+    g_LSRTable[ idx ].byFlag = 0;
+
+    if ( idx & 1 )
+      g_LSRTable[ idx ].byFlag = FLAG_C;
+
+    if ( g_LSRTable[ idx ].byValue == 0 )
+      g_LSRTable[ idx ].byFlag |= FLAG_Z;
+
+    ++idx;
+  } while ( idx != 0 );
+
+  // Make a table ROL
+  for ( idx2 = 0; idx2 < 2; ++idx2 )
+  {
+    idx = 0;
+    do
+    {
+      g_ROLTable[ idx2 ][ idx ].byValue = ( idx << 1 ) | idx2;
+      g_ROLTable[ idx2 ][ idx ].byFlag = 0;
+
+      if ( idx > 127 )
+        g_ROLTable[ idx2 ][ idx ].byFlag = FLAG_C;
+
+      if ( g_ROLTable[ idx2 ][ idx ].byValue == 0 )
+        g_ROLTable[ idx2 ][ idx ].byFlag |= FLAG_Z;
+      else
+      if ( g_ROLTable[ idx2 ][ idx ].byValue & 0x80 )
+        g_ROLTable[ idx2 ][ idx ].byFlag |= FLAG_N;
+
+      ++idx;
+    } while ( idx != 0 );
+  }
+
+  // Make a table ROR
+  for ( idx2 = 0; idx2 < 2; ++idx2 )
+  {
+    idx = 0;
+    do
+    {
+      g_RORTable[ idx2 ][ idx ].byValue = ( idx >> 1 ) | ( idx2 << 7 );
+      g_RORTable[ idx2 ][ idx ].byFlag = 0;
+
+      if ( idx & 1 )
+        g_RORTable[ idx2 ][ idx ].byFlag = FLAG_C;
+
+      if ( g_RORTable[ idx2 ][ idx ].byValue == 0 )
+        g_RORTable[ idx2 ][ idx ].byFlag |= FLAG_Z;
+      else
+      if ( g_RORTable[ idx2 ][ idx ].byValue & 0x80 )
+        g_RORTable[ idx2 ][ idx ].byFlag |= FLAG_N;
+
+      ++idx;
+    } while ( idx != 0 );
+  }
+}
+
+/*===================================================================*/
+/*                                                                   */
+/*                K6502_Reset() : Reset a CPU                        */
+/*                                                                   */
+/*===================================================================*/
+void K6502_Reset()
+{
+/*
+ *  Reset a CPU
+ *
+ */
+
+  // Reset Registers
+  PC = K6502_ReadW( VECTOR_RESET );
+  SP = 0xFF;
+  A = X = Y = 0;
+  F = FLAG_Z | FLAG_R;
+
+  // Set up the state of the Interrupt pin.
+  NMI_State = NMI_Wiring;
+  IRQ_State = IRQ_Wiring;
+
+  // Reset Passed Clocks
+  g_wPassedClocks = 0;
+}
+
+/*===================================================================*/
+/*                                                                   */
+/*    K6502_Set_Int_Wiring() : Set up wiring of the interrupt pin    */
+/*                                                                   */
+/*===================================================================*/
+void K6502_Set_Int_Wiring( BYTE byNMI_Wiring, BYTE byIRQ_Wiring )
+{
+/*
+ * Set up wiring of the interrupt pin
+ *
+ */
+
+  NMI_Wiring = byNMI_Wiring;
+  IRQ_Wiring = byIRQ_Wiring;
+}
+
+int dbgstep = 0;
+int check_userbutton();
+
+/*===================================================================*/
+/*                                                                   */
+/*  K6502_Step() :                                                   */
+/*          Only the specified number of the clocks execute Op.      */
+/*                                                                   */
+/*===================================================================*/
+void K6502_Step( WORD wClocks )
+{
+/*
+ *  Only the specified number of the clocks execute Op.
+ *
+ *  Parameters
+ *    WORD wClocks              (Read)
+ *      The number of the clocks
+ */
+
+  BYTE byCode;
+
+  WORD wA0;
+  BYTE byD0;
+  BYTE byD1;
+  WORD wD0;
+
+  // Dispose of it if there is an interrupt requirement
+  if ( NMI_State != NMI_Wiring )
+  {
+    // NMI Interrupt
+    CLK( 7 );
+
+    PUSHW( PC );
+    PUSH( F & ~FLAG_B );
+
+    RSTF( FLAG_D );
+
+    PC = K6502_ReadW( VECTOR_NMI );
+  }
+  else
+  if ( IRQ_State != IRQ_Wiring )
+  {
+    // IRQ Interrupt
+    // Execute IRQ if an I flag isn't being set
+    if ( !( F & FLAG_I ) )
+    {
+      CLK( 7 );
+
+      PUSHW( PC );
+      PUSH( F & ~FLAG_B );
+
+      RSTF( FLAG_D );
+      SETF( FLAG_I );
+    
+      PC = K6502_ReadW( VECTOR_IRQ );
+    }
+  }
+
+  NMI_State = NMI_Wiring;
+  IRQ_State = IRQ_Wiring;
+
+  // It has a loop until a constant clock passes
+  while ( g_wPassedClocks < wClocks )
+  {
+    // Read an instruction
+    byCode = K6502_Read( PC++ );
+ 
+    //if (dbgstep % 10000 == 0)
+    //{
+    //    printf("%8d PC:%4x Code:%2x SP:%2x F:%2x A:%2x X:%2x Y:%2x\r\n", dbgstep, PC - 1, byCode, SP, F, A, X, Y);
+    //    while (check_userbutton() != 0) ;
+    //    wait(0.1);
+    //}
+    //dbgstep++;
+    
+    // Execute an instruction.
+    switch ( byCode )
+    {
+      case 0x00:  // BRK
+        ++PC; PUSHW( PC ); SETF( FLAG_B ); PUSH( F ); SETF( FLAG_I ); RSTF( FLAG_D ); PC = K6502_ReadW( VECTOR_IRQ ); CLK( 7 );
+        break;
+
+      case 0x01:  // ORA (Zpg,X)
+        ORA( A_IX ); CLK( 6 );
+        break;
+
+      case 0x05:  // ORA Zpg
+        ORA( A_ZP ); CLK( 3 );
+        break;
+
+      case 0x06:  // ASL Zpg
+        ASL( AA_ZP ); CLK( 5 );
+        break;
+
+      case 0x08:  // PHP
+        PUSH( F ); CLK( 3 );
+        break;
+
+      case 0x09:  // ORA #Oper
+        ORA( A_IMM ); CLK( 2 );
+        break;
+
+      case 0x0A:  // ASL A
+        ASLA; CLK( 2 );
+        break;
+
+      case 0x0D:  // ORA Abs
+        ORA( A_ABS ); CLK( 4 );
+        break;
+
+      case 0x0e:  // ASL Abs 
+        ASL( AA_ABS ); CLK( 6 );
+        break;
+
+      case 0x10: // BPL Oper
+        BRA( !( F & FLAG_N ) );
+        break;
+
+      case 0x11: // ORA (Zpg),Y
+        ORA( A_IY ); CLK( 5 );
+        break;
+
+      case 0x15: // ORA Zpg,X
+        ORA( A_ZPX ); CLK( 4 );
+        break;
+
+      case 0x16: // ASL Zpg,X
+        ASL( AA_ZPX ); CLK( 6 );
+        break;
+
+      case 0x18: // CLC
+        RSTF( FLAG_C ); CLK( 2 );
+        break;
+
+      case 0x19: // ORA Abs,Y
+        ORA( A_ABSY ); CLK( 4 );
+        break;
+
+      case 0x1D: // ORA Abs,X
+        ORA( A_ABSX ); CLK( 4 );
+        break;
+
+      case 0x1E: // ASL Abs,X
+        ASL( AA_ABSX ); CLK( 7 );
+        break;
+
+      case 0x20: // JSR Abs
+        JSR; CLK( 6 );
+        break;
+
+      case 0x21: // AND (Zpg,X)
+        AND( A_IX ); CLK( 6 );
+        break;
+
+      case 0x24: // BIT Zpg
+        BIT( A_ZP ); CLK( 3 );
+        break;
+
+      case 0x25: // AND Zpg
+        AND( A_ZP ); CLK( 3 );
+        break;
+
+      case 0x26: // ROL Zpg
+        ROL( AA_ZP ); CLK( 5 );
+        break;
+
+      case 0x28: // PLP
+        POP( F ); SETF( FLAG_R ); CLK( 4 );
+        break;
+
+      case 0x29: // AND #Oper
+        AND( A_IMM ); CLK( 2 );
+        break;
+
+      case 0x2A: // ROL A
+        ROLA; CLK( 2 );
+        break;
+
+      case 0x2C: // BIT Abs
+        BIT( A_ABS ); CLK( 4 );
+        break;
+
+      case 0x2D: // AND Abs 
+        AND( A_ABS ); CLK( 4 );
+        break;
+
+      case 0x2E: // ROL Abs
+        ROL( AA_ABS ); CLK( 6 );
+        break;
+
+      case 0x30: // BMI Oper 
+        BRA( F & FLAG_N );
+        break;
+
+      case 0x31: // AND (Zpg),Y
+        AND( A_IY ); CLK( 5 );
+        break;
+
+      case 0x35: // AND Zpg,X
+        AND( A_ZPX ); CLK( 4 );
+        break;
+
+      case 0x36: // ROL Zpg,X
+        ROL( AA_ZPX ); CLK( 6 );
+        break;
+
+      case 0x38: // SEC
+        SETF( FLAG_C ); CLK( 2 );
+        break;
+
+      case 0x39: // AND Abs,Y
+        AND( A_ABSY ); CLK( 4 );
+        break;
+
+      case 0x3D: // AND Abs,X
+        AND( A_ABSX ); CLK( 4 );
+        break;
+
+      case 0x3E: // ROL Abs,X
+        ROL( AA_ABSX ); CLK( 7 );
+        break;
+
+      case 0x40: // RTI
+        POP( F ); SETF( FLAG_R ); POPW( PC ); CLK( 6 );
+        break;
+
+      case 0x41: // EOR (Zpg,X)
+        EOR( A_IX ); CLK( 6 );
+        break;
+
+      case 0x45: // EOR Zpg
+        EOR( A_ZP ); CLK( 3 );
+        break;
+
+      case 0x46: // LSR Zpg
+        LSR( AA_ZP ); CLK( 5 );
+        break;
+
+      case 0x48: // PHA
+        PUSH( A ); CLK( 3 );
+        break;
+
+      case 0x49: // EOR #Oper
+        EOR( A_IMM ); CLK( 2 );
+        break;
+
+      case 0x4A: // LSR A
+        LSRA; CLK( 2 );
+        break;
+
+      case 0x4C: // JMP Abs
+        JMP( AA_ABS ); CLK( 3 );
+        break;
+
+      case 0x4D: // EOR Abs
+        EOR( A_ABS ); CLK( 4 );
+        break;
+
+      case 0x4E: // LSR Abs
+        LSR( AA_ABS ); CLK( 6 );
+        break;
+
+      case 0x50: // BVC
+        BRA( !( F & FLAG_V ) );
+        break;
+
+      case 0x51: // EOR (Zpg),Y
+        EOR( A_IY ); CLK( 5 );
+        break;
+
+      case 0x55: // EOR Zpg,X
+        EOR( A_ZPX ); CLK( 4 );
+        break;
+
+      case 0x56: // LSR Zpg,X
+        LSR( AA_ZPX ); CLK( 6 );
+        break;
+
+      case 0x58: // CLI
+        byD0 = F;
+        RSTF( FLAG_I ); CLK( 2 );
+        if ( ( byD0 & FLAG_I ) && IRQ_State == 0 )
+        {
+          // IRQ Interrupt
+          // Execute IRQ if an I flag isn't being set
+          if ( !( F & FLAG_I ) )
+          {
+            CLK( 7 );
+
+            PUSHW( PC );
+            PUSH( F & ~FLAG_B );
+
+            RSTF( FLAG_D );
+            SETF( FLAG_I );
+    
+            PC = K6502_ReadW( VECTOR_IRQ );
+          }
+        }
+        break;
+
+      case 0x59: // EOR Abs,Y
+        EOR( A_ABSY ); CLK( 4 );
+        break;
+
+      case 0x5D: // EOR Abs,X
+        EOR( A_ABSX ); CLK( 4 );
+        break;
+
+      case 0x5E: // LSR Abs,X
+        LSR( AA_ABSX ); CLK( 7 );
+        break;
+
+      case 0x60: // RTS
+        POPW( PC ); ++PC; CLK( 6 );
+        break;
+
+      case 0x61: // ADC (Zpg,X)
+        ADC( A_IX ); CLK( 6 );
+        break;
+
+      case 0x65: // ADC Zpg
+        ADC( A_ZP ); CLK( 3 );
+        break;
+
+      case 0x66: // ROR Zpg
+        ROR( AA_ZP ); CLK( 5 );
+        break;
+
+      case 0x68: // PLA
+        POP( A ); TEST( A ); CLK( 4 );
+        break;
+
+      case 0x69: // ADC #Oper
+        ADC( A_IMM ); CLK( 2 );
+        break;
+
+      case 0x6A: // ROR A
+        RORA; CLK( 2 );
+        break;
+
+      case 0x6C: // JMP (Abs)
+        JMP( K6502_ReadW( AA_ABS ) ); CLK( 5 );
+        break;
+
+      case 0x6D: // ADC Abs
+        ADC( A_ABS ); CLK( 4 );
+        break;
+
+      case 0x6E: // ROR Abs
+        ROR( AA_ABS ); CLK( 6 );
+        break;
+
+      case 0x70: // BVS
+        BRA( F & FLAG_V );
+        break;
+
+      case 0x71: // ADC (Zpg),Y
+        ADC( A_IY ); CLK( 5 );
+        break;
+
+      case 0x75: // ADC Zpg,X
+        ADC( A_ZPX ); CLK( 4 );
+        break;
+
+      case 0x76: // ROR Zpg,X
+        ROR( AA_ZPX ); CLK( 6 );
+        break;
+
+      case 0x78: // SEI
+        SETF( FLAG_I ); CLK( 2 );
+        break;
+
+      case 0x79: // ADC Abs,Y
+        ADC( A_ABSY ); CLK( 4 );
+        break;
+
+      case 0x7D: // ADC Abs,X
+        ADC( A_ABSX ); CLK( 4 );
+        break;
+
+      case 0x7E: // ROR Abs,X
+        ROR( AA_ABSX ); CLK( 7 );
+        break;
+
+      case 0x81: // STA (Zpg,X)
+        STA( AA_IX ); CLK( 6 );
+        break;
+      
+      case 0x84: // STY Zpg
+        STY( AA_ZP ); CLK( 3 );
+        break;
+
+      case 0x85: // STA Zpg
+        STA( AA_ZP ); CLK( 3 );
+        break;
+
+      case 0x86: // STX Zpg
+        STX( AA_ZP ); CLK( 3 );
+        break;
+
+      case 0x88: // DEY
+        --Y; TEST( Y ); CLK( 2 );
+        break;
+
+      case 0x8A: // TXA
+        A = X; TEST( A ); CLK( 2 );
+        break;
+
+      case 0x8C: // STY Abs
+        STY( AA_ABS ); CLK( 4 );
+        break;
+
+      case 0x8D: // STA Abs
+        STA( AA_ABS ); CLK( 4 );
+        break;
+
+      case 0x8E: // STX Abs
+        STX( AA_ABS ); CLK( 4 );
+        break;
+
+      case 0x90: // BCC
+        BRA( !( F & FLAG_C ) );
+        break;
+
+      case 0x91: // STA (Zpg),Y
+        STA( AA_IY ); CLK( 6 );
+        break;
+
+      case 0x94: // STY Zpg,X
+        STY( AA_ZPX ); CLK( 4 );
+        break;
+
+      case 0x95: // STA Zpg,X
+        STA( AA_ZPX ); CLK( 4 );
+        break;
+
+      case 0x96: // STX Zpg,Y
+        STX( AA_ZPY ); CLK( 4 );
+        break;
+
+      case 0x98: // TYA
+        A = Y; TEST( A ); CLK( 2 );
+        break;
+
+      case 0x99: // STA Abs,Y
+        STA( AA_ABSY ); CLK( 5 );
+        break;
+
+      case 0x9A: // TXS
+        SP = X; CLK( 2 );
+        break;
+
+      case 0x9D: // STA Abs,X
+        STA( AA_ABSX ); CLK( 5 );
+        break;
+
+      case 0xA0: // LDY #Oper
+        LDY( A_IMM ); CLK( 2 );
+        break;
+
+      case 0xA1: // LDA (Zpg,X)
+        LDA( A_IX ); CLK( 6 );
+        break;
+
+      case 0xA2: // LDX #Oper
+        LDX( A_IMM ); CLK( 2 );
+        break;
+
+      case 0xA4: // LDY Zpg
+        LDY( A_ZP ); CLK( 3 );
+        break;
+
+      case 0xA5: // LDA Zpg
+        LDA( A_ZP ); CLK( 3 );
+        break;
+
+      case 0xA6: // LDX Zpg
+        LDX( A_ZP ); CLK( 3 );
+        break;
+
+      case 0xA8: // TAY
+        Y = A; TEST( A ); CLK( 2 );
+        break;
+
+      case 0xA9: // LDA #Oper
+        LDA( A_IMM ); CLK( 2 );
+        break;
+
+      case 0xAA: // TAX
+        X = A; TEST( A ); CLK( 2 );
+        break;
+
+      case 0xAC: // LDY Abs
+        LDY( A_ABS ); CLK( 4 );
+        break;
+
+      case 0xAD: // LDA Abs
+        LDA( A_ABS ); CLK( 4 );
+        break;
+
+      case 0xAE: // LDX Abs
+        LDX( A_ABS ); CLK( 4 );
+        break;
+
+      case 0xB0: // BCS
+        BRA( F & FLAG_C );
+        break;
+
+      case 0xB1: // LDA (Zpg),Y
+        LDA( A_IY ); CLK( 5 );
+        break;
+
+      case 0xB4: // LDY Zpg,X
+        LDY( A_ZPX ); CLK( 4 );
+        break;
+
+      case 0xB5: // LDA Zpg,X
+        LDA( A_ZPX ); CLK( 4 );
+        break;
+
+      case 0xB6: // LDX Zpg,Y
+        LDX( A_ZPY ); CLK( 4 );
+        break;
+
+      case 0xB8: // CLV
+        RSTF( FLAG_V ); CLK( 2 );
+        break;
+
+      case 0xB9: // LDA Abs,Y
+        LDA( A_ABSY ); CLK( 4 );
+        break;
+
+      case 0xBA: // TSX
+        X = SP; TEST( X ); CLK( 2 );
+        break;
+
+      case 0xBC: // LDY Abs,X
+        LDY( A_ABSX ); CLK( 4 );
+        break;
+
+      case 0xBD: // LDA Abs,X
+        LDA( A_ABSX ); CLK( 4 );
+        break;
+
+      case 0xBE: // LDX Abs,Y
+        LDX( A_ABSY ); CLK( 4 );
+        break;
+
+      case 0xC0: // CPY #Oper
+        CPY( A_IMM ); CLK( 2 );
+        break;
+
+      case 0xC1: // CMP (Zpg,X)
+        CMP( A_IX ); CLK( 6 );
+        break;
+
+      case 0xC4: // CPY Zpg
+        CPY( A_ZP ); CLK( 3 );
+        break;
+
+      case 0xC5: // CMP Zpg
+        CMP( A_ZP ); CLK( 3 );
+        break;
+
+      case 0xC6: // DEC Zpg
+        DEC( AA_ZP ); CLK( 5 );
+        break;
+
+      case 0xC8: // INY
+        ++Y; TEST( Y ); CLK( 2 );
+        break;
+
+      case 0xC9: // CMP #Oper
+        CMP( A_IMM ); CLK( 2 );
+        break;
+
+      case 0xCA: // DEX
+        --X; TEST( X ); CLK( 2 );
+        break;
+
+      case 0xCC: // CPY Abs
+        CPY( A_ABS ); CLK( 4 );
+        break;
+
+      case 0xCD: // CMP Abs
+        CMP( A_ABS ); CLK( 4 );
+        break;
+
+      case 0xCE: // DEC Abs
+        DEC( AA_ABS ); CLK( 6 );
+        break;
+
+      case 0xD0: // BNE
+        BRA( !( F & FLAG_Z ) );
+        break;
+
+      case 0xD1: // CMP (Zpg),Y
+        CMP( A_IY ); CLK( 5 );
+        break;
+
+      case 0xD5: // CMP Zpg,X
+        CMP( A_ZPX ); CLK( 4 );
+        break;
+
+      case 0xD6: // DEC Zpg,X
+        DEC( AA_ZPX ); CLK( 6 );
+        break;
+
+      case 0xD8: // CLD
+        RSTF( FLAG_D ); CLK( 2 );
+        break;
+
+      case 0xD9: // CMP Abs,Y
+        CMP( A_ABSY ); CLK( 4 );
+        break;
+
+      case 0xDD: // CMP Abs,X
+        CMP( A_ABSX ); CLK( 4 );
+        break;
+
+      case 0xDE: // DEC Abs,X
+        DEC( AA_ABSX ); CLK( 7 );
+        break;
+
+      case 0xE0: // CPX #Oper
+        CPX( A_IMM ); CLK( 2 );
+        break;
+
+      case 0xE1: // SBC (Zpg,X)
+        SBC( A_IX ); CLK( 6 );
+        break;
+
+      case 0xE4: // CPX Zpg
+        CPX( A_ZP ); CLK( 3 );
+        break;
+
+      case 0xE5: // SBC Zpg
+        SBC( A_ZP ); CLK( 3 );
+        break;
+
+      case 0xE6: // INC Zpg
+        INC( AA_ZP ); CLK( 5 );
+        break;
+
+      case 0xE8: // INX
+        ++X; TEST( X ); CLK( 2 );
+        break;
+
+      case 0xE9: // SBC #Oper
+        SBC( A_IMM ); CLK( 2 );
+        break;
+
+      case 0xEA: // NOP
+        CLK( 2 );
+        break;
+
+      case 0xEC: // CPX Abs
+        CPX( A_ABS ); CLK( 4 );
+        break;
+
+      case 0xED: // SBC Abs
+        SBC( A_ABS ); CLK( 4 );
+        break;
+
+      case 0xEE: // INC Abs
+        INC( AA_ABS ); CLK( 6 );
+        break;
+
+      case 0xF0: // BEQ
+        BRA( F & FLAG_Z );
+        break;
+
+      case 0xF1: // SBC (Zpg),Y
+        SBC( A_IY ); CLK( 5 );
+        break;
+
+      case 0xF5: // SBC Zpg,X
+        SBC( A_ZPX ); CLK( 4 );
+        break;
+
+      case 0xF6: // INC Zpg,X
+        INC( AA_ZPX ); CLK( 6 );
+        break;
+
+      case 0xF8: // SED
+        SETF( FLAG_D ); CLK( 2 );
+        break;
+
+      case 0xF9: // SBC Abs,Y
+        SBC( A_ABSY ); CLK( 4 );
+        break;
+
+      case 0xFD: // SBC Abs,X
+        SBC( A_ABSX ); CLK( 4 );
+        break;
+
+      case 0xFE: // INC Abs,X
+        INC( AA_ABSX ); CLK( 7 );
+        break;
+
+      default:   // Unknown Instruction
+        CLK( 2 );
+        break;
+        
+    }  /* end of switch ( byCode ) */
+
+  }  /* end of while ... */
+
+  // Correct the number of the clocks
+  g_wPassedClocks -= wClocks;
+}
+
+// Addressing Op.
+// Data
+// Absolute,X
+static inline BYTE K6502_ReadAbsX(){ WORD wA0, wA1; wA0 = AA_ABS; wA1 = wA0 + X; CLK( ( wA0 & 0x0100 ) != ( wA1 & 0x0100 ) ); return K6502_Read( wA1 ); };
+// Absolute,Y
+static inline BYTE K6502_ReadAbsY(){ WORD wA0, wA1; wA0 = AA_ABS; wA1 = wA0 + Y; CLK( ( wA0 & 0x0100 ) != ( wA1 & 0x0100 ) ); return K6502_Read( wA1 ); };
+// (Indirect),Y
+static inline BYTE K6502_ReadIY(){ WORD wA0, wA1; wA0 = K6502_ReadZpW( K6502_Read( PC++ ) ); wA1 = wA0 + Y; CLK( ( wA0 & 0x0100 ) != ( wA1 & 0x0100 ) ); return K6502_Read( wA1 ); };
+
+/*===================================================================*/
+/*                                                                   */
+/*                  6502 Reading/Writing Operation                   */
+/*                                                                   */
+/*===================================================================*/
+#include "K6502_rw.h"
+
+
+