[NES] add CxROM and fix a severe timing issue which repairs many obvious glitches
This commit is contained in:
parent
af861b6475
commit
c713b9a8f0
|
@ -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" />
|
||||||
|
|
|
@ -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
|
||||||
";
|
";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue