SMS: Implement TMS9918 legacy Mode 0
This commit is contained in:
parent
8a2307feb4
commit
34ec0bba39
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
|
@ -49,6 +49,7 @@
|
|||
<ItemGroup>
|
||||
<Compile Include="Consoles\Sega\SMS\MemoryMap.CodeMasters.cs" />
|
||||
<Compile Include="Consoles\Sega\SMS\MemoryMap.Sega.cs" />
|
||||
<Compile Include="Consoles\Sega\SMS\VDP.ModeTMS.cs" />
|
||||
<Compile Include="Consoles\Sega\SMS\VDP.Mode4.cs" />
|
||||
<Compile Include="Consoles\Sega\SMS\VDP.Tables.cs" />
|
||||
<Compile Include="CPUs\68000\Diassembler.cs" />
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
// Contains rendering functions for legacy TMS9918 modes.
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Sega
|
||||
{
|
||||
public partial class VDP
|
||||
{
|
||||
private int[] PaletteTMS9918 = new int[]
|
||||
{
|
||||
unchecked((int)0x00000000),
|
||||
unchecked((int)0xFF000000),
|
||||
unchecked((int)0xFF47B73B),
|
||||
unchecked((int)0xFF7CCF6F),
|
||||
unchecked((int)0xFF5D4EFF),
|
||||
unchecked((int)0xFF8072FF),
|
||||
unchecked((int)0xFFB66247),
|
||||
unchecked((int)0xFF5DC8ED),
|
||||
unchecked((int)0xFFD76B48),
|
||||
unchecked((int)0xFFFB8F6C),
|
||||
unchecked((int)0xFFC3CD41),
|
||||
unchecked((int)0xFFD3DA76),
|
||||
unchecked((int)0xFF3E9F2F),
|
||||
unchecked((int)0xFFB664C7),
|
||||
unchecked((int)0xFFCCCCCC),
|
||||
unchecked((int)0xFFFFFFFF)
|
||||
};
|
||||
|
||||
private void RenderBackgroundM0()
|
||||
{
|
||||
int yc = ScanLine/8;
|
||||
int yofs = ScanLine%8;
|
||||
int FrameBufferOffset = ScanLine*256;
|
||||
int PatternNameOffset = mystery_pn + (yc*32);
|
||||
|
||||
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 fgColor = PaletteTMS9918[(colorEntry >> 4 & 0x0F)];
|
||||
int bgColor = PaletteTMS9918[(colorEntry & 0x0F)];
|
||||
|
||||
FrameBuffer[FrameBufferOffset++] = ((pv & 0x80) > 0) ? fgColor : bgColor;
|
||||
FrameBuffer[FrameBufferOffset++] = ((pv & 0x40) > 0) ? fgColor : bgColor;
|
||||
FrameBuffer[FrameBufferOffset++] = ((pv & 0x20) > 0) ? fgColor : bgColor;
|
||||
FrameBuffer[FrameBufferOffset++] = ((pv & 0x10) > 0) ? fgColor : bgColor;
|
||||
FrameBuffer[FrameBufferOffset++] = ((pv & 0x08) > 0) ? fgColor : bgColor;
|
||||
FrameBuffer[FrameBufferOffset++] = ((pv & 0x04) > 0) ? fgColor : bgColor;
|
||||
FrameBuffer[FrameBufferOffset++] = ((pv & 0x02) > 0) ? fgColor : bgColor;
|
||||
FrameBuffer[FrameBufferOffset++] = ((pv & 0x01) > 0) ? fgColor : bgColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,6 +23,7 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
private byte VdpBuffer;
|
||||
private ushort VdpAddress;
|
||||
private VdpCommand vdpCommand;
|
||||
private int TmsMode = 4;
|
||||
|
||||
private bool VIntPending;
|
||||
private bool HIntPending;
|
||||
|
@ -37,7 +38,9 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
public int[] FrameBuffer = new int[256*192];
|
||||
public int[] GameGearFrameBuffer = new int[160*144];
|
||||
|
||||
public bool Mode1Bit { get { return (Registers[1] & 16) > 0;} }
|
||||
public bool Mode2Bit { get { return (Registers[0] & 2) > 0; } }
|
||||
public bool Mode3Bit { get { return (Registers[1] & 8) > 0; } }
|
||||
public bool Mode4Bit { get { return (Registers[0] & 4) > 0; } }
|
||||
public bool ShiftSpritesLeft8Pixels { get { return (Registers[0] & 8) > 0; } }
|
||||
public bool EnableLineInterrupts { get { return (Registers[0] & 16) > 0; } }
|
||||
|
@ -53,6 +56,10 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
public byte BackdropColor { get { return (byte)(16 + (Registers[7] & 15)); } }
|
||||
|
||||
private int NameTableBase;
|
||||
private int ColorTableBase;
|
||||
private int PatternGeneratorBase;
|
||||
private int SpritePatternGeneratorBase;
|
||||
private int mystery_pn;
|
||||
|
||||
// preprocessed state assist stuff.
|
||||
public int[] Palette = new int[32];
|
||||
|
@ -194,8 +201,33 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
|
||||
private void CheckVideoMode()
|
||||
{
|
||||
if (Mode4Bit && Mode2Bit) // if Mode4 and Mode2 set, then check extension modes
|
||||
if (Mode4Bit == false) // check old TMS modes
|
||||
{
|
||||
if (Mode1Bit)
|
||||
{
|
||||
Console.WriteLine("set mode 1....");
|
||||
TmsMode = 1;
|
||||
}
|
||||
else if (Mode2Bit)
|
||||
{
|
||||
Console.WriteLine("set mode 2....");
|
||||
TmsMode = 2;
|
||||
}
|
||||
else if (Mode3Bit)
|
||||
{
|
||||
Console.WriteLine("set mode 3....");
|
||||
TmsMode = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("set mode 0....");
|
||||
TmsMode = 0;
|
||||
}
|
||||
}
|
||||
|
||||
else if (Mode4Bit && Mode2Bit) // if Mode4 and Mode2 set, then check extension modes
|
||||
{
|
||||
TmsMode = 4;
|
||||
switch (Registers[1] & 0x18)
|
||||
{
|
||||
case 0x00:
|
||||
|
@ -227,7 +259,10 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
}
|
||||
break;
|
||||
}
|
||||
} else { // default to standard 192-line mode4
|
||||
}
|
||||
|
||||
else { // default to standard 192-line mode4
|
||||
TmsMode = 4;
|
||||
if (FrameHeight != 192)
|
||||
{
|
||||
Console.WriteLine("Change video mode to 192-line Mode4");
|
||||
|
@ -253,6 +288,19 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
break;
|
||||
case 2: // Name Table Base Address
|
||||
NameTableBase = CalcNameTableBase();
|
||||
mystery_pn = (Registers[2] << 10) & 0x3C00;
|
||||
break;
|
||||
case 3: // Color Table Base Address
|
||||
ColorTableBase = (Registers[3] << 6) & 0x3FC0;
|
||||
break;
|
||||
case 4: // Pattern Generator Base Address
|
||||
PatternGeneratorBase = (Registers[4] << 11) & 0x3800;
|
||||
break;
|
||||
case 5: // Sprite Attribute Table Base Address
|
||||
// ??? should I move from my property to precalculated?
|
||||
break;
|
||||
case 6: // Sprite Pattern Generator Base Adderss
|
||||
SpritePatternGeneratorBase = (Registers[6] << 11) & 0x3800;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -326,13 +374,18 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
if (ScanLine >= FrameHeight)
|
||||
return;
|
||||
|
||||
// TODO: make frameskip actually skip rendering
|
||||
RenderBackgroundCurrentLine();
|
||||
|
||||
if (EnableDoubledSprites)
|
||||
RenderSpritesCurrentLineDoubleSize();
|
||||
else
|
||||
RenderSpritesCurrentLine();
|
||||
if (TmsMode == 4)
|
||||
{
|
||||
// TODO: make frameskip actually skip rendering
|
||||
RenderBackgroundCurrentLine();
|
||||
|
||||
if (EnableDoubledSprites)
|
||||
RenderSpritesCurrentLineDoubleSize();
|
||||
else
|
||||
RenderSpritesCurrentLine();
|
||||
} else if (TmsMode == 0) {
|
||||
RenderBackgroundM0();
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveStateText(TextWriter writer)
|
||||
|
|
|
@ -7,31 +7,27 @@
|
|||
|
||||
static CRC32()
|
||||
{
|
||||
//unchecked {
|
||||
CRC32Table = new uint[256];
|
||||
for (uint i = 0; i < 256; ++i)
|
||||
CRC32Table = new uint[256];
|
||||
for (uint i = 0; i < 256; ++i)
|
||||
{
|
||||
uint crc = i;
|
||||
for (int j = 8; j > 0; --j)
|
||||
{
|
||||
uint crc = i;
|
||||
for (int j = 8; j > 0; --j)
|
||||
{
|
||||
if ((crc & 1) == 1)
|
||||
crc = ((crc >> 1) ^ 0xEDB88320);
|
||||
else
|
||||
crc >>= 1;
|
||||
}
|
||||
CRC32Table[i] = crc;
|
||||
if ((crc & 1) == 1)
|
||||
crc = ((crc >> 1) ^ 0xEDB88320);
|
||||
else
|
||||
crc >>= 1;
|
||||
}
|
||||
//}
|
||||
CRC32Table[i] = crc;
|
||||
}
|
||||
}
|
||||
|
||||
public static int Calculate(byte[] data)
|
||||
{
|
||||
//unchecked {
|
||||
uint Result = 0xFFFFFFFF;
|
||||
foreach (var b in data)
|
||||
Result = (((Result) >> 8) ^ CRC32Table[b ^ ((Result) & 0xFF)]);
|
||||
return (int)~Result;
|
||||
//}
|
||||
uint Result = 0xFFFFFFFF;
|
||||
foreach (var b in data)
|
||||
Result = (((Result) >> 8) ^ CRC32Table[b ^ ((Result) & 0xFF)]);
|
||||
return (int)~Result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue