diff --git a/trunk/src/boards/coolboy.cpp b/trunk/src/boards/coolboy.cpp index 67e4ae54..eea09c3b 100644 --- a/trunk/src/boards/coolboy.cpp +++ b/trunk/src/boards/coolboy.cpp @@ -45,7 +45,7 @@ static void COOLBOYCW(uint32 A, uint8 V) { } static void COOLBOYPW(uint32 A, uint8 V) { - uint32 mask, shift; + uint32 mask; uint32 base = ((EXPREGS[0] & 0x07) >> 0) | ((EXPREGS[1] & 0x10) >> 1) | ((EXPREGS[1] & 0x0C) << 2) | ((EXPREGS[0] & 0x30) << 2); switch(EXPREGS[0] & 0xC0) { case 0x00: diff --git a/trunk/src/boards/unrom512.cpp b/trunk/src/boards/unrom512.cpp index 3591589b..57b2ae7f 100644 --- a/trunk/src/boards/unrom512.cpp +++ b/trunk/src/boards/unrom512.cpp @@ -197,7 +197,7 @@ static void UNROM512LSync() { } else if (latche==0x10) { - for(int i=0;i<(ROM_size*4);i++) + for(uint32 i=0;i<(ROM_size*4);i++) inc_flash_write_count(i>>2,i<<12); memset(flashdata,0xFF,ROM_size*0x4000); //Erasing the rom chip as instructed. Crash rate calulated to be 99.9% :) } diff --git a/trunk/src/drivers/win/config.cpp b/trunk/src/drivers/win/config.cpp index e3b1b773..4ec3d277 100644 --- a/trunk/src/drivers/win/config.cpp +++ b/trunk/src/drivers/win/config.cpp @@ -18,14 +18,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -/****************************************************************/ -/* FCE Ultra */ -/* */ -/* This file contains code to interface to the standard */ -/* FCE Ultra configuration file saving/loading code. */ -/* */ -/****************************************************************/ - #include "config.h" #include "common.h" #include "main.h" @@ -184,6 +176,9 @@ static CFGSTRUCT fceuconfig[] = AC(ntsccol),AC(ntsctint),AC(ntschue), AC(force_grayscale), AC(dendy), + AC(extrascanlines), + AC(overclocked), + AC(skip_7bit_overclocking), NAC("palyo",pal_emulation), NAC("genie",genie), diff --git a/trunk/src/drivers/win/debugger.h b/trunk/src/drivers/win/debugger.h index ba93f5ce..49f3df0b 100644 --- a/trunk/src/drivers/win/debugger.h +++ b/trunk/src/drivers/win/debugger.h @@ -14,7 +14,6 @@ #define INVALID_BREAKPOINT_CONDITION 3 //extern volatile int userpause; //mbg merge 7/18/06 removed for merging -extern int scanline; //current scanline! :D extern HWND hDebug; extern int childwnd,numWPs; //mbg merge 7/18/06 had to make extern diff --git a/trunk/src/drivers/win/main.cpp b/trunk/src/drivers/win/main.cpp index aa19fd8a..d32dbf27 100644 --- a/trunk/src/drivers/win/main.cpp +++ b/trunk/src/drivers/win/main.cpp @@ -147,6 +147,12 @@ int genie = 0; int pal_emulation = 0; int pal_setting_specified = 0; int dendy = 0; +// overclock the console by adding dummy scanlines to PPU loop +// disables DMC DMA and WaveHi filling for these dummies +// doesn't work with new PPU +bool overclocked = 0; +// 7-bit samples have priority over overclocking +bool skip_7bit_overclocking = 1; bool swapDuty = 0; // some Famicom and NES clones had duty cycle bits swapped int ntsccol = 0, ntsctint, ntschue; std::string BaseDirectory; diff --git a/trunk/src/drivers/win/main.h b/trunk/src/drivers/win/main.h index f90c3a57..ab573840 100644 --- a/trunk/src/drivers/win/main.h +++ b/trunk/src/drivers/win/main.h @@ -57,6 +57,11 @@ extern int EnableBackgroundInput; extern int AFon; extern int AFoff; extern int AutoFireOffset; +extern int normalscanlines; +extern int extrascanlines; +extern int totalscanlines; +extern bool overclocked; +extern bool skip_7bit_overclocking; extern int vmod; diff --git a/trunk/src/drivers/win/ppuview.h b/trunk/src/drivers/win/ppuview.h index 9ea092dd..188e689c 100644 --- a/trunk/src/drivers/win/ppuview.h +++ b/trunk/src/drivers/win/ppuview.h @@ -1,6 +1,5 @@ extern int PPUViewScanline; extern int PPUViewer; -extern int scanline; void DoPPUView(); void PPUViewDoBlit(); diff --git a/trunk/src/drivers/win/res.rc b/trunk/src/drivers/win/res.rc index de227b40..b2f74bac 100644 --- a/trunk/src/drivers/win/res.rc +++ b/trunk/src/drivers/win/res.rc @@ -559,15 +559,19 @@ BEGIN PUSHBUTTON "Enter",400,444,107,16,28 END -TIMINGCONFIG DIALOGEX 23, 157, 203, 60 +TIMINGCONFIG DIALOGEX 23, 157, 203, 83 STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Timing Configuration" FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN - DEFPUSHBUTTON "Close",1,137,38,56,14 + DEFPUSHBUTTON "Close",1,137,61,56,14 CONTROL "Disable speed throttling used when sound is disabled.",CB_DISABLE_SPEED_THROTTLING, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,8,183,12 - CONTROL "Set high-priority thread.",CB_SET_HIGH_PRIORITY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,24,146,12 + CONTROL "Set high-priority thread.",CB_SET_HIGH_PRIORITY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,24,102,12 + CONTROL "Overclocking (old PPU only).",CB_OVERCLOCKING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,42,101,10 + EDITTEXT IDC_EXTRA_SCANLINES,122,38,61,14,ES_AUTOHSCROLL + LTEXT "Extra scanlines:",IDC_STATIC,127,26,51,8 + CONTROL "Don't overclock 7-bit samples.",CB_SKIP_7BIT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,58,111,10 END MOVIEOPTIONS DIALOGEX 65520, 76, 147, 222 diff --git a/trunk/src/drivers/win/resource.h b/trunk/src/drivers/win/resource.h index d0432adf..89225574 100644 --- a/trunk/src/drivers/win/resource.h +++ b/trunk/src/drivers/win/resource.h @@ -577,6 +577,7 @@ #define IDC_SELECTION_MARKER_EDIT 1147 #define IDC_NOTE_TO_FIND 1147 #define IDC_AUTOSAVE_PERIOD 1147 +#define IDC_EXTRA_SCANLINES 1147 #define IDC_BUTTON9 1148 #define TASEDITOR_FIND_NEXT_SIMILAR_MARKER 1148 #define IDC_SYMBOLIC_ADDRESS 1148 @@ -636,6 +637,7 @@ #define IDC_MASK_UNUSED_GRAPHICS 1203 #define CHECK_SOUND_SWAPDUTY 1203 #define CHECK_PALETTE_MONOCHROME 1203 +#define CB_OVERCLOCKING 1203 #define IDC_VOLUMEGROUP 1204 #define IDC_OMITBLANK 1204 #define IDC_CHECK3 1204 @@ -762,6 +764,7 @@ #define CTL_PALHUE_TRACKBAR 1291 #define CHECK_PALETTE_HDTV 1292 #define STATIC_HUEVALUE 1293 +#define CB_SKIP_7BIT 1294 #define MENU_NETWORK 40040 #define MENU_PALETTE 40041 #define MENU_SOUND 40042 diff --git a/trunk/src/drivers/win/timing.cpp b/trunk/src/drivers/win/timing.cpp index 502a4dfd..2090e677 100644 --- a/trunk/src/drivers/win/timing.cpp +++ b/trunk/src/drivers/win/timing.cpp @@ -3,6 +3,9 @@ #include "gui.h" #include "resource.h" +char str[5]; +extern int newppu; + /** * This function is called when the dialog closes. * @@ -28,7 +31,27 @@ void CloseTimingDialog(HWND hwndDlg) eoptions &= ~EO_NOTHROTTLE; } - EndDialog(hwndDlg, 0); + overclocked = (IsDlgButtonChecked(hwndDlg, CB_OVERCLOCKING) == BST_CHECKED); + skip_7bit_overclocking = (IsDlgButtonChecked(hwndDlg, CB_SKIP_7BIT) == BST_CHECKED); + + GetDlgItemText(hwndDlg, IDC_EXTRA_SCANLINES, str, 4); + sscanf(str,"%d",&extrascanlines); + + if (extrascanlines < 0) + { + extrascanlines = 0; + MessageBox(hwndDlg, "Overclocking is when you speed up your CPU, not slow it down!", "Error", MB_OK); + sprintf(str,"%d",extrascanlines); + SetDlgItemText(hwndDlg,IDC_EXTRA_SCANLINES,str); + } + else if (overclocked && newppu) + { + MessageBox(hwndDlg, "Overclocking doesn't work with new PPU!", "Error", MB_OK); + } + else + EndDialog(hwndDlg, 0); + + totalscanlines = normalscanlines + (overclocked ? extrascanlines : 0); } /** @@ -51,6 +74,17 @@ BOOL CALLBACK TimingConCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar CheckDlgButton(hwndDlg, CB_DISABLE_SPEED_THROTTLING, BST_CHECKED); } + if(overclocked) + CheckDlgButton(hwndDlg, CB_OVERCLOCKING, BST_CHECKED); + + if(skip_7bit_overclocking) + CheckDlgButton(hwndDlg, CB_SKIP_7BIT, BST_CHECKED); + + SendDlgItemMessage(hwndDlg,IDC_EXTRA_SCANLINES,EM_SETLIMITTEXT,3,0); + + sprintf(str,"%d",extrascanlines); + SetDlgItemText(hwndDlg,IDC_EXTRA_SCANLINES,str); + CenterWindowOnScreen(hwndDlg); break; diff --git a/trunk/src/fceu.cpp b/trunk/src/fceu.cpp index fe4f4f7c..034e6341 100644 --- a/trunk/src/fceu.cpp +++ b/trunk/src/fceu.cpp @@ -135,10 +135,12 @@ void FCEU_TogglePPU(void) { if (newppu) { FCEU_DispMessage("New PPU loaded", 0); FCEUI_printf("New PPU loaded"); + overclocked = 0; } else { FCEU_DispMessage("Old PPU loaded", 0); FCEUI_printf("Old PPU loaded"); } + normalscanlines = (dendy ? 290 : 240)+newppu; // use flag as number! #ifdef WIN32 SetMainWindowText(); #endif @@ -856,6 +858,11 @@ void FCEU_ResetVidSys(void) { PAL = w ? 1 : 0; + if (newppu) + overclocked = 0; + + normalscanlines = (dendy ? 290 : 240)+newppu; // use flag as number! + totalscanlines = normalscanlines + (overclocked ? extrascanlines : 0); FCEUPPU_SetVideoSystem(w || dendy); SetSoundVariables(); } @@ -921,18 +928,23 @@ int FCEUI_GetCurrentVidSystem(int *slstart, int *slend) { void FCEUI_SetRegion(int region) { switch (region) { case 0: // NTSC + normalscanlines = 240; pal_emulation = 0; dendy = 0; break; case 1: // PAL + normalscanlines = 240; pal_emulation = 1; dendy = 0; break; case 2: // Dendy + normalscanlines = 290; pal_emulation = 0; dendy = 1; break; } + normalscanlines += newppu; + totalscanlines = normalscanlines + (overclocked ? extrascanlines : 0); FCEUI_SetVidSystem(pal_emulation); RefreshThrottleFPS(); #ifdef WIN32 diff --git a/trunk/src/ppu.cpp b/trunk/src/ppu.cpp index b291e666..e9e034e9 100644 --- a/trunk/src/ppu.cpp +++ b/trunk/src/ppu.cpp @@ -19,45 +19,45 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "types.h" -#include "x6502.h" -#include "fceu.h" -#include "ppu.h" -#include "nsf.h" -#include "sound.h" -#include "file.h" -#include "utils/endian.h" -#include "utils/memory.h" +#include "types.h" +#include "x6502.h" +#include "fceu.h" +#include "ppu.h" +#include "nsf.h" +#include "sound.h" +#include "file.h" +#include "utils/endian.h" +#include "utils/memory.h" + +#include "cart.h" +#include "palette.h" +#include "state.h" +#include "video.h" +#include "input.h" +#include "driver.h" +#include "debug.h" + +#include +#include +#include -#include "cart.h" -#include "palette.h" -#include "state.h" -#include "video.h" -#include "input.h" -#include "driver.h" -#include "debug.h" +#define VBlankON (PPU[0] & 0x80) //Generate VBlank NMI +#define Sprite16 (PPU[0] & 0x20) //Sprites 8x16/8x8 +#define BGAdrHI (PPU[0] & 0x10) //BG pattern adr $0000/$1000 +#define SpAdrHI (PPU[0] & 0x08) //Sprite pattern adr $0000/$1000 +#define INC32 (PPU[0] & 0x04) //auto increment 1/32 -#include -#include -#include +#define SpriteON (PPU[1] & 0x10) //Show Sprite +#define ScreenON (PPU[1] & 0x08) //Show screen +#define PPUON (PPU[1] & 0x18) //PPU should operate +#define GRAYSCALE (PPU[1] & 0x01) //Grayscale (AND palette entries with 0x30) -#define VBlankON (PPU[0] & 0x80) //Generate VBlank NMI -#define Sprite16 (PPU[0] & 0x20) //Sprites 8x16/8x8 -#define BGAdrHI (PPU[0] & 0x10) //BG pattern adr $0000/$1000 -#define SpAdrHI (PPU[0] & 0x08) //Sprite pattern adr $0000/$1000 -#define INC32 (PPU[0] & 0x04) //auto increment 1/32 +#define SpriteLeft8 (PPU[1] & 0x04) +#define BGLeft8 (PPU[1] & 0x02) -#define SpriteON (PPU[1] & 0x10) //Show Sprite -#define ScreenON (PPU[1] & 0x08) //Show screen -#define PPUON (PPU[1] & 0x18) //PPU should operate -#define GRAYSCALE (PPU[1] & 0x01) //Grayscale (AND palette entries with 0x30) +#define PPU_status (PPU[2]) -#define SpriteLeft8 (PPU[1] & 0x04) -#define BGLeft8 (PPU[1] & 0x02) - -#define PPU_status (PPU[2]) - -#define Pal (PALRAM) +#define Pal (PALRAM) static void FetchSpriteData(void); static void RefreshLine(int lastpixel); @@ -343,6 +343,9 @@ static int maxsprites = 8; //scanline is equal to the current visible scanline we're on. int scanline; +int normalscanlines; +int extrascanlines = 0; +int totalscanlines; int g_rasterpos; static uint32 scanlines_per_frame; @@ -1759,7 +1762,7 @@ int FCEUPPU_Loop(int skip) { kook ^= 1; } if (GameInfo->type == GIT_NSF) - X6502_Run((256 + 85) * (dendy ? 290 : 240)); + X6502_Run((256 + 85) * normalscanlines); #ifdef FRAMESKIP else if (skip) { int y; @@ -1786,14 +1789,22 @@ int FCEUPPU_Loop(int skip) { #endif else { int x, max, maxref; - deemp = PPU[1] >> 5; - for (scanline = 0; scanline < (dendy ? 290 : 240); ) { //scanline is incremented in DoLine. Evil. :/ + + // manual samples can't play correctly with overclocking + if (DMC_7bit && skip_7bit_overclocking) + totalscanlines = normalscanlines; + else + totalscanlines = normalscanlines + (overclocked ? extrascanlines : 0); + + for (scanline = 0; scanline < totalscanlines; ) { //scanline is incremented in DoLine. Evil. :/ deempcnt[deemp]++; - if (scanline < 240) + if (scanline < normalscanlines) DEBUG(FCEUD_UpdatePPUView(scanline, 1)); DoLine(); } + DMC_7bit = 0; + if (MMC5Hack) MMC5_hb(scanline); for (x = 1, max = 0, maxref = 0; x < 7; x++) { if (deempcnt[x] > max) { @@ -2032,7 +2043,8 @@ int FCEUX_PPU_Loop(int skip) { //capture the initial xscroll //int xscroll = ppur.fh; //render 241/291 scanlines (1 dummy at beginning, dendy's 50 at the end) - for (int sl = 0; sl < (dendy ? 291 : 241); sl++) { + //ignore overclocking! + for (int sl = 0; sl < normalscanlines; sl++) { spr_read.start_scanline(); g_rasterpos = 0; @@ -2318,6 +2330,8 @@ int FCEUX_PPU_Loop(int skip) { runppu(1); } //scanline loop + DMC_7bit = 0; + if (MMC5Hack) MMC5_hb(240); //idle for one line diff --git a/trunk/src/ppu.h b/trunk/src/ppu.h index 5db71582..a4c387a4 100644 --- a/trunk/src/ppu.h +++ b/trunk/src/ppu.h @@ -34,9 +34,11 @@ extern void (*FFCEUX_PPUWrite)(uint32 A, uint8 V); extern uint8 FASTCALL FFCEUX_PPURead_Default(uint32 A); void FFCEUX_PPUWrite_Default(uint32 A, uint8 V); -extern int scanline; extern int g_rasterpos; extern uint8 PPU[4]; +extern bool overclocked; +extern bool skip_7bit_overclocking; +extern bool DMC_7bit; enum PPUPHASE { PPUPHASE_VBL, PPUPHASE_BG, PPUPHASE_OBJ diff --git a/trunk/src/sound.cpp b/trunk/src/sound.cpp index dabc865f..ea006c2e 100644 --- a/trunk/src/sound.cpp +++ b/trunk/src/sound.cpp @@ -58,6 +58,7 @@ uint8 EnabledChannels=0; // $4015 / Sound channels enable and status uint8 IRQFrameMode=0; // $4017 / Frame counter control / xx000000 uint8 InitialRawDALatch=0; // used only for lua +bool DMC_7bit = 0; // used to skip overclocking ENVUNIT EnvUnits[3]; static const int RectDuties[4]={1,2,4,6}; @@ -307,58 +308,69 @@ static DECLFW(Write_PSG) static DECLFW(Write_DMCRegs) { - A&=0xF; - - switch(A) - { - case 0x00:DoPCM(); - LoadDMCPeriod(V&0xF); - - if(SIRQStat&0x80) - { - if(!(V&0x80)) - { - X6502_IRQEnd(FCEU_IQDPCM); - SIRQStat&=~0x80; - } - else X6502_IRQBegin(FCEU_IQDPCM); - } - DMCFormat=V; - break; - case 0x01:DoPCM(); - InitialRawDALatch=V&0x7F; - RawDALatch=InitialRawDALatch; - break; - case 0x02:DMCAddressLatch=V;break; - case 0x03:DMCSizeLatch=V;break; - } - - + A&=0xF; + + switch(A) + { + case 0x00: + DoPCM(); + LoadDMCPeriod(V&0xF); + + if(SIRQStat&0x80) + { + if(!(V&0x80)) + { + X6502_IRQEnd(FCEU_IQDPCM); + SIRQStat&=~0x80; + } + else X6502_IRQBegin(FCEU_IQDPCM); + } + DMCFormat=V; + break; + case 0x01: + DoPCM(); + InitialRawDALatch=V&0x7F; + RawDALatch=InitialRawDALatch; + if (RawDALatch) + DMC_7bit = 1; + break; + case 0x02: + DMCAddressLatch=V; + if (V) + DMC_7bit = 0; + break; + case 0x03: + DMCSizeLatch=V; + if (V) + DMC_7bit = 0; + break; + } } static DECLFW(StatusWrite) { int x; - DoSQ1(); - DoSQ2(); - DoTriangle(); - DoNoise(); - DoPCM(); - for(x=0;x<4;x++) - if(!(V&(1<