gen: improved memory map and VDP I/O
This commit is contained in:
parent
7ad3ea9ef5
commit
2f73408029
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue