Browse Source

Merge newcore branch into master/trunk. Correct lots of warning. (now warning are threat as error by default)

Signed-off-by: Godzil <godzil@godzil.net>
godzil 12 years ago
parent
commit
bc65a7a4f0

+ 5 - 0
.gitignore

@@ -0,0 +1,5 @@
+#Temp files
+/build*
+
+*~
+*.swp

+ 1 - 1
CMakeLists.txt

@@ -10,7 +10,7 @@
 # $Revision$
 
 
-cmake_minimum_required (VERSION 2.4)
+cmake_minimum_required (VERSION 2.6)
 project (TINES)
 
 add_subdirectory (src)

+ 6 - 3
src/CMakeLists.txt

@@ -38,6 +38,9 @@ endif (APPLE)
 # Link & Compile flags
 ##########################
 
+set (CMAKE_C_FLAGS "-Wall -Wextra -Wno-unused-parameter -Werror ${PLATFORM_FLAGS}")
+set (CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-unused-parameter -Werror ${PLATFORM_FLAGS}")
+
 add_definitions (-DNO_DECIMAL -DFAST_RDOP)
 
 SET ( CMAKE_EXE_LINKER_FLAGS "-mmacosx-version-min=10.4")
@@ -105,10 +108,10 @@ if (TARGET_TI68k)
 elseif (APPLE AND ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
    add_subdirectory(os/macos)
 elseif (UNIX)
-   add_subdirectory(os/win32)
+   add_subdirectory(os/unix)
 else (TARGET_TI68k)
    #So we target UNIX like OS
-   add_subdirectory(os/unix)
+   add_subdirectory(os/win32)
 endif (TARGET_TI68k)
 
 
@@ -126,7 +129,7 @@ endif (USE_EFENCE)
 
 if (USE_ALLEGRO)
    target_link_libraries(tines debug alld-main)
-   target_link_libraries(tines optimized alleg-main)
+   #   target_link_libraries(tines)
    if (APPLE)
       find_library(COCOALIB Cocoa)
       target_link_libraries(tines ${COCOALIB})

+ 2 - 1
src/apu/CMakeLists.txt

@@ -9,4 +9,5 @@
 # $HeadURL$
 # $Revision$
 
-add_library(apu SndAlleg.c Sound.c)
+add_library(apu SndUnixT.c Sound.c)
+#add_library(apu SndAlleg.c Sound.c)

+ 9 - 5
src/apu/SndAlleg.c

@@ -43,7 +43,7 @@ static int MasterSwitch = (1<<SND_CHANNELS)-1;
 static int LoopFreq     = 25;
 static int NoiseGen     = 1;
 static int Suspended    = 0;
-
+static int SoundRun     = 0;
 static struct
 {
   int Type;                       /* Channel type (SND_*)             */
@@ -351,6 +351,7 @@ int InitSound(int Rate,int Verbose)
   pthread_detach(ThreadID);
 
   /* Done */
+  SoundRun = 1;
   if(Verbose) puts("OK");
   return(SoundRate=Rate);
 }
@@ -360,10 +361,13 @@ int InitSound(int Rate,int Verbose)
 /*************************************************************/
 void TrashSound(void)
 {
-  StopSound();
-  console_printf(Console_Default, "%s: Kill thread...\n", __func__);
-  if(ThreadID)    pthread_cancel(ThreadID);
-
+  if (SoundRun == 1)
+  {
+     StopSound();
+     console_printf(Console_Default, "%s: Kill thread...\n", __func__);
+     if(ThreadID)    pthread_cancel(ThreadID);
+  }
+  SoundRun = 0;
   SoundRate = 0;
   ThreadID  = 0;
 }

+ 9 - 8
src/apu/SndUnixT.c

@@ -10,8 +10,6 @@
 /**     commercially. Please, notify me, if you make any    **/
 /**     changes to this file.                               **/
 /*************************************************************/
-#ifdef UNIX
-
 #include "Sound.h"
 
 #include <stdlib.h>
@@ -21,6 +19,8 @@
 #include <pthread.h>
 #include <sys/ioctl.h>
 
+#include <os_dependent.h>
+
 #ifdef SUN_AUDIO  
 
 #include <sys/audioio.h>
@@ -106,7 +106,7 @@ static struct
   int Count;                      /* Phase counter                    */
 } CH[SND_CHANNELS];
 
-static void UnixSetWave(int Channel,signed char *Data,int Length,int Rate);
+static void UnixSetWave(int Channel, signed char *Data,int Length,int Freq);
 static void UnixSetSound(int Channel,int NewType);
 static void UnixDrum(int Type,int Force);
 static void UnixSetChannels(int Volume,int Switch);
@@ -221,6 +221,9 @@ static void *DSPLoop(void *Arg)
   unsigned char Buf[SND_BUFSIZE];
   register int J,I,K,L,M,N,L1,L2,A1,A2,V;
   int FreqCount;
+  int ret;
+
+  L = N = A2 = 0;
 
   for(J=0;J<SND_CHANNELS;J++)
   {
@@ -421,7 +424,7 @@ static void *DSPLoop(void *Arg)
       /* We'll block here until next DMA buffer becomes free. It happens 
       ** once per (1<<SND_BITS)/SoundRate seconds.
       */
-      write(SoundFD,Buf,SND_BUFSIZE);
+      ret = write(SoundFD,Buf,SND_BUFSIZE);
 #endif
     }
   }
@@ -531,13 +534,13 @@ void UnixSetSound(int Channel,int NewType)
 /** waveform to be an instrument or set it to the waveform  **/
 /** own playback rate.                                      **/
 /*************************************************************/
-void UnixSetWave(int Channel,signed char *Data,int Length,int Rate)
+void UnixSetWave(int Channel, signed char *Data, int Length, int Freq)
 {
   if((Channel<0)||(Channel>=SND_CHANNELS)||(Length<=0)) return;
 
   CH[Channel].Type   = SND_WAVE;
   CH[Channel].Length = Length;
-  CH[Channel].Rate   = Rate;
+  CH[Channel].Rate   = Freq;
   CH[Channel].Pos    = 0;
   CH[Channel].Count  = 0;
   CH[Channel].Data   = Data;
@@ -550,5 +553,3 @@ void UnixDrum(int Type,int Force)
 {
   /* This function is currently empty */
 }
-
-#endif /* UNIX */

+ 2 - 2
src/apu/Sound.c

@@ -36,7 +36,7 @@ struct SndDriverStruct SndDriver =
   (void (*)(int,int))0,
   (void (*)(int,int))0,
   (void (*)(int,int,int))0,
-  (void (*)(int,const signed char *,int,int))0,
+  (void (*)(int,signed char *,int,int))0,
   (const signed char *(*)(int))0
 };
 
@@ -167,7 +167,7 @@ void SetChannels(int Volume,int Switch)
 /** waveform to be an instrument or set it to the waveform  **/
 /** own playback rate.                                      **/
 /*************************************************************/
-void SetWave(int Channel,const signed char *Data,int Length,int Rate)
+void SetWave(int Channel,signed char *Data,int Length,int Rate)
 {
   if((Channel<0)||(Length<=0)) return;
 

+ 503 - 98
src/corecpu/corecpu.c

@@ -12,9 +12,12 @@
  *
  */
 
+/* TODO: Add Inst/MemAccess breakpoints */
+
 /* Depending on the OS, one of these provide the malloc function */
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdint.h>
 #include <string.h>
 
 #include <os_dependent.h>
@@ -26,14 +29,68 @@
 //#define TRACE_INSTRUCTIONS
 
 #ifdef TRACE_INSTRUCTIONS
-#define TRACEi(trace) do { console_printf(Console_Debug, "$%04X - ", cpu->reg_PC - 1); console_printf_d trace ; console_printf(Console_Debug, "\n"); } while(0)
-#define TRACEiE(trace) do { console_printf(Console_Debug, "$%04X - ", cpu->reg_PC - 1); console_printf_d trace ; console_printf(Console_Debug, "\n"); } while(0)
+#define TRACEi(trace) do { console_printf(Console_Debug, ">> $%04X - ", cpu->reg_PC-1); console_printf_d trace ; console_printf(Console_Debug, "\n"); } while(0)
+#define TRACEiE(trace) do { console_printf(Console_Debug, ">> $%04X - ", cpu->reg_PC-1); console_printf_d trace ; console_printf(Console_Debug, "\n"); } while(0)
 #else
 #define TRACEi(trace) { }
 //#define TRACEiE(trace) { }
-#define TRACEiE(trace) do { console_printf(Console_Debug, "$%04X - ", cpu->reg_PC - 1); console_printf_d trace ; console_printf(Console_Debug, "\n"); } while(0)
+#define TRACEiE(trace) do { console_printf(Console_Debug, ">> $%04X - ", cpu->reg_PC-1); console_printf_d trace ; console_printf(Console_Debug, "\n"); } while(0)
 #endif
 
+/*
+ * IP_ == "Instruction Parameter"
+ * nP: No parameters
+ * iM: Immediate
+ * iX: Indirect by X
+ * iY: Indirect by Y
+ * zP: Zero Page
+ * zX: Zero Page Indexec by X
+ * zY: Zero Page Indexec by Y
+ * iD: Indirect Double
+ * aB: Absolute
+ * aX: Absolute by X
+ * aY: Absolute by Y 
+ * rE: Relative
+ */
+#define IP_nP "N"
+#define IP_iM "I"
+#define IP_iX "X"
+#define IP_iY "Y"
+#define IP_zP "0"
+#define IP_zX "z"
+#define IP_zY "Z"
+#define IP_iD "D"
+#define IP_aB "A"
+#define IP_aX "x"
+#define IP_aY "y"
+#define IP_rE "R"
+
+#define IP_nPc 'N'
+#define IP_iMc 'I'
+#define IP_iXc 'X'
+#define IP_iYc 'Y'
+#define IP_zPc '0'
+#define IP_zXc 'z'
+#define IP_zYc 'Z'
+#define IP_iDc 'D'
+#define IP_aBc 'A'
+#define IP_aXc 'x'
+#define IP_aYc 'y'
+#define IP_rEc 'R'
+
+#define IPf_nP ""
+#define IPf_iM " $%02X"
+#define IPf_iX " ($%02X,X)"
+#define IPf_iY " ($%02X),Y"
+#define IPf_zP " $%02X"
+#define IPf_zX " $%02X,X"
+#define IPf_zY " $%02X,Y"
+#define IPf_iD " ($%02X%02X)"
+#define IPf_aB " $%02X%02X"
+#define IPf_aX " $%02X%02X,X"
+#define IPf_aY " $%02X%02X,Y"
+#define IPf_rE " $%02X%02X"
+
 #define _INTERNAL_QUICK6502_CORECPU_
 #include "corecpu.h"
 
@@ -49,15 +106,15 @@
 #define MEMORY_READ_ZP() cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC++))
 
 #define MEMORY_READ_IX() cpu->memory_read( (cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC  ) + cpu->reg_X    ) & 0xFF) |\
-                                           (cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC++) + cpu->reg_X + 1) << 8) )
+                                           (cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC  ) + cpu->reg_X + 1) << 8) ); cpu->reg_PC++
 #define MEMORY_READ_IY() cpu->memory_read( ( cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC  )    ) |\
-                                            (cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC++) + 1) << 8) ) + cpu->reg_Y  )
+                                            (cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC  ) + 1) << 8) ) + cpu->reg_Y  ); cpu->reg_PC++
 
 #define MEMORY_READ_ZX() cpu->memory_page0_read( (cpu->memory_opcode_read(cpu->reg_PC++) + cpu->reg_X) )
 #define MEMORY_READ_ZY() cpu->memory_page0_read( (cpu->memory_opcode_read(cpu->reg_PC++) + cpu->reg_Y) )
 
-#define MEMORY_READ_AB() cpu->memory_read( ((cpu->memory_opcode_read(cpu->reg_PC++)     ) |\
-                                            (cpu->memory_opcode_read(cpu->reg_PC++) << 8) ))
+#define MEMORY_READ_AB() cpu->memory_read( ((cpu->memory_opcode_read(cpu->reg_PC  )     ) |\
+                                            (cpu->memory_opcode_read(cpu->reg_PC+1) << 8) )); cpu->reg_PC += 2
 
 #define MEMORY_READ_AX() cpu->memory_read( ((op1     ) |\
                                             (op2 << 8) ) + cpu->reg_X)
@@ -68,26 +125,26 @@
 #define MEMORY_WRITE_ZP(val) cpu->memory_page0_write(cpu->memory_opcode_read(cpu->reg_PC++), val)
 
 #define MEMORY_WRITE_IX(val) cpu->memory_write( (cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC  ) + cpu->reg_X    ) & 0xFF) |\
-                                                 (cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC++) + cpu->reg_X + 1) << 8)   , val)
+                                                 (cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC  ) + cpu->reg_X + 1) << 8)   , val); cpu->reg_PC++
 #define MEMORY_WRITE_IY(val) cpu->memory_write( ( cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC  )    ) |\
-                                                 (cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC++) + 1) << 8) ) + cpu->reg_Y , val)
+                                                 (cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC  ) + 1) << 8) ) + cpu->reg_Y , val); cpu->reg_PC++
 
 #define MEMORY_WRITE_ZX(val) cpu->memory_page0_write( (cpu->memory_opcode_read(cpu->reg_PC++) + cpu->reg_X), val)
 #define MEMORY_WRITE_ZY(val) cpu->memory_page0_write( (cpu->memory_opcode_read(cpu->reg_PC++) + cpu->reg_Y), val)
 
-#define MEMORY_WRITE_AB(val) cpu->memory_write( ((cpu->memory_opcode_read(cpu->reg_PC++)     ) |\
-                                                 (cpu->memory_opcode_read(cpu->reg_PC++) << 8) ), val)
+#define MEMORY_WRITE_AB(val) cpu->memory_write( ((cpu->memory_opcode_read(cpu->reg_PC  )     ) |\
+                                                 (cpu->memory_opcode_read(cpu->reg_PC+1) << 8) ), val); cpu->reg_PC += 2
 
-#define MEMORY_WRITE_AX(val) cpu->memory_write( ((cpu->memory_opcode_read(cpu->reg_PC++)     ) |\
-                                                 (cpu->memory_opcode_read(cpu->reg_PC++) << 8) ) + cpu->reg_X, val)
-#define MEMORY_WRITE_AY(val) cpu->memory_write( ((cpu->memory_opcode_read(cpu->reg_PC++)     ) |\
-                                                 (cpu->memory_opcode_read(cpu->reg_PC++) << 8) ) + cpu->reg_Y, val)
+#define MEMORY_WRITE_AX(val) cpu->memory_write( ((cpu->memory_opcode_read(cpu->reg_PC  )     ) |\
+                                                 (cpu->memory_opcode_read(cpu->reg_PC+1) << 8) ) + cpu->reg_X, val); cpu->reg_PC += 2 
+#define MEMORY_WRITE_AY(val) cpu->memory_write( ((cpu->memory_opcode_read(cpu->reg_PC  )     ) |\
+                                                 (cpu->memory_opcode_read(cpu->reg_PC+1) << 8) ) + cpu->reg_Y, val); cpu->reg_PC += 2
 
 
 #define PUSH_S(value) cpu->memory_stack_write(0x100 | (cpu->reg_S--), value)
 #define POP_S()      (cpu->memory_stack_read (0x100 | (++cpu->reg_S)       ))
 
-#ifdef NO_DECIMAL
+#ifdef Q6502_NO_DECIMAL
 
 #define ADC_OPERATION(read) do {\
    unsigned short tmp = 0; unsigned char v = read; \
@@ -110,7 +167,7 @@
 } while(0)
 
 #else
-#error Quick6502 doesn't actually support DECIMAL mode
+#error Quick6502 doesn t actually support DECIMAL mode
 #endif
 
 
@@ -346,7 +403,7 @@ void quick6502_int(quick6502_cpu *cpu, quick6502_signal signal)
        PUSH_S((cpu->reg_PC >> 8) & 0xFF   );
        PUSH_S((cpu->reg_PC     ) & 0xFF   );
        PUSH_S( cpu->reg_P                 );
-       cpu->reg_P = cpu->reg_P | Q6502_I_FLAG & ~Q6502_B_FLAG;
+       cpu->reg_P = (cpu->reg_P | Q6502_I_FLAG) & ~Q6502_B_FLAG;
 
        cpu->reg_PC = (cpu->memory_read(Q6502_NMI_LOW)) | (cpu->memory_read(Q6502_NMI_HIGH)<<8);
        
@@ -363,10 +420,10 @@ void quick6502_int(quick6502_cpu *cpu, quick6502_signal signal)
 void quick6502_dump(quick6502_cpu *cpu, FILE * fp)
 {
    short i;
-   char instr[20];
+   char instr[100];
    /* Display registers */
    fprintf(fp, 
-       "Quick6502: PC:$%04X A:$%02X X:$%02X Y:$%02X S:$%02X P:$%02X P:[%c%c%c%c%c%c%c%c]\n",
+       "## Quick6502: PC:$%04X A:$%02X X:$%02X Y:$%02X S:$%02X P:$%02X [%c%c%c%c%c%c%c%c]\n",
        cpu->reg_PC, cpu->reg_A, cpu->reg_X, cpu->reg_Y, cpu->reg_S, cpu->reg_P,
        cpu->reg_P&Q6502_N_FLAG ? 'N':'.',
        cpu->reg_P&Q6502_V_FLAG ? 'V':'.',
@@ -379,28 +436,59 @@ void quick6502_dump(quick6502_cpu *cpu, FILE * fp)
          );
 
    /* Display stack */
-   fprintf(fp, "Quick6502: Stack: [ ");
+   fprintf(fp, "## Quick6502: Stack: [ ");
    for (i = cpu->reg_S+1; i < 0x100; i++)
    {
-    fprintf(fp, "$%02X ", cpu->memory_opcode_read(0x100 | i));
+    fprintf(fp, "$%02X ", cpu->memory_read(0x100 | i));
    }
    fprintf(fp, "] Run:%c Cycle:%ld\n", cpu->running?'Y':'N', cpu->cycle_done);
-
-   quick6502_getinstruction(cpu, cpu->reg_PC, instr);
-   fprintf(fp, "Quick6502: Instruction at PC: %s\n", instr);
-}
-
-/** Get current instruction name at specified address and put it into buffer */
-void quick6502_getinstruction(quick6502_cpu *cpu, unsigned short addr, char *buffer)
-{
-   buffer[0] = 0;
-}
+   
+   fprintf(fp, "## Quick6502: InstrMem: [ ");
+   for (i = 0; i < 0x5; i++)
+   {
+    fprintf(fp, "$%02X ", cpu->memory_opcode_read(cpu->reg_PC + i));
+   }
+   fprintf(fp, "]\n");
+
+   quick6502_getinstruction(cpu, (1==1), cpu->reg_PC, instr, NULL);
+   fprintf(fp, "## $%04X: %s\n", cpu->reg_PC, instr);
+}
+
+typedef enum InstructionNameTag
+{
+   n_ILG = 0, n_NOP,
+   n_CLI, n_SEI, n_CLC, n_SEC, n_CLD, n_SED, n_CLV,
+   n_LDA, n_LDX, n_LDY, n_STA, n_STX, n_STY,
+   n_TXA, n_TAX, n_TAY, n_TYA, n_TSX, n_TXS,
+   n_PHA, n_PLA, n_PHP, n_PLP,
+   n_DEX, n_DEY, n_INX, n_INY, n_DEC, n_INC,
+   n_JSR, n_RTS, n_JMP, n_BRK, n_RTI, 
+   n_BCC, n_BCS, n_BEQ, n_BNE, n_BHI, n_BPL, n_BVS, n_BVC, n_BMI,
+   n_EOR, n_AND, n_BIT, n_ORA, n_ADC, n_SBC,
+   n_ROL, n_ROR, n_ASL, n_LSR,
+   n_CMP, n_CPX, n_CPY,
+} InstructionNameTag;
+
+char *InstructionName[] =
+{
+   "ILLEGAL", "NOP",
+   "CLI", "SEI", "CLC", "SEC", "CLD", "SED", "CLV",
+   "LDA", "LDX", "LDY", "STA", "STX", "STY",
+   "TXA", "TAX", "TAY", "TYA", "TSX", "TXS",
+   "PHA", "PLA", "PHP", "PLP",
+   "DEX", "DEY", "INX", "INY", "DEC", "INC",
+   "JSR", "RTS", "JMP", "BRK", "RTI",
+   "BCC", "BCS", "BEQ", "BNE", "BHI", "BPL", "BVS", "BVC", "BVS",
+   "EOR", "AND", "BIT", "ORA", "ADC", "SBC",
+   "ROL", "ROR", "ASL", "LSR",
+   "CMP", "CPX", "CPY",
+};
 
 /**
  * Free the CPU 
  *
  * This function will free the CPU only if it's not currently used, it will
- * return !0 if everything goes well and 0 if the free is impossible
+ * return 0 if everything goes well and !0 if the free is impossible
  */
 int quick6502_free(quick6502_cpu *cpu)
 {
@@ -447,52 +535,52 @@ INSTRUCTION(ILLEG)
 }
 
 /** 58 : CLI - CLear Interrupt **/
-INSTRUCTION(CLIiM)
+INSTRUCTION(CLInP)
 {
-   TRACEi(("CLC"));
+   TRACEi(("CLI"));
    cpu->reg_P &= ~Q6502_I_FLAG;
 }
 /** 78 : SEI - SEt Interrupt **/
-INSTRUCTION(SEIiM)
+INSTRUCTION(SEInP)
 {
    TRACEi(("SEI"));
    cpu->reg_P |= Q6502_I_FLAG;
 }
 
 /** 18 : CLC - CLear Carry **/
-INSTRUCTION(CLCiM)
+INSTRUCTION(CLCnP)
 {
    TRACEi(("CLC"));
    cpu->reg_P &= ~Q6502_C_FLAG;
 }
 /** 38 : SEC - SEt Carry **/
-INSTRUCTION(SECiM)
+INSTRUCTION(SECnP)
 {
    TRACEi(("SEC"));
    cpu->reg_P |= Q6502_C_FLAG;
 }
 
 /** D8 : CLD - CLear Decimal **/
-INSTRUCTION(CLDiM)
+INSTRUCTION(CLDnP)
 {
    TRACEi(("CLD"));
    cpu->reg_P &= ~Q6502_D_FLAG;
 }
 /** F8 : SED - SEt Decimal **/
-INSTRUCTION(SEDiM)
+INSTRUCTION(SEDnP)
 {
    TRACEi(("SED"));
    cpu->reg_P |= Q6502_D_FLAG;
 }
 /** B8 : CLV - CLear oVerflo **/
-INSTRUCTION(CLViM)
+INSTRUCTION(CLVnP)
 {
    TRACEi(("CLV"));
    cpu->reg_P &= ~Q6502_V_FLAG;
 }
 
 /** EA : NOP - NO oPeration **/
-INSTRUCTION(NOPiM)
+INSTRUCTION(NOPnP)
 {
    TRACEi(("NOP"));
 }
@@ -752,7 +840,7 @@ INSTRUCTION(STYaB)
 /**** Register functions ****/
 
 /** AA : TAX - Transfer A to X **/
-INSTRUCTION(TAXiM)
+INSTRUCTION(TAXnP)
 {
    TRACEi(("TAX"));
    cpu->reg_X = cpu->reg_A;
@@ -760,7 +848,7 @@ INSTRUCTION(TAXiM)
 }
 
 /** 8A : TXA - Transfer X to A **/
-INSTRUCTION(TXAiM)
+INSTRUCTION(TXAnP)
 {
    TRACEi(("TXA"));
    cpu->reg_A = cpu->reg_X;
@@ -768,7 +856,7 @@ INSTRUCTION(TXAiM)
 }
 
 /** A8 : TAY - Transfer A to Y **/
-INSTRUCTION(TAYiM)
+INSTRUCTION(TAYnP)
 {
    TRACEi(("TAY"));
    cpu->reg_Y = cpu->reg_A;
@@ -776,7 +864,7 @@ INSTRUCTION(TAYiM)
 }
 
 /** 98 : TYA - Transfer Y to A **/
-INSTRUCTION(TYAiM)
+INSTRUCTION(TYAnP)
 {
    TRACEi(("TYA"));
    cpu->reg_A = cpu->reg_Y;
@@ -784,7 +872,7 @@ INSTRUCTION(TYAiM)
 }
 
 /* BA : TSX - Transfer S to X **/
-INSTRUCTION(TSXiM)
+INSTRUCTION(TSXnP)
 {
    TRACEi(("TSX"));
    cpu->reg_X = cpu->reg_S;
@@ -792,7 +880,7 @@ INSTRUCTION(TSXiM)
 }
 
 /** 9A : TXS - Transfer X to S **/
-INSTRUCTION(TXSiM)
+INSTRUCTION(TXSnP)
 {
    TRACEi(("TXS"));
    cpu->reg_S = cpu->reg_X;
@@ -801,7 +889,7 @@ INSTRUCTION(TXSiM)
 /**** Simple register operation instructions ****/
 
 /** CA : DEX - DEcrement X **/
-INSTRUCTION(DEXiM)
+INSTRUCTION(DEXnP)
 {
    TRACEi(("DEX"));
    cpu->reg_X --;
@@ -809,7 +897,7 @@ INSTRUCTION(DEXiM)
 }
 
 /** 88 : DEY - DEcrement Y **/
-INSTRUCTION(DEYiM)
+INSTRUCTION(DEYnP)
 {
    TRACEi(("DEY"));
    cpu->reg_Y --;
@@ -817,7 +905,7 @@ INSTRUCTION(DEYiM)
 }
 
 /** E8 : INX - INcrement X **/
-INSTRUCTION(INXiM)
+INSTRUCTION(INXnP)
 {
    TRACEi(("INX"));
    cpu->reg_X ++;
@@ -825,7 +913,7 @@ INSTRUCTION(INXiM)
 }
 
 /** C8 : INY - INcrement Y **/
-INSTRUCTION(INYiM)
+INSTRUCTION(INYnP)
 {
    TRACEi(("INY"));
    cpu->reg_Y ++;
@@ -835,14 +923,14 @@ INSTRUCTION(INYiM)
 /**** Stack related instructions ****/
 
 /** 48 : PHA - PusH A */
-INSTRUCTION(PHAiM)
+INSTRUCTION(PHAnP)
 {
    TRACEi(("PHA"));
    PUSH_S(cpu->reg_A);
 }
 
 /** 68 : PLA - PuLl A */
-INSTRUCTION(PLAiM)
+INSTRUCTION(PLAnP)
 {
    TRACEi(("PLA"));
    cpu->reg_A = POP_S();
@@ -850,14 +938,14 @@ INSTRUCTION(PLAiM)
 }
 
 /** 08 : PHP - PusH P */
-INSTRUCTION(PHPiM)
+INSTRUCTION(PHPnP)
 {
    TRACEi(("PHP"));
    PUSH_S((cpu->reg_P | Q6502_R_FLAG | Q6502_B_FLAG));
 }
 
 /** 28 : PLP - PuLl P */
-INSTRUCTION(PLPiM)
+INSTRUCTION(PLPnP)
 {
    TRACEi(("PLP"));
    cpu->reg_P = POP_S() & ~(Q6502_R_FLAG | Q6502_B_FLAG);
@@ -880,10 +968,11 @@ INSTRUCTION(JSRaB)
 }
 
 /** 60 : RTS - ReTurn from Subrutine */
-INSTRUCTION(RTSiM)
+INSTRUCTION(RTSnP)
 {
    TRACEi(("RTS"));
-   cpu->reg_PC = POP_S() | (POP_S() << 8);
+   cpu->reg_PC = POP_S();
+   cpu->reg_PC |= (POP_S() << 8);
    cpu->reg_PC ++;
 }
 
@@ -891,7 +980,7 @@ INSTRUCTION(RTSiM)
 INSTRUCTION(JMPaB)
 {
    TRACEi(("JMP $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC)));
-   cpu->reg_PC = cpu->memory_opcode_read(cpu->reg_PC++) | (cpu->memory_opcode_read(cpu->reg_PC) << 8);
+   cpu->reg_PC = cpu->memory_opcode_read(cpu->reg_PC) | (cpu->memory_opcode_read(cpu->reg_PC+1) << 8);
 }
 
 /** 6C : JMP ($xxxx) - JuMP inconditionaly to ($xxxx) **/
@@ -904,7 +993,7 @@ INSTRUCTION(JMPiD)
 }
 
 /** 00 : BRK - BReaK **/
-INSTRUCTION(BRKiM)
+INSTRUCTION(BRKnP)
 {
    TRACEi(("BRK"));
    cpu->reg_PC++;
@@ -917,11 +1006,12 @@ INSTRUCTION(BRKiM)
 }
 
 /** 40 : RTI - ReTurn from Interruption **/
-INSTRUCTION(RTIiM)
+INSTRUCTION(RTInP)
 {
    TRACEi(("RTI"));
    cpu->reg_P = POP_S();
-   cpu->reg_PC = POP_S() | (POP_S() << 8);
+   cpu->reg_PC  = POP_S();
+   cpu->reg_PC |= (POP_S() << 8);
 
    if (cpu->int_pending != 0)
    {
@@ -935,7 +1025,7 @@ INSTRUCTION(BCCrE)
    TRACEi(("BCC $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
    if (!(cpu->reg_P & Q6502_C_FLAG))
    {
-      cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC++) + 1;
+      cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1;
       /* Need to set timing */
 
       /* +1 is same page */
@@ -952,7 +1042,7 @@ INSTRUCTION(BCSrE)
    TRACEi(("BCS $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
    if (cpu->reg_P & Q6502_C_FLAG)
    {
-      cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC ++) + 1;
+      cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1;
       /* Need to set timing */
 
       /* +1 is same page */
@@ -969,7 +1059,7 @@ INSTRUCTION(BEQrE)
    TRACEi(("BEQ $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
    if (cpu->reg_P & Q6502_Z_FLAG)
    {
-      cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC ++) + 1;
+      cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1;
       /* Need to set timing */
 
       /* +1 is same page */
@@ -986,7 +1076,7 @@ INSTRUCTION(BMIrE)
    TRACEi(("BMI $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
    if (cpu->reg_P & Q6502_N_FLAG)
    {
-      cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC ++) + 1;
+      cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1;
       /* Need to set timing */
 
       /* +1 is same page */
@@ -1003,7 +1093,7 @@ INSTRUCTION(BNErE)
    TRACEi(("BNE $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
    if (!(cpu->reg_P & Q6502_Z_FLAG))
    {
-      cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC ++) + 1;
+      cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1;
       /* Need to set timing */
 
       /* +1 is same page */
@@ -1020,7 +1110,7 @@ INSTRUCTION(BPLrE)
    TRACEi(("BPL $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
    if (!(cpu->reg_P & Q6502_N_FLAG))
    {
-      cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC ++) + 1;
+      cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1;
       /* Need to set timing */
 
       /* +1 is same page */
@@ -1037,7 +1127,7 @@ INSTRUCTION(BVCrE)
    TRACEi(("BVC $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
    if (!(cpu->reg_P & Q6502_V_FLAG))
    {
-      cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC ++) + 1;
+      cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1;
       /* Need to set timing */
 
       /* +1 is same page */
@@ -1054,7 +1144,7 @@ INSTRUCTION(BVSrE)
    TRACEi(("BVS $%04X", cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1));
    if (cpu->reg_P & Q6502_V_FLAG)
    {
-      cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC ++) + 1;
+      cpu->reg_PC += (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1;
       /* Need to set timing */
 
       /* +1 is same page */
@@ -1515,28 +1605,28 @@ INSTRUCTION(BITaB)
 }
 
 /** 2A : ROL A **/
-INSTRUCTION(ROLiM)
+INSTRUCTION(ROLnP)
 {
    TRACEi(("ROL A"));
    ROL_OPERATION(cpu->reg_A);
 }
 
 /** 6A : ROR A **/
-INSTRUCTION(RORiM)
+INSTRUCTION(RORnP)
 {
    TRACEi(("ROR A"));
    ROR_OPERATION(cpu->reg_A);
 }
 
 /** 0A : ASL A **/
-INSTRUCTION(ASLiM)
+INSTRUCTION(ASLnP)
 {
    TRACEi(("ASL A"));
    ASL_OPERATION(cpu->reg_A);
 }
 
 /** 4A : LSR A **/
-INSTRUCTION(LSRiM)
+INSTRUCTION(LSRnP)
 {
    TRACEi(("LSR A"));
    LSR_OPERATION(cpu->reg_A);
@@ -1800,34 +1890,346 @@ INSTRUCTION(INCzX)
    NZ_FLAG_UPDATE(val);
 }
 
-/* */
-static InstructionFunction InstructionTable[256] =
-{
-/*         00       01       02       03       04       05       06       07       08       09       0A       0B       0C       0D       0E       0F */
-/* 00 */ I_BRKiM, I_ORAiX, I_ILLEG, I_ILLEG, I_ILLEG, I_ORAzP, I_ASLzP, I_ILLEG, I_PHPiM, I_ORAiM, I_ASLiM, I_ILLEG, I_ILLEG, I_ORAaB, I_ASLaB, I_ILLEG,
-/* 10 */ I_BPLrE, I_ORAiY, I_ILLEG, I_ILLEG, I_ILLEG, I_ORAzX, I_ASLzX, I_ILLEG, I_CLCiM, I_ORAaY, I_ILLEG, I_ILLEG, I_ILLEG, I_ORAaX, I_ASLaX, I_ILLEG,
-/* 20 */ I_JSRaB, I_ANDiX, I_ILLEG, I_ILLEG, I_BITzP, I_ANDzP, I_ROLzP, I_ILLEG, I_PLPiM, I_ANDiM, I_ROLiM, I_ILLEG, I_BITaB, I_ANDaB, I_ROLaB, I_ILLEG,
-/* 30 */ I_BMIrE, I_ANDiY, I_ILLEG, I_ILLEG, I_ILLEG, I_ANDzX, I_ROLzX, I_ILLEG, I_SECiM, I_ANDaY, I_ILLEG, I_ILLEG, I_ILLEG, I_ANDaX, I_ROLaX, I_ILLEG,
-/* 40 */ I_RTIiM, I_EORiX, I_ILLEG, I_ILLEG, I_ILLEG, I_EORzP, I_LSRzP, I_ILLEG, I_PHAiM, I_EORiM, I_LSRiM, I_ILLEG, I_JMPaB, I_EORaB, I_LSRaB, I_ILLEG,
-/* 50 */ I_BVCrE, I_EORiY, I_ILLEG, I_ILLEG, I_ILLEG, I_EORzX, I_LSRzX, I_ILLEG, I_CLIiM, I_EORaY, I_ILLEG, I_ILLEG, I_ILLEG, I_EORaX, I_LSRaX, I_ILLEG,
-/* 60 */ I_RTSiM, I_ADCiX, I_ILLEG, I_ILLEG, I_ILLEG, I_ADCzP, I_RORzP, I_ILLEG, I_PLAiM, I_ADCiM, I_RORiM, I_ILLEG, I_JMPiD, I_ADCaB, I_RORaB, I_ILLEG,
-/* 70 */ I_BVSrE, I_ADCiY, I_ILLEG, I_ILLEG, I_ILLEG, I_ADCzX, I_RORzX, I_ILLEG, I_SEIiM, I_ADCaY, I_ILLEG, I_ILLEG, I_ILLEG, I_ADCaX, I_RORaX, I_ILLEG,
-/* 80 */ I_ILLEG, I_STAiX, I_ILLEG, I_ILLEG, I_STYzP, I_STAzP, I_STXzP, I_ILLEG, I_DEYiM, I_ILLEG, I_TXAiM, I_ILLEG, I_STYaB, I_STAaB, I_STXaB, I_ILLEG,
-/* 90 */ I_BCCrE, I_STAiY, I_ILLEG, I_ILLEG, I_STYzX, I_STAzX, I_STXzY, I_ILLEG, I_TYAiM, I_STAaY, I_TXSiM, I_ILLEG, I_ILLEG, I_STAaX, I_ILLEG, I_ILLEG,
-/* A0 */ I_LDYiM, I_LDAiX, I_LDXiM, I_ILLEG, I_LDYzP, I_LDAzP, I_LDXzP, I_ILLEG, I_TAYiM, I_LDAiM, I_TAXiM, I_ILLEG, I_LDYaB, I_LDAaB, I_LDXaB, I_ILLEG,
-/* B0 */ I_BCSrE, I_LDAiY, I_ILLEG, I_ILLEG, I_LDYzX, I_LDAzX, I_LDXzY, I_ILLEG, I_CLViM, I_LDAaY, I_TSXiM, I_ILLEG, I_LDYaX, I_LDAaX, I_LDXaY, I_ILLEG,
-/* C0 */ I_CPYiM, I_CMPiX, I_ILLEG, I_ILLEG, I_CPYzP, I_CMPzP, I_DECzP, I_ILLEG, I_INYiM, I_CMPiM, I_DEXiM, I_ILLEG, I_CPYaB, I_CMPaB, I_DECaB, I_ILLEG,
-/* D0 */ I_BNErE, I_CMPiY, I_ILLEG, I_ILLEG, I_ILLEG, I_CMPzX, I_DECzX, I_ILLEG, I_CLDiM, I_CMPaY, I_ILLEG, I_ILLEG, I_ILLEG, I_CMPaX, I_DECaX, I_ILLEG,
-/* E0 */ I_CPXiM, I_SBCiX, I_ILLEG, I_ILLEG, I_CPXzP, I_SBCzP, I_INCzP, I_ILLEG, I_INXiM, I_SBCiM, I_NOPiM, I_ILLEG, I_CPXaB, I_SBCaB, I_INCaB, I_ILLEG,
-/* F0 */ I_BEQrE, I_SBCiY, I_ILLEG, I_ILLEG, I_ILLEG, I_SBCzX, I_INCzX, I_ILLEG, I_SEDiM, I_SBCaY, I_ILLEG, I_ILLEG, I_ILLEG, I_SBCaX, I_INCaX, I_ILLEG
-/*         00       01       02       03       04       05       06       07       08       09       0A       0B       0C       0D       0E       0F */
+/* iM: Immediate
+ * iX: Indirect by X
+ * iY: Indirect by Y
+ * zP: Zero Page
+ * zX: Zero Page Indexec by X
+ * zY: Zero Page Indexec by Y
+ * iD: Indirect Double
+ * aB: Absolute
+ * aX: Absolute by X
+ * aY: Absolute by Y 
+ */
+ static InstructionFunction InstructionTable[256] =
+ {
+ /*         00       01       02       03       04       05       06       07       08       09       0A       0B       0C       0D       0E       0F */
+ /* 00 */ I_BRKnP, I_ORAiX, I_ILLEG, I_ILLEG, I_ILLEG, I_ORAzP, I_ASLzP, I_ILLEG, I_PHPnP, I_ORAiM, I_ASLnP, I_ILLEG, I_ILLEG, I_ORAaB, I_ASLaB, I_ILLEG,
+ /* 10 */ I_BPLrE, I_ORAiY, I_ILLEG, I_ILLEG, I_ILLEG, I_ORAzX, I_ASLzX, I_ILLEG, I_CLCnP, I_ORAaY, I_ILLEG, I_ILLEG, I_ILLEG, I_ORAaX, I_ASLaX, I_ILLEG,
+ /* 20 */ I_JSRaB, I_ANDiX, I_ILLEG, I_ILLEG, I_BITzP, I_ANDzP, I_ROLzP, I_ILLEG, I_PLPnP, I_ANDiM, I_ROLnP, I_ILLEG, I_BITaB, I_ANDaB, I_ROLaB, I_ILLEG,
+ /* 30 */ I_BMIrE, I_ANDiY, I_ILLEG, I_ILLEG, I_ILLEG, I_ANDzX, I_ROLzX, I_ILLEG, I_SECnP, I_ANDaY, I_ILLEG, I_ILLEG, I_ILLEG, I_ANDaX, I_ROLaX, I_ILLEG,
+ /* 40 */ I_RTInP, I_EORiX, I_ILLEG, I_ILLEG, I_ILLEG, I_EORzP, I_LSRzP, I_ILLEG, I_PHAnP, I_EORiM, I_LSRnP, I_ILLEG, I_JMPaB, I_EORaB, I_LSRaB, I_ILLEG,
+ /* 50 */ I_BVCrE, I_EORiY, I_ILLEG, I_ILLEG, I_ILLEG, I_EORzX, I_LSRzX, I_ILLEG, I_CLInP, I_EORaY, I_ILLEG, I_ILLEG, I_ILLEG, I_EORaX, I_LSRaX, I_ILLEG,
+ /* 60 */ I_RTSnP, I_ADCiX, I_ILLEG, I_ILLEG, I_ILLEG, I_ADCzP, I_RORzP, I_ILLEG, I_PLAnP, I_ADCiM, I_RORnP, I_ILLEG, I_JMPiD, I_ADCaB, I_RORaB, I_ILLEG,
+ /* 70 */ I_BVSrE, I_ADCiY, I_ILLEG, I_ILLEG, I_ILLEG, I_ADCzX, I_RORzX, I_ILLEG, I_SEInP, I_ADCaY, I_ILLEG, I_ILLEG, I_ILLEG, I_ADCaX, I_RORaX, I_ILLEG,
+ /* 80 */ I_ILLEG, I_STAiX, I_ILLEG, I_ILLEG, I_STYzP, I_STAzP, I_STXzP, I_ILLEG, I_DEYnP, I_ILLEG, I_TXAnP, I_ILLEG, I_STYaB, I_STAaB, I_STXaB, I_ILLEG,
+ /* 90 */ I_BCCrE, I_STAiY, I_ILLEG, I_ILLEG, I_STYzX, I_STAzX, I_STXzY, I_ILLEG, I_TYAnP, I_STAaY, I_TXSnP, I_ILLEG, I_ILLEG, I_STAaX, I_ILLEG, I_ILLEG,
+ /* A0 */ I_LDYiM, I_LDAiX, I_LDXiM, I_ILLEG, I_LDYzP, I_LDAzP, I_LDXzP, I_ILLEG, I_TAYnP, I_LDAiM, I_TAXnP, I_ILLEG, I_LDYaB, I_LDAaB, I_LDXaB, I_ILLEG,
+ /* B0 */ I_BCSrE, I_LDAiY, I_ILLEG, I_ILLEG, I_LDYzX, I_LDAzX, I_LDXzY, I_ILLEG, I_CLVnP, I_LDAaY, I_TSXnP, I_ILLEG, I_LDYaX, I_LDAaX, I_LDXaY, I_ILLEG,
+ /* C0 */ I_CPYiM, I_CMPiX, I_ILLEG, I_ILLEG, I_CPYzP, I_CMPzP, I_DECzP, I_ILLEG, I_INYnP, I_CMPiM, I_DEXnP, I_ILLEG, I_CPYaB, I_CMPaB, I_DECaB, I_ILLEG,
+ /* D0 */ I_BNErE, I_CMPiY, I_ILLEG, I_ILLEG, I_ILLEG, I_CMPzX, I_DECzX, I_ILLEG, I_CLDnP, I_CMPaY, I_ILLEG, I_ILLEG, I_ILLEG, I_CMPaX, I_DECaX, I_ILLEG,
+ /* E0 */ I_CPXiM, I_SBCiX, I_ILLEG, I_ILLEG, I_CPXzP, I_SBCzP, I_INCzP, I_ILLEG, I_INXnP, I_SBCiM, I_NOPnP, I_ILLEG, I_CPXaB, I_SBCaB, I_INCaB, I_ILLEG,
+ /* F0 */ I_BEQrE, I_SBCiY, I_ILLEG, I_ILLEG, I_ILLEG, I_SBCzX, I_INCzX, I_ILLEG, I_SEDnP, I_SBCaY, I_ILLEG, I_ILLEG, I_ILLEG, I_SBCaX, I_INCaX, I_ILLEG
+ /*         00       01       02       03       04       05       06       07       08       09       0A       0B       0C       0D       0E       0F */
+ };
+ 
+#ifdef MINE
+
+typedef enum InstructionType
+{
+   t_IMM = 0, t_IDX, t_IDY, t_ABS,
+   t_REL, t_ZEP, t_ZPX, t_ZPY,
+   t_ABX, t_ABY, t_IND, t_NOP,
+} InstructionType;
+
+static InstructionType InstructionTypeTable[256] =
+{
+/*       00     01     02     03     04     05     06     07     08     09     0A     0B     0C     0D     0E     0F */
+/* 00 */ t_NOP, t_IDX, t_IMM, t_IMM, t_IMM, t_ZEP, t_ZEP, t_IMM, t_NOP, t_IMM, t_NOP, t_IMM, t_IMM, t_ABS, t_ABS, t_IMM,
+/* 10 */ t_REL, t_IDY, t_IMM, t_IMM, t_IMM, t_ZPX, t_ZPX, t_IMM, t_NOP, t_ABY, t_IMM, t_IMM, t_IMM, t_ABX, t_ABX, t_IMM,
+/* 20 */ t_ABS, t_IDX, t_IMM, t_IMM, t_ZEP, t_ZEP, t_ZEP, t_IMM, t_NOP, t_IMM, t_NOP, t_IMM, t_ABS, t_ABS, t_ABS, t_IMM,
+/* 30 */ t_REL, t_IDY, t_IMM, t_IMM, t_IMM, t_ZPX, t_ZPX, t_IMM, t_NOP, t_ABY, t_IMM, t_IMM, t_IMM, t_ABX, t_ABX, t_IMM,
+/* 40 */ t_NOP, t_IDX, t_IMM, t_IMM, t_IMM, t_ZEP, t_ZEP, t_IMM, t_NOP, t_IMM, t_NOP, t_IMM, t_ABS, t_ABS, t_ABS, t_IMM,
+/* 50 */ t_REL, t_IDY, t_IMM, t_IMM, t_IMM, t_ZPX, t_ZPX, t_IMM, t_NOP, t_ABY, t_IMM, t_IMM, t_IMM, t_ABX, t_ABX, t_IMM,
+/* 60 */ t_NOP, t_IDX, t_IMM, t_IMM, t_IMM, t_ZEP, t_ZEP, t_IMM, t_NOP, t_IMM, t_NOP, t_IMM, t_IND, t_ABS, t_ABS, t_IMM,
+/* 70 */ t_REL, t_IDY, t_IMM, t_IMM, t_IMM, t_ZPX, t_ZPX, t_IMM, t_NOP, t_ABY, t_IMM, t_IMM, t_IMM, t_ABX, t_ABX, t_IMM,
+/* 80 */ t_IMM, t_IDX, t_IMM, t_IMM, t_ZEP, t_ZEP, t_ZEP, t_IMM, t_NOP, t_IMM, t_NOP, t_IMM, t_ABS, t_ABS, t_ABS, t_IMM,
+/* 90 */ t_REL, t_IDY, t_IMM, t_IMM, t_ZPX, t_ZPX, t_ZPY, t_IMM, t_NOP, t_ABY, t_NOP, t_IMM, t_IMM, t_ABX, t_IMM, t_IMM,
+/* A0 */ t_IMM, t_IDX, t_IMM, t_IMM, t_ZEP, t_ZEP, t_ZEP, t_IMM, t_NOP, t_IMM, t_NOP, t_IMM, t_ABS, t_ABS, t_ABS, t_IMM,
+/* B0 */ t_REL, t_IDY, t_IMM, t_IMM, t_ZPX, t_ZPX, t_ZPY, t_IMM, t_NOP, t_ABY, t_NOP, t_IMM, t_ABX, t_ABX, t_ABY, t_IMM,
+/* C0 */ t_IMM, t_IDX, t_IMM, t_IMM, t_ZEP, t_ZEP, t_ZEP, t_IMM, t_NOP, t_IMM, t_NOP, t_IMM, t_ABS, t_ABS, t_ABS, t_IMM,
+/* D0 */ t_REL, t_IDY, t_IMM, t_IMM, t_IMM, t_ZPX, t_ZPX, t_IMM, t_NOP, t_ABY, t_IMM, t_IMM, t_IMM, t_ABX, t_ABX, t_IMM,
+/* E0 */ t_IMM, t_IDX, t_IMM, t_IMM, t_ZEP, t_ZEP, t_ZEP, t_IMM, t_NOP, t_IMM, t_IMM, t_IMM, t_ABS, t_ABS, t_ABS, t_IMM,
+/* F0 */ t_REL, t_IDY, t_IMM, t_IMM, t_IMM, t_ZPX, t_ZPX, t_IMM, t_NOP, t_ABY, t_IMM, t_IMM, t_IMM, t_ABX, t_ABX, t_IMM
+/*       00     01     02     03     04     05     06     07     08     09     0A     0B     0C     0D     0E     0F */
+};
+
+static InstructionNameTag InstructionNameTable[256] =
+{
+/*       00     01     02     03     04     05     06     07     08     09     0A     0B     0C     0D     0E     0F */
+/* 00 */ n_BRK, n_ORA, n_ILG, n_ILG, n_ILG, n_ORA, n_ASL, n_ILG, n_PHP, n_ORA, n_ASL, n_ILG, n_ILG, n_ORA, n_ASL, n_ILG,
+/* 10 */ n_BPL, n_ORA, n_ILG, n_ILG, n_ILG, n_ORA, n_ASL, n_ILG, n_CLC, n_ORA, n_ILG, n_ILG, n_ILG, n_ORA, n_ASL, n_ILG,
+/* 20 */ n_JSR, n_AND, n_ILG, n_ILG, n_BIT, n_AND, n_ROL, n_ILG, n_PLP, n_AND, n_ROL, n_ILG, n_BIT, n_AND, n_ROL, n_ILG,
+/* 30 */ n_BMI, n_AND, n_ILG, n_ILG, n_ILG, n_AND, n_ROL, n_ILG, n_SEC, n_AND, n_ILG, n_ILG, n_ILG, n_AND, n_ROL, n_ILG,
+/* 40 */ n_RTI, n_EOR, n_ILG, n_ILG, n_ILG, n_EOR, n_LSR, n_ILG, n_PHA, n_EOR, n_LSR, n_ILG, n_JMP, n_EOR, n_LSR, n_ILG,
+/* 50 */ n_BVC, n_EOR, n_ILG, n_ILG, n_ILG, n_EOR, n_LSR, n_ILG, n_CLI, n_EOR, n_ILG, n_ILG, n_ILG, n_EOR, n_LSR, n_ILG,
+/* 60 */ n_RTS, n_ADC, n_ILG, n_ILG, n_ILG, n_ADC, n_ROR, n_ILG, n_PLA, n_ADC, n_ROR, n_ILG, n_JMP, n_ADC, n_ROR, n_ILG,
+/* 70 */ n_BVS, n_ADC, n_ILG, n_ILG, n_ILG, n_ADC, n_ROR, n_ILG, n_SEI, n_ADC, n_ILG, n_ILG, n_ILG, n_ADC, n_ROR, n_ILG,
+/* 80 */ n_ILG, n_STA, n_ILG, n_ILG, n_STY, n_STA, n_STX, n_ILG, n_DEY, n_ILG, n_TXA, n_ILG, n_STY, n_STA, n_STX, n_ILG,
+/* 90 */ n_BCC, n_STA, n_ILG, n_ILG, n_STY, n_STA, n_STX, n_ILG, n_TYA, n_STA, n_TXS, n_ILG, n_ILG, n_STA, n_ILG, n_ILG,
+/* A0 */ n_LDY, n_LDA, n_LDX, n_ILG, n_LDY, n_LDA, n_LDX, n_ILG, n_TAY, n_LDA, n_TAX, n_ILG, n_LDY, n_LDA, n_LDX, n_ILG,
+/* B0 */ n_BCS, n_LDA, n_ILG, n_ILG, n_LDY, n_LDA, n_LDX, n_ILG, n_CLV, n_LDA, n_TSX, n_ILG, n_LDY, n_LDA, n_LDX, n_ILG,
+/* C0 */ n_CPY, n_CMP, n_ILG, n_ILG, n_CPY, n_CMP, n_DEC, n_ILG, n_INY, n_CMP, n_DEX, n_ILG, n_CPY, n_CMP, n_DEC, n_ILG,
+/* D0 */ n_BNE, n_CMP, n_ILG, n_ILG, n_ILG, n_CMP, n_DEC, n_ILG, n_CLD, n_CMP, n_ILG, n_ILG, n_ILG, n_CMP, n_DEC, n_ILG,
+/* E0 */ n_CPX, n_SBC, n_ILG, n_ILG, n_CPX, n_SBC, n_INC, n_ILG, n_INX, n_SBC, n_NOP, n_ILG, n_CPX, n_SBC, n_INC, n_ILG,
+/* F0 */ n_BEQ, n_SBC, n_ILG, n_ILG, n_ILG, n_SBC, n_INC, n_ILG, n_SED, n_SBC, n_ILG, n_ILG, n_ILG, n_SBC, n_INC, n_ILG,
+/*       00     01     02     03     04     05     06     07     08     09     0A     0B     0C     0D     0E     0F */
+};
+
+/** Get current instruction name at specified address and put it into buffer */
+int quick6502_getinstruction(quick6502_cpu *cpu, char interpret,
+                             unsigned short addr, char *buffer, int *strlength)
+{
+   int len = 0, curlen;
+   int readbyte = 1;
+   char *str = buffer;
+
+   uint8_t opcode = cpu->memory_opcode_read(addr);
+
+   uint8_t  value_u8;
+   uint16_t value_u16;
+   
+   curlen = sprintf(str, "%s", InstructionName[InstructionNameTable[opcode]]);
+   str += curlen; len += curlen;
+   
+   switch(InstructionTypeTable[opcode])
+   {
+   default: /* Nothing to do */
+   case t_NOP:
+      break;
+      
+   case t_IMM: 
+      curlen = sprintf(str, " #$%02X", cpu->memory_opcode_read(addr + 1));
+      str += curlen; len += curlen;
+
+      /* Nothing to interpret.. Really */
+
+      readbyte += 2;
+
+      break;
+
+   case t_IDX:
+      curlen = sprintf(str, " ($%02X, X)", cpu->memory_opcode_read(addr + 1));
+      str += curlen; len += curlen;
+
+      if (interpret)
+      {
+         value_u8 = cpu->memory_opcode_read( addr + 1 );
+         value_u16 = value_u8 + cpu->reg_X;
+      
+         curlen = sprintf(str, " ; ($%02X + $%02X) -> ($%02X) -> $%02X%02X",
+                           value_u8, cpu->reg_X,
+                           value_u16 & 0xFF,
+                           cpu->memory_page0_read(value_u16),
+                           cpu->memory_page0_read(value_u16 + 1));
+         str += curlen; len += curlen;
+      }
+
+      readbyte += 1;
+      break;
+      
+   case t_IDY:
+      curlen = sprintf(str, " ($%02X), Y", cpu->memory_opcode_read(addr + 1));
+      str += curlen; len += curlen;
+
+      if (interpret)
+      {
+         value_u8 = cpu->memory_opcode_read( addr + 1 );
+         value_u16 = (cpu->memory_page0_read(value_u8 + 1) << 8) |
+                     (cpu->memory_page0_read(value_u8) );
+         
+         curlen = sprintf(str, " ; ($%02X) + $%02X -> $%04X + $%02X -> $%04X",
+                          value_u8, cpu->reg_Y,
+                          value_u16, cpu->reg_Y,
+                          value_u16 + cpu->reg_Y
+                         );
+         str += curlen; len += curlen;
+      }
+
+      readbyte += 1;
+      break;
+
+   case t_ABS:
+      curlen = sprintf(str, " $%02X%02X", cpu->memory_opcode_read(addr + 2),
+                                          cpu->memory_opcode_read(addr + 1));
+      str += curlen; len += curlen;
+
+      /* Nothing to interpret.. Really */
+
+      readbyte += 2;
+      break;
+
+   case t_REL:
+      value_u16 = 2 + addr + (signed char) cpu->memory_opcode_read(addr + 1);
+      curlen = sprintf(str, " $%04X", value_u16);
+      str += curlen; len += curlen;
+
+      /* Nothing to interpret.. Really */
+
+      readbyte += 1;
+      break;
+
+   case t_ZEP:
+      curlen = sprintf(str, " $%02X", cpu->memory_opcode_read(addr + 1));
+      str += curlen; len += curlen;
+
+      /* Nothing to interpret.. Really */
+
+      readbyte += 1;
+      break;
+
+   case t_ZPX:
+      curlen = sprintf(str, " $%02X, X", cpu->memory_opcode_read(addr + 1));
+      str += curlen; len += curlen;
+
+      if (interpret)
+      {
+         curlen = sprintf(str, " ; $%02X + $%02x -> $%02X",
+                          cpu->memory_opcode_read(addr + 1), cpu->reg_X,
+                          (cpu->memory_opcode_read(addr + 1) + cpu->reg_X) & 0xFF);
+         str += curlen; len += curlen;
+      }
+
+      readbyte += 1;
+      break;
+
+   case t_ZPY:
+      curlen = sprintf(str, " $%02X, Y", cpu->memory_opcode_read(addr + 1));
+      str += curlen; len += curlen;
+
+      if (interpret)
+      {
+         curlen = sprintf(str, " ; $%02X + $%02x -> $%02X",
+                          cpu->memory_opcode_read(addr + 1), cpu->reg_Y,
+                          (cpu->memory_opcode_read(addr + 1) + cpu->reg_Y) & 0xFF);
+         str += curlen; len += curlen;
+      }
+
+      readbyte += 1;
+      break;
+
+   case t_ABX:
+      curlen = sprintf(str, " $%02X%02X, X", cpu->memory_opcode_read(addr + 2),
+                                             cpu->memory_opcode_read(addr + 1));
+      str += curlen; len += curlen;
+
+      if (interpret)
+      {
+         value_u16 = (cpu->memory_opcode_read(addr + 2) << 8) | 
+                     cpu->memory_opcode_read(addr + 1);
+         curlen = sprintf(str, " ; $%04X + $%02X -> $%04X", value_u16,
+                          cpu->reg_X, value_u16 + cpu->reg_X);
+         str += curlen; len += curlen;
+      }
+
+      readbyte += 2;
+      break;
+
+   case t_ABY:
+      curlen = sprintf(str, " $%02X%02X, Y", cpu->memory_opcode_read(addr + 2),
+                                             cpu->memory_opcode_read(addr + 1));
+      str += curlen; len += curlen;
+
+      if (interpret)
+      {
+         value_u16 = (cpu->memory_opcode_read(addr + 2) << 8) | 
+                     cpu->memory_opcode_read(addr + 1);
+         curlen = sprintf(str, " ; $%04X + $%02X -> $%04X", value_u16,
+                           cpu->reg_Y, value_u16 + cpu->reg_Y);
+         str += curlen; len += curlen;
+      }
+
+      readbyte += 2;
+      break;
+
+   case t_IND:
+      curlen = sprintf(str, " ($%02X%02X)", cpu->memory_opcode_read(addr + 2),
+                                            cpu->memory_opcode_read(addr + 1));
+      str += curlen; len += curlen;
+
+      if (interpret)
+      {
+         value_u16 = (cpu->memory_opcode_read(addr + 2) << 8) | 
+                     cpu->memory_opcode_read(addr + 1);
+         value_u16 = cpu->memory_read(value_u16) | 
+                    (cpu->memory_read(   ( value_u16 & 0xFF00 )     | 
+                                       ( ( value_u16 + 1 ) & 0x00FF ) ) << 8 );
+         curlen = sprintf(str, " ; ($%02X%02X) -> $%04X", 
+                               cpu->memory_opcode_read(addr + 2),
+                               cpu->memory_opcode_read(addr + 1),
+                               cpu->memory_opcode_read(addr));
+         str += curlen; len += curlen;
+      }
+
+      readbyte += 2;
+      break;
+   }
+   
+   if (strlength != NULL)
+      *strlength = len;
+   
+   return readbyte;
+}
+
+#else
+static char InstructionParameters[256][10] =
+{
+/*         00           01           02           03           04           05           06           07           08           09           0A           0B           0C           0D           0E           0F         */
+/* 00 */ IP_iM "BRK", IP_iX "ORA", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_zP "ORA", IP_zP "ASL", IP_iM "ILG", IP_iM "PHP", IP_iM "ORA", IP_iM "ASL", IP_iM "ILG", IP_iM "ILG", IP_aB "ORA", IP_aB "ASL", IP_iM "ILG",
+/* 10 */ IP_rE "BPL", IP_iY "ORA", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_zX "ORA", IP_zX "ASL", IP_iM "ILG", IP_iM "CLC", IP_aY "ORA", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_aX "ORA", IP_aX "ASL", IP_iM "ILG",
+/* 20 */ IP_aB "JSR", IP_iX "AND", IP_iM "ILG", IP_iM "ILG", IP_zP "BIT", IP_zP "AND", IP_zP "ROL", IP_iM "ILG", IP_iM "PLP", IP_iM "AND", IP_iM "ROL", IP_iM "ILG", IP_aB "BIT", IP_aB "AND", IP_aB "ROL", IP_iM "ILG",
+/* 30 */ IP_rE "BMI", IP_iY "AND", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_zX "AND", IP_zX "ROL", IP_iM "ILG", IP_iM "SEC", IP_aY "AND", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_aX "AND", IP_aX "ROL", IP_iM "ILG",
+/* 40 */ IP_iM "RTI", IP_iX "EOR", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_zP "EOR", IP_zP "LSR", IP_iM "ILG", IP_iM "PHA", IP_iM "EOR", IP_iM "LSR", IP_iM "ILG", IP_aB "JMP", IP_aB "EOR", IP_aB "LSR", IP_iM "ILG",
+/* 50 */ IP_rE "BVC", IP_iY "EOR", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_zX "EOR", IP_zX "LSR", IP_iM "ILG", IP_iM "CLI", IP_aY "EOR", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_aX "EOR", IP_aX "LSR", IP_iM "ILG",
+/* 60 */ IP_iM "RTS", IP_iX "ADC", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_zP "ADC", IP_zP "ROR", IP_iM "ILG", IP_iM "PLA", IP_iM "ADC", IP_iM "ROR", IP_iM "ILG", IP_iD "JMP", IP_aB "ADC", IP_aB "ROR", IP_iM "ILG",
+/* 70 */ IP_rE "BVS", IP_iY "ADC", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_zX "ADC", IP_zX "ROR", IP_iM "ILG", IP_iM "SEI", IP_aY "ADC", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_aX "ADC", IP_aX "ROR", IP_iM "ILG",
+/* 80 */ IP_iM "ILG", IP_iX "STA", IP_iM "ILG", IP_iM "ILG", IP_zP "STY", IP_zP "STA", IP_zP "STX", IP_iM "ILG", IP_iM "DEY", IP_iM "ILG", IP_iM "TXA", IP_iM "ILG", IP_aB "STY", IP_aB "STA", IP_aB "STX", IP_iM "ILG",
+/* 90 */ IP_rE "BCC", IP_iY "STA", IP_iM "ILG", IP_iM "ILG", IP_zX "STY", IP_zX "STA", IP_zY "STX", IP_iM "ILG", IP_iM "TYA", IP_aY "STA", IP_iM "TXS", IP_iM "ILG", IP_iM "ILG", IP_aX "STA", IP_iM "ILG", IP_iM "ILG",
+/* A0 */ IP_iM "LDY", IP_iX "LDA", IP_iM "LDX", IP_iM "ILG", IP_zP "LDY", IP_zP "LDA", IP_zP "LDX", IP_iM "ILG", IP_iM "TAY", IP_iM "LDA", IP_iM "TAX", IP_iM "ILG", IP_aB "LDY", IP_aB "LDA", IP_aB "LDX", IP_iM "ILG",
+/* B0 */ IP_rE "BCS", IP_iY "LDA", IP_iM "ILG", IP_iM "ILG", IP_zX "LDY", IP_zX "LDA", IP_zY "LDX", IP_iM "ILG", IP_iM "CLV", IP_aY "LDA", IP_iM "TSX", IP_iM "ILG", IP_aX "LDY", IP_aX "LDA", IP_aY "LDX", IP_iM "ILG",
+/* C0 */ IP_iM "CPY", IP_iX "CMP", IP_iM "ILG", IP_iM "ILG", IP_zP "CPY", IP_zP "CMP", IP_zP "DEC", IP_iM "ILG", IP_iM "INY", IP_iM "CMP", IP_iM "DEX", IP_iM "ILG", IP_aB "CPY", IP_aB "CMP", IP_aB "DEC", IP_iM "ILG",
+/* D0 */ IP_rE "BNE", IP_iY "CMP", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_zX "CMP", IP_zX "DEC", IP_iM "ILG", IP_iM "CLD", IP_aY "CMP", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_aX "CMP", IP_aX "DEC", IP_iM "ILG",
+/* E0 */ IP_iM "CPX", IP_iX "SBC", IP_iM "ILG", IP_iM "ILG", IP_zP "CPX", IP_zP "SBC", IP_zP "INC", IP_iM "ILG", IP_iM "INX", IP_iM "SBC", IP_iM "NOP", IP_iM "ILG", IP_aB "CPX", IP_aB "SBC", IP_aB "INC", IP_iM "ILG",
+/* F0 */ IP_rE "BEQ", IP_iY "SBC", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_zX "SBC", IP_zX "INC", IP_iM "ILG", IP_iM "SED", IP_aY "SBC", IP_iM "ILG", IP_iM "ILG", IP_iM "ILG", IP_aX "SBC", IP_aX "INC", IP_iM "ILG"
+/*         00           01           02           03           04           05           06           07           08           09           0A           0B           0C           0D           0E           0F         */
 };
 
+/** Get current instruction name at specified address and put it into buffer */
+int quick6502_getinstruction(quick6502_cpu *cpu, char interpret,
+                             unsigned short addr, char *buffer, int *strlength)
+{
+   unsigned char instr = cpu->memory_opcode_read(cpu->reg_PC);
+   unsigned char *instrText = InstructionParameters[instr];
+   
+   buffer += strlen(strcpy(buffer, instrText[1]));
+   switch(instrText[0])
+   {
+      case IP_nPc: default: break;
+      case IP_iMc: buffer += strlen(sprintf(buffer, IPf_iM, cpu->memory_opcode_read(cpu->reg_PC + 1))); break;
+      case IP_iXc: buffer += strlen(sprintf(buffer, IPf_iX, cpu->memory_opcode_read(cpu->reg_PC + 1))); break;
+      case IP_iYc: buffer += strlen(sprintf(buffer, IPf_iY, cpu->memory_opcode_read(cpu->reg_PC + 1))); break;
+      case IP_zPc: buffer += strlen(sprintf(buffer, IPf_zP, cpu->memory_opcode_read(cpu->reg_PC + 1))); break;
+      case IP_zXc: buffer += strlen(sprintf(buffer, IPf_zX, cpu->memory_opcode_read(cpu->reg_PC + 1))); break;
+      case IP_zYc: buffer += strlen(sprintf(buffer, IPf_zY, cpu->memory_opcode_read(cpu->reg_PC + 1))); break;
+      case IP_iDc: buffer += strlen(sprintf(buffer, IPf_iD, cpu->memory_opcode_read(cpu->reg_PC + 2), cpu->memory_opcode_read(cpu->reg_PC + 1))); break;
+      case IP_aBc: buffer += strlen(sprintf(buffer, IPf_aB, cpu->memory_opcode_read(cpu->reg_PC + 2), cpu->memory_opcode_read(cpu->reg_PC + 1))); break;
+      case IP_aXc: buffer += strlen(sprintf(buffer, IPf_aX, cpu->memory_opcode_read(cpu->reg_PC + 2), cpu->memory_opcode_read(cpu->reg_PC + 1))); break;
+      case IP_aYc: buffer += strlen(sprintf(buffer, IPf_aY, cpu->memory_opcode_read(cpu->reg_PC + 2), cpu->memory_opcode_read(cpu->reg_PC + 1))); break;
+      case IP_rEc: buffer += strlen(sprintf(buffer, IPf_rE, cpu->reg_PC + (signed char) cpu->memory_opcode_read(cpu->reg_PC) + 1)); break;
+   }
+   
+   *buffer = 0;
+}
+
+#endif
 
 static inline int quick6502_exec_one(quick6502_cpu *cpu)
 {
-   register byte opcode = cpu->memory_opcode_read(cpu->reg_PC++);
+   register byte opcode = cpu->memory_opcode_read(cpu->reg_PC);
    
+   //char instr[100];
+   //quick6502_dump(cpu, stdout);
+   cpu->reg_PC++;
    TRACEi(("Quick6502: PC:$%04X A:$%02X X:$%02X Y:$%02X S:$%02X P:$%02X P:[%c%c%c%c%c%c%c%c]",
            cpu->reg_PC, cpu->reg_A, cpu->reg_X, cpu->reg_Y, cpu->reg_S, cpu->reg_P,
            cpu->reg_P&Q6502_N_FLAG ? 'N':'.',
@@ -1837,9 +2239,12 @@ static inline int quick6502_exec_one(quick6502_cpu *cpu)
            cpu->reg_P&Q6502_D_FLAG ? 'D':'.',
            cpu->reg_P&Q6502_I_FLAG ? 'I':'.',
            cpu->reg_P&Q6502_Z_FLAG ? 'Z':'.',
-           cpu->reg_P&Q6502_C_FLAG ? 'C':'.'));
-   
+           cpu->reg_P&Q6502_C_FLAG ? 'C':'.'));  
    InstructionTable[opcode](cpu);
+   //printf("--------------------------------------------------------------\n");
+   /*quick6502_getinstruction(cpu, (1==1), cpu->reg_PC, instr, NULL);
+   printf("%04X: %s\n", cpu->reg_PC, instr);*/
+ 
    cpu->cycle_done += CycleTable[opcode];
    if (cpu->page_crossed) { cpu->cycle_done++; cpu->page_crossed = 0; }
    if (cpu->int_pending != 0)

+ 9 - 8
src/include/NESCarts.h

@@ -14,6 +14,7 @@
 #ifndef NESCARTS_H
 #define NESCARTS_H
 
+#include <stdint.h>
 #include <types.h>
 
 #define iNES_MIRROR  0x01
@@ -23,14 +24,14 @@
 
 typedef struct NesCart_
 {  
-    unsigned long PROMSize, /* Size of PROM */
-                  VROMSize; /* Size of VROM */
-    char MapperID;          /* Mapper Type */
-    byte Flags;
-    char *FileName;
-    byte *File;             /* Pointer on the file in memory */
-    byte *PROMBanks;        /* Pointer on the first PROM */
-    byte *VROMBanks;        /* Pointer on the first VROM */
+    uint32_t PROMSize, /* Size of PROM */
+             VROMSize; /* Size of VROM */
+    char     MapperID;          /* Mapper Type */
+    uint8_t  Flags;
+    char    *FileName;
+    uint8_t *File;             /* Pointer on the file in memory */
+    uint8_t *PROMBanks;        /* Pointer on the first PROM */
+    uint8_t *VROMBanks;        /* Pointer on the first VROM */
 } NesCart;
 
 void DumpCartProperties();

+ 2 - 2
src/include/Sound.h

@@ -93,7 +93,7 @@ void SetChannels(int Volume,int Switch);
 /** waveform to be an instrument or set it to the waveform  **/
 /** own playback rate.                                      **/
 /*************************************************************/
-void SetWave(int Channel,const signed char *Data,int Length,int Rate);
+void SetWave(int Channel,signed char *Data,int Length,int Rate);
 
 /** GetWave() ************************************************/
 /** Get current read position for the buffer set with the   **/
@@ -225,7 +225,7 @@ struct SndDriverStruct
   void (*Drum)(int Type,int Force);
   void (*SetChannels)(int Volume,int Switch);
   void (*Sound)(int Channel,int NewFreq,int NewVolume);
-  void (*SetWave)(int Channel,const signed char *Data,int Length,int Freq);
+  void (*SetWave)(int Channel,signed char *Data,int Length,int Freq);
   const signed char *(*GetWave)(int Channel);
 };
 extern struct SndDriverStruct SndDriver;

+ 48 - 0
src/include/color.h

@@ -0,0 +1,48 @@
+/**
+ *  ANSI Color definitiont - The Quick6502 Project
+ *  include/color.h
+ *
+ *  Created by Manoel Trapier on 25/06/10
+ *  Copyright 2010 986 Corp. All rights reserved.
+ *
+ *  $LastChangedDate:$
+ *  $Author:$
+ *  $HeadURL:$
+ *  $Revision:$
+ *
+ */
+
+#ifndef COLOR_H
+#define	COLOR_H
+
+#define ALLOW_COLORS
+
+#ifdef ALLOW_COLORS
+#define __C(c) "\x1B[" c "m"
+#else
+#define __C(c) ""
+#endif
+
+#define ANSI_COLOR __C
+#define FBLACK ANSI_COLOR("30")
+#define FRED ANSI_COLOR("31")
+#define FGREEN ANSI_COLOR("32")
+#define FYELLOW ANSI_COLOR("33")
+#define FBLUE ANSI_COLOR("34")
+#define FMAGENTA ANSI_COLOR("35")
+#define FCYAN ANSI_COLOR("36")
+#define FWHITE ANSI_COLOR("37")
+
+#define BBLACK ANSI_COLOR("40")
+#define BRED ANSI_COLOR("41")
+#define BGREEN ANSI_COLOR("42")
+#define BYELLOW ANSI_COLOR("43")
+#define BBLUE ANSI_COLOR("44")
+#define BMAGENTA ANSI_COLOR("45")
+#define BCYAN ANSI_COLOR("46")
+#define BWHITE ANSI_COLOR("47")
+
+#define CNORMAL ANSI_COLOR("0")
+
+#endif	/* COLOR_H */
+

+ 14 - 8
src/include/corecpu.h

@@ -18,22 +18,23 @@
 /* M6502 configuration
  *
  * Supported DEFINEs :
- * NO_DECIMAL     Quick6502 will not support BDC arithemtic (used for NES)
- * CMOS_6502     Quick6502 will act as a CMOS 6502 (Not actually used)
+ * Q6502_NO_DECIMAL     Quick6502 will not support BDC arithemtic (used for NES)
+ * Q6502_CMOS           Quick6502 will act as a CMOS 6502 (Not actually used)
+ * Q6502_DEBUGGER       Quick6502 will be build with debugguer support. Add some KB to the binary 
+ *                      and may slowdown a bit the emulation.
  *
  */
 
-#ifdef CMOS_6502
+#ifdef Q6502_CMOS
 //#warning Quick6502 CMOS support is actually desactivated, desactivate it
-#undef CMOS_6502
+#undef Q6502_CMOS
 #endif
 
-#ifndef NO_DECIMAL
+#ifndef Q6502_NO_DECIMAL
 //#warning Quick6502 have actually no BCD support, fallback to no NO_DECIMAL
-#define NO_DECIMAL
+#define Q6502_NO_DECIMAL
 #endif
 
-
 #include "types.h"
 
 typedef byte (*quick6502_MemoryReadFunction)(unsigned short addr);
@@ -63,6 +64,9 @@ typedef struct quick6502_cpu_
    /* Other config options */
    byte running; /* This field is used to prevent cpu free if this cpu is running */
    byte page_crossed;
+   
+   /* TODO add support for Inst/MemAccess breakpoints */
+   
 } quick6502_cpu;
 
 typedef struct quick6502_cpuconfig_
@@ -150,8 +154,10 @@ void quick6502_int(quick6502_cpu *cpu, quick6502_signal signal);
 void quick6502_dump(quick6502_cpu *cpu, FILE * fp);
 
 /** Get current instruction name at specified address and put it into buffer */
-void quick6502_getinstruction(quick6502_cpu *cpu, unsigned short addr, char *buffer); 
+#define MINE
 
+int quick6502_getinstruction(quick6502_cpu *cpu, char interpret,
+                             unsigned short addr, char *buffer, int *strlength);                        
 /**
  * Free the CPU 
  *

+ 42 - 0
src/include/log.h

@@ -0,0 +1,42 @@
+/**
+ *  Log Facility - The Quick6502 Project
+ *  include/log.h
+ *
+ *  Created by Manoel Trapier on 19/05/10
+ *  Copyright 2010 986 Corp. All rights reserved.
+ *
+ *  $LastChangedDate:$
+ *  $Author:$
+ *  $HeadURL:$
+ *  $Revision:$
+ *
+ */
+
+#ifndef _LOG_H
+#define	_LOG_H
+
+enum
+{
+    LOG_ALWAYS = -1,
+    LOG_PANIC = 0,
+    LOG_ERROR,
+    LOG_WARNING,
+    LOG_NORMAL,
+    LOG_VERBOSE,
+    LOG_DEBUG,
+};
+
+#define TIME_STAMP_LOG
+
+#define MAX_DEBUG_LEVEL LOG_PANIC
+#define log(_level, _user, _fmt, ...) if ((_level <= MAX_DEBUG_LEVEL) || (_level <= LOG_PANIC)) do { log_real(_level, _user, _fmt, ##__VA_ARGS__); } while(0)
+
+void log_real(int level, char *user, char *fmt, ...);
+
+#define LOG(_level, _str, ...) if ((_level <= MAX_DEBUG_LEVEL) || (_level <= LOG_PANIC)) do { puts(_str); } while(0)
+#define LOGCODE(_level, _user, _code) log(_level, _user, ""); \
+    if ((_level <= MAX_DEBUG_LEVEL) || (_level <= LOG_PANIC)) \
+       do { _code; printf("\n"); } while(0)
+
+#endif	/* _LOG_H */
+

+ 1 - 1
src/include/memory/manager.h

@@ -63,6 +63,6 @@ void InitMemory();
 byte ReadMemory(byte page, byte addr);
 void WriteMemory(byte page, byte addr, byte value);
 
-void DumpMemoryState();
+void DumpMemoryState(FILE *fp);
 
 #endif

+ 125 - 0
src/log.c

@@ -0,0 +1,125 @@
+/**
+ *  Log Facility - The Quick6502 Project
+ *  log.c
+ *
+ *  Created by Manoel Trapier on 19/05/10
+ *  Copyright 2010 986 Corp. All rights reserved.
+ *
+ *  $LastChangedDate:$
+ *  $Author:$
+ *  $HeadURL:$
+ *  $Revision:$
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <color.h>
+#include <string.h>
+#include <stdarg.h>
+#include <log.h>
+#include <sys/time.h>
+#include <time.h>
+
+#ifdef TIME_STAMP_LOG
+void time_stamp_line(void)
+{
+   /* Time "0" will be thefirst log line */
+   static char firstRun = 1;
+   static struct timeval firstTime;
+   struct timeval curTime; 
+
+   int cMin, cSec;
+   long long cMSec;
+
+   /* Get datetime */
+   gettimeofday(&curTime, NULL);
+
+   if (firstRun == 1)
+   {
+      firstRun = 0;
+      firstTime.tv_sec = curTime.tv_sec;
+      firstTime.tv_usec = curTime.tv_usec;
+   }
+
+   cMSec = ((curTime.tv_sec - firstTime.tv_sec)* 1000) + (curTime.tv_usec - firstTime.tv_usec)/1000;
+   cSec = (cMSec/1000);
+   cMSec %= 1000;
+
+   cMin = cSec / 60;
+
+   cSec %= 60;
+
+   /* Put cursor at start of line */
+   printf("%c[s", 0x1B);
+   printf("%c[7000D", 0x1B);
+   printf("%c[1C", 0x1B);
+   printf(FWHITE"[" FYELLOW "%03d" FRED "." FBLUE "%02d" FRED "." FGREEN "%03lld" FWHITE "]" CNORMAL, cMin, cSec, cMSec);
+   printf("%c[u", 0x1B);
+}
+#endif /* TIME_STAMP_LOG */
+
+void log_real(int level, char *user, char *fmt, ...)
+{
+   int i;
+   va_list va;
+   
+   /* The LOG_PANIC must always be displayed */
+   if ((level <= MAX_DEBUG_LEVEL) || (level <= LOG_PANIC))
+   {
+      switch(level)
+      {
+      case LOG_PANIC: printf(BRED FWHITE); break;
+      case LOG_ERROR:  printf(FRED); break;
+      case LOG_WARNING: printf(FYELLOW); break;
+      default:
+      case LOG_NORMAL: printf(FGREEN); break;
+      case LOG_VERBOSE: printf(FCYAN); break;
+      case LOG_DEBUG: printf(BBLUE FWHITE); break;
+      }
+
+#ifdef TIME_STAMP_LOG
+      printf("           ");
+#endif
+
+      if (user != NULL)
+      {
+         i = strlen(user);
+         if (i < 12)
+         {
+            i = 12 - i;
+            for (; i >= 0; i--)
+               putchar(' ');
+         }
+         printf("%s", user);
+      }
+      else
+      {
+         switch(level)
+         {     
+         case LOG_PANIC:   printf("   PANIC"); break;
+         case LOG_ERROR:   printf("   Error"); break;
+         case LOG_WARNING: printf(" Warning"); break;
+         default:
+         case LOG_NORMAL:  printf("    Info"); break;
+         case LOG_VERBOSE: printf(" Verbose"); break;
+         case LOG_DEBUG:   printf("   Debug"); break;
+         }
+      }
+      
+      printf(CNORMAL ": ");
+
+#ifdef TIME_STAMP_LOG
+         time_stamp_line();
+#endif /* TIME_STAMP_LOG */
+
+      va_start(va, fmt);
+      vprintf(fmt, va);
+      va_end(va);
+
+      if (fmt[0] != 0)
+      {      
+         printf("\n");
+      }
+   }
+}

+ 52 - 60
src/main.c

@@ -3,7 +3,7 @@
  *  main.c
  *
  *  Created by Manoel TRAPIER.
- *  Copyright (c) 2003-2008 986Corp. All rights reserved.
+ *  Copyright (c) 2003-2012 986Corp. All rights reserved.
  *
  *  $LastChangedDate$
  *  $Author$
@@ -87,6 +87,8 @@ double APU_BASEFREQ = 1.7897725;
 # error Cannot use ISPAL with ISNTSC together !
 #endif
 
+//#define MEMORY_TEST
+
 /* TI-NESulator Version */
 #define V_MAJOR 0
 #define V_MINOR 40
@@ -140,6 +142,7 @@ volatile unsigned long FPS, IPS;
 PALETTE pal;
 
 short IRQScanHit = -1;
+short SZHit = -1;
 
 /* palette */
 unsigned long ColorPalette[ 8 * 63 ];
@@ -177,6 +180,7 @@ void SaveSaveRam(char *name)
    FILE *fp;
    int i;
    char fname[512];
+   int ret;
    strcpy(fname, name);
    strcat(fname, ".svt");
    if ((fp = fopen(fname, "wb")))
@@ -184,7 +188,7 @@ void SaveSaveRam(char *name)
 	 console_printf(Console_Default, "Saving savestate '%s'\n", fname);
 	 for( i = 0x60; i < 0x80; i++)
 	 {
-	    fwrite(get_page_ptr(i), 1, 0x100, fp);
+	    ret = fwrite(get_page_ptr(i), 1, 0x100, fp);
 	 }
 	 
 	 fclose(fp);
@@ -196,7 +200,7 @@ void LoadSaveRam(char *name)
    FILE *fp;
    int i;
    char fname[512];
-   
+   int ret;
    strcpy(fname, name);
    strcat(fname, ".svt");
    if ((fp = fopen(fname, "rb")))
@@ -204,7 +208,7 @@ void LoadSaveRam(char *name)
 	 console_printf(Console_Default, "Loading savestate '%s'\n", fname);
 	 for( i = 0x60; i < 0x80; i++)
 	 {
-	    fread(get_page_ptr(i), 1, 0x0100, fp);
+	    ret = fread(get_page_ptr(i), 1, 0x0100, fp);
 	 }    
 	 fclose(fp);
 	 
@@ -215,7 +219,7 @@ void LoadSaveRam(char *name)
 void LoadPalette(char *filename, PALETTE pal)
 {
    FILE *fp;
-   
+   int ret;
    unsigned char r, v, b, i;
    console_printf(Console_Default, "%s: try to load pallette file '%s'", __func__, filename);
    if ((fp = fopen(filename, "rb")) != NULL)
@@ -224,9 +228,9 @@ void LoadPalette(char *filename, PALETTE pal)
 	 for (i = 0; i < 64; i++)
 	 {
 	    
-	    fread(&r, 1, 1, fp);
-	    fread(&v, 1, 1, fp);
-	    fread(&b, 1, 1, fp);
+	    ret = fread(&r, 1, 1, fp);
+	    ret = fread(&v, 1, 1, fp);
+	    ret = fread(&b, 1, 1, fp);
 	    
 	    /*            r = (r * 64) / 255;
 		v = (v * 64) / 255;
@@ -255,7 +259,7 @@ void LoadPalette(char *filename, PALETTE pal)
 	    ColorPalette[i + (6 * 63)] = SET_RGB(r - 10, v + 05, b + 05);
 	    
 	    /* Red + Green + Blue emphase */
-	    ColorPalette[i + (7 * 63)] = SET_RGB(r + 00, v + 00, b + 00);*/
+	    ColorPalette[i + (7 * 63)] = SET_RGB(r + 00, v + 00, b + 00);
 #else /* Else Use 8Bits */
 	    pal[i].r = r;
 	    pal[i].g = v;
@@ -284,16 +288,12 @@ void LoadPalette(char *filename, PALETTE pal)
    }
 }
 
-void *signalhandler(int sig)
+void signalhandler(int sig)
 {
-#if 0
    static int state=0;
 
-   byte F;
-   int J, I;
-   static char FA[8] = "NVRBDIZC";    
-   char S[128];
    char name[512];
+   
    static FILE *fp = NULL;
    sprintf(name, "crashdump-%d.txt", (int)time(NULL));
    if (state != 0)
@@ -332,27 +332,17 @@ void *signalhandler(int sig)
 	 case SIGTERM: fprintf(fp,"Termination request"); break;
    }
    fprintf(fp,"\nAn error occured during the excution.\n Crash report information :\n");
-#ifdef DEBUG
-   DAsm(S, R->PC.W);
-#endif
-   fprintf(fp, "CPU: A:%02X  P:%02X  X:%02X  Y:%02X  S:%04X  PC:%04X  Flags:[", 
-		 R->A, R->P, R->X, R->Y, R->S + 0x0100, R->PC.W);
-   for (J = 0, F = R->P; J < 8; J++, F <<= 1)
-	 fprintf(fp, "%c", F & 0x80 ? FA[J] : '.');
-   fprintf(fp, "]\nCPU: ");
-   fprintf(fp, "AT PC: [%02X - %s]   AT SP: [%02X %02X %02X]\nLast execution :\n", 
-           Rd6502(R->PC.W), S, 
-           Rd6502(0x0100 + (byte) (R->S + 1)), 
-           Rd6502(0x0100 + (byte) (R->S + 2)), 
-           Rd6502(0x0100 + (byte) (R->S + 3)));
-   showlastop(fp);
+
+   //quick6502_dump(cpu, fp);
+
+   //showlastop(fp);
    //       fprintf(fp, "PPU: CR1: 0x%02X (NT:%d AI:%d SP:%d BP:%d SS:%d NMI:%d)\n",ppu.ControlRegister1.b, ppu.ControlRegister1.s.NameTblAddr, ppu.ControlRegister1.s.AddrIncrmt, ppu.ControlRegister1.s.SptPattern, ppu.ControlRegister1.s.BgPattern, ppu.ControlRegister1.s.SpriteSize, ppu.ControlRegister1.s.VBlank_NMI);
    //       fprintf(fp, "PPU: CR2: 0x%02X (FBC/CI:%d SV:%d BV:%d SC:%d BC:%d DT:%d)\n",ppu.ControlRegister2.b,ppu.ControlRegister2.s.Colour,ppu.ControlRegister2.s.SpriteVisibility,ppu.ControlRegister2.s.BgVisibility,ppu.ControlRegister2.s.SpriteClipping,ppu.ControlRegister2.s.BgClipping,ppu.ControlRegister2.s.DisplayType);
    //       fprintf(fp, "PPU: SR: 0x%02X (VB:%d S0:%d SSC:%d VWF:%d)\n", ppu.StatusRegister.b,ppu.StatusRegister.s.VBlankOccur,ppu.StatusRegister.s.Sprite0Occur,ppu.StatusRegister.s.SprtCount,ppu.StatusRegister.s.VRAMProtect);
    //       fprintf(fp, "PPU: M:%d ST:%d VRAMPtr:0x%04X T:0x%04X\n",ppu.MirrorDir,ppu.ScreenType,ppu.VRAMAddrReg2.W,ppu.TmpVRamPtr);
    
    //MapperDump(fp);
-   
+#if 0   
    for(I = 0; I < 0xFFFF; I += 0x10)
 	 fprintf(fp, "%04X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X | %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n",
 		    I,
@@ -377,12 +367,12 @@ void *signalhandler(int sig)
 		    isprint(Rd6502(I+0x0D))?Rd6502(I+0x0D):'_',
 		    isprint(Rd6502(I+0x0E))?Rd6502(I+0x0E):'_',
 		    isprint(Rd6502(I+0x0F))?Rd6502(I+0x0F):'_');
-   
+#endif   
    DumpMemoryState(fp);
    
    console_printf(Console_Error, "\nPlease join this informations when submiting crash report\n");
    if (fp != stderr) fclose(fp);
-#endif
+
    exit(-42);
 }
 
@@ -410,7 +400,6 @@ void WrHook4000Multiplexer(byte addr, byte value)
    static byte Sq2_reg3 = 0;
    
    double SQ = 0.0;
-   
    switch(addr)
    {
 #ifdef USE_SOUND    
@@ -623,8 +612,6 @@ byte RdHook4000Multiplexer(byte addr)
 	    
 	 case 0x15:
 	    ret = 0x1F;
-	    break;
-	    
 	 default:
 	    ret = 0x42;
    }   
@@ -645,7 +632,6 @@ void printUsage(int argc, char *argv[])
 int main(int argc, char *argv[])
 {    
    int i;
-   unsigned char j, k;
    unsigned char *MemoryPage;
    quick6502_cpuconfig CpuConfig;
    
@@ -665,11 +651,11 @@ int main(int argc, char *argv[])
     2kB Internal RAM, mirrored 4 times
     --------------------------------------- $0000
     */
-   console_init(Console_Default);
+   console_init(Console_Debug);
    /* Print the banner */
    console_printf(Console_Default, "--------------------------------------------------------------------------------\n"
           "Welcome to TI-NESulator v%d.%d - by Godzil\n"
-          "Copyright 2003-2008 TRAPIER Manoel (godzil@godzil.net)\n"
+          "Copyright 2003-2012 TRAPIER Manoel (godzil@godzil.net)\n"
           "%s\n%s\n%s\n"
           "--------------------------------------------------------------------------------\n\n", 
           V_MAJOR,
@@ -679,15 +665,15 @@ int main(int argc, char *argv[])
           VS_AUTHOR);
    
    console_printf(Console_Default, "Install signal handlers...\t[");
-   //    signal(SIGABRT,signalhandler);
+   signal(SIGABRT, signalhandler);
    console_printf(Console_Default, "A");
-   //    signal(SIGILL,signalhandler);
+   signal(SIGILL, signalhandler);
    console_printf(Console_Default, "I");
-   /*signal(SIGINT,signalhandler);*/
+   /*signal(SIGINT, signalhandler);*/
    console_printf(Console_Default, ".");
-   //    signal(SIGSEGV,signalhandler);
+   signal(SIGSEGV, signalhandler);
    console_printf(Console_Default, "S");
-   //    signal(SIGTERM,signalhandler);
+   signal(SIGTERM, signalhandler);
    console_printf(Console_Default, "T]\n");
    
    /*  */
@@ -812,6 +798,7 @@ int main(int argc, char *argv[])
    
 #define Value(s) (((s%0xFF) + (rand()%0xFF-128) )%0xFF)
    
+#ifdef MEMORY_TEST
    console_printf(Console_Default, "Testing memory validity...\n");
    
    map_sram();
@@ -841,12 +828,13 @@ int main(int argc, char *argv[])
       if ((k=MemoryOpCodeRead(i)) != j)
          console_printf(Console_Error, "Error opcode @ 0x%X [w:%d,r:%d]\n", i, j, k);
    }
-   
+#endif
    /* SRAM (0x6000 : 0x2000 bytes ) */
    MemoryPage = (unsigned char *)malloc (0x2000);
    
    set_page_ptr_8k(0x60, MemoryPage);
    
+#ifdef MEMORY_TEST
    for(i = 0x6000; i < 0x8000; i ++)
    {    
       if (MemoryPage[i-0x6000] != (k = MemoryRead(i)))
@@ -865,7 +853,7 @@ int main(int argc, char *argv[])
       if ((k=MemoryOpCodeRead(i)) != j)
          console_printf(Console_Error, "Error opcode @ 0x%X [w:%d,r:%d]\n", i, j, k);
    }
-   
+
    console_printf(Console_Default, "Reseting main RAM...\t\t");
 
    /* Force the stack to be full of zero */
@@ -875,6 +863,7 @@ int main(int argc, char *argv[])
    }
    
    console_printf(Console_Default, "[ OK ]\n");
+#endif
  
    Cart = malloc( sizeof (NesCart));
    if (Cart == NULL)
@@ -887,8 +876,13 @@ int main(int argc, char *argv[])
    {
       int fd;
       console_printf(Console_Default, "Loading FDS ROM...\t\t");
-	 //fd = open("../data/disksys.rom", O_RDONLY);
-	 fd = open("TI-NESulator.app/Contents/Resources/disksys.rom", O_RDONLY);
+	 fd = open("../data/disksys.rom", O_RDONLY);
+	 //fd = open("TI-NESulator.app/Contents/Resources/disksys.rom", O_RDONLY);
+      if (fd < 0)
+      {
+         console_printf(Console_Error, "Can't find FDS ROM...\n");
+         exit(-1);
+      }
       
       FDSRom = mmap(NULL, 8*1024, PROT_READ, MAP_PRIVATE, fd, 0);
       console_printf(Console_Default, "%p [ OK ]\n", FDSRom);
@@ -930,7 +924,7 @@ int main(int argc, char *argv[])
       }        
       
    }
-   
+
    unmap_sram();
    
    InitPaddle(&P1);
@@ -959,7 +953,7 @@ int main(int argc, char *argv[])
       exit(-1);
    }
    
-   DumpMemoryState();
+   DumpMemoryState(stdout);
    
    if (Cart->Flags & iNES_4SCREEN)
    {
@@ -1033,7 +1027,7 @@ int main(int argc, char *argv[])
    }
    return 0;
 }
-//END_OF_MAIN()
+END_OF_MAIN()
 
 /* Access directly to Memory pages *HACKISH* */
 extern byte *memory_pages[0xFF];
@@ -1091,7 +1085,7 @@ void Loop6502(quick6502_cpu *R)
    
    ret = 0;
    
-   if ( mapper_irqloop (ScanLine) )
+   if ( (mapper_irqloop) && ( mapper_irqloop (ScanLine) ) )
    {
       ret = Q6502_IRQ_SIGNAL;
       IRQScanHit = ScanLine;
@@ -1108,12 +1102,11 @@ void Loop6502(quick6502_cpu *R)
       ret = Q6502_NMI_SIGNAL;        
    }
    
-   if (ScanLine == 239)
-      frame++;  
-   
    if (ScanLine == (239 + VBLANK_TIME))
    {  /* End of VBlank Time */
-      
+      frame++;
+      SZHit = -1;
+      IRQScanHit = -1;
       /* Sync at 60FPS */
       /* Get current time in microseconds */
       gettimeofday(&timeEnd, NULL);     
@@ -1129,9 +1122,9 @@ void Loop6502(quick6502_cpu *R)
 #endif
       
       /* If we press Page Up, we want to accelerate "time" */
-      if (!key[KEY_PGUP])
-	  if ((WaitTime >= 0) && (WaitTime < 100000))
-	  usleep(WaitTime);
+      if ((!key[KEY_PGUP]) && (!key[KEY_Y]))
+         if ((WaitTime >= 0) && (WaitTime < 100000))
+	         usleep(WaitTime);
       
       /* Now get the time after sleep */
       gettimeofday(&timeStart, NULL);
@@ -1142,7 +1135,7 @@ void Loop6502(quick6502_cpu *R)
       delta *= 1000000;
       delta += (timeStart.tv_usec - timeEnd.tv_usec);
       delta = WaitTime - delta;
-      
+
       /* To avoid strange time warp when stoping emulation or using acceleration a lot */
       if ((delta > 10000) || (delta < -10000)) 
          delta = 0;
@@ -1154,7 +1147,6 @@ void Loop6502(quick6502_cpu *R)
    else
       ScanLine++;
    
-   
    //console_printf(Console_Default, "SL:%d HBT:%d VbT:%d\n", ScanLine, HBLANK_TIME, VBLANK_TIME);
    if (keypressed())
    {

+ 7 - 5
src/mappersmanager/manager.c

@@ -31,7 +31,7 @@ typedef struct Mapper_
    MapperInit      init;
    MapperIRQ       irq;
    MapperDump      dump;
-   
+
 } Mapper;
 
 #include "mappers_list.h"
@@ -50,13 +50,14 @@ void mapper_list ()
 int mapper_init (NesCart *cart)
 {
    Mapper *ptr = &(Mappers[0]);
-   console_printf (Console_Default, "Search for a compatible mapper ID #%X:\n", cart->MapperID);
+   console_printf (Console_Default, "Search for a compatible mapper ID #%d:\n", cart->MapperID);
    while (ptr->name != NULL)
    {
       if (ptr->id == cart->MapperID)
       {
-         console_printf (Console_Default, "Found mapper ID #%X - '%s'\n", ptr->id, ptr->name);
-         ptr->init (cart);
+         console_printf (Console_Default, "Found mapper ID #%d - '%s'\n", ptr->id, ptr->name);
+         if (ptr->init)
+            ptr->init (cart);
          
          mapper_irqloop = ptr->irq;
          mapper_dump    = ptr->dump;
@@ -65,5 +66,6 @@ int mapper_init (NesCart *cart)
       }
       ptr++;
    }
+   console_printf (Console_Default, "No compatible mapper found!\n");
    return -1;
-}
+}

+ 1 - 1
src/mappersmanager/mappers/aorom.c

@@ -55,7 +55,7 @@ void aorom_MapperWriteHook(register byte Addr, register byte Value)
 
         aorom_load_bank = BankNb;
 
-        //console_printf(Console_Default, "aorom: Asking bank %d (giving %d & %d) - mirror is %d\n",BankNb,BankNb,(Value<<1)+1,Value&0x0F);
+        console_printf(Console_Default, "aorom: Asking bank %d - NT is 0x%04X\n",BankNb,(Value&0x10)?0x2400:0x2000);
         set_prom_bank_32k(0x8000,BankNb);
 } 
 

+ 1 - 1
src/mappersmanager/mappers/iremh3001.c

@@ -116,7 +116,7 @@ void iremh3001_MapperDump(FILE *fp)
         iremh3001_vrom_slot[4], 
         iremh3001_vrom_slot[5],
         iremh3001_vrom_slot[6],
-        iremh3001_prom_slot[7]);
+        iremh3001_vrom_slot[7]);
 }
 
 

+ 11 - 11
src/mappersmanager/mappers/mmc1.c

@@ -12,17 +12,17 @@
  *
  */
 
-#include "norom.h"
+#include "mmc1.h"
 
-unsigned char MMC1_reg0;
+uint8_t MMC1_reg0;
 
-unsigned char MMC1_reg1;
+uint8_t MMC1_reg1;
 
-unsigned char MMC1_reg2;
+uint8_t MMC1_reg2;
 
-unsigned char MMC1_reg3;
+uint8_t MMC1_reg3;
 
-unsigned char mmc1_CurrentBank;
+uint8_t mmc1_CurrentBank;
 
 #define MMC1_R0_MIRROR    0x01
 #define MMC1_R0_ONESCREEN  0x02
@@ -135,7 +135,7 @@ Reg 0
 void mmc1_ApplyReg0Mod() 
 {
     
-    static unsigned char OldSwitchArea = MMC1_R0_PRGAREA;
+    static uint8_t OldSwitchArea = MMC1_R0_PRGAREA;
     
     
        
@@ -182,9 +182,9 @@ void mmc1_ApplyReg0Mod()
        
 } 
 
-int VROMBankNb;
-unsigned char Bit = 0;
-unsigned char BitBuf = 0;
+uint32_t VROMBankNb;
+uint8_t Bit = 0;
+uint8_t BitBuf = 0;
 
 void mmc1_MapperWriteReg0(register byte Addr, register byte Value) 
 {
@@ -321,7 +321,7 @@ void mmc1_MapperWriteReg3(register byte Addr, register byte Value)
         
             MMC1_reg3 = BitBuf;
             
-            if (MMC1_reg3<<14 > Cart->PROMSize)
+            if ( ((uint32_t)MMC1_reg3 << 14) > Cart->PROMSize)
                 return;
                 
             if ( (MMC1_reg0 & MMC1_R0_PRGSIZE) != 0 )

+ 4 - 3
src/mappersmanager/mappers/mmc4.c

@@ -27,6 +27,7 @@ byte mmc4_RegF;
 #define LOG(s) { }  
 #endif
 
+/* MAPPER WARNING: This mapper need to attach to the PPU memory... Need more work on this parts.. */
 
 void mmc4_MapperWriteRegA(register byte Addr, register byte Value)
 {
@@ -85,13 +86,13 @@ void mmc4_MapperDump(FILE *fp)
 int mmc4_InitMapper(NesCart * cart) 
 {
     int i;
-    
-    set_prom_bank_16k(0x8000,0);
+
+    set_prom_bank_16k(0x8000, 0);
     set_prom_bank_16k(0xC000, GETLAST16KBANK(cart));
 
     if (cart->VROMSize > 0)
         set_vrom_bank_8k(0x0000,0);
-       
+    
     /* Mapper should register itself for write hook */
     for (i = 0xA0; i < 0xB0 ; i++)
     {

+ 5 - 3
src/mappersmanager/mappers_list.h

@@ -32,10 +32,12 @@ Mapper Mappers[] = {
 
 { 1 , "MMC1", mmc1_InitMapper, norom_MapperIRQ, mmc1_MapperDump },   
 { 4 , "MMC3", mmc3_InitMapper, mmc3_MapperIRQ, mmc3_MapperDump },   
-{ 10, "MMC4", mmc3_InitMapper, norom_MapperIRQ, mmc4_MapperDump }, 
-
-{ 65, "Irem H3001", iremh3001_InitMapper, iremh3001_MapperIRQ, iremh3001_MapperDump },   
+{ 10, "MMC4", mmc4_InitMapper, norom_MapperIRQ, mmc4_MapperDump }, 
    
+{ 65, "Irem H3001", iremh3001_InitMapper, iremh3001_MapperIRQ, iremh3001_MapperDump },   
+
+
+{ 100, "Floppy Disk System", NULL, norom_MapperIRQ, norom_MapperDump },   
    /* EOL tag */
 { 0, NULL, NULL, NULL, NULL }
 };

+ 1 - 1
src/memorymanager/memory.c

@@ -40,7 +40,7 @@ byte memory_pages_attr[0x100];
 func_rdhook rdh_table[0x100];
 func_wrhook wrh_table[0x100];
 
-//#define DEBUG
+#define DEBUG
 #undef DEBUG
 
 #ifdef DEBUG

+ 1 - 1
src/os/macos/io.c

@@ -58,4 +58,4 @@ int console_printf_d(const char *format, ...)
    console_vprintf (Console_Debug, format, ap);
    
    return 0;
-}
+}

+ 1 - 1
src/os/unix/CMakeLists.txt

@@ -9,4 +9,4 @@
 # $HeadURL$
 # $Revision$
 
-add_library(oslib loadfile.c)
+add_library(oslib loadfile.c graphics.c sound.c io.c)

+ 29 - 0
src/os/unix/graphics.c

@@ -0,0 +1,29 @@
+/*
+ *  Graphic Manager - The TI-NESulator Project
+ *  os/macos/graphics.c
+ *
+ *  Created by Manoel TRAPIER on 08/05/08.
+ *  Copyright (c) 2003-2008 986Corp. All rights reserved.
+ *
+ *  $LastChangedDate$
+ *  $Author$
+ *  $HeadURL$
+ *  $Revision$
+ *
+ */
+#include <os_dependent.h>
+
+int graphics_init()
+{
+   return 0;
+}
+
+int graphics_drawpixel(long x, long y, long color)
+{
+   return 0;
+}
+
+int graphics_blit(long x, long y, long w, long h)
+{
+   return 0;
+}

+ 61 - 0
src/os/unix/io.c

@@ -0,0 +1,61 @@
+/*
+ *  IO Manager - The TI-NESulator Project
+ *  os/macos/graphics.c
+ *
+ *  Created by Manoël Trapier on 04/01/09.
+ *  Copyright (c) 2003-2009 986 Corp. All rights reserved.
+ *
+ *  $LastChangedDate$
+ *  $Author$
+ *  $HeadURL$
+ *  $Revision$
+ *
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <os_dependent.h>
+
+char LevelChar[] = { 'E', 'W', 'A', 'N', 'V',  'D'};
+
+ConsoleLevel console_ActualLevel = Console_Default;
+
+/* Actually nothing to do */
+int console_init(ConsoleLevel DefaultLevel)
+{
+   console_ActualLevel = DefaultLevel;
+   return 0;
+}
+
+/* Actually a simple printf with levels */
+int console_vprintf(const ConsoleLevel level, const char *format, va_list ap)
+{
+   if (console_ActualLevel >= level)
+      vprintf(format, ap);
+   
+   return 0;
+}
+
+
+int console_printf(const ConsoleLevel level, const char *format, ...)
+{
+   int ret = 0;
+   va_list ap;
+   va_start(ap, format);
+
+   ret = console_vprintf(level, format, ap);
+
+   va_end(ap);
+   return 0;
+}
+
+int console_printf_d(const char *format, ...)
+{
+   va_list ap;
+   va_start(ap, format);
+   
+   console_vprintf (Console_Debug, format, ap);
+   
+   return 0;
+}

+ 0 - 0
src/os/unix/sound.c


+ 2 - 2
src/ppu/debug/ppu.debug.c

@@ -355,8 +355,8 @@ void ppu_dumpPalette(int x, int y)
 {
     int i;
 
-    textout(Buffer, font, "Bg Palette", x , y, 5);
-    textout(Buffer, font, "Sprt Palette", x + 90, y, 5);
+    textout_ex(Buffer, font, "Bg Palette", x , y, 5, 0);
+    textout_ex(Buffer, font, "Sprt Palette", x + 90, y, 5, 0);
 
     rect(Buffer, x+0, y+20, x+4 * 20 + 2, y + 4 * 20 + 22, 0);
     rect(Buffer, x+90, y+20, x+90 + 4 * 20 + 2, y + 4 * 20 + 22, 0);

+ 36 - 15
src/ppu/ppu.c

@@ -25,6 +25,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdint.h>
 
 #define __TINES_PPU_INTERNAL__
 #include <ppu/ppu.h>
@@ -47,6 +48,7 @@ volatile extern unsigned long IPS, FPS;
 
 extern unsigned long ColorPalette[ 9 * 63 ];
 extern short IRQScanHit;
+extern short SZHit;
 
 BITMAP *VideoBuffer; /* The ppu will only write pixel to this, and then bliting 
                         this on the screen "surface" */
@@ -272,8 +274,9 @@ int ppu_init()
 
 void ppu_updateSpriteScanlineTable()
 {
-    int i, line, j, k;
-    volatile int sprite_x, sprite_y, sprite_idx, sprite_attr;
+    int32_t i,j,k;
+    int line;
+    volatile int32_t sprite_x, sprite_y, sprite_idx, sprite_attr;
 
     int curline;
 
@@ -312,11 +315,11 @@ void ppu_updateSpriteScanlineTable()
             if (((sprite_x+8) < 0) && ((sprite_x-8) > 256))
                 continue; /* this sprite isn't either displayable */
             /* Now test if this sprite can be put in the sprite list */            
-            for (j = 0; j <= PPU_NbSpriteByScanLine[curline]; j++)
+            for (j = 0; j <= (int32_t)PPU_NbSpriteByScanLine[curline]; j++)
             {
                 /* sprite are ordered by their y value, so, the first time that
                    we have lower y value is where we need to put the sprite */
-                if (sprite_x < PPU_SCANLINESPRITE_GET_X(PPU_SpriteByScanLine[curline][j]))
+                if (sprite_x < (int32_t)PPU_SCANLINESPRITE_GET_X(PPU_SpriteByScanLine[curline][j]))
                 {
                     /* move the j eme item and next to the right in the list, trashing
                        if needed the rightest item. */
@@ -477,21 +480,23 @@ _AAA BCDD DDDE EEEE
 
 int ppu_hblank(int scanline)
 {
-    int i, j;
+    uint32_t i, j;
     byte pixelColor = 0x42;
     byte BgColor = 0x42;
     byte SpriteColor = 0x42;
-    unsigned short addr;
+    uint16_t addr;
     byte value;
-    unsigned short tmp_HHT = 0;
-    unsigned short tmp_VVTFV = 0;
-    unsigned long CurrentSprite;
+    uint16_t tmp_HHT = 0;
+    uint16_t tmp_VVTFV = 0;
+    uint32_t CurrentSprite;
     byte SpriteVFlip;
       
     if (scanline == 0)
     {
       ppu_bgColor =  ppu_readMemory(0x3F,00);
 
+      rectfill(Buffer, 256, 0, 277, 260, ppu_bgColor);
+
       if ((ppu_spriteVisibility != 0) || (ppu_backgroundVisibility != 0))
           ppu_updateCounters();
     }
@@ -621,7 +626,12 @@ int ppu_hblank(int scanline)
                         if ((PPU_SCANLINESPRITE_GET_ATTRS(CurrentSprite) & 0x04) &&
                             (SpriteColor != 0x00) && (BgColor != 0x00))
                         {
-                           ppu_spriteZeroHit = 1;
+                           if (!ppu_spriteZeroHit)
+                           {
+                             ppu_spriteZeroHit = (ppu_backgroundVisibility)?1:0;
+                             if (ppu_spriteZeroHit)
+                                 SZHit = scanline;
+                           }
                         }
                      if ( ( (PPU_SCANLINESPRITE_GET_ATTRS(CurrentSprite) & PPU_SPRITE_FLAGS_BGPRIO) && (BgColor == 0x0000)) ||
                          (!(PPU_SCANLINESPRITE_GET_ATTRS(CurrentSprite) & PPU_SPRITE_FLAGS_BGPRIO)) )
@@ -645,7 +655,6 @@ int ppu_hblank(int scanline)
             
        //blit(VideoBuffer, screen, 0, scanline, 0, scanline, 256, 1);
 
-
         if (ppu_backgroundVisibility == 1)
         {
 
@@ -697,14 +706,27 @@ E = HT
     if (scanline == 239)
     {
          ppu_inVBlankTime = 1;
-
-       textprintf(Buffer, font, 260, 3, 4, "FPS : %ld (CPU@~%2.2fMhz : %d%%)", FPS, (float) (((float) IPS) / 1000000.0), (int) ((((float) IPS) / 1770000.0) * 100.0));  
+       textprintf_ex(Buffer, font, 260, 3, 4, 0, "FPS : %ld (CPU@~%2.2fMhz : %d%%)", FPS, (float) (((float) IPS) / 1000000.0), (int) ((((float) IPS) / 1770000.0) * 100.0));  
        
         blit(VideoBuffer, Buffer, 0, 0, 0, 0, 256, 240);
         blit(Buffer, screen, 0, 0, 0, 0, 512+256, 512);
 
         return ppu_execNMIonVBlank;
     }
+    
+    if (scanline == SZHit)
+    {
+       line(Buffer, 257, scanline, 267, scanline, 0x12);
+       line(Buffer, 257, scanline, 260, scanline-2, 0x12);
+       line(Buffer, 257, scanline, 260, scanline+2, 0x12);
+    }
+
+    if (scanline == IRQScanHit)
+    {
+       line(Buffer, 267, scanline, 277, scanline, 0x13);
+       line(Buffer, 267, scanline, 270, scanline-2, 0x13);
+       line(Buffer, 267, scanline, 270, scanline+2, 0x13);
+    }
 
     if (key[KEY_B])
     {
@@ -712,8 +734,7 @@ E = HT
         blit(Buffer, screen, 0, 0, 0, 0, 512 + 256, 480);
     }
 
-
-    if (scanline == (239 + VBLANK_TIME))
+    if (scanline == (239 + VBLANK_TIME)+0)
     {
         ppu_inVBlankTime = 0;
         ppu_spriteZeroHit = 0;

+ 1 - 1
unix/Makefile

@@ -53,4 +53,4 @@ plugins.o: $(SRC)/pluginsmanager/manager.c $(PLUGINS)
 
 .PHONY: clean
 clean:
-	rm -Rf *.a *.o *~ core
+	rm -Rf *.a *.o *~ core