From bc65a7a4f008b85f75f8c32c197bfd0446bf8b46 Mon Sep 17 00:00:00 2001 From: godzil Date: Tue, 31 Jan 2012 15:15:55 +0000 Subject: [PATCH] Merge newcore branch into master/trunk. Correct lots of warning. (now warning are threat as error by default) Signed-off-by: Godzil --- .gitignore | 5 + CMakeLists.txt | 2 +- src/CMakeLists.txt | 9 +- src/apu/CMakeLists.txt | 3 +- src/apu/SndAlleg.c | 14 +- src/apu/SndUnixT.c | 17 +- src/apu/Sound.c | 4 +- src/corecpu/corecpu.c | 591 +++++++++++++++++++++---- src/include/NESCarts.h | 17 +- src/include/Sound.h | 4 +- src/include/color.h | 48 ++ src/include/corecpu.h | 22 +- src/include/log.h | 42 ++ src/include/memory/manager.h | 2 +- src/log.c | 125 ++++++ src/main.c | 112 +++-- src/mappersmanager/manager.c | 12 +- src/mappersmanager/mappers/aorom.c | 2 +- src/mappersmanager/mappers/iremh3001.c | 2 +- src/mappersmanager/mappers/mmc1.c | 22 +- src/mappersmanager/mappers/mmc4.c | 7 +- src/mappersmanager/mappers_list.h | 8 +- src/memorymanager/memory.c | 2 +- src/os/macos/io.c | 2 +- src/os/unix/CMakeLists.txt | 2 +- src/os/unix/graphics.c | 29 ++ src/os/unix/io.c | 61 +++ src/os/unix/sound.c | 0 src/ppu/debug/ppu.debug.c | 4 +- src/ppu/ppu.c | 51 ++- unix/Makefile | 2 +- 31 files changed, 986 insertions(+), 237 deletions(-) create mode 100644 .gitignore create mode 100644 src/include/color.h create mode 100644 src/include/log.h create mode 100644 src/log.c create mode 100644 src/os/unix/graphics.c create mode 100644 src/os/unix/io.c create mode 100644 src/os/unix/sound.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..14c6c3d --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +#Temp files +/build* + +*~ +*.swp diff --git a/CMakeLists.txt b/CMakeLists.txt index bbed34e..fa841c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ # $Revision$ -cmake_minimum_required (VERSION 2.4) +cmake_minimum_required (VERSION 2.6) project (TINES) add_subdirectory (src) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0f42459..23662c1 100644 --- a/src/CMakeLists.txt +++ b/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}) diff --git a/src/apu/CMakeLists.txt b/src/apu/CMakeLists.txt index 2ce8c08..7cc1994 100644 --- a/src/apu/CMakeLists.txt +++ b/src/apu/CMakeLists.txt @@ -9,4 +9,5 @@ # $HeadURL$ # $Revision$ -add_library(apu SndAlleg.c Sound.c) \ No newline at end of file +add_library(apu SndUnixT.c Sound.c) +#add_library(apu SndAlleg.c Sound.c) diff --git a/src/apu/SndAlleg.c b/src/apu/SndAlleg.c index 7d96ce4..33a40c9 100755 --- a/src/apu/SndAlleg.c +++ b/src/apu/SndAlleg.c @@ -43,7 +43,7 @@ static int MasterSwitch = (1< @@ -21,6 +19,8 @@ #include #include +#include + #ifdef SUN_AUDIO #include @@ -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)||(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 */ diff --git a/src/apu/Sound.c b/src/apu/Sound.c index 9256efe..cd826a0 100644 --- a/src/apu/Sound.c +++ b/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; diff --git a/src/corecpu/corecpu.c b/src/corecpu/corecpu.c index 5884b67..c39a1f5 100644 --- a/src/corecpu/corecpu.c +++ b/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 #include +#include #include #include @@ -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); + + 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, cpu->reg_PC, instr); - fprintf(fp, "Quick6502: Instruction at PC: %s\n", instr); + quick6502_getinstruction(cpu, (1==1), cpu->reg_PC, instr, NULL); + fprintf(fp, "## $%04X: %s\n", cpu->reg_PC, instr); } -/** Get current instruction name at specified address and put it into buffer */ -void quick6502_getinstruction(quick6502_cpu *cpu, unsigned short addr, char *buffer) +typedef enum InstructionNameTag { - buffer[0] = 0; -} + 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] = +/* 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 { -/* 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 */ + 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) diff --git a/src/include/NESCarts.h b/src/include/NESCarts.h index a849d87..cff32a7 100755 --- a/src/include/NESCarts.h +++ b/src/include/NESCarts.h @@ -14,6 +14,7 @@ #ifndef NESCARTS_H #define NESCARTS_H +#include #include #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(); diff --git a/src/include/Sound.h b/src/include/Sound.h index 9cf2013..2d7499c 100644 --- a/src/include/Sound.h +++ b/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; diff --git a/src/include/color.h b/src/include/color.h new file mode 100644 index 0000000..264d05c --- /dev/null +++ b/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 */ + diff --git a/src/include/corecpu.h b/src/include/corecpu.h index 070e81a..bf90c9d 100644 --- a/src/include/corecpu.h +++ b/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 * diff --git a/src/include/log.h b/src/include/log.h new file mode 100644 index 0000000..c966744 --- /dev/null +++ b/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 */ + diff --git a/src/include/memory/manager.h b/src/include/memory/manager.h index 9160a31..46d3a6f 100755 --- a/src/include/memory/manager.h +++ b/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 diff --git a/src/log.c b/src/log.c new file mode 100644 index 0000000..1658083 --- /dev/null +++ b/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 +#include +#include +#include +#include +#include +#include +#include + +#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"); + } + } +} diff --git a/src/main.c b/src/main.c index 9f7e0bd..277b754 100755 --- a/src/main.c +++ b/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()) { diff --git a/src/mappersmanager/manager.c b/src/mappersmanager/manager.c index d866c74..7b006ce 100644 --- a/src/mappersmanager/manager.c +++ b/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; -} \ No newline at end of file +} diff --git a/src/mappersmanager/mappers/aorom.c b/src/mappersmanager/mappers/aorom.c index df51428..761b324 100755 --- a/src/mappersmanager/mappers/aorom.c +++ b/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); } diff --git a/src/mappersmanager/mappers/iremh3001.c b/src/mappersmanager/mappers/iremh3001.c index 56d90d3..df7f4f2 100755 --- a/src/mappersmanager/mappers/iremh3001.c +++ b/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]); } diff --git a/src/mappersmanager/mappers/mmc1.c b/src/mappersmanager/mappers/mmc1.c index 5689fd6..7ca0dbb 100755 --- a/src/mappersmanager/mappers/mmc1.c +++ b/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 ) diff --git a/src/mappersmanager/mappers/mmc4.c b/src/mappersmanager/mappers/mmc4.c index 6be7829..1170aa6 100644 --- a/src/mappersmanager/mappers/mmc4.c +++ b/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++) { diff --git a/src/mappersmanager/mappers_list.h b/src/mappersmanager/mappers_list.h index a5a52a0..0875845 100644 --- a/src/mappersmanager/mappers_list.h +++ b/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 } }; diff --git a/src/memorymanager/memory.c b/src/memorymanager/memory.c index 6984619..6abab72 100755 --- a/src/memorymanager/memory.c +++ b/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 diff --git a/src/os/macos/io.c b/src/os/macos/io.c index 0640886..daf3590 100644 --- a/src/os/macos/io.c +++ b/src/os/macos/io.c @@ -58,4 +58,4 @@ int console_printf_d(const char *format, ...) console_vprintf (Console_Debug, format, ap); return 0; -} \ No newline at end of file +} diff --git a/src/os/unix/CMakeLists.txt b/src/os/unix/CMakeLists.txt index 487726e..915b2d3 100644 --- a/src/os/unix/CMakeLists.txt +++ b/src/os/unix/CMakeLists.txt @@ -9,4 +9,4 @@ # $HeadURL$ # $Revision$ -add_library(oslib loadfile.c) \ No newline at end of file +add_library(oslib loadfile.c graphics.c sound.c io.c) diff --git a/src/os/unix/graphics.c b/src/os/unix/graphics.c new file mode 100644 index 0000000..97a69fb --- /dev/null +++ b/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 + +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; +} diff --git a/src/os/unix/io.c b/src/os/unix/io.c new file mode 100644 index 0000000..84e999c --- /dev/null +++ b/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 +#include + +#include + +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; +} \ No newline at end of file diff --git a/src/os/unix/sound.c b/src/os/unix/sound.c new file mode 100644 index 0000000..e69de29 diff --git a/src/ppu/debug/ppu.debug.c b/src/ppu/debug/ppu.debug.c index 3cce3b4..a4b0927 100644 --- a/src/ppu/debug/ppu.debug.c +++ b/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); diff --git a/src/ppu/ppu.c b/src/ppu/ppu.c index eb398e5..451ea12 100755 --- a/src/ppu/ppu.c +++ b/src/ppu/ppu.c @@ -25,6 +25,7 @@ #include #include +#include #define __TINES_PPU_INTERNAL__ #include @@ -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; diff --git a/unix/Makefile b/unix/Makefile index 595d1b3..a34e888 100755 --- a/unix/Makefile +++ b/unix/Makefile @@ -53,4 +53,4 @@ plugins.o: $(SRC)/pluginsmanager/manager.c $(PLUGINS) .PHONY: clean clean: - rm -Rf *.a *.o *~ core \ No newline at end of file + rm -Rf *.a *.o *~ core