diff --git a/BizHawk.Emulation/Consoles/Sega/Genesis/GenVDP.Render.cs b/BizHawk.Emulation/Consoles/Sega/Genesis/GenVDP.Render.cs index bdc973a99b..ff257aace6 100644 --- a/BizHawk.Emulation/Consoles/Sega/Genesis/GenVDP.Render.cs +++ b/BizHawk.Emulation/Consoles/Sega/Genesis/GenVDP.Render.cs @@ -166,19 +166,19 @@ namespace BizHawk.Emulation.Consoles.Sega void FetchSprite(int spriteNo) { - int satbase = SpriteAttributeTableAddr + (spriteNo*8); - sprite.Y = (VRAM[satbase + 0] | (VRAM[satbase + 1] << 8) & 0x3FF) - 128; - sprite.X = (VRAM[satbase + 6] | (VRAM[satbase + 7] << 8) & 0x3FF) - 128; - sprite.WidthPixels = SpriteSizeTable[(VRAM[satbase + 3] >> 2) & 3]; - sprite.HeightPixels = SpriteSizeTable[VRAM[satbase + 3] & 3]; - sprite.WidthCells = ((VRAM[satbase + 3] >> 2) & 3) + 1; - sprite.HeightCells = (VRAM[satbase + 3] & 3) + 1; - sprite.Link = VRAM[satbase + 2] & 0x7F; - sprite.PatternIndex = (VRAM[satbase + 4] | (VRAM[satbase + 5] << 8)) & 0x7FF; - sprite.HFlip = ((VRAM[satbase + 5] >> 3) & 1) != 0; - sprite.VFlip = ((VRAM[satbase + 5] >> 4) & 1) != 0; - sprite.Palette = (VRAM[satbase + 5] >> 5) & 3; - sprite.Priority = ((VRAM[satbase + 5] >> 7) & 1) != 0; + int SatBase = SpriteAttributeTableAddr + (spriteNo*8); + sprite.Y = (VRAM[SatBase + 0] | (VRAM[SatBase + 1] << 8) & 0x3FF) - 128; + sprite.X = (VRAM[SatBase + 6] | (VRAM[SatBase + 7] << 8) & 0x3FF) - 128; + sprite.WidthPixels = SpriteSizeTable[(VRAM[SatBase + 3] >> 2) & 3]; + sprite.HeightPixels = SpriteSizeTable[VRAM[SatBase + 3] & 3]; + sprite.WidthCells = ((VRAM[SatBase + 3] >> 2) & 3) + 1; + sprite.HeightCells = (VRAM[SatBase + 3] & 3) + 1; + sprite.Link = VRAM[SatBase + 2] & 0x7F; + sprite.PatternIndex = (VRAM[SatBase + 4] | (VRAM[SatBase + 5] << 8)) & 0x7FF; + sprite.HFlip = ((VRAM[SatBase + 5] >> 3) & 1) != 0; + sprite.VFlip = ((VRAM[SatBase + 5] >> 4) & 1) != 0; + sprite.Palette = (VRAM[SatBase + 5] >> 5) & 3; + sprite.Priority = ((VRAM[SatBase + 5] >> 7) & 1) != 0; } struct Sprite diff --git a/BizHawk.Emulation/Consoles/Sega/Genesis/GenVDP.cs b/BizHawk.Emulation/Consoles/Sega/Genesis/GenVDP.cs index 75dff7c8ad..b4971483f1 100644 --- a/BizHawk.Emulation/Consoles/Sega/Genesis/GenVDP.cs +++ b/BizHawk.Emulation/Consoles/Sega/Genesis/GenVDP.cs @@ -38,11 +38,48 @@ namespace BizHawk.Emulation.Consoles.Sega ushort VdpDataAddr; byte VdpDataCode; + const int CommandVramRead = 0; + const int CommandVramWrite = 1; + const int CommandCramWrite = 3; + const int CommandVsramRead = 4; + const int CommandVsramWrite = 5; + const int CommandCramRead = 7; + static readonly byte[] PalXlatTable = { 0, 0, 36, 36, 73, 73, 109, 109, 145, 145, 182, 182, 219, 219, 255, 255 }; + public ushort ReadVdp(int addr) + { + switch (addr) + { + case 0: + case 2: + return ReadVdpData(); + case 4: + case 6: + return ReadVdpControl(); + default: + throw new Exception("HV Counter read...."); + } + } + + public void WriteVdp(int addr, ushort data) + { + switch (addr) + { + case 0: + case 2: + WriteVdpData(data); + return; + case 4: + case 6: + WriteVdpControl(data); + return; + } + } + public void WriteVdpControl(ushort data) { - Log.Note("VDP", "VDP: Control Write {0:X4}", data); + //Log.Note("VDP", "VDP: Control Write {0:X4}", data); if (ControlWordPending == false) { @@ -84,7 +121,7 @@ namespace BizHawk.Emulation.Consoles.Sega DmaFillModePending = true; break; case 3: - Log.Note("VDP", "VRAM COPY **** UNIMPLEMENTED ***"); + Log.Error("VDP", "VRAM COPY **** UNIMPLEMENTED ***"); break; default: Log.Note("VDP", "68k->VRAM COPY"); @@ -100,7 +137,7 @@ namespace BizHawk.Emulation.Consoles.Sega { ushort value = 0x3400; // fixed bits per genvdp.txt TODO test on everdrive, I guess. value |= 0x0200; // Fifo empty - Log.Note("VDP", "VDP: Control Read {0:X4}", value); + //Log.Note("VDP", "VDP: Control Read {0:X4}", value); return value; } @@ -109,8 +146,9 @@ namespace BizHawk.Emulation.Consoles.Sega ControlWordPending = false; // byte-swap incoming data when A0 is set - if ((VdpDataAddr & 1) != 0) - data = (ushort) ((data >> 8) | (data << 8)); + // TODO what is the reason for thinking that this happens? + //if ((VdpDataAddr & 1) != 0) + // data = (ushort) ((data >> 8) | (data << 8)); if (DmaFillModePending) { @@ -119,7 +157,7 @@ namespace BizHawk.Emulation.Consoles.Sega switch (VdpDataCode & 7) { - case 1: // VRAM Write + case CommandVramWrite: // VRAM Write VRAM[VdpDataAddr & 0xFFFE] = (byte) data; VRAM[(VdpDataAddr & 0xFFFE) + 1] = (byte) (data >> 8); UpdatePatternBuffer(VdpDataAddr & 0xFFFE); @@ -127,13 +165,13 @@ namespace BizHawk.Emulation.Consoles.Sega //Console.WriteLine("Wrote VRAM[{0:X4}] = {1:X4}", VdpDataAddr, data); VdpDataAddr += Registers[0x0F]; break; - case 3: // CRAM write + case CommandCramWrite: // CRAM write CRAM[(VdpDataAddr / 2) % 64] = data; //Console.WriteLine("Wrote CRAM[{0:X2}] = {1:X4}", (VdpDataAddr / 2) % 64, data); ProcessPalette((VdpDataAddr/2)%64); VdpDataAddr += Registers[0x0F]; break; - case 5: // VSRAM write + case CommandVsramWrite: // VSRAM write VSRAM[(VdpDataAddr / 2) % 40] = data; //Console.WriteLine("Wrote VSRAM[{0:X2}] = {1:X4}", (VdpDataAddr / 2) % 40, data); VdpDataAddr += Registers[0x0F]; @@ -147,7 +185,22 @@ namespace BizHawk.Emulation.Consoles.Sega public ushort ReadVdpData() { Console.WriteLine("VDP: Data Read"); - return 0; + + ushort retval = 0xBEEF; + switch (VdpDataCode & 7) + { + case CommandVramRead: + retval = VRAM[VdpDataAddr & 0xFFFE]; + retval |= (ushort) (VRAM[(VdpDataAddr & 0xFFFE) + 1] << 8); + VdpDataAddr += Registers[0x0F]; + break; + case CommandVsramRead: + throw new Exception("VSRAM read"); + case CommandCramRead: + throw new Exception("CRAM read"); + } + + return retval; } public void WriteVdpRegister(int register, byte data) @@ -259,13 +312,13 @@ namespace BizHawk.Emulation.Consoles.Sega case 0x11: // Window H Position int whp = data & 31; bool fromright = (data & 0x80) != 0; - //Log.Note("VDP", "Window H is {0} units from {1}", whp, fromright ? "right" : "left"); + Log.Error("VDP", "Window H is {0} units from {1}", whp, fromright ? "right" : "left"); break; case 0x12: // Window V whp = data & 31; fromright = (data & 0x80) != 0; - //Log.Note("VDP", "Window V is {0} units from {1}", whp, fromright ? "lower" : "upper"); + Log.Error("VDP", "Window V is {0} units from {1}", whp, fromright ? "lower" : "upper"); break; case 0x13: // DMA Length Low diff --git a/BizHawk.Emulation/Consoles/Sega/Genesis/MemoryMap.68000.cs b/BizHawk.Emulation/Consoles/Sega/Genesis/MemoryMap.68000.cs index 434df79a89..1bb2809034 100644 --- a/BizHawk.Emulation/Consoles/Sega/Genesis/MemoryMap.68000.cs +++ b/BizHawk.Emulation/Consoles/Sega/Genesis/MemoryMap.68000.cs @@ -26,9 +26,10 @@ namespace BizHawk.Emulation.Consoles.Sega if ((address & 0xFF0000) == 0xA00000) return (sbyte) ReadMemoryZ80((ushort) (address & 0x7FFF)); - if (address >= 0xC00004 && address < 0xC00008) + if (address >= 0xC00000 && address < 0xC00010) { - ushort value = VDP.ReadVdpControl(); + 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 @@ -52,8 +53,8 @@ namespace BizHawk.Emulation.Consoles.Sega return (short)((Ram[maskedAddr] << 8) | Ram[maskedAddr + 1]); } - if (address >= 0xC00004 && address < 0xC00008) - return (short) VDP.ReadVdpControl(); + if (address >= 0xC00000 && address < 0xC00010) + return (short) VDP.ReadVdp(address & 0x0E); if (address >= 0xA10000 && address <= 0xA1001F) return (sbyte)ReadIO(address); @@ -120,28 +121,16 @@ namespace BizHawk.Emulation.Consoles.Sega //Console.WriteLine("z80 reset: " + Z80Reset); return; } - if (address >= 0xC00000) + if (address >= 0xC00000 && address < 0xC00010) { // when writing to VDP in byte mode, the LSB is duplicated into the MSB - switch (address & 0x1F) - { - case 0x00: - case 0x02: - //zero 15-feb-2012 - added latter two ushort casts to kill a warning - VDP.WriteVdpData((ushort) ((ushort)value | ((ushort)value << 8))); - return; - case 0x04: - case 0x06: - //zero 15-feb-2012 - added latter two ushort casts to kill a warning - VDP.WriteVdpControl((ushort) ((ushort)value | ((ushort)value << 8))); - return; - case 0x11: - case 0x13: - case 0x15: - case 0x17: - PSG.WritePsgData((byte) value, SoundCPU.TotalExecutedCycles); - return; - } + 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; } Console.WriteLine("UNHANDLED WRITEB {0:X6}:{1:X2}", address, value); @@ -211,5 +200,14 @@ namespace BizHawk.Emulation.Consoles.Sega 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); } } }