SMS: Implement TMS9918 legacy Mode 0

This commit is contained in:
beirich 2011-01-17 07:41:01 +00:00
parent 8a2307feb4
commit 34ec0bba39
4 changed files with 132 additions and 29 deletions

View File

@ -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" />

View File

@ -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;
}
}
}
}

View File

@ -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)

View File

@ -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;
}
}
}