PAL support for SMS
This commit is contained in:
parent
aa784295d8
commit
3c8236fd32
|
@ -1,6 +1,4 @@
|
|||
using System;
|
||||
|
||||
namespace BizHawk.Emulation.CPUs.Z80
|
||||
namespace BizHawk.Emulation.CPUs.Z80
|
||||
{
|
||||
public partial class Z80A
|
||||
{
|
||||
|
|
|
@ -36,7 +36,6 @@ namespace BizHawk.Emulation.CPUs.Z80
|
|||
totalExecutedCycles += 4; pendingCycles -= 4;
|
||||
} else {
|
||||
++RegR;
|
||||
//System.Console.WriteLine(State());
|
||||
|
||||
switch (ReadMemory(RegPC.Word++))
|
||||
{
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
======= Sega MasterSystem Compatibility Issues =======
|
||||
|
||||
* CodeMasters games use a custom mapper and special video modes (both implemented)
|
||||
+ Cosmic Spacehead and Micro Machines are playable but suffer from a graphic glitch on the
|
||||
top part of the frame. In my defense, Kega, Cogwheel, and other emulators do the precise
|
||||
same thing.
|
||||
+ Fantastic Dizzy crashes shortly after starting a new game. Investigating.
|
||||
|
||||
* F16 Fighting Falcon uses old SG-1000 video mode, and doesn't work on a GG/Genesis either.
|
||||
|
|
|
@ -10,19 +10,18 @@ using BizHawk.Emulation.Sound;
|
|||
VDP:
|
||||
+ Double Size Sprites
|
||||
+ HCounter
|
||||
+ Possibly work on VDP tests, but they don't really affect games.
|
||||
- Other video modes / CodeMasters 224 lines / old SG-1000 video modes.
|
||||
+ Old TMS video modes (SG-1000)
|
||||
|
||||
GENERAL:
|
||||
+ Debug some GameGear game issues.
|
||||
+ Port 3F emulation (Japanese BIOS)
|
||||
+ Try to clean up the organization of the source code.
|
||||
+ SG-1000 support
|
||||
|
||||
**********************************************************/
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Sega
|
||||
{
|
||||
public enum DisplayType { NTSC, PAL }
|
||||
|
||||
public sealed partial class SMS : IEmulator
|
||||
{
|
||||
|
@ -59,7 +58,6 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
private byte Port02 = 0xFF;
|
||||
private byte Port3F = 0xFF;
|
||||
|
||||
private int framesPerSecond;
|
||||
private int scanlinesPerFrame;
|
||||
|
||||
private DisplayType displayType;
|
||||
|
@ -69,15 +67,7 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
set
|
||||
{
|
||||
displayType = value;
|
||||
if (displayType == DisplayType.NTSC)
|
||||
{
|
||||
framesPerSecond = 60;
|
||||
scanlinesPerFrame = 262;
|
||||
} else // PAL
|
||||
{
|
||||
framesPerSecond = 50;
|
||||
scanlinesPerFrame = 313;
|
||||
}
|
||||
scanlinesPerFrame = displayType == DisplayType.NTSC ? 262 : 313;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,7 +75,6 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
|
||||
public void Init()
|
||||
{
|
||||
DisplayType = DisplayType.NTSC;
|
||||
if (Controller == null)
|
||||
Controller = NullController.GetNullController();
|
||||
|
||||
|
@ -93,21 +82,23 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
Cpu.ReadHardware = ReadPort;
|
||||
Cpu.WriteHardware = WritePort;
|
||||
|
||||
Vdp = new VDP(IsGameGear ? VdpMode.GameGear : VdpMode.SMS);
|
||||
Vdp = new VDP(IsGameGear ? VdpMode.GameGear : VdpMode.SMS, DisplayType);
|
||||
PSG = new SN76489();
|
||||
YM2413 = new YM2413();
|
||||
SoundMixer = new SoundMixer(PSG, YM2413);
|
||||
|
||||
if (HasYM2413 && Options.Contains("WhenFMDisablePSG"))
|
||||
SoundMixer.DisableSource(PSG);
|
||||
|
||||
ActiveSoundProvider = PSG;
|
||||
HardReset();
|
||||
//PSG.StereoPanning = 0xDA;
|
||||
}
|
||||
|
||||
public void HardReset()
|
||||
{
|
||||
Cpu.Reset();
|
||||
Cpu.RegisterSP = 0xDFF0;
|
||||
Vdp = new VDP(Vdp.VdpMode);
|
||||
Vdp = new VDP(Vdp.VdpMode, DisplayType);
|
||||
PSG.Reset();
|
||||
YM2413.Reset();
|
||||
SystemRam = new byte[0x2000];
|
||||
|
@ -123,26 +114,17 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
RomData = game.GetRomData();
|
||||
RomBanks = (byte)(RomData.Length/BankSize);
|
||||
Options = game.GetOptions();
|
||||
DisplayType = DisplayType.NTSC;
|
||||
foreach (string option in Options)
|
||||
{
|
||||
var args = option.Split('=');
|
||||
if (option == "FM") HasYM2413 = true;
|
||||
else if (args[0] == "IPeriod") IPeriod = int.Parse(args[1]);
|
||||
else if (args[0] == "Japan") Region = "Japan";
|
||||
else if (args[0] == "PAL") DisplayType = DisplayType.PAL;
|
||||
}
|
||||
|
||||
Init();
|
||||
|
||||
// In Outrun FM mode, when you start a race, the PSG noise channel is left on until a "wheel squeeling"
|
||||
// sound effect occurs, and this happens again every "extended play" checkpoint. Every emulator I have tested
|
||||
// does this; if it's a bug, it is a bug that no emulator gets right.
|
||||
// In any case, it is annoying, so this turns it off.
|
||||
// My view is that because I believe it to be a game bug (not an emulation bug), this doesn't count as a game-specific hack :)
|
||||
|
||||
if (HasYM2413 && game.Name.StartsWith("OutRun", StringComparison.InvariantCultureIgnoreCase))
|
||||
SoundMixer.DisableSource(PSG);
|
||||
|
||||
// TODO: at some point we need a proper Game Library construct with various metadata about emulation hints and options for games and roms.
|
||||
}
|
||||
|
||||
public byte ReadPort(ushort port)
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
{
|
||||
public partial class VDP
|
||||
{
|
||||
// TODO: PAL video modes, HCounter
|
||||
|
||||
// TODO: HCounter
|
||||
private readonly byte[] VLineCounterTableNTSC192 =
|
||||
{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
|
@ -25,9 +24,54 @@
|
|||
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
|
||||
};
|
||||
|
||||
|
||||
private readonly byte[] VLineCounterTableNTSC240 =
|
||||
{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
|
||||
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
|
||||
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
|
||||
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
|
||||
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
|
||||
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
|
||||
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05
|
||||
};
|
||||
|
||||
private readonly byte[] VLineCounterTablePAL192 =
|
||||
{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
|
||||
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
|
||||
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
|
||||
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
|
||||
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
|
||||
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
|
||||
0xF0, 0xF1, 0xF2,
|
||||
0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
|
||||
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
|
||||
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
|
||||
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
|
||||
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
|
||||
};
|
||||
|
||||
private readonly byte[] VLineCounterTablePAL240 =
|
||||
{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
|
||||
|
@ -44,7 +88,10 @@
|
|||
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
|
||||
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
|
||||
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
|
||||
0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
|
||||
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
|
||||
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Emulates the Texas Instruments TMS9918 VDP.
|
||||
/// Emulates the Texas Instruments TMS9918(A) VDP.
|
||||
/// </summary>
|
||||
public sealed partial class VDP : IVideoProvider
|
||||
{
|
||||
|
@ -46,6 +46,8 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
public int[] FrameBuffer = new int[256*192];
|
||||
public int[] GameGearFrameBuffer = new int[160*144];
|
||||
|
||||
private DisplayType DisplayType = DisplayType.NTSC;
|
||||
|
||||
// preprocessed state assist stuff.
|
||||
public int[] Palette = new int[32];
|
||||
|
||||
|
@ -79,11 +81,12 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
private byte[] ScanlinePriorityBuffer = new byte[256];
|
||||
private byte[] SpriteCollisionBuffer = new byte[256];
|
||||
|
||||
public VDP(VdpMode mode)
|
||||
public VDP(VdpMode mode, DisplayType displayType)
|
||||
{
|
||||
this.mode = mode;
|
||||
if (mode == VdpMode.SMS) CRAM = new byte[32];
|
||||
if (mode == VdpMode.GameGear) CRAM = new byte[64];
|
||||
DisplayType = displayType;
|
||||
}
|
||||
|
||||
public byte ReadVram()
|
||||
|
@ -105,7 +108,16 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
|
||||
public byte ReadVLineCounter()
|
||||
{
|
||||
return FrameHeight == 240 ? VLineCounterTableNTSC240[ScanLine] : VLineCounterTableNTSC192[ScanLine];
|
||||
if (DisplayType == DisplayType.NTSC)
|
||||
{
|
||||
if (FrameHeight == 240)
|
||||
return VLineCounterTableNTSC240[ScanLine];
|
||||
return VLineCounterTableNTSC192[ScanLine];
|
||||
} else { // PAL
|
||||
if (FrameHeight == 240)
|
||||
return VLineCounterTablePAL240[ScanLine];
|
||||
return VLineCounterTablePAL192[ScanLine];
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteVdpRegister(byte value)
|
||||
|
|
|
@ -35,15 +35,21 @@ namespace BizHawk
|
|||
while (reader.EndOfStream == false)
|
||||
{
|
||||
string line = reader.ReadLine();
|
||||
if (line.Trim().Length == 0) continue;
|
||||
string[] items = line.Split('\t');
|
||||
|
||||
var Game = new GameInfo();
|
||||
Game.CRC32 = Int32.Parse(items[0], NumberStyles.HexNumber);
|
||||
Game.Name = items[2];
|
||||
Game.System = items[3];
|
||||
Game.MetaData = items.Length >= 6 ? items[5] : null;
|
||||
db[Game.CRC32] = Game;
|
||||
try
|
||||
{
|
||||
if (line.Trim().Length == 0) continue;
|
||||
string[] items = line.Split('\t');
|
||||
|
||||
var Game = new GameInfo();
|
||||
Game.CRC32 = Int32.Parse(items[0], NumberStyles.HexNumber);
|
||||
Game.Name = items[2];
|
||||
Game.System = items[3];
|
||||
Game.MetaData = items.Length >= 6 ? items[5] : null;
|
||||
db[Game.CRC32] = Game;
|
||||
} catch (Exception e)
|
||||
{
|
||||
Console.WriteLine("Error parsing database entry: "+line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,4 +29,6 @@ namespace BizHawk
|
|||
void LoadStateBinary(BinaryReader reader);
|
||||
byte[] SaveStateBinary();
|
||||
}
|
||||
|
||||
public enum DisplayType { NTSC, PAL }
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue