gen: improved memory map and VDP I/O

This commit is contained in:
beirich 2012-08-26 03:43:35 +00:00
parent 7ad3ea9ef5
commit 2f73408029
3 changed files with 99 additions and 48 deletions

View File

@ -166,19 +166,19 @@ namespace BizHawk.Emulation.Consoles.Sega
void FetchSprite(int spriteNo) void FetchSprite(int spriteNo)
{ {
int satbase = SpriteAttributeTableAddr + (spriteNo*8); int SatBase = SpriteAttributeTableAddr + (spriteNo*8);
sprite.Y = (VRAM[satbase + 0] | (VRAM[satbase + 1] << 8) & 0x3FF) - 128; sprite.Y = (VRAM[SatBase + 0] | (VRAM[SatBase + 1] << 8) & 0x3FF) - 128;
sprite.X = (VRAM[satbase + 6] | (VRAM[satbase + 7] << 8) & 0x3FF) - 128; sprite.X = (VRAM[SatBase + 6] | (VRAM[SatBase + 7] << 8) & 0x3FF) - 128;
sprite.WidthPixels = SpriteSizeTable[(VRAM[satbase + 3] >> 2) & 3]; sprite.WidthPixels = SpriteSizeTable[(VRAM[SatBase + 3] >> 2) & 3];
sprite.HeightPixels = SpriteSizeTable[VRAM[satbase + 3] & 3]; sprite.HeightPixels = SpriteSizeTable[VRAM[SatBase + 3] & 3];
sprite.WidthCells = ((VRAM[satbase + 3] >> 2) & 3) + 1; sprite.WidthCells = ((VRAM[SatBase + 3] >> 2) & 3) + 1;
sprite.HeightCells = (VRAM[satbase + 3] & 3) + 1; sprite.HeightCells = (VRAM[SatBase + 3] & 3) + 1;
sprite.Link = VRAM[satbase + 2] & 0x7F; sprite.Link = VRAM[SatBase + 2] & 0x7F;
sprite.PatternIndex = (VRAM[satbase + 4] | (VRAM[satbase + 5] << 8)) & 0x7FF; sprite.PatternIndex = (VRAM[SatBase + 4] | (VRAM[SatBase + 5] << 8)) & 0x7FF;
sprite.HFlip = ((VRAM[satbase + 5] >> 3) & 1) != 0; sprite.HFlip = ((VRAM[SatBase + 5] >> 3) & 1) != 0;
sprite.VFlip = ((VRAM[satbase + 5] >> 4) & 1) != 0; sprite.VFlip = ((VRAM[SatBase + 5] >> 4) & 1) != 0;
sprite.Palette = (VRAM[satbase + 5] >> 5) & 3; sprite.Palette = (VRAM[SatBase + 5] >> 5) & 3;
sprite.Priority = ((VRAM[satbase + 5] >> 7) & 1) != 0; sprite.Priority = ((VRAM[SatBase + 5] >> 7) & 1) != 0;
} }
struct Sprite struct Sprite

View File

@ -38,11 +38,48 @@ namespace BizHawk.Emulation.Consoles.Sega
ushort VdpDataAddr; ushort VdpDataAddr;
byte VdpDataCode; 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 }; 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) 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) if (ControlWordPending == false)
{ {
@ -84,7 +121,7 @@ namespace BizHawk.Emulation.Consoles.Sega
DmaFillModePending = true; DmaFillModePending = true;
break; break;
case 3: case 3:
Log.Note("VDP", "VRAM COPY **** UNIMPLEMENTED ***"); Log.Error("VDP", "VRAM COPY **** UNIMPLEMENTED ***");
break; break;
default: default:
Log.Note("VDP", "68k->VRAM COPY"); 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. ushort value = 0x3400; // fixed bits per genvdp.txt TODO test on everdrive, I guess.
value |= 0x0200; // Fifo empty value |= 0x0200; // Fifo empty
Log.Note("VDP", "VDP: Control Read {0:X4}", value); //Log.Note("VDP", "VDP: Control Read {0:X4}", value);
return value; return value;
} }
@ -109,8 +146,9 @@ namespace BizHawk.Emulation.Consoles.Sega
ControlWordPending = false; ControlWordPending = false;
// byte-swap incoming data when A0 is set // byte-swap incoming data when A0 is set
if ((VdpDataAddr & 1) != 0) // TODO what is the reason for thinking that this happens?
data = (ushort) ((data >> 8) | (data << 8)); //if ((VdpDataAddr & 1) != 0)
// data = (ushort) ((data >> 8) | (data << 8));
if (DmaFillModePending) if (DmaFillModePending)
{ {
@ -119,7 +157,7 @@ namespace BizHawk.Emulation.Consoles.Sega
switch (VdpDataCode & 7) switch (VdpDataCode & 7)
{ {
case 1: // VRAM Write case CommandVramWrite: // VRAM Write
VRAM[VdpDataAddr & 0xFFFE] = (byte) data; VRAM[VdpDataAddr & 0xFFFE] = (byte) data;
VRAM[(VdpDataAddr & 0xFFFE) + 1] = (byte) (data >> 8); VRAM[(VdpDataAddr & 0xFFFE) + 1] = (byte) (data >> 8);
UpdatePatternBuffer(VdpDataAddr & 0xFFFE); UpdatePatternBuffer(VdpDataAddr & 0xFFFE);
@ -127,13 +165,13 @@ namespace BizHawk.Emulation.Consoles.Sega
//Console.WriteLine("Wrote VRAM[{0:X4}] = {1:X4}", VdpDataAddr, data); //Console.WriteLine("Wrote VRAM[{0:X4}] = {1:X4}", VdpDataAddr, data);
VdpDataAddr += Registers[0x0F]; VdpDataAddr += Registers[0x0F];
break; break;
case 3: // CRAM write case CommandCramWrite: // CRAM write
CRAM[(VdpDataAddr / 2) % 64] = data; CRAM[(VdpDataAddr / 2) % 64] = data;
//Console.WriteLine("Wrote CRAM[{0:X2}] = {1:X4}", (VdpDataAddr / 2) % 64, data); //Console.WriteLine("Wrote CRAM[{0:X2}] = {1:X4}", (VdpDataAddr / 2) % 64, data);
ProcessPalette((VdpDataAddr/2)%64); ProcessPalette((VdpDataAddr/2)%64);
VdpDataAddr += Registers[0x0F]; VdpDataAddr += Registers[0x0F];
break; break;
case 5: // VSRAM write case CommandVsramWrite: // VSRAM write
VSRAM[(VdpDataAddr / 2) % 40] = data; VSRAM[(VdpDataAddr / 2) % 40] = data;
//Console.WriteLine("Wrote VSRAM[{0:X2}] = {1:X4}", (VdpDataAddr / 2) % 40, data); //Console.WriteLine("Wrote VSRAM[{0:X2}] = {1:X4}", (VdpDataAddr / 2) % 40, data);
VdpDataAddr += Registers[0x0F]; VdpDataAddr += Registers[0x0F];
@ -147,7 +185,22 @@ namespace BizHawk.Emulation.Consoles.Sega
public ushort ReadVdpData() public ushort ReadVdpData()
{ {
Console.WriteLine("VDP: Data Read"); 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) public void WriteVdpRegister(int register, byte data)
@ -259,13 +312,13 @@ namespace BizHawk.Emulation.Consoles.Sega
case 0x11: // Window H Position case 0x11: // Window H Position
int whp = data & 31; int whp = data & 31;
bool fromright = (data & 0x80) != 0; 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; break;
case 0x12: // Window V case 0x12: // Window V
whp = data & 31; whp = data & 31;
fromright = (data & 0x80) != 0; 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; break;
case 0x13: // DMA Length Low case 0x13: // DMA Length Low

View File

@ -26,9 +26,10 @@ namespace BizHawk.Emulation.Consoles.Sega
if ((address & 0xFF0000) == 0xA00000) if ((address & 0xFF0000) == 0xA00000)
return (sbyte) ReadMemoryZ80((ushort) (address & 0x7FFF)); 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 if ((address & 1) == 0) // read MSB
return (sbyte) (value >> 8); return (sbyte) (value >> 8);
return (sbyte) value; // read LSB return (sbyte) value; // read LSB
@ -52,8 +53,8 @@ namespace BizHawk.Emulation.Consoles.Sega
return (short)((Ram[maskedAddr] << 8) | Ram[maskedAddr + 1]); return (short)((Ram[maskedAddr] << 8) | Ram[maskedAddr + 1]);
} }
if (address >= 0xC00004 && address < 0xC00008) if (address >= 0xC00000 && address < 0xC00010)
return (short) VDP.ReadVdpControl(); return (short) VDP.ReadVdp(address & 0x0E);
if (address >= 0xA10000 && address <= 0xA1001F) if (address >= 0xA10000 && address <= 0xA1001F)
return (sbyte)ReadIO(address); return (sbyte)ReadIO(address);
@ -120,28 +121,16 @@ namespace BizHawk.Emulation.Consoles.Sega
//Console.WriteLine("z80 reset: " + Z80Reset); //Console.WriteLine("z80 reset: " + Z80Reset);
return; return;
} }
if (address >= 0xC00000) if (address >= 0xC00000 && address < 0xC00010)
{ {
// when writing to VDP in byte mode, the LSB is duplicated into the MSB // when writing to VDP in byte mode, the LSB is duplicated into the MSB
switch (address & 0x1F) VDP.WriteVdp(address & 0x1E, (ushort)((ushort)value | ((ushort)value << 8)));
{ return;
case 0x00: }
case 0x02: if (address >= 0xC00011 && address <= 0xC00017 && (address & 1) != 0)
//zero 15-feb-2012 - added latter two ushort casts to kill a warning {
VDP.WriteVdpData((ushort) ((ushort)value | ((ushort)value << 8))); PSG.WritePsgData((byte) value, SoundCPU.TotalExecutedCycles);
return; 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;
}
} }
Console.WriteLine("UNHANDLED WRITEB {0:X6}:{1:X2}", address, value); 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); 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); }
} }
} }