[NES] add CxROM and fix a severe timing issue which repairs many obvious glitches

This commit is contained in:
zeromus 2011-02-28 09:13:27 +00:00
parent af861b6475
commit c713b9a8f0
10 changed files with 95 additions and 20 deletions

View File

@ -55,6 +55,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Consoles\Calculator\TI83.cs" /> <Compile Include="Consoles\Calculator\TI83.cs" />
<Compile Include="Consoles\Nintendo\NES\Boards\CxROM.cs" />
<Compile Include="Consoles\Nintendo\NES\Boards\NROM.cs" /> <Compile Include="Consoles\Nintendo\NES\Boards\NROM.cs" />
<Compile Include="Consoles\Nintendo\NES\BoardDetector.cs" /> <Compile Include="Consoles\Nintendo\NES\BoardDetector.cs" />
<Compile Include="Consoles\Nintendo\NES\Boards\UxROM.cs" /> <Compile Include="Consoles\Nintendo\NES\Boards\UxROM.cs" />

View File

@ -42,6 +42,8 @@ NROM 0 1 1
NROM 0 2 1 NROM 0 2 1
UNROM 2 8 0 UNROM 2 8 0
UOROM 2 16 0 UOROM 2 16 0
CNROM 3 2 2
CNROM 3 2 4
"; ";
} }

View File

@ -0,0 +1,49 @@
using System;
using System.Diagnostics;
namespace BizHawk.Emulation.Consoles.Nintendo.Boards
{
//generally mapper3
public class CxROM : NES.NESBoardBase
{
string type;
public CxROM(string type)
{
this.type = type;
}
public override void Initialize(NES.RomInfo romInfo, NES nes)
{
base.Initialize(romInfo, nes);
Debug.Assert(Util.IsPowerOfTwo(RomInfo.CHR_Size));
chr_mask = RomInfo.CHR_Size - 1;
bus_conflict = true;
}
public override void WritePRG(int addr, byte value)
{
if (bus_conflict)
{
byte old_value = value;
value &= ReadPRG(addr);
Debug.Assert(old_value == value,"Found a test case of CxROM bus conflict. please report.");
}
chr = value&chr_mask;
Console.WriteLine("at {0}, set chr={1}", NES.ppu.ppur.status.sl, chr);
}
public override byte ReadPPU(int addr)
{
if (addr < 0x2000)
{
return RomInfo.VROM[addr + (chr<<13)];
}
else return base.ReadPPU(addr);
}
int chr;
int chr_mask;
bool bus_conflict;
}
}

View File

@ -5,7 +5,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.Boards
{ {
public class NROM : NES.NESBoardBase public class NROM : NES.NESBoardBase
{ {
public virtual void Initialize(NES.RomInfo romInfo, NES nes) public override void Initialize(NES.RomInfo romInfo, NES nes)
{ {
base.Initialize(romInfo, nes); base.Initialize(romInfo, nes);
Debug.Assert(romInfo.PRG_Size < 3); Debug.Assert(romInfo.PRG_Size < 3);

View File

@ -3,6 +3,8 @@ using System.Diagnostics;
namespace BizHawk.Emulation.Consoles.Nintendo.Boards namespace BizHawk.Emulation.Consoles.Nintendo.Boards
{ {
//generally mapper2
public class UxROM : NES.NESBoardBase public class UxROM : NES.NESBoardBase
{ {
string type; string type;
@ -29,13 +31,12 @@ namespace BizHawk.Emulation.Consoles.Nintendo.Boards
{ {
int block = addr >> 14; int block = addr >> 14;
int page = block == 1 ? pagemask : prg; int page = block == 1 ? pagemask : prg;
page &= pagemask;
int ofs = addr & 0x3FFF; int ofs = addr & 0x3FFF;
return RomInfo.ROM[(page << 14) | ofs]; return RomInfo.ROM[(page << 14) | ofs];
} }
public override void WritePRG(int addr, byte value) public override void WritePRG(int addr, byte value)
{ {
prg = value; prg = value & pagemask;
} }
public override byte ReadPPU(int addr) public override byte ReadPPU(int addr)

View File

@ -114,7 +114,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
//hardware //hardware
protected MOS6502 cpu; protected MOS6502 cpu;
INESBoard board; INESBoard board;
PPU ppu; public PPU ppu;
RomInfo romInfo; RomInfo romInfo;
byte[] ram; byte[] ram;
@ -237,9 +237,9 @@ namespace BizHawk.Emulation.Consoles.Nintendo
int pixel = emu.ppu.xbuf[i]; int pixel = emu.ppu.xbuf[i];
int deemph = pixel >> 8; int deemph = pixel >> 8;
int palentry = pixel & 0xFF; int palentry = pixel & 0xFF;
int r = emu.palette[pixel, 0]; int r = emu.palette[palentry, 0];
int g = emu.palette[pixel, 1]; int g = emu.palette[palentry, 1];
int b = emu.palette[pixel, 2]; int b = emu.palette[palentry, 2];
Palettes.ApplyDeemphasis(ref r, ref g, ref b, deemph); Palettes.ApplyDeemphasis(ref r, ref g, ref b, deemph);
pixels[i] = (r<<16)|(g<<8)|b; pixels[i] = (r<<16)|(g<<8)|b;
i++; i++;
@ -278,9 +278,19 @@ namespace BizHawk.Emulation.Consoles.Nintendo
ppu.FrameAdvance(); ppu.FrameAdvance();
} }
int cpu_accumulate;
protected void RunCpu(int cycles) protected void RunCpu(int cycles)
{ {
cpu.Execute(cycles); if (ppu.PAL)
cycles *= 15;
else
cycles *= 16;
cpu_accumulate += cycles;
int todo = cpu_accumulate / 48;
cpu_accumulate -= todo * 48;
if(todo>0)
cpu.Execute(todo);
} }
interface IPortDevice interface IPortDevice
@ -611,6 +621,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
case "NROM": board = new Boards.NROM(); break; case "NROM": board = new Boards.NROM(); break;
case "UNROM": board = new Boards.UxROM("UNROM"); break; case "UNROM": board = new Boards.UxROM("UNROM"); break;
case "UOROM": board = new Boards.UxROM("UOROM"); break; case "UOROM": board = new Boards.UxROM("UOROM"); break;
case "CNROM": board = new Boards.CxROM("CNROM"); break;
} }
if (board == null) throw new InvalidOperationException("Couldn't classify NES rom"); if (board == null) throw new InvalidOperationException("Couldn't classify NES rom");

View File

@ -11,7 +11,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
{ {
partial class NES partial class NES
{ {
partial class PPU public partial class PPU
{ {
//when the ppu issues a write it goes through here and into the game board //when the ppu issues a write it goes through here and into the game board
void ppubus_write(int addr, byte value) void ppubus_write(int addr, byte value)
@ -74,13 +74,12 @@ namespace BizHawk.Emulation.Consoles.Nintendo
//DON'T LIKE THIS.... //DON'T LIKE THIS....
ppur.status.cycle = (ppur.status.cycle + x) % ppur.status.cycle = (ppur.status.cycle + x) %
ppur.status.end_cycle; ppur.status.end_cycle;
nes.RunCpu(x); nes.RunCpu(x);
//pputime -= cputodo<<2; //pputime -= cputodo<<2;
} }
//hack //hack
bool PAL = false; public bool PAL = false;
bool SPRITELIMIT = true; bool SPRITELIMIT = true;
const int MAXSPRITES = 8; const int MAXSPRITES = 8;

View File

@ -54,7 +54,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
} }
struct PPUSTATUS public struct PPUSTATUS
{ {
public int sl; public int sl;
public int cycle, end_cycle; public int cycle, end_cycle;
@ -62,7 +62,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
//uses the internal counters concept at http://nesdev.icequake.net/PPU%20addressing.txt //uses the internal counters concept at http://nesdev.icequake.net/PPU%20addressing.txt
//TODO - this should be turned into a state machine //TODO - this should be turned into a state machine
class PPUREGS public class PPUREGS
{ {
PPU ppu; PPU ppu;
public PPUREGS(PPU ppu) public PPUREGS(PPU ppu)
@ -242,7 +242,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
Bit Reg2002_objhit; //Sprite 0 overlap. Set when a nonzero pixel of sprite 0 is drawn overlapping a nonzero background pixel. Used for raster timing. Bit Reg2002_objhit; //Sprite 0 overlap. Set when a nonzero pixel of sprite 0 is drawn overlapping a nonzero background pixel. Used for raster timing.
Bit Reg2002_vblank_active; //Vertical blank start (0: has not started; 1: has started) Bit Reg2002_vblank_active; //Vertical blank start (0: has not started; 1: has started)
byte PPUGenLatch; byte PPUGenLatch;
PPUREGS ppur; public PPUREGS ppur;
Reg_2000 reg_2000; Reg_2000 reg_2000;
Reg_2001 reg_2001; Reg_2001 reg_2001;
byte reg_2003; byte reg_2003;

View File

@ -25,10 +25,6 @@ namespace BizHawk.Emulation.Consoles.Nintendo
void Read_bgdata(ref BGDataRecord bgdata) { void Read_bgdata(ref BGDataRecord bgdata) {
int addr = ppur.get_ntread(); int addr = ppur.get_ntread();
if (addr == 0x2043)
{
int zzz = 9;
}
bgdata.nt = ppubus_read(addr); bgdata.nt = ppubus_read(addr);
runppu(kFetchTime); runppu(kFetchTime);

View File

@ -2314,8 +2314,8 @@ C7538FE4132AADC1A2535042C6BBF29C Spelunker (U) NES board=NROM;mirror=V;PRG=2;C
22F4719A16FCF0DEFE1DF7F4C6C7D83D Spy Vs Spy (U) NES board=NROM;mirror=H;PRG=2;CHR=1 22F4719A16FCF0DEFE1DF7F4C6C7D83D Spy Vs Spy (U) NES board=NROM;mirror=H;PRG=2;CHR=1
96250E185FF5B8C596A210803484322E Sqoon (U) NES board=NROM;mirror=V;PRG=2;CHR=1 96250E185FF5B8C596A210803484322E Sqoon (U) NES board=NROM;mirror=V;PRG=2;CHR=1
80F94BBB851A5466BF773DBBC6D056F2 Stack-Up (JU) NES board=NROM;mirror=H;PRG=2;CHR=1 80F94BBB851A5466BF773DBBC6D056F2 Stack-Up (JU) NES board=NROM;mirror=H;PRG=2;CHR=1
8E3630186E35D477231BF8FD50E54CDD Super Mario Bros (Rev 0) (JU) NES board=NROM;mirror=V;PRG=2;CHR=1;bug=1 8E3630186E35D477231BF8FD50E54CDD Super Mario Bros (Rev 0) (JU) NES board=NROM;mirror=V;PRG=2;CHR=1
D7176817CDE28CE3F6589B5E833089A4 Super Mario Bros (Rev 1) (JU) NES board=NROM;mirror=V;PRG=2;CHR=1;bug=1 D7176817CDE28CE3F6589B5E833089A4 Super Mario Bros (Rev 1) (JU) NES board=NROM;mirror=V;PRG=2;CHR=1
FA57750AD33815E99C40986F26FC697E Tag Team Wrestling (U) NES board=NROM;mirror=H;PRG=2;CHR=1; FA57750AD33815E99C40986F26FC697E Tag Team Wrestling (U) NES board=NROM;mirror=H;PRG=2;CHR=1;
7A471AC3E9F2ED9B252C0EE6C5B69F5B Volleyball (U) NES board=NROM;mirror=V;PRG=2;CHR=1 7A471AC3E9F2ED9B252C0EE6C5B69F5B Volleyball (U) NES board=NROM;mirror=V;PRG=2;CHR=1
E7D7225DAD044B624FBAD9C9CA96E835 Wrecking Crew (JUE) NES board=NROM;mirror=H;PRG=2;CHR=1 E7D7225DAD044B624FBAD9C9CA96E835 Wrecking Crew (JUE) NES board=NROM;mirror=H;PRG=2;CHR=1
@ -2337,3 +2337,19 @@ C0C74CC78E6CD34775A83CC21A0C75B5 Paperboy 2 (U) NES board=UOROM;mirror=H;PRG=1
;mapper66? mhrom? wtf?? ;mapper66? mhrom? wtf??
;27100B746D50E6AE6FBAE2C794173240 Metal Gear (U) NES board=UXROM;mirror=H;PRG=8;CHR=0;CRAM=8;bug=1 ;27100B746D50E6AE6FBAE2C794173240 Metal Gear (U) NES board=UXROM;mirror=H;PRG=8;CHR=0;CRAM=8;bug=1
;CNROM 2,2
646ADDFCC3F43330681482061BEF9493 Arkanoid (J) NES board=CNROM;mirror=H;PRG=2;CHR=2
0CCC1A2FE5214354C3FD75A6C81550CC Arkanoid (U) NES board=CNROM;mirror=H;PRG=2;CHR=2
;CNROM 2,4
39FC2CB541D2D2E32ED5E5E45E54CE74 Solomon's Key (U) NES board=CNROM;mirror=H;PRG=2;CHR=4
248BA1ACBFED28BE4E6839A858A5C60A Hudson's Adventure Island (U) NES board=CNROM;mirror=V;PRG=2;CHR=4
C3263D7DE9FD9AA6BDC416526399314E Adventures of Dino Riki (U) NES board=CNROM;mirror=V;PRG=2;CHR=4
6307B2766D33A38AE68C639019DC8890 Alpha Mission (U) NES board=CNROM;mirror=H;PRG=2;CHR=4
C2E8AD9E054DD3AF022404856DC8916F ASO - Armored Scrum Object (J) NES board=CNROM;mirror=H;PRG=2;CHR=4
930371365F634BECEFA5538D0C3065C5 Athletic World (U) NES board=CNROM;mirror=V;PRG=2;CHR=4
797383138B0590CE00ED0F6FDEA14053 Arkista's Ring (U) NES board=CNROM;mirror=H;PRG=2;CHR=4
8E7811BE263CF530ADECF3368B9E6012 Bump'n'Jump (U) NES board=CNROM;mirror=H;PRG=2;CHR=4
5DB8BC3BD36484BB164EEA6097A1E313 Cybernoid - The Fighting Machine (U) NES board=CNROM;mirror=V;PRG=2;CHR=4;bug=1