Update to bsnes v017 release.

- This version adds major accuracy improvements, countless bugfixes and DSP-1 support. At the time of this release, the only remaining known bug in bsnes is with Uniracers 2-player mode, with well over 300+ games tested.
Changelog:
    - DSP-1 support added [Andreas Naive, byuu]
    - Added cooperative multithreading library, written by myself
    - Rewritten CPU core, now bus accurate
    - Rewritten APU core, now bus accurate
    - Added cartridge database
    - Added several PCB mappers, thanks to research from Overload
    - Added several games to database, fixing several mapping-related bugs
    - Improved mirroring [Nach, grinvader, byuu]
    - vscroll bug in hires, interlaced mode fixed. Fixes RPM racing
    - RTO X=256 bug corrected. Fixes Super Conflict title screen [anomie]
    - Fixed bug in NTSC filter with hires games
    - Updated snes_ntsc to version 2.0.1 [blargg]
    - Fixed bugs in HiROM / LoROM memory mapping. Fixes countless games
    - Fixed major bugs in HDMA routine. Fixes ToP, Mortal Kombat and Genjuu Ryodan
    - Added out-of-order execution to CPU, APU synchronization for major speedup with no accuracy loss
    - IRQs are now delayed after H/DMA transfers. Fixes Wild Guns
    - HDMA transfers now kill active DMA channels that are on the same channel. Fixes Bugs Bunny and World Class Rugby. Special thanks to zones for researching this
    - CPU emulation mode accuracy was improved
    - Cleaned up port-specific code to ease porting
    - Created unified Makefile, used by all ports [Nach]
    - Created GTK+ port of bsnes (although input is currently broken)
    - WRAM is now initialized to 0x55, SRAM to 0xff. Fixes Power Drive, Death Brade and RPM Racing
    - Fixed extreme NMI / IRQ edge case. Fixes Chou Aniki
    - Adjusted PAL execution speed. Fixes Earthworm Jim 2 (E) sound effects
    - Fixed auto joypad polling bug. Fixes La Wares
    - Fixed H/DMA bug that was preventing saves from working in Secret of Evermore
    - bsnes low loads d3dx9_*.dll dynamically at runtime, it is no longer required
    - Added support for 239-line PAL mode rendering
    - As usual, there have been much more changes I've forgotten about since the last release
    - Two C4 bugs fixed. Mega Man X2 / X3 have no remaining known bugs [anomie, byuu]
This commit is contained in:
byuu 2006-08-27 03:01:06 +00:00
parent 192e53bb87
commit e308cf4275
20 changed files with 361 additions and 253 deletions

BIN
bsnes.exe

Binary file not shown.

View File

@ -4,9 +4,10 @@ You are free to redistribute this software, and its source code; provided
there is no charge for the software, nor any charge for the medium used to
distribute the software. You are also free to use and modify the source code
as you desire for personal use only. No publically-released derivative works
of this source code are permitted without my permission, though I will likely
grant you permission if you ask me. You must also abide by the terms of any
additional source code licenses contained within this program.
of this program nor its source code are permitted without my permission,
though I will likely grant you permission if you ask me. You must also abide
by the terms of any additional source code licenses contained within this
program.
Simple DirectMedia Layer License:
---------------------------------
@ -20,7 +21,15 @@ http://www.libsdl.org/
This library is distributed under the terms of the GNU LGPL:
http://www.gnu.org/copyleft/lesser.html
JMA License:
------------
JMA is licensed under the GNU GPL. I have received special exemption from
Nach to use this library in bsnes.
Licensing Exemptions:
---------------------
libco is public domain. You may obtain the latest version at:
http://byuu.org/
Richard Bannister has asked for and received my permission to distribute
a binary-only port of bsnes on the Mac OS X platform.

108
readme.txt Normal file
View File

@ -0,0 +1,108 @@
bsnes
Version 0.017
Author: byuu
General
-------
bsnes is a Super Nintendo / Super Famicom emulator that began on
October 14th, 2004.
The latest version can be downloaded from:
http://byuu.org/
Please see license.txt for important licensing information.
Known Bug(s)
------------
Uniracers / Unirally
- 2-player mode sprite issues (mid-frame OAM writes not supported)
Known Limitations
-----------------
S-CPU
- Invalid DMA / HDMA transfers (eg WRAM<>WRAM) not fully emulated
- DMA / HDMA bus synchronization timing not supported
- Multiply / Divide register delays not implemented
S-SMP
- Cycle breakdown of opcodes is theoretical, but mostly correct
S-PPU
- Uses scanline-based renderer. This is very inaccurate, but very
few games rely on mid-scanline writes to function correctly
- Does not support FirstSprite+Y priority
- OAM / CGRAM accesses during active display not supported correctly
- RTO flags are not calculated on frames that are skipped when frameskipping
is enabled. This provides a major speedup, however it will cause in issues
in games that test these flags, eg the SNES Test Program Electronics Test.
Turning frameskipping off will allow RTO flag calculation on every frame
S-DSP
- Runs at 32khz. Hardware S-DSP likely runs at 1.024mhz to perform
multiple reads / writes per sample. Sound is still output at 32khz,
of course
Hardware Bugs
- CPUr1 HDMA crashing bug not emulated
- CPU<>APU communication bus conflicts not emulated
Unsupported Hardware
--------------------
SA-1
Coprocessor used in many popular games, including:
- Dragon Ball Z Hyper Dimension
- Kirby Super Star
- Kirby's Dreamland 3
- Marvelous
- SD Gundam G-NEXT
- Super Mario RPG
Super FX
Coprocessor used in many popular games, including:
- Doom
- Star Fox
- Star Fox 2 (unreleased beta)
- Super Mario World 2: Yoshi's Island
SPC7110
Coprocessor used only by the following games:
- Far East of Eden Zero
- Far East of Eden Zero: Shounen Jump no Shou
- Momotarou Densetsu Happy
- Super Power League 4
DSP-3
Coprocessor used only by SD Gundam GX
DSP-4
Coprocessor used only by Top Gear 3000
ST010 / ST011 / ST018
SETA coprocessors used by very few games
BS-X (Broadcast Satellite)
Add-on unit sold only in Japan that played specially-made games that
were downloaded via satellite
BS-X Flashcart
Flash cartridge used by BS-X, as well as some standalone games by
Asciisoft
Bandai Sufami Turbo
Special cartloader to play some Bandai games
Super Gameboy
Cartridge passthrough used for playing Gameboy games
Unsupported controllers
-----------------------
Mouse
Super Scope
Justifier
Multitap (4-port)
Multitap (5-port)

View File

@ -1,4 +1,4 @@
#define BSNES_VERSION "0.016.52"
#define BSNES_VERSION "0.017"
#define BSNES_TITLE "bsnes v" BSNES_VERSION
#define MEMCORE bMemBus
@ -14,13 +14,13 @@
#define CHEAT_SYSTEM
//enable GZ, ZIP format support
//#define GZIP_SUPPORT
#define GZIP_SUPPORT
//enable JMA support
//#define JMA_SUPPORT
#define JMA_SUPPORT
//debugging extensions (~10% speed hit)
#define DEBUGGER
//#define DEBUGGER
//snes core polymorphism
//(allow mem/cpu/apu/ppu overriding, ~10% speed hit)

View File

@ -482,25 +482,25 @@ void bCPU::mmio_w4206(uint8 value) {
//HTIMEL
void bCPU::mmio_w4207(uint8 value) {
status.hirq_pos = (status.hirq_pos & 0xff00) | value;
status.hirq_pos = ((status.hirq_pos & 0xff00) | value) & 0x01ff;
update_interrupts();
}
//HTIMEH
void bCPU::mmio_w4208(uint8 value) {
status.hirq_pos = (status.hirq_pos & 0x00ff) | (value << 8);
status.hirq_pos = ((status.hirq_pos & 0x00ff) | (value << 8)) & 0x01ff;
update_interrupts();
}
//VTIMEL
void bCPU::mmio_w4209(uint8 value) {
status.virq_pos = (status.virq_pos & 0xff00) | value;
status.virq_pos = ((status.virq_pos & 0xff00) | value) & 0x01ff;
update_interrupts();
}
//VTIMEH
void bCPU::mmio_w420a(uint8 value) {
status.virq_pos = (status.virq_pos & 0x00ff) | (value << 8);
status.virq_pos = ((status.virq_pos & 0x00ff) | (value << 8)) & 0x01ff;
update_interrupts();
}

View File

@ -21,19 +21,19 @@ void sCPU::mmio_w2180(uint8 data) {
//WMADDL
void sCPU::mmio_w2181(uint8 data) {
status.wram_addr = (status.wram_addr & 0xffff00) | (data);
status.wram_addr = (status.wram_addr & 0xffff00) | (data);
status.wram_addr &= 0x01ffff;
}
//WMADDM
void sCPU::mmio_w2182(uint8 data) {
status.wram_addr = (status.wram_addr & 0xff00ff) | (data << 8);
status.wram_addr = (status.wram_addr & 0xff00ff) | (data << 8);
status.wram_addr &= 0x01ffff;
}
//WMADDH
void sCPU::mmio_w2183(uint8 data) {
status.wram_addr = (status.wram_addr & 0x00ffff) | (data << 16);
status.wram_addr = (status.wram_addr & 0x00ffff) | (data << 16);
status.wram_addr &= 0x01ffff;
}
@ -51,7 +51,8 @@ uint8 sCPU::mmio_r4016() {
uint8 r = regs.mdr & 0xfc;
r |= status.joypad1_bits & 1;
if(status.joypad_strobe_latch == 0) {
status.joypad1_bits = asr<1>(status.joypad1_bits);
status.joypad1_bits >>= 1;
status.joypad1_bits |= 0x8000;
}
return r;
@ -65,7 +66,8 @@ uint8 sCPU::mmio_r4017() {
uint8 r = (regs.mdr & 0xe0) | 0x1c;
r |= status.joypad2_bits & 1;
if(status.joypad_strobe_latch == 0) {
status.joypad2_bits = asr<1>(status.joypad2_bits);
status.joypad2_bits >>= 1;
status.joypad2_bits |= 0x8000;
}
return r;
@ -179,25 +181,29 @@ void sCPU::mmio_w4200(uint8 data) {
//HTIMEL
void sCPU::mmio_w4207(uint8 data) {
status.hirq_pos = (status.hirq_pos & 0xff00) | (data);
status.hirq_pos = (status.hirq_pos & ~0xff) | (data);
status.hirq_pos &= 0x01ff;
update_interrupts();
}
//HTIMEH
void sCPU::mmio_w4208(uint8 data) {
status.hirq_pos = (status.hirq_pos & 0x00ff) | (data << 8);
status.hirq_pos = (status.hirq_pos & 0xff) | (data << 8);
status.hirq_pos &= 0x01ff;
update_interrupts();
}
//VTIMEL
void sCPU::mmio_w4209(uint8 data) {
status.virq_pos = (status.virq_pos & 0xff00) | (data);
status.virq_pos = (status.virq_pos & ~0xff) | (data);
status.virq_pos &= 0x01ff;
update_interrupts();
}
//VTIMEH
void sCPU::mmio_w420a(uint8 data) {
status.virq_pos = (status.virq_pos & 0x00ff) | (data << 8);
status.virq_pos = (status.virq_pos & 0xff) | (data << 8);
status.virq_pos &= 0x01ff;
update_interrupts();
}

View File

@ -14,7 +14,6 @@ void sCPU::run_manual_joypad_poll() {
status.joypad1_bits |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_X)) << 9;
status.joypad1_bits |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_L)) << 10;
status.joypad1_bits |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_R)) << 11;
status.joypad1_bits |= ~0xffff;
status.joypad2_bits = uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_B)) << 0;
status.joypad2_bits |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_Y)) << 1;
@ -28,7 +27,6 @@ void sCPU::run_manual_joypad_poll() {
status.joypad2_bits |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_X)) << 9;
status.joypad2_bits |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_L)) << 10;
status.joypad2_bits |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_R)) << 11;
status.joypad2_bits |= ~0xffff;
}
/*****
@ -66,6 +64,6 @@ uint16 joy1 = 0x0000, joy2 = 0x0000;
status.joypad1_bits >>= 16;
status.joypad2_bits >>= 16;
status.joypad1_bits |= ~0xffff;
status.joypad2_bits |= ~0xffff;
status.joypad1_bits |= 0xffff;
status.joypad2_bits |= 0xffff;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 281 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

View File

@ -23,13 +23,6 @@ void bPPU::scanline() {
regs.mosaic_countdown = regs.mosaic_size + 1;
regs.mosaic_countdown--;
//OAM sprite priority rotation
if(regs.oam_priority == false) {
regs.oam_firstsprite = 0;
} else {
regs.oam_firstsprite = (regs.oam_addr >> 2) & 127;
}
} else {
for(int bg = BG1; bg <= BG4; bg++) {
if(!regs.mosaic_enabled[bg] || !regs.mosaic_countdown) {
@ -43,9 +36,11 @@ void bPPU::scanline() {
regs.mosaic_countdown--;
}
if(line.y == (!r_cpu->overscan() ? 225 : 240) && regs.display_disabled == false) {
//OAM address reset
regs.oam_addr = regs.oam_baseaddr << 1;
if(line.y == (!r_cpu->overscan() ? 225 : 240)) {
if(regs.display_disabled == false) {
//OAM address reset
regs.oam_addr = regs.oam_baseaddr << 1;
}
}
if(line.y == 241 && line.interlace_field == 1) {
@ -98,7 +93,7 @@ void bPPU::power() {
//$2102-$2103
regs.oam_baseaddr = 0x0000;
regs.oam_addr = regs.oam_baseaddr << 1;
regs.oam_addr = 0x0000;
regs.oam_priority = false;
regs.oam_firstsprite = 0;

View File

@ -81,7 +81,7 @@ uint16 hc = r_cpu->hcycles();
//INIDISP
void bPPU::mmio_w2100(uint8 value) {
regs.display_disabled = bool(value & 0x80);
regs.display_disabled = !!(value & 0x80);
regs.display_brightness = value & 15;
}
@ -93,69 +93,55 @@ void bPPU::mmio_w2101(uint8 value) {
}
//OAMADDL
void bPPU::mmio_w2102(uint8 value) {
regs.oam_baseaddr = (regs.oam_baseaddr & 0x100) | value;
regs.oam_addr = regs.oam_baseaddr << 1;
if(regs.oam_priority == false) {
regs.oam_firstsprite = 0;
} else {
regs.oam_firstsprite = (regs.oam_addr >> 2) & 127;
}
void bPPU::mmio_w2102(uint8 data) {
regs.oam_baseaddr = (regs.oam_baseaddr & ~0xff) | (data << 0);
regs.oam_baseaddr &= 0x01ff;
regs.oam_addr = regs.oam_baseaddr << 1;
regs.oam_firstsprite = (regs.oam_priority == false) ? 0 : (regs.oam_addr >> 2) & 127;
}
//OAMADDH
void bPPU::mmio_w2103(uint8 value) {
regs.oam_priority = bool(value & 0x80);
regs.oam_baseaddr = ((value & 1) << 8) | (regs.oam_baseaddr & 0xff);
regs.oam_addr = regs.oam_baseaddr << 1;
if(regs.oam_priority == false) {
regs.oam_firstsprite = 0;
} else {
regs.oam_firstsprite = (regs.oam_addr >> 2) & 127;
}
void bPPU::mmio_w2103(uint8 data) {
regs.oam_priority = !!(data & 0x80);
regs.oam_baseaddr = (regs.oam_baseaddr & 0xff) | (data << 8);
regs.oam_baseaddr &= 0x01ff;
regs.oam_addr = regs.oam_baseaddr << 1;
regs.oam_firstsprite = (regs.oam_priority == false) ? 0 : (regs.oam_addr >> 2) & 127;
}
//OAMDATA
void bPPU::mmio_w2104(uint8 value) {
if(regs.oam_addr >= 0x0200) {
oam_write(regs.oam_addr, value);
} else if(!(regs.oam_addr & 1)) {
regs.oam_latchdata = value;
void bPPU::mmio_w2104(uint8 data) {
if(regs.oam_addr & 0x0200) {
oam_write(regs.oam_addr, data);
} else if((regs.oam_addr & 1) == 0) {
regs.oam_latchdata = data;
} else {
oam_write((regs.oam_addr & 0x01fe) + 0, regs.oam_latchdata);
oam_write((regs.oam_addr & 0x01fe) + 1, value);
oam_write((regs.oam_addr & ~1) + 0, regs.oam_latchdata);
oam_write((regs.oam_addr & ~1) + 1, data);
}
regs.oam_addr++;
regs.oam_addr &= 0x03ff;
if(!(regs.oam_addr & 1)) {
if(regs.oam_priority == false) {
regs.oam_firstsprite = 0;
} else {
regs.oam_firstsprite = (regs.oam_addr >> 2) & 127;
}
}
regs.oam_firstsprite = (regs.oam_priority == false) ? 0 : (regs.oam_addr >> 2) & 127;
}
//BGMODE
void bPPU::mmio_w2105(uint8 value) {
regs.bg_tilesize[BG4] = bool(value & 0x80);
regs.bg_tilesize[BG3] = bool(value & 0x40);
regs.bg_tilesize[BG2] = bool(value & 0x20);
regs.bg_tilesize[BG1] = bool(value & 0x10);
regs.bg3_priority = bool(value & 0x08);
regs.bg_tilesize[BG4] = !!(value & 0x80);
regs.bg_tilesize[BG3] = !!(value & 0x40);
regs.bg_tilesize[BG2] = !!(value & 0x20);
regs.bg_tilesize[BG1] = !!(value & 0x10);
regs.bg3_priority = !!(value & 0x08);
regs.bg_mode = (value & 7);
}
//MOSAIC
void bPPU::mmio_w2106(uint8 value) {
regs.mosaic_size = (value >> 4) & 15;
regs.mosaic_enabled[BG4] = bool(value & 0x08);
regs.mosaic_enabled[BG3] = bool(value & 0x04);
regs.mosaic_enabled[BG2] = bool(value & 0x02);
regs.mosaic_enabled[BG1] = bool(value & 0x01);
regs.mosaic_enabled[BG4] = !!(value & 0x08);
regs.mosaic_enabled[BG3] = !!(value & 0x04);
regs.mosaic_enabled[BG2] = !!(value & 0x02);
regs.mosaic_enabled[BG1] = !!(value & 0x01);
}
//BG1SC
@ -250,7 +236,7 @@ void bPPU::mmio_w2114(uint8 value) {
//VMAIN
void bPPU::mmio_w2115(uint8 value) {
regs.vram_incmode = bool(value & 0x80);
regs.vram_incmode = !!(value & 0x80);
regs.vram_mapping = (value >> 2) & 3;
switch(value & 3) {
case 0: regs.vram_incsize = 1; break;
@ -305,8 +291,8 @@ uint16 addr = get_vram_address() + 1;
//M7SEL
void bPPU::mmio_w211a(uint8 value) {
regs.mode7_repeat = (value >> 6) & 3;
regs.mode7_vflip = bool(value & 0x02);
regs.mode7_hflip = bool(value & 0x01);
regs.mode7_vflip = !!(value & 0x02);
regs.mode7_hflip = !!(value & 0x01);
}
//M7A
@ -371,38 +357,38 @@ void bPPU::mmio_w2122(uint8 value) {
//W12SEL
void bPPU::mmio_w2123(uint8 value) {
regs.window2_enabled[BG2] = bool(value & 0x80);
regs.window2_invert [BG2] = bool(value & 0x40);
regs.window1_enabled[BG2] = bool(value & 0x20);
regs.window1_invert [BG2] = bool(value & 0x10);
regs.window2_enabled[BG1] = bool(value & 0x08);
regs.window2_invert [BG1] = bool(value & 0x04);
regs.window1_enabled[BG1] = bool(value & 0x02);
regs.window1_invert [BG1] = bool(value & 0x01);
regs.window2_enabled[BG2] = !!(value & 0x80);
regs.window2_invert [BG2] = !!(value & 0x40);
regs.window1_enabled[BG2] = !!(value & 0x20);
regs.window1_invert [BG2] = !!(value & 0x10);
regs.window2_enabled[BG1] = !!(value & 0x08);
regs.window2_invert [BG1] = !!(value & 0x04);
regs.window1_enabled[BG1] = !!(value & 0x02);
regs.window1_invert [BG1] = !!(value & 0x01);
}
//W34SEL
void bPPU::mmio_w2124(uint8 value) {
regs.window2_enabled[BG4] = bool(value & 0x80);
regs.window2_invert [BG4] = bool(value & 0x40);
regs.window1_enabled[BG4] = bool(value & 0x20);
regs.window1_invert [BG4] = bool(value & 0x10);
regs.window2_enabled[BG3] = bool(value & 0x08);
regs.window2_invert [BG3] = bool(value & 0x04);
regs.window1_enabled[BG3] = bool(value & 0x02);
regs.window1_invert [BG3] = bool(value & 0x01);
regs.window2_enabled[BG4] = !!(value & 0x80);
regs.window2_invert [BG4] = !!(value & 0x40);
regs.window1_enabled[BG4] = !!(value & 0x20);
regs.window1_invert [BG4] = !!(value & 0x10);
regs.window2_enabled[BG3] = !!(value & 0x08);
regs.window2_invert [BG3] = !!(value & 0x04);
regs.window1_enabled[BG3] = !!(value & 0x02);
regs.window1_invert [BG3] = !!(value & 0x01);
}
//WOBJSEL
void bPPU::mmio_w2125(uint8 value) {
regs.window2_enabled[COL] = bool(value & 0x80);
regs.window2_invert [COL] = bool(value & 0x40);
regs.window1_enabled[COL] = bool(value & 0x20);
regs.window1_invert [COL] = bool(value & 0x10);
regs.window2_enabled[OAM] = bool(value & 0x08);
regs.window2_invert [OAM] = bool(value & 0x04);
regs.window1_enabled[OAM] = bool(value & 0x02);
regs.window1_invert [OAM] = bool(value & 0x01);
regs.window2_enabled[COL] = !!(value & 0x80);
regs.window2_invert [COL] = !!(value & 0x40);
regs.window1_enabled[COL] = !!(value & 0x20);
regs.window1_invert [COL] = !!(value & 0x10);
regs.window2_enabled[OAM] = !!(value & 0x08);
regs.window2_invert [OAM] = !!(value & 0x04);
regs.window1_enabled[OAM] = !!(value & 0x02);
regs.window1_invert [OAM] = !!(value & 0x01);
}
//WH0
@ -441,58 +427,58 @@ void bPPU::mmio_w212b(uint8 value) {
//TM
void bPPU::mmio_w212c(uint8 value) {
regs.bg_enabled[OAM] = bool(value & 0x10);
regs.bg_enabled[BG4] = bool(value & 0x08);
regs.bg_enabled[BG3] = bool(value & 0x04);
regs.bg_enabled[BG2] = bool(value & 0x02);
regs.bg_enabled[BG1] = bool(value & 0x01);
regs.bg_enabled[OAM] = !!(value & 0x10);
regs.bg_enabled[BG4] = !!(value & 0x08);
regs.bg_enabled[BG3] = !!(value & 0x04);
regs.bg_enabled[BG2] = !!(value & 0x02);
regs.bg_enabled[BG1] = !!(value & 0x01);
}
//TS
void bPPU::mmio_w212d(uint8 value) {
regs.bgsub_enabled[OAM] = bool(value & 0x10);
regs.bgsub_enabled[BG4] = bool(value & 0x08);
regs.bgsub_enabled[BG3] = bool(value & 0x04);
regs.bgsub_enabled[BG2] = bool(value & 0x02);
regs.bgsub_enabled[BG1] = bool(value & 0x01);
regs.bgsub_enabled[OAM] = !!(value & 0x10);
regs.bgsub_enabled[BG4] = !!(value & 0x08);
regs.bgsub_enabled[BG3] = !!(value & 0x04);
regs.bgsub_enabled[BG2] = !!(value & 0x02);
regs.bgsub_enabled[BG1] = !!(value & 0x01);
}
//TMW
void bPPU::mmio_w212e(uint8 value) {
regs.window_enabled[OAM] = bool(value & 0x10);
regs.window_enabled[BG4] = bool(value & 0x08);
regs.window_enabled[BG3] = bool(value & 0x04);
regs.window_enabled[BG2] = bool(value & 0x02);
regs.window_enabled[BG1] = bool(value & 0x01);
regs.window_enabled[OAM] = !!(value & 0x10);
regs.window_enabled[BG4] = !!(value & 0x08);
regs.window_enabled[BG3] = !!(value & 0x04);
regs.window_enabled[BG2] = !!(value & 0x02);
regs.window_enabled[BG1] = !!(value & 0x01);
}
//TSW
void bPPU::mmio_w212f(uint8 value) {
regs.sub_window_enabled[OAM] = bool(value & 0x10);
regs.sub_window_enabled[BG4] = bool(value & 0x08);
regs.sub_window_enabled[BG3] = bool(value & 0x04);
regs.sub_window_enabled[BG2] = bool(value & 0x02);
regs.sub_window_enabled[BG1] = bool(value & 0x01);
regs.sub_window_enabled[OAM] = !!(value & 0x10);
regs.sub_window_enabled[BG4] = !!(value & 0x08);
regs.sub_window_enabled[BG3] = !!(value & 0x04);
regs.sub_window_enabled[BG2] = !!(value & 0x02);
regs.sub_window_enabled[BG1] = !!(value & 0x01);
}
//CGWSEL
void bPPU::mmio_w2130(uint8 value) {
regs.color_mask = (value >> 6) & 3;
regs.colorsub_mask = (value >> 4) & 3;
regs.addsub_mode = bool(value & 0x02);
regs.direct_color = bool(value & 0x01);
regs.addsub_mode = !!(value & 0x02);
regs.direct_color = !!(value & 0x01);
}
//CGADDSUB
void bPPU::mmio_w2131(uint8 value) {
regs.color_mode = bool(value & 0x80);
regs.color_halve = bool(value & 0x40);
regs.color_enabled[BACK] = bool(value & 0x20);
regs.color_enabled[OAM] = bool(value & 0x10);
regs.color_enabled[BG4] = bool(value & 0x08);
regs.color_enabled[BG3] = bool(value & 0x04);
regs.color_enabled[BG2] = bool(value & 0x02);
regs.color_enabled[BG1] = bool(value & 0x01);
regs.color_mode = !!(value & 0x80);
regs.color_halve = !!(value & 0x40);
regs.color_enabled[BACK] = !!(value & 0x20);
regs.color_enabled[OAM] = !!(value & 0x10);
regs.color_enabled[BG4] = !!(value & 0x08);
regs.color_enabled[BG3] = !!(value & 0x04);
regs.color_enabled[BG2] = !!(value & 0x02);
regs.color_enabled[BG1] = !!(value & 0x01);
}
//COLDATA
@ -506,11 +492,11 @@ void bPPU::mmio_w2132(uint8 value) {
//SETINI
void bPPU::mmio_w2133(uint8 value) {
regs.mode7_extbg = bool(value & 0x40);
regs.pseudo_hires = bool(value & 0x08);
regs.overscan = bool(value & 0x04);
regs.oam_interlace = bool(value & 0x02);
regs.interlace = bool(value & 0x01);
regs.mode7_extbg = !!(value & 0x40);
regs.pseudo_hires = !!(value & 0x08);
regs.overscan = !!(value & 0x04);
regs.oam_interlace = !!(value & 0x02);
regs.interlace = !!(value & 0x01);
r_cpu->set_overscan(regs.overscan);
}
@ -550,16 +536,10 @@ uint8 bPPU::mmio_r2137() {
//OAMDATAREAD
uint8 bPPU::mmio_r2138() {
regs.ppu1_mdr = oam_read(regs.oam_addr);
regs.oam_addr++;
regs.oam_addr &= 0x03ff;
if(!(regs.oam_addr & 1)) {
if(regs.oam_priority == false) {
regs.oam_firstsprite = 0;
} else {
regs.oam_firstsprite = (regs.oam_addr >> 2) & 127;
}
}
regs.oam_firstsprite = (regs.oam_priority == false) ? 0 : (regs.oam_addr >> 2) & 127;
return regs.ppu1_mdr;
}
@ -681,18 +661,18 @@ uint8 bPPU::mmio_read(uint16 addr) {
case 0x2129:
case 0x212a:
return regs.ppu1_mdr;
case 0x2134:return mmio_r2134(); //MPYL
case 0x2135:return mmio_r2135(); //MPYM
case 0x2136:return mmio_r2136(); //MPYH
case 0x2137:return mmio_r2137(); //SLHV
case 0x2138:return mmio_r2138(); //OAMDATAREAD
case 0x2139:return mmio_r2139(); //VMDATALREAD
case 0x213a:return mmio_r213a(); //VMDATAHREAD
case 0x213b:return mmio_r213b(); //CGDATAREAD
case 0x213c:return mmio_r213c(); //OPHCT
case 0x213d:return mmio_r213d(); //OPVCT
case 0x213e:return mmio_r213e(); //STAT77
case 0x213f:return mmio_r213f(); //STAT78
case 0x2134: return mmio_r2134(); //MPYL
case 0x2135: return mmio_r2135(); //MPYM
case 0x2136: return mmio_r2136(); //MPYH
case 0x2137: return mmio_r2137(); //SLHV
case 0x2138: return mmio_r2138(); //OAMDATAREAD
case 0x2139: return mmio_r2139(); //VMDATALREAD
case 0x213a: return mmio_r213a(); //VMDATAHREAD
case 0x213b: return mmio_r213b(); //CGDATAREAD
case 0x213c: return mmio_r213c(); //OPHCT
case 0x213d: return mmio_r213d(); //OPVCT
case 0x213e: return mmio_r213e(); //STAT77
case 0x213f: return mmio_r213f(); //STAT78
}
//return 0x00;
@ -701,57 +681,57 @@ uint8 bPPU::mmio_read(uint16 addr) {
void bPPU::mmio_write(uint16 addr, uint8 data) {
switch(addr) {
case 0x2100:mmio_w2100(data);return; //INIDISP
case 0x2101:mmio_w2101(data);return; //OBSEL
case 0x2102:mmio_w2102(data);return; //OAMADDL
case 0x2103:mmio_w2103(data);return; //OAMADDH
case 0x2104:mmio_w2104(data);return; //OAMDATA
case 0x2105:mmio_w2105(data);return; //BGMODE
case 0x2106:mmio_w2106(data);return; //MOSAIC
case 0x2107:mmio_w2107(data);return; //BG1SC
case 0x2108:mmio_w2108(data);return; //BG2SC
case 0x2109:mmio_w2109(data);return; //BG3SC
case 0x210a:mmio_w210a(data);return; //BG4SC
case 0x210b:mmio_w210b(data);return; //BG12NBA
case 0x210c:mmio_w210c(data);return; //BG34NBA
case 0x210d:mmio_w210d(data);return; //BG1HOFS
case 0x210e:mmio_w210e(data);return; //BG1VOFS
case 0x210f:mmio_w210f(data);return; //BG2HOFS
case 0x2110:mmio_w2110(data);return; //BG2VOFS
case 0x2111:mmio_w2111(data);return; //BG3HOFS
case 0x2112:mmio_w2112(data);return; //BG3VOFS
case 0x2113:mmio_w2113(data);return; //BG4HOFS
case 0x2114:mmio_w2114(data);return; //BG4VOFS
case 0x2115:mmio_w2115(data);return; //VMAIN
case 0x2116:mmio_w2116(data);return; //VMADDL
case 0x2117:mmio_w2117(data);return; //VMADDH
case 0x2118:mmio_w2118(data);return; //VMDATAL
case 0x2119:mmio_w2119(data);return; //VMDATAH
case 0x211a:mmio_w211a(data);return; //M7SEL
case 0x211b:mmio_w211b(data);return; //M7A
case 0x211c:mmio_w211c(data);return; //M7B
case 0x211d:mmio_w211d(data);return; //M7C
case 0x211e:mmio_w211e(data);return; //M7D
case 0x211f:mmio_w211f(data);return; //M7X
case 0x2120:mmio_w2120(data);return; //M7Y
case 0x2121:mmio_w2121(data);return; //CGADD
case 0x2122:mmio_w2122(data);return; //CGDATA
case 0x2123:mmio_w2123(data);return; //W12SEL
case 0x2124:mmio_w2124(data);return; //W34SEL
case 0x2125:mmio_w2125(data);return; //WOBJSEL
case 0x2126:mmio_w2126(data);return; //WH0
case 0x2127:mmio_w2127(data);return; //WH1
case 0x2128:mmio_w2128(data);return; //WH2
case 0x2129:mmio_w2129(data);return; //WH3
case 0x212a:mmio_w212a(data);return; //WBGLOG
case 0x212b:mmio_w212b(data);return; //WOBJLOG
case 0x212c:mmio_w212c(data);return; //TM
case 0x212d:mmio_w212d(data);return; //TS
case 0x212e:mmio_w212e(data);return; //TMW
case 0x212f:mmio_w212f(data);return; //TSW
case 0x2130:mmio_w2130(data);return; //CGWSEL
case 0x2131:mmio_w2131(data);return; //CGADDSUB
case 0x2132:mmio_w2132(data);return; //COLDATA
case 0x2133:mmio_w2133(data);return; //SETINI
case 0x2100: mmio_w2100(data); return; //INIDISP
case 0x2101: mmio_w2101(data); return; //OBSEL
case 0x2102: mmio_w2102(data); return; //OAMADDL
case 0x2103: mmio_w2103(data); return; //OAMADDH
case 0x2104: mmio_w2104(data); return; //OAMDATA
case 0x2105: mmio_w2105(data); return; //BGMODE
case 0x2106: mmio_w2106(data); return; //MOSAIC
case 0x2107: mmio_w2107(data); return; //BG1SC
case 0x2108: mmio_w2108(data); return; //BG2SC
case 0x2109: mmio_w2109(data); return; //BG3SC
case 0x210a: mmio_w210a(data); return; //BG4SC
case 0x210b: mmio_w210b(data); return; //BG12NBA
case 0x210c: mmio_w210c(data); return; //BG34NBA
case 0x210d: mmio_w210d(data); return; //BG1HOFS
case 0x210e: mmio_w210e(data); return; //BG1VOFS
case 0x210f: mmio_w210f(data); return; //BG2HOFS
case 0x2110: mmio_w2110(data); return; //BG2VOFS
case 0x2111: mmio_w2111(data); return; //BG3HOFS
case 0x2112: mmio_w2112(data); return; //BG3VOFS
case 0x2113: mmio_w2113(data); return; //BG4HOFS
case 0x2114: mmio_w2114(data); return; //BG4VOFS
case 0x2115: mmio_w2115(data); return; //VMAIN
case 0x2116: mmio_w2116(data); return; //VMADDL
case 0x2117: mmio_w2117(data); return; //VMADDH
case 0x2118: mmio_w2118(data); return; //VMDATAL
case 0x2119: mmio_w2119(data); return; //VMDATAH
case 0x211a: mmio_w211a(data); return; //M7SEL
case 0x211b: mmio_w211b(data); return; //M7A
case 0x211c: mmio_w211c(data); return; //M7B
case 0x211d: mmio_w211d(data); return; //M7C
case 0x211e: mmio_w211e(data); return; //M7D
case 0x211f: mmio_w211f(data); return; //M7X
case 0x2120: mmio_w2120(data); return; //M7Y
case 0x2121: mmio_w2121(data); return; //CGADD
case 0x2122: mmio_w2122(data); return; //CGDATA
case 0x2123: mmio_w2123(data); return; //W12SEL
case 0x2124: mmio_w2124(data); return; //W34SEL
case 0x2125: mmio_w2125(data); return; //WOBJSEL
case 0x2126: mmio_w2126(data); return; //WH0
case 0x2127: mmio_w2127(data); return; //WH1
case 0x2128: mmio_w2128(data); return; //WH2
case 0x2129: mmio_w2129(data); return; //WH3
case 0x212a: mmio_w212a(data); return; //WBGLOG
case 0x212b: mmio_w212b(data); return; //WOBJLOG
case 0x212c: mmio_w212c(data); return; //TM
case 0x212d: mmio_w212d(data); return; //TS
case 0x212e: mmio_w212e(data); return; //TMW
case 0x212f: mmio_w212f(data); return; //TSW
case 0x2130: mmio_w2130(data); return; //CGWSEL
case 0x2131: mmio_w2131(data); return; //CGADDSUB
case 0x2132: mmio_w2132(data); return; //COLDATA
case 0x2133: mmio_w2133(data); return; //SETINI
}
}

View File

@ -87,7 +87,6 @@ uint width = (!hires) ? 256 : 512;
if(hires) {
hscroll <<= 1;
if(regs.interlace) {
vscroll <<= 1;
y = (y << 1) + line.interlace_field;
}
}

View File

@ -13,10 +13,19 @@ ASFLAGS = -f elf
LIBS = `pkg-config --libs gtk+-2.0` `sdl-config --libs`
endif
ifeq ($(PLATFORM),x-gcc-sdl)
OS = unix
CC = gcc
CFLAGS = -O3 -fomit-frame-pointer -ffast-math -DPLATFORM_X -DCOMPILER_GCC -DPROCESSOR_X86 -DUI_SDL `sdl-config --cflags`
AS = nasm
ASFLAGS = -f elf
LIBS = `sdl-config --libs`
endif
ifeq ($(PLATFORM),win-visualc)
OS = win
CC = cl
CFLAGS = /nologo /O2 /arch:SSE2 /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_WIN
CFLAGS = /nologo /O2 /EHsc /arch:SSE2 /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_WIN
AS = nasm
ASFLAGS = -f win32 -DWIN32
LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib
@ -25,7 +34,7 @@ endif
ifeq ($(PLATFORM),win-visualc-wip)
OS = win
CC = cl
CFLAGS = /nologo /O2 /GL /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_WIN
CFLAGS = /nologo /O2 /GL /EHsc /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_WIN
AS = nasm
ASFLAGS = -f win32 -DWIN32
LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib
@ -35,7 +44,7 @@ endif
ifeq ($(PLATFORM),win-visualc-pgi)
OS = win
CC = cl
CFLAGS = /nologo /O2 /GL /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_WIN
CFLAGS = /nologo /O2 /GL /EHsc /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_WIN
AS = nasm
ASFLAGS = -f win32 -DWIN32
LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib
@ -45,7 +54,7 @@ endif
ifeq ($(PLATFORM),win-visualc-pgo)
OS = win
CC = cl
CFLAGS = /nologo /O2 /GL /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_WIN
CFLAGS = /nologo /O2 /GL /EHsc /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_WIN
AS = nasm
ASFLAGS = -f win32 -DWIN32
LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib
@ -55,7 +64,7 @@ endif
ifeq ($(PLATFORM),win-visualc-sdl)
OS = win
CC = cl
CFLAGS = /nologo /O2 /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_SDL
CFLAGS = /nologo /O2 /EHsc /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_SDL
AS = nasm
ASFLAGS = -f win32 -DWIN32
LIBS = sdlmain.lib sdl.lib dsound.lib
@ -109,10 +118,10 @@ OBJS = main.$(OBJ) \
bdsp.$(OBJ) \
ppu.$(OBJ) bppu.$(OBJ) \
snes.$(OBJ) \
srtc.$(OBJ) sdd1.$(OBJ) c4.$(OBJ) dsp1.$(OBJ) dsp2.$(OBJ) obc1.$(OBJ)
#adler32.$(OBJ) compress.$(OBJ) crc32.$(OBJ) deflate.$(OBJ) gzio.$(OBJ) inffast.$(OBJ) \
#inflate.$(OBJ) inftrees.$(OBJ) ioapi.$(OBJ) trees.$(OBJ) unzip.$(OBJ) zip.$(OBJ) zutil.$(OBJ) \
#jma.$(OBJ) jcrc32.$(OBJ) lzmadec.$(OBJ) 7zlzma.$(OBJ) iiostrm.$(OBJ) inbyte.$(OBJ) lzma.$(OBJ) winout.$(OBJ)
srtc.$(OBJ) sdd1.$(OBJ) c4.$(OBJ) dsp1.$(OBJ) dsp2.$(OBJ) obc1.$(OBJ) \
adler32.$(OBJ) compress.$(OBJ) crc32.$(OBJ) deflate.$(OBJ) gzio.$(OBJ) inffast.$(OBJ) \
inflate.$(OBJ) inftrees.$(OBJ) ioapi.$(OBJ) trees.$(OBJ) unzip.$(OBJ) zip.$(OBJ) zutil.$(OBJ) \
jma.$(OBJ) jcrc32.$(OBJ) lzmadec.$(OBJ) 7zlzma.$(OBJ) iiostrm.$(OBJ) inbyte.$(OBJ) lzma.$(OBJ) winout.$(OBJ)
ifeq ($(OS),win)
ifeq ($(CC),cl)

View File

@ -1,7 +1,3 @@
#define IDI_APP_ICON 100
#define IDB_ABOUT_ART 101
#define IDB_CONTROLLER_ART 102
#define IDI_APP_ICON 100
IDI_APP_ICON ICON DISCARDABLE "../data/bsnes.ico"
IDB_ABOUT_ART BITMAP DISCARDABLE "../data/about.bmp"
IDB_CONTROLLER_ART BITMAP DISCARDABLE "../data/snes_controller.bmp"
IDI_APP_ICON ICON DISCARDABLE "../data/bsnes.ico"

View File

@ -1,3 +1,3 @@
@make PLATFORM=win-visualc
@make PLATFORM=win-visualc-wip
@move bsnes.exe ../../bsnes.exe>nul
@pause

View File

@ -1,3 +1,4 @@
#warning "WARNING: GTK+ port input is currently broken! Controls will not work! Please use SDL port instead."
#include "main.h"
#include "bsnes.h"

View File

@ -6,17 +6,17 @@ void CALLBACK wInputConfigInputTimerProc(HWND hwnd, UINT msg, UINT event, DWORD
bool InputConfigWindow::Event(EventInfo &info) {
switch(info.event_id) {
case EVENT_DRAW: {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
HDC hdcsrc = CreateCompatibleDC(hdc);
HBITMAP hbm = LoadBitmap(GetModuleHandle(0), MAKEINTRESOURCE(102));
SelectObject(hdcsrc, hbm);
BitBlt(hdc, 285, 169, 190, 100, hdcsrc, 0, 0, SRCCOPY);
DeleteDC(hdcsrc);
DeleteObject(hbm);
EndPaint(hwnd, &ps);
} break;
//case EVENT_DRAW: {
//PAINTSTRUCT ps;
//HDC hdc = BeginPaint(hwnd, &ps);
//HDC hdcsrc = CreateCompatibleDC(hdc);
//HBITMAP hbm = LoadBitmap(GetModuleHandle(0), MAKEINTRESOURCE(102));
// SelectObject(hdcsrc, hbm);
// BitBlt(hdc, 285, 169, 190, 100, hdcsrc, 0, 0, SRCCOPY);
// DeleteDC(hdcsrc);
// DeleteObject(hbm);
// EndPaint(hwnd, &ps);
//} break;
case EVENT_INPUTKEYDOWN: {
if(button_update.active == true) {

View File

@ -12,7 +12,7 @@ long height;
height = -MulDiv(8, GetDeviceCaps(hdc, LOGPIXELSY), 72);
global::fwf = CreateFont(height, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Courier New");
height = -MulDiv(9, GetDeviceCaps(hdc, LOGPIXELSY), 72);
global::font_about = CreateFont(height, 0, 0, 0, FW_BOLD, 0, 0, 0, 0, 0, 0, 0, 0, "Verdana");
global::font_about = CreateFont(height, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Verdana");
height = -MulDiv(14, GetDeviceCaps(hdc, LOGPIXELSY), 72);
global::font_header = CreateFont(height, 0, 0, 0, FW_BOLD, 0, 0, 0, 0, 0, 0, 0, 0, "Verdana");
height = -MulDiv(10, GetDeviceCaps(hdc, LOGPIXELSY), 72);
@ -25,7 +25,7 @@ long height;
wMain.Center();
wAbout.SetIcon(100);
wAbout.Create(0, "bsnes_about", "topmost|popup|frame|dragmove", 0, 0, 400, 240, "About bsnes...");
wAbout.Create(0, "bsnes_about", "topmost|popup|frame|dragmove", 0, 0, 325, 165, "About bsnes...");
wAbout.Center();
init_settings();

View File

@ -84,7 +84,8 @@ struct {
class AboutWindow : public Window {
public:
Button Ok;
Editbox AboutText;
Button Ok;
static const char about_text[4096];
bool Event(EventInfo &info);

View File

@ -2,10 +2,10 @@ const char AboutWindow::about_text[4096] = ""
"bsnes -- version " BSNES_VERSION "\r\n"
"Author: byuu\r\n"
"Project began: October 14th, 2004\r\n"
"\r\n\r\n\r\n\r\n\r\n"
"\r\n\r\n"
"Contributors:\r\n"
" anomie, blargg, DMV27, GIGO, kode54, Nach,\r\n"
" Overload, Richard Bannister, TRAC, zones\r\n";
" Overload, Richard Bannister, TRAC, zones";
bool AboutWindow::Event(EventInfo &info) {
switch(info.event_id) {
@ -16,14 +16,16 @@ bool AboutWindow::Event(EventInfo &info) {
} break;
case EVENT_DRAW: {
break;
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
HDC hdcsrc = CreateCompatibleDC(hdc);
HBITMAP hbm = LoadBitmap(GetModuleHandle(0), MAKEINTRESOURCE(101));
SelectObject(hdcsrc, hbm);
BitBlt(hdc, 0, 0, 400, 240, hdcsrc, 0, 0, SRCCOPY);
DeleteDC(hdcsrc);
DeleteObject(hbm);
//HDC hdcsrc = CreateCompatibleDC(hdc);
//HBITMAP hbm = LoadBitmap(GetModuleHandle(0), MAKEINTRESOURCE(101));
// SelectObject(hdcsrc, hbm);
// BitBlt(hdc, 0, 0, 400, 240, hdcsrc, 0, 0, SRCCOPY);
// DeleteDC(hdcsrc);
// DeleteObject(hbm);
SelectObject(hdc, (HGDIOBJ)global::font_about);
SetBkMode(hdc, TRANSPARENT);
@ -56,5 +58,9 @@ bool AboutWindow::Event(EventInfo &info) {
}
void AboutWindow::Setup() {
Ok.Create(this, "visible", 321, 201, 60, 20, "Ok");
AboutText.Create(this, "visible|edge|multiline|readonly", 5, 5, 315, 125, about_text);
AboutText.SetBackgroundColor(32, 32, 32);
AboutText.SetTextColor(255, 255, 255);
AboutText.SetFont(global::font_about);
Ok.Create(this, "visible", 240, 135, 80, 25, "Ok");
}