Another round of BizHawk.Emulation namespace changes
This commit is contained in:
parent
da16e8874b
commit
9266cafd2a
|
@ -3,6 +3,8 @@ using System.Linq;
|
|||
|
||||
using LuaInterface;
|
||||
using BizHawk.Emulation.Consoles.Nintendo;
|
||||
using BizHawk.Emulation.Cores.PCEngine;
|
||||
using BizHawk.Emulation.Cores.Sega.MasterSystem;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
|
@ -50,7 +52,7 @@ namespace BizHawk.Client.Common
|
|||
Global.CoreComm.NES_ShowOBJ = Global.Config.NESDispSprites = (bool)lua_p[0];
|
||||
Global.CoreComm.NES_ShowBG = Global.Config.NESDispBackground = (bool)lua_p[1];
|
||||
}
|
||||
else if (Global.Emulator is Emulation.Consoles.TurboGrafx.PCEngine)
|
||||
else if (Global.Emulator is PCEngine)
|
||||
{
|
||||
Global.CoreComm.PCE_ShowOBJ1 = Global.Config.PCEDispOBJ1 = (bool)lua_p[0];
|
||||
Global.CoreComm.PCE_ShowBG1 = Global.Config.PCEDispBG1 = (bool)lua_p[1];
|
||||
|
@ -60,7 +62,7 @@ namespace BizHawk.Client.Common
|
|||
Global.CoreComm.PCE_ShowBG2 = Global.Config.PCEDispBG2 = (bool)lua_p[3];
|
||||
}
|
||||
}
|
||||
else if (Global.Emulator is Emulation.Consoles.Sega.SMS)
|
||||
else if (Global.Emulator is SMS)
|
||||
{
|
||||
Global.CoreComm.SMS_ShowOBJ = Global.Config.SMSDispOBJ = (bool)lua_p[0];
|
||||
Global.CoreComm.SMS_ShowBG = Global.Config.SMSDispBG = (bool)lua_p[1];
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using BizHawk.Emulation.Consoles.Nintendo.SNES;
|
||||
using BizHawk.Emulation.Cores.Nintendo.SNES;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
|
|
|
@ -8,8 +8,8 @@ using BizHawk.Client.Common;
|
|||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Cores.Calculators;
|
||||
using BizHawk.Emulation.Cores.Atari.Atari2600;
|
||||
using BizHawk.Emulation.Cores.Nintendo.SNES;
|
||||
using BizHawk.Emulation.Cores.Nintendo.Gameboy;
|
||||
using BizHawk.Emulation.Consoles.Nintendo.SNES;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
|
|
|
@ -4,9 +4,9 @@ using System.Windows.Forms;
|
|||
|
||||
using BizHawk.Client.Common;
|
||||
using BizHawk.Emulation.Cores.Nintendo.GBA;
|
||||
using BizHawk.Emulation.Consoles.Sega;
|
||||
using BizHawk.Emulation.Consoles.Sega.Saturn;
|
||||
using BizHawk.Emulation.Consoles.Sony.PSP;
|
||||
using BizHawk.Emulation.Cores.Sega.Genesis;
|
||||
using BizHawk.Emulation.Cores.Sega.Saturn;
|
||||
using BizHawk.Emulation.Cores.Sony.PSP;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
|
|
|
@ -12,20 +12,28 @@ using BizHawk.Common;
|
|||
using BizHawk.Client.Common;
|
||||
using BizHawk.Emulation;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.DiscSystem;
|
||||
|
||||
using BizHawk.Emulation.Cores.Computers.Commodore64;
|
||||
using BizHawk.Emulation.Cores.Calculators;
|
||||
using BizHawk.Emulation.Cores.Atari.Atari2600;
|
||||
using BizHawk.Emulation.Cores.Atari.Atari7800;
|
||||
using BizHawk.Emulation.Cores.ColecoVision;
|
||||
using BizHawk.Emulation.Cores.Nintendo.Gameboy;
|
||||
using BizHawk.Emulation.Cores.Intellivision;
|
||||
using BizHawk.Emulation.Cores.PCEngine;
|
||||
|
||||
using BizHawk.Emulation.Consoles.Nintendo;
|
||||
using BizHawk.Emulation.Cores.Nintendo.GBA;
|
||||
using BizHawk.Emulation.Cores.Nintendo.SNES;
|
||||
using BizHawk.Emulation.Cores.Nintendo.N64;
|
||||
using BizHawk.Emulation.Consoles.Nintendo.SNES;
|
||||
using BizHawk.Emulation.Consoles.Sega;
|
||||
using BizHawk.Emulation.Consoles.TurboGrafx;
|
||||
using BizHawk.Emulation.DiscSystem;
|
||||
using BizHawk.Emulation.Cores.Nintendo.Gameboy;
|
||||
using BizHawk.Emulation.Cores.Nintendo.GBA;
|
||||
|
||||
using BizHawk.Emulation.Cores.Sega.MasterSystem;
|
||||
using BizHawk.Emulation.Cores.Sega.Genesis;
|
||||
using BizHawk.Emulation.Cores.Sega.Saturn;
|
||||
|
||||
using BizHawk.Emulation.Cores.Sony.PSX;
|
||||
using BizHawk.Emulation.Cores.Sony.PSP;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
|
@ -1457,10 +1465,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
return ret;
|
||||
}
|
||||
|
||||
private void SaturnSetPrefs(Emulation.Consoles.Sega.Saturn.Yabause e = null)
|
||||
private void SaturnSetPrefs(Yabause e = null)
|
||||
{
|
||||
if (e == null)
|
||||
e = Global.Emulator as Emulation.Consoles.Sega.Saturn.Yabause;
|
||||
e = Global.Emulator as Yabause;
|
||||
|
||||
if (Global.Config.SaturnUseGL != e.GLMode)
|
||||
{
|
||||
|
@ -3128,20 +3136,20 @@ namespace BizHawk.Client.EmuHawk
|
|||
MessageBox.Show("Saturn BIOS not found. Please check firmware configurations.");
|
||||
return false;
|
||||
}
|
||||
var saturn = new Emulation.Consoles.Sega.Saturn.Yabause(nextComm, disc, File.ReadAllBytes(biosPath), Global.Config.SaturnUseGL);
|
||||
var saturn = new Yabause(nextComm, disc, File.ReadAllBytes(biosPath), Global.Config.SaturnUseGL);
|
||||
nextEmulator = saturn;
|
||||
SaturnSetPrefs(saturn);
|
||||
}
|
||||
break;
|
||||
case "PSP":
|
||||
{
|
||||
var psp = new Emulation.Consoles.Sony.PSP.PSP(nextComm, file.Name);
|
||||
var psp = new PSP(nextComm, file.Name);
|
||||
nextEmulator = psp;
|
||||
}
|
||||
break;
|
||||
case "PSX":
|
||||
{
|
||||
var psx = new Emulation.Consoles.PSX.Octoshock(nextComm);
|
||||
var psx = new Octoshock(nextComm);
|
||||
nextEmulator = psx;
|
||||
psx.LoadCuePath(file.CanonicalFullPath);
|
||||
nextEmulator.CoreComm.RomStatusDetails = "PSX etc.";
|
||||
|
|
|
@ -4,11 +4,11 @@ using System.IO;
|
|||
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Cores.ColecoVision;
|
||||
using BizHawk.Emulation.Cores.Nintendo.Gameboy;
|
||||
using BizHawk.Emulation.Consoles.Nintendo.SNES;
|
||||
using BizHawk.Emulation.Consoles.Sega;
|
||||
using BizHawk.Emulation.Cores.Sega.MasterSystem;
|
||||
using BizHawk.Emulation.Consoles.Nintendo;
|
||||
using BizHawk.Emulation.Cores.Nintendo.SNES;
|
||||
using BizHawk.Emulation.Cores.Nintendo.N64;
|
||||
using BizHawk.Emulation.Cores.Nintendo.Gameboy;
|
||||
using BizHawk.Client.Common;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
|
|
|
@ -10,9 +10,9 @@ using System.Threading.Tasks;
|
|||
using System.Windows.Forms;
|
||||
|
||||
using BizHawk.Client.Common;
|
||||
using BizHawk.Emulation.Consoles.Nintendo.SNES;
|
||||
using BizHawk.Emulation.Consoles.Nintendo;
|
||||
using BizHawk.Emulation.Consoles.Sega;
|
||||
using BizHawk.Emulation.Cores.Nintendo.SNES;
|
||||
using BizHawk.Emulation.Cores.Sega.Genesis;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
|
|
|
@ -6,7 +6,7 @@ using System.Globalization;
|
|||
using System.Text.RegularExpressions;
|
||||
|
||||
using BizHawk.Client.Common;
|
||||
using BizHawk.Emulation.Consoles.Sega;
|
||||
using BizHawk.Emulation.Cores.Sega.Genesis;
|
||||
|
||||
#pragma warning disable 675 //TOOD: fix the potential problem this is masking
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ using System.Windows.Forms;
|
|||
using System.Drawing.Imaging;
|
||||
|
||||
using BizHawk.Client.Common;
|
||||
using BizHawk.Emulation.Consoles.TurboGrafx;
|
||||
using BizHawk.Emulation.Cores.PCEngine;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
|
|
|
@ -4,9 +4,9 @@ using System.Drawing;
|
|||
using System.Windows.Forms;
|
||||
using System.Globalization;
|
||||
using System.Text.RegularExpressions;
|
||||
using BizHawk.Emulation.Consoles.Nintendo.SNES;
|
||||
|
||||
using BizHawk.Client.Common;
|
||||
using BizHawk.Emulation.Cores.Nintendo.SNES;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
|
@ -36,9 +36,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
InitializeComponent();
|
||||
Closing += (o, e) => SaveConfigSettings();
|
||||
//including transposition
|
||||
//Code: D F 4 7 0 9 1 5 6 B C 8 A 2 3 E
|
||||
//Hex: 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
//including transposition
|
||||
//Code: D F 4 7 0 9 1 5 6 B C 8 A 2 3 E
|
||||
//Hex: 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
|
||||
GameGenieTable.Add('D', 0); //0000
|
||||
GameGenieTable.Add('F', 1); //0001
|
||||
|
|
|
@ -31,7 +31,7 @@ using System.Windows.Forms;
|
|||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Client.Common;
|
||||
using BizHawk.Emulation.Consoles.Nintendo.SNES;
|
||||
using BizHawk.Emulation.Cores.Nintendo.SNES;
|
||||
using BizHawk.Client.EmuHawk; //TODO: What??
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
|
|
|
@ -3,10 +3,9 @@ using System.Drawing;
|
|||
using System.Windows.Forms;
|
||||
|
||||
using BizHawk.Client.Common;
|
||||
using BizHawk.Emulation.Consoles.Nintendo;
|
||||
using BizHawk.Emulation.Cores.Calculators;
|
||||
using BizHawk.Emulation.Consoles.Nintendo.SNES;
|
||||
using BizHawk.Emulation.Consoles.Sega;
|
||||
using BizHawk.Emulation.Consoles.Nintendo;
|
||||
using BizHawk.Emulation.Cores.Nintendo.SNES;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
|
|
|
@ -5,6 +5,7 @@ using System.Linq;
|
|||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Cores.Nintendo.SNES;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
||||
{
|
||||
|
@ -31,8 +32,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
|||
|
||||
const int SampPerFrame = 35112;
|
||||
|
||||
Consoles.Nintendo.SNES.LibsnesCore.SnesSaveController LCont = new BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesCore.SnesSaveController(Gameboy.GbController);
|
||||
Consoles.Nintendo.SNES.LibsnesCore.SnesSaveController RCont = new BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesCore.SnesSaveController(Gameboy.GbController);
|
||||
LibsnesCore.SnesSaveController LCont = new LibsnesCore.SnesSaveController(Gameboy.GbController);
|
||||
LibsnesCore.SnesSaveController RCont = new LibsnesCore.SnesSaveController(Gameboy.GbController);
|
||||
|
||||
public GambatteLink(CoreComm comm, GameInfo leftinfo, byte[] leftrom, GameInfo rightinfo, byte[] rightrom)
|
||||
{
|
||||
|
|
|
@ -6,7 +6,7 @@ using System.Collections.Generic;
|
|||
using System.Runtime.InteropServices;
|
||||
using System.IO.MemoryMappedFiles;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Nintendo.SNES
|
||||
namespace BizHawk.Emulation.Cores.Nintendo.SNES
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -18,7 +18,7 @@ using System.Runtime.InteropServices;
|
|||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Nintendo.SNES
|
||||
namespace BizHawk.Emulation.Cores.Nintendo.SNES
|
||||
{
|
||||
|
||||
public class ScanlineHookManager
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
using System;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Nintendo.SNES
|
||||
namespace BizHawk.Emulation.Cores.Nintendo.SNES
|
||||
{
|
||||
|
||||
public unsafe class SNESGraphicsDecoder : IDisposable
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace BizHawk.Emulation.Consoles.Nintendo.SNES
|
||||
namespace BizHawk.Emulation.Cores.Nintendo.SNES
|
||||
{
|
||||
public static class SnesColors
|
||||
{
|
||||
|
|
|
@ -6,7 +6,7 @@ using System.Globalization;
|
|||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.TurboGrafx
|
||||
namespace BizHawk.Emulation.Cores.PCEngine
|
||||
{
|
||||
public sealed class ADPCM : ISoundProvider
|
||||
{
|
||||
|
|
|
@ -4,7 +4,7 @@ using System.Globalization;
|
|||
|
||||
using BizHawk.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.TurboGrafx
|
||||
namespace BizHawk.Emulation.Cores.PCEngine
|
||||
{
|
||||
partial class PCEngine
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.TurboGrafx
|
||||
namespace BizHawk.Emulation.Cores.PCEngine
|
||||
{
|
||||
public partial class PCEngine
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using BizHawk.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.TurboGrafx
|
||||
namespace BizHawk.Emulation.Cores.PCEngine
|
||||
{
|
||||
public partial class PCEngine
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using BizHawk.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.TurboGrafx
|
||||
namespace BizHawk.Emulation.Cores.PCEngine
|
||||
{
|
||||
public partial class PCEngine
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using BizHawk.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.TurboGrafx
|
||||
namespace BizHawk.Emulation.Cores.PCEngine
|
||||
{
|
||||
public partial class PCEngine
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using BizHawk.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.TurboGrafx
|
||||
namespace BizHawk.Emulation.Cores.PCEngine
|
||||
{
|
||||
public partial class PCEngine
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using BizHawk.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.TurboGrafx
|
||||
namespace BizHawk.Emulation.Cores.PCEngine
|
||||
{
|
||||
public partial class PCEngine
|
||||
{
|
||||
|
|
|
@ -9,7 +9,7 @@ using BizHawk.Emulation.CPUs.H6280;
|
|||
using BizHawk.Emulation.DiscSystem;
|
||||
using BizHawk.Emulation.Sound;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.TurboGrafx
|
||||
namespace BizHawk.Emulation.Cores.PCEngine
|
||||
{
|
||||
public enum NecSystemType { TurboGrafx, TurboCD, SuperGrafx }
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ using BizHawk.Common;
|
|||
using BizHawk.Emulation.DiscSystem;
|
||||
using BizHawk.Emulation.Sound;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.TurboGrafx
|
||||
namespace BizHawk.Emulation.Cores.PCEngine
|
||||
{
|
||||
// TODO we can adjust this to have Think take the number of cycles and not require
|
||||
// a reference to Cpu.TotalExecutedCycles
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using BizHawk.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.TurboGrafx
|
||||
namespace BizHawk.Emulation.Cores.PCEngine
|
||||
{
|
||||
public partial class PCEngine
|
||||
{
|
||||
|
|
|
@ -4,141 +4,141 @@ using System.IO;
|
|||
|
||||
using BizHawk.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.TurboGrafx
|
||||
namespace BizHawk.Emulation.Cores.PCEngine
|
||||
{
|
||||
// HuC6260 Video Color Encoder
|
||||
public sealed class VCE
|
||||
{
|
||||
public ushort VceAddress;
|
||||
public ushort[] VceData = new ushort[512];
|
||||
public int[] Palette = new int[512];
|
||||
public byte CR;
|
||||
// HuC6260 Video Color Encoder
|
||||
public sealed class VCE
|
||||
{
|
||||
public ushort VceAddress;
|
||||
public ushort[] VceData = new ushort[512];
|
||||
public int[] Palette = new int[512];
|
||||
public byte CR;
|
||||
|
||||
public int NumberOfScanlines { get { return ((CR & 4) != 0) ? 263 : 262; } }
|
||||
public int DotClock
|
||||
{
|
||||
get
|
||||
{
|
||||
int clock = CR & 3;
|
||||
if (clock == 3)
|
||||
clock = 2;
|
||||
return clock;
|
||||
}
|
||||
}
|
||||
public int NumberOfScanlines { get { return ((CR & 4) != 0) ? 263 : 262; } }
|
||||
public int DotClock
|
||||
{
|
||||
get
|
||||
{
|
||||
int clock = CR & 3;
|
||||
if (clock == 3)
|
||||
clock = 2;
|
||||
return clock;
|
||||
}
|
||||
}
|
||||
|
||||
// guess the dot clock affects wait states in combination with the dot with regs.
|
||||
// We dont currently emulate wait states, probably will have to eventually...
|
||||
// guess the dot clock affects wait states in combination with the dot with regs.
|
||||
// We dont currently emulate wait states, probably will have to eventually...
|
||||
|
||||
// Note: To keep the VCE class from needing a reference to the CPU, the 1-cycle access
|
||||
// penalty for the VCE is handled by the memory mappers.
|
||||
// One day I guess I could create an ICpu with a StealCycles method...
|
||||
// Note: To keep the VCE class from needing a reference to the CPU, the 1-cycle access
|
||||
// penalty for the VCE is handled by the memory mappers.
|
||||
// One day I guess I could create an ICpu with a StealCycles method...
|
||||
|
||||
public void WriteVCE(int port, byte value)
|
||||
{
|
||||
port &= 0x07;
|
||||
switch (port)
|
||||
{
|
||||
case 0: // Control Port
|
||||
CR = value;
|
||||
break;
|
||||
case 2: // Address LSB
|
||||
VceAddress &= 0xFF00;
|
||||
VceAddress |= value;
|
||||
break;
|
||||
case 3: // Address MSB
|
||||
VceAddress &= 0x00FF;
|
||||
VceAddress |= (ushort) (value << 8);
|
||||
VceAddress &= 0x01FF;
|
||||
break;
|
||||
case 4: // Data LSB
|
||||
VceData[VceAddress] &= 0xFF00;
|
||||
VceData[VceAddress] |= value;
|
||||
PrecomputePalette(VceAddress);
|
||||
break;
|
||||
case 5: // Data MSB
|
||||
VceData[VceAddress] &= 0x00FF;
|
||||
VceData[VceAddress] |= (ushort) (value << 8);
|
||||
PrecomputePalette(VceAddress);
|
||||
VceAddress++;
|
||||
VceAddress &= 0x1FF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
public void WriteVCE(int port, byte value)
|
||||
{
|
||||
port &= 0x07;
|
||||
switch (port)
|
||||
{
|
||||
case 0: // Control Port
|
||||
CR = value;
|
||||
break;
|
||||
case 2: // Address LSB
|
||||
VceAddress &= 0xFF00;
|
||||
VceAddress |= value;
|
||||
break;
|
||||
case 3: // Address MSB
|
||||
VceAddress &= 0x00FF;
|
||||
VceAddress |= (ushort)(value << 8);
|
||||
VceAddress &= 0x01FF;
|
||||
break;
|
||||
case 4: // Data LSB
|
||||
VceData[VceAddress] &= 0xFF00;
|
||||
VceData[VceAddress] |= value;
|
||||
PrecomputePalette(VceAddress);
|
||||
break;
|
||||
case 5: // Data MSB
|
||||
VceData[VceAddress] &= 0x00FF;
|
||||
VceData[VceAddress] |= (ushort)(value << 8);
|
||||
PrecomputePalette(VceAddress);
|
||||
VceAddress++;
|
||||
VceAddress &= 0x1FF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public byte ReadVCE(int port)
|
||||
{
|
||||
port &= 0x07;
|
||||
switch (port)
|
||||
{
|
||||
case 4: // Data LSB
|
||||
return (byte) (VceData[VceAddress] & 0xFF);
|
||||
case 5: // Data MSB
|
||||
byte value = (byte) ((VceData[VceAddress] >> 8) | 0xFE);
|
||||
VceAddress++;
|
||||
VceAddress &= 0x1FF;
|
||||
return value;
|
||||
default: return 0xFF;
|
||||
}
|
||||
}
|
||||
public byte ReadVCE(int port)
|
||||
{
|
||||
port &= 0x07;
|
||||
switch (port)
|
||||
{
|
||||
case 4: // Data LSB
|
||||
return (byte)(VceData[VceAddress] & 0xFF);
|
||||
case 5: // Data MSB
|
||||
byte value = (byte)((VceData[VceAddress] >> 8) | 0xFE);
|
||||
VceAddress++;
|
||||
VceAddress &= 0x1FF;
|
||||
return value;
|
||||
default: return 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
static readonly byte[] PalConvert = {0, 36, 72, 109, 145, 182, 218, 255};
|
||||
static readonly byte[] PalConvert = { 0, 36, 72, 109, 145, 182, 218, 255 };
|
||||
|
||||
public void PrecomputePalette(int slot)
|
||||
{
|
||||
byte r = PalConvert[(VceData[slot] >> 3) & 7];
|
||||
byte g = PalConvert[(VceData[slot] >> 6) & 7];
|
||||
byte b = PalConvert[VceData[slot] & 7];
|
||||
Palette[slot] = Colors.ARGB(r, g, b);
|
||||
}
|
||||
public void PrecomputePalette(int slot)
|
||||
{
|
||||
byte r = PalConvert[(VceData[slot] >> 3) & 7];
|
||||
byte g = PalConvert[(VceData[slot] >> 6) & 7];
|
||||
byte b = PalConvert[VceData[slot] & 7];
|
||||
Palette[slot] = Colors.ARGB(r, g, b);
|
||||
}
|
||||
|
||||
public void SaveStateText(TextWriter writer)
|
||||
{
|
||||
writer.WriteLine("[VCE]");
|
||||
writer.WriteLine("VceAddress {0:X4}", VceAddress);
|
||||
writer.WriteLine("CR {0}", CR);
|
||||
writer.Write("VceData ");
|
||||
VceData.SaveAsHex(writer);
|
||||
writer.WriteLine("[/VCE]\n");
|
||||
}
|
||||
public void SaveStateText(TextWriter writer)
|
||||
{
|
||||
writer.WriteLine("[VCE]");
|
||||
writer.WriteLine("VceAddress {0:X4}", VceAddress);
|
||||
writer.WriteLine("CR {0}", CR);
|
||||
writer.Write("VceData ");
|
||||
VceData.SaveAsHex(writer);
|
||||
writer.WriteLine("[/VCE]\n");
|
||||
}
|
||||
|
||||
public void LoadStateText(TextReader reader)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
string[] args = reader.ReadLine().Split(' ');
|
||||
if (args[0].Trim() == "") continue;
|
||||
if (args[0] == "[/VCE]") break;
|
||||
if (args[0] == "VceAddress")
|
||||
VceAddress = ushort.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "CR")
|
||||
CR = byte.Parse(args[1]);
|
||||
else if (args[0] == "VceData")
|
||||
VceData.ReadFromHex(args[1]);
|
||||
else
|
||||
Console.WriteLine("Skipping unrecognized identifier " + args[0]);
|
||||
}
|
||||
public void LoadStateText(TextReader reader)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
string[] args = reader.ReadLine().Split(' ');
|
||||
if (args[0].Trim() == "") continue;
|
||||
if (args[0] == "[/VCE]") break;
|
||||
if (args[0] == "VceAddress")
|
||||
VceAddress = ushort.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "CR")
|
||||
CR = byte.Parse(args[1]);
|
||||
else if (args[0] == "VceData")
|
||||
VceData.ReadFromHex(args[1]);
|
||||
else
|
||||
Console.WriteLine("Skipping unrecognized identifier " + args[0]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < VceData.Length; i++)
|
||||
PrecomputePalette(i);
|
||||
}
|
||||
for (int i = 0; i < VceData.Length; i++)
|
||||
PrecomputePalette(i);
|
||||
}
|
||||
|
||||
public void SaveStateBinary(BinaryWriter writer)
|
||||
{
|
||||
writer.Write(VceAddress);
|
||||
writer.Write(CR);
|
||||
for (int i = 0; i < VceData.Length; i++)
|
||||
writer.Write(VceData[i]);
|
||||
}
|
||||
public void SaveStateBinary(BinaryWriter writer)
|
||||
{
|
||||
writer.Write(VceAddress);
|
||||
writer.Write(CR);
|
||||
for (int i = 0; i < VceData.Length; i++)
|
||||
writer.Write(VceData[i]);
|
||||
}
|
||||
|
||||
public void LoadStateBinary(BinaryReader reader)
|
||||
{
|
||||
VceAddress = reader.ReadUInt16();
|
||||
CR = reader.ReadByte();
|
||||
for (int i = 0; i < VceData.Length; i++)
|
||||
{
|
||||
VceData[i] = reader.ReadUInt16();
|
||||
PrecomputePalette(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void LoadStateBinary(BinaryReader reader)
|
||||
{
|
||||
VceAddress = reader.ReadUInt16();
|
||||
CR = reader.ReadByte();
|
||||
for (int i = 0; i < VceData.Length; i++)
|
||||
{
|
||||
VceData[i] = reader.ReadUInt16();
|
||||
PrecomputePalette(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,353 +1,353 @@
|
|||
using System;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.TurboGrafx
|
||||
namespace BizHawk.Emulation.Cores.PCEngine
|
||||
{
|
||||
// This rendering code is only used for TurboGrafx/TurboCD Mode.
|
||||
// In SuperGrafx mode, separate rendering functions in the VPC class are used.
|
||||
// This rendering code is only used for TurboGrafx/TurboCD Mode.
|
||||
// In SuperGrafx mode, separate rendering functions in the VPC class are used.
|
||||
|
||||
public partial class VDC
|
||||
{
|
||||
/* There are many line-counters here. Here is a breakdown of what they each are:
|
||||
public partial class VDC
|
||||
{
|
||||
/* There are many line-counters here. Here is a breakdown of what they each are:
|
||||
|
||||
+ ScanLine is the current NTSC scanline. It has a range from 0 to 262.
|
||||
+ ActiveLine is the current offset into the framebuffer. 0 is the first
|
||||
line of active display, and the last value will be BufferHeight-1.
|
||||
+ BackgroundY is the current offset into the scroll plane. It is set with BYR
|
||||
register at certain sync points and incremented every scanline.
|
||||
Its values range from 0 - $1FF.
|
||||
+ RCRCounter is set to $40 at the first line of active display, and incremented each
|
||||
scanline thereafter.
|
||||
*/
|
||||
public int ScanLine;
|
||||
public int BackgroundY;
|
||||
public int RCRCounter;
|
||||
public int ActiveLine;
|
||||
+ ScanLine is the current NTSC scanline. It has a range from 0 to 262.
|
||||
+ ActiveLine is the current offset into the framebuffer. 0 is the first
|
||||
line of active display, and the last value will be BufferHeight-1.
|
||||
+ BackgroundY is the current offset into the scroll plane. It is set with BYR
|
||||
register at certain sync points and incremented every scanline.
|
||||
Its values range from 0 - $1FF.
|
||||
+ RCRCounter is set to $40 at the first line of active display, and incremented each
|
||||
scanline thereafter.
|
||||
*/
|
||||
public int ScanLine;
|
||||
public int BackgroundY;
|
||||
public int RCRCounter;
|
||||
public int ActiveLine;
|
||||
|
||||
public int HBlankCycles = 79;
|
||||
public bool PerformSpriteLimit;
|
||||
public int HBlankCycles = 79;
|
||||
public bool PerformSpriteLimit;
|
||||
|
||||
byte[] PriorityBuffer = new byte[512];
|
||||
byte[] InterSpritePriorityBuffer = new byte[512];
|
||||
byte[] PriorityBuffer = new byte[512];
|
||||
byte[] InterSpritePriorityBuffer = new byte[512];
|
||||
|
||||
public void ExecFrame(bool render)
|
||||
{
|
||||
if (MultiResHack > 0 && render)
|
||||
Array.Clear(FrameBuffer, 0, FrameBuffer.Length);
|
||||
|
||||
while (true)
|
||||
{
|
||||
int ActiveDisplayStartLine = DisplayStartLine;
|
||||
int VBlankLine = ActiveDisplayStartLine + Registers[VDW] + 1;
|
||||
if (VBlankLine > 261)
|
||||
VBlankLine = 261;
|
||||
ActiveLine = ScanLine - ActiveDisplayStartLine;
|
||||
bool InActiveDisplay = (ScanLine >= ActiveDisplayStartLine) && (ScanLine < VBlankLine);
|
||||
public void ExecFrame(bool render)
|
||||
{
|
||||
if (MultiResHack > 0 && render)
|
||||
Array.Clear(FrameBuffer, 0, FrameBuffer.Length);
|
||||
|
||||
if (ScanLine == ActiveDisplayStartLine)
|
||||
RCRCounter = 0x40;
|
||||
while (true)
|
||||
{
|
||||
int ActiveDisplayStartLine = DisplayStartLine;
|
||||
int VBlankLine = ActiveDisplayStartLine + Registers[VDW] + 1;
|
||||
if (VBlankLine > 261)
|
||||
VBlankLine = 261;
|
||||
ActiveLine = ScanLine - ActiveDisplayStartLine;
|
||||
bool InActiveDisplay = (ScanLine >= ActiveDisplayStartLine) && (ScanLine < VBlankLine);
|
||||
|
||||
if (ScanLine == VBlankLine)
|
||||
UpdateSpriteAttributeTable();
|
||||
if (ScanLine == ActiveDisplayStartLine)
|
||||
RCRCounter = 0x40;
|
||||
|
||||
if (RCRCounter == (Registers[RCR] & 0x3FF))
|
||||
{
|
||||
if (RasterCompareInterruptEnabled)
|
||||
{
|
||||
StatusByte |= StatusRasterCompare;
|
||||
cpu.IRQ1Assert = true;
|
||||
}
|
||||
}
|
||||
if (ScanLine == VBlankLine)
|
||||
UpdateSpriteAttributeTable();
|
||||
|
||||
cpu.Execute(HBlankCycles);
|
||||
if (RCRCounter == (Registers[RCR] & 0x3FF))
|
||||
{
|
||||
if (RasterCompareInterruptEnabled)
|
||||
{
|
||||
StatusByte |= StatusRasterCompare;
|
||||
cpu.IRQ1Assert = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (InActiveDisplay)
|
||||
{
|
||||
if (ScanLine == ActiveDisplayStartLine)
|
||||
BackgroundY = Registers[BYR];
|
||||
else
|
||||
{
|
||||
BackgroundY++;
|
||||
BackgroundY &= 0x01FF;
|
||||
}
|
||||
if (render) RenderScanLine();
|
||||
}
|
||||
cpu.Execute(HBlankCycles);
|
||||
|
||||
if (ScanLine == VBlankLine && VBlankInterruptEnabled)
|
||||
StatusByte |= StatusVerticalBlanking;
|
||||
if (InActiveDisplay)
|
||||
{
|
||||
if (ScanLine == ActiveDisplayStartLine)
|
||||
BackgroundY = Registers[BYR];
|
||||
else
|
||||
{
|
||||
BackgroundY++;
|
||||
BackgroundY &= 0x01FF;
|
||||
}
|
||||
if (render) RenderScanLine();
|
||||
}
|
||||
|
||||
if (ScanLine == VBlankLine + 4 && SatDmaPerformed)
|
||||
{
|
||||
SatDmaPerformed = false;
|
||||
if ((Registers[DCR] & 1) > 0)
|
||||
StatusByte |= StatusVramSatDmaComplete;
|
||||
}
|
||||
if (ScanLine == VBlankLine && VBlankInterruptEnabled)
|
||||
StatusByte |= StatusVerticalBlanking;
|
||||
|
||||
cpu.Execute(2);
|
||||
if (ScanLine == VBlankLine + 4 && SatDmaPerformed)
|
||||
{
|
||||
SatDmaPerformed = false;
|
||||
if ((Registers[DCR] & 1) > 0)
|
||||
StatusByte |= StatusVramSatDmaComplete;
|
||||
}
|
||||
|
||||
if ((StatusByte & (StatusVerticalBlanking | StatusVramSatDmaComplete)) != 0)
|
||||
cpu.IRQ1Assert = true;
|
||||
cpu.Execute(2);
|
||||
|
||||
cpu.Execute(455 - HBlankCycles - 2);
|
||||
if ((StatusByte & (StatusVerticalBlanking | StatusVramSatDmaComplete)) != 0)
|
||||
cpu.IRQ1Assert = true;
|
||||
|
||||
if (InActiveDisplay == false && DmaRequested)
|
||||
RunDmaForScanline();
|
||||
cpu.Execute(455 - HBlankCycles - 2);
|
||||
|
||||
ScanLine++;
|
||||
RCRCounter++;
|
||||
if (InActiveDisplay == false && DmaRequested)
|
||||
RunDmaForScanline();
|
||||
|
||||
if (ScanLine == vce.NumberOfScanlines)
|
||||
{
|
||||
ScanLine = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ScanLine++;
|
||||
RCRCounter++;
|
||||
|
||||
public void RenderScanLine()
|
||||
{
|
||||
if (ActiveLine >= FrameHeight)
|
||||
return;
|
||||
if (ScanLine == vce.NumberOfScanlines)
|
||||
{
|
||||
ScanLine = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RenderBackgroundScanline(pce.CoreComm.PCE_ShowBG1);
|
||||
RenderSpritesScanline(pce.CoreComm.PCE_ShowOBJ1);
|
||||
}
|
||||
public void RenderScanLine()
|
||||
{
|
||||
if (ActiveLine >= FrameHeight)
|
||||
return;
|
||||
|
||||
void RenderBackgroundScanline(bool show)
|
||||
{
|
||||
Array.Clear(PriorityBuffer, 0, FrameWidth);
|
||||
RenderBackgroundScanline(pce.CoreComm.PCE_ShowBG1);
|
||||
RenderSpritesScanline(pce.CoreComm.PCE_ShowOBJ1);
|
||||
}
|
||||
|
||||
if (BackgroundEnabled == false)
|
||||
{
|
||||
for (int i = 0; i < FrameWidth; i++)
|
||||
FrameBuffer[(ActiveLine * FramePitch) + i] = vce.Palette[256];
|
||||
return;
|
||||
}
|
||||
void RenderBackgroundScanline(bool show)
|
||||
{
|
||||
Array.Clear(PriorityBuffer, 0, FrameWidth);
|
||||
|
||||
int batHeight = BatHeight * 8;
|
||||
int batWidth = BatWidth * 8;
|
||||
if (BackgroundEnabled == false)
|
||||
{
|
||||
for (int i = 0; i < FrameWidth; i++)
|
||||
FrameBuffer[(ActiveLine * FramePitch) + i] = vce.Palette[256];
|
||||
return;
|
||||
}
|
||||
|
||||
int vertLine = BackgroundY;
|
||||
vertLine %= batHeight;
|
||||
int yTile = (vertLine / 8);
|
||||
int yOfs = vertLine % 8;
|
||||
int batHeight = BatHeight * 8;
|
||||
int batWidth = BatWidth * 8;
|
||||
|
||||
// This is not optimized. But it seems likely to remain that way.
|
||||
int xScroll = Registers[BXR] & 0x3FF;
|
||||
for (int x = 0; x < FrameWidth; x++)
|
||||
{
|
||||
int xTile = ((x + xScroll) / 8) % BatWidth;
|
||||
int xOfs = (x + xScroll) & 7;
|
||||
int tileNo = VRAM[(ushort)(((yTile * BatWidth) + xTile))] & 2047;
|
||||
int paletteNo = VRAM[(ushort)(((yTile * BatWidth) + xTile))] >> 12;
|
||||
int paletteBase = paletteNo * 16;
|
||||
int vertLine = BackgroundY;
|
||||
vertLine %= batHeight;
|
||||
int yTile = (vertLine / 8);
|
||||
int yOfs = vertLine % 8;
|
||||
|
||||
byte c = PatternBuffer[(tileNo * 64) + (yOfs * 8) + xOfs];
|
||||
if (c == 0)
|
||||
FrameBuffer[(ActiveLine * FramePitch) + x] = vce.Palette[0];
|
||||
else
|
||||
{
|
||||
FrameBuffer[(ActiveLine * FramePitch) + x] = show ? vce.Palette[paletteBase + c] : vce.Palette[0];
|
||||
PriorityBuffer[x] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
// This is not optimized. But it seems likely to remain that way.
|
||||
int xScroll = Registers[BXR] & 0x3FF;
|
||||
for (int x = 0; x < FrameWidth; x++)
|
||||
{
|
||||
int xTile = ((x + xScroll) / 8) % BatWidth;
|
||||
int xOfs = (x + xScroll) & 7;
|
||||
int tileNo = VRAM[(ushort)(((yTile * BatWidth) + xTile))] & 2047;
|
||||
int paletteNo = VRAM[(ushort)(((yTile * BatWidth) + xTile))] >> 12;
|
||||
int paletteBase = paletteNo * 16;
|
||||
|
||||
byte[] heightTable = { 16, 32, 64, 64 };
|
||||
byte c = PatternBuffer[(tileNo * 64) + (yOfs * 8) + xOfs];
|
||||
if (c == 0)
|
||||
FrameBuffer[(ActiveLine * FramePitch) + x] = vce.Palette[0];
|
||||
else
|
||||
{
|
||||
FrameBuffer[(ActiveLine * FramePitch) + x] = show ? vce.Palette[paletteBase + c] : vce.Palette[0];
|
||||
PriorityBuffer[x] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RenderSpritesScanline(bool show)
|
||||
{
|
||||
if (SpritesEnabled == false)
|
||||
return;
|
||||
byte[] heightTable = { 16, 32, 64, 64 };
|
||||
|
||||
Array.Clear(InterSpritePriorityBuffer, 0, FrameWidth);
|
||||
bool Sprite4ColorMode = Sprite4ColorModeEnabled;
|
||||
int activeSprites = 0;
|
||||
public void RenderSpritesScanline(bool show)
|
||||
{
|
||||
if (SpritesEnabled == false)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
if (activeSprites >= 16 && PerformSpriteLimit)
|
||||
break;
|
||||
|
||||
int y = (SpriteAttributeTable[(i * 4) + 0] & 1023) - 64;
|
||||
int x = (SpriteAttributeTable[(i * 4) + 1] & 1023) - 32;
|
||||
ushort flags = SpriteAttributeTable[(i * 4) + 3];
|
||||
int height = heightTable[(flags >> 12) & 3];
|
||||
int width = (flags & 0x100) == 0 ? 16 : 32;
|
||||
Array.Clear(InterSpritePriorityBuffer, 0, FrameWidth);
|
||||
bool Sprite4ColorMode = Sprite4ColorModeEnabled;
|
||||
int activeSprites = 0;
|
||||
|
||||
if (y + height <= ActiveLine || y > ActiveLine)
|
||||
continue;
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
if (activeSprites >= 16 && PerformSpriteLimit)
|
||||
break;
|
||||
|
||||
activeSprites += width == 16 ? 1 : 2;
|
||||
|
||||
int patternNo = (((SpriteAttributeTable[(i * 4) + 2]) >> 1) & 0x1FF);
|
||||
int paletteBase = 256 + ((flags & 15) * 16);
|
||||
bool priority = (flags & 0x80) != 0;
|
||||
bool hflip = (flags & 0x0800) != 0;
|
||||
bool vflip = (flags & 0x8000) != 0;
|
||||
int y = (SpriteAttributeTable[(i * 4) + 0] & 1023) - 64;
|
||||
int x = (SpriteAttributeTable[(i * 4) + 1] & 1023) - 32;
|
||||
ushort flags = SpriteAttributeTable[(i * 4) + 3];
|
||||
int height = heightTable[(flags >> 12) & 3];
|
||||
int width = (flags & 0x100) == 0 ? 16 : 32;
|
||||
|
||||
int colorMask = 0xFF;
|
||||
if (Sprite4ColorMode)
|
||||
{
|
||||
if ((SpriteAttributeTable[(i * 4) + 2] & 1) == 0)
|
||||
colorMask = 0x03;
|
||||
else
|
||||
colorMask = 0x0C;
|
||||
}
|
||||
if (y + height <= ActiveLine || y > ActiveLine)
|
||||
continue;
|
||||
|
||||
if (width == 32)
|
||||
patternNo &= 0x1FE;
|
||||
activeSprites += width == 16 ? 1 : 2;
|
||||
|
||||
int yofs = 0;
|
||||
if (vflip == false)
|
||||
{
|
||||
yofs = (ActiveLine - y) & 15;
|
||||
if (height == 32)
|
||||
{
|
||||
patternNo &= 0x1FD;
|
||||
if (ActiveLine - y >= 16)
|
||||
{
|
||||
y += 16;
|
||||
patternNo += 2;
|
||||
}
|
||||
}
|
||||
else if (height == 64)
|
||||
{
|
||||
patternNo &= 0x1F9;
|
||||
if (ActiveLine - y >= 48)
|
||||
{
|
||||
y += 48;
|
||||
patternNo += 6;
|
||||
}
|
||||
else if (ActiveLine - y >= 32)
|
||||
{
|
||||
y += 32;
|
||||
patternNo += 4;
|
||||
}
|
||||
else if (ActiveLine - y >= 16)
|
||||
{
|
||||
y += 16;
|
||||
patternNo += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // vflip == true
|
||||
{
|
||||
yofs = 15 - ((ActiveLine - y) & 15);
|
||||
if (height == 32)
|
||||
{
|
||||
patternNo &= 0x1FD;
|
||||
if (ActiveLine - y < 16)
|
||||
{
|
||||
y += 16;
|
||||
patternNo += 2;
|
||||
}
|
||||
}
|
||||
else if (height == 64)
|
||||
{
|
||||
patternNo &= 0x1F9;
|
||||
if (ActiveLine - y < 16)
|
||||
{
|
||||
y += 48;
|
||||
patternNo += 6;
|
||||
}
|
||||
else if (ActiveLine - y < 32)
|
||||
{
|
||||
y += 32;
|
||||
patternNo += 4;
|
||||
}
|
||||
else if (ActiveLine - y < 48)
|
||||
{
|
||||
y += 16;
|
||||
patternNo += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hflip == false)
|
||||
{
|
||||
if (x + width > 0 && y + height > 0)
|
||||
{
|
||||
for (int xs = x >= 0 ? x : 0; xs < x + 16 && xs >= 0 && xs < FrameWidth; xs++)
|
||||
{
|
||||
byte pixel = (byte)(SpriteBuffer[(patternNo * 256) + (yofs * 16) + (xs - x)] & colorMask);
|
||||
if (colorMask == 0x0C)
|
||||
pixel >>= 2;
|
||||
if (pixel != 0 && InterSpritePriorityBuffer[xs] == 0)
|
||||
{
|
||||
InterSpritePriorityBuffer[xs] = 1;
|
||||
if ((priority || PriorityBuffer[xs] == 0) && show)
|
||||
FrameBuffer[(ActiveLine * FramePitch) + xs] = vce.Palette[paletteBase + pixel];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (width == 32)
|
||||
{
|
||||
patternNo++;
|
||||
x += 16;
|
||||
for (int xs = x >= 0 ? x : 0; xs < x + 16 && xs >= 0 && xs < FrameWidth; xs++)
|
||||
{
|
||||
byte pixel = (byte)(SpriteBuffer[(patternNo * 256) + (yofs * 16) + (xs - x)] & colorMask);
|
||||
if (colorMask == 0x0C)
|
||||
pixel >>= 2;
|
||||
if (pixel != 0 && InterSpritePriorityBuffer[xs] == 0)
|
||||
{
|
||||
InterSpritePriorityBuffer[xs] = 1;
|
||||
if ((priority || PriorityBuffer[xs] == 0) && show)
|
||||
FrameBuffer[(ActiveLine * FramePitch) + xs] = vce.Palette[paletteBase + pixel];
|
||||
}
|
||||
int patternNo = (((SpriteAttributeTable[(i * 4) + 2]) >> 1) & 0x1FF);
|
||||
int paletteBase = 256 + ((flags & 15) * 16);
|
||||
bool priority = (flags & 0x80) != 0;
|
||||
bool hflip = (flags & 0x0800) != 0;
|
||||
bool vflip = (flags & 0x8000) != 0;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // hflip = true
|
||||
if (x + width > 0 && y + height > 0)
|
||||
{
|
||||
if (width == 32)
|
||||
patternNo++;
|
||||
for (int xs = x >= 0 ? x : 0; xs < x + 16 && xs >= 0 && xs < FrameWidth; xs++)
|
||||
{
|
||||
byte pixel = (byte)(SpriteBuffer[(patternNo * 256) + (yofs * 16) + 15 - (xs - x)] & colorMask);
|
||||
if (colorMask == 0x0C)
|
||||
pixel >>= 2;
|
||||
if (pixel != 0 && InterSpritePriorityBuffer[xs] == 0)
|
||||
{
|
||||
InterSpritePriorityBuffer[xs] = 1;
|
||||
if ((priority || PriorityBuffer[xs] == 0) && show)
|
||||
FrameBuffer[(ActiveLine * FramePitch) + xs] = vce.Palette[paletteBase + pixel];
|
||||
}
|
||||
}
|
||||
if (width == 32)
|
||||
{
|
||||
patternNo--;
|
||||
x += 16;
|
||||
for (int xs = x >= 0 ? x : 0; xs < x + 16 && xs >= 0 && xs < FrameWidth; xs++)
|
||||
{
|
||||
byte pixel = (byte)(SpriteBuffer[(patternNo * 256) + (yofs * 16) + 15 - (xs - x)] & colorMask);
|
||||
if (colorMask == 0x0C)
|
||||
pixel >>= 2;
|
||||
if (pixel != 0 && InterSpritePriorityBuffer[xs] == 0)
|
||||
{
|
||||
InterSpritePriorityBuffer[xs] = 1;
|
||||
if ((priority || PriorityBuffer[xs] == 0) && show)
|
||||
FrameBuffer[(ActiveLine * FramePitch) + xs] = vce.Palette[paletteBase + pixel];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int colorMask = 0xFF;
|
||||
if (Sprite4ColorMode)
|
||||
{
|
||||
if ((SpriteAttributeTable[(i * 4) + 2] & 1) == 0)
|
||||
colorMask = 0x03;
|
||||
else
|
||||
colorMask = 0x0C;
|
||||
}
|
||||
|
||||
int FramePitch = 256;
|
||||
int FrameWidth = 256;
|
||||
int FrameHeight = 240;
|
||||
int[] FrameBuffer = new int[256 * 240];
|
||||
if (width == 32)
|
||||
patternNo &= 0x1FE;
|
||||
|
||||
public int[] GetVideoBuffer() { return FrameBuffer; }
|
||||
int yofs = 0;
|
||||
if (vflip == false)
|
||||
{
|
||||
yofs = (ActiveLine - y) & 15;
|
||||
if (height == 32)
|
||||
{
|
||||
patternNo &= 0x1FD;
|
||||
if (ActiveLine - y >= 16)
|
||||
{
|
||||
y += 16;
|
||||
patternNo += 2;
|
||||
}
|
||||
}
|
||||
else if (height == 64)
|
||||
{
|
||||
patternNo &= 0x1F9;
|
||||
if (ActiveLine - y >= 48)
|
||||
{
|
||||
y += 48;
|
||||
patternNo += 6;
|
||||
}
|
||||
else if (ActiveLine - y >= 32)
|
||||
{
|
||||
y += 32;
|
||||
patternNo += 4;
|
||||
}
|
||||
else if (ActiveLine - y >= 16)
|
||||
{
|
||||
y += 16;
|
||||
patternNo += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // vflip == true
|
||||
{
|
||||
yofs = 15 - ((ActiveLine - y) & 15);
|
||||
if (height == 32)
|
||||
{
|
||||
patternNo &= 0x1FD;
|
||||
if (ActiveLine - y < 16)
|
||||
{
|
||||
y += 16;
|
||||
patternNo += 2;
|
||||
}
|
||||
}
|
||||
else if (height == 64)
|
||||
{
|
||||
patternNo &= 0x1F9;
|
||||
if (ActiveLine - y < 16)
|
||||
{
|
||||
y += 48;
|
||||
patternNo += 6;
|
||||
}
|
||||
else if (ActiveLine - y < 32)
|
||||
{
|
||||
y += 32;
|
||||
patternNo += 4;
|
||||
}
|
||||
else if (ActiveLine - y < 48)
|
||||
{
|
||||
y += 16;
|
||||
patternNo += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hflip == false)
|
||||
{
|
||||
if (x + width > 0 && y + height > 0)
|
||||
{
|
||||
for (int xs = x >= 0 ? x : 0; xs < x + 16 && xs >= 0 && xs < FrameWidth; xs++)
|
||||
{
|
||||
byte pixel = (byte)(SpriteBuffer[(patternNo * 256) + (yofs * 16) + (xs - x)] & colorMask);
|
||||
if (colorMask == 0x0C)
|
||||
pixel >>= 2;
|
||||
if (pixel != 0 && InterSpritePriorityBuffer[xs] == 0)
|
||||
{
|
||||
InterSpritePriorityBuffer[xs] = 1;
|
||||
if ((priority || PriorityBuffer[xs] == 0) && show)
|
||||
FrameBuffer[(ActiveLine * FramePitch) + xs] = vce.Palette[paletteBase + pixel];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (width == 32)
|
||||
{
|
||||
patternNo++;
|
||||
x += 16;
|
||||
for (int xs = x >= 0 ? x : 0; xs < x + 16 && xs >= 0 && xs < FrameWidth; xs++)
|
||||
{
|
||||
byte pixel = (byte)(SpriteBuffer[(patternNo * 256) + (yofs * 16) + (xs - x)] & colorMask);
|
||||
if (colorMask == 0x0C)
|
||||
pixel >>= 2;
|
||||
if (pixel != 0 && InterSpritePriorityBuffer[xs] == 0)
|
||||
{
|
||||
InterSpritePriorityBuffer[xs] = 1;
|
||||
if ((priority || PriorityBuffer[xs] == 0) && show)
|
||||
FrameBuffer[(ActiveLine * FramePitch) + xs] = vce.Palette[paletteBase + pixel];
|
||||
}
|
||||
|
||||
public int VirtualWidth { get { return FramePitch; } }
|
||||
public int BufferWidth { get { return FramePitch; } }
|
||||
public int BufferHeight { get { return FrameHeight; } }
|
||||
public int BackgroundColor { get { return vce.Palette[256]; } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // hflip = true
|
||||
if (x + width > 0 && y + height > 0)
|
||||
{
|
||||
if (width == 32)
|
||||
patternNo++;
|
||||
for (int xs = x >= 0 ? x : 0; xs < x + 16 && xs >= 0 && xs < FrameWidth; xs++)
|
||||
{
|
||||
byte pixel = (byte)(SpriteBuffer[(patternNo * 256) + (yofs * 16) + 15 - (xs - x)] & colorMask);
|
||||
if (colorMask == 0x0C)
|
||||
pixel >>= 2;
|
||||
if (pixel != 0 && InterSpritePriorityBuffer[xs] == 0)
|
||||
{
|
||||
InterSpritePriorityBuffer[xs] = 1;
|
||||
if ((priority || PriorityBuffer[xs] == 0) && show)
|
||||
FrameBuffer[(ActiveLine * FramePitch) + xs] = vce.Palette[paletteBase + pixel];
|
||||
}
|
||||
}
|
||||
if (width == 32)
|
||||
{
|
||||
patternNo--;
|
||||
x += 16;
|
||||
for (int xs = x >= 0 ? x : 0; xs < x + 16 && xs >= 0 && xs < FrameWidth; xs++)
|
||||
{
|
||||
byte pixel = (byte)(SpriteBuffer[(patternNo * 256) + (yofs * 16) + 15 - (xs - x)] & colorMask);
|
||||
if (colorMask == 0x0C)
|
||||
pixel >>= 2;
|
||||
if (pixel != 0 && InterSpritePriorityBuffer[xs] == 0)
|
||||
{
|
||||
InterSpritePriorityBuffer[xs] = 1;
|
||||
if ((priority || PriorityBuffer[xs] == 0) && show)
|
||||
FrameBuffer[(ActiveLine * FramePitch) + xs] = vce.Palette[paletteBase + pixel];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int FramePitch = 256;
|
||||
int FrameWidth = 256;
|
||||
int FrameHeight = 240;
|
||||
int[] FrameBuffer = new int[256 * 240];
|
||||
|
||||
public int[] GetVideoBuffer() { return FrameBuffer; }
|
||||
|
||||
public int VirtualWidth { get { return FramePitch; } }
|
||||
public int BufferWidth { get { return FramePitch; } }
|
||||
public int BufferHeight { get { return FrameHeight; } }
|
||||
public int BackgroundColor { get { return vce.Palette[256]; } }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ using BizHawk.Common;
|
|||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.CPUs.H6280;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.TurboGrafx
|
||||
namespace BizHawk.Emulation.Cores.PCEngine
|
||||
{
|
||||
// HuC6270 Video Display Controller
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ using BizHawk.Common;
|
|||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.CPUs.H6280;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.TurboGrafx
|
||||
namespace BizHawk.Emulation.Cores.PCEngine
|
||||
{
|
||||
// ------------------------------------------------------
|
||||
// HuC6202 Video Priority Controller
|
||||
|
|
|
@ -7,7 +7,7 @@ using BizHawk.Emulation.Common;
|
|||
|
||||
#pragma warning disable 649 //adelikat: Disable dumb warnings until this file is complete
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.PSX
|
||||
namespace BizHawk.Emulation.Cores.Sony.PSX
|
||||
{
|
||||
public unsafe class Octoshock : IEmulator, IVideoProvider, ISoundProvider
|
||||
{
|
||||
|
|
|
@ -3,7 +3,7 @@ using System.Globalization;
|
|||
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Sega
|
||||
namespace BizHawk.Emulation.Cores.Sega.Genesis
|
||||
{
|
||||
partial class Genesis
|
||||
{
|
||||
|
|
|
@ -1,61 +1,61 @@
|
|||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Sega
|
||||
namespace BizHawk.Emulation.Cores.Sega.Genesis
|
||||
{
|
||||
partial class Genesis
|
||||
{
|
||||
public string RH_Console { get { return GetRomString(0x100, 0x10); } }
|
||||
public string RH_Copyright { get { return GetRomString(0x110, 0x10); } }
|
||||
public string RH_NameDomestic { get { return GetRomString(0x120, 0x30); } }
|
||||
public string RH_NameExport { get { return GetRomString(0x150, 0x30); } }
|
||||
public int RH_RomSize { get { return GetRomLongWord(0x1A4); } }
|
||||
public string RH_Region { get { return GetRomString(0x1F0, 3); } }
|
||||
partial class Genesis
|
||||
{
|
||||
public string RH_Console { get { return GetRomString(0x100, 0x10); } }
|
||||
public string RH_Copyright { get { return GetRomString(0x110, 0x10); } }
|
||||
public string RH_NameDomestic { get { return GetRomString(0x120, 0x30); } }
|
||||
public string RH_NameExport { get { return GetRomString(0x150, 0x30); } }
|
||||
public int RH_RomSize { get { return GetRomLongWord(0x1A4); } }
|
||||
public string RH_Region { get { return GetRomString(0x1F0, 3); } }
|
||||
|
||||
public bool RH_SRamPresent { get { return (RomData[0x1B2] & 0x40) != 0; } }
|
||||
public int RH_SRamCode { get { return (RomData[0x1B2] >> 3) & 3; } }
|
||||
public int RH_SRamStart { get { return GetRomLongWord(0x1B4); } }
|
||||
public int RH_SRamEnd { get { return GetRomLongWord(0x1B8); } }
|
||||
public bool RH_SRamPresent { get { return (RomData[0x1B2] & 0x40) != 0; } }
|
||||
public int RH_SRamCode { get { return (RomData[0x1B2] >> 3) & 3; } }
|
||||
public int RH_SRamStart { get { return GetRomLongWord(0x1B4); } }
|
||||
public int RH_SRamEnd { get { return GetRomLongWord(0x1B8); } }
|
||||
|
||||
public string RH_SRamInterpretation()
|
||||
{
|
||||
switch (RH_SRamCode)
|
||||
{
|
||||
case 0: return "Even and odd addresses";
|
||||
case 2: return "Even addresses";
|
||||
case 3: return "Odd addresses";
|
||||
default: return "Invalid type";
|
||||
}
|
||||
}
|
||||
public string RH_SRamInterpretation()
|
||||
{
|
||||
switch (RH_SRamCode)
|
||||
{
|
||||
case 0: return "Even and odd addresses";
|
||||
case 2: return "Even addresses";
|
||||
case 3: return "Odd addresses";
|
||||
default: return "Invalid type";
|
||||
}
|
||||
}
|
||||
|
||||
string GetRomString(int offset, int len)
|
||||
{
|
||||
return Encoding.ASCII.GetString(RomData, offset, len).Trim();
|
||||
}
|
||||
string GetRomString(int offset, int len)
|
||||
{
|
||||
return Encoding.ASCII.GetString(RomData, offset, len).Trim();
|
||||
}
|
||||
|
||||
int GetRomLongWord(int offset)
|
||||
{
|
||||
return (RomData[offset] << 24) | (RomData[offset + 1] << 16) | (RomData[offset + 2] << 8) | RomData[offset + 3];
|
||||
}
|
||||
int GetRomLongWord(int offset)
|
||||
{
|
||||
return (RomData[offset] << 24) | (RomData[offset + 1] << 16) | (RomData[offset + 2] << 8) | RomData[offset + 3];
|
||||
}
|
||||
|
||||
void LogCartInfo()
|
||||
{
|
||||
Console.WriteLine("==================");
|
||||
Console.WriteLine("ROM Cartridge Data");
|
||||
Console.WriteLine("==================");
|
||||
Console.WriteLine("System: {0}", RH_Console);
|
||||
Console.WriteLine("Copyright: {0}", RH_Copyright);
|
||||
Console.WriteLine("Name (Dom): {0}", RH_NameDomestic);
|
||||
Console.WriteLine("Name (Exp): {0}", RH_NameExport);
|
||||
Console.WriteLine("Region: {0}", RH_Region);
|
||||
Console.WriteLine("Rom Size: {0,7} (${0:X})", RH_RomSize);
|
||||
Console.WriteLine("SRAM Used: {0}", RH_SRamPresent);
|
||||
if (RH_SRamPresent)
|
||||
{
|
||||
Console.WriteLine("SRAM Start: {0,7} (${0:X})", RH_SRamStart);
|
||||
Console.WriteLine("SRAM End: {0,7} (${0:X})", RH_SRamEnd);
|
||||
Console.WriteLine("SRAM Type: {0}", RH_SRamInterpretation());
|
||||
}
|
||||
}
|
||||
}
|
||||
void LogCartInfo()
|
||||
{
|
||||
Console.WriteLine("==================");
|
||||
Console.WriteLine("ROM Cartridge Data");
|
||||
Console.WriteLine("==================");
|
||||
Console.WriteLine("System: {0}", RH_Console);
|
||||
Console.WriteLine("Copyright: {0}", RH_Copyright);
|
||||
Console.WriteLine("Name (Dom): {0}", RH_NameDomestic);
|
||||
Console.WriteLine("Name (Exp): {0}", RH_NameExport);
|
||||
Console.WriteLine("Region: {0}", RH_Region);
|
||||
Console.WriteLine("Rom Size: {0,7} (${0:X})", RH_RomSize);
|
||||
Console.WriteLine("SRAM Used: {0}", RH_SRamPresent);
|
||||
if (RH_SRamPresent)
|
||||
{
|
||||
Console.WriteLine("SRAM Start: {0,7} (${0:X})", RH_SRamStart);
|
||||
Console.WriteLine("SRAM End: {0,7} (${0:X})", RH_SRamEnd);
|
||||
Console.WriteLine("SRAM Type: {0}", RH_SRamInterpretation());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Sega
|
||||
namespace BizHawk.Emulation.Cores.Sega.Genesis
|
||||
{
|
||||
partial class Genesis
|
||||
{
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using BizHawk.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Sega
|
||||
namespace BizHawk.Emulation.Cores.Sega.Genesis
|
||||
{
|
||||
public partial class GenVDP
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -5,7 +5,7 @@ using System.Globalization;
|
|||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Sega
|
||||
namespace BizHawk.Emulation.Cores.Sega.Genesis
|
||||
{
|
||||
public sealed partial class GenVDP : IVideoProvider
|
||||
{
|
||||
|
|
|
@ -13,7 +13,7 @@ using BizHawk.Emulation.Sound;
|
|||
using Native68000;
|
||||
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Sega
|
||||
namespace BizHawk.Emulation.Cores.Sega.Genesis
|
||||
{
|
||||
public sealed partial class Genesis : IEmulator
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using BizHawk.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Sega
|
||||
namespace BizHawk.Emulation.Cores.Sega.Genesis
|
||||
{
|
||||
partial class Genesis
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Sega
|
||||
namespace BizHawk.Emulation.Cores.Sega.Genesis
|
||||
{
|
||||
partial class Genesis
|
||||
{
|
||||
|
|
|
@ -1,254 +1,254 @@
|
|||
using System;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Sega
|
||||
namespace BizHawk.Emulation.Cores.Sega.Genesis
|
||||
{
|
||||
partial class Genesis
|
||||
{
|
||||
public sbyte ReadByte(int address)
|
||||
{
|
||||
address &= 0x00FFFFFF;
|
||||
partial class Genesis
|
||||
{
|
||||
public sbyte ReadByte(int address)
|
||||
{
|
||||
address &= 0x00FFFFFF;
|
||||
|
||||
if (address < 0x200000)
|
||||
return (sbyte) RomData[address];
|
||||
if (address < 0x200000)
|
||||
return (sbyte)RomData[address];
|
||||
|
||||
if (address < 0x400000)
|
||||
{
|
||||
if (SaveRamEnabled && address >= SaveRamStartOffset && address < SaveRamEndOffset)
|
||||
{
|
||||
if (SaveRamEveryOtherByte)
|
||||
return (sbyte) SaveRAM[(address - SaveRamStartOffset) >> 1];
|
||||
else
|
||||
return (sbyte) SaveRAM[address - SaveRamStartOffset];
|
||||
}
|
||||
return (sbyte)RomData[address];
|
||||
}
|
||||
if (address < 0x400000)
|
||||
{
|
||||
if (SaveRamEnabled && address >= SaveRamStartOffset && address < SaveRamEndOffset)
|
||||
{
|
||||
if (SaveRamEveryOtherByte)
|
||||
return (sbyte)SaveRAM[(address - SaveRamStartOffset) >> 1];
|
||||
else
|
||||
return (sbyte)SaveRAM[address - SaveRamStartOffset];
|
||||
}
|
||||
return (sbyte)RomData[address];
|
||||
}
|
||||
|
||||
if (address >= 0xE00000)
|
||||
return (sbyte) Ram[address & 0xFFFF];
|
||||
if (address >= 0xE00000)
|
||||
return (sbyte)Ram[address & 0xFFFF];
|
||||
|
||||
if (address == 0xA11100) // Z80 BUS status
|
||||
{
|
||||
//Console.WriteLine("QUERY z80 bus status. 68000 can access? " + (M68000HasZ80Bus && Z80Reset == false));
|
||||
return (sbyte) (M68000HasZ80Bus && Z80Reset == false ? 0 : 1);
|
||||
}
|
||||
if (address == 0xA11100) // Z80 BUS status
|
||||
{
|
||||
//Console.WriteLine("QUERY z80 bus status. 68000 can access? " + (M68000HasZ80Bus && Z80Reset == false));
|
||||
return (sbyte)(M68000HasZ80Bus && Z80Reset == false ? 0 : 1);
|
||||
}
|
||||
|
||||
if (address >= 0xA10000 && address <= 0xA1001F)
|
||||
return (sbyte)ReadIO(address);
|
||||
if (address >= 0xA10000 && address <= 0xA1001F)
|
||||
return (sbyte)ReadIO(address);
|
||||
|
||||
if ((address & 0xFF0000) == 0xA00000)
|
||||
return (sbyte) ReadMemoryZ80((ushort) (address & 0x7FFF));
|
||||
if ((address & 0xFF0000) == 0xA00000)
|
||||
return (sbyte)ReadMemoryZ80((ushort)(address & 0x7FFF));
|
||||
|
||||
if (address >= 0xC00000 && address < 0xC00010)
|
||||
{
|
||||
//Console.WriteLine("byte-reading the VDP. someone is probably stupid.");
|
||||
ushort value = VDP.ReadVdp(address & 0x0E);
|
||||
if ((address & 1) == 0) // read MSB
|
||||
return (sbyte) (value >> 8);
|
||||
return (sbyte) value; // read LSB
|
||||
}
|
||||
if (address >= 0xC00000 && address < 0xC00010)
|
||||
{
|
||||
//Console.WriteLine("byte-reading the VDP. someone is probably stupid.");
|
||||
ushort value = VDP.ReadVdp(address & 0x0E);
|
||||
if ((address & 1) == 0) // read MSB
|
||||
return (sbyte)(value >> 8);
|
||||
return (sbyte)value; // read LSB
|
||||
}
|
||||
|
||||
Console.WriteLine("UNHANDLED READB {0:X6}", address);
|
||||
return 0x7D;
|
||||
}
|
||||
|
||||
public short ReadWord(int address)
|
||||
{
|
||||
address &= 0x00FFFFFF;
|
||||
Console.WriteLine("UNHANDLED READB {0:X6}", address);
|
||||
return 0x7D;
|
||||
}
|
||||
|
||||
int maskedAddr;
|
||||
if (address < 0x400000)
|
||||
return (short)((RomData[address] << 8) | RomData[address + 1]);
|
||||
public short ReadWord(int address)
|
||||
{
|
||||
address &= 0x00FFFFFF;
|
||||
|
||||
if (address >= 0xE00000) // Work RAM
|
||||
{
|
||||
maskedAddr = address & 0xFFFE;
|
||||
return (short)((Ram[maskedAddr] << 8) | Ram[maskedAddr + 1]);
|
||||
}
|
||||
int maskedAddr;
|
||||
if (address < 0x400000)
|
||||
return (short)((RomData[address] << 8) | RomData[address + 1]);
|
||||
|
||||
if (address >= 0xC00000 && address < 0xC00010)
|
||||
return (short) VDP.ReadVdp(address & 0x0E);
|
||||
if (address >= 0xE00000) // Work RAM
|
||||
{
|
||||
maskedAddr = address & 0xFFFE;
|
||||
return (short)((Ram[maskedAddr] << 8) | Ram[maskedAddr + 1]);
|
||||
}
|
||||
|
||||
if (address >= 0xA10000 && address <= 0xA1001F)
|
||||
return (sbyte)ReadIO(address);
|
||||
if (address >= 0xC00000 && address < 0xC00010)
|
||||
return (short)VDP.ReadVdp(address & 0x0E);
|
||||
|
||||
if (address == 0xA11100) // Z80 BUS status
|
||||
return (short)(M68000HasZ80Bus && Z80Reset == false ? 0x0000 : 0x0100);
|
||||
if (address >= 0xA10000 && address <= 0xA1001F)
|
||||
return (sbyte)ReadIO(address);
|
||||
|
||||
Console.WriteLine("UNHANDLED READW {0:X6}", address);
|
||||
return 0x7DCD;
|
||||
}
|
||||
if (address == 0xA11100) // Z80 BUS status
|
||||
return (short)(M68000HasZ80Bus && Z80Reset == false ? 0x0000 : 0x0100);
|
||||
|
||||
public int ReadLong(int address)
|
||||
{
|
||||
address &= 0x00FFFFFF;
|
||||
Console.WriteLine("UNHANDLED READW {0:X6}", address);
|
||||
return 0x7DCD;
|
||||
}
|
||||
|
||||
int maskedAddr;
|
||||
if (address < 0x400000) // Cartridge ROM
|
||||
return (RomData[address] << 24) | (RomData[address + 1] << 16) | (RomData[address + 2] << 8) | RomData[address + 3];
|
||||
public int ReadLong(int address)
|
||||
{
|
||||
address &= 0x00FFFFFF;
|
||||
|
||||
if (address >= 0xE00000) // Work RAM
|
||||
{
|
||||
maskedAddr = address & 0xFFFF;
|
||||
return (Ram[maskedAddr] << 24) | (Ram[maskedAddr + 1] << 16) | (Ram[maskedAddr + 2] << 8) | Ram[maskedAddr + 3];
|
||||
}
|
||||
int maskedAddr;
|
||||
if (address < 0x400000) // Cartridge ROM
|
||||
return (RomData[address] << 24) | (RomData[address + 1] << 16) | (RomData[address + 2] << 8) | RomData[address + 3];
|
||||
|
||||
if (address >= 0xC00000)
|
||||
{
|
||||
//Console.WriteLine("long-read from VDP");
|
||||
short msw = ReadWord(address);
|
||||
short msl = ReadWord(address + 2);
|
||||
return (msw << 16) | (ushort) msl;
|
||||
}
|
||||
if (address >= 0xE00000) // Work RAM
|
||||
{
|
||||
maskedAddr = address & 0xFFFF;
|
||||
return (Ram[maskedAddr] << 24) | (Ram[maskedAddr + 1] << 16) | (Ram[maskedAddr + 2] << 8) | Ram[maskedAddr + 3];
|
||||
}
|
||||
|
||||
// try to handle certain things separate if they need to be separate? otherwise handle as 2x readwords?
|
||||
{
|
||||
return ((ushort)ReadWord(address) | (ushort)(ReadWord(address + 2) << 16));
|
||||
}
|
||||
//if (address == 0xA10008) return 0; // FIXME HACK for tg-sync.
|
||||
if (address >= 0xC00000)
|
||||
{
|
||||
//Console.WriteLine("long-read from VDP");
|
||||
short msw = ReadWord(address);
|
||||
short msl = ReadWord(address + 2);
|
||||
return (msw << 16) | (ushort)msl;
|
||||
}
|
||||
|
||||
//Console.WriteLine("UNHANDLED READL {0:X6}", address);
|
||||
//return 0x7DCDCDCD;
|
||||
}
|
||||
// try to handle certain things separate if they need to be separate? otherwise handle as 2x readwords?
|
||||
{
|
||||
return ((ushort)ReadWord(address) | (ushort)(ReadWord(address + 2) << 16));
|
||||
}
|
||||
//if (address == 0xA10008) return 0; // FIXME HACK for tg-sync.
|
||||
|
||||
public void WriteByte(int address, sbyte value)
|
||||
{
|
||||
address &= 0x00FFFFFF;
|
||||
//Console.WriteLine("UNHANDLED READL {0:X6}", address);
|
||||
//return 0x7DCDCDCD;
|
||||
}
|
||||
|
||||
if (address >= 0xE00000) // Work RAM
|
||||
{
|
||||
//Console.WriteLine("MEM[{0:X4}] change from {1:X2} to {2:X2}", address & 0xFFFF, Ram[address & 0xFFFF], value);
|
||||
Ram[address & 0xFFFF] = (byte)value;
|
||||
return;
|
||||
}
|
||||
if ((address & 0xFF0000) == 0xA00000)
|
||||
{
|
||||
WriteMemoryZ80((ushort)(address & 0x7FFF), (byte)value);
|
||||
return;
|
||||
}
|
||||
if (address >= 0xA10000 && address <= 0xA1001F)
|
||||
{
|
||||
WriteIO(address, value);
|
||||
return;
|
||||
}
|
||||
if (address == 0xA11100)
|
||||
{
|
||||
M68000HasZ80Bus = (value & 1) != 0;
|
||||
//Console.WriteLine("68000 has the z80 bus: " + M68000HasZ80Bus);
|
||||
return;
|
||||
}
|
||||
if (address == 0xA11200) // Z80 RESET
|
||||
{
|
||||
Z80Reset = (value & 1) == 0;
|
||||
if (Z80Reset)
|
||||
SoundCPU.SoftReset();
|
||||
//Console.WriteLine("z80 reset: " + Z80Reset);
|
||||
return;
|
||||
}
|
||||
if (address >= 0xC00000 && address < 0xC00010)
|
||||
{
|
||||
// when writing to VDP in byte mode, the LSB is duplicated into the MSB
|
||||
VDP.WriteVdp(address & 0x1E, (ushort)((ushort)value | ((ushort)value << 8)));
|
||||
return;
|
||||
}
|
||||
if (address >= 0xC00011 && address <= 0xC00017 && (address & 1) != 0)
|
||||
{
|
||||
PSG.WritePsgData((byte) value, SoundCPU.TotalExecutedCycles);
|
||||
return;
|
||||
}
|
||||
public void WriteByte(int address, sbyte value)
|
||||
{
|
||||
address &= 0x00FFFFFF;
|
||||
|
||||
if (SaveRamEnabled && address >= SaveRamStartOffset && address < SaveRamEndOffset)
|
||||
{
|
||||
if (SaveRamEveryOtherByte)
|
||||
SaveRAM[(address - SaveRamStartOffset) >> 1] = (byte) value;
|
||||
else
|
||||
SaveRAM[address - SaveRamStartOffset] = (byte) value;
|
||||
|
||||
SaveRamModified = true;
|
||||
return;
|
||||
}
|
||||
if (address >= 0xE00000) // Work RAM
|
||||
{
|
||||
//Console.WriteLine("MEM[{0:X4}] change from {1:X2} to {2:X2}", address & 0xFFFF, Ram[address & 0xFFFF], value);
|
||||
Ram[address & 0xFFFF] = (byte)value;
|
||||
return;
|
||||
}
|
||||
if ((address & 0xFF0000) == 0xA00000)
|
||||
{
|
||||
WriteMemoryZ80((ushort)(address & 0x7FFF), (byte)value);
|
||||
return;
|
||||
}
|
||||
if (address >= 0xA10000 && address <= 0xA1001F)
|
||||
{
|
||||
WriteIO(address, value);
|
||||
return;
|
||||
}
|
||||
if (address == 0xA11100)
|
||||
{
|
||||
M68000HasZ80Bus = (value & 1) != 0;
|
||||
//Console.WriteLine("68000 has the z80 bus: " + M68000HasZ80Bus);
|
||||
return;
|
||||
}
|
||||
if (address == 0xA11200) // Z80 RESET
|
||||
{
|
||||
Z80Reset = (value & 1) == 0;
|
||||
if (Z80Reset)
|
||||
SoundCPU.SoftReset();
|
||||
//Console.WriteLine("z80 reset: " + Z80Reset);
|
||||
return;
|
||||
}
|
||||
if (address >= 0xC00000 && address < 0xC00010)
|
||||
{
|
||||
// when writing to VDP in byte mode, the LSB is duplicated into the MSB
|
||||
VDP.WriteVdp(address & 0x1E, (ushort)((ushort)value | ((ushort)value << 8)));
|
||||
return;
|
||||
}
|
||||
if (address >= 0xC00011 && address <= 0xC00017 && (address & 1) != 0)
|
||||
{
|
||||
PSG.WritePsgData((byte)value, SoundCPU.TotalExecutedCycles);
|
||||
return;
|
||||
}
|
||||
|
||||
if (EepromEnabled && (address == SclAddr || address == SdaInAddr))
|
||||
{
|
||||
WriteByteEeprom(address, (byte) value);
|
||||
return;
|
||||
if (SaveRamEnabled && address >= SaveRamStartOffset && address < SaveRamEndOffset)
|
||||
{
|
||||
if (SaveRamEveryOtherByte)
|
||||
SaveRAM[(address - SaveRamStartOffset) >> 1] = (byte)value;
|
||||
else
|
||||
SaveRAM[address - SaveRamStartOffset] = (byte)value;
|
||||
|
||||
}
|
||||
SaveRamModified = true;
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine("UNHANDLED WRITEB {0:X6}:{1:X2}", address, value);
|
||||
}
|
||||
if (EepromEnabled && (address == SclAddr || address == SdaInAddr))
|
||||
{
|
||||
WriteByteEeprom(address, (byte)value);
|
||||
return;
|
||||
|
||||
public void WriteWord(int address, short value)
|
||||
{
|
||||
address &= 0x00FFFFFF;
|
||||
}
|
||||
|
||||
if (address >= 0xE00000) // Work RAM
|
||||
{
|
||||
//Console.WriteLine("MEM[{0:X4}] change to {1:X4}", address & 0xFFFF, value);
|
||||
Ram[(address & 0xFFFF) + 0] = (byte)(value >> 8);
|
||||
Ram[(address & 0xFFFF) + 1] = (byte)value;
|
||||
return;
|
||||
}
|
||||
if (address >= 0xC00000)
|
||||
{
|
||||
switch (address & 0x1F)
|
||||
{
|
||||
case 0x00:
|
||||
case 0x02:
|
||||
VDP.WriteVdpData((ushort)value);
|
||||
return;
|
||||
case 0x04:
|
||||
case 0x06:
|
||||
VDP.WriteVdpControl((ushort)value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (address == 0xA11100) // Z80 BUSREQ
|
||||
{
|
||||
M68000HasZ80Bus = (value & 0x100) != 0;
|
||||
//Console.WriteLine("68000 has the z80 bus: " + M68000HasZ80Bus);
|
||||
return;
|
||||
}
|
||||
if (address == 0xA11200) // Z80 RESET
|
||||
{
|
||||
Z80Reset = (value & 0x100) == 0;
|
||||
if (Z80Reset)
|
||||
SoundCPU.SoftReset();
|
||||
//Console.WriteLine("z80 reset: " + Z80Reset);
|
||||
return;
|
||||
}
|
||||
Console.WriteLine("UNHANDLED WRITEW {0:X6}:{1:X4}", address, value);
|
||||
}
|
||||
Console.WriteLine("UNHANDLED WRITEB {0:X6}:{1:X2}", address, value);
|
||||
}
|
||||
|
||||
public void WriteLong(int address, int value)
|
||||
{
|
||||
address &= 0x00FFFFFF;
|
||||
public void WriteWord(int address, short value)
|
||||
{
|
||||
address &= 0x00FFFFFF;
|
||||
|
||||
if (address >= 0xE00000) // Work RAM
|
||||
{
|
||||
//Console.WriteLine("MEM[{0:X4}] change to {1:X8}", address & 0xFFFF, value);
|
||||
Ram[(address & 0xFFFF) + 0] = (byte)(value >> 24);
|
||||
Ram[(address & 0xFFFF) + 1] = (byte)(value >> 16);
|
||||
Ram[(address & 0xFFFF) + 2] = (byte)(value >> 8);
|
||||
Ram[(address & 0xFFFF) + 3] = (byte)value;
|
||||
return;
|
||||
}
|
||||
if (address >= 0xC00000)
|
||||
{
|
||||
WriteWord(address, (short)(value >> 16));
|
||||
WriteWord(address+2, (short)value);
|
||||
return;
|
||||
}
|
||||
if (address >= 0xE00000) // Work RAM
|
||||
{
|
||||
//Console.WriteLine("MEM[{0:X4}] change to {1:X4}", address & 0xFFFF, value);
|
||||
Ram[(address & 0xFFFF) + 0] = (byte)(value >> 8);
|
||||
Ram[(address & 0xFFFF) + 1] = (byte)value;
|
||||
return;
|
||||
}
|
||||
if (address >= 0xC00000)
|
||||
{
|
||||
switch (address & 0x1F)
|
||||
{
|
||||
case 0x00:
|
||||
case 0x02:
|
||||
VDP.WriteVdpData((ushort)value);
|
||||
return;
|
||||
case 0x04:
|
||||
case 0x06:
|
||||
VDP.WriteVdpControl((ushort)value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (address == 0xA11100) // Z80 BUSREQ
|
||||
{
|
||||
M68000HasZ80Bus = (value & 0x100) != 0;
|
||||
//Console.WriteLine("68000 has the z80 bus: " + M68000HasZ80Bus);
|
||||
return;
|
||||
}
|
||||
if (address == 0xA11200) // Z80 RESET
|
||||
{
|
||||
Z80Reset = (value & 0x100) == 0;
|
||||
if (Z80Reset)
|
||||
SoundCPU.SoftReset();
|
||||
//Console.WriteLine("z80 reset: " + Z80Reset);
|
||||
return;
|
||||
}
|
||||
Console.WriteLine("UNHANDLED WRITEW {0:X6}:{1:X4}", address, value);
|
||||
}
|
||||
|
||||
Console.WriteLine("UNHANDLED WRITEL {0:X6}:{1:X8}", address, value);
|
||||
}
|
||||
public void WriteLong(int address, int value)
|
||||
{
|
||||
address &= 0x00FFFFFF;
|
||||
|
||||
// Mushashi interop test stuff. TODO kill this when we're ready to ditch musashi.
|
||||
if (address >= 0xE00000) // Work RAM
|
||||
{
|
||||
//Console.WriteLine("MEM[{0:X4}] change to {1:X8}", address & 0xFFFF, value);
|
||||
Ram[(address & 0xFFFF) + 0] = (byte)(value >> 24);
|
||||
Ram[(address & 0xFFFF) + 1] = (byte)(value >> 16);
|
||||
Ram[(address & 0xFFFF) + 2] = (byte)(value >> 8);
|
||||
Ram[(address & 0xFFFF) + 3] = (byte)value;
|
||||
return;
|
||||
}
|
||||
if (address >= 0xC00000)
|
||||
{
|
||||
WriteWord(address, (short)(value >> 16));
|
||||
WriteWord(address + 2, (short)value);
|
||||
return;
|
||||
}
|
||||
|
||||
public uint Read8(uint a) { /*Console.WriteLine("read8 {0:X}", a);*/ return (uint)ReadByte((int)a) & 0xFF; }
|
||||
public uint Read16(uint a) { /*Console.WriteLine("read16 {0:X}", a);*/ return (uint)ReadWord((int)a) & 0xFFFF; }
|
||||
public uint Read32(uint a) { /*Console.WriteLine("read32 {0:X}", a);*/ return (uint)ReadLong((int)a); }
|
||||
public void Write8(uint a, uint v) { /*Console.WriteLine("write8 {0:X}:{1:X2}", a, v);*/ WriteByte((int)a, (sbyte)v); }
|
||||
public void Write16(uint a, uint v) { /*Console.WriteLine("write16 {0:X}:{1:X4}", a, v);*/ WriteWord((int)a, (short)v); }
|
||||
public void Write32(uint a, uint v) { /*Console.WriteLine("write32 {0:X}:{1:X8}", a, v);*/ WriteLong((int)a, (int)v); }
|
||||
}
|
||||
Console.WriteLine("UNHANDLED WRITEL {0:X6}:{1:X8}", address, value);
|
||||
}
|
||||
|
||||
// Mushashi interop test stuff. TODO kill this when we're ready to ditch musashi.
|
||||
|
||||
public uint Read8(uint a) { /*Console.WriteLine("read8 {0:X}", a);*/ return (uint)ReadByte((int)a) & 0xFF; }
|
||||
public uint Read16(uint a) { /*Console.WriteLine("read16 {0:X}", a);*/ return (uint)ReadWord((int)a) & 0xFFFF; }
|
||||
public uint Read32(uint a) { /*Console.WriteLine("read32 {0:X}", a);*/ return (uint)ReadLong((int)a); }
|
||||
public void Write8(uint a, uint v) { /*Console.WriteLine("write8 {0:X}:{1:X2}", a, v);*/ WriteByte((int)a, (sbyte)v); }
|
||||
public void Write16(uint a, uint v) { /*Console.WriteLine("write16 {0:X}:{1:X4}", a, v);*/ WriteWord((int)a, (short)v); }
|
||||
public void Write32(uint a, uint v) { /*Console.WriteLine("write32 {0:X}:{1:X8}", a, v);*/ WriteLong((int)a, (int)v); }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,84 +1,84 @@
|
|||
using System;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Sega
|
||||
namespace BizHawk.Emulation.Cores.Sega.Genesis
|
||||
{
|
||||
partial class Genesis
|
||||
{
|
||||
private int BankRegion;
|
||||
partial class Genesis
|
||||
{
|
||||
private int BankRegion;
|
||||
|
||||
public byte ReadMemoryZ80(ushort address)
|
||||
{
|
||||
if (address < 0x4000)
|
||||
{
|
||||
//Console.WriteLine("read z80 memory {0:X4}: {1:X2}",address, Z80Ram[address & 0x1FFF]);
|
||||
return Z80Ram[address & 0x1FFF];
|
||||
}
|
||||
if (address >= 0x4000 && address < 0x6000)
|
||||
{
|
||||
//Console.WriteLine(" === Z80 READS FM STATUS ===");
|
||||
return YM2612.ReadStatus(SoundCPU.TotalExecutedCycles); // TODO: more than 1 read port probably?
|
||||
}
|
||||
if (address >= 0x8000)
|
||||
{
|
||||
// 68000 Bank region
|
||||
return (byte) ReadByte(BankRegion | (address & 0x7FFF));
|
||||
}
|
||||
if (address <= 0x6100) // read from bank address register - returns FF
|
||||
return 0xFF;
|
||||
Console.WriteLine("UNHANDLED Z80 READ {0:X4}",address);
|
||||
return 0xCD;
|
||||
}
|
||||
public byte ReadMemoryZ80(ushort address)
|
||||
{
|
||||
if (address < 0x4000)
|
||||
{
|
||||
//Console.WriteLine("read z80 memory {0:X4}: {1:X2}",address, Z80Ram[address & 0x1FFF]);
|
||||
return Z80Ram[address & 0x1FFF];
|
||||
}
|
||||
if (address >= 0x4000 && address < 0x6000)
|
||||
{
|
||||
//Console.WriteLine(" === Z80 READS FM STATUS ===");
|
||||
return YM2612.ReadStatus(SoundCPU.TotalExecutedCycles); // TODO: more than 1 read port probably?
|
||||
}
|
||||
if (address >= 0x8000)
|
||||
{
|
||||
// 68000 Bank region
|
||||
return (byte)ReadByte(BankRegion | (address & 0x7FFF));
|
||||
}
|
||||
if (address <= 0x6100) // read from bank address register - returns FF
|
||||
return 0xFF;
|
||||
Console.WriteLine("UNHANDLED Z80 READ {0:X4}", address);
|
||||
return 0xCD;
|
||||
}
|
||||
|
||||
public void WriteMemoryZ80(ushort address, byte value)
|
||||
{
|
||||
if (address < 0x4000)
|
||||
{
|
||||
//Console.WriteLine("write z80 memory {0:X4}: {1:X2}",address, value);
|
||||
Z80Ram[address & 0x1FFF] = value;
|
||||
return;
|
||||
}
|
||||
if (address >= 0x4000 && address < 0x6000)
|
||||
{
|
||||
//Console.WriteLine(" === Z80 WRITES YM2612 {0:X4}:{1:X2} ===",address, value);
|
||||
YM2612.Write(address & 3, value, SoundCPU.TotalExecutedCycles);
|
||||
return;
|
||||
}
|
||||
if (address < 0x6100)
|
||||
{
|
||||
BankRegion >>= 1;
|
||||
BankRegion |= (value & 1) << 23;
|
||||
BankRegion &= 0x00FF8000;
|
||||
//Console.WriteLine("Bank pointing at {0:X8}",BankRegion);
|
||||
return;
|
||||
}
|
||||
if (address >= 0x7F00 && address < 0x7F20)
|
||||
{
|
||||
switch (address & 0x1F)
|
||||
{
|
||||
case 0x00:
|
||||
case 0x02:
|
||||
VDP.WriteVdpData((ushort) ((value<<8) | value));
|
||||
return;
|
||||
|
||||
case 0x04:
|
||||
case 0x06:
|
||||
VDP.WriteVdpControl((ushort)((value << 8) | value));
|
||||
return;
|
||||
public void WriteMemoryZ80(ushort address, byte value)
|
||||
{
|
||||
if (address < 0x4000)
|
||||
{
|
||||
//Console.WriteLine("write z80 memory {0:X4}: {1:X2}",address, value);
|
||||
Z80Ram[address & 0x1FFF] = value;
|
||||
return;
|
||||
}
|
||||
if (address >= 0x4000 && address < 0x6000)
|
||||
{
|
||||
//Console.WriteLine(" === Z80 WRITES YM2612 {0:X4}:{1:X2} ===",address, value);
|
||||
YM2612.Write(address & 3, value, SoundCPU.TotalExecutedCycles);
|
||||
return;
|
||||
}
|
||||
if (address < 0x6100)
|
||||
{
|
||||
BankRegion >>= 1;
|
||||
BankRegion |= (value & 1) << 23;
|
||||
BankRegion &= 0x00FF8000;
|
||||
//Console.WriteLine("Bank pointing at {0:X8}",BankRegion);
|
||||
return;
|
||||
}
|
||||
if (address >= 0x7F00 && address < 0x7F20)
|
||||
{
|
||||
switch (address & 0x1F)
|
||||
{
|
||||
case 0x00:
|
||||
case 0x02:
|
||||
VDP.WriteVdpData((ushort)((value << 8) | value));
|
||||
return;
|
||||
|
||||
case 0x11:
|
||||
case 0x13:
|
||||
case 0x15:
|
||||
case 0x17:
|
||||
PSG.WritePsgData(value, SoundCPU.TotalExecutedCycles);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (address >= 0x8000)
|
||||
{
|
||||
WriteByte(BankRegion | (address & 0x7FFF), (sbyte) value);
|
||||
return;
|
||||
}
|
||||
Console.WriteLine("UNHANDLED Z80 WRITE {0:X4}:{1:X2}", address, value);
|
||||
}
|
||||
}
|
||||
case 0x04:
|
||||
case 0x06:
|
||||
VDP.WriteVdpControl((ushort)((value << 8) | value));
|
||||
return;
|
||||
|
||||
case 0x11:
|
||||
case 0x13:
|
||||
case 0x15:
|
||||
case 0x17:
|
||||
PSG.WritePsgData(value, SoundCPU.TotalExecutedCycles);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (address >= 0x8000)
|
||||
{
|
||||
WriteByte(BankRegion | (address & 0x7FFF), (sbyte)value);
|
||||
return;
|
||||
}
|
||||
Console.WriteLine("UNHANDLED Z80 WRITE {0:X4}:{1:X2}", address, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
namespace BizHawk.Emulation.Consoles.Sega
|
||||
namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
||||
{
|
||||
public static class BIOS
|
||||
{
|
||||
#region USA System BIOS (SMS 1) [No Cartridge Present]
|
||||
public static readonly byte[] USABios =
|
||||
public static class BIOS
|
||||
{
|
||||
#region USA System BIOS (SMS 1) [No Cartridge Present]
|
||||
public static readonly byte[] USABios =
|
||||
{
|
||||
0xf3, 0xed, 0x56, 0x31, 0xf0, 0xdf, 0x18, 0x65, 0xf5, 0xe7, 0xf1, 0xd3, 0xbe,
|
||||
0xc9, 0xff, 0xff, 0xe7, 0xaf, 0x0e, 0xbe, 0xed, 0xa3, 0xf5, 0xf1, 0xed, 0x79,
|
||||
|
@ -637,10 +637,10 @@
|
|||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff
|
||||
};
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region USA System BIOS [For Use With a ROM - Displays SEGA logo, then boots ROM]
|
||||
public static readonly byte[] ROMBios =
|
||||
#region USA System BIOS [For Use With a ROM - Displays SEGA logo, then boots ROM]
|
||||
public static readonly byte[] ROMBios =
|
||||
{
|
||||
0xf3, 0xed, 0x56, 0x31, 0xf0, 0xdf, 0x18, 0x65, 0xf5, 0xe7, 0xf1, 0xd3, 0xbe,
|
||||
0xc9, 0xff, 0xff, 0xe7, 0xaf, 0x0e, 0xbe, 0xed, 0xa3, 0xf5, 0xf1, 0xed, 0x79,
|
||||
|
@ -1274,10 +1274,10 @@
|
|||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff
|
||||
};
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Japanese Mark III System BIOS [No Cartridge Present]
|
||||
public static readonly byte[] Mk3Bios =
|
||||
#region Japanese Mark III System BIOS [No Cartridge Present]
|
||||
public static readonly byte[] Mk3Bios =
|
||||
{
|
||||
0xf3, 0xed, 0x56, 0x31, 0xef, 0xdf, 0x18, 0x60, 0xe7, 0x01, 0xbe, 0x00, 0x1e,
|
||||
0x02, 0xed, 0xb3, 0xed, 0xb3, 0xed, 0xb3, 0x1d, 0x20, 0xf7, 0xc9, 0xe5, 0xe1,
|
||||
|
@ -1911,6 +1911,6 @@
|
|||
0x04, 0x10, 0x02, 0x12, 0x1a, 0x10, 0x81, 0x12, 0x05, 0x10, 0x02, 0x12, 0x02,
|
||||
0x10, 0x00, 0x00
|
||||
};
|
||||
#endregion
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Sega
|
||||
namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
||||
{
|
||||
public partial class SMS
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace BizHawk.Emulation.Consoles.Sega
|
||||
namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
||||
{
|
||||
public partial class SMS
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace BizHawk.Emulation.Consoles.Sega
|
||||
namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
||||
{
|
||||
public partial class SMS
|
||||
{
|
||||
|
|
|
@ -21,7 +21,7 @@ using BizHawk.Emulation.Sound;
|
|||
|
||||
**********************************************************/
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Sega
|
||||
namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
||||
{
|
||||
public sealed partial class SMS : IEmulator
|
||||
{
|
||||
|
|
|
@ -2,348 +2,348 @@
|
|||
|
||||
// Contains rendering functions for TMS9918 Mode 4.
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Sega
|
||||
namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
||||
{
|
||||
public partial class VDP
|
||||
{
|
||||
internal void RenderBackgroundCurrentLine(bool show)
|
||||
{
|
||||
if (DisplayOn == false)
|
||||
{
|
||||
for (int x = 0; x < 256; x++)
|
||||
FrameBuffer[(ScanLine*256) + x] = Palette[BackdropColor];
|
||||
return;
|
||||
}
|
||||
public partial class VDP
|
||||
{
|
||||
internal void RenderBackgroundCurrentLine(bool show)
|
||||
{
|
||||
if (DisplayOn == false)
|
||||
{
|
||||
for (int x = 0; x < 256; x++)
|
||||
FrameBuffer[(ScanLine * 256) + x] = Palette[BackdropColor];
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear the priority buffer for this scanline
|
||||
Array.Clear(ScanlinePriorityBuffer, 0, 256);
|
||||
// Clear the priority buffer for this scanline
|
||||
Array.Clear(ScanlinePriorityBuffer, 0, 256);
|
||||
|
||||
int mapBase = NameTableBase;
|
||||
int mapBase = NameTableBase;
|
||||
|
||||
int vertOffset = ScanLine + Registers[9];
|
||||
if (FrameHeight == 192)
|
||||
{
|
||||
if (vertOffset >= 224)
|
||||
vertOffset -= 224;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (vertOffset >= 256)
|
||||
vertOffset -= 256;
|
||||
}
|
||||
byte horzOffset = (HorizScrollLock && ScanLine < 16) ? (byte)0 : Registers[8];
|
||||
int vertOffset = ScanLine + Registers[9];
|
||||
if (FrameHeight == 192)
|
||||
{
|
||||
if (vertOffset >= 224)
|
||||
vertOffset -= 224;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (vertOffset >= 256)
|
||||
vertOffset -= 256;
|
||||
}
|
||||
byte horzOffset = (HorizScrollLock && ScanLine < 16) ? (byte)0 : Registers[8];
|
||||
|
||||
int yTile = vertOffset / 8;
|
||||
int yTile = vertOffset / 8;
|
||||
|
||||
for (int xTile = 0; xTile < 32; xTile++)
|
||||
{
|
||||
if (xTile == 24 && VerticalScrollLock)
|
||||
{
|
||||
vertOffset = ScanLine;
|
||||
yTile = vertOffset / 8;
|
||||
}
|
||||
for (int xTile = 0; xTile < 32; xTile++)
|
||||
{
|
||||
if (xTile == 24 && VerticalScrollLock)
|
||||
{
|
||||
vertOffset = ScanLine;
|
||||
yTile = vertOffset / 8;
|
||||
}
|
||||
|
||||
byte PaletteBase = 0;
|
||||
int tileInfo = VRAM[mapBase + ((yTile * 32) + xTile) * 2] | (VRAM[mapBase + (((yTile * 32) + xTile) * 2) + 1] << 8);
|
||||
int tileNo = tileInfo & 0x01FF;
|
||||
if ((tileInfo & 0x800) != 0)
|
||||
PaletteBase = 16;
|
||||
bool Priority = (tileInfo & 0x1000) != 0;
|
||||
bool VFlip = (tileInfo & 0x400) != 0;
|
||||
bool HFlip = (tileInfo & 0x200) != 0;
|
||||
byte PaletteBase = 0;
|
||||
int tileInfo = VRAM[mapBase + ((yTile * 32) + xTile) * 2] | (VRAM[mapBase + (((yTile * 32) + xTile) * 2) + 1] << 8);
|
||||
int tileNo = tileInfo & 0x01FF;
|
||||
if ((tileInfo & 0x800) != 0)
|
||||
PaletteBase = 16;
|
||||
bool Priority = (tileInfo & 0x1000) != 0;
|
||||
bool VFlip = (tileInfo & 0x400) != 0;
|
||||
bool HFlip = (tileInfo & 0x200) != 0;
|
||||
|
||||
int yOfs = vertOffset & 7;
|
||||
if (VFlip)
|
||||
yOfs = 7 - yOfs;
|
||||
int yOfs = vertOffset & 7;
|
||||
if (VFlip)
|
||||
yOfs = 7 - yOfs;
|
||||
|
||||
if (HFlip == false)
|
||||
{
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 0] + PaletteBase] : Palette[BackdropColor];
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 1] + PaletteBase] : Palette[BackdropColor];
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 2] + PaletteBase] : Palette[BackdropColor];
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 3] + PaletteBase] : Palette[BackdropColor];
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 4] + PaletteBase] : Palette[BackdropColor];
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 5] + PaletteBase] : Palette[BackdropColor];
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 6] + PaletteBase] : Palette[BackdropColor];
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 7] + PaletteBase] : Palette[BackdropColor];
|
||||
if (HFlip == false)
|
||||
{
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 0] + PaletteBase] : Palette[BackdropColor];
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 1] + PaletteBase] : Palette[BackdropColor];
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 2] + PaletteBase] : Palette[BackdropColor];
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 3] + PaletteBase] : Palette[BackdropColor];
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 4] + PaletteBase] : Palette[BackdropColor];
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 5] + PaletteBase] : Palette[BackdropColor];
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 6] + PaletteBase] : Palette[BackdropColor];
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 7] + PaletteBase] : Palette[BackdropColor];
|
||||
|
||||
if (Priority)
|
||||
{
|
||||
horzOffset -= 8;
|
||||
for (int k = 0; k < 8; k++)
|
||||
{
|
||||
if (PatternBuffer[(tileNo * 64) + (yOfs * 8) + k] != 0)
|
||||
ScanlinePriorityBuffer[horzOffset] = 1;
|
||||
horzOffset++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // Flipped Horizontally
|
||||
{
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 7] + PaletteBase] : Palette[BackdropColor];
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 6] + PaletteBase] : Palette[BackdropColor];
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 5] + PaletteBase] : Palette[BackdropColor];
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 4] + PaletteBase] : Palette[BackdropColor];
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 3] + PaletteBase] : Palette[BackdropColor];
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 2] + PaletteBase] : Palette[BackdropColor];
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 1] + PaletteBase] : Palette[BackdropColor];
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 0] + PaletteBase] : Palette[BackdropColor];
|
||||
if (Priority)
|
||||
{
|
||||
horzOffset -= 8;
|
||||
for (int k = 0; k < 8; k++)
|
||||
{
|
||||
if (PatternBuffer[(tileNo * 64) + (yOfs * 8) + k] != 0)
|
||||
ScanlinePriorityBuffer[horzOffset] = 1;
|
||||
horzOffset++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // Flipped Horizontally
|
||||
{
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 7] + PaletteBase] : Palette[BackdropColor];
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 6] + PaletteBase] : Palette[BackdropColor];
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 5] + PaletteBase] : Palette[BackdropColor];
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 4] + PaletteBase] : Palette[BackdropColor];
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 3] + PaletteBase] : Palette[BackdropColor];
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 2] + PaletteBase] : Palette[BackdropColor];
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 1] + PaletteBase] : Palette[BackdropColor];
|
||||
FrameBuffer[(ScanLine * 256) + horzOffset++] = show ? Palette[PatternBuffer[(tileNo * 64) + (yOfs * 8) + 0] + PaletteBase] : Palette[BackdropColor];
|
||||
|
||||
if (Priority)
|
||||
{
|
||||
horzOffset -= 8;
|
||||
for (int k = 7; k >= 0; k--)
|
||||
{
|
||||
if (PatternBuffer[(tileNo * 64) + (yOfs * 8) + k] != 0)
|
||||
ScanlinePriorityBuffer[horzOffset] = 1;
|
||||
horzOffset++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Priority)
|
||||
{
|
||||
horzOffset -= 8;
|
||||
for (int k = 7; k >= 0; k--)
|
||||
{
|
||||
if (PatternBuffer[(tileNo * 64) + (yOfs * 8) + k] != 0)
|
||||
ScanlinePriorityBuffer[horzOffset] = 1;
|
||||
horzOffset++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void RenderSpritesCurrentLine(bool show)
|
||||
{
|
||||
if (DisplayOn == false) return;
|
||||
int SpriteBase = SpriteAttributeTableBase;
|
||||
int SpriteHeight = EnableLargeSprites ? 16 : 8;
|
||||
internal void RenderSpritesCurrentLine(bool show)
|
||||
{
|
||||
if (DisplayOn == false) return;
|
||||
int SpriteBase = SpriteAttributeTableBase;
|
||||
int SpriteHeight = EnableLargeSprites ? 16 : 8;
|
||||
|
||||
// Clear the sprite collision buffer for this scanline
|
||||
Array.Clear(SpriteCollisionBuffer, 0, 256);
|
||||
// Clear the sprite collision buffer for this scanline
|
||||
Array.Clear(SpriteCollisionBuffer, 0, 256);
|
||||
|
||||
// Loop through these sprites and render the current scanline
|
||||
int SpritesDrawnThisScanline = 0;
|
||||
for (int i=0; i<64; i++)
|
||||
{
|
||||
if (SpritesDrawnThisScanline >= 8)
|
||||
{
|
||||
StatusByte |= 0x40; // Set Overflow bit
|
||||
if (SpriteLimit) break;
|
||||
}
|
||||
// Loop through these sprites and render the current scanline
|
||||
int SpritesDrawnThisScanline = 0;
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
if (SpritesDrawnThisScanline >= 8)
|
||||
{
|
||||
StatusByte |= 0x40; // Set Overflow bit
|
||||
if (SpriteLimit) break;
|
||||
}
|
||||
|
||||
int x = VRAM[SpriteBase + 0x80 + (i * 2)];
|
||||
if (ShiftSpritesLeft8Pixels)
|
||||
x -= 8;
|
||||
int x = VRAM[SpriteBase + 0x80 + (i * 2)];
|
||||
if (ShiftSpritesLeft8Pixels)
|
||||
x -= 8;
|
||||
|
||||
int y = VRAM[SpriteBase + i] + 1;
|
||||
if (y == 209 && FrameHeight == 192) break; // 208 is special terminator sprite (in 192-line mode)
|
||||
if (y >= (EnableLargeSprites ? 240 : 248)) y -= 256;
|
||||
int y = VRAM[SpriteBase + i] + 1;
|
||||
if (y == 209 && FrameHeight == 192) break; // 208 is special terminator sprite (in 192-line mode)
|
||||
if (y >= (EnableLargeSprites ? 240 : 248)) y -= 256;
|
||||
|
||||
if (y + SpriteHeight <= ScanLine || y > ScanLine)
|
||||
continue;
|
||||
if (y + SpriteHeight <= ScanLine || y > ScanLine)
|
||||
continue;
|
||||
|
||||
int tileNo = VRAM[SpriteBase + 0x80 + (i * 2) + 1];
|
||||
if (EnableLargeSprites)
|
||||
tileNo &= 0xFE;
|
||||
tileNo += SpriteTileBase;
|
||||
int tileNo = VRAM[SpriteBase + 0x80 + (i * 2) + 1];
|
||||
if (EnableLargeSprites)
|
||||
tileNo &= 0xFE;
|
||||
tileNo += SpriteTileBase;
|
||||
|
||||
int ys = ScanLine - y;
|
||||
int ys = ScanLine - y;
|
||||
|
||||
for (int xs = 0; xs < 8 && x + xs < 256; xs++)
|
||||
{
|
||||
byte color = PatternBuffer[(tileNo * 64) + (ys * 8) + xs];
|
||||
if (color != 0 && x + xs >= 0)
|
||||
{
|
||||
if (SpriteCollisionBuffer[x + xs] != 0)
|
||||
StatusByte |= 0x20; // Set Collision bit
|
||||
else if (ScanlinePriorityBuffer[x + xs] == 0)
|
||||
{
|
||||
if (show) FrameBuffer[(ys + y) * 256 + x + xs] = Palette[(color + 16)];
|
||||
SpriteCollisionBuffer[x + xs] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
SpritesDrawnThisScanline++;
|
||||
}
|
||||
}
|
||||
for (int xs = 0; xs < 8 && x + xs < 256; xs++)
|
||||
{
|
||||
byte color = PatternBuffer[(tileNo * 64) + (ys * 8) + xs];
|
||||
if (color != 0 && x + xs >= 0)
|
||||
{
|
||||
if (SpriteCollisionBuffer[x + xs] != 0)
|
||||
StatusByte |= 0x20; // Set Collision bit
|
||||
else if (ScanlinePriorityBuffer[x + xs] == 0)
|
||||
{
|
||||
if (show) FrameBuffer[(ys + y) * 256 + x + xs] = Palette[(color + 16)];
|
||||
SpriteCollisionBuffer[x + xs] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
SpritesDrawnThisScanline++;
|
||||
}
|
||||
}
|
||||
|
||||
internal void RenderSpritesCurrentLineDoubleSize(bool show)
|
||||
{
|
||||
if (DisplayOn == false) return;
|
||||
int SpriteBase = SpriteAttributeTableBase;
|
||||
int SpriteHeight = EnableLargeSprites ? 16 : 8;
|
||||
internal void RenderSpritesCurrentLineDoubleSize(bool show)
|
||||
{
|
||||
if (DisplayOn == false) return;
|
||||
int SpriteBase = SpriteAttributeTableBase;
|
||||
int SpriteHeight = EnableLargeSprites ? 16 : 8;
|
||||
|
||||
// Clear the sprite collision buffer for this scanline
|
||||
Array.Clear(SpriteCollisionBuffer, 0, 256);
|
||||
// Clear the sprite collision buffer for this scanline
|
||||
Array.Clear(SpriteCollisionBuffer, 0, 256);
|
||||
|
||||
// Loop through these sprites and render the current scanline
|
||||
int SpritesDrawnThisScanline = 0;
|
||||
for (int i = 0; i <64; i++)
|
||||
{
|
||||
if (SpritesDrawnThisScanline >= 8)
|
||||
{
|
||||
StatusByte |= 0x40; // Set Overflow bit
|
||||
if (SpriteLimit) break;
|
||||
}
|
||||
// Loop through these sprites and render the current scanline
|
||||
int SpritesDrawnThisScanline = 0;
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
if (SpritesDrawnThisScanline >= 8)
|
||||
{
|
||||
StatusByte |= 0x40; // Set Overflow bit
|
||||
if (SpriteLimit) break;
|
||||
}
|
||||
|
||||
int x = VRAM[SpriteBase + 0x80 + (i * 2)];
|
||||
if (ShiftSpritesLeft8Pixels)
|
||||
x -= 8;
|
||||
int x = VRAM[SpriteBase + 0x80 + (i * 2)];
|
||||
if (ShiftSpritesLeft8Pixels)
|
||||
x -= 8;
|
||||
|
||||
int y = VRAM[SpriteBase + i] + 1;
|
||||
if (y == 209 && FrameHeight == 192) break; // terminator sprite
|
||||
if (y >= (EnableLargeSprites ? 240 : 248)) y -= 256;
|
||||
int y = VRAM[SpriteBase + i] + 1;
|
||||
if (y == 209 && FrameHeight == 192) break; // terminator sprite
|
||||
if (y >= (EnableLargeSprites ? 240 : 248)) y -= 256;
|
||||
|
||||
if (y + (SpriteHeight*2) <= ScanLine || y > ScanLine)
|
||||
continue;
|
||||
if (y + (SpriteHeight * 2) <= ScanLine || y > ScanLine)
|
||||
continue;
|
||||
|
||||
int tileNo = VRAM[SpriteBase + 0x80 + (i * 2) + 1];
|
||||
if (EnableLargeSprites)
|
||||
tileNo &= 0xFE;
|
||||
tileNo += SpriteTileBase;
|
||||
int tileNo = VRAM[SpriteBase + 0x80 + (i * 2) + 1];
|
||||
if (EnableLargeSprites)
|
||||
tileNo &= 0xFE;
|
||||
tileNo += SpriteTileBase;
|
||||
|
||||
int ys = ScanLine - y;
|
||||
int ys = ScanLine - y;
|
||||
|
||||
for (int xs = 0; xs < 16 && x + xs < 256; xs++)
|
||||
{
|
||||
byte color = PatternBuffer[(tileNo * 64) + ((ys/2) * 8) + (xs/2)];
|
||||
if (color != 0 && x + xs >= 0 && ScanlinePriorityBuffer[x + xs] == 0)
|
||||
{
|
||||
if (SpriteCollisionBuffer[x + xs] != 0)
|
||||
StatusByte |= 0x20; // Set Collision bit
|
||||
else
|
||||
{
|
||||
if (show) FrameBuffer[(ys + y) * 256 + x + xs] = Palette[(color + 16)];
|
||||
SpriteCollisionBuffer[x + xs] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
SpritesDrawnThisScanline++;
|
||||
}
|
||||
}
|
||||
for (int xs = 0; xs < 16 && x + xs < 256; xs++)
|
||||
{
|
||||
byte color = PatternBuffer[(tileNo * 64) + ((ys / 2) * 8) + (xs / 2)];
|
||||
if (color != 0 && x + xs >= 0 && ScanlinePriorityBuffer[x + xs] == 0)
|
||||
{
|
||||
if (SpriteCollisionBuffer[x + xs] != 0)
|
||||
StatusByte |= 0x20; // Set Collision bit
|
||||
else
|
||||
{
|
||||
if (show) FrameBuffer[(ys + y) * 256 + x + xs] = Palette[(color + 16)];
|
||||
SpriteCollisionBuffer[x + xs] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
SpritesDrawnThisScanline++;
|
||||
}
|
||||
}
|
||||
|
||||
internal void ProcessSpriteCollisionForFrameskip()
|
||||
{
|
||||
if (DisplayOn == false) return;
|
||||
int SpriteBase = SpriteAttributeTableBase;
|
||||
int SpriteHeight = EnableLargeSprites ? 16 : 8;
|
||||
internal void ProcessSpriteCollisionForFrameskip()
|
||||
{
|
||||
if (DisplayOn == false) return;
|
||||
int SpriteBase = SpriteAttributeTableBase;
|
||||
int SpriteHeight = EnableLargeSprites ? 16 : 8;
|
||||
|
||||
// Clear the sprite collision buffer for this scanline
|
||||
Array.Clear(SpriteCollisionBuffer, 0, 256);
|
||||
// Clear the sprite collision buffer for this scanline
|
||||
Array.Clear(SpriteCollisionBuffer, 0, 256);
|
||||
|
||||
// 208 is a special terminator sprite (in 192-line mode). Lets find it...
|
||||
int TerminalSprite = 64;
|
||||
if (FrameHeight == 192)
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
if (VRAM[SpriteBase + i] == 208)
|
||||
{
|
||||
TerminalSprite = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 208 is a special terminator sprite (in 192-line mode). Lets find it...
|
||||
int TerminalSprite = 64;
|
||||
if (FrameHeight == 192)
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
if (VRAM[SpriteBase + i] == 208)
|
||||
{
|
||||
TerminalSprite = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Loop through these sprites and render the current scanline
|
||||
int SpritesDrawnThisScanline = 0;
|
||||
for (int i = TerminalSprite - 1; i >= 0; i--)
|
||||
{
|
||||
if (SpritesDrawnThisScanline >= 8)
|
||||
StatusByte |= 0x40; // Set Overflow bit
|
||||
// Loop through these sprites and render the current scanline
|
||||
int SpritesDrawnThisScanline = 0;
|
||||
for (int i = TerminalSprite - 1; i >= 0; i--)
|
||||
{
|
||||
if (SpritesDrawnThisScanline >= 8)
|
||||
StatusByte |= 0x40; // Set Overflow bit
|
||||
|
||||
int x = VRAM[SpriteBase + 0x80 + (i * 2)];
|
||||
if (ShiftSpritesLeft8Pixels)
|
||||
x -= 8;
|
||||
int x = VRAM[SpriteBase + 0x80 + (i * 2)];
|
||||
if (ShiftSpritesLeft8Pixels)
|
||||
x -= 8;
|
||||
|
||||
int y = VRAM[SpriteBase + i] + 1;
|
||||
if (y >= (EnableLargeSprites ? 240 : 248)) y -= 256;
|
||||
int y = VRAM[SpriteBase + i] + 1;
|
||||
if (y >= (EnableLargeSprites ? 240 : 248)) y -= 256;
|
||||
|
||||
if (y + SpriteHeight <= ScanLine || y > ScanLine)
|
||||
continue;
|
||||
if (y + SpriteHeight <= ScanLine || y > ScanLine)
|
||||
continue;
|
||||
|
||||
int tileNo = VRAM[SpriteBase + 0x80 + (i * 2) + 1];
|
||||
if (EnableLargeSprites)
|
||||
tileNo &= 0xFE;
|
||||
tileNo += SpriteTileBase;
|
||||
int tileNo = VRAM[SpriteBase + 0x80 + (i * 2) + 1];
|
||||
if (EnableLargeSprites)
|
||||
tileNo &= 0xFE;
|
||||
tileNo += SpriteTileBase;
|
||||
|
||||
int ys = ScanLine - y;
|
||||
int ys = ScanLine - y;
|
||||
|
||||
for (int xs = 0; xs < 8 && x + xs < 256; xs++)
|
||||
{
|
||||
byte color = PatternBuffer[(tileNo * 64) + (ys * 8) + xs];
|
||||
if (color != 0 && x + xs >= 0)
|
||||
{
|
||||
if (SpriteCollisionBuffer[x + xs] != 0)
|
||||
StatusByte |= 0x20; // Set Collision bit
|
||||
SpriteCollisionBuffer[x + xs] = 1;
|
||||
}
|
||||
}
|
||||
SpritesDrawnThisScanline++;
|
||||
}
|
||||
}
|
||||
for (int xs = 0; xs < 8 && x + xs < 256; xs++)
|
||||
{
|
||||
byte color = PatternBuffer[(tileNo * 64) + (ys * 8) + xs];
|
||||
if (color != 0 && x + xs >= 0)
|
||||
{
|
||||
if (SpriteCollisionBuffer[x + xs] != 0)
|
||||
StatusByte |= 0x20; // Set Collision bit
|
||||
SpriteCollisionBuffer[x + xs] = 1;
|
||||
}
|
||||
}
|
||||
SpritesDrawnThisScanline++;
|
||||
}
|
||||
}
|
||||
|
||||
// Performs render buffer blanking. This includes the left-column blanking as well as Game Gear blanking if requested.
|
||||
// Should be called at the end of the frame.
|
||||
internal void RenderBlankingRegions()
|
||||
{
|
||||
int blankingColor = Palette[BackdropColor];
|
||||
// Performs render buffer blanking. This includes the left-column blanking as well as Game Gear blanking if requested.
|
||||
// Should be called at the end of the frame.
|
||||
internal void RenderBlankingRegions()
|
||||
{
|
||||
int blankingColor = Palette[BackdropColor];
|
||||
|
||||
if (LeftBlanking)
|
||||
{
|
||||
for (int y = 0; y < FrameHeight; y++)
|
||||
{
|
||||
for (int x = 0; x < 8; x++)
|
||||
FrameBuffer[(y * 256) + x] = blankingColor;
|
||||
}
|
||||
}
|
||||
if (LeftBlanking)
|
||||
{
|
||||
for (int y = 0; y < FrameHeight; y++)
|
||||
{
|
||||
for (int x = 0; x < 8; x++)
|
||||
FrameBuffer[(y * 256) + x] = blankingColor;
|
||||
}
|
||||
}
|
||||
|
||||
if (mode == VdpMode.GameGear)
|
||||
{
|
||||
if (Sms.CoreComm.GG_ShowClippedRegions == false)
|
||||
{
|
||||
int yStart = (FrameHeight - 144)/2;
|
||||
for (int y = 0; y < 144; y++)
|
||||
for (int x = 0; x < 160; x++)
|
||||
GameGearFrameBuffer[(y * 160) + x] = FrameBuffer[((y + yStart) * 256) + x + 48];
|
||||
}
|
||||
if (mode == VdpMode.GameGear)
|
||||
{
|
||||
if (Sms.CoreComm.GG_ShowClippedRegions == false)
|
||||
{
|
||||
int yStart = (FrameHeight - 144) / 2;
|
||||
for (int y = 0; y < 144; y++)
|
||||
for (int x = 0; x < 160; x++)
|
||||
GameGearFrameBuffer[(y * 160) + x] = FrameBuffer[((y + yStart) * 256) + x + 48];
|
||||
}
|
||||
|
||||
if (Sms.CoreComm.GG_HighlightActiveDisplayRegion && Sms.CoreComm.GG_ShowClippedRegions)
|
||||
{
|
||||
// Top 24 scanlines
|
||||
for (int y = 0; y < 24; y++)
|
||||
{
|
||||
for (int x = 0; x < 256; x++)
|
||||
{
|
||||
int frameOffset = (y * 256) + x;
|
||||
int p = (FrameBuffer[frameOffset] >> 1) & 0x7F7F7F7F;
|
||||
FrameBuffer[frameOffset] = (int)((uint)p | 0x80000000);
|
||||
}
|
||||
}
|
||||
if (Sms.CoreComm.GG_HighlightActiveDisplayRegion && Sms.CoreComm.GG_ShowClippedRegions)
|
||||
{
|
||||
// Top 24 scanlines
|
||||
for (int y = 0; y < 24; y++)
|
||||
{
|
||||
for (int x = 0; x < 256; x++)
|
||||
{
|
||||
int frameOffset = (y * 256) + x;
|
||||
int p = (FrameBuffer[frameOffset] >> 1) & 0x7F7F7F7F;
|
||||
FrameBuffer[frameOffset] = (int)((uint)p | 0x80000000);
|
||||
}
|
||||
}
|
||||
|
||||
// Bottom 24 scanlines
|
||||
for (int y = 168; y < 192; y++)
|
||||
{
|
||||
for (int x = 0; x < 256; x++)
|
||||
{
|
||||
int frameOffset = (y * 256) + x;
|
||||
int p = (FrameBuffer[frameOffset] >> 1) & 0x7F7F7F7F;
|
||||
FrameBuffer[frameOffset] = (int)((uint)p | 0x80000000);
|
||||
}
|
||||
}
|
||||
// Bottom 24 scanlines
|
||||
for (int y = 168; y < 192; y++)
|
||||
{
|
||||
for (int x = 0; x < 256; x++)
|
||||
{
|
||||
int frameOffset = (y * 256) + x;
|
||||
int p = (FrameBuffer[frameOffset] >> 1) & 0x7F7F7F7F;
|
||||
FrameBuffer[frameOffset] = (int)((uint)p | 0x80000000);
|
||||
}
|
||||
}
|
||||
|
||||
// Left 48 pixels
|
||||
for (int y = 24; y < 168; y++)
|
||||
{
|
||||
for (int x = 0; x < 48; x++)
|
||||
{
|
||||
int frameOffset = (y * 256) + x;
|
||||
int p = (FrameBuffer[frameOffset] >> 1) & 0x7F7F7F7F;
|
||||
FrameBuffer[frameOffset] = (int)((uint)p | 0x80000000);
|
||||
}
|
||||
}
|
||||
// Left 48 pixels
|
||||
for (int y = 24; y < 168; y++)
|
||||
{
|
||||
for (int x = 0; x < 48; x++)
|
||||
{
|
||||
int frameOffset = (y * 256) + x;
|
||||
int p = (FrameBuffer[frameOffset] >> 1) & 0x7F7F7F7F;
|
||||
FrameBuffer[frameOffset] = (int)((uint)p | 0x80000000);
|
||||
}
|
||||
}
|
||||
|
||||
// Right 48 pixels
|
||||
for (int y = 24; y < 168; y++)
|
||||
{
|
||||
for (int x = 208; x < 256; x++)
|
||||
{
|
||||
int frameOffset = (y * 256) + x;
|
||||
int p = (FrameBuffer[frameOffset] >> 1) & 0x7F7F7F7F;
|
||||
FrameBuffer[frameOffset] = (int)((uint)p | 0x80000000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Right 48 pixels
|
||||
for (int y = 24; y < 168; y++)
|
||||
{
|
||||
for (int x = 208; x < 256; x++)
|
||||
{
|
||||
int frameOffset = (y * 256) + x;
|
||||
int p = (FrameBuffer[frameOffset] >> 1) & 0x7F7F7F7F;
|
||||
FrameBuffer[frameOffset] = (int)((uint)p | 0x80000000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
using System;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Sega
|
||||
namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
||||
{
|
||||
public partial class VDP
|
||||
{
|
||||
int[] PaletteTMS9918 = new int[]
|
||||
{
|
||||
public partial class VDP
|
||||
{
|
||||
int[] PaletteTMS9918 = new int[]
|
||||
{
|
||||
unchecked((int)0xFF000000),
|
||||
unchecked((int)0xFF000000),
|
||||
unchecked((int)0xFF47B73B),
|
||||
|
@ -26,138 +26,138 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
unchecked((int)0xFFFFFFFF)
|
||||
};
|
||||
|
||||
void RenderBackgroundM0(bool show)
|
||||
{
|
||||
if (DisplayOn == false)
|
||||
{
|
||||
Array.Clear(FrameBuffer, ScanLine * 256, 256);
|
||||
return;
|
||||
}
|
||||
void RenderBackgroundM0(bool show)
|
||||
{
|
||||
if (DisplayOn == false)
|
||||
{
|
||||
Array.Clear(FrameBuffer, ScanLine * 256, 256);
|
||||
return;
|
||||
}
|
||||
|
||||
int yc = ScanLine/8;
|
||||
int yofs = ScanLine%8;
|
||||
int FrameBufferOffset = ScanLine*256;
|
||||
int PatternNameOffset = TmsPatternNameTableBase + (yc*32);
|
||||
int ScreenBGColor = PaletteTMS9918[Registers[7] & 0x0F];
|
||||
int yc = ScanLine / 8;
|
||||
int yofs = ScanLine % 8;
|
||||
int FrameBufferOffset = ScanLine * 256;
|
||||
int PatternNameOffset = TmsPatternNameTableBase + (yc * 32);
|
||||
int ScreenBGColor = PaletteTMS9918[Registers[7] & 0x0F];
|
||||
|
||||
for (int xc=0; xc<32; xc++)
|
||||
{
|
||||
int pn = VRAM[PatternNameOffset++];
|
||||
int pv = VRAM[PatternGeneratorBase + (pn*8) + yofs];
|
||||
int colorEntry = VRAM[ColorTableBase + (pn/8)];
|
||||
int fgIndex = (colorEntry >> 4) & 0x0F;
|
||||
int bgIndex = colorEntry & 0x0F;
|
||||
int fgColor = fgIndex == 0 ? ScreenBGColor : PaletteTMS9918[fgIndex];
|
||||
int bgColor = bgIndex == 0 ? ScreenBGColor : PaletteTMS9918[bgIndex];
|
||||
for (int xc = 0; xc < 32; xc++)
|
||||
{
|
||||
int pn = VRAM[PatternNameOffset++];
|
||||
int pv = VRAM[PatternGeneratorBase + (pn * 8) + yofs];
|
||||
int colorEntry = VRAM[ColorTableBase + (pn / 8)];
|
||||
int fgIndex = (colorEntry >> 4) & 0x0F;
|
||||
int bgIndex = colorEntry & 0x0F;
|
||||
int fgColor = fgIndex == 0 ? ScreenBGColor : PaletteTMS9918[fgIndex];
|
||||
int bgColor = bgIndex == 0 ? ScreenBGColor : PaletteTMS9918[bgIndex];
|
||||
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x80) > 0) ? fgColor : bgColor) : 0;
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x40) > 0) ? fgColor : bgColor) : 0;
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x20) > 0) ? fgColor : bgColor) : 0;
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x10) > 0) ? fgColor : bgColor) : 0;
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x08) > 0) ? fgColor : bgColor) : 0;
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x04) > 0) ? fgColor : bgColor) : 0;
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x02) > 0) ? fgColor : bgColor) : 0;
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x01) > 0) ? fgColor : bgColor) : 0;
|
||||
}
|
||||
}
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x80) > 0) ? fgColor : bgColor) : 0;
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x40) > 0) ? fgColor : bgColor) : 0;
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x20) > 0) ? fgColor : bgColor) : 0;
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x10) > 0) ? fgColor : bgColor) : 0;
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x08) > 0) ? fgColor : bgColor) : 0;
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x04) > 0) ? fgColor : bgColor) : 0;
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x02) > 0) ? fgColor : bgColor) : 0;
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x01) > 0) ? fgColor : bgColor) : 0;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderBackgroundM2(bool show)
|
||||
{
|
||||
if (DisplayOn == false)
|
||||
{
|
||||
Array.Clear(FrameBuffer, ScanLine * 256, 256);
|
||||
return;
|
||||
}
|
||||
void RenderBackgroundM2(bool show)
|
||||
{
|
||||
if (DisplayOn == false)
|
||||
{
|
||||
Array.Clear(FrameBuffer, ScanLine * 256, 256);
|
||||
return;
|
||||
}
|
||||
|
||||
int yrow = ScanLine/8;
|
||||
int yofs = ScanLine%8;
|
||||
int FrameBufferOffset = ScanLine*256;
|
||||
int PatternNameOffset = TmsPatternNameTableBase + (yrow*32);
|
||||
int PatternGeneratorOffset = (((Registers[4] & 4) << 11) & 0x2000);// +((yrow / 8) * 0x100);
|
||||
int ColorOffset = (ColorTableBase & 0x2000);// +((yrow / 8) * 0x100);
|
||||
int ScreenBGColor = PaletteTMS9918[Registers[7] & 0x0F];
|
||||
int yrow = ScanLine / 8;
|
||||
int yofs = ScanLine % 8;
|
||||
int FrameBufferOffset = ScanLine * 256;
|
||||
int PatternNameOffset = TmsPatternNameTableBase + (yrow * 32);
|
||||
int PatternGeneratorOffset = (((Registers[4] & 4) << 11) & 0x2000);// +((yrow / 8) * 0x100);
|
||||
int ColorOffset = (ColorTableBase & 0x2000);// +((yrow / 8) * 0x100);
|
||||
int ScreenBGColor = PaletteTMS9918[Registers[7] & 0x0F];
|
||||
|
||||
for (int xc=0; xc<32; xc++)
|
||||
{
|
||||
int pn = VRAM[PatternNameOffset++] + ((yrow/8)*0x100);
|
||||
int pv = VRAM[PatternGeneratorOffset + (pn * 8) + yofs];
|
||||
int colorEntry = VRAM[ColorOffset + (pn * 8) + yofs];
|
||||
int fgIndex = (colorEntry >> 4) & 0x0F;
|
||||
int bgIndex = colorEntry & 0x0F;
|
||||
int fgColor = fgIndex == 0 ? ScreenBGColor : PaletteTMS9918[fgIndex];
|
||||
int bgColor = bgIndex == 0 ? ScreenBGColor : PaletteTMS9918[bgIndex];
|
||||
for (int xc = 0; xc < 32; xc++)
|
||||
{
|
||||
int pn = VRAM[PatternNameOffset++] + ((yrow / 8) * 0x100);
|
||||
int pv = VRAM[PatternGeneratorOffset + (pn * 8) + yofs];
|
||||
int colorEntry = VRAM[ColorOffset + (pn * 8) + yofs];
|
||||
int fgIndex = (colorEntry >> 4) & 0x0F;
|
||||
int bgIndex = colorEntry & 0x0F;
|
||||
int fgColor = fgIndex == 0 ? ScreenBGColor : PaletteTMS9918[fgIndex];
|
||||
int bgColor = bgIndex == 0 ? ScreenBGColor : PaletteTMS9918[bgIndex];
|
||||
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x80) > 0) ? fgColor : bgColor) : 0;
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x40) > 0) ? fgColor : bgColor) : 0;
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x20) > 0) ? fgColor : bgColor) : 0;
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x10) > 0) ? fgColor : bgColor) : 0;
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x08) > 0) ? fgColor : bgColor) : 0;
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x04) > 0) ? fgColor : bgColor) : 0;
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x02) > 0) ? fgColor : bgColor) : 0;
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x01) > 0) ? fgColor : bgColor) : 0;
|
||||
}
|
||||
}
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x80) > 0) ? fgColor : bgColor) : 0;
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x40) > 0) ? fgColor : bgColor) : 0;
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x20) > 0) ? fgColor : bgColor) : 0;
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x10) > 0) ? fgColor : bgColor) : 0;
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x08) > 0) ? fgColor : bgColor) : 0;
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x04) > 0) ? fgColor : bgColor) : 0;
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x02) > 0) ? fgColor : bgColor) : 0;
|
||||
FrameBuffer[FrameBufferOffset++] = show ? (((pv & 0x01) > 0) ? fgColor : bgColor) : 0;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderTmsSprites(bool show)
|
||||
{
|
||||
if (DisplayOn == false) return;
|
||||
void RenderTmsSprites(bool show)
|
||||
{
|
||||
if (DisplayOn == false) return;
|
||||
|
||||
Array.Clear(ScanlinePriorityBuffer, 0, 256);
|
||||
Array.Clear(SpriteCollisionBuffer, 0, 256);
|
||||
Array.Clear(ScanlinePriorityBuffer, 0, 256);
|
||||
Array.Clear(SpriteCollisionBuffer, 0, 256);
|
||||
|
||||
bool Double = EnableDoubledSprites;
|
||||
bool LargeSprites = EnableLargeSprites;
|
||||
bool Double = EnableDoubledSprites;
|
||||
bool LargeSprites = EnableLargeSprites;
|
||||
|
||||
int SpriteSize = 8;
|
||||
if (LargeSprites) SpriteSize *= 2;
|
||||
if (Double) SpriteSize *= 2;
|
||||
int OneCellSize = Double ? 16 : 8;
|
||||
int SpriteSize = 8;
|
||||
if (LargeSprites) SpriteSize *= 2;
|
||||
if (Double) SpriteSize *= 2;
|
||||
int OneCellSize = Double ? 16 : 8;
|
||||
|
||||
int NumSpritesOnScanline = 0;
|
||||
for (int i=0; i<32; i++)
|
||||
{
|
||||
int SpriteBase = TmsSpriteAttributeBase + (i*4);
|
||||
int y = VRAM[SpriteBase++];
|
||||
int x = VRAM[SpriteBase++];
|
||||
int Pattern = VRAM[SpriteBase++];
|
||||
int Color = VRAM[SpriteBase];
|
||||
int NumSpritesOnScanline = 0;
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
int SpriteBase = TmsSpriteAttributeBase + (i * 4);
|
||||
int y = VRAM[SpriteBase++];
|
||||
int x = VRAM[SpriteBase++];
|
||||
int Pattern = VRAM[SpriteBase++];
|
||||
int Color = VRAM[SpriteBase];
|
||||
|
||||
if (y == 208) break; // terminator sprite
|
||||
if (y > 224) y -= 256; // sprite Y wrap
|
||||
y++; // inexplicably, sprites start on Y+1
|
||||
if (y > ScanLine || y + SpriteSize <= ScanLine) continue; // sprite is not on this scanline
|
||||
if ((Color & 0x80) > 0) x -= 32; // Early Clock adjustment
|
||||
if (y == 208) break; // terminator sprite
|
||||
if (y > 224) y -= 256; // sprite Y wrap
|
||||
y++; // inexplicably, sprites start on Y+1
|
||||
if (y > ScanLine || y + SpriteSize <= ScanLine) continue; // sprite is not on this scanline
|
||||
if ((Color & 0x80) > 0) x -= 32; // Early Clock adjustment
|
||||
|
||||
if (++NumSpritesOnScanline == 5)
|
||||
{
|
||||
StatusByte |= (byte) i; // set 5th sprite index
|
||||
StatusByte |= 0x40; // set overflow bit
|
||||
break;
|
||||
}
|
||||
if (++NumSpritesOnScanline == 5)
|
||||
{
|
||||
StatusByte |= (byte)i; // set 5th sprite index
|
||||
StatusByte |= 0x40; // set overflow bit
|
||||
break;
|
||||
}
|
||||
|
||||
if (LargeSprites) Pattern &= 0xFC; // 16x16 sprites forced to 4-byte alignment
|
||||
int SpriteLine = ScanLine - y;
|
||||
if (Double) SpriteLine /= 2;
|
||||
if (LargeSprites) Pattern &= 0xFC; // 16x16 sprites forced to 4-byte alignment
|
||||
int SpriteLine = ScanLine - y;
|
||||
if (Double) SpriteLine /= 2;
|
||||
|
||||
byte pv = VRAM[SpritePatternGeneratorBase + (Pattern*8) + SpriteLine];
|
||||
byte pv = VRAM[SpritePatternGeneratorBase + (Pattern * 8) + SpriteLine];
|
||||
|
||||
for (int xp = 0; xp < SpriteSize && x + xp < 256; xp++)
|
||||
{
|
||||
if (x+xp < 0) continue;
|
||||
if (LargeSprites && xp == OneCellSize)
|
||||
pv = VRAM[SpritePatternGeneratorBase + (Pattern * 8) + SpriteLine + 16];
|
||||
for (int xp = 0; xp < SpriteSize && x + xp < 256; xp++)
|
||||
{
|
||||
if (x + xp < 0) continue;
|
||||
if (LargeSprites && xp == OneCellSize)
|
||||
pv = VRAM[SpritePatternGeneratorBase + (Pattern * 8) + SpriteLine + 16];
|
||||
|
||||
if ((pv & (1 << (7 - (xp & 7)))) > 0)
|
||||
{
|
||||
// todo sprite collision
|
||||
if (Color != 0 && ScanlinePriorityBuffer[x+xp] == 0)
|
||||
{
|
||||
ScanlinePriorityBuffer[x + xp] = 1;
|
||||
if (show) FrameBuffer[(ScanLine*256) + x + xp] = PaletteTMS9918[Color & 0x0F];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((pv & (1 << (7 - (xp & 7)))) > 0)
|
||||
{
|
||||
// todo sprite collision
|
||||
if (Color != 0 && ScanlinePriorityBuffer[x + xp] == 0)
|
||||
{
|
||||
ScanlinePriorityBuffer[x + xp] = 1;
|
||||
if (show) FrameBuffer[(ScanLine * 256) + x + xp] = PaletteTMS9918[Color & 0x0F];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace BizHawk.Emulation.Consoles.Sega
|
||||
namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
||||
{
|
||||
public partial class VDP
|
||||
{
|
||||
|
|
|
@ -7,7 +7,7 @@ using BizHawk.Emulation.Common;
|
|||
using BizHawk.Emulation.CPUs.Z80;
|
||||
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Sega
|
||||
namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
||||
{
|
||||
public enum VdpMode { SMS, GameGear }
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ using System.IO;
|
|||
using System.IO.Pipes;
|
||||
using System.Threading;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Sega.Saturn
|
||||
namespace BizHawk.Emulation.Cores.Sega.Saturn
|
||||
{
|
||||
/// <summary>
|
||||
/// helpers for moving files across named pipes
|
||||
|
|
|
@ -4,7 +4,7 @@ using System.Linq;
|
|||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Sega.Saturn
|
||||
namespace BizHawk.Emulation.Cores.Sega.Saturn
|
||||
{
|
||||
public static class LibYabause
|
||||
{
|
||||
|
|
|
@ -9,7 +9,7 @@ using BizHawk.Common;
|
|||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.DiscSystem;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Sega.Saturn
|
||||
namespace BizHawk.Emulation.Cores.Sega.Saturn
|
||||
{
|
||||
public class Yabause : IEmulator, IVideoProvider, ISyncSoundProvider
|
||||
{
|
||||
|
|
|
@ -4,7 +4,7 @@ using System.Linq;
|
|||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Sony.PSP
|
||||
namespace BizHawk.Emulation.Cores.Sony.PSP
|
||||
{
|
||||
public static class PPSSPPDll
|
||||
{
|
||||
|
|
|
@ -6,7 +6,7 @@ using System.Runtime.InteropServices;
|
|||
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Sony.PSP
|
||||
namespace BizHawk.Emulation.Cores.Sony.PSP
|
||||
{
|
||||
public class PSP : IEmulator, IVideoProvider, ISyncSoundProvider
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue