diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..bbed34e --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,16 @@ +# +# TI-NES CMake +# +# Created by Manoel TRAPIER. +# Copyright (c) 2003-2008 986Corp. All rights reserved. +# +# $LastChangedDate$ +# $Author$ +# $HeadURL$ +# $Revision$ + + +cmake_minimum_required (VERSION 2.4) +project (TINES) + +add_subdirectory (src) diff --git a/doc/Changements.txt b/doc/Changements.txt index 046877d..8e75858 100755 --- a/doc/Changements.txt +++ b/doc/Changements.txt @@ -8,7 +8,7 @@ - Unix & Windows build are totaly broken... - Sprite are back! There are some bad behaviour, but they will be corrected with next versions. - New SVN repository (the disk where the old one was had crashed...) - - Iremh3100 is now active! (finaly) + - Iremh3100 is now active! (finaly) 05/10/2007 V0.30 part 2 ... In progress ... - Start rewrite of mapper manager. The goal, like for plugin manager, is diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..0f42459 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,137 @@ +# +# TI-NES CMake +# +# Created by Manoel TRAPIER. +# Copyright (c) 2003-2008 986Corp. All rights reserved. +# +# $LastChangedDate$ +# $Author$ +# $HeadURL$ +# $Revision$ + +include_directories($(TINES_SOURCE_DIR)/include) + +########################## +# Configurations variables +########################## +set(PPU_ISPAL OFF CACHE BOOL "When switch to ON the PPU is in PAL mode, else it will act as a NTSC one.") +set(Q6502_DEBUGGER OFF CACHE BOOL "Activate the Quick6502 debugger?") +set(USE_SOUND OFF CACHE BOOL "Activate the sound?") +set(DETECT_BUS_CONFLICT OFF CACHE BOOL "Activate the bus conflit detector? (Could slow down the emulator a lot.)") + +set(USE_EFENCE OFF CACHE BOOL "Use electricfence memory debugger?") +set(USE_PROFILING OFF CACHE BOOL "Use profiling tools? (Will slow down a lot.)") + +set(USE_ALLEGRO ON CACHE BOOL "Use Allegro backend" FORCE) + +IF(NOT CMAKE_BUILD_TYPE) + SET(CMAKE_BUILD_TYPE Debug CACHE STRING + "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." + FORCE) +ENDIF(NOT CMAKE_BUILD_TYPE) + +if (APPLE) + SET (CMAKE_FIND_FRAMEWORK LAST) +endif (APPLE) + +########################## +# Link & Compile flags +########################## + +add_definitions (-DNO_DECIMAL -DFAST_RDOP) + +SET ( CMAKE_EXE_LINKER_FLAGS "-mmacosx-version-min=10.4") + +if (PPU_ISPAL) + add_definitions (-DISPAL) +else (PPU_ISPAL) + add_definitions (-DISNTSC) +endif (PPU_ISPAL) + +if (Q6502_DEBUGGER) + add_definitions (-DDEBUG) +endif (Q6502_DEBUGGER) + +if (USE_SOUND) + add_definitions (-DUSE_SOUND) +endif (USE_SOUND) + +if (DETECT_BUS_CONFLICT) + add_definitions (-DDETECT_BUS_CONFLICT) +endif (DETECT_BUS_CONFLICT) + +if (USE_EFENCE) + if (CMAKE_BUILD_TYPE MATCHES Release) + SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Debug info is forced" FORCE) + else(CMAKE_BUILD_TYPE) + SET(CMAKE_BUILD_TYPE Debug CACHE STRING "Debug info is forced" FORCE) + endif(CMAKE_BUILD_TYPE) + +endif (USE_EFENCE) + +if (USE_PROFILING) + if (CMAKE_BUILD_TYPE MATCHES Rel) + SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Debug info is forced" FORCE) + else(CMAKE_BUILD_TYPE MATCHES Rel) + SET(CMAKE_BUILD_TYPE Debug CACHE STRING "Debug info is forced" FORCE) + endif(CMAKE_BUILD_TYPE MATCHES Rel) + + set(CMAKE_C_FLAGS -pg) +endif (USE_PROFILING) + +if (APPLE) + include_directories(BEFORE /usr/include) +endif (APPLE) + +#if the CPU is LSB set the define +if (CMAKE_SYSTEM_PROCESSOR MATCHES i386 OR CMAKE_SYSTEM_PROCESSOR MATCHES [aA][rR][mM]) + add_definitions (-DLSB_FIRST) +endif (CMAKE_SYSTEM_PROCESSOR MATCHES i386 OR CMAKE_SYSTEM_PROCESSOR MATCHES [aA][rR][mM]) + +#Add release mode extra C Flags +set (CMAKE_C_FLAGS_RELEASE "-fomit-frame-pointer -funroll-loops -Wall ${CMAKE_C_FLAGS_RELEASE}") +set (CMAKE_C_FLAGS_RELWITHDEBINFO "-fomit-frame-pointer -funroll-loops -Wall ${CMAKE_C_FLAGS_RELWITHDEBINFO}") + +add_subdirectory(apu) +add_subdirectory(corecpu) +add_subdirectory(mappersmanager) +add_subdirectory(memorymanager) +add_subdirectory(pluginsmanager) +add_subdirectory(ppu) + + +if (TARGET_TI68k) + add_subdirectory(os/ti68k) +elseif (APPLE AND ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + add_subdirectory(os/macos) +elseif (UNIX) + add_subdirectory(os/win32) +else (TARGET_TI68k) + #So we target UNIX like OS + add_subdirectory(os/unix) +endif (TARGET_TI68k) + + +add_library (main main.c paddle.c NESCarts.c) + +add_executable(tines main.c) +set(CMAKE_FIND_FRAMEWORK LAST) +find_library(ALLEGROLIB allegro) +find_library(PTHREADLIB pthread) + +if (USE_EFENCE) + find_library(EFENCELIB efence) + target_link_libraries(tines ${EFENCELIB}) +endif (USE_EFENCE) + +if (USE_ALLEGRO) + target_link_libraries(tines debug alld-main) + target_link_libraries(tines optimized alleg-main) + if (APPLE) + find_library(COCOALIB Cocoa) + target_link_libraries(tines ${COCOALIB}) + endif (APPLE) + +endif (USE_ALLEGRO) + +target_link_libraries(tines main apu corecpu mappermanager memorymanager pluginsmanager ppu oslib ${ALLEGROLIB} ${PTHREADLIB}) diff --git a/src/NESCarts.c b/src/NESCarts.c index 2784991..ddccc81 100755 --- a/src/NESCarts.c +++ b/src/NESCarts.c @@ -11,21 +11,30 @@ * $Revision$ * */ - -#include "include/NESCarts.h" -#include "include/mappers/manager.h" +/* System Headers */ +#if !defined(__TIGCC__) && !defined(__GCC4TI__) && !defined(__GTC__) #include #include +#include -/* Plateform dependent function */ -void *LoadFilePtr(char * filename); +#else /* Support for TI-68k compilation */ + +#define TIGCC_COMPAT +#include +#endif + +/* TI-NES headers */ +#include +#include +#include +#include void DumpCartProperties(FILE *out, NesCart * cart) { - fprintf(out, + console_printf(Console_Verbose, "'%s' informations:\n" - " Total ROM Size : 0x%06X | Total VROM Size : 0x%06X\n" + " Total ROM Size : 0x%06lX | Total VROM Size : 0x%06lX\n" " Mapper ID : 0x%06X | Mirroring ? : %s\n" " Battery ? : %s | 4 Screen ? : %s \n" " PROMBanks start at : %p |\n" @@ -43,12 +52,12 @@ void DumpCartProperties(FILE *out, NesCart * cart) int LoadCart(const char *filename, NesCart * cart) { - byte buffer[6]; + char buffer[6]; /* Load the cart into memory */ - cart->File = (byte *)LoadFilePtr(filename); + cart->File = (byte *)LoadFilePtr((char *)filename); - if (cart->File == -1) + if ((cart->File == NULL) || ((int)cart->File == -1)) return -1; sprintf(buffer, "%c%c%c%c", 0x4E, 0x45, 0x53, 0x1A); @@ -56,15 +65,12 @@ int LoadCart(const char *filename, NesCart * cart) /* Verify that this is a real iNES valid file */ if (memcmp(cart->File, buffer, 4)) return -1; - - if ((cart->File == NULL) || (cart->File == -1)) - return -1; /* Before go elsewhere, verify that the header is clean ! (aka no DiskDude! in it) */ if (memcmp(cart->File+7, "DiskDude!", 9) == 0) { - printf("\n" + console_printf(Console_Warning, "\n" "*******************WARNING****************\n" "* The header of this game is not clean *\n" "* (DiskDude! pollution) I will only use *\n" @@ -83,7 +89,7 @@ int LoadCart(const char *filename, NesCart * cart) } /* Now fill the structure */ - cart->FileName = filename; + cart->FileName = (char *)filename; cart->PROMSize = cart->File[4] * 16 * 1024; /* Size of PROM */ cart->VROMSize = cart->File[5] * 8 * 1024; /* Size of VROM */ @@ -92,7 +98,7 @@ int LoadCart(const char *filename, NesCart * cart) /* We don't and we will never support trainer-ed ROM */ if (cart->Flags & iNES_TRAINER) { - printf("\n" + console_printf(Console_Error, "\n" "********************ERROR*****************\n" "* This cart have an embedded trainer. *\n" "* There is NO support for them. *\n" diff --git a/src/apu/CMakeLists.txt b/src/apu/CMakeLists.txt new file mode 100644 index 0000000..2ce8c08 --- /dev/null +++ b/src/apu/CMakeLists.txt @@ -0,0 +1,12 @@ +# +# TI-NES CMake +# +# Created by Manoel TRAPIER. +# Copyright (c) 2003-2008 986Corp. All rights reserved. +# +# $LastChangedDate$ +# $Author$ +# $HeadURL$ +# $Revision$ + +add_library(apu SndAlleg.c Sound.c) \ No newline at end of file diff --git a/src/apu/SndAlleg.c b/src/apu/SndAlleg.c index 407f650..7d96ce4 100755 --- a/src/apu/SndAlleg.c +++ b/src/apu/SndAlleg.c @@ -13,7 +13,16 @@ */ #include +/* Allegro includes */ +#ifdef __APPLE__ +#define USE_CONSOLE +#include +#else +#define USE_CONSOLE #include +#endif + +#include #include #include @@ -265,6 +274,8 @@ static void *DSPLoop(void *Arg) L2=L1+K; Wave[I]+= L1&0x8000?V:-V /*(L2&0x8000? V:0):(L2&0x8000? 0:-V)*/; L1=L2; + + } CH[J].Count=L1; break; @@ -314,14 +325,14 @@ int InitSound(int Rate,int Verbose) if (install_sound(DIGI_AUTODETECT, MIDI_NONE, "") != 0) { - fprintf(stderr, "%s!\n", allegro_error); + console_printf(Console_Error, "%s!\n", allegro_error); return 1; } stream = play_audio_stream(SND_BUFSIZE, 8, FALSE, Rate, 255, 128); if (!stream) { - fprintf(stderr, "Error creating audio stream!\n"); + console_printf(Console_Error, "Error creating audio stream!\n"); return 1; } @@ -332,7 +343,7 @@ int InitSound(int Rate,int Verbose) if(!(Rate=OpenSoundDevice(Rate,Verbose))) return(0); /* Create DSPLoop() thread */ - if(Verbose) printf(" Creating thread..."); + if(Verbose) console_printf(Console_Default, " Creating thread..."); if(pthread_create(&ThreadID,0,DSPLoop,0)) { if(Verbose) puts("FAILED");return(0); } @@ -350,7 +361,7 @@ int InitSound(int Rate,int Verbose) void TrashSound(void) { StopSound(); - printf("%s: Kill thread...\n", __func__); + console_printf(Console_Default, "%s: Kill thread...\n", __func__); if(ThreadID) pthread_cancel(ThreadID); SoundRate = 0; diff --git a/src/apu/SndUnixT.c b/src/apu/SndUnixT.c index b5faeea..118e584 100755 --- a/src/apu/SndUnixT.c +++ b/src/apu/SndUnixT.c @@ -90,7 +90,7 @@ static int MasterVolume = 64; static int MasterSwitch = (1<=SoundRate/3) break; K=0x10000*CH[J].Freq/SoundRate; @@ -333,9 +333,9 @@ static void *DSPLoop(void *Arg) L1=L2; } CH[J].Count=L1; - break; - - case SND_QS_DU1: + break; + + case SND_QS_DU1: /* Do not allow frequencies that are too high */ if(CH[J].Freq>=SoundRate/3) break; K=0x10000*CH[J].Freq/SoundRate; @@ -348,9 +348,9 @@ static void *DSPLoop(void *Arg) L1=L2; } CH[J].Count=L1; - break; - - case SND_QS_DU3: + break; + + case SND_QS_DU3: /* Do not allow frequencies that are too high */ if(CH[J].Freq>=SoundRate/3) break; K=0x10000*CH[J].Freq/SoundRate; @@ -363,8 +363,8 @@ static void *DSPLoop(void *Arg) L1=L2; } CH[J].Count=L1; - break; - + break; + case SND_QS_DU2: case SND_MELODIC: /* Melodic Sound */ default: /* Default Sound */ @@ -380,8 +380,8 @@ static void *DSPLoop(void *Arg) L1=L2; } CH[J].Count=L1; - break; - + break; + case SND_TRIANGLE: /* Default Sound */ /* Do not allow frequencies that are too high */ if(CH[J].Freq>=SoundRate/3) break; @@ -462,7 +462,7 @@ int InitSound(int Rate,int Verbose) if(!(Rate=OpenSoundDevice(Rate,Verbose))) return(0); /* Create DSPLoop() thread */ - if(Verbose) printf(" Creating thread..."); + if(Verbose) console_printf(Console_Default, " Creating thread..."); if(pthread_create(&ThreadID,0,DSPLoop,0)) { if(Verbose) puts("FAILED");return(0); } @@ -480,9 +480,9 @@ int InitSound(int Rate,int Verbose) void TrashSound(void) { StopSound(); - printf("%s: Kill thread...\n", __func__); - if(ThreadID) pthread_cancel(ThreadID); - printf("%s: close /dev/xxx ...\n", __func__); + console_printf(Console_Default, "%s: Kill thread...\n", __func__); + if(ThreadID) pthread_cancel(ThreadID); + console_printf(Console_Default, "%s: close /dev/xxx ...\n", __func__); if(SoundFD!=-1) close(SoundFD); SoundRate = 0; diff --git a/src/corecpu/CMakeLists.txt b/src/corecpu/CMakeLists.txt new file mode 100644 index 0000000..c561f3b --- /dev/null +++ b/src/corecpu/CMakeLists.txt @@ -0,0 +1,12 @@ +# +# TI-NES CMake +# +# Created by Manoel TRAPIER. +# Copyright (c) 2003-2008 986Corp. All rights reserved. +# +# $LastChangedDate$ +# $Author$ +# $HeadURL$ +# $Revision$ + +add_library(corecpu corecpu.c) \ No newline at end of file diff --git a/src/corecpu/corecpu.c b/src/corecpu/corecpu.c new file mode 100644 index 0000000..5884b67 --- /dev/null +++ b/src/corecpu/corecpu.c @@ -0,0 +1,1850 @@ +/** + * CoreCPU - The Quick6502 Project + * corecpu.c + * + * Created by Manoel Trapier on 24/02/08 + * Copyright 2008 986 Corp. All rights reserved. + * + * $LastChangedDate$ + * $Author$ + * $HeadURL$ + * $Revision$ + * + */ + +/* Depending on the OS, one of these provide the malloc function */ +#include +#include +#include + +#include + +/******************************************************************************* + /!\ WARNING this debug tool slow down a lot the emulator! /!\ + /!\ Use it only if you really need it ! /!\ + *******************************************************************************/ +//#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) +#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) +#endif + +#define _INTERNAL_QUICK6502_CORECPU_ +#include "corecpu.h" + + +/*** Instructions useful macros ***/ +#define INSTRUCTION(s) static inline void I_##s (quick6502_cpu *cpu) + +#define NZ_FLAG_UPDATE(value) cpu->reg_P = (cpu->reg_P & ~(Q6502_N_FLAG | Q6502_Z_FLAG)) | \ + (value & 0x80) | ((value)?0:Q6502_Z_FLAG) + +#define CROSS_CYCLE_UPDATE(value) if ((value) & 0x0F00) cpu->page_crossed = 1 + +#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) ) +#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 ) + +#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_AX() cpu->memory_read( ((op1 ) |\ + (op2 << 8) ) + cpu->reg_X) +#define MEMORY_READ_AY() cpu->memory_read( ((op1 ) |\ + (op2 << 8) ) + cpu->reg_Y ) + + +#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) +#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) + +#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_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 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 + +#define ADC_OPERATION(read) do {\ + unsigned short tmp = 0; unsigned char v = read; \ + tmp = cpu->reg_A + v + (cpu->reg_P & Q6502_C_FLAG); \ + cpu->reg_P = (cpu->reg_P & ~(Q6502_C_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG | Q6502_V_FLAG)) | \ + (tmp & 0x80) | ((tmp&0xFF)?0:Q6502_Z_FLAG) | \ + ((tmp & 0xFF00)?Q6502_C_FLAG:0) | \ + ( ( ~(cpu->reg_A^v)&(cpu->reg_A^tmp) )&0x80?Q6502_V_FLAG:0 ); \ + cpu->reg_A = tmp & 0xFF; \ +} while(0) + +#define SBC_OPERATION(read) do {\ + unsigned short tmp = 0; unsigned char v = read; \ + tmp = cpu->reg_A - v - (~cpu->reg_P & Q6502_C_FLAG); \ + cpu->reg_P = (cpu->reg_P & ~(Q6502_C_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG | Q6502_V_FLAG)) | \ + (tmp & Q6502_N_FLAG) | ((tmp&0xFF)?0:Q6502_Z_FLAG) | \ + ((tmp & 0xFF00)?0:Q6502_C_FLAG) | \ + ( ( (cpu->reg_A^v)&(cpu->reg_A^tmp) )&0x80?Q6502_V_FLAG:0 ); \ + cpu->reg_A = tmp & 0xFF; \ +} while(0) + +#else +#error Quick6502 doesn't actually support DECIMAL mode +#endif + + +#define AND_OPERATION(read) cpu->reg_A &= read; NZ_FLAG_UPDATE(cpu->reg_A) + +/* CMP is like SBC but without storing the result value */ +#define CMP_OPERATION(register, read) do { \ + unsigned short tmp = 0; \ + tmp = register - read; \ + cpu->reg_P = (cpu->reg_P & ~(Q6502_C_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG)) | \ + (tmp & Q6502_N_FLAG) | ((tmp&0xFF)?0:Q6502_Z_FLAG) | \ + ((tmp & 0xFF00)?0:Q6502_C_FLAG); \ +} while(0) + +#define EOR_OPERATION(read) cpu->reg_A ^= read; NZ_FLAG_UPDATE(cpu->reg_A) +#define ORA_OPERATION(read) cpu->reg_A |= read; NZ_FLAG_UPDATE(cpu->reg_A) + +#define BIT_OPERATION(read) do { \ + byte tmp = read; \ + cpu->reg_P = (cpu->reg_P & ~(Q6502_V_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG)) | \ + (tmp & Q6502_N_FLAG) | (tmp & Q6502_V_FLAG) | \ + ((tmp & cpu->reg_A)?0:Q6502_Z_FLAG); \ +} while(0) + +#define ASL_OPERATION(val) cpu->reg_P = (cpu->reg_P & ~(Q6502_C_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG)) | \ + ((val&0x40)?Q6502_N_FLAG:0) | \ + ((val&0x80)?Q6502_C_FLAG:0) | \ + ((val&0x7F)?0:Q6502_Z_FLAG); \ + val = val << 1 + +#define LSR_OPERATION(val) cpu->reg_P = (cpu->reg_P & ~(Q6502_C_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG)) | \ + (val & Q6502_C_FLAG) | \ + ((val&0xFE)?0:Q6502_Z_FLAG); \ + val = val >> 1 + +#define ROR_OPERATION(val) do {\ + unsigned short tmp = val | (cpu->reg_P & Q6502_C_FLAG) << 8; \ + cpu->reg_P = (cpu->reg_P & ~(Q6502_C_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG)) | \ + ( tmp&Q6502_C_FLAG) | /* Set the C flag */ \ + ((tmp&0x100) >> 1) | /* Set the N flag */ \ + ((tmp&0x1FE)?0:Q6502_Z_FLAG); /* 0x1FE will be the new 8bit value */ \ + val = (tmp>>1) & 0xFF; \ +} while(0) + +#define ROL_OPERATION(val) do {\ +unsigned short tmp = (val << 1) | (cpu->reg_P & Q6502_C_FLAG); \ + cpu->reg_P = (cpu->reg_P & ~(Q6502_C_FLAG | Q6502_N_FLAG | Q6502_Z_FLAG)) | \ + ((tmp&0x100)?Q6502_C_FLAG:0) | /* Set the C flag */ \ + ((tmp&0x80)) | /* Set the N flag */ \ + ((tmp&0xFF)?0:Q6502_Z_FLAG); /* 0x1FE will be the new 8bit value */ \ + val = tmp & 0xFF; \ +} while(0) + + +/** Function used for execution of instruction */ +static inline int quick6502_exec_one(quick6502_cpu *cpu); + +/** + * Initialise the CPU + * + * Inputs: + * + * - CPU Init structure: + * - Memory Read function pointer + * - Memory Write function pointer + * - Fast memory read function pointer (for opcodes read) + * - Fast page 0 function Read/Write + * - Fast page 1 function Read/Write + * + * Output: + * + * (void *): An opaque pointer to the internal structure of the CPU. + * NULL if an error occured ! + */ +quick6502_cpu *quick6502_init(quick6502_cpuconfig *config) +{ + quick6502_cpu *cpu; + + /* Alloc structure */ + cpu = (quick6502_cpu *) malloc (sizeof (quick6502_cpu)); + if (!cpu) + return NULL; + + /* Initialise other variables */ + cpu->running = 0; /* CPU is currently NOT running */ + + cpu->cycle_done = 0; + cpu->int_pending = 0; + + cpu->page_crossed = 0; + + /* Initialise registers */ + cpu->reg_A = 0; + cpu->reg_X = 0; + cpu->reg_Y = 0; + cpu->reg_S = 0xFF; + + cpu->reg_P = Q6502_D_FLAG | Q6502_I_FLAG; + + if (config->memory_read != NULL) + cpu->memory_read = config->memory_read; + else + goto init_error; + + if (config->memory_write != NULL) + cpu->memory_write = config->memory_write; + else + goto init_error; + + if (config->memory_opcode_read != NULL) + cpu->memory_opcode_read = config->memory_opcode_read; + else + cpu->memory_opcode_read = config->memory_read; + + + if (config->memory_page0_read != NULL) + cpu->memory_page0_read = config->memory_page0_read; + else + cpu->memory_page0_read = config->memory_read; + + if (config->memory_page0_write != NULL) + cpu->memory_page0_write = config->memory_page0_write; + else + cpu->memory_page0_write = config->memory_write; + + if (config->memory_stack_read != NULL) + cpu->memory_stack_read = config->memory_stack_read; + else + cpu->memory_stack_read = config->memory_read; + + if (config->memory_stack_write != NULL) + cpu->memory_stack_write = config->memory_stack_write; + else + cpu->memory_stack_write = config->memory_write; + + return cpu; + +init_error: + if (cpu) + free (cpu); + + return NULL; +} + + +/** Reset the CPU (must be done after init) */ +void quick6502_reset(quick6502_cpu *cpu) +{ + /* Initialise registers */ + /*cpu->reg_A = 0; + cpu->reg_X = 0; + cpu->reg_Y = 0; + cpu->reg_S = 0xFF;*/ + + //cpu->reg_P = Q6502_D_FLAG | Q6502_I_FLAG | 0x20 | Q6502_B_FLAG; + + /* Set the PC to the RESET vector */ + cpu->reg_PC = ( cpu->memory_read(Q6502_RESET_HIGH) << 8) + | cpu->memory_read(Q6502_RESET_LOW); + + cpu->exit_loop = 0; +} + +/** + * Run cpu for at least X cycles + * + * Output: + * + * int: (Number of cycle really done) - (Number of cycle asked) + */ +int quick6502_run(quick6502_cpu *cpu, int cycles) +{ + cpu->running = !0; + + while(cpu->cycle_done < cycles) + { + quick6502_exec_one(cpu); + } + cpu->cycle_done -= cycles; + + cpu->running = 0; + + return cycles + cpu->cycle_done; +} + +/** Loop CPU until explicit quit */ +void quick6502_loop(quick6502_cpu *cpu) +{ + cpu->running = !0; + while(cpu->exit_loop) + { + quick6502_exec_one(cpu); + } + cpu->running = 0; +} + +/** Run CPU for one instruction */ +void quick6502_exec(quick6502_cpu *cpu) +{ + cpu->running = !0; + quick6502_exec_one(cpu); + cpu->running = 0; +} + +/** Send IRQ/NMI/EXITLOOP signal to CPU */ +void quick6502_int(quick6502_cpu *cpu, quick6502_signal signal) +{ + switch(signal) + { + default: + break; + + case Q6502_IRQ_SIGNAL: + if (! (cpu->reg_P & Q6502_I_FLAG) ) + { + TRACEi(("IRQ Triggered !")); + PUSH_S((cpu->reg_PC >> 8) & 0xFF ); + PUSH_S((cpu->reg_PC ) & 0xFF ); + PUSH_S( cpu->reg_P & ~Q6502_B_FLAG ); + cpu->reg_P = cpu->reg_P | Q6502_I_FLAG; + + cpu->reg_PC = (cpu->memory_read(Q6502_IRQ_LOW)) | (cpu->memory_read(Q6502_IRQ_HIGH)<<8); + + cpu->cycle_done += 7; + } + else + cpu->int_pending = 1; + + break; + + case Q6502_NMI_SIGNAL: + TRACEi(("NMI Triggered !")); + 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_PC = (cpu->memory_read(Q6502_NMI_LOW)) | (cpu->memory_read(Q6502_NMI_HIGH)<<8); + + cpu->cycle_done += 7; + break; + + case Q6502_STOPLOOP_SIGNAL: + cpu->exit_loop = 1; + break; + } +} + +/** Dump CPU State to the given file */ +void quick6502_dump(quick6502_cpu *cpu, FILE * fp) +{ + short i; + char instr[20]; + /* 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", + 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':'.', + '.', /* No real flag here */ + cpu->reg_P&Q6502_B_FLAG ? 'B':'.', + 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':'.' + ); + + /* Display 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, "] 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; +} + +/** + * 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 + */ +int quick6502_free(quick6502_cpu *cpu) +{ + + return 0; +} + +/******************************************************************************* + *** Here start real CPU logic *** + *******************************************************************************/ +static byte CycleTable[256] = +{ +/* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */ +/* 00 */ 7, 6, 0, 8, 3, 3, 5, 5, 3, 2, 2, 2, 4, 4, 6, 6, +/* 10 */ 2, 5, 0, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, +/* 20 */ 6, 6, 0, 8, 3, 3, 5, 5, 4, 2, 2, 2, 4, 4, 6, 6, +/* 30 */ 2, 5, 0, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, +/* 40 */ 6, 6, 0, 8, 3, 3, 5, 5, 3, 2, 2, 2, 3, 4, 6, 6, +/* 50 */ 2, 5, 0, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, +/* 60 */ 6, 6, 0, 8, 3, 3, 5, 5, 4, 2, 2, 2, 5, 4, 6, 6, +/* 70 */ 2, 5, 0, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, +/* 80 */ 2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4, +/* 90 */ 2, 6, 0, 6, 4, 4, 4, 4, 2, 5, 2, 5, 5, 5, 5, 5, +/* A0 */ 2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4, +/* B0 */ 2, 5, 0, 5, 4, 4, 4, 4, 2, 4, 2, 4, 4, 4, 4, 4, +/* C0 */ 2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6, +/* D0 */ 2, 5, 0, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, +/* E0 */ 2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6, +/* F0 */ 2, 5, 0, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7 +/* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */ +}; + +typedef void (*InstructionFunction)(quick6502_cpu *cpu); + +/******************************************************************************* + * Instruction implementations + *******************************************************************************/ + +/**** Other instructions ****/ +INSTRUCTION(ILLEG) +{ + TRACEiE(("Illegal instruction $%02X", cpu->memory_opcode_read(cpu->reg_PC-1))); + //exit(-1); +} + +/** 58 : CLI - CLear Interrupt **/ +INSTRUCTION(CLIiM) +{ + TRACEi(("CLC")); + cpu->reg_P &= ~Q6502_I_FLAG; +} +/** 78 : SEI - SEt Interrupt **/ +INSTRUCTION(SEIiM) +{ + TRACEi(("SEI")); + cpu->reg_P |= Q6502_I_FLAG; +} + +/** 18 : CLC - CLear Carry **/ +INSTRUCTION(CLCiM) +{ + TRACEi(("CLC")); + cpu->reg_P &= ~Q6502_C_FLAG; +} +/** 38 : SEC - SEt Carry **/ +INSTRUCTION(SECiM) +{ + TRACEi(("SEC")); + cpu->reg_P |= Q6502_C_FLAG; +} + +/** D8 : CLD - CLear Decimal **/ +INSTRUCTION(CLDiM) +{ + TRACEi(("CLD")); + cpu->reg_P &= ~Q6502_D_FLAG; +} +/** F8 : SED - SEt Decimal **/ +INSTRUCTION(SEDiM) +{ + TRACEi(("SED")); + cpu->reg_P |= Q6502_D_FLAG; +} +/** B8 : CLV - CLear oVerflo **/ +INSTRUCTION(CLViM) +{ + TRACEi(("CLV")); + cpu->reg_P &= ~Q6502_V_FLAG; +} + +/** EA : NOP - NO oPeration **/ +INSTRUCTION(NOPiM) +{ + TRACEi(("NOP")); +} + +/**** Load/Store functions ****/ + +/** A9 : LDA #$xx - LoaD an immediate value into A */ +INSTRUCTION(LDAiM) +{ + TRACEi(("LDA #$%02X", cpu->memory_opcode_read(cpu->reg_PC))); + cpu->reg_A = cpu->memory_opcode_read(cpu->reg_PC++); + NZ_FLAG_UPDATE(cpu->reg_A); +} + +/** A2 : LDX #$xx - LoaD an immediate value into X */ +INSTRUCTION(LDXiM) +{ + TRACEi(("LDX #$%02X", cpu->memory_opcode_read(cpu->reg_PC))); + cpu->reg_X = cpu->memory_opcode_read(cpu->reg_PC++); + NZ_FLAG_UPDATE(cpu->reg_X); +} + +/** A0 : LDY #$xx - LoaD an immediate value into Y */ +INSTRUCTION(LDYiM) +{ + TRACEi(("LDY #$%02X", cpu->memory_opcode_read(cpu->reg_PC))); + cpu->reg_Y = cpu->memory_opcode_read(cpu->reg_PC++); + NZ_FLAG_UPDATE(cpu->reg_Y); +} + +/** A5: LDA $xx - LoaD to A from zero page **/ +INSTRUCTION(LDAzP) +{ + TRACEi(("LDA $%02X", cpu->memory_opcode_read(cpu->reg_PC))); + cpu->reg_A = MEMORY_READ_ZP(); + NZ_FLAG_UPDATE(cpu->reg_A); +} + +/** B5: LDA $xx,X - LoaD to A **/ +INSTRUCTION(LDAzX) +{ + TRACEi(("LDA $%02X,X", cpu->memory_opcode_read(cpu->reg_PC))); + cpu->reg_A = MEMORY_READ_ZX(); + NZ_FLAG_UPDATE(cpu->reg_A); +} + +/** A1: LDA ($xx,X) - LoaD to A **/ +INSTRUCTION(LDAiX) +{ + TRACEi(("LDA ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC))); + cpu->reg_A = MEMORY_READ_IX(); + NZ_FLAG_UPDATE(cpu->reg_A); +} + +/** B1: LDA ($xx),Y - LoaD to A **/ +INSTRUCTION(LDAiY) +{ + TRACEi(("LDA ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC))); + cpu->reg_A = MEMORY_READ_IY(); + NZ_FLAG_UPDATE(cpu->reg_A); + CROSS_CYCLE_UPDATE(cpu->memory_opcode_read(cpu->reg_PC-1) + cpu->reg_Y); +} + +/** AD: LDA $xxxx - LoaD to A **/ +INSTRUCTION(LDAaB) +{ + TRACEi(("LDA $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + cpu->reg_A = MEMORY_READ_AB(); + NZ_FLAG_UPDATE(cpu->reg_A); +} + +/** DD: LDA $xxxx,X - LoaD to A **/ +INSTRUCTION(LDAaX) +{ + register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++); + register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++); + + TRACEi(("LDA $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + cpu->reg_A = MEMORY_READ_AX(); + NZ_FLAG_UPDATE(cpu->reg_A); + CROSS_CYCLE_UPDATE(op1 + cpu->reg_X); +} + +/** D9: LDA $xxxx,Y - LoaD to A **/ +INSTRUCTION(LDAaY) +{ + register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++); + register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++); + cpu->reg_A = MEMORY_READ_AY(); + NZ_FLAG_UPDATE(cpu->reg_A); + CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y); +} + +/** 85: STA $xx - STore A to zero page **/ +INSTRUCTION(STAzP) +{ + TRACEi(("STA $%02X", cpu->memory_opcode_read(cpu->reg_PC))); + cpu->memory_page0_write(cpu->memory_opcode_read(cpu->reg_PC++), cpu->reg_A); +} + +/** 95: STA $xx,X - STore A **/ +INSTRUCTION(STAzX) +{ + TRACEi(("STA $%02X,X", cpu->memory_opcode_read(cpu->reg_PC))); + MEMORY_WRITE_ZX(cpu->reg_A); +} + +/** 81: STA ($xx,X) - STore A **/ +INSTRUCTION(STAiX) +{ + TRACEi(("STA ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC))); + MEMORY_WRITE_IX(cpu->reg_A); +} + +/** 91: STA ($xx),Y - STore A **/ +INSTRUCTION(STAiY) +{ + TRACEi(("STA ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC))); + MEMORY_WRITE_IY(cpu->reg_A); +} + +/** 8D: STA $xxxx - STore A **/ +INSTRUCTION(STAaB) +{ + TRACEi(("STA $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + MEMORY_WRITE_AB(cpu->reg_A); +} + +/** 9D: STA $xxxx,X - STore A **/ +INSTRUCTION(STAaX) +{ + TRACEi(("STA $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + MEMORY_WRITE_AX(cpu->reg_A); +} + +/** 99: STA $xxxx,Y - STore A **/ +INSTRUCTION(STAaY) +{ + TRACEi(("STA $%02X%02X,Y", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + MEMORY_WRITE_AY(cpu->reg_A); +} + +/** A6: LDX $xx - LoaD to X from zero page **/ +INSTRUCTION(LDXzP) +{ + TRACEi(("LDX $%02X", cpu->memory_opcode_read(cpu->reg_PC))); + cpu->reg_X = MEMORY_READ_ZP(); + NZ_FLAG_UPDATE(cpu->reg_X); +} + +/** B6: LDX $xx,Y - LoaD to X **/ +INSTRUCTION(LDXzY) +{ + TRACEi(("LDX $%02X,Y", cpu->memory_opcode_read(cpu->reg_PC))); + cpu->reg_X = MEMORY_READ_ZY(); + NZ_FLAG_UPDATE(cpu->reg_X); +} + +/** AE: LDX $xxxx - LoaD to X **/ +INSTRUCTION(LDXaB) +{ + TRACEi(("LDX $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + cpu->reg_X = MEMORY_READ_AB(); + NZ_FLAG_UPDATE(cpu->reg_X); +} + +/** BE: LDX $xxxx,Y - LoaD to X **/ +INSTRUCTION(LDXaY) +{ + register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++); + register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++); + TRACEi(("LDX $%02X%02X,Y", op2, op1)); + cpu->reg_X = MEMORY_READ_AY(); + NZ_FLAG_UPDATE(cpu->reg_X); + CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y); +} + +/** B6: STX $xx - STore X to zero page **/ +INSTRUCTION(STXzP) +{ + TRACEi(("STX $%02X", cpu->memory_opcode_read(cpu->reg_PC))); + cpu->memory_page0_write(cpu->memory_opcode_read(cpu->reg_PC++), cpu->reg_X); +} + +/** 96: STX $xx,Y - STore X **/ +INSTRUCTION(STXzY) +{ + TRACEi(("STX $%02X,Y", cpu->memory_opcode_read(cpu->reg_PC))); + MEMORY_WRITE_ZY(cpu->reg_X); +} + +/** 8E: STX $xxxx - STore X **/ +INSTRUCTION(STXaB) +{ + TRACEi(("STX $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + MEMORY_WRITE_AB(cpu->reg_X); +} + +/** A4: LDY $xx - LoaD to Y from zero page **/ +INSTRUCTION(LDYzP) +{ + TRACEi(("LDY $%02X", cpu->memory_opcode_read(cpu->reg_PC))); + cpu->reg_Y = MEMORY_READ_ZP(); + NZ_FLAG_UPDATE(cpu->reg_Y); +} + +/** B4: LDY $xx,X - LoaD to Y **/ +INSTRUCTION(LDYzX) +{ + TRACEi(("LDY $%02X,X", cpu->memory_opcode_read(cpu->reg_PC))); + cpu->reg_Y = MEMORY_READ_ZX(); + NZ_FLAG_UPDATE(cpu->reg_Y); +} + +/** AC: LDY $xxxx - LoaD to Y **/ +INSTRUCTION(LDYaB) +{ + TRACEi(("LDY $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + cpu->reg_Y = MEMORY_READ_AB(); + NZ_FLAG_UPDATE(cpu->reg_Y); +} + +/** BC: LDY $xxxx,X - LoaD to Y **/ +INSTRUCTION(LDYaX) +{ + register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++); + register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++); + + TRACEi(("LDY $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + cpu->reg_Y = MEMORY_READ_AX(); + NZ_FLAG_UPDATE(cpu->reg_Y); + + CROSS_CYCLE_UPDATE(op1 + cpu->reg_X); +} + +/** 84: STY $xx - STore Y to zero page **/ +INSTRUCTION(STYzP) +{ + TRACEi(("STY $%02X", cpu->memory_opcode_read(cpu->reg_PC))); + cpu->memory_page0_write(cpu->memory_opcode_read(cpu->reg_PC++), cpu->reg_Y); +} + +/** 94: STY $xx,X - STore Y **/ +INSTRUCTION(STYzX) +{ + TRACEi(("STY $%02X,X", cpu->memory_opcode_read(cpu->reg_PC))); + MEMORY_WRITE_ZX(cpu->reg_Y); +} + +/** 8C: STY $xxxx - STore Y **/ +INSTRUCTION(STYaB) +{ + TRACEi(("STY $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + MEMORY_WRITE_AB(cpu->reg_Y); +} + +/**** Register functions ****/ + +/** AA : TAX - Transfer A to X **/ +INSTRUCTION(TAXiM) +{ + TRACEi(("TAX")); + cpu->reg_X = cpu->reg_A; + NZ_FLAG_UPDATE(cpu->reg_X); +} + +/** 8A : TXA - Transfer X to A **/ +INSTRUCTION(TXAiM) +{ + TRACEi(("TXA")); + cpu->reg_A = cpu->reg_X; + NZ_FLAG_UPDATE(cpu->reg_A); +} + +/** A8 : TAY - Transfer A to Y **/ +INSTRUCTION(TAYiM) +{ + TRACEi(("TAY")); + cpu->reg_Y = cpu->reg_A; + NZ_FLAG_UPDATE(cpu->reg_Y); +} + +/** 98 : TYA - Transfer Y to A **/ +INSTRUCTION(TYAiM) +{ + TRACEi(("TYA")); + cpu->reg_A = cpu->reg_Y; + NZ_FLAG_UPDATE(cpu->reg_A); +} + +/* BA : TSX - Transfer S to X **/ +INSTRUCTION(TSXiM) +{ + TRACEi(("TSX")); + cpu->reg_X = cpu->reg_S; + NZ_FLAG_UPDATE(cpu->reg_X); +} + +/** 9A : TXS - Transfer X to S **/ +INSTRUCTION(TXSiM) +{ + TRACEi(("TXS")); + cpu->reg_S = cpu->reg_X; +} + +/**** Simple register operation instructions ****/ + +/** CA : DEX - DEcrement X **/ +INSTRUCTION(DEXiM) +{ + TRACEi(("DEX")); + cpu->reg_X --; + NZ_FLAG_UPDATE(cpu->reg_X); +} + +/** 88 : DEY - DEcrement Y **/ +INSTRUCTION(DEYiM) +{ + TRACEi(("DEY")); + cpu->reg_Y --; + NZ_FLAG_UPDATE(cpu->reg_Y); +} + +/** E8 : INX - INcrement X **/ +INSTRUCTION(INXiM) +{ + TRACEi(("INX")); + cpu->reg_X ++; + NZ_FLAG_UPDATE(cpu->reg_X); +} + +/** C8 : INY - INcrement Y **/ +INSTRUCTION(INYiM) +{ + TRACEi(("INY")); + cpu->reg_Y ++; + NZ_FLAG_UPDATE(cpu->reg_Y); +} + +/**** Stack related instructions ****/ + +/** 48 : PHA - PusH A */ +INSTRUCTION(PHAiM) +{ + TRACEi(("PHA")); + PUSH_S(cpu->reg_A); +} + +/** 68 : PLA - PuLl A */ +INSTRUCTION(PLAiM) +{ + TRACEi(("PLA")); + cpu->reg_A = POP_S(); + NZ_FLAG_UPDATE(cpu->reg_A); +} + +/** 08 : PHP - PusH P */ +INSTRUCTION(PHPiM) +{ + TRACEi(("PHP")); + PUSH_S((cpu->reg_P | Q6502_R_FLAG | Q6502_B_FLAG)); +} + +/** 28 : PLP - PuLl P */ +INSTRUCTION(PLPiM) +{ + TRACEi(("PLP")); + cpu->reg_P = POP_S() & ~(Q6502_R_FLAG | Q6502_B_FLAG); + if (cpu->int_pending != 0) + { + quick6502_int(cpu, Q6502_IRQ_SIGNAL); + } +} + +/**** Branch instructions ****/ + +/** 20 : JSR $xxxx - Jump to SubRoutine */ +INSTRUCTION(JSRaB) +{ + TRACEi(("JSR $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + cpu->reg_PC++; + PUSH_S((cpu->reg_PC >> 8) & 0xFF); + PUSH_S((cpu->reg_PC ) & 0xFF); + cpu->reg_PC = ((cpu->memory_opcode_read(cpu->reg_PC-1) ) | (cpu->memory_opcode_read(cpu->reg_PC) << 8)); +} + +/** 60 : RTS - ReTurn from Subrutine */ +INSTRUCTION(RTSiM) +{ + TRACEi(("RTS")); + cpu->reg_PC = POP_S() | (POP_S() << 8); + cpu->reg_PC ++; +} + +/** 4C : JMP $xxxx - JuMP inconditionaly to $xxxx **/ +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); +} + +/** 6C : JMP ($xxxx) - JuMP inconditionaly to ($xxxx) **/ +INSTRUCTION(JMPiD) +{ + 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+1) << 8); + cpu->reg_PC = cpu->memory_read(cpu->reg_PC) | + (cpu->memory_read((cpu->reg_PC & 0xFF00) | ((cpu->reg_PC+1) & 0x00FF)) << 8); +} + +/** 00 : BRK - BReaK **/ +INSTRUCTION(BRKiM) +{ + TRACEi(("BRK")); + cpu->reg_PC++; + 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_PC = (cpu->memory_read(Q6502_IRQ_LOW)) | (cpu->memory_read(Q6502_IRQ_HIGH)<<8); +} + +/** 40 : RTI - ReTurn from Interruption **/ +INSTRUCTION(RTIiM) +{ + TRACEi(("RTI")); + cpu->reg_P = POP_S(); + cpu->reg_PC = POP_S() | (POP_S() << 8); + + if (cpu->int_pending != 0) + { + quick6502_int(cpu, Q6502_IRQ_SIGNAL); + } +} + +/** 90 : BCC - Branch if Carry Clear **/ +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; + /* Need to set timing */ + + /* +1 is same page */ + cpu->cycle_done += 1; + /* +2 is another */ + } + else + cpu->reg_PC ++; +} + +/** B0 : BCS - Branch if Carry Set**/ +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; + /* Need to set timing */ + + /* +1 is same page */ + cpu->cycle_done += 1; + /* +2 is another */ + } + else + cpu->reg_PC ++; +} + +/** F0 : BEQ - Branch if Equal**/ +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; + /* Need to set timing */ + + /* +1 is same page */ + cpu->cycle_done += 1; + /* +2 is another */ + } + else + cpu->reg_PC ++; +} + +/** 30 : BMI - Branch if MInus**/ +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; + /* Need to set timing */ + + /* +1 is same page */ + cpu->cycle_done += 1; + /* +2 is another */ + } + else + cpu->reg_PC ++; +} + +/** D0 : Bxx - Branch if Not Equal**/ +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; + /* Need to set timing */ + + /* +1 is same page */ + cpu->cycle_done += 1; + /* +2 is another */ + } + else + cpu->reg_PC ++; +} + +/** 10 : BPL - Branch if PLus **/ +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; + /* Need to set timing */ + + /* +1 is same page */ + cpu->cycle_done += 1; + /* +2 is another */ + } + else + cpu->reg_PC ++; +} + +/** 50 : BVC - Branch if oVerflow Clear**/ +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; + /* Need to set timing */ + + /* +1 is same page */ + cpu->cycle_done += 1; + /* +2 is another */ + } + else + cpu->reg_PC ++; +} + +/** 70 : BVS - Branch if oVerflow Set**/ +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; + /* Need to set timing */ + + /* +1 is same page */ + cpu->cycle_done += 1; + /* +2 is another */ + } + else + cpu->reg_PC ++; +} + +/*** Mathematical functions ***/ + +/** 69 : ADC - ADd with Carry **/ +INSTRUCTION(ADCiM) +{ + TRACEi(("ADC #$%02X", cpu->memory_opcode_read(cpu->reg_PC) )); + ADC_OPERATION(cpu->memory_opcode_read(cpu->reg_PC++)); +} + +/** 65 : ADC - ADd with Carry **/ +INSTRUCTION(ADCzP) +{ + TRACEi(("ADC $%02X", cpu->memory_opcode_read(cpu->reg_PC) )); + ADC_OPERATION(MEMORY_READ_ZP()); +} + +/** 75 : ADC - ADd with Carry **/ +INSTRUCTION(ADCzX) +{ + TRACEi(("ADC $%02X,X", cpu->memory_opcode_read(cpu->reg_PC) )); + ADC_OPERATION(MEMORY_READ_ZX()); +} + +/** 61 : ADC - ADd with Carry **/ +INSTRUCTION(ADCiX) +{ + TRACEi(("ADC ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC) )); + ADC_OPERATION(MEMORY_READ_IX()); +} + +/** 71 : ADC - ADd with Carry **/ +INSTRUCTION(ADCiY) +{ + TRACEi(("ADC ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC) )); + ADC_OPERATION(MEMORY_READ_IY()); + CROSS_CYCLE_UPDATE(cpu->memory_opcode_read(cpu->reg_PC-1) + cpu->reg_Y); +} + +/** 6D : ADC - ADd with Carry **/ +INSTRUCTION(ADCaB) +{ + TRACEi(("ADC $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + ADC_OPERATION(MEMORY_READ_AB()); +} + +/** 7D : ADC - ADd with Carry **/ +INSTRUCTION(ADCaX) +{ + register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++); + register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++); + + TRACEi(("ADC $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + ADC_OPERATION(MEMORY_READ_AX()); + CROSS_CYCLE_UPDATE(op1 + cpu->reg_X); +} + +/** 79 : ADC - ADd with Carry **/ +INSTRUCTION(ADCaY) +{ + register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++); + register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++); + TRACEi(("ADC $%02X%02X,Y", op2, op1)); + ADC_OPERATION(MEMORY_READ_AY()); + CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y); +} + +/** E9 : SBC - SuBstract with Carry **/ +INSTRUCTION(SBCiM) +{ + TRACEi(("SBC #$%02X", cpu->memory_opcode_read(cpu->reg_PC) )); + SBC_OPERATION(cpu->memory_opcode_read(cpu->reg_PC++)); +} + +/** E5 : SBC - SuBstract with Carry **/ +INSTRUCTION(SBCzP) +{ + TRACEi(("SBC $%02X", cpu->memory_opcode_read(cpu->reg_PC) )); + SBC_OPERATION(MEMORY_READ_ZP()); +} + +/** F5 : SBC - SuBstract with Carry **/ +INSTRUCTION(SBCzX) +{ + TRACEi(("SBC $%02X,X", cpu->memory_opcode_read(cpu->reg_PC) )); + SBC_OPERATION(MEMORY_READ_ZX()); +} + +/** E1 : SBC - SuBstract with Carry **/ +INSTRUCTION(SBCiX) +{ + TRACEi(("SBC ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC) )); + SBC_OPERATION(MEMORY_READ_IX()); +} + +/** F1 : SBC - SuBstract with Carry **/ +INSTRUCTION(SBCiY) +{ + TRACEi(("SBC ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC) )); + SBC_OPERATION(MEMORY_READ_IY()); + CROSS_CYCLE_UPDATE(cpu->memory_opcode_read(cpu->reg_PC-1) + cpu->reg_Y); +} + +/** ED : SBC - SuBstract with Carry **/ +INSTRUCTION(SBCaB) +{ + TRACEi(("SBC $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + SBC_OPERATION(MEMORY_READ_AB()); +} + +/** FD : SBC - SuBstract with Carry **/ +INSTRUCTION(SBCaX) +{ + register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++); + register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++); + + TRACEi(("SBC $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + SBC_OPERATION(MEMORY_READ_AX()); + + CROSS_CYCLE_UPDATE(op1 + cpu->reg_X); +} + +/** F9 : SBC - SuBstract with Carry **/ +INSTRUCTION(SBCaY) +{ + register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++); + register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++); + TRACEi(("SBC $%02X%02X,Y", op2, op1)); + SBC_OPERATION(MEMORY_READ_AY()); + CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y); +} + +/** C9 : CMP - CoMPare **/ +INSTRUCTION(CMPiM) +{ + TRACEi(("CMP #$%02X", cpu->memory_opcode_read(cpu->reg_PC) )); + CMP_OPERATION(cpu->reg_A, cpu->memory_opcode_read(cpu->reg_PC++)); +} + +/** C5 : CMP - CoMPare **/ +INSTRUCTION(CMPzP) +{ + TRACEi(("CMP $%02X", cpu->memory_opcode_read(cpu->reg_PC) )); + CMP_OPERATION(cpu->reg_A, MEMORY_READ_ZP()); +} + +/** D5 : CMP - CoMPare **/ +INSTRUCTION(CMPzX) +{ + TRACEi(("CMP $%02X,X", cpu->memory_opcode_read(cpu->reg_PC) )); + CMP_OPERATION(cpu->reg_A, MEMORY_READ_ZX()); +} + +/** C1 : CMP - CoMPare **/ +INSTRUCTION(CMPiX) +{ + TRACEi(("CMP ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC) )); + CMP_OPERATION(cpu->reg_A, MEMORY_READ_IX()); +} + +/** D1 : CMP - CoMPare **/ +INSTRUCTION(CMPiY) +{ + TRACEi(("CMP ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC) )); + CMP_OPERATION(cpu->reg_A, MEMORY_READ_IY()); + CROSS_CYCLE_UPDATE(cpu->memory_opcode_read(cpu->reg_PC-1) + cpu->reg_Y); +} + +/** CD : CMP - CoMPare **/ +INSTRUCTION(CMPaB) +{ + TRACEi(("CMP $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + CMP_OPERATION(cpu->reg_A, MEMORY_READ_AB()); +} + +/** DD : CMP - CoMPare **/ +INSTRUCTION(CMPaX) +{ + register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++); + register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++); + + TRACEi(("CMP $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + CMP_OPERATION(cpu->reg_A, MEMORY_READ_AX()); + CROSS_CYCLE_UPDATE(op1 + cpu->reg_X); +} + +/** D9 : CMP - CoMPare **/ +INSTRUCTION(CMPaY) +{ + register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++); + register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++); + TRACEi(("CMP $%02X%02X,Y", op2, op1)); + CMP_OPERATION(cpu->reg_A, MEMORY_READ_AY()); + CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y); +} + +/** E0 : CPX - ComPare with Y **/ +INSTRUCTION(CPXiM) +{ + TRACEi(("CPX #$%02X", cpu->memory_opcode_read(cpu->reg_PC))); + CMP_OPERATION(cpu->reg_X, cpu->memory_opcode_read(cpu->reg_PC++)); +} + +/** E4 : CPX - ComPare with X **/ +INSTRUCTION(CPXzP) +{ + TRACEi(("CPX $%02X", cpu->memory_opcode_read(cpu->reg_PC))); + CMP_OPERATION(cpu->reg_X, MEMORY_READ_ZP()); +} + +/** EC : CPX - ComPare with X **/ +INSTRUCTION(CPXaB) +{ + TRACEi(("CPX $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + CMP_OPERATION(cpu->reg_X, MEMORY_READ_AB()); +} + +/** C0 : CPY - ComPare with Y **/ +INSTRUCTION(CPYiM) +{ + TRACEi(("CPY #$%02X", cpu->memory_opcode_read(cpu->reg_PC))); + CMP_OPERATION(cpu->reg_Y, cpu->memory_opcode_read(cpu->reg_PC++)); +} + +/** C4 : CPY - ComPare with Y **/ +INSTRUCTION(CPYzP) +{ + TRACEi(("CPY $%02X", cpu->memory_opcode_read(cpu->reg_PC))); + CMP_OPERATION(cpu->reg_Y, MEMORY_READ_ZP()); +} + +/** CC : CPY - ComPare with Y **/ +INSTRUCTION(CPYaB) +{ + TRACEi(("CPY $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + CMP_OPERATION(cpu->reg_Y, MEMORY_READ_AB()); +} + +/** 09 : ORA - OR with A **/ +INSTRUCTION(ORAiM) +{ + TRACEi(("ORA #$%02X", cpu->memory_opcode_read(cpu->reg_PC) )); + ORA_OPERATION(cpu->memory_opcode_read(cpu->reg_PC++)); +} + +/** 405 : ORA - OR with A **/ +INSTRUCTION(ORAzP) +{ + TRACEi(("ORA $%02X", cpu->memory_opcode_read(cpu->reg_PC) )); + ORA_OPERATION(cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC++))); +} + +/** 15 : ORA - OR with A **/ +INSTRUCTION(ORAzX) +{ + TRACEi(("ORA $%02X,X", cpu->memory_opcode_read(cpu->reg_PC) )); + ORA_OPERATION(MEMORY_READ_ZX()); +} + +/** 01 : ORA - OR with A **/ +INSTRUCTION(ORAiX) +{ + TRACEi(("ORA ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC) )); + ORA_OPERATION(MEMORY_READ_IX()); +} + +/** 11 : ORA - OR with A **/ +INSTRUCTION(ORAiY) +{ + TRACEi(("ORA ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC) )); + ORA_OPERATION(MEMORY_READ_IY()); + CROSS_CYCLE_UPDATE(cpu->memory_opcode_read(cpu->reg_PC-1) + cpu->reg_Y); +} + +/** 0D : ORA - OR with A **/ +INSTRUCTION(ORAaB) +{ + TRACEi(("ORA $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + ORA_OPERATION(MEMORY_READ_AB()); +} + +/** 1D : ORA - OR with A **/ +INSTRUCTION(ORAaX) +{ + register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++); + register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++); + + TRACEi(("ORA $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + ORA_OPERATION(MEMORY_READ_AX()); + CROSS_CYCLE_UPDATE(op1 + cpu->reg_X); +} + +/** 19 : ORA - OR with A **/ +INSTRUCTION(ORAaY) +{ + register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++); + register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++); + + TRACEi(("ORA $%02X%02X,Y", op2, op1)); + ORA_OPERATION(MEMORY_READ_AY()); + CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y); +} + +/** 49 : EOR - Exclusive OR **/ +INSTRUCTION(EORiM) +{ + TRACEi(("EOR #$%02X", cpu->memory_opcode_read(cpu->reg_PC) )); + EOR_OPERATION(cpu->memory_opcode_read(cpu->reg_PC++)); +} + +/** 45 : EOR - Exclusive OR **/ +INSTRUCTION(EORzP) +{ + TRACEi(("EOR $%02X", cpu->memory_opcode_read(cpu->reg_PC) )); + EOR_OPERATION(cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC++))); +} + +/** 55 : EOR - Exclusive OR **/ +INSTRUCTION(EORzX) +{ + TRACEi(("EOR $%02X,X", cpu->memory_opcode_read(cpu->reg_PC) )); + EOR_OPERATION(MEMORY_READ_ZX()); +} + +/** 41 : EOR - Exclusive OR **/ +INSTRUCTION(EORiX) +{ + TRACEi(("EOR ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC) )); + EOR_OPERATION(MEMORY_READ_IX()); +} + +/** 51 : EOR - Exclusive OR **/ +INSTRUCTION(EORiY) +{ + TRACEi(("EOR ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC) )); + EOR_OPERATION(MEMORY_READ_IY()); + + CROSS_CYCLE_UPDATE(cpu->memory_opcode_read(cpu->reg_PC-1) + cpu->reg_Y); +} + +/** 4D : EOR - Exclusive OR **/ +INSTRUCTION(EORaB) +{ + TRACEi(("EOR $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + EOR_OPERATION(MEMORY_READ_AB()); +} + +/** 5D : EOR - Exclusive OR **/ +INSTRUCTION(EORaX) +{ + register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++); + register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++); + + TRACEi(("EOR $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + EOR_OPERATION(MEMORY_READ_AX()); + CROSS_CYCLE_UPDATE(op1 + cpu->reg_X); +} + +/** 59 : EOR - Exclusive OR **/ +INSTRUCTION(EORaY) +{ + register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++); + register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++); + TRACEi(("EOR $%02X%02X,Y", op2, op1)); + EOR_OPERATION(MEMORY_READ_AY()); + CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y); +} + +/** 29 : AND - Logical AND **/ +INSTRUCTION(ANDiM) +{ + TRACEi(("AND #$%02X", cpu->memory_opcode_read(cpu->reg_PC) )); + AND_OPERATION(cpu->memory_opcode_read(cpu->reg_PC++)); +} + +/** 25 : AND - Logical AND **/ +INSTRUCTION(ANDzP) +{ + TRACEi(("AND $%02X", cpu->memory_opcode_read(cpu->reg_PC) )); + AND_OPERATION(cpu->memory_page0_read(cpu->memory_opcode_read(cpu->reg_PC++))); +} + +/** 35 : AND - Logical AND **/ +INSTRUCTION(ANDzX) +{ + TRACEi(("AND $%02X,X", cpu->memory_opcode_read(cpu->reg_PC) )); + AND_OPERATION(MEMORY_READ_ZX()); +} + +/** 21 : AND - Logical AND **/ +INSTRUCTION(ANDiX) +{ + TRACEi(("AND ($%02X,X)", cpu->memory_opcode_read(cpu->reg_PC) )); + AND_OPERATION(MEMORY_READ_IX()); +} + +/** 31 : AND - Logical AND **/ +INSTRUCTION(ANDiY) +{ + TRACEi(("AND ($%02X),Y", cpu->memory_opcode_read(cpu->reg_PC) )); + AND_OPERATION(MEMORY_READ_IY()); + + CROSS_CYCLE_UPDATE(cpu->memory_opcode_read(cpu->reg_PC-1) + cpu->reg_Y); +} + +/** 2D : AND - Logical AND **/ +INSTRUCTION(ANDaB) +{ + TRACEi(("AND $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + AND_OPERATION(MEMORY_READ_AB()); +} + +/** 3D : AND - Logical AND **/ +INSTRUCTION(ANDaX) +{ + register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++); + register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++); + + TRACEi(("AND $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + AND_OPERATION(MEMORY_READ_AX()); + + CROSS_CYCLE_UPDATE(op1 + cpu->reg_X); +} + +/** 39 : AND - Logical AND **/ +INSTRUCTION(ANDaY) +{ + register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++); + register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++); + TRACEi(("AND $%02X%02X,Y", op2, op1)); + AND_OPERATION(MEMORY_READ_AY()); + CROSS_CYCLE_UPDATE(op1 + cpu->reg_Y); +} + +/*** Misc instructions ***/ + +/** 24 : BIT **/ +INSTRUCTION(BITzP) +{ + TRACEi(("BIT $%02X", cpu->memory_opcode_read(cpu->reg_PC))); + BIT_OPERATION(MEMORY_READ_ZP()); +} + +/** 2C : BIT **/ +INSTRUCTION(BITaB) +{ + TRACEi(("BIT $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + BIT_OPERATION(MEMORY_READ_AB()); +} + +/** 2A : ROL A **/ +INSTRUCTION(ROLiM) +{ + TRACEi(("ROL A")); + ROL_OPERATION(cpu->reg_A); +} + +/** 6A : ROR A **/ +INSTRUCTION(RORiM) +{ + TRACEi(("ROR A")); + ROR_OPERATION(cpu->reg_A); +} + +/** 0A : ASL A **/ +INSTRUCTION(ASLiM) +{ + TRACEi(("ASL A")); + ASL_OPERATION(cpu->reg_A); +} + +/** 4A : LSR A **/ +INSTRUCTION(LSRiM) +{ + TRACEi(("LSR A")); + LSR_OPERATION(cpu->reg_A); +} + +/** 2E : ROL **/ +INSTRUCTION(ROLaB) +{ + TRACEi(("ROL $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + byte val = MEMORY_READ_AB(); + cpu->reg_PC -= 2; + ROL_OPERATION(val); + MEMORY_WRITE_AB(val); +} + +/** 26 : ROL **/ +INSTRUCTION(ROLzP) +{ + TRACEi(("ROL $%02X", cpu->memory_opcode_read(cpu->reg_PC))); + byte val = MEMORY_READ_ZP(); + cpu->reg_PC -= 1; + ROL_OPERATION(val); + MEMORY_WRITE_ZP(val); +} + +/** 3E : ROL **/ +INSTRUCTION(ROLaX) +{ + register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++); + register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++); + + TRACEi(("ROL $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + byte val = MEMORY_READ_AX(); + cpu->reg_PC -= 2; + ROL_OPERATION(val); + MEMORY_WRITE_AX(val); +} + +/** 36 : ROL **/ +INSTRUCTION(ROLzX) +{ + TRACEi(("ROL $%02X,X", cpu->memory_opcode_read(cpu->reg_PC))); + byte val = MEMORY_READ_ZX(); + cpu->reg_PC -= 1; + ROL_OPERATION(val); + MEMORY_WRITE_ZX(val); +} + +/** 6E : ROR **/ +INSTRUCTION(RORaB) +{ + TRACEi(("ROR $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + byte val = MEMORY_READ_AB(); + cpu->reg_PC -= 2; + ROR_OPERATION(val); + MEMORY_WRITE_AB(val); +} + +/** 66 : ROR **/ +INSTRUCTION(RORzP) +{ + TRACEi(("ROR $%02X", cpu->memory_opcode_read(cpu->reg_PC))); + byte val = MEMORY_READ_ZP(); + cpu->reg_PC -= 1; + ROR_OPERATION(val); + MEMORY_WRITE_ZP(val); +} + +/** 7E : ROR **/ +INSTRUCTION(RORaX) +{ + register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++); + register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++); + + TRACEi(("ROR $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + byte val = MEMORY_READ_AX(); + cpu->reg_PC -= 2; + ROR_OPERATION(val); + MEMORY_WRITE_AX(val); +} + +/** 76 : ROR **/ +INSTRUCTION(RORzX) +{ + TRACEi(("ROR $%02X,X", cpu->memory_opcode_read(cpu->reg_PC))); + byte val = MEMORY_READ_ZX(); + cpu->reg_PC -= 1; + ROR_OPERATION(val); + MEMORY_WRITE_ZX(val); +} + +/** 0E : ASL **/ +INSTRUCTION(ASLaB) +{ + TRACEi(("ASL $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + byte val = MEMORY_READ_AB(); + cpu->reg_PC -= 2; + ASL_OPERATION(val); + MEMORY_WRITE_AB(val); +} + +/** 06 : ASL **/ +INSTRUCTION(ASLzP) +{ + TRACEi(("ASL $%02X", cpu->memory_opcode_read(cpu->reg_PC))); + byte val = MEMORY_READ_ZP(); + cpu->reg_PC -= 1; + ASL_OPERATION(val); + MEMORY_WRITE_ZP(val); +} + +/** 1E : ASL **/ +INSTRUCTION(ASLaX) +{ + register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++); + register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++); + + TRACEi(("ASL $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + byte val = MEMORY_READ_AX(); + cpu->reg_PC -= 2; + ASL_OPERATION(val); + MEMORY_WRITE_AX(val); +} + +/** 16 : ASL **/ +INSTRUCTION(ASLzX) +{ + TRACEi(("ASL $%02X,X", cpu->memory_opcode_read(cpu->reg_PC))); + byte val = MEMORY_READ_ZX(); + cpu->reg_PC -= 1; + ASL_OPERATION(val); + MEMORY_WRITE_ZX(val); +} + +/** 4E : LSR **/ +INSTRUCTION(LSRaB) +{ + TRACEi(("LSR $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + byte val = MEMORY_READ_AB(); + cpu->reg_PC -= 2; + LSR_OPERATION(val); + MEMORY_WRITE_AB(val); +} + +/** 46 : LSR **/ +INSTRUCTION(LSRzP) +{ + TRACEi(("LSR $%02X", cpu->memory_opcode_read(cpu->reg_PC))); + byte val = MEMORY_READ_ZP(); + cpu->reg_PC -= 1; + LSR_OPERATION(val); + MEMORY_WRITE_ZP(val); +} + +/** 5E : LSR **/ +INSTRUCTION(LSRaX) +{ + register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++); + register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++); + + TRACEi(("LSR $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + byte val = MEMORY_READ_AX(); + cpu->reg_PC -= 2; + LSR_OPERATION(val); + MEMORY_WRITE_AX(val); +} + +/** 56 : LSR **/ +INSTRUCTION(LSRzX) +{ + TRACEi(("LSR $%02X,X", cpu->memory_opcode_read(cpu->reg_PC))); + byte val = MEMORY_READ_ZX(); + cpu->reg_PC -= 1; + LSR_OPERATION(val); + MEMORY_WRITE_ZX(val); +} + +/** CE : DEC **/ +INSTRUCTION(DECaB) +{ + TRACEi(("DEC $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + byte val = MEMORY_READ_AB(); + cpu->reg_PC -= 2; + MEMORY_WRITE_AB(--val); + NZ_FLAG_UPDATE(val); +} + +/** C6 : DEC **/ +INSTRUCTION(DECzP) +{ + TRACEi(("DEC $%02X", cpu->memory_opcode_read(cpu->reg_PC))); + byte val = MEMORY_READ_ZP(); + cpu->reg_PC -= 1; + MEMORY_WRITE_ZP(--val); + NZ_FLAG_UPDATE(val); +} + +/** DE : DEC **/ +INSTRUCTION(DECaX) +{ + register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++); + register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++); + + TRACEi(("DEC $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + byte val = MEMORY_READ_AX(); + cpu->reg_PC -= 2; + MEMORY_WRITE_AX(--val); + NZ_FLAG_UPDATE(val); +} + +/** D6 : DEC **/ +INSTRUCTION(DECzX) +{ + TRACEi(("DEC $%02X,X", cpu->memory_opcode_read(cpu->reg_PC))); + byte val = MEMORY_READ_ZX(); + cpu->reg_PC -= 1; + MEMORY_WRITE_ZX(--val); + NZ_FLAG_UPDATE(val); +} + +/** EE : INC **/ +INSTRUCTION(INCaB) +{ + TRACEi(("INC $%02X%02X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + byte val = MEMORY_READ_AB(); + cpu->reg_PC -= 2; + MEMORY_WRITE_AB(++val); + NZ_FLAG_UPDATE(val); +} + +/** E6 : INC **/ +INSTRUCTION(INCzP) +{ + TRACEi(("INC $%02X", cpu->memory_opcode_read(cpu->reg_PC))); + byte val = MEMORY_READ_ZP(); + cpu->reg_PC -= 1; + MEMORY_WRITE_ZP(++val); + NZ_FLAG_UPDATE(val); +} + +/** FE : INC **/ +INSTRUCTION(INCaX) +{ + register byte op1 = cpu->memory_opcode_read(cpu->reg_PC++); + register byte op2 = cpu->memory_opcode_read(cpu->reg_PC++); + + TRACEi(("INC $%02X%02X,X", cpu->memory_opcode_read(cpu->reg_PC+1), cpu->memory_opcode_read(cpu->reg_PC))); + byte val = MEMORY_READ_AX(); + cpu->reg_PC -= 2; + MEMORY_WRITE_AX(++val); + NZ_FLAG_UPDATE(val); +} + +/** F6 : INC **/ +INSTRUCTION(INCzX) +{ + TRACEi(("INC $%02X,X", cpu->memory_opcode_read(cpu->reg_PC))); + byte val = MEMORY_READ_ZX(); + cpu->reg_PC -= 1; + MEMORY_WRITE_ZX(++val); + 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 */ +}; + + +static inline int quick6502_exec_one(quick6502_cpu *cpu) +{ + register byte opcode = cpu->memory_opcode_read(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':'.', + cpu->reg_P&Q6502_V_FLAG ? 'V':'.', + cpu->reg_P&Q6502_R_FLAG ? 'R':'.', + cpu->reg_P&Q6502_B_FLAG ? 'B':'.', + 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':'.')); + + InstructionTable[opcode](cpu); + cpu->cycle_done += CycleTable[opcode]; + if (cpu->page_crossed) { cpu->cycle_done++; cpu->page_crossed = 0; } + if (cpu->int_pending != 0) + { + quick6502_int(cpu, Q6502_IRQ_SIGNAL); + } + return 0; +} diff --git a/src/include/NESCarts.h b/src/include/NESCarts.h index de0e47f..a849d87 100755 --- a/src/include/NESCarts.h +++ b/src/include/NESCarts.h @@ -14,7 +14,7 @@ #ifndef NESCARTS_H #define NESCARTS_H -#include "types.h" +#include #define iNES_MIRROR 0x01 #define iNES_BATTERY 0x02 diff --git a/src/include/Sound.h b/src/include/Sound.h index 6c06248..9cf2013 100644 --- a/src/include/Sound.h +++ b/src/include/Sound.h @@ -129,7 +129,7 @@ int MIDILogging(int Switch); void MIDITicks(int N); //#ifdef UNIX -#define SND_CHANNELS 16 /* Number of channels */ +#define SND_CHANNELS 4 /* Number of channels */ #define SND_SAMPLESIZE 256 /* Max. SetWave() sample size */ #define SND_BUFSIZE 256 /* Buffer size, <= 2^SND_BITS */ #define SND_BITS 8 /* Number of bits in a fragment */ diff --git a/src/include/corecpu.h b/src/include/corecpu.h new file mode 100644 index 0000000..070e81a --- /dev/null +++ b/src/include/corecpu.h @@ -0,0 +1,164 @@ +/** + * CoreCPU - The Quick6502 Project + * corecpu.h + * + * Created by Manoel Trapier on 24/02/08 + * Copyright 2008 986 Corp. All rights reserved. + * + * $LastChangedDate$ + * $Author$ + * $HeadURL$ + * $Revision$ + * + */ + +#ifndef _QUICK6502_CORECPU_H_ +#define _QUICK6502_CORECPU_H_ + +/* 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) + * + */ + +#ifdef CMOS_6502 +//#warning Quick6502 CMOS support is actually desactivated, desactivate it +#undef CMOS_6502 +#endif + +#ifndef NO_DECIMAL +//#warning Quick6502 have actually no BCD support, fallback to no NO_DECIMAL +#define NO_DECIMAL +#endif + + +#include "types.h" + +typedef byte (*quick6502_MemoryReadFunction)(unsigned short addr); +typedef void (*quick6502_MemoryWriteFunction)(unsigned short addr, byte value); + +typedef struct quick6502_cpu_ +{ + /* 6502 registers */ + byte reg_A, reg_X, reg_Y; + byte reg_P, reg_S; + unsigned short reg_PC; + + /* Read/Write memory functions */ + quick6502_MemoryReadFunction memory_read; + quick6502_MemoryWriteFunction memory_write; + quick6502_MemoryReadFunction memory_page0_read; + quick6502_MemoryWriteFunction memory_page0_write; + quick6502_MemoryReadFunction memory_stack_read; + quick6502_MemoryWriteFunction memory_stack_write; + quick6502_MemoryReadFunction memory_opcode_read; + + /* Timing related */ + long cycle_done; + byte exit_loop; + byte int_pending; + + /* Other config options */ + byte running; /* This field is used to prevent cpu free if this cpu is running */ + byte page_crossed; +} quick6502_cpu; + +typedef struct quick6502_cpuconfig_ +{ + /* Read/Write memory functions */ + quick6502_MemoryReadFunction memory_read; + quick6502_MemoryWriteFunction memory_write; + quick6502_MemoryReadFunction memory_page0_read; + quick6502_MemoryWriteFunction memory_page0_write; + quick6502_MemoryReadFunction memory_stack_read; + quick6502_MemoryWriteFunction memory_stack_write; + quick6502_MemoryReadFunction memory_opcode_read; +} quick6502_cpuconfig; + +/*** Signal that we can send to the CPU ***/ +typedef enum +{ + Q6502_NO_SIGNAL = 0, + Q6502_IRQ_SIGNAL, + Q6502_NMI_SIGNAL, + Q6502_STOPLOOP_SIGNAL +} quick6502_signal; + +/*** Some 6502 related definitions ***/ + +/*** P register flags ***/ +#define Q6502_N_FLAG 0x80 /* Negavite flag */ +#define Q6502_V_FLAG 0x40 /* oVerflow flag */ +#define Q6502_R_FLAG 0x20 /* Not a real flag, but need to be to 1 on PHP */ +#define Q6502_B_FLAG 0x10 /* Break flag */ +#define Q6502_D_FLAG 0x08 /* BCD flag */ +#define Q6502_I_FLAG 0x04 /* IRQ/BRK flag */ +#define Q6502_Z_FLAG 0x02 /* Zero flag */ +#define Q6502_C_FLAG 0x01 /* Carry flag */ + +/*** Interuption Vectors ***/ +#define Q6502_NMI_LOW 0xFFFA +#define Q6502_NMI_HIGH 0xFFFB +#define Q6502_RESET_LOW 0xFFFC +#define Q6502_RESET_HIGH 0xFFFD +#define Q6502_IRQ_LOW 0xFFFE +#define Q6502_IRQ_HIGH 0xFFFF + +/** + * Initialise the CPU + * + * Inputs: + * + * - CPU Init structure: + * +- Memory Read function pointer + * +- Memory Write function pointer + * +- Fast memory read function pointer (for opcodes read) + * +- Fast page 0 function / Read/Write + * +- Fast page 1 function / Read/Write + * + * Output: + * + * (void *): An opaque pointer to the internal structure of the CPU + * + */ +quick6502_cpu *quick6502_init(quick6502_cpuconfig *config); + +/* Reset the CPU (must be done after init) */ +void quick6502_reset(quick6502_cpu *cpu); + +/** + * Run cpu for at least X cycles + * + * Output: + * + * int: (Number of cycle really done) - (Number of cycle asked) + */ +int quick6502_run(quick6502_cpu *cpu, int cycles); + +/** Loop CPU until explicit quit */ +void quick6502_loop(quick6502_cpu *cpu); + +/** Run CPU for one instruction */ +void quick6502_exec(quick6502_cpu *cpu); + +/** Send IRQ/NMI/EXITLOOP signal to CPU */ +void quick6502_int(quick6502_cpu *cpu, quick6502_signal signal); + +/** Dump CPU State to the given file */ +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); + +/** + * 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 + */ +int quick6502_free(quick6502_cpu *cpu); + +#endif /* _QUICK6502_CORECPU_H_ */ + diff --git a/src/include/mappers/manager.h b/src/include/mappers/manager.h index 44544fd..ec252fe 100755 --- a/src/include/mappers/manager.h +++ b/src/include/mappers/manager.h @@ -29,6 +29,7 @@ typedef void (*MapperDump) (); #include #include +#include extern NesCart *Cart; diff --git a/src/include/os_dependent.h b/src/include/os_dependent.h new file mode 100644 index 0000000..d1ba00b --- /dev/null +++ b/src/include/os_dependent.h @@ -0,0 +1,45 @@ +/* + * OS Dependent functions - The TI-NESulator Project + * os_dependent.h + * + * Created by Manoel TRAPIER on 08/05/08. + * Copyright (c) 2003-2008 986Corp. All rights reserved. + * + * $LastChangedDate$ + * $Author$ + * $HeadURL$ + * $Revision$ + * + */ + +#ifndef OS_DEPENDENT_H +#define OS_DEPENDENT_H + +/* File related functions */ +/* Graphics related functions */ +int graphics_init(); +int graphics_drawpixel(long x, long y, long color); +int graphics_blit(long x, long y, long w, long h); + +/* Sound related functions */ + +/* IO functions */ +void *LoadFilePtr(char * filename); + +/* Console functions */ +typedef enum ConsoleLevel_t +{ + Console_Error = 0, + Console_Warning, + Console_Alert, + Console_Default, + Console_Verbose, + Console_Debug, +} ConsoleLevel; + + +int console_init(ConsoleLevel DefaultLevel); +int console_printf(const ConsoleLevel level, const char *format, ...); +int console_printf_d(const char *format, ...); + +#endif /* OS_DEPENDENT_H */ \ No newline at end of file diff --git a/src/include/palette.h b/src/include/palette.h index 74068e2..53e4661 100644 --- a/src/include/palette.h +++ b/src/include/palette.h @@ -262,5 +262,5 @@ PALETTE basicPalette = { { 0x29, 0x3C, 0x3C, 0x08 }, { 0x32, 0x31, 0x32, 0xB7 }, { 0x01, 0x01, 0x01, 0x08 }, - { 0x01, 0x01, 0x01, 0xBF } + { 0x01, 0x01, 0x01, 0xBF }, }; diff --git a/src/include/ppu/ppu.memory.h b/src/include/ppu/ppu.memory.h index fca2a46..212083a 100644 --- a/src/include/ppu/ppu.memory.h +++ b/src/include/ppu/ppu.memory.h @@ -27,6 +27,8 @@ void ppu_memoryDumpState(FILE *fp); byte ppu_readMemory(byte page, byte addr); void ppu_writeMemory(byte page, byte addr, byte value); +void ppu_setPageGhost(byte page, bool value, byte ghost); + #else #error Must only be included inside the PPU code #endif diff --git a/src/main.c b/src/main.c index 1719fe4..9f7e0bd 100755 --- a/src/main.c +++ b/src/main.c @@ -12,6 +12,10 @@ * */ +/* System includes */ + +#if !defined(__TIGCC__) && !defined(__GCC4TI__) && !defined(__GTC__) + #include #include #include @@ -22,37 +26,27 @@ #include #include -#ifndef WIN32 - -//#include -#include - +/* Allegro includes */ +#ifdef __APPLE__ +#define USE_CONSOLE +#include #else - #define USE_CONSOLE #include - #endif -#if ISPAL && !ISNTSC -//#define VBLANK_TIME 70 -//#define HBLANK_TIME 261 -int VBLANK_TIME = 70; -int HBLANK_TIME = 140; -double APU_BASEFREQ = 1.7734474; -#elif !ISPAL && ISNTSC -int VBLANK_TIME = 20; -int HBLANK_TIME = 115; //119; -double APU_BASEFREQ = 1.7897725; -//#define VBLANK_TIME 20 -//#define HBLANK_TIME 260 + #else -#error Cannot use ISPAL with ISNTSC together ! + +#define TIGCC_COMPAT +#include + #endif -/* Should find something better for sharing the copu interface... */ +/* TI-NES modules includes */ +#include -#include +#include #include #include #include @@ -69,26 +63,57 @@ double APU_BASEFREQ = 1.7897725; #include -#define V_MAJOR 0 -#define V_MINOR 30 +/* PAL support is broken, so force NTSC mode */ +#if ISPAL || ISNTSC +#undef ISPAL +#undef ISNTSC +#endif +#define ISNTSC 1 +#if ISPAL && !ISNTSC + +int VBLANK_TIME = 70; +int HBLANK_TIME = 140; +double APU_BASEFREQ = 1.7734474; + +#elif !ISPAL && ISNTSC + +int VBLANK_TIME = 20; +int HBLANK_TIME = 113; +double APU_BASEFREQ = 1.7897725; +#elif !ISPAL && !ISNTSC +# error You MUST define one of ISPAL Xor ISNTSC +#else +# error Cannot use ISPAL with ISNTSC together ! +#endif + +/* TI-NESulator Version */ +#define V_MAJOR 0 +#define V_MINOR 40 + +/* SVN specific values */ #define VS_ID "$Id$" #define VS_REVISION "$Revision$" #define VS_LASTCHANGEDDATE "$LastChangedDate$" #define VS_HEADURL "$HeadURL$" #define VS_AUTHOR "$Author$" +/* #define MAXLASTOP 42 word latestop[MAXLASTOP]; +*/ -M6502 MainCPU; - -BITMAP *Buffer; +/* NES specific variables */ +quick6502_cpu *MainCPU; +NesCart *Cart; byte *FDSRom; byte *FDSRam; +/* Allegro main screen */ +BITMAP *Buffer; + /* Command line options */ byte START_DEBUG = 0; @@ -96,14 +121,12 @@ byte START_WITH_FDS = 0; char *CART_FILENAME = NULL; char *PALETTE_FILENAME = NULL; -#define fatal(s) { printf("%s",s); exit(-1); } - Paddle P1, P2; unsigned short ScanLine; volatile int frame = 0; -volatile extern int icount; +volatile int ccount; char MapperWantIRQ = 0; @@ -123,6 +146,18 @@ unsigned long ColorPalette[ 8 * 63 ]; #define SET_RGB(r,g,b) ((((r<<8)|g)<<8)|b)|0xFF000000 +/* Memory functions */ +byte MemoryRead (unsigned short Addr); +byte MemoryOpCodeRead (unsigned short Addr); +byte MemoryStackRead (unsigned short Addr); +byte MemoryPageZeroRead (unsigned short Addr); + +void MemoryWrite (unsigned short Addr, byte Value); +void MemoryStackWrite (unsigned short Addr, byte Value); +void MemoryPageZeroWrite (unsigned short Addr, byte Value); + +void Loop6502(quick6502_cpu *R); + void CloseHook(void) { WantClosing = 1; @@ -131,11 +166,10 @@ void CloseHook(void) void ips_fps_counter(void) { FPS = frame; - IPS = icount; + IPS = ccount; frame = 0; - icount = 0; + ccount = 0; } - END_OF_FUNCTION(ips_fps_counter); void SaveSaveRam(char *name) @@ -143,12 +177,11 @@ void SaveSaveRam(char *name) FILE *fp; int i; char fname[512]; - //byte car; strcpy(fname, name); strcat(fname, ".svt"); if ((fp = fopen(fname, "wb"))) { - printf("Saving savestate '%s'\n", fname); + console_printf(Console_Default, "Saving savestate '%s'\n", fname); for( i = 0x60; i < 0x80; i++) { fwrite(get_page_ptr(i), 1, 0x100, fp); @@ -168,7 +201,7 @@ void LoadSaveRam(char *name) strcat(fname, ".svt"); if ((fp = fopen(fname, "rb"))) { - printf("Loading savestate '%s'\n", fname); + console_printf(Console_Default, "Loading savestate '%s'\n", fname); for( i = 0x60; i < 0x80; i++) { fread(get_page_ptr(i), 1, 0x0100, fp); @@ -184,7 +217,7 @@ void LoadPalette(char *filename, PALETTE pal) FILE *fp; unsigned char r, v, b, i; - printf("%s: try to load pallette file '%s'", __func__, filename); + console_printf(Console_Default, "%s: try to load pallette file '%s'", __func__, filename); if ((fp = fopen(filename, "rb")) != NULL) { @@ -242,48 +275,20 @@ void LoadPalette(char *filename, PALETTE pal) #endif } fclose(fp); - printf(" [ OK ]\n"); + console_printf(Console_Default, " [ OK ]\n"); } else { - printf("Error loading palette '%s'!\n", filename); + console_printf(Console_Error, "Error loading palette '%s'!\n", filename); exit(-1); } } -int DAsm(char *S, word A); - -int oppos = 0; - -void pushop(word op) -{ - latestop[oppos] = op; - // printf("%d\n", oppos); - oppos = (oppos+1)%42; -} - -void showlastop(FILE *fp) -{ -#ifdef DEBUG - int i,j; - char S[256]; - i = oppos; - do - { - j=(DAsm(S,latestop[i])-1); - fprintf(fp, "0x%04X : %s\n", MainCPU.PC.W,S); - i = (i+1)%42; - } - while(i != oppos); -#endif -} - -NesCart *Cart; - void *signalhandler(int sig) { +#if 0 static int state=0; - M6502 *R = &MainCPU; + byte F; int J, I; static char FA[8] = "NVRBDIZC"; @@ -293,7 +298,7 @@ void *signalhandler(int sig) sprintf(name, "crashdump-%d.txt", (int)time(NULL)); if (state != 0) { - fprintf(stderr, "\n\n\nCrashed within signal!\nEmergency exit\n"); + console_printf(Console_Error, "\n\n\nCrashed within signal!\nEmergency exit\n"); exit(42); } state = 1; @@ -303,7 +308,7 @@ void *signalhandler(int sig) state = 2; - if (fp) fprintf(stderr, + if (fp) console_printf(Console_Error, "\n\n\n\n\n" "#sick# TI-NESulator %d.%d #sick#\n" "see %s for more information", @@ -375,9 +380,9 @@ void *signalhandler(int sig) DumpMemoryState(fp); - fprintf(stderr, "\nPlease join this informations when submiting crash report\n"); + console_printf(Console_Error, "\nPlease join this informations when submiting crash report\n"); if (fp != stderr) fclose(fp); - //getchar(); +#endif exit(-42); } @@ -413,7 +418,7 @@ void WrHook4000Multiplexer(byte addr, byte value) Sq1_reg0 = value; if (Sq1_reg0 & 0x10) { - SQ1V = 0x0F/*(0x04+(value&0x0F))& 0x0F*/; + SQ1V = (0x04+(value&0x0F))& 0x0F; } else { @@ -421,37 +426,39 @@ void WrHook4000Multiplexer(byte addr, byte value) } break; + case 0x01: /* EPPP NSSS */ Sq1_reg1 = value; break; + case 0x02: - /*printf("Sq1 reg0: 0x%02X - duty:0x%X loop:0x%X env:0x%X vol:0x%X\n", + /*console_printf(Console_Default, "Sq1 reg0: 0x%02X - duty:0x%X loop:0x%X env:0x%X vol:0x%X\n", Sq1_reg0, (Sq1_reg0&0xC0)>>6, (Sq1_reg0&0x20)>>5, (Sq1_reg0&0x10)>>4, Sq1_reg0&0x0F); - printf("Sq1 reg1: 0x%02X - sweep:0x%X period:0x%X neg:0x%X shift:0x%X\n", + console_printf(Console_Default, "Sq1 reg1: 0x%02X - sweep:0x%X period:0x%X neg:0x%X shift:0x%X\n", Sq1_reg1, (Sq1_reg1&0x80)>>8, (Sq1_reg1&0x70)>>4, (Sq1_reg1&0x08)>>3, Sq1_reg1&0x07); - printf("Sq1 reg2: 0x%02X\n", value); - printf("Sq1 reg3: 0x%02X\n", Sq1_reg3);*/ + console_printf(Console_Default, "Sq1 reg2: 0x%02X\n", value); + console_printf(Console_Default, "Sq1 reg3: 0x%02X\n", Sq1_reg3);*/ SQ1P = value | ((Sq1_reg3&0x7) << 8); SQ = APU_BASEFREQ * 1000 * 1000 / (SQ1P+1 /*+ (Sq1_reg1&0x80)?0:( (Sq1_reg1&0x08)?(SQ1P>>(Sq1_reg1&0x07)):(SQ1P<<(Sq1_reg1&0x07)) )*/); - SetSound(0,SND_MELODIC); + //SetSound(0,SND_MELODIC); - //printf("SQ1V = %d - SQ = %f - SQ1P = %d\n", SQ1V, SQ, SQ1P); + //console_printf(Console_Default, "SQ1V = %d - SQ = %f - SQ1P = %d\n", SQ1V, SQ, SQ1P); #ifdef SOUND_LOG { FILE *fp = fopen("sound.log", "at"); fprintf(fp, "%d %d %d\n", 0, SQ1P, SQ1V); fclose(fp); } #endif Sound(0, (int) SQ/22, (0xFF/0x0F) * SQ1V); - // printf("40%02X: 0x%02X (SQ1P:%d SQ:%f (%d))\n", addr, value, SQ1P, SQ, (int) SQ); + //console_printf(Console_Default, "40%02X: 0x%02X (SQ1P:%d SQ:%f (%d))\n", addr, value, SQ1P, SQ, (int) SQ); Sq1_reg2 = value; break; @@ -472,8 +479,7 @@ void WrHook4000Multiplexer(byte addr, byte value) Sq2_reg0 = value; if (Sq2_reg0 & 0x10) { - SQ2V = 0x0F; - //SQ2V = (0x04+(value&0x0F))& 0x0F; + SQ2V = (0x04+(value&0x0F))& 0x0F; } else { @@ -493,21 +499,21 @@ void WrHook4000Multiplexer(byte addr, byte value) SQ = APU_BASEFREQ * 1000 * 1000 / (SQ2P+1 /*+ (Sq2_reg1&0x80)?0:( (Sq2_reg1&0x08)?(SQ2P>>(Sq2_reg1&0x07)):(SQ2P<<(Sq2_reg1&0x07)) )*/); - /* printf("Sq2 reg0: 0x%02X - duty:0x%X loop:0x%X env:0x%X vol:0x%X\n", + /* console_printf(Console_Default, "Sq2 reg0: 0x%02X - duty:0x%X loop:0x%X env:0x%X vol:0x%X\n", Sq2_reg0, (Sq2_reg0&0xC0)>>6, (Sq2_reg0&0x20)>>5, (Sq2_reg0&0x10)>>4, Sq2_reg0&0x0F); - printf("Sq2 reg1: 0x%02X - sweep:0x%X period:0x%X neg:0x%X shift:0x%X\n", + console_printf(Console_Default, "Sq2 reg1: 0x%02X - sweep:0x%X period:0x%X neg:0x%X shift:0x%X\n", Sq2_reg1, (Sq2_reg1&0x80)>>8, (Sq2_reg1&0x70)>>4, (Sq2_reg1&0x08)>>3, Sq2_reg1&0x07); - printf("Sq2 reg2: 0x%02X\n", value); - printf("Sq2 reg3: 0x%02X\n", Sq2_reg3); - printf("SQ2V = %d - SQ = %f - SQ2P = %d\n", SQ2V, SQ, SQ2P);*/ + console_printf(Console_Default, "Sq2 reg2: 0x%02X\n", value); + console_printf(Console_Default, "Sq2 reg3: 0x%02X\n", Sq2_reg3); + console_printf(Console_Default, "SQ2V = %d - SQ = %f - SQ2P = %d\n", SQ2V, SQ, SQ2P);*/ #ifdef SOUND_LOG { FILE *fp = fopen("sound.log", "at"); fprintf(fp, "%d %d %d\n", 1, SQ2P, SQ2V); fclose(fp); } #endif @@ -518,7 +524,7 @@ void WrHook4000Multiplexer(byte addr, byte value) Sq2_reg3 = value; SQ2P = Sq2_reg2 | ((Sq2_reg3&0x7) << 8); - //SQ2P = (SQ2P & 0x00FF) | ((value&0x7) << 8); + SQ = APU_BASEFREQ * 1000 * 1000 / (SQ2P+1 /*+ (Sq2_reg1&0x80)?0:( (Sq2_reg1&0x08)?(SQ2P>>(Sq2_reg1&0x07)):(SQ2P<<(Sq2_reg1&0x07)) )*/); #ifdef SOUND_LOG @@ -550,7 +556,7 @@ void WrHook4000Multiplexer(byte addr, byte value) #ifdef SOUND_LOG { FILE *fp = fopen("sound.log", "at"); fprintf(fp, "%d %d %d\n", 3, NOIP, NOIV); fclose(fp); } #endif - SetSound(3, SND_NOISE); + //SetSound(3, SND_NOISE); Sound(3, (int) SQ/22, (0xFF/0x0F) * NOIV); break; @@ -560,7 +566,7 @@ void WrHook4000Multiplexer(byte addr, byte value) #ifdef SOUND_LOG { FILE *fp = fopen("sound.log", "at"); fprintf(fp, "%d %d %d\n", 3, NOIP, NOIV); fclose(fp); } #endif - SetSound(3, SND_NOISE); + //SetSound(3, SND_NOISE); Sound(3, (int) SQ/22, NOIV); break; case 0x0F: @@ -569,7 +575,7 @@ void WrHook4000Multiplexer(byte addr, byte value) case 0x15: /* DMC, Noise, Triangle, Sq 2, Sq 1 */ //SetChannels(0, (value&0x01)?0x01:0); - /* printf("40%02X: 0x%02X [%c%c%c%c%c]\n", addr, value, + /* console_printf(Console_Default, "40%02X: 0x%02X [%c%c%c%c%c]\n", addr, value, (value&0x10)?'d':'.', (value&0x08)?'n':'.', (value&0x04)?'t':'.', @@ -588,15 +594,16 @@ void WrHook4000Multiplexer(byte addr, byte value) break; case 0x17: - // printf("40%02X: 0x%02X\n", addr, value); - if (value == 0x00) - Int6502(&MainCPU,INT_IRQ); + if (value == 0x00) + { + quick6502_int(MainCPU, Q6502_IRQ_SIGNAL); + } - break; + break; // default: //Page40[addr] = value; - // printf("40%02X: 0x%02X\n", addr, value); - // printf("pAPU: 0x%X @ 0x40%X\n", value, addr); + // console_printf(Console_Default, "40%02X: 0x%02X\n", addr, value); + // console_printf(Console_Default, "pAPU: 0x%X @ 0x40%X\n", value, addr); } } @@ -616,6 +623,8 @@ byte RdHook4000Multiplexer(byte addr) case 0x15: ret = 0x1F; + break; + default: ret = 0x42; } @@ -624,7 +633,7 @@ byte RdHook4000Multiplexer(byte addr) void printUsage(int argc, char *argv[]) { - printf("Usage : %s game.nes [-p number][-f][-b filename.pal][ filename.nes\n" + console_printf(Console_Default, "Usage : %s game.nes [-p number][-f][-b filename.pal][ filename.nes\n" " -p: to add plugin 'number'\n" " -f: to start in FDS mode\n" " -d: to start directily into the debugguer\n" @@ -638,6 +647,7 @@ int main(int argc, char *argv[]) int i; unsigned char j, k; unsigned char *MemoryPage; + quick6502_cpuconfig CpuConfig; /* Here we will fill the memory */ /* @@ -655,9 +665,9 @@ int main(int argc, char *argv[]) 2kB Internal RAM, mirrored 4 times --------------------------------------- $0000 */ - + console_init(Console_Default); /* Print the banner */ - printf("--------------------------------------------------------------------------------\n" + console_printf(Console_Default, "--------------------------------------------------------------------------------\n" "Welcome to TI-NESulator v%d.%d - by Godzil\n" "Copyright 2003-2008 TRAPIER Manoel (godzil@godzil.net)\n" "%s\n%s\n%s\n" @@ -668,23 +678,23 @@ int main(int argc, char *argv[]) VS_LASTCHANGEDDATE, VS_AUTHOR); - printf("Install signal handlers...\t["); + console_printf(Console_Default, "Install signal handlers...\t["); // signal(SIGABRT,signalhandler); - printf("A"); + console_printf(Console_Default, "A"); // signal(SIGILL,signalhandler); - printf("I"); + console_printf(Console_Default, "I"); /*signal(SIGINT,signalhandler);*/ - printf("."); + console_printf(Console_Default, "."); // signal(SIGSEGV,signalhandler); - printf("S"); + console_printf(Console_Default, "S"); // signal(SIGTERM,signalhandler); - printf("T]\n"); + console_printf(Console_Default, "T]\n"); /* */ - printf("Initialize memory...\t\t"); + console_printf(Console_Default, "Initialize memory...\t\t"); InitMemory(); - printf("[ OK ]\n"); - printf("Parsing parameters (%d)...\n", argc); + console_printf(Console_Default, "[ OK ]\n"); + console_printf(Console_Default, "Parsing parameters (%d)...\n", argc); /* Now we use a real argument parser ! */ for(i = 1 ; (i < argc) && (argv[i][0]=='-'); i++) { @@ -698,7 +708,7 @@ int main(int argc, char *argv[]) case 'p': if (atoi(argv[i+1]) != 0) { - printf("-Load plugin #%d...\n", atoi(argv[i+1])); + console_printf(Console_Default, "-Load plugin #%d...\n", atoi(argv[i+1])); if ( plugin_load(atoi(argv[i+1])) == -1) { plugin_list(); @@ -714,17 +724,17 @@ int main(int argc, char *argv[]) break; case 'f': - printf("-Start with fds!\n"); + console_printf(Console_Default, "-Start with fds!\n"); START_WITH_FDS = 1; break; case 'd': - printf("-Start with debug!\n"); + console_printf(Console_Default, "-Start with debug!\n"); START_DEBUG = 1; break; case 'b': - printf("-Palette file is %s\n", argv[i+1]); + console_printf(Console_Default, "-Palette file is %s\n", argv[i+1]); PALETTE_FILENAME = argv[i+1]; i++; break; @@ -737,7 +747,7 @@ int main(int argc, char *argv[]) if (CART_FILENAME == NULL) printUsage(argc, argv); - printf("Allocating 6502 memory\t\t"); + console_printf(Console_Default, "Allocating 6502 memory\t\t"); /* Allocating first 0x7FF memory */ MemoryPage = (unsigned char *)malloc (0x800); @@ -790,11 +800,6 @@ int main(int argc, char *argv[]) /* Exp ROM : Nothing to do actually */ - /* SRAM (0x6000 : 0x2000 bytes ) */ - MemoryPage = (unsigned char *)malloc (0x2000); - - set_page_ptr_8k(0x60, MemoryPage); - /* ROM ptr will be set by mapper */ /* But we will set the readable bit */ for (i = 0x80; i < 0x100; i++) @@ -803,80 +808,103 @@ int main(int argc, char *argv[]) set_page_writeable(i, false); } - printf("[ OK ]\n"); + console_printf(Console_Default, "[ OK ]\n"); #define Value(s) (((s%0xFF) + (rand()%0xFF-128) )%0xFF) - printf("Testing memory validity...\n"); + console_printf(Console_Default, "Testing memory validity...\n"); map_sram(); - for(i = 0x0000; i < 0x2000; i ++) - { - j = Value(i); + console_printf(Console_Verbose, "Testing Page Zero\n"); + for( i = 0 ; i < 0x100 ; i++) + { + j = rand() % 0xFF; MemoryPage[i] = j; + if ((k = MemoryPageZeroRead(i)) != j) + console_printf(Console_Error, "Error MemoryPageZeroRead @ 0x%04X [j:%02X, should:%02X, is:%02X]\n", i, j, MemoryPage[i], k); + + j = rand() % 0xFF; + MemoryPageZeroWrite(i, j); + if ((k = MemoryPage[i]) != j) + console_printf(Console_Error, "Error MemoryPageZeroWrite @ 0x%04X [j:%02X, should:%02X, is:%02X]\n", i, j, MemoryPage[i], k); + MemoryPage[i] = 0; } + console_printf(Console_Verbose, "Testing memory... (<0x2000)\n"); + for( i = 0 ; i < 0x2000 ; i++ ) + { + j = Value(i); + MemoryWrite(i, j); + if ((k=MemoryRead(i)) != j) + console_printf(Console_Error, "Error read/write @ 0x%X [w:%d,r:%d]\n", i, j, k); + if ((k=MemoryOpCodeRead(i)) != j) + console_printf(Console_Error, "Error opcode @ 0x%X [w:%d,r:%d]\n", i, j, k); + } + + /* SRAM (0x6000 : 0x2000 bytes ) */ + MemoryPage = (unsigned char *)malloc (0x2000); + + set_page_ptr_8k(0x60, MemoryPage); + for(i = 0x6000; i < 0x8000; i ++) { - if (MemoryPage[i-0x6000] != (k = Rd6502(i))) - printf("Error RdRead @ 0x%X [should:%d,is:%d]\n", i, MemoryPage[i-0x6000], k); - if (MemoryPage[i-0x6000] != (k = Op6502(i))) - printf("Error OpRead @ 0x%X [should:%d,is:%d]\n", i, MemoryPage[i-0x6000], k); + if (MemoryPage[i-0x6000] != (k = MemoryRead(i))) + console_printf(Console_Error, "Error MemoryRead @ 0x%X [should:%d,is:%d]\n", i, MemoryPage[i-0x6000], k); + if (MemoryPage[i-0x6000] != (k = MemoryOpCodeRead(i))) + console_printf(Console_Error, "Error MemoryOpCodeRead @ 0x%X [should:%d,is:%d]\n", i, MemoryPage[i-0x6000], k); } - printf("Testing memory... (<0x2000)\n"); - for( i = 0 ; i < 0x2000 ; i++ ) { + console_printf(Console_Verbose, "Testing memory... (0x6000-0x8000)\n"); + for(i=0x6000;i<0x8000;i++) + { j = Value(i); - Wr6502(i, j); - if ((k=Rd6502(i)) != j) - printf("Error read/write @ 0x%X [w:%d,r:%d]\n", i, j, k); - if ((k=Op6502(i)) != j) - printf("Error opcode @ 0x%X [w:%d,r:%d]\n", i, j, k); + MemoryWrite(i, j); + if ((k=MemoryRead(i)) != j) + console_printf(Console_Error, "Error read/write @ 0x%X [w:%d,r:%d]\n", i, j, k); + if ((k=MemoryOpCodeRead(i)) != j) + console_printf(Console_Error, "Error opcode @ 0x%X [w:%d,r:%d]\n", i, j, k); } - printf("Testing memory... (0x6000-0x8000)\n"); - for(i=0x6000;i<0x8000;i++) { - j = Value(i); - Wr6502(i, j); - if ((k=Rd6502(i)) != j) - printf("Error read/write @ 0x%X [w:%d,r:%d]\n", i, j, k); - if ((k=Op6502(i)) != j) - printf("Error opcode @ 0x%X [w:%d,r:%d]\n", i, j, k); - } - - printf("Reseting main RAM...\t\t"); + console_printf(Console_Default, "Reseting main RAM...\t\t"); + /* Force the stack to be full of zero */ - for( i = 0x100 ; i < 0x200 ; i++ ) { - Wr6502(i, 0x00); + for( i = 0x100 ; i < 0x200 ; i++ ) + { + MemoryWrite(i, 0x00); } - - for( i = 0x000 ; i < 0x800 ; i++ ) { - Wr6502(i, 0x00); + console_printf(Console_Default, "[ OK ]\n"); + + Cart = malloc( sizeof (NesCart)); + if (Cart == NULL) + { + console_printf(Console_Error, "Memory allocation error...\n"); + exit(-1); } - printf("[ OK ]\n"); - if (START_WITH_FDS) { int fd; - printf("Loading FDS ROM...\t\t"); - - fd = open("../data/disksys.rom", O_RDONLY); + 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); FDSRom = mmap(NULL, 8*1024, PROT_READ, MAP_PRIVATE, fd, 0); - printf("%p [ OK ]\n", FDSRom); + console_printf(Console_Default, "%p [ OK ]\n", FDSRom); close(fd); set_page_ptr_8k(0xE0, FDSRom); - printf("Allocating FDS RAM...\t\t"); + console_printf(Console_Default, "Allocating FDS RAM...\n"); FDSRam = (byte*) malloc( (8+16) * 1024); if (FDSRam == NULL) - fatal("Allocation error\n"); + { + console_printf(Console_Error, "Allocation error\n"); + exit(-1); + } for (i = 0x80; i < 0xE0; i++) { @@ -888,13 +916,13 @@ int main(int argc, char *argv[]) Cart->MapperID = 100; } else - { - Cart = malloc( sizeof (NesCart)); - if (Cart == NULL) - fatal("Memory allocation error...\n"); - printf("Please Wait while loading %s cartridge...\n", CART_FILENAME); + { + console_printf(Console_Default, "Please Wait while loading %s cartridge...\n", CART_FILENAME); if (LoadCart(CART_FILENAME, Cart) != 0) - fatal("Loading error...\n"); + { + console_printf(Console_Error, "Loading error...\n"); + exit(-1); + } if (Cart->Flags & iNES_BATTERY) { @@ -907,28 +935,32 @@ int main(int argc, char *argv[]) InitPaddle(&P1); - printf("Initializing Allegro...\t\t"); + console_printf(Console_Default, "Initializing Allegro...\t\t"); allegro_init(); install_timer(); install_keyboard(); - printf("[ OK ]\n"); - printf("Set graphic mode...\t\t"); + console_printf(Console_Default, "[ OK ]\n"); + console_printf(Console_Default, "Set graphic mode...\t\t"); set_color_depth(8); set_gfx_mode(GFX_AUTODETECT_WINDOWED, 512 + 256, 480, 512 + 256, 480); Buffer = create_bitmap(512 + 256, 480); clear_to_color(Buffer, 0x0D); - set_close_button_callback(CloseHook); - set_window_title("TI-NESulator"); + //set_close_button_callback(CloseHook); + //set_window_title("TI-NESulator"); - printf("[ OK ]\n"); + console_printf(Console_Default, "[ OK ]\n"); - printf("Init PPU...\n"); + console_printf(Console_Default, "Init PPU...\n"); if (ppu_init() != 0) - fatal("PPU Initialisation error..\n"); + { + console_printf(Console_Error, "PPU Initialisation error..\n"); + exit(-1); + } + + DumpMemoryState(); - /* DumpMemoryState(); */ if (Cart->Flags & iNES_4SCREEN) { ppu_setScreenMode(PPU_SCMODE_FOURSC); @@ -939,10 +971,10 @@ int main(int argc, char *argv[]) ppu_setMirroring((Cart->Flags & iNES_MIRROR)?PPU_MIRROR_VERTICAL:PPU_MIRROR_HORIZTAL); } - printf("Init mapper...\t\t\t"); + console_printf(Console_Default, "Init mapper...\t\t\t"); if (mapper_init(Cart) == -1) return -1; - printf("[ OK ]\n"); + console_printf(Console_Default, "[ OK ]\n"); if (PALETTE_FILENAME == NULL) { @@ -954,91 +986,46 @@ int main(int argc, char *argv[]) set_palette(pal); } - /* for(i = 0; i < 256; i++) - { - r = (r * 64) / 255; - v = (v * 64) / 255; - b = (b * 64) / 255; - - pal[i].r = r; - pal[i].g = v; - pal[i].b = b; - - pal[i + 64].r = r; - pal[i + 64].g = v; - pal[i + 64].b = b; - - pal[i + 128].r = r; - pal[i + 128].g = v; - pal[i + 128].b = b; - - pal[i + 192].r = r; - pal[i + 192].g = v; - pal[i + 192].b = b; - - printf(" { 0x%02X, 0x%02X, 0x%02X, 0x%02X },\n", - (basicPalette[i].r * 64) / 255, - (basicPalette[i].g * 64) / 255, - (basicPalette[i].b * 64) / 255, - basicPalette[i].filler); - printf(" { 0x%02X, 0x%02X, 0x%02X, 0x%02X },\n", - pal[i].r, - pal[i].g, - pal[i].b, - pal[i].filler); - } - - exit(0);*/ - #ifdef USE_SOUND - InitSound(48000,!0); + InitSound(44400,!0); SetSound(0, SND_RECTANGLE); SetSound(1, SND_RECTANGLE); SetSound(2, SND_TRIANGLE); SetSound(3, SND_NOISE); #endif - - - /* short val = 0xCE; - - while(1) - { - - Wr6502(0x4000, 0x74); - Wr6502(0x4001, 0x68); - Wr6502(0x4002, val & 0xFF); - Wr6502(0x4003, 0x08 | ((val & 0x700) >> 8)); - - - if (key[KEY_UP]) - val++; - if (key[KEY_DOWN]) - val--; - - usleep(500); - } - - - exit(0);*/ - - printf("Press ESC to pause emulation and jump to debugguer\n"); + // Actually no real debugguer... + //console_printf(Console_Default, "Press ESC to pause emulation and jump to debugguer\n"); install_int(ips_fps_counter, 1000); ScanLine = 0; - //Do a loop every HBlank - MainCPU.IPeriod = HBLANK_TIME; + /* Initialize the CPU */ + CpuConfig.memory_read = MemoryRead; + CpuConfig.memory_write = MemoryWrite; + CpuConfig.memory_page0_read = MemoryPageZeroRead; + CpuConfig.memory_page0_write = MemoryPageZeroWrite; + CpuConfig.memory_stack_read = MemoryStackRead; + CpuConfig.memory_stack_write = MemoryStackWrite; + CpuConfig.memory_opcode_read = MemoryOpCodeRead; - Reset6502(&MainCPU); + MainCPU = quick6502_init(&CpuConfig); + quick6502_reset(MainCPU); + +/* No debugger actually MainCPU.Trace = 0; - if (START_DEBUG) MainCPU.Trace = 1; + */ gettimeofday(&timeStart, NULL); - Run6502(&MainCPU); + while(!WantClosing) + { + ccount += quick6502_run(MainCPU, HBLANK_TIME); + + Loop6502(MainCPU); + } if (Cart->Flags & iNES_BATTERY) { @@ -1046,75 +1033,87 @@ int main(int argc, char *argv[]) } return 0; } -END_OF_MAIN() +//END_OF_MAIN() -/** Rd6502()/Wr6502/Op6502() *********************************/ -/** These functions are called when access to RAM occurs. **/ -/** They allow to control memory access. Op6502 is the same **/ -/** as Rd6502, but used to read *opcodes* only, when many **/ -/** checks can be skipped to make it fast. It is only **/ -/** required if there is a #define FAST_RDOP. **/ -/************************************ TO BE WRITTEN BY USER **/ -void Wr6502(register word Addr, register byte Value) -{ /* Write to memory */ +/* Access directly to Memory pages *HACKISH* */ +extern byte *memory_pages[0xFF]; +/* Memory functions */ + +/* Read memory, general function */ +byte MemoryRead (unsigned short Addr) +{ + return ReadMemory((Addr&0xFF00)>>8,Addr&0x00FF); +} + +/* Read memory for opcode (need fast access) */ +byte MemoryOpCodeRead (unsigned short Addr) +{ + byte *ptr; + return ((ptr = memory_pages[(Addr&0xFF00)>>8])>(byte*)1)?ptr[Addr&0x00FF]:0xEA; +} + +byte MemoryStackRead (unsigned short Addr) +{ + byte *ptr = memory_pages[1]; + return ptr[Addr&0x00FF]; +} + +byte MemoryPageZeroRead (unsigned short Addr) +{ + byte *ptr = memory_pages[0]; + return ptr[Addr&0x00FF]; +} + +/* Write to memory, general function */ +void MemoryWrite (unsigned short Addr, byte Value) +{ WriteMemory((Addr&0xFF00)>>8,Addr&0x00FF, Value); } -byte Rd6502(register word Addr) -{ /* Read memory for normal use */ - return ReadMemory((Addr&0xFF00)>>8,Addr&0x00FF); - +void MemoryStackWrite (unsigned short Addr, byte Value) +{ + byte *ptr = memory_pages[1]; + ptr[Addr&0x00FF] = Value; } -extern byte *memory_pages[0xFF]; -byte Op6502(register word Addr) -{ /* Read OpCodes */ - byte *ptr; - return ((ptr = memory_pages[(Addr&0xFF00)>>8])>(byte*)1)?ptr[Addr&0x00FF]:0; - - //return ReadMemory((Addr&0xFF00)>>8,Addr&0x00FF); +void MemoryPageZeroWrite (unsigned short Addr, byte Value) +{ + byte *ptr = memory_pages[0]; + ptr[Addr&0x00FF] = Value; } -/** Loop6502() ***********************************************/ -/** 6502 emulation calls this function periodically to **/ -/** check if the system hardware requires any interrupts. **/ -/** This function must return one of following values: **/ -/** INT_NONE, INT_IRQ, INT_NMI, or INT_QUIT to exit the **/ -/** emulation loop. **/ -/************************************ TO BE WRITTEN BY USER **/ -byte Loop6502(register M6502 * R) +void Loop6502(quick6502_cpu *R) { byte ret; short skey; long WaitTime; static long delta=0; - ret = INT_NONE; + ret = 0; if ( mapper_irqloop (ScanLine) ) { - ret = INT_IRQ; + ret = Q6502_IRQ_SIGNAL; IRQScanHit = ScanLine; } if ( MapperWantIRQ == 1) { MapperWantIRQ = 0; - ret = INT_IRQ; + ret = Q6502_IRQ_SIGNAL; } if ( ppu_hblank(ScanLine) != 0 ) { - /* if (ret == INT_IRQ) - MapperWantIRQ = 1;*/ - ret = INT_NMI; + ret = Q6502_NMI_SIGNAL; } - if (ScanLine == 241) + if (ScanLine == 239) frame++; - if (ScanLine >= (240 + VBLANK_TIME - 1)) - { /* End of VBlank Time */ + if (ScanLine == (239 + VBLANK_TIME)) + { /* End of VBlank Time */ + /* Sync at 60FPS */ /* Get current time in microseconds */ gettimeofday(&timeEnd, NULL); @@ -1129,11 +1128,10 @@ byte Loop6502(register M6502 * R) WaitTime = 20000 - WaitTime + delta; #endif - /* If we press Page Up, we dont we to accelerate "time" */ + /* If we press Page Up, we want to accelerate "time" */ if (!key[KEY_PGUP]) if ((WaitTime >= 0) && (WaitTime < 100000)) usleep(WaitTime); - //usleep(WaitTime<0?0:(WaitTime>100000?0:WaitTime)); /* Now get the time after sleep */ gettimeofday(&timeStart, NULL); @@ -1148,90 +1146,59 @@ byte Loop6502(register M6502 * R) /* To avoid strange time warp when stoping emulation or using acceleration a lot */ if ((delta > 10000) || (delta < -10000)) delta = 0; - - ScanLine = 0; } + + /* There is Two dummy scanline */ + if (ScanLine >= (239 + VBLANK_TIME + 4)) + ScanLine = 0; else - ScanLine++; + + //console_printf(Console_Default, "SL:%d HBT:%d VbT:%d\n", ScanLine, HBLANK_TIME, VBLANK_TIME); if (keypressed()) { skey = (readkey() & 0xFF); - if (skey == 27) - R->Trace = 1; + // TODO: NO DEBUGER +/* if (skey == 27) + R->Trace = 1;*/ if (skey == '9') { - VBLANK_TIME += 1; - printf("VBLT: %d\n", VBLANK_TIME); + VBLANK_TIME += 2; + console_printf(Console_Default, "VBLT: %d\n", VBLANK_TIME); } if (skey == '6') { - VBLANK_TIME -= 1; - printf("VBLT: %d\n", VBLANK_TIME); + VBLANK_TIME -= 2; + console_printf(Console_Default, "VBLT: %d\n", VBLANK_TIME); } if (skey == '7') { HBLANK_TIME += 1; - printf("HBLT: %d\n", HBLANK_TIME); - MainCPU.IPeriod = HBLANK_TIME; + console_printf(Console_Default, "HBLT: %d\n", HBLANK_TIME); } if (skey == '4') { HBLANK_TIME -= 1; - printf("HBLT: %d\n", HBLANK_TIME); - MainCPU.IPeriod = HBLANK_TIME; + console_printf(Console_Default, "HBLT: %d\n", HBLANK_TIME); } - // if ((skey == '&') || (skey == '1')) - // ppu.ForceBgVisibility = ~ppu.ForceBgVisibility; - // if ((skey == 'ª') || (skey == '2')) - // ppu.ForceSpriteVisibility = ~ppu.ForceSpriteVisibility; - - // if ((skey == '"') || (skey == '3')) - // ppu.DisplayNameTables = ~ppu.DisplayNameTables; - - // if ((skey == '\'') || (skey == '4')) - // ppu.DisplayAttributeTable = ~ppu.DisplayAttributeTable; - - // if ((skey == '(') || (skey == '5')) - // ppu.DisplayPalette = ~ppu.DisplayPalette; - - // if ((skey == '-') || (skey == 'fl') || (skey == '6')) - // ppu.DisplayVRAM = ~ppu.DisplayVRAM; - if ((skey == 'r') || (skey == 'R')) { - //Reset6502(R); - MainCPU.PC.B.l=Rd6502(0xFFFC); - MainCPU.PC.B.h=Rd6502(0xFFFD); - + /* Force the PPU to stop NMIs */ + MemoryWrite(0x2000, 0x00); + quick6502_reset(R); } plugin_keypress(skey); } - - if (WantClosing == 1) - { - ret = INT_QUIT; - } - return ret; + + if (ret != 0) + quick6502_int(R, ret); } -/** Patch6502() **********************************************/ -/** Emulation calls this function when it encounters an **/ -/** unknown opcode. This can be used to patch the code to **/ -/** emulate BIOS calls, such as disk and tape access. The **/ -/** function should return 1 if the exception was handled, **/ -/** or 0 if the opcode was truly illegal. **/ -/************************************ TO BE WRITTEN BY USER **/ -byte Patch6502(register byte Op, register M6502 * R) -{ - //printf("Invalid Opcode : 0x%X @ 0x%04X !\n", Op, R->PC.W); - return 1; -} diff --git a/src/mappersmanager/CMakeLists.txt b/src/mappersmanager/CMakeLists.txt new file mode 100644 index 0000000..cb0a6df --- /dev/null +++ b/src/mappersmanager/CMakeLists.txt @@ -0,0 +1,13 @@ +# +# TI-NES CMake +# +# Created by Manoel TRAPIER. +# Copyright (c) 2003-2008 986Corp. All rights reserved. +# +# $LastChangedDate$ +# $Author$ +# $HeadURL$ +# $Revision$ + +file(GLOB mappers_list mappers/*.c) +add_library(mappermanager utils.c manager.c ${mappers_list} ) \ No newline at end of file diff --git a/src/mappersmanager/manager.c b/src/mappersmanager/manager.c index 1bd8400..d866c74 100644 --- a/src/mappersmanager/manager.c +++ b/src/mappersmanager/manager.c @@ -17,6 +17,8 @@ #include +#include + MapperIRQ mapper_irqloop; MapperDump mapper_dump; MapperWriteHook mapper_hook; @@ -37,10 +39,10 @@ typedef struct Mapper_ void mapper_list () { Mapper *ptr = &(Mappers[0]); - printf("Available mapers:\n"); + console_printf(Console_Default, "Available mapers:\n"); while(ptr->name != NULL) { - printf("%d - %s\n", ptr->id, ptr->name); + console_printf(Console_Default, "%d - %s\n", ptr->id, ptr->name); ptr++; } } @@ -48,12 +50,12 @@ void mapper_list () int mapper_init (NesCart *cart) { Mapper *ptr = &(Mappers[0]); - printf ("Search for a compatible mapper ID #%X:\n", cart->MapperID); + console_printf (Console_Default, "Search for a compatible mapper ID #%X:\n", cart->MapperID); while (ptr->name != NULL) { if (ptr->id == cart->MapperID) { - printf ("Found mapper ID #%X - '%s'\n", ptr->id, ptr->name); + console_printf (Console_Default, "Found mapper ID #%X - '%s'\n", ptr->id, ptr->name); ptr->init (cart); mapper_irqloop = ptr->irq; diff --git a/src/mappersmanager/mappers/aorom.c b/src/mappersmanager/mappers/aorom.c index 13145c2..df51428 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; - //printf("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 (giving %d & %d) - mirror is %d\n",BankNb,BankNb,(Value<<1)+1,Value&0x0F); set_prom_bank_32k(0x8000,BankNb); } diff --git a/src/mappersmanager/mappers/genericmapper.c b/src/mappersmanager/mappers/genericmapper.c.template similarity index 100% rename from src/mappersmanager/mappers/genericmapper.c rename to src/mappersmanager/mappers/genericmapper.c.template diff --git a/src/mappersmanager/mappers/iremh3001.c b/src/mappersmanager/mappers/iremh3001.c index 514ae02..56d90d3 100755 --- a/src/mappersmanager/mappers/iremh3001.c +++ b/src/mappersmanager/mappers/iremh3001.c @@ -45,29 +45,29 @@ int iremh3001_InitMapper(NesCart * cart) int iremh3001_MapperWriteHook(register byte Addr, register byte Value) { - +#if 0 switch(Addr) { case 0x8000: /* Set 8k PROM @ 8000 */ - printf("iremh3001: %X: change PROM to %d[%X]\n", Addr, Value, Value); + console_printf(Console_Default, "iremh3001: %X: change PROM to %d[%X]\n", Addr, Value, Value); set_prom_bank_8k(0x8000, Value); iremh3001_prom_slot[0] = Value; break; case 0x9003: /* Mirroring ??? */ - printf("iremh3001: Mirroring[0x%X:%d] ?\n", Value, Value); + console_printf(Console_Default, "iremh3001: Mirroring[0x%X:%d] ?\n", Value, Value); break; case 0x9005: /* IRQ ??? */ - printf("iremh3001: IRQ[0x%X:%d] ?\n", Value, Value); + console_printf(Console_Default, "iremh3001: IRQ[0x%X:%d] ?\n", Value, Value); break; case 0x9006: /* IRQ ??? */ - printf("iremh3001: IRQ[0x%X:%d] ?\n", Value, Value); + console_printf(Console_Default, "iremh3001: IRQ[0x%X:%d] ?\n", Value, Value); break; case 0xA000: /* Set 8k PROM @ A000 */ - printf("iremh3001: %X: change PROM to %d[%X]\n", Addr, Value, Value); + console_printf(Console_Default, "iremh3001: %X: change PROM to %d[%X]\n", Addr, Value, Value); set_prom_bank_8k(0xA000, Value); iremh3001_prom_slot[1] = Value; break; @@ -80,23 +80,23 @@ int iremh3001_MapperWriteHook(register byte Addr, register byte Value) case 0xB005: /* Set 1k VROM @ 1400 */ case 0xB006: /* Set 1k VROM @ 1800 */ case 0xB007: /* Set 1k VROM @ 1C00 */ - printf("iremh3001: %X: change VROM to %d[%X]\n", (Addr&0x0F)<<10, Value, Value); + console_printf(Console_Default, "iremh3001: %X: change VROM to %d[%X]\n", (Addr&0x0F)<<10, Value, Value); set_vrom_bank_1k((Addr&0xF)<<10, Value); iremh3001_vrom_slot[Addr&0x0F] = Value; break; case 0xC000: /* Set 8k PROM @ C000 */ - printf("iremh3001: %X: change PROM to %d[%X]\n", Addr, Value, Value); + console_printf(Console_Default, "iremh3001: %X: change PROM to %d[%X]\n", Addr, Value, Value); set_prom_bank_8k(0xC000, Value); iremh3001_prom_slot[2] = Value; break; default: - printf("@:%X -- V:%X", Addr, Value); + console_printf(Console_Default, "@:%X -- V:%X", Addr, Value); return 0; } - +#endif return 1; } diff --git a/src/mappersmanager/mappers/mmc1.c b/src/mappersmanager/mappers/mmc1.c index 85e66e0..5689fd6 100755 --- a/src/mappersmanager/mappers/mmc1.c +++ b/src/mappersmanager/mappers/mmc1.c @@ -139,7 +139,7 @@ void mmc1_ApplyReg0Mod() - //printf("Change to reg0 done ! (0x%x)\n\tMiror flag : %d\n\tOneScreen Flag : %d\n\tPRG Size : %d\n\tPRG Area : %d\n\tVROM Switch size : %d\n", MMC1_reg0, MMC1_reg0 & MMC1_R0_MIRROR, MMC1_reg0 & MMC1_R0_ONESCREEN, MMC1_reg0 & MMC1_R0_PRGAREA, MMC1_reg0 & MMC1_R0_PRGSIZE, MMC1_reg0 & MMC1_R0_VROMSW); + //console_printf(Console_Default, "Change to reg0 done ! (0x%x)\n\tMiror flag : %d\n\tOneScreen Flag : %d\n\tPRG Size : %d\n\tPRG Area : %d\n\tVROM Switch size : %d\n", MMC1_reg0, MMC1_reg0 & MMC1_R0_MIRROR, MMC1_reg0 & MMC1_R0_ONESCREEN, MMC1_reg0 & MMC1_R0_PRGAREA, MMC1_reg0 & MMC1_R0_PRGSIZE, MMC1_reg0 & MMC1_R0_VROMSW); switch (MMC1_reg0 & 0x03) { @@ -191,7 +191,7 @@ void mmc1_MapperWriteReg0(register byte Addr, register byte Value) if (Value & 0x80) { MMC1_reg0 = MMC1_REG0_DEFAULT; - printf("MMC1: Reg0 Reset occured !\n"); + console_printf(Console_Default, "MMC1: Reg0 Reset occured !\n"); mmc1_ApplyReg0Mod(); } else @@ -218,7 +218,7 @@ void mmc1_MapperWriteReg1(register byte Addr, register byte Value) if (Value & 0x80) { MMC1_reg1 = MMC1_REG1_DEFAULT; - printf("MMC1: Reg1 Reset occured !\n"); + console_printf(Console_Default, "MMC1: Reg1 Reset occured !\n"); } else { @@ -238,18 +238,18 @@ void mmc1_MapperWriteReg1(register byte Addr, register byte Value) if (Cart->VROMSize == 0) { - printf("Try to change VROM but with didn't have any VROM ! [%04X]\n", VROMBankNb); + console_printf(Console_Default, "Try to change VROM but with didn't have any VROM ! [%04X]\n", VROMBankNb); return; } if ( (MMC1_reg0 & MMC1_R0_VROMSW) != 0 ) { /* 4K vram */ - //printf("Switching VROM at 0x0000 to 4k bank %d\n", VROMBankNb); + //console_printf(Console_Default, "Switching VROM at 0x0000 to 4k bank %d\n", VROMBankNb); set_vrom_bank_4k(0x0000,VROMBankNb); } else { /* 8K vram */ - //printf("Switching VROM at 0x0000 to 8k bank %d\n", VROMBankNb>>1); + //console_printf(Console_Default, "Switching VROM at 0x0000 to 8k bank %d\n", VROMBankNb>>1); set_vrom_bank_8k(0x0000,VROMBankNb>>1); } } @@ -261,7 +261,7 @@ void mmc1_MapperWriteReg2(register byte Addr, register byte Value) if (Value & 0x80) { MMC1_reg2 = MMC1_REG2_DEFAULT; - printf("MMC1: Reg2 Reset occured !\n"); + console_printf(Console_Default, "MMC1: Reg2 Reset occured !\n"); } else { @@ -279,21 +279,21 @@ void mmc1_MapperWriteReg2(register byte Addr, register byte Value) VROMBankNb = (MMC1_reg2 /* & MMC1_R2_VROMB2 */ ); - //printf("Want to switch VROM at 0x1000 to 4k bank %d\n", VROMBankNb); + //console_printf(Console_Default, "Want to switch VROM at 0x1000 to 4k bank %d\n", VROMBankNb); if (Cart->VROMSize == 0) { - //printf(": No\n"); + //console_printf(Console_Default, ": No\n"); return; } if ( (MMC1_reg0 & MMC1_R0_VROMSW) != 0 ) { /* 4K vram */ - //printf("Switching VROM at 0x1000 to 4k bank %d\n", VROMBankNb); + //console_printf(Console_Default, "Switching VROM at 0x1000 to 4k bank %d\n", VROMBankNb); set_vrom_bank_4k(0x1000,VROMBankNb); } else { /* 8K vram */ - // printf("Switching VROM at 0x1000 to 8k bank %d\n", VROMBankNb>>1); + // console_printf(Console_Default, "Switching VROM at 0x1000 to 8k bank %d\n", VROMBankNb>>1); // set_vrom_bank_8k(0x1000,VROMBankNb>>1); } } @@ -305,7 +305,7 @@ void mmc1_MapperWriteReg3(register byte Addr, register byte Value) if (Value & 0x80) { MMC1_reg3 = MMC1_REG3_DEFAULT; - printf("MMC1: Reg3 Reset occured !\n"); + console_printf(Console_Default, "MMC1: Reg3 Reset occured !\n"); } else { @@ -329,12 +329,12 @@ void mmc1_MapperWriteReg3(register byte Addr, register byte Value) if ( (MMC1_reg0 & MMC1_R0_PRGAREA) != 0 ) { /* 0x8000 switch */ set_prom_bank_16k(0x8000,MMC1_reg3); - //printf("LowBank is now %d ( 0x%p )\n", MMC1_reg3, mLBank); + //console_printf(Console_Default, "LowBank is now %d ( 0x%p )\n", MMC1_reg3, mLBank); } else { /* 0xC000 switch */ set_prom_bank_16k(0xC000,MMC1_reg3); - //printf("HighBank is now %d ( 0x%p )\n", MMC1_reg3, mUBank); + //console_printf(Console_Default, "HighBank is now %d ( 0x%p )\n", MMC1_reg3, mUBank); } } else @@ -354,4 +354,4 @@ void mmc1_MapperWriteReg3(register byte Addr, register byte Value) } } - //printf("MMC1: Debug (Reg:%d,Val:0x%02X,reg0:0x%02X,reg1:0x%02X,reg2:0x%02X,reg3:0x%02X)\n", MMC1_GetReg(Addr), Value, MMC1_reg0, MMC1_reg1, MMC1_reg2, MMC1_reg3); + //console_printf(Console_Default, "MMC1: Debug (Reg:%d,Val:0x%02X,reg0:0x%02X,reg1:0x%02X,reg2:0x%02X,reg3:0x%02X)\n", MMC1_GetReg(Addr), Value, MMC1_reg0, MMC1_reg1, MMC1_reg2, MMC1_reg3); diff --git a/src/mappersmanager/mappers/mmc3.c b/src/mappersmanager/mappers/mmc3.c index 9e0dc89..80a6ecf 100755 --- a/src/mappersmanager/mappers/mmc3.c +++ b/src/mappersmanager/mappers/mmc3.c @@ -11,7 +11,6 @@ * $Revision$ * */ - #include "mmc3.h" extern unsigned short ScanLine; @@ -58,7 +57,7 @@ int mmc3_InitMapper(NesCart * cart) mmc3_command = -1; mmc3_irq_counter = -1; - mmc3_irq_enable = 1; + mmc3_irq_enable = 0; mmc3_irq_counter_reload = 0; mmc3_use_xor = 0x42; @@ -96,7 +95,7 @@ int mmc3_InitMapper(NesCart * cart) void mmc3_MapperWrite80Hook(byte addr, byte Value) { - //printf("%s(0x%02X, 0x%02X)\n", __func__, addr, Value); + //console_printf(Console_Default, "%s(0x%02X, 0x%02X)\n", __func__, addr, Value); if (addr > 0x01) return; @@ -133,7 +132,7 @@ void mmc3_MapperWrite80Hook(byte addr, byte Value) { if (!(Value & 0x40)) { - printf("MMC3: Switch -> 8/A\n"); + console_printf(Console_Default, "MMC3: Switch -> 8/A\n"); mmc3_first_prom_page = 0x8000; mmc3_second_prom_page = 0xA000; @@ -146,7 +145,7 @@ void mmc3_MapperWrite80Hook(byte addr, byte Value) } else { - printf("MMC3: Switch -> C/A\n"); + console_printf(Console_Default, "MMC3: Switch -> C/A\n"); mmc3_first_prom_page = 0xC000; mmc3_second_prom_page = 0xA000; @@ -158,9 +157,9 @@ void mmc3_MapperWrite80Hook(byte addr, byte Value) //prg_bank(max_prg-1,prg1,prg0,max_prg); } - mmc3_last_prom_switch = (Value & 0x40); + mmc3_last_prom_switch = (Value & 0x40); } - mmc3_command = Value & 0x07; + mmc3_command = Value & 0x07; @@ -224,13 +223,13 @@ void mmc3_MapperWrite80Hook(byte addr, byte Value) void mmc3_MapperWriteA0Hook(byte addr, byte Value) { - //printf("%s(0x%02X, 0x%02X)\n", __func__, addr, Value); + //console_printf(Console_Default, "%s(0x%02X, 0x%02X)\n", __func__, addr, Value); if (addr > 0x01) return; if (!addr) { - //printf("MMC3: Select mirroring (0xA000) : 0x%X\n",Value); + //console_printf(Console_Default, "MMC3: Select mirroring (0xA000) : 0x%X\n",Value); if (Value & 0x1) ppu_setMirroring(PPU_MIRROR_HORIZTAL); @@ -240,7 +239,7 @@ void mmc3_MapperWriteA0Hook(byte addr, byte Value) } else { - //printf("MMC3: SaveRAM Toggle (0xA001) : 0x%X\n",Value); + //console_printf(Console_Default, "MMC3: SaveRAM Toggle (0xA001) : 0x%X\n",Value); if (Value) map_sram(); else @@ -251,7 +250,7 @@ void mmc3_MapperWriteA0Hook(byte addr, byte Value) void mmc3_MapperWriteC0Hook(byte addr, byte Value) { - //printf("%s(0x%02X, 0x%02X)\n", __func__, addr, Value); + //console_printf(Console_Default, "%s(0x%02X, 0x%02X)\n", __func__, addr, Value); if (addr > 0x01) return; @@ -259,33 +258,33 @@ void mmc3_MapperWriteC0Hook(byte addr, byte Value) { mmc3_irq_counter_reload = Value; mmc3_irq_counter = Value; - //printf("MMC3 IRQ[%d]: SetIRQ reload to %d\n", ScanLine, Value); + //console_printf(Console_Default, "MMC3 IRQ[%d]: SetIRQ reload to %d\n", ScanLine, Value); }else{ /* C001 */ - //printf("MMC3: New tmp IRQ value (0xC001) : 0x%X\n",Value); - //printf("MMC3 IRQ[%d]: Reset IRQ counter to val %d [Value = %d]\n", ScanLine, mmc3_irq_counter_reload, Value); + //console_printf(Console_Default, "MMC3: New tmp IRQ value (0xC001) : 0x%X\n",Value); + //console_printf(Console_Default, "MMC3 IRQ[%d]: Reset IRQ counter to val %d [Value = %d]\n", ScanLine, mmc3_irq_counter_reload, Value); mmc3_irq_counter = Value; } } void mmc3_MapperWriteE0Hook(byte addr, byte Value) { - //printf("%s(0x%02X, 0x%02X)\n", __func__, addr, Value); + //console_printf(Console_Default, "%s(0x%02X, 0x%02X)\n", __func__, addr, Value); if (addr > 0x01) return; if (!addr) { - //printf("MMC3: Writing to 0xE001 : 0x%X\n",Value); - //printf("MMC3 IRQ[%d]: IRQ disabled\n", ScanLine); + //console_printf(Console_Default, "MMC3: Writing to 0xE001 : 0x%X\n",Value); + //console_printf(Console_Default, "MMC3 IRQ[%d]: IRQ disabled\n", ScanLine); mmc3_irq_enable = 0; //MapperWantIRQ = 1; // Add a way to raise an IRQ }else{ /* E001 */ - //printf("MMC3: Writing to 0xE001 : 0x%X\n",Value); - //printf("MMC3: IRQ Enabled (value : %d)\n",mmc3_irq_counter); - //printf("MMC3 IRQ[%d]: Enable IRQ\nr", ScanLine); + //console_printf(Console_Default, "MMC3: Writing to 0xE001 : 0x%X\n",Value); + //console_printf(Console_Default, "MMC3: IRQ Enabled (value : %d)\n",mmc3_irq_counter); + //console_printf(Console_Default, "MMC3 IRQ[%d]: Enable IRQ\nr", ScanLine); mmc3_irq_enable = 1; } } @@ -306,7 +305,7 @@ int mmc3_MapperIRQ(int cycledone) mmc3_irq_enable = 0; - //printf("MMC3 IRQ[%d]: Tick next at %d\n", ScanLine, mmc3_irq_counter_reload); + //console_printf(Console_Default, "MMC3 IRQ[%d]: Tick next at %d\n", ScanLine, mmc3_irq_counter_reload); return 1; } diff --git a/src/mappersmanager/mappers/mmc4.c b/src/mappersmanager/mappers/mmc4.c index 33087e3..6be7829 100644 --- a/src/mappersmanager/mappers/mmc4.c +++ b/src/mappersmanager/mappers/mmc4.c @@ -22,16 +22,15 @@ byte mmc4_RegE; byte mmc4_RegF; #ifdef DEBUG -#define LOG -//printf +#define LOG(s) printf s #else -#define LOG +#define LOG(s) { } #endif void mmc4_MapperWriteRegA(register byte Addr, register byte Value) { - LOG("%s(%02X, %02X)\n", __func__, Addr, Value); + LOG(("%s(%02X, %02X)\n", __func__, Addr, Value)); mmc4_RegA = Value; set_prom_bank_16k(0x8000, Value & 0x0F); @@ -40,7 +39,7 @@ void mmc4_MapperWriteRegA(register byte Addr, register byte Value) void mmc4_MapperWriteRegB(register byte Addr, register byte Value) { - LOG("%s(%02X, %02X)\n", __func__, Addr, Value); + LOG(("%s(%02X, %02X)\n", __func__, Addr, Value)); mmc4_RegB = Value; set_vrom_bank_4k(0x0000, Value & 0x1F); @@ -48,28 +47,28 @@ void mmc4_MapperWriteRegB(register byte Addr, register byte Value) void mmc4_MapperWriteRegC(register byte Addr, register byte Value) { - LOG("%s(%02X, %02X)\n", __func__, Addr, Value); + LOG(("%s(%02X, %02X)\n", __func__, Addr, Value)); mmc4_RegC = Value; set_vrom_bank_4k(0x0000, Value & 0x1F); } void mmc4_MapperWriteRegD(register byte Addr, register byte Value) { - LOG("%s(%02X, %02X)\n", __func__, Addr, Value); + LOG(("%s(%02X, %02X)\n", __func__, Addr, Value)); mmc4_RegD = Value; set_vrom_bank_4k(0x1000, Value & 0x1F); } void mmc4_MapperWriteRegE(register byte Addr, register byte Value) { - LOG("%s(%02X, %02X)\n", __func__, Addr, Value); + LOG(("%s(%02X, %02X)\n", __func__, Addr, Value)); mmc4_RegE = Value; set_vrom_bank_4k(0x1000, Value & 0x1F); } void mmc4_MapperWriteRegF(register byte Addr, register byte Value) { - LOG("%s(%02X, %02X)\n", __func__, Addr, Value); + LOG(("%s(%02X, %02X)\n", __func__, Addr, Value)); mmc4_RegF = Value; if (Value & 0x01) ppu_setMirroring(PPU_MIRROR_HORIZTAL); diff --git a/src/mappersmanager/unused/mmc1.h b/src/mappersmanager/unused/mmc1.h index 7c563dc..4fae5c1 100755 --- a/src/mappersmanager/unused/mmc1.h +++ b/src/mappersmanager/unused/mmc1.h @@ -137,7 +137,7 @@ void mmc1_ApplyReg0Mod() - //printf("Change to reg0 done ! (0x%x)\n\tMiror flag : %d\n\tOneScreen Flag : %d\n\tPRG Size : %d\n\tPRG Area : %d\n\tVROM Switch size : %d\n", MMC1_reg0, MMC1_reg0 & MMC1_R0_MIRROR, MMC1_reg0 & MMC1_R0_ONESCREEN, MMC1_reg0 & MMC1_R0_PRGAREA, MMC1_reg0 & MMC1_R0_PRGSIZE, MMC1_reg0 & MMC1_R0_VROMSW); + //console_printf(Console_Default, "Change to reg0 done ! (0x%x)\n\tMiror flag : %d\n\tOneScreen Flag : %d\n\tPRG Size : %d\n\tPRG Area : %d\n\tVROM Switch size : %d\n", MMC1_reg0, MMC1_reg0 & MMC1_R0_MIRROR, MMC1_reg0 & MMC1_R0_ONESCREEN, MMC1_reg0 & MMC1_R0_PRGAREA, MMC1_reg0 & MMC1_R0_PRGSIZE, MMC1_reg0 & MMC1_R0_VROMSW); switch (MMC1_reg0 & 0x03) { @@ -189,7 +189,7 @@ void mmc1_MapperWriteReg0(register byte Addr, register byte Value) if (Value & 0x80) { MMC1_reg0 = MMC1_REG0_DEFAULT; - printf("MMC1: Reg0 Reset occured !\n"); + console_printf(Console_Default, "MMC1: Reg0 Reset occured !\n"); mmc1_ApplyReg0Mod(); } else @@ -216,7 +216,7 @@ void mmc1_MapperWriteReg1(register byte Addr, register byte Value) if (Value & 0x80) { MMC1_reg1 = MMC1_REG1_DEFAULT; - printf("MMC1: Reg1 Reset occured !\n"); + console_printf(Console_Default, "MMC1: Reg1 Reset occured !\n"); } else { @@ -236,18 +236,18 @@ void mmc1_MapperWriteReg1(register byte Addr, register byte Value) if (Cart->VROMSize == 0) { - printf("Try to change VROM but with didn't have any VROM ! [%04X]\n", VROMBankNb); + console_printf(Console_Default, "Try to change VROM but with didn't have any VROM ! [%04X]\n", VROMBankNb); return; } if ( (MMC1_reg0 & MMC1_R0_VROMSW) != 0 ) { /* 4K vram */ - //printf("Switching VROM at 0x0000 to 4k bank %d\n", VROMBankNb); + //console_printf(Console_Default, "Switching VROM at 0x0000 to 4k bank %d\n", VROMBankNb); set_vrom_bank_4k(0x0000,VROMBankNb); } else { /* 8K vram */ - //printf("Switching VROM at 0x0000 to 8k bank %d\n", VROMBankNb>>1); + //console_printf(Console_Default, "Switching VROM at 0x0000 to 8k bank %d\n", VROMBankNb>>1); set_vrom_bank_8k(0x0000,VROMBankNb>>1); } } @@ -259,7 +259,7 @@ void mmc1_MapperWriteReg2(register byte Addr, register byte Value) if (Value & 0x80) { MMC1_reg2 = MMC1_REG2_DEFAULT; - printf("MMC1: Reg2 Reset occured !\n"); + console_printf(Console_Default, "MMC1: Reg2 Reset occured !\n"); } else { @@ -277,21 +277,21 @@ void mmc1_MapperWriteReg2(register byte Addr, register byte Value) VROMBankNb = (MMC1_reg2 /* & MMC1_R2_VROMB2 */ ); - //printf("Want to switch VROM at 0x1000 to 4k bank %d\n", VROMBankNb); + //console_printf(Console_Default, "Want to switch VROM at 0x1000 to 4k bank %d\n", VROMBankNb); if (Cart->VROMSize == 0) { - //printf(": No\n"); + //console_printf(Console_Default, ": No\n"); return; } if ( (MMC1_reg0 & MMC1_R0_VROMSW) != 0 ) { /* 4K vram */ - //printf("Switching VROM at 0x1000 to 4k bank %d\n", VROMBankNb); + //console_printf(Console_Default, "Switching VROM at 0x1000 to 4k bank %d\n", VROMBankNb); set_vrom_bank_4k(0x1000,VROMBankNb); } else { /* 8K vram */ - // printf("Switching VROM at 0x1000 to 8k bank %d\n", VROMBankNb>>1); + // console_printf(Console_Default, "Switching VROM at 0x1000 to 8k bank %d\n", VROMBankNb>>1); // set_vrom_bank_8k(0x1000,VROMBankNb>>1); } } @@ -303,7 +303,7 @@ void mmc1_MapperWriteReg3(register byte Addr, register byte Value) if (Value & 0x80) { MMC1_reg3 = MMC1_REG3_DEFAULT; - printf("MMC1: Reg3 Reset occured !\n"); + console_printf(Console_Default, "MMC1: Reg3 Reset occured !\n"); } else { @@ -327,12 +327,12 @@ void mmc1_MapperWriteReg3(register byte Addr, register byte Value) if ( (MMC1_reg0 & MMC1_R0_PRGAREA) != 0 ) { /* 0x8000 switch */ set_prom_bank_16k(0x8000,MMC1_reg3); - //printf("LowBank is now %d ( 0x%p )\n", MMC1_reg3, mLBank); + //console_printf(Console_Default, "LowBank is now %d ( 0x%p )\n", MMC1_reg3, mLBank); } else { /* 0xC000 switch */ set_prom_bank_16k(0xC000,MMC1_reg3); - //printf("HighBank is now %d ( 0x%p )\n", MMC1_reg3, mUBank); + //console_printf(Console_Default, "HighBank is now %d ( 0x%p )\n", MMC1_reg3, mUBank); } } else @@ -352,4 +352,4 @@ void mmc1_MapperWriteReg3(register byte Addr, register byte Value) } } - //printf("MMC1: Debug (Reg:%d,Val:0x%02X,reg0:0x%02X,reg1:0x%02X,reg2:0x%02X,reg3:0x%02X)\n", MMC1_GetReg(Addr), Value, MMC1_reg0, MMC1_reg1, MMC1_reg2, MMC1_reg3); + //console_printf(Console_Default, "MMC1: Debug (Reg:%d,Val:0x%02X,reg0:0x%02X,reg1:0x%02X,reg2:0x%02X,reg3:0x%02X)\n", MMC1_GetReg(Addr), Value, MMC1_reg0, MMC1_reg1, MMC1_reg2, MMC1_reg3); diff --git a/src/mappersmanager/utils.c b/src/mappersmanager/utils.c index 225b157..6d91101 100755 --- a/src/mappersmanager/utils.c +++ b/src/mappersmanager/utils.c @@ -38,7 +38,7 @@ extern char MapperWantIRQ; void set_vrom_bank_1k(unsigned short addr,int slot) { #ifdef DEBUG_VROM_BANK_SWITCH - printf("Change vrom 1k bank 0x%X to slot %d\n",addr,slot); + console_printf(Console_Default, "Change vrom 1k bank 0x%X to slot %d\n",addr,slot); #endif ppu_setPagePtr1k((addr>>8)&0xFF, Cart->VROMBanks + (slot * 1024)); // memcpy(ppu.Memory+addr, Cart->VROMBanks + (slot * 1024), 0x0400); @@ -47,7 +47,7 @@ void set_vrom_bank_1k(unsigned short addr,int slot) void set_vrom_bank_2k(unsigned short addr,int slot) { #ifdef DEBUG_VROM_BANK_SWITCH - printf("Change vrom 2k bank 0x%X to slot %d\n",addr,slot); + console_printf(Console_Default, "Change vrom 2k bank 0x%X to slot %d\n",addr,slot); #endif ppu_setPagePtr2k((addr>>8)&0xFF, Cart->VROMBanks + (slot * 2 * 1024)); // memcpy(ppu.Memory+addr, Cart->VROMBanks + (slot * 2 * 1024), 0x0800); @@ -56,7 +56,7 @@ void set_vrom_bank_2k(unsigned short addr,int slot) void set_vrom_bank_4k(unsigned short addr,int slot) { #ifdef DEBUG_VROM_BANK_SWITCH - printf("Change vrom 4k bank 0x%X to slot %d\n",addr,slot); + console_printf(Console_Default, "Change vrom 4k bank 0x%X to slot %d\n",addr,slot); #endif ppu_setPagePtr4k((addr>>8)&0xFF, Cart->VROMBanks + (slot * 4 * 1024)); // memcpy(ppu.Memory+addr, Cart->VROMBanks + (slot * 4 * 1024), 0x1000); @@ -65,7 +65,7 @@ void set_vrom_bank_4k(unsigned short addr,int slot) void set_vrom_bank_8k(unsigned short addr, int slot) { #ifdef DEBUG_VROM_BANK_SWITCH - printf("Change vrom 8k bank 0x%X to slot %d\n",addr,slot); + console_printf(Console_Default, "Change vrom 8k bank 0x%X to slot %d\n",addr,slot); #endif ppu_setPagePtr8k(0x00, Cart->VROMBanks + (slot * 8 * 1024)); // memcpy(ppu.Memory, Cart->VROMBanks + (slot * 8 * 1024) , 0x2000); @@ -76,7 +76,7 @@ void set_vrom_bank_8k(unsigned short addr, int slot) void set_prom_bank_8k(unsigned short addr,int slot) { #ifdef DEBUG_PROM_BANK_SWITCH - printf("Change prom 8k bank 0x%X to slot %d\n",addr,slot); + console_printf(Console_Default, "Change prom 8k bank 0x%X to slot %d\n",addr,slot); #endif set_page_ptr_8k(addr >> 8, Cart->PROMBanks + (slot * 8 * 1024)); } @@ -84,7 +84,7 @@ void set_prom_bank_8k(unsigned short addr,int slot) void set_prom_bank_16k(unsigned short addr,int slot) { #ifdef DEBUG_PROM_BANK_SWITCH - printf("Change prom 16k bank @ 0x%X [0x%X] to slot 0x%X\n",addr, addr>>8,slot); + console_printf(Console_Default, "Change prom 16k bank @ 0x%X [0x%X] to slot 0x%X\n",addr, addr>>8,slot); #endif set_page_ptr_16k(addr >> 8, Cart->PROMBanks + (slot * 16 * 1024)); } @@ -93,7 +93,7 @@ void set_prom_bank_32k(unsigned short addr,int slot) { /* addr may not be different from 0x8000 !*/ /* Anyway I don't use it */ #ifdef DEBUG_PROM_BANK_SWITCH - printf("Change prom 32k bank 0x%X to slot %d\n",addr,slot); + console_printf(Console_Default, "Change prom 32k bank 0x%X to slot %d\n",addr,slot); #endif set_page_ptr_32k(addr >> 8, Cart->PROMBanks + (slot * 32 * 1024)); /* set_page_ptr_16k(0x80, Cart->PROMBanks[(slot<<1)]); diff --git a/src/memorymanager/CMakeLists.txt b/src/memorymanager/CMakeLists.txt new file mode 100644 index 0000000..7a865e3 --- /dev/null +++ b/src/memorymanager/CMakeLists.txt @@ -0,0 +1,12 @@ +# +# TI-NES CMake +# +# Created by Manoel TRAPIER. +# Copyright (c) 2003-2008 986Corp. All rights reserved. +# +# $LastChangedDate$ +# $Author$ +# $HeadURL$ +# $Revision$ + +add_library(memorymanager memory.c) \ No newline at end of file diff --git a/src/memorymanager/memory.c b/src/memorymanager/memory.c index f804b56..6984619 100755 --- a/src/memorymanager/memory.c +++ b/src/memorymanager/memory.c @@ -11,11 +11,13 @@ * $Revision$ * */ - #include -#include "types.h" -#include "../include/memory/manager.h" +#include + +#include + +#include /* Private structures */ @@ -50,13 +52,13 @@ func_wrhook wrh_table[0x100]; /* Public functions */ void set_page_ptr(byte page, byte *ptr) { - LOG(printf("Set page 0x%X to ptr %p\n", page, ptr)); + LOG(console_printf(Console_Default, "Set page 0x%X to ptr %p\n", page, ptr)); memory_pages[page] = ptr; } void set_page_ptr_1k(byte page, byte *ptr) { /* 1k = 4 * 256 */ - LOG(printf("Set page(1k) 0x%X to ptr %p\n", page, ptr)); + LOG(console_printf(Console_Default, "Set page(1k) 0x%X to ptr %p\n", page, ptr)); memory_pages[page + 0] = ptr; memory_pages[page + 1] = ptr + 0x100; memory_pages[page + 2] = ptr + (0x100 * 2); @@ -65,7 +67,7 @@ void set_page_ptr_1k(byte page, byte *ptr) void set_page_ptr_2k(byte page, byte *ptr) { - LOG(printf("Set page(2k) 0x%X to ptr %p\n", page, ptr)); + LOG(console_printf(Console_Default, "Set page(2k) 0x%X to ptr %p\n", page, ptr)); memory_pages[page + 0] = ptr; memory_pages[page + 1] = ptr + 0x100; memory_pages[page + 2] = ptr + (0x100 * 2); @@ -78,14 +80,14 @@ void set_page_ptr_2k(byte page, byte *ptr) void set_page_ptr_4k(byte page, byte *ptr) { - LOG(printf("Set page(4k) 0x%X to ptr %p\n", page, ptr)); + LOG(console_printf(Console_Default, "Set page(4k) 0x%X to ptr %p\n", page, ptr)); set_page_ptr_2k(page, ptr); set_page_ptr_2k(page+((4 KBYTE / 256) / 2), ptr + 2 KBYTE); } void set_page_ptr_8k(byte page, byte *ptr) { - LOG(printf("Set page(8k) 0x%X to ptr %p\n", page, ptr)); + LOG(console_printf(Console_Default, "Set page(8k) 0x%X to ptr %p\n", page, ptr)); set_page_ptr_4k(page, ptr); set_page_ptr_4k(page+((8 KBYTE / 256) / 2), ptr + 4 KBYTE); } @@ -195,26 +197,23 @@ func_wrhook get_page_wrhook(byte page) return NULL; } - - - byte ReadMemory(byte page, byte addr) { static byte LastRetByte = 0xA5; byte *page_ptr; byte attributes; - LOG(printf("Read @ 0x%X-%X\n", page, addr)); + LOG(console_printf(Console_Default, "Read @ 0x%X-%X\n", page, addr)); /* Est-ce que la page est mappĆ© ? && Est-ce que la page est "readable" ? */ if ((page_ptr = memory_pages[page]) && ( (attributes = memory_pages_attr[page]) & ATTR_PAGE_READABLE) ) { - LOG(printf("Page is non null & readable\n")); + LOG(console_printf(Console_Default, "Page is non null & readable\n")); if ( attributes & ATTR_PAGE_HAVE_RDHOOK ) return ( LastRetByte = rdh_table[page](addr) ); else return ( LastRetByte = page_ptr[addr] ); } - //printf("Trying to read @ 0x%X-%X\n", page, addr); + //console_printf(Console_Default, "Trying to read @ 0x%X-%X\n", page, addr); return LastRetByte; } @@ -222,7 +221,7 @@ void WriteMemory(byte page, byte addr, byte value) { byte *page_ptr; byte attributes; - LOG(printf("Write 0x%x @ 0x%X-%X\n", value, page, addr)); + LOG(console_printf(Console_Default, "Write 0x%x @ 0x%X-%X\n", value, page, addr)); /* Est-ce que la page est mappĆ© ? && Est-ce que la page est "writable" ? */ if ( (page_ptr = memory_pages[page]) && ( (attributes = memory_pages_attr[page]) & ATTR_PAGE_WRITEABLE) ) @@ -231,14 +230,14 @@ void WriteMemory(byte page, byte addr, byte value) { #ifdef DETECT_BUS_CONFLICT if ((page >= 0x80) && (memory_pages[page][addr] != value)) - printf("WriteHook: bus conflict at %02X%02X rom:%02X write:%02X\n", page, addr, memory_pages[page][addr], value); + console_printf(Console_Default, "WriteHook: bus conflict at %02X%02X rom:%02X write:%02X\n", page, addr, memory_pages[page][addr], value); #endif wrh_table[page](addr, value); } else page_ptr[addr] = value; } - else { printf("Trying to write 0x%X @ 0x%X-%X\n", value, page, addr); } + else { console_printf(Console_Default, "Trying to write 0x%X @ 0x%X-%X\n", value, page, addr); } } void DumpMemoryState(FILE *fp) diff --git a/src/os/macos/CMakeLists.txt b/src/os/macos/CMakeLists.txt new file mode 100644 index 0000000..36c73c0 --- /dev/null +++ b/src/os/macos/CMakeLists.txt @@ -0,0 +1,12 @@ +# +# TI-NES CMake +# +# Created by Manoel TRAPIER. +# Copyright (c) 2003-2008 986Corp. All rights reserved. +# +# $LastChangedDate$ +# $Author$ +# $HeadURL$ +# $Revision$ + +add_library(oslib loadfile.c graphics.c sound.c io.c) \ No newline at end of file diff --git a/src/os/macos/graphics.c b/src/os/macos/graphics.c new file mode 100644 index 0000000..97c5ef7 --- /dev/null +++ b/src/os/macos/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() +{ + +} + +int graphics_drawpixel(long x, long y, long color) +{ + +} + +int graphics_blit(long x, long y, long w, long h) +{ + +} diff --git a/src/os/macos/io.c b/src/os/macos/io.c new file mode 100644 index 0000000..0640886 --- /dev/null +++ b/src/os/macos/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 ret; +} + +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/macos/loadfile.c b/src/os/macos/loadfile.c new file mode 100644 index 0000000..cb7b329 --- /dev/null +++ b/src/os/macos/loadfile.c @@ -0,0 +1,45 @@ +/* + * File functions - The TI-NESulator Project + * os/macos/load.c + * + * Copyright (c) 2003-2008 986Corp. All rights reserved. + * + * $LastChangedDate$ + * $Author$ + * $HeadURL$ + * $Revision$ + * + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#include + +/* Map a file in memory */ +void *LoadFilePtr(char * filename) +{ + int fd; + void *RetPtr = NULL; + struct stat FileStat; + + fd = open(filename, O_RDONLY); + + fstat(fd, &FileStat); + + RetPtr = mmap(NULL, FileStat.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); + + close(fd); + + return RetPtr; +} diff --git a/src/os/macos/sound.c b/src/os/macos/sound.c new file mode 100644 index 0000000..e69de29 diff --git a/src/os/ti68k/CMakeLists.txt b/src/os/ti68k/CMakeLists.txt new file mode 100644 index 0000000..487726e --- /dev/null +++ b/src/os/ti68k/CMakeLists.txt @@ -0,0 +1,12 @@ +# +# TI-NES CMake +# +# Created by Manoel TRAPIER. +# Copyright (c) 2003-2008 986Corp. All rights reserved. +# +# $LastChangedDate$ +# $Author$ +# $HeadURL$ +# $Revision$ + +add_library(oslib loadfile.c) \ No newline at end of file diff --git a/src/os/ti68k/loadfile.c b/src/os/ti68k/loadfile.c new file mode 100644 index 0000000..07b60c7 --- /dev/null +++ b/src/os/ti68k/loadfile.c @@ -0,0 +1,34 @@ +/* + * TI-68k Loading external file functions - The TI-NESulator Project + * ti68k/loadfile.c + * + * Created by Manoel TRAPIER. + * Copyright (c) 2003-2008 986Corp. All rights reserved. + * + * $LastChangedDate:$ + * $Author:$ + * $HeadURL:$ + * $Revision:$ + * + */ + +#define TIGCC_COMPAT +#include + +/* Map a file in memory */ +void *LoadFilePtr(char * filename) +{ + void *RetPtr = NULL; + FILE *fp; + + if ((fp = fopen(filename,"rb")) == NULL) + return -1; + + /* TI Related stuff, very uggly, and need to be changed.. */ + HeapLock(fp->handle); + RetPtr = 2 + HeapDeref(fp->handle); + + fclose (fp); + + return RetPtr; +} diff --git a/src/os/ti68k/main.c b/src/os/ti68k/main.c new file mode 100644 index 0000000..3e49188 --- /dev/null +++ b/src/os/ti68k/main.c @@ -0,0 +1,8 @@ +#include + +int main(int argc, char *argv[]); + +void _main() +{ + main(1, "smb1.nes"); +} \ No newline at end of file diff --git a/src/os/unix/CMakeLists.txt b/src/os/unix/CMakeLists.txt new file mode 100644 index 0000000..487726e --- /dev/null +++ b/src/os/unix/CMakeLists.txt @@ -0,0 +1,12 @@ +# +# TI-NES CMake +# +# Created by Manoel TRAPIER. +# Copyright (c) 2003-2008 986Corp. All rights reserved. +# +# $LastChangedDate$ +# $Author$ +# $HeadURL$ +# $Revision$ + +add_library(oslib loadfile.c) \ No newline at end of file diff --git a/src/os/win32/CMakeLists.txt b/src/os/win32/CMakeLists.txt new file mode 100644 index 0000000..487726e --- /dev/null +++ b/src/os/win32/CMakeLists.txt @@ -0,0 +1,12 @@ +# +# TI-NES CMake +# +# Created by Manoel TRAPIER. +# Copyright (c) 2003-2008 986Corp. All rights reserved. +# +# $LastChangedDate$ +# $Author$ +# $HeadURL$ +# $Revision$ + +add_library(oslib loadfile.c) \ No newline at end of file diff --git a/src/paddle.c b/src/paddle.c index 06ac00b..c35c517 100755 --- a/src/paddle.c +++ b/src/paddle.c @@ -12,7 +12,14 @@ * */ +/* Allegro includes */ +#ifdef __APPLE__ +#define USE_CONSOLE +#include +#else +#define USE_CONSOLE #include +#endif #include "paddle.h" void InitPaddle(Paddle * pdl) @@ -99,7 +106,7 @@ unsigned char ReadPaddle(Paddle * pdl) case 20: - return 0x41; + return 0x40; break; @@ -116,6 +123,6 @@ unsigned char ReadPaddle(Paddle * pdl) break; } - return 0x40; + return 0x40; } diff --git a/src/pluginsmanager/CMakeLists.txt b/src/pluginsmanager/CMakeLists.txt new file mode 100644 index 0000000..15a00b5 --- /dev/null +++ b/src/pluginsmanager/CMakeLists.txt @@ -0,0 +1,13 @@ +# +# TI-NES CMake +# +# Created by Manoel TRAPIER. +# Copyright (c) 2003-2008 986Corp. All rights reserved. +# +# $LastChangedDate$ +# $Author$ +# $HeadURL$ +# $Revision$ + +file(GLOB plugins_list plugins/*.c) +add_library(pluginsmanager manager.c ${plugins_list}) \ No newline at end of file diff --git a/src/pluginsmanager/manager.c b/src/pluginsmanager/manager.c index 05bbf3a..88b1bd3 100644 --- a/src/pluginsmanager/manager.c +++ b/src/pluginsmanager/manager.c @@ -15,6 +15,8 @@ #include #include +#include + #include typedef struct Plugin_ @@ -44,10 +46,10 @@ void plugin_list() { Plugin *ptr = &(Plugins[0]); int i = 1; - printf("Available plugins:\n"); + console_printf(Console_Default, "Available plugins:\n"); while(ptr->name != NULL) { - printf("%d - %s\n", i, ptr->name); + console_printf(Console_Default, "%d - %s\n", i, ptr->name); ptr++; i++; } } @@ -57,11 +59,11 @@ int plugin_load(int id) Plugin *ptr = &(Plugins[0]); int i = id; - printf("%s(%d)", __func__, id); + console_printf(Console_Default, "%s(%d)", __func__, id); for ( ; i > 1 && ptr->name != NULL; i -- ) { - printf("%d - %s\n", i, ptr->name); + console_printf(Console_Default, "%d - %s\n", i, ptr->name); ptr ++; } diff --git a/src/pluginsmanager/plugins/gamegenie.c b/src/pluginsmanager/plugins/gamegenie.c index 2778da5..cec5e42 100644 --- a/src/pluginsmanager/plugins/gamegenie.c +++ b/src/pluginsmanager/plugins/gamegenie.c @@ -14,7 +14,8 @@ #include #include -#include + +#include #define __TINES_PLUGINS__ #include @@ -22,7 +23,16 @@ #include #include -#include "allegro.h" + +/* Allegro includes */ +#ifdef __APPLE__ +#define USE_CONSOLE +#include +#else +#define USE_CONSOLE +#include +#endif + typedef enum gg_States_ { @@ -310,7 +320,7 @@ unsigned short SelectNumber(char *title, char *msg, byte size) int DispMenu(int itemc, char *itemv[], char *title) { - //printf("%s(%d, %p, \"%s\");\n", __func__, itemc, itemv, title); + //console_printf(Console_Default, "%s(%d, %p, \"%s\");\n", __func__, itemc, itemv, title); int selection = 0; int i; @@ -428,7 +438,7 @@ byte gg_SelectPatch() for (i = 0; i < GG_MAX_PATCH; i++) { tmp = (char*) malloc(0x100); - printf("Items[%d]: %p\n", i, tmp); + console_printf(Console_Default, "Items[%d]: %p\n", i, tmp); if (gg_PatchUsed[i] == 0x00) sprintf(tmp, "Patch %d: Not used", i); else @@ -456,7 +466,7 @@ byte gg_SelectPatch() void gg_PatchManager() { - printf("DTC!\n"); + console_printf(Console_Default, "DTC!\n"); } void gg_InitSearch() @@ -484,7 +494,7 @@ typedef enum gg_SearchForMode_ void gg_SearchForValue(byte value) { unsigned short addr; - byte oldValue; + //byte oldValue; byte currentValue; gg_ResultNumber = 0x00; for(addr = 0x000; addr < 0x800; addr ++) @@ -494,7 +504,7 @@ void gg_SearchForValue(byte value) /* "Backup" the old ram */ memcpy(gg_OldMainRAM, gg_MainRAM, 0x800); - oldValue = gg_MainRAM[addr]; + //oldValue = gg_MainRAM[addr]; currentValue = ReadMemory((addr&0xFF00)>>8,addr&0x00FF); if (currentValue != value) @@ -597,7 +607,7 @@ byte gg_DisplayResults() { while(gg_use_MainRAM[addr] != 0xFF) addr ++; - printf("0x%04X [%d]\n", addr, i); + console_printf(Console_Default, "0x%04X [%d]\n", addr, i); tmp = (char*) malloc(0x100); sprintf(tmp,"Patch: %08XAddress 0x%04X - Was: 0x%02X - Actual: 0x%02X", i, @@ -799,7 +809,7 @@ S02_MENU: int gg_Init() { int i; - printf("Initializing GG plugin...\n"); + console_printf(Console_Default, "Initializing GG plugin...\n"); plugin_install_keypressHandler('g', gg_Start); diff --git a/src/ppu/CMakeLists.txt b/src/ppu/CMakeLists.txt new file mode 100644 index 0000000..c3b40b6 --- /dev/null +++ b/src/ppu/CMakeLists.txt @@ -0,0 +1,13 @@ +# +# TI-NES CMake +# +# Created by Manoel TRAPIER. +# Copyright (c) 2003-2008 986Corp. All rights reserved. +# +# $LastChangedDate$ +# $Author$ +# $HeadURL$ +# $Revision$ + +file(GLOB ppu_debug_list debug/*.c) +add_library(ppu ppu.c ppu.memory.c ${ppu_debug_list}) \ No newline at end of file diff --git a/src/ppu/debug/ppu.debug.c b/src/ppu/debug/ppu.debug.c index d2c66f9..3cce3b4 100644 --- a/src/ppu/debug/ppu.debug.c +++ b/src/ppu/debug/ppu.debug.c @@ -15,7 +15,14 @@ #include #include +/* Allegro includes */ +#ifdef __APPLE__ +#define USE_CONSOLE +#include +#else +#define USE_CONSOLE #include +#endif #define __TINES_PPU_INTERNAL__ @@ -200,7 +207,7 @@ void DebugSprites() #define GetTilePos(addr,x,y) (addr+x+(y*32)) -#define GetTileColor(tile,x1,y1) ( ( ppu_readMemory(((tile+y1)>>8)&0xFF, (tile+y1) & 0xFF) & (1<<(7-x1)) ) == 0 ? 0 : 1 ) | \ +#define GetTileColor(tile,x1,y1) ( ( ppu_readMemory(((tile+y1)>>8)&0xFF, (tile+y1) & 0xFF) & (1<<(7-x1)) ) == 0 ? 0 : 1 ) |\ ( ( ppu_readMemory(((tile+y1+8)>>8) & 0xFF, (tile+y1+8) &0xFF) & (1<<(7-x1)) ) == 0 ? 0 : 1<<1 ) #define PPU_Rd(addr) ppu_readMemory((addr>>8)&0xFF, addr&0xFF) diff --git a/src/ppu/oldppu.c b/src/ppu/oldppu.c index b4af09b..2dd0eaf 100755 --- a/src/ppu/oldppu.c +++ b/src/ppu/oldppu.c @@ -193,7 +193,7 @@ void PPU_Wr(unsigned short Addr, unsigned char Value) else if (Addr >= 0x3F00) { - //printf("%s palette: color %x new value : %d (0x%x)\n", (PalAddr(Addr) < 0x10) ? "Bgnd" : "Sprt", PalAddr(Addr), Value & 0x3F, Addr); + //console_printf(Console_Default, "%s palette: color %x new value : %d (0x%x)\n", (PalAddr(Addr) < 0x10) ? "Bgnd" : "Sprt", PalAddr(Addr), Value & 0x3F, Addr); ppu.Memory[ /* 0x3F00 | PalAddr(Addr) */ Addr] = Value & 0x3F; if (PalAddr(Addr) == 0x10) ppu.Memory[0x3F00] = Value & 0x3F; @@ -399,7 +399,7 @@ unsigned char XScroll, YScroll; clear_to_color(Buffer, BgColor); /* if (ppu.ControlRegister2.s.Colour != 0) - printf("ppu.ColorEmphasis : %d", ppu.ControlRegister2.s.Colour);*/ + console_printf(Console_Default, "ppu.ColorEmphasis : %d", ppu.ControlRegister2.s.Colour);*/ for (i = 0; i < 249; i++) @@ -657,7 +657,7 @@ frame start (line 0) (if background or sprites are enabled): v=t */ ppu.VRAMAddrReg2.W = ppu.TimedTmpPtr[0] | 0x2000; - //printf("Starting addresses : 0x%X\n",ppu.VRAMAddrReg2.W); + //console_printf(Console_Default, "Starting addresses : 0x%X\n",ppu.VRAMAddrReg2.W); XScroll = ppu.TimedHScroll[0]; @@ -982,7 +982,7 @@ t:0000 1100 0000 0000 = d:0000 0011 break; case 1: /* Control Register 2 */ - //printf("PPU: new CR2 ; 0x%x\n", val); + //console_printf(Console_Default, "PPU: new CR2 ; 0x%x\n", val); ppu.ControlRegister2.b = val; break; case 3: /* SPR-RAM Addresse Register */ @@ -1004,7 +1004,7 @@ x=d:00000111 ppu.TmpVRamPtr = ((ppu.TmpVRamPtr & 0xFFE0) | ((val & 0xF8) >> 3)); ppu.HScroll = val & 0x7; - //printf("%d -> 2005 w1: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); + //console_printf(Console_Default, "%d -> 2005 w1: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); } else { @@ -1019,9 +1019,9 @@ t:0111 0000 0000 0000=d:0000 0111 ppu.TmpVScroll = ((ppu.TmpVRamPtr & 0x700) >> 12) & 0x7; if (ppu.TmpVScroll != 0) - printf("2002: TmpVScroll == %d \n", ppu.TmpVScroll); + console_printf(Console_Default, "2002: TmpVScroll == %d \n", ppu.TmpVScroll); - //printf("%d -> 2005 w2: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); + //console_printf(Console_Default, "%d -> 2005 w2: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); } break; @@ -1036,7 +1036,7 @@ t:1100 0000 0000 0000=0 */ ppu.TmpVRamPtr = ((ppu.TmpVRamPtr & 0xC0FF) | ((val&0x3F) << 8)) & 0x3FFF; - //printf("%d -> 2006 w1: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); + //console_printf(Console_Default, "%d -> 2006 w1: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); } else { @@ -1049,7 +1049,7 @@ v=t ppu.TmpVRamPtr = ((ppu.TmpVRamPtr & 0xFF00) | (val & 0x00FF)); ppu.VRAMAddrReg2.W = ppu.TmpVRamPtr; - //printf("%d -> 2006 w2: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); + //console_printf(Console_Default, "%d -> 2006 w2: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); } break; diff --git a/src/ppu/ppu.24.c b/src/ppu/ppu.24.c index c89995e..b2f7666 100755 --- a/src/ppu/ppu.24.c +++ b/src/ppu/ppu.24.c @@ -249,7 +249,7 @@ void PPU_Wr(unsigned short Addr, unsigned char Value) else if (Addr >= 0x3F00) { - //printf("%s palette: color %x new value : %d (0x%x)\n", (PalAddr(Addr) < 0x10) ? "Bgnd" : "Sprt", PalAddr(Addr), Value & 0x3F, Addr); + //console_printf(Console_Default, "%s palette: color %x new value : %d (0x%x)\n", (PalAddr(Addr) < 0x10) ? "Bgnd" : "Sprt", PalAddr(Addr), Value & 0x3F, Addr); ppu.Memory[ /* 0x3F00 | PalAddr(Addr) */ Addr] = Value & 0x3F; if (PalAddr(Addr) == 0x10) ppu.Memory[0x3F00] = Value & 0x3F; @@ -290,7 +290,7 @@ void NewPPUDispSprite() if ((py > 0) && (py < 249) && ((++NbOfSprite[py]) > 7)) { ppu.StatusRegister.b |= PPU_FLAG_SR_8SPRT ; - //printf("%d Hohoho!\n", py); + //console_printf(Console_Default, "%d Hohoho!\n", py); // line(Buffer, 0, py+1, 256, py+1, 10); //continue; // Do not display more than 8 sprites on this line :p } @@ -824,7 +824,7 @@ unsigned char XScroll, YScroll; clear_to_color(Buffer, GetColor(BgColor)); if (ppu.ControlRegister2.s.Colour != 0) - printf("ppu.ColorEmphasis : %d\n", ppu.ControlRegister2.s.Colour); + console_printf(Console_Default, "ppu.ColorEmphasis : %d\n", ppu.ControlRegister2.s.Colour); for (i = 0; i < 249; i++) @@ -848,7 +848,7 @@ frame start (line 0) (if background or sprites are enabled): v=t */ ppu.VRAMAddrReg2.W = ppu.TimedTmpPtr[0] | 0x2000; - //printf("Starting addresses : 0x%X\n",ppu.VRAMAddrReg2.W); + //console_printf(Console_Default, "Starting addresses : 0x%X\n",ppu.VRAMAddrReg2.W); XScroll = ppu.TimedHScroll[0]; @@ -864,14 +864,14 @@ v:0000 0100 0001 1111=t:0000 0100 0001 1111 5432 10 */ //if (y == 142) - // printf("______________142 Ptr:0x%04X ____ 0x%04X\n", ppu.TimedTmpPtr[y], ppu.VRAMAddrReg2.W); + // console_printf(Console_Default, "______________142 Ptr:0x%04X ____ 0x%04X\n", ppu.TimedTmpPtr[y], ppu.VRAMAddrReg2.W); ppu.VRAMAddrReg2.W = (ppu.VRAMAddrReg2.W & 0xFBE0) | ((ppu.TimedTmpPtr[y]) & 0x041F) | 0x2000; //if (y == 142) - // printf("______________142 Ptr:0x%04X ____ 0x%04X\n", ppu.TimedTmpPtr[y], ppu.VRAMAddrReg2.W); + // console_printf(Console_Default, "______________142 Ptr:0x%04X ____ 0x%04X\n", ppu.TimedTmpPtr[y], ppu.VRAMAddrReg2.W); TileID = (PPU_Rd(ppu.VRAMAddrReg2.W) << 4) | ppu.Bg_Pattern_Table; @@ -1177,7 +1177,7 @@ void WritePPUReg(byte RegID, byte val) switch (RegID) { default:/* For not writeable reg */ - printf("WritePPU error\n"); + console_printf(Console_Default, "WritePPU error\n"); break; case 0: /* Control Register 1 */ ppu.ControlRegister1.b = val; @@ -1209,7 +1209,7 @@ t:0000 1100 0000 0000 = d:0000 0011 break; case 1: /* Control Register 2 */ - //printf("PPU: new CR2 ; 0x%x\n", val); + //console_printf(Console_Default, "PPU: new CR2 ; 0x%x\n", val); ppu.ControlRegister2.b = val; break; case 3: /* SPR-RAM Addresse Register */ @@ -1226,15 +1226,15 @@ t:0000 1100 0000 0000 = d:0000 0011 t:0000 0000 0001 1111=d:1111 1000 x=d:00000111 */ - //printf("2005[1st][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); + //console_printf(Console_Default, "2005[1st][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); ppu.VRAMAddrMode = 1; ppu.TmpVRamPtr = ((ppu.TmpVRamPtr & 0xFFE0) | ((val & 0xF8) >> 3)); ppu.HScroll = val & 0x7; - //printf("2005[1st][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); - //printf("%d -> 2005 w1: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); + //console_printf(Console_Default, "2005[1st][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); + //console_printf(Console_Default, "%d -> 2005 w1: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); } else { @@ -1249,25 +1249,25 @@ x=d:00000111 t:0000 0011 1110 0000=d:1111 1000 t:0111 0000 0000 0000=d:0000 0111 */ - //printf("2005[2nd][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); + //console_printf(Console_Default, "2005[2nd][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); ppu.VRAMAddrMode = 0; ppu.TmpVRamPtr = ((ppu.TmpVRamPtr & 0xFC1F) | ((val & 0xF8) << 2)); ppu.TmpVRamPtr = ((ppu.TmpVRamPtr & 0x8FFF) | ((val & 0x07) << 12)); ppu.TmpVScroll = (val & 0x7); //if (ppu.TmpVScroll != 0) - //printf("2002: TmpVScroll == %d \n", ppu.TmpVScroll); + //console_printf(Console_Default, "2002: TmpVScroll == %d \n", ppu.TmpVScroll); - //printf("2005[2nd][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); + //console_printf(Console_Default, "2005[2nd][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); - //printf("%d -> 2005 w2: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); + //console_printf(Console_Default, "%d -> 2005 w2: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); } break; case 6: /* VRAM Address register 2 */ if (ppu.VRAMAddrMode == 0) { - //printf("2006[1st][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); + //console_printf(Console_Default, "2006[1st][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); ppu.VRAMAddrMode = 1; /* 2006 first write: @@ -1275,13 +1275,13 @@ t:0011 1111 0000 0000 = d:0011 1111 t:1100 0000 0000 0000=0 */ ppu.TmpVRamPtr = ((ppu.TmpVRamPtr & 0xC0FF) | ((val&0x3F) << 8)) & 0x3FFF; - //printf("2006[1st][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); + //console_printf(Console_Default, "2006[1st][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); - //printf("%d -> 2006 w1: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); + //console_printf(Console_Default, "%d -> 2006 w1: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); } else { - //printf("2006[2nd][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); + //console_printf(Console_Default, "2006[2nd][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); ppu.VRAMAddrMode = 0; /* 2006 second write: @@ -1290,8 +1290,8 @@ v=t */ ppu.TmpVRamPtr = ((ppu.TmpVRamPtr & 0xFF00) | (val & 0x00FF)); ppu.VRAMAddrReg2.W = ppu.TmpVRamPtr; - //printf("2006[2nd][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); - //printf("%d -> 2006 w2: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); + //console_printf(Console_Default, "2006[2nd][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); + //console_printf(Console_Default, "%d -> 2006 w2: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); } break; diff --git a/src/ppu/ppu.c b/src/ppu/ppu.c index 166e146..eb398e5 100755 --- a/src/ppu/ppu.c +++ b/src/ppu/ppu.c @@ -14,7 +14,15 @@ * */ +/* Allegro includes */ +#ifdef __APPLE__ +#define USE_CONSOLE +#include +#else +#define USE_CONSOLE #include +#endif + #include #include @@ -23,28 +31,14 @@ #include #include -#include - #include +#include + #define __TINES_PLUGINS__ #include -#if ISPAL && !ISNTSC -//#define VBLANK_TIME 70 extern int VBLANK_TIME; -#elif !ISPAL && ISNTSC -//#define VBLANK_TIME 20 -extern int VBLANK_TIME; -#else -#error Cannot use ISPAL with ISNTSC together ! -#endif - -#ifdef NO_N_KEY -#define IF_N_KEY if (!key[KEY_N]) -#else -#define IF_N_KEY if (key[KEY_N]) -#endif extern BITMAP *Buffer; @@ -209,7 +203,7 @@ int ppu_init() if (!ppu_mem_paletteValues) return -1; - printf("ppu_mem_nameTables :%p\n" + console_printf(Console_Default, "ppu_mem_nameTables :%p\n" "ppu_mem_patternTables:%p\n" "ppu_mem_paletteValues:%p\n", ppu_mem_nameTables, @@ -238,9 +232,6 @@ int ppu_init() //memcpy(ppu_mem_paletteValues, defaultColors, 32); - /* Dump PPU memory state */ - //ppu_memoryDumpState(stdout); - /* Set some other variables */ ppu_VramAccessFlipFlop = 0; @@ -270,12 +261,6 @@ int ppu_init() for(i = 0x21; i < 0x40; i++) set_page_ghost(i, true, 0x20); -// plugin_install_keypressHandler('i', ppu_debugSprites); -// plugin_install_keypressHandler('I', ppu_debugSprites); - -// plugin_install_keypressHandler('u', ppu_debugColor); -// plugin_install_keypressHandler('U', ppu_debugColor); - /* allocate the PPU Video memory */ VideoBuffer = create_bitmap(256, 240); @@ -322,7 +307,6 @@ void ppu_updateSpriteScanlineTable() else { PPU_NbSpriteByScanLineOverFlow[curline] = 1; - //printf("sprite of: %u - %u\n", curline, PPU_NbSpriteByScanLine[curline]); continue; /* We have 8 sprite in this line, don't continue */ } if (((sprite_x+8) < 0) && ((sprite_x-8) > 256)) @@ -342,18 +326,12 @@ void ppu_updateSpriteScanlineTable() PPU_SpriteByScanLine[curline][j] = 0; PPU_SCANLINESPRITE_SET_ATTRS (PPU_SpriteByScanLine[curline][j], sprite_attr); - //printf("new sprite [%02X:%02X:%02X:%02X] at sl:%d : 0x%08X ", - //sprite_attr, sprite_idx, curline - sprite_x, sprite_y, - //curline, PPU_SpriteByScanLine[curline][j]); - + PPU_SCANLINESPRITE_SET_TILIDX(PPU_SpriteByScanLine[curline][j], sprite_idx); - //printf("- 0x%08X ", PPU_SpriteByScanLine[curline][j]); - + PPU_SCANLINESPRITE_SET_RELY (PPU_SpriteByScanLine[curline][j], curline - sprite_y); - //printf("- 0x%08X ", PPU_SpriteByScanLine[curline][j]); - + PPU_SCANLINESPRITE_SET_X (PPU_SpriteByScanLine[curline][j], sprite_x); - //printf("- 0x%08X\n", PPU_SpriteByScanLine[curline][j]); break; /* Stop the for, we don't need to go further in the line list */ } @@ -377,14 +355,12 @@ void ppu_setMirroring(byte direction) ppu_mirrorMode = direction; case PPU_MIRROR_HORIZTAL: /* Horizontal */ - //printf("Set mirror to Hor\n"); ppu_setPagePtr1k(0x20, ppu_mem_nameTables + 0x000); ppu_setPagePtr1k(0x24, ppu_mem_nameTables + 0x000); ppu_setPagePtr1k(0x28, ppu_mem_nameTables + 0x400); ppu_setPagePtr1k(0x2C, ppu_mem_nameTables + 0x400); break; case PPU_MIRROR_VERTICAL: /* Vertical */ - //printf("Set mirror to Ver\n"); ppu_setPagePtr1k(0x20, ppu_mem_nameTables + 0x000); ppu_setPagePtr1k(0x24, ppu_mem_nameTables + 0x400); ppu_setPagePtr1k(0x28, ppu_mem_nameTables + 0x000); @@ -408,7 +384,6 @@ void ppu_setSingleScreen(byte screen) ppu_singleScreenMode = screen; case PPU_SCREEN_000: /* 0x2000 */ - //printf("Set screen to 0x000\n"); ppu_setPagePtr1k(0x20, ppu_mem_nameTables + 0x000); ppu_setPagePtr1k(0x24, ppu_mem_nameTables + 0x000); ppu_setPagePtr1k(0x28, ppu_mem_nameTables + 0x000); @@ -416,7 +391,6 @@ void ppu_setSingleScreen(byte screen) break; case PPU_SCREEN_400: /* 0x2400 */ - //printf("Set screen to 0x400\n"); ppu_setPagePtr1k(0x20, ppu_mem_nameTables + 0x400); ppu_setPagePtr1k(0x24, ppu_mem_nameTables + 0x400); ppu_setPagePtr1k(0x28, ppu_mem_nameTables + 0x400); @@ -424,7 +398,6 @@ void ppu_setSingleScreen(byte screen) break; case PPU_SCREEN_800: /* 0x2800 */ - //printf("Set screen to 0x800\n"); ppu_setPagePtr1k(0x20, ppu_mem_nameTables + 0x800); ppu_setPagePtr1k(0x24, ppu_mem_nameTables + 0x800); ppu_setPagePtr1k(0x28, ppu_mem_nameTables + 0x800); @@ -432,7 +405,6 @@ void ppu_setSingleScreen(byte screen) break; case PPU_SCREEN_C00: /* 0x2C00 */ - //printf("Set screen to 0xC00\n"); ppu_setPagePtr1k(0x20, ppu_mem_nameTables + 0xC00); ppu_setPagePtr1k(0x24, ppu_mem_nameTables + 0xC00); ppu_setPagePtr1k(0x28, ppu_mem_nameTables + 0xC00); @@ -456,7 +428,6 @@ void ppu_setScreenMode(byte mode) switch(mode) { case PPU_SCMODE_SINGLE: /* Single screen (1 NT with mirroring) */ - //printf("Set Single Screen\n"); ppu_setSingleScreen(~ppu_singleScreenMode); break; @@ -465,12 +436,10 @@ void ppu_setScreenMode(byte mode) ppu_screenMode = mode; case PPU_SCMODE_NORMAL: /* Normal screen (2 NT with mirroring) */ - //printf("Set Normal Screen\n"); ppu_setMirroring(~ppu_mirrorMode); break; case PPU_SCMODE_FOURSC: /* Four screen (4 NT withou mirroring) */ - //printf("Set Four Screen\n"); ppu_setPagePtr1k(0x20, ppu_mem_nameTables + 0x000); ppu_setPagePtr1k(0x24, ppu_mem_nameTables + 0x400); ppu_setPagePtr1k(0x28, ppu_mem_nameTables + 0x800); @@ -479,11 +448,6 @@ void ppu_setScreenMode(byte mode) } } -void ppu_setSprite(unsigned short i, PPU_Sprite *sprt) -{ - -} - /* update whole counters */ void ppu_updateCounters() { @@ -509,12 +473,8 @@ _AAA BCDD DDDE EEEE PPU_Reg_Counter |= PPU_Reg_H << 10; PPU_Reg_Counter |= PPU_Reg_VT << 5; PPU_Reg_Counter |= PPU_Reg_HT; - - IF_N_KEY printf("Counter update to %04X\n",PPU_Reg_Counter); } -extern M6502 MainCPU; - int ppu_hblank(int scanline) { int i, j; @@ -527,13 +487,10 @@ int ppu_hblank(int scanline) unsigned short tmp_VVTFV = 0; unsigned long CurrentSprite; byte SpriteVFlip; - - /* If no plan activated, we have nothing to do ! */ - + if (scanline == 0) { ppu_bgColor = ppu_readMemory(0x3F,00); - clear_to_color(VideoBuffer, ppu_bgColor); if ((ppu_spriteVisibility != 0) || (ppu_backgroundVisibility != 0)) ppu_updateCounters(); @@ -629,7 +586,6 @@ int ppu_hblank(int scanline) else addr = (((PPU_SCANLINESPRITE_GET_TILIDX(CurrentSprite)&0xFE) + (SpriteVFlip?0:1)) << 4) + ((PPU_SCANLINESPRITE_GET_TILIDX(CurrentSprite)&0x01)?0x1000:0x0000); } - //printf("sprite addr: %04X\n", addr); if (SpriteVFlip) { addr += 7; @@ -674,13 +630,14 @@ int ppu_hblank(int scanline) } } } - - + + /* Set to monochrome if needed */ + if (ppu_displayType) + pixelColor &= 0x30; + /* draw the pixel */ - /*if (ppu_displayType) - pixelColor &= 0x30;*/ _putpixel(VideoBuffer, i, scanline, pixelColor); - } + } if (ppu_backgroundVisibility || ppu_spriteVisibility) if (PPU_NbSpriteByScanLineOverFlow[scanline] == 1) @@ -695,24 +652,19 @@ int ppu_hblank(int scanline) tmp_VVTFV = ((PPU_Reg_Counter >> 3 ) & 0x0100) | /* V */ ((PPU_Reg_Counter >> 2 ) & 0x00F8) | /* VT */ ((PPU_Reg_Counter >> 12) & 0x0007); /* FV */ - //printf("counter:%04X vvtfv:%04X ", PPU_Reg_Counter, tmp_VVTFV); tmp_VVTFV++; - //printf("__ vvtfv:0x%04X == 0x%04X ? ", tmp_VVTFV, 30<<3); if ((tmp_VVTFV&0x0F8) == 0xF0) { tmp_VVTFV &= ~0x0F8; tmp_VVTFV ^= 0x100; - //printf("YES _"); } - //printf("vvtfv:%04X ", tmp_VVTFV); PPU_Reg_Counter = ( PPU_Reg_Counter & 0x041F) | ((tmp_VVTFV & 0x0100 ) << 3 ) | /* V */ ((tmp_VVTFV & 0x00F8 ) << 2 ) | /* VT */ ((tmp_VVTFV & 0x0007 ) << 12); /* FV */ - //printf("counter:%04X ", PPU_Reg_Counter); /* Update H & HT */ PPU_Reg_Counter = (PPU_Reg_Counter & ~0x041F) | (PPU_Reg_H << 10) | @@ -720,7 +672,6 @@ int ppu_hblank(int scanline) } } /* Increment only V & VT & FV*/ - /* 8421 8421 8421 8421 @@ -745,8 +696,13 @@ E = HT */ if (scanline == 239) { - ppu_inVBlankTime = 1; - IF_N_KEY printf("============= enter vblank =================\n"); + 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)); + + blit(VideoBuffer, Buffer, 0, 0, 0, 0, 256, 240); + blit(Buffer, screen, 0, 0, 0, 0, 512+256, 512); + return ppu_execNMIonVBlank; } @@ -757,37 +713,11 @@ E = HT } - if (scanline >= (240 + VBLANK_TIME - 1)) + if (scanline == (239 + VBLANK_TIME)) { - /*for ( i = 0; i < 256; i++) - for ( j = 0; j < 256; j++) - { - int i2 = i<<1, j2 = j<<1; - putpixel(Buffer, i2 , j2 , Op6502(i+j*256)); - putpixel(Buffer, i2 , j2+1, Op6502(i+j*256)); - putpixel(Buffer, i2+1, j2 , Op6502(i+j*256)); - // putpixel(Buffer, i2+1, j2+1, Op6502(i+j*256)); - }*/ - - //textprintf(Buffer, font, 5, 340, 4, "(SL:%d) FPS : %d IPS : %d", scanline, FPS, IPS); - textprintf(Buffer, font, 260, 3, 4, "FPS : %d (CPU@~%2.2fMhz : %d%%)", FPS, (float) (((float) IPS) / 1000000.0), (int) ((((float) IPS) / 1770000.0) * 100.0)); - //printf("(SL:%d) FPS : %d IPS : %d\n", scanline, FPS, IPS); - - //ppu_dumpPalette(0, 241); - //ppu_dumpPattern(280, 150); - //ppu_dumpNameTable(256,0); - //ppu_dumpAttributeTable(257, 0); - - blit(VideoBuffer, Buffer, 0, 0, 0, 0, 256, 240); - blit(Buffer, screen, 0, 0, 0, 0, 512+256, 512); - //blit(VideoBuffer, screen, 0, 0, 0, 0, 256, 240); - - - IF_N_KEY printf("_____________ leave vblank _________________\n"); ppu_inVBlankTime = 0; ppu_spriteZeroHit = 0; ppu_scanlineSpriteOverflow = 0; - //ppu_updateCounters(); } return 0; } @@ -803,7 +733,6 @@ byte ppu_readReg(byte id) { default: garbage = PPU_RegValues[id]; - printf("%s: try to read 0x20%02X\n", __func__, id); break; case 0x02: /* PPU Status Register */ @@ -814,9 +743,6 @@ byte ppu_readReg(byte id) garbage |= (ppu_inVBlankTime!=0) ?PPU_FLAG_SR_VBLANK:0; garbage |= (ppu_spriteZeroHit!=0) ?PPU_FLAG_SR_SPRT0:0; garbage |= (ppu_scanlineSpriteOverflow!=0)?PPU_FLAG_SR_8SPRT:0; - /*garbage ^= PPU_FLAG_SR_RDWRALLOW;*/ - - IF_N_KEY printf("%s() = %02X\n", __func__, garbage); ppu_inVBlankTime = 0; break; @@ -844,7 +770,6 @@ byte ppu_readReg(byte id) break; } - //printf("ppuread %02X return: %02X\n", id, garbage); return garbage; } @@ -852,12 +777,10 @@ byte ppu_readReg(byte id) void ppu_writeReg(byte id, byte val) { id &= 0x07; - //printf("ppuwrte %02X val: %02X\n", id, val); PPU_RegValues[id] = val; switch(id) { default: - //printf("%s: try to write 0x%02X @ 0x20%02X\n", __func__, val, id); break; case 0x00: /* PPU Control Register #1 */ @@ -872,18 +795,6 @@ void ppu_writeReg(byte id, byte val) | |+===++=++=++=====++=====+ | +---------------+-----------------------------------------------+ */ - IF_N_KEY - printf("%s(%02X, %02X); /* 2000: " - "NMI:%c SPRTSIZE:%02d BGTA:%04X[0x%04X] SPTA:%04X INC:%02d NTA:%04X */\n", - __func__, id, val, - (val & 0x80)?'E':'D', - (val & 0x20)?16:8, - (val & 0x10)?0x1000:0x0000, PPU_Reg_S, - (val & 0x08)?0x1000:0x0000, - (val & 0x04)?32:1, - (val & 0x03)<<10|0x2000 - ); - /* Set PPU internal registers */ PPU_Reg_V = (val & 0x02)?1:0; PPU_Reg_H = (val & 0x01)?1:0; @@ -905,17 +816,6 @@ void ppu_writeReg(byte id, byte val) ppu_displayType = (val & 0x01)?1:0; ppu_updateSpriteScanlineTable(); - - IF_N_KEY - printf("%s(%02X, %02X); /* 2001 : " - "SprtV:%c BckgV:%c SprtC:%c BckgC:%c DispT:%c" - " */\n", __func__, id, val, - ppu_spriteVisibility?'y':'n', - ppu_backgroundVisibility?'y':'n', - ppu_spriteClipping?'y':'n', - ppu_backgroundClipping?'y':'n', - ppu_displayType?'m':'c' - ); break; case 0x03: /* SPR-RAM Address Register */ @@ -945,8 +845,6 @@ void ppu_writeReg(byte id, byte val) PPU_Reg_FH = val & 0x07; PPU_Reg_HT = (val & 0xF8) >> 3; - IF_N_KEY - printf("2005/1[%04X]: fv:%01X v:%01X h:%01X vt:%01X ht:%01X fh:%01X\n",val,PPU_Reg_FV,PPU_Reg_V,PPU_Reg_H,PPU_Reg_VT,PPU_Reg_HT,PPU_Reg_FH); } else { @@ -954,8 +852,6 @@ void ppu_writeReg(byte id, byte val) PPU_Reg_FV = val & 0x07; PPU_Reg_VT = (val & 0xF8) >> 3; - IF_N_KEY - printf("2005/2[%04X]: fv:%01X v:%01X h:%01X vt:%01X ht:%01X fh:%01X\n",val,PPU_Reg_FV,PPU_Reg_V,PPU_Reg_H,PPU_Reg_VT,PPU_Reg_HT,PPU_Reg_FH); } break; @@ -980,8 +876,6 @@ void ppu_writeReg(byte id, byte val) PPU_Reg_V = (val >> 3) & 0x01; PPU_Reg_H = (val >> 2) & 0x01; PPU_Reg_VT = (PPU_Reg_VT & 0x07) | ((val & 0x03) << 3); - IF_N_KEY - printf("2006/1[%04X]: fv:%01X v:%01X h:%01X vt:%01X ht:%01X fh:%01X\n",val,PPU_Reg_FV,PPU_Reg_V,PPU_Reg_H,PPU_Reg_VT,PPU_Reg_HT,PPU_Reg_FH); } else { @@ -989,9 +883,6 @@ void ppu_writeReg(byte id, byte val) PPU_Reg_VT = (PPU_Reg_VT & 0x18) | ((val >> 5) & 0x07); PPU_Reg_HT = val & 0x1F; - IF_N_KEY - printf("2006/2[%04X]: fv:%01X v:%01X h:%01X vt:%01X ht:%01X fh:%01X\n",val,PPU_Reg_FV,PPU_Reg_V,PPU_Reg_H,PPU_Reg_VT,PPU_Reg_HT,PPU_Reg_FH); - ppu_updateCounters(); } @@ -1009,25 +900,7 @@ void ppu_writeReg(byte id, byte val) +===============+===============================================+ */ - - - //if ( (PPU_Reg_Counter&0xFF00) == 0x3F00) - //{ - // printf("fv:%01X v:%01X h:%01X vt:%01X ht:%01X fh:%01X\n",PPU_Reg_FV,PPU_Reg_V,PPU_Reg_H,PPU_Reg_VT,PPU_Reg_HT,PPU_Reg_FH); - // printf("will write ppu: counter:%04X pa:%02X%02X v:%02X\n", - // PPU_Reg_Counter, (PPU_Reg_Counter>>8) & 0x3F, PPU_Reg_Counter & 0xFF, val); - // } - ppu_writeMemory((PPU_Reg_Counter>>8) & 0x3F, PPU_Reg_Counter & 0xFF, val); - - IF_N_KEY - { - ppu_dumpPalette(0, 241); - ppu_dumpPattern(280, 150); - ppu_dumpNameTable(256,0); - blit(Buffer, screen, 0, 0, 0, 0, 512 + 256, 480); - } - PPU_Reg_Counter += ppu_addrIncrement; break; @@ -1042,6 +915,5 @@ void ppu_fillSprRamDMA(byte value) { ppu_mem_spritesTable[(ppu_mem_sptrTablePtr + i)&0xFF] = *(ptr+i); } - //memcpy(ppu_mem_spritesTable, ptr, 0xFF); ppu_updateSpriteScanlineTable(); } diff --git a/src/ppu/ppu.memory.c b/src/ppu/ppu.memory.c index 774ffcf..fdb2f61 100644 --- a/src/ppu/ppu.memory.c +++ b/src/ppu/ppu.memory.c @@ -15,9 +15,11 @@ #include #include +#include + #define __TINES_PPU_INTERNAL__ -#include +#include #include #include @@ -120,7 +122,7 @@ void ppu_setPageGhost(byte page, bool value, byte ghost) { ppu_memoryPages[page] = ppu_memoryPages[ghost]; ppu_memoryGhostLink[ghost] = page; - printf("set ghost of 0x%02X to 0x%02X (ptr: %p)\n", ghost, page, ppu_memoryGhostLink[ghost]); + console_printf(Console_Default, "set ghost of 0x%02X to 0x%02X (ptr: %p)\n", ghost, page, &(ppu_memoryGhostLink[ghost])); } } @@ -155,7 +157,7 @@ void ppu_writeMemory(byte page, byte addr, byte value) { /* Here we will cheat with the palette miroring, since we didn't write as often as we read the palette, we will mirror here */ - //printf("%s palette: color %02X new value : %02d (0x%02X%02X)\n", ((addr&0x10)< 0x10) ? "Bgnd" : "Sprt", addr&0x1F, value & 0x3F, page, addr); + //console_printf(Console_Default, "%s palette: color %02X new value : %02d (0x%02X%02X)\n", ((addr&0x10)< 0x10) ? "Bgnd" : "Sprt", addr&0x1F, value & 0x3F, page, addr); if ((addr & 0xEF) == 0x00) { ppu_memoryPages[0x3F][0x00] = value; diff --git a/src/ppu/ppu.new.c b/src/ppu/ppu.new.c index dc00ebc..adf31dc 100755 --- a/src/ppu/ppu.new.c +++ b/src/ppu/ppu.new.c @@ -219,7 +219,7 @@ void PPU_Wr(unsigned short Addr, unsigned char Value) else if (Addr >= 0x3F00) { - //printf("%s palette: color %x new value : %d (0x%x)\n", (PalAddr(Addr) < 0x10) ? "Bgnd" : "Sprt", PalAddr(Addr), Value & 0x3F, Addr); + //console_printf(Console_Default, "%s palette: color %x new value : %d (0x%x)\n", (PalAddr(Addr) < 0x10) ? "Bgnd" : "Sprt", PalAddr(Addr), Value & 0x3F, Addr); ppu.Memory[ /* 0x3F00 | PalAddr(Addr) */ Addr] = Value & 0x3F; if (PalAddr(Addr) == 0x10) ppu.Memory[0x3F00] = Value & 0x3F; @@ -260,7 +260,7 @@ void NewPPUDispSprite() if ((py > 0) && (py < 249) && ((++NbOfSprite[py]) > 7)) { ppu.StatusRegister.b |= PPU_FLAG_SR_8SPRT ; - //printf("%d Hohoho!\n", py); + //console_printf(Console_Default, "%d Hohoho!\n", py); // line(Buffer, 0, py+1, 256, py+1, 10); //continue; // Do not display more than 8 sprites on this line :p } @@ -551,7 +551,7 @@ struct timeval timeStart, timeEnd; clear_to_color(Buffer, BgColor); /* if (ppu.ControlRegister2.s.Colour != 0) - printf("ppu.ColorEmphasis : %d", ppu.ControlRegister2.s.Colour);*/ + console_printf(Console_Default, "ppu.ColorEmphasis : %d", ppu.ControlRegister2.s.Colour);*/ for (i = 0; i < 249; i++) @@ -809,7 +809,7 @@ frame start (line 0) (if background or sprites are enabled): v=t */ ppu.VRAMAddrReg2.W = ppu.TimedTmpPtr[0] | 0x2000; - //printf("Starting addresses : 0x%X\n",ppu.VRAMAddrReg2.W); + //console_printf(Console_Default, "Starting addresses : 0x%X\n",ppu.VRAMAddrReg2.W); XScroll = ppu.TimedHScroll[0]; @@ -836,13 +836,13 @@ v:0000 0100 0001 1111=t:0000 0100 0001 1111 XScroll = ppu.TimedHScroll[y]; /*YScroll += ppu.TimedVScroll[y];*/ -/* printf("Y:%d -_- ", YScroll); +/* console_printf(Console_Default, "Y:%d -_- ", YScroll); if (ppu.TimedVScroll[y] != 0) { YScroll = ppu.TimedVScroll[y]; - printf("Y:%d", YScroll); + console_printf(Console_Default, "Y:%d", YScroll); } - printf("\n");*/ + console_printf(Console_Default, "\n");*/ for (x = 0; x < 256; x++) { /* Calculer la couleur du point */ @@ -1068,7 +1068,7 @@ NoDraw: TimeStart = 1000000 * timeStart.tv_sec + timeStart.tv_usec; TimeEnd = 1000000 * timeEnd.tv_sec + timeEnd.tv_usec; - //printf("Start: %d\nEnd: %d\nResult: %d\n",TimeStart, TimeEnd, 16666 - (TimeEnd - TimeStart)); + //console_printf(Console_Default, "Start: %d\nEnd: %d\nResult: %d\n",TimeStart, TimeEnd, 16666 - (TimeEnd - TimeStart)); WaitTime = 14000 - (TimeEnd - TimeStart); if (!key[KEY_PGUP]) usleep(WaitTime<0?0:WaitTime); @@ -1138,7 +1138,7 @@ void WritePPUReg(byte RegID, byte val) switch (RegID) { default:/* For not writeable reg */ - printf("WritePPU error\n"); + console_printf(Console_Default, "WritePPU error\n"); break; case 0: /* Control Register 1 */ ppu.ControlRegister1.b = val; @@ -1170,7 +1170,7 @@ t:0000 1100 0000 0000 = d:0000 0011 break; case 1: /* Control Register 2 */ - //printf("PPU: new CR2 ; 0x%x\n", val); + //console_printf(Console_Default, "PPU: new CR2 ; 0x%x\n", val); ppu.ControlRegister2.b = val; break; case 3: /* SPR-RAM Addresse Register */ @@ -1192,7 +1192,7 @@ x=d:00000111 ppu.TmpVRamPtr = ((ppu.TmpVRamPtr & 0xFFE0) | ((val & 0xF8) >> 3)); ppu.HScroll = val & 0x7; - //printf("%d -> 2005 w1: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); + //console_printf(Console_Default, "%d -> 2005 w1: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); } else { @@ -1207,9 +1207,9 @@ t:0111 0000 0000 0000=d:0000 0111 ppu.TmpVScroll = ((ppu.TmpVRamPtr & 0x700) >> 12) & 0x7; if (ppu.TmpVScroll != 0) - printf("2002: TmpVScroll == %d \n", ppu.TmpVScroll); + console_printf(Console_Default, "2002: TmpVScroll == %d \n", ppu.TmpVScroll); - //printf("%d -> 2005 w2: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); + //console_printf(Console_Default, "%d -> 2005 w2: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); } break; @@ -1224,7 +1224,7 @@ t:1100 0000 0000 0000=0 */ ppu.TmpVRamPtr = ((ppu.TmpVRamPtr & 0xC0FF) | ((val&0x3F) << 8)) & 0x3FFF; - //printf("%d -> 2006 w1: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); + //console_printf(Console_Default, "%d -> 2006 w1: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); } else { @@ -1237,7 +1237,7 @@ v=t ppu.TmpVRamPtr = ((ppu.TmpVRamPtr & 0xFF00) | (val & 0x00FF)); ppu.VRAMAddrReg2.W = ppu.TmpVRamPtr; - //printf("%d -> 2006 w2: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); + //console_printf(Console_Default, "%d -> 2006 w2: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); } break; diff --git a/src/ppu/ppu.new2.c b/src/ppu/ppu.new2.c index 6907e5f..a64db3a 100755 --- a/src/ppu/ppu.new2.c +++ b/src/ppu/ppu.new2.c @@ -249,7 +249,7 @@ void PPU_Wr(unsigned short Addr, unsigned char Value) else if (Addr >= 0x3F00) { - //printf("%s palette: color %x new value : %d (0x%x)\n", (PalAddr(Addr) < 0x10) ? "Bgnd" : "Sprt", PalAddr(Addr), Value & 0x3F, Addr); + //console_printf(Console_Default, "%s palette: color %x new value : %d (0x%x)\n", (PalAddr(Addr) < 0x10) ? "Bgnd" : "Sprt", PalAddr(Addr), Value & 0x3F, Addr); ppu.Memory[ /* 0x3F00 | PalAddr(Addr) */ Addr] = Value & 0x3F; if (PalAddr(Addr) == 0x10) ppu.Memory[0x3F00] = Value & 0x3F; @@ -290,7 +290,7 @@ void NewPPUDispSprite() if ((py > 0) && (py < 249) && ((++NbOfSprite[py]) > 7)) { ppu.StatusRegister.b |= PPU_FLAG_SR_8SPRT ; - //printf("%d Hohoho!\n", py); + //console_printf(Console_Default, "%d Hohoho!\n", py); // line(Buffer, 0, py+1, 256, py+1, 10); //continue; // Do not display more than 8 sprites on this line :p } @@ -827,7 +827,7 @@ unsigned char XScroll, YScroll; ppu_displayNameTables(); if (ppu.ControlRegister2.s.Colour != 0) - printf("ppu.ColorEmphasis : %d\n", ppu.ControlRegister2.s.Colour); + console_printf(Console_Default, "ppu.ColorEmphasis : %d\n", ppu.ControlRegister2.s.Colour); for (i = 0; i < 249; i++) @@ -851,7 +851,7 @@ frame start (line 0) (if background or sprites are enabled): v=t */ ppu.VRAMAddrReg2.W = ppu.TimedTmpPtr[0]|0x2000; - //printf("Starting addresses : 0x%X\n",ppu.VRAMAddrReg2.W); + //console_printf(Console_Default, "Starting addresses : 0x%X\n",ppu.VRAMAddrReg2.W); YScroll = ppu.TmpVScroll; @@ -865,7 +865,7 @@ v:0000 0100 0001 1111=t:0000 0100 0001 1111 5432 10 */ if ((y == IRQScanHit)||(y == IRQScanHit + 1)) - printf("%s: IRQ Hit : bf Reg2: 0x%04X\n", __func__, ppu.VRAMAddrReg2.W); + console_printf(Console_Default, "%s: IRQ Hit : bf Reg2: 0x%04X\n", __func__, ppu.VRAMAddrReg2.W); #define PPU_SSCAN_MASK 0x041F @@ -880,10 +880,10 @@ v:0000 0100 0001 1111=t:0000 0100 0001 1111 XScroll = ppu.TimedHScroll[y]; if (y == IRQScanHit) - printf("%s: IRQ Hit : Reg2: 0x%04X TmpPtr:0x%04X \n", __func__, ppu.VRAMAddrReg2.W, ppu.TimedTmpPtr[y]); + console_printf(Console_Default, "%s: IRQ Hit : Reg2: 0x%04X TmpPtr:0x%04X \n", __func__, ppu.VRAMAddrReg2.W, ppu.TimedTmpPtr[y]); if (y == IRQScanHit + 1) - printf("%s: IRQ Hit + 1: Reg2: 0x%04X TmpPtr:0x%04X \n", __func__, ppu.VRAMAddrReg2.W, ppu.TimedTmpPtr[y]); + console_printf(Console_Default, "%s: IRQ Hit + 1: Reg2: 0x%04X TmpPtr:0x%04X \n", __func__, ppu.VRAMAddrReg2.W, ppu.TimedTmpPtr[y]); for (x = 0; x < 256; x++) @@ -1194,7 +1194,7 @@ void WritePPUReg(byte RegID, byte val) switch (RegID) { default:/* For not writeable reg */ - printf("WritePPU error\n"); + console_printf(Console_Default, "WritePPU error\n"); break; case 0: /* Control Register 1 */ ppu.ControlRegister1.b = val; @@ -1226,7 +1226,7 @@ t:0000 1100 0000 0000 = d:0000 0011 break; case 1: /* Control Register 2 */ - //printf("PPU: new CR2 ; 0x%x\n", val); + //console_printf(Console_Default, "PPU: new CR2 ; 0x%x\n", val); ppu.ControlRegister2.b = val; break; case 3: /* SPR-RAM Addresse Register */ @@ -1243,15 +1243,15 @@ t:0000 1100 0000 0000 = d:0000 0011 t:0000 0000 0001 1111=d:1111 1000 x=d:00000111 */ - //printf("2005[1st][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); + //console_printf(Console_Default, "2005[1st][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); ppu.VRAMAddrMode = 1; ppu.TmpVRamPtr = ((ppu.TmpVRamPtr & 0xFFE0) | ((val & 0xF8) >> 3)); ppu.HScroll = val & 0x7; - //printf("2005[1st][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); - //printf("%d -> 2005 w1: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); + //console_printf(Console_Default, "2005[1st][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); + //console_printf(Console_Default, "%d -> 2005 w1: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); } else { @@ -1266,25 +1266,25 @@ x=d:00000111 t:0000 0011 1110 0000=d:1111 1000 t:0111 0000 0000 0000=d:0000 0111 */ - //printf("2005[2nd][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); + //console_printf(Console_Default, "2005[2nd][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); ppu.VRAMAddrMode = 0; ppu.TmpVRamPtr = ((ppu.TmpVRamPtr & ~(0x03E0)) | ((val & 0xF8) << 2)); ppu.TmpVRamPtr = ((ppu.TmpVRamPtr & 0x8FFF ) | ((val & 0x07) << 12)); ppu.TmpVScroll = (val & 0x7); //if (ppu.TmpVScroll != 0) - //printf("2002: TmpVScroll == %d \n", ppu.TmpVScroll); + //console_printf(Console_Default, "2002: TmpVScroll == %d \n", ppu.TmpVScroll); - //printf("2005[2nd][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); + //console_printf(Console_Default, "2005[2nd][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); - //printf("%d -> 2005 w2: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); + //console_printf(Console_Default, "%d -> 2005 w2: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); } break; case 6: /* VRAM Address register 2 */ if (ppu.VRAMAddrMode == 0) { - //printf("2006[1st][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); + //console_printf(Console_Default, "2006[1st][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); ppu.VRAMAddrMode = 1; /* 2006 first write: @@ -1292,13 +1292,13 @@ t:0011 1111 0000 0000 = d:0011 1111 t:1100 0000 0000 0000=0 */ ppu.TmpVRamPtr = ((ppu.TmpVRamPtr & 0x00FF) | ((val&0x3F) << 8)); - //printf("2006[1st][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); + //console_printf(Console_Default, "2006[1st][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); - //printf("%d -> 2006 w1: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); + //console_printf(Console_Default, "%d -> 2006 w1: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); } else { - //printf("2006[2nd][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); + //console_printf(Console_Default, "2006[2nd][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); ppu.VRAMAddrMode = 0; /* 2006 second write: @@ -1307,8 +1307,8 @@ v=t */ ppu.TmpVRamPtr = ((ppu.TmpVRamPtr & 0xFF00) | (val & 0x00FF)); ppu.VRAMAddrReg2.W = ppu.TmpVRamPtr; - //printf("2006[2nd][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); - //printf("%d -> 2006 w2: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); + //console_printf(Console_Default, "2006[2nd][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); + //console_printf(Console_Default, "%d -> 2006 w2: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); } break; diff --git a/src/ppu/ppu.old.c b/src/ppu/ppu.old.c index c9d478d..aa58b74 100755 --- a/src/ppu/ppu.old.c +++ b/src/ppu/ppu.old.c @@ -231,7 +231,7 @@ void PPU_Wr(unsigned short Addr, unsigned char Value) else if (Addr >= 0x3F00) { - //printf("%s palette: color %x new value : %d (0x%x)\n", (PalAddr(Addr) < 0x10) ? "Bgnd" : "Sprt", PalAddr(Addr), Value & 0x3F, Addr); + //console_printf(Console_Default, "%s palette: color %x new value : %d (0x%x)\n", (PalAddr(Addr) < 0x10) ? "Bgnd" : "Sprt", PalAddr(Addr), Value & 0x3F, Addr); ppu.Memory[ /* 0x3F00 | PalAddr(Addr) */ Addr] = Value & 0x3F; if (PalAddr(Addr) == 0x10) ppu.Memory[0x3F00] = Value & 0x3F; @@ -272,7 +272,7 @@ void NewPPUDispSprite() if ((py > 0) && (py < 249) && ((++NbOfSprite[py]) > 7)) { ppu.StatusRegister.b |= PPU_FLAG_SR_8SPRT ; - //printf("%d Hohoho!\n", py); + //console_printf(Console_Default, "%d Hohoho!\n", py); // line(Buffer, 0, py+1, 256, py+1, 10); //continue; // Do not display more than 8 sprites on this line :p } @@ -806,7 +806,7 @@ unsigned char XScroll, YScroll; clear_to_color(Buffer, BgColor); /* if (ppu.ControlRegister2.s.Colour != 0) - printf("ppu.ColorEmphasis : %d", ppu.ControlRegister2.s.Colour);*/ + console_printf(Console_Default, "ppu.ColorEmphasis : %d", ppu.ControlRegister2.s.Colour);*/ for (i = 0; i < 249; i++) @@ -830,7 +830,7 @@ frame start (line 0) (if background or sprites are enabled): v=t */ ppu.VRAMAddrReg2.W = ppu.TimedTmpPtr[0] | 0x2000; - //printf("Starting addresses : 0x%X\n",ppu.VRAMAddrReg2.W); + //console_printf(Console_Default, "Starting addresses : 0x%X\n",ppu.VRAMAddrReg2.W); XScroll = ppu.TimedHScroll[0]; @@ -846,14 +846,14 @@ v:0000 0100 0001 1111=t:0000 0100 0001 1111 5432 10 */ //if (y == 142) - // printf("______________142 Ptr:0x%04X ____ 0x%04X\n", ppu.TimedTmpPtr[y], ppu.VRAMAddrReg2.W); + // console_printf(Console_Default, "______________142 Ptr:0x%04X ____ 0x%04X\n", ppu.TimedTmpPtr[y], ppu.VRAMAddrReg2.W); ppu.VRAMAddrReg2.W = (ppu.VRAMAddrReg2.W & 0xFBE0) | ((ppu.TimedTmpPtr[y]) & 0x041F) | 0x2000; //if (y == 142) - // printf("______________142 Ptr:0x%04X ____ 0x%04X\n", ppu.TimedTmpPtr[y], ppu.VRAMAddrReg2.W); + // console_printf(Console_Default, "______________142 Ptr:0x%04X ____ 0x%04X\n", ppu.TimedTmpPtr[y], ppu.VRAMAddrReg2.W); TileID = (PPU_Rd(ppu.VRAMAddrReg2.W) << 4) | ppu.Bg_Pattern_Table; @@ -1145,7 +1145,7 @@ void WritePPUReg(byte RegID, byte val) switch (RegID) { default:/* For not writeable reg */ - printf("WritePPU error\n"); + console_printf(Console_Default, "WritePPU error\n"); break; case 0: /* Control Register 1 */ ppu.ControlRegister1.b = val; @@ -1177,7 +1177,7 @@ t:0000 1100 0000 0000 = d:0000 0011 break; case 1: /* Control Register 2 */ - //printf("PPU: new CR2 ; 0x%x\n", val); + //console_printf(Console_Default, "PPU: new CR2 ; 0x%x\n", val); ppu.ControlRegister2.b = val; break; case 3: /* SPR-RAM Addresse Register */ @@ -1194,15 +1194,15 @@ t:0000 1100 0000 0000 = d:0000 0011 t:0000 0000 0001 1111=d:1111 1000 x=d:00000111 */ - //printf("2005[1st][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); + //console_printf(Console_Default, "2005[1st][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); ppu.VRAMAddrMode = 1; ppu.TmpVRamPtr = ((ppu.TmpVRamPtr & 0xFFE0) | ((val & 0xF8) >> 3)); ppu.HScroll = val & 0x7; - //printf("2005[1st][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); - //printf("%d -> 2005 w1: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); + //console_printf(Console_Default, "2005[1st][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); + //console_printf(Console_Default, "%d -> 2005 w1: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); } else { @@ -1217,25 +1217,25 @@ x=d:00000111 t:0000 0011 1110 0000=d:1111 1000 t:0111 0000 0000 0000=d:0000 0111 */ - //printf("2005[2nd][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); + //console_printf(Console_Default, "2005[2nd][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); ppu.VRAMAddrMode = 0; ppu.TmpVRamPtr = ((ppu.TmpVRamPtr & 0xFC1F) | ((val & 0xF8) << 2)); ppu.TmpVRamPtr = ((ppu.TmpVRamPtr & 0x8FFF) | ((val & 0x07) << 12)); ppu.TmpVScroll = (val & 0x7); //if (ppu.TmpVScroll != 0) - //printf("2002: TmpVScroll == %d \n", ppu.TmpVScroll); + //console_printf(Console_Default, "2002: TmpVScroll == %d \n", ppu.TmpVScroll); - //printf("2005[2nd][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); + //console_printf(Console_Default, "2005[2nd][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); - //printf("%d -> 2005 w2: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); + //console_printf(Console_Default, "%d -> 2005 w2: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); } break; case 6: /* VRAM Address register 2 */ if (ppu.VRAMAddrMode == 0) { - //printf("2006[1st][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); + //console_printf(Console_Default, "2006[1st][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); ppu.VRAMAddrMode = 1; /* 2006 first write: @@ -1243,13 +1243,13 @@ t:0011 1111 0000 0000 = d:0011 1111 t:1100 0000 0000 0000=0 */ ppu.TmpVRamPtr = ((ppu.TmpVRamPtr & 0xC0FF) | ((val&0x3F) << 8)) & 0x3FFF; - //printf("2006[1st][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); + //console_printf(Console_Default, "2006[1st][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); - //printf("%d -> 2006 w1: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); + //console_printf(Console_Default, "%d -> 2006 w1: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); } else { - //printf("2006[2nd][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); + //console_printf(Console_Default, "2006[2nd][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); ppu.VRAMAddrMode = 0; /* 2006 second write: @@ -1258,8 +1258,8 @@ v=t */ ppu.TmpVRamPtr = ((ppu.TmpVRamPtr & 0xFF00) | (val & 0x00FF)); ppu.VRAMAddrReg2.W = ppu.TmpVRamPtr; - //printf("2006[2nd][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); - //printf("%d -> 2006 w2: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); + //console_printf(Console_Default, "2006[2nd][%d]: 0x%02X [0x%04X]\n", ScanLine, val, ppu.TmpVRamPtr); + //console_printf(Console_Default, "%d -> 2006 w2: 0x%04X (val: 0x%02X)\n", ScanLine, ppu.TmpVRamPtr, val); } break; diff --git a/src/utils/bin2h/bin2h.c b/src/utils/bin2h/bin2h.c index a5390dc..9b775c5 100755 --- a/src/utils/bin2h/bin2h.c +++ b/src/utils/bin2h/bin2h.c @@ -38,7 +38,7 @@ int main(int argc, char *argv[]) infile = argv[i+1]; if (fpin == NULL) { - fprintf(stderr,"Error: cannot open in file '%s'\n", argv[i+1]); + fprintf (stderr, "Error: cannot open in file '%s'\n", argv[i+1]); exit(-1); } i++; @@ -49,14 +49,14 @@ int main(int argc, char *argv[]) fpout = fopen(argv[i+1], "wb"); if (fpout == NULL) { - fprintf(stderr,"Error: cannot open out file '%s'\n", argv[i+1]); + fprintf (stderr, "Error: cannot open out file '%s'\n", argv[i+1]); exit(-1); } i++; break; default: - fprintf(stderr,"Error: unknown argument: %s\n", argv[i]); + fprintf (stderr, "Error: unknown argument: %s\n", argv[i]); exit(-1); } } diff --git a/ti68k/Makefile b/ti68k/Makefile new file mode 100644 index 0000000..9e424b4 --- /dev/null +++ b/ti68k/Makefile @@ -0,0 +1,14 @@ +INCLUDE_FILES = ../src/include + +APU_FILES = ../src/apu/Sound.c +CORECPU_FILES = ../src/corecpu/corecpu.c +MAPPERS_FILES = ../src/mappersmanager/manager.c ../src/mappersmanager/mappers/aorom.c ../src/mappersmanager/mappers/cnrom.c ../src/mappersmanager/mappers/iremh3001.c ../src/mappersmanager/mappers/mmc1.c ../src/mappersmanager/mappers/mmc3.c ../src/mappersmanager/mappers/mmc4.c ../src/mappersmanager/mappers/norom.c ../src/mappersmanager/mappers/unrom.c +MEMORY_FILES = ../src/memorymanager/memory.c +PLUGINS_FILES = ../src/pluginsmanager/manager.c +PPU_FILES = ../src/ppu/ppu.c + +C_FILES = ../src/os/ti68k/main.c ../src/main.c ../src/NESCarts.c ../src/paddle.c ${APU_FILES} ${CORECPU_FILES} ${MAPPERS_FILES} ${MEMORY_FILES} ${PLUGINS_FILES} ${PPU_FILES} + + +tines: ${C_FILES} + gtc -I ${INCLUDE_FILES} -o $@ ${C_FILES} \ No newline at end of file diff --git a/unix/Makefile b/unix/Makefile index 2609268..595d1b3 100755 --- a/unix/Makefile +++ b/unix/Makefile @@ -27,30 +27,30 @@ MAPPERS=$(shell ls $(SRC)/$(MAPPERS_DIR)/*.c) all: tines -tines: tines.a corecpu.a apu.a ppu.a plugins.a mappers.a memory.a +tines: tines.o corecpu.o apu.o ppu.o plugins.o mappers.o memory.o $(CC) -o $@ $(LDFLAGS) $^ -apu.a: $(SRC)/apu/Sound.c $(SRC)/apu/SndAlleg.c +apu.o: $(SRC)/apu/Sound.c $(SRC)/apu/SndAlleg.c $(CC) $(CFLAGS) -c $^ -o $@ -corecpu.a: $(SRC)/corecpu/Debug.c $(SRC)/corecpu/M6502.c +corecpu.o: $(SRC)/corecpu/corecpu.c $(CC) $(CFLAGS) -Wno-pointer-sign -c $^ -o $@ -tines.a: $(SRC)/main.c $(SRC)/paddle.c $(SRC)/NESCarts.c +tines.o: $(SRC)/main.c $(SRC)/paddle.c $(SRC)/NESCarts.c $(CC) $(CFLAGS) -c $^ -o $@ -memory.a: $(SRC)/memorymanager/memory.c +memory.o: $(SRC)/memorymanager/memory.c $(CC) $(CFLAGS) -c $^ -o $@ -ppu.a: $(SRC)/ppu/ppu.c $(SRC)/ppu/ppu.memory.c $(SRC)/ppu/debug/ppu.debug.c +ppu.o: $(SRC)/ppu/ppu.c $(SRC)/ppu/ppu.memory.c $(SRC)/ppu/debug/ppu.debug.c $(CC) $(CFLAGS) -c $^ -o $@ -mappers.a: $(SRC)/mappersmanager/manager.c $(SRC)/mappersmanager/utils.c $(MAPPERS) +mappers.o: $(SRC)/mappersmanager/manager.c $(SRC)/mappersmanager/utils.c $(MAPPERS) $(CC) $(CFLAGS) -c $^ -o $@ -plugins.a: $(SRC)/pluginsmanager/manager.c $(PLUGINS) +plugins.o: $(SRC)/pluginsmanager/manager.c $(PLUGINS) $(CC) $(CFLAGS) -c $^ -o $@ .PHONY: clean clean: - rm -Rf *.o *~ core \ No newline at end of file + rm -Rf *.a *.o *~ core \ No newline at end of file