GEN: Preliminary sprite rendering. hook up MemoryDomains.
This commit is contained in:
parent
a95957dcf6
commit
f8564bf8a7
|
@ -8,6 +8,7 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
public Func<int, short> DmaReadFrom68000; // TODO make ushort
|
||||
|
||||
public int DmaLength { get { return Registers[19] | (Registers[20] << 8); } }
|
||||
public int DmaMode { get { return (Registers[23] >> 6) & 3; } }
|
||||
|
||||
public int DmaSource
|
||||
{
|
||||
|
@ -21,28 +22,26 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
bool DmaFillModePending;
|
||||
|
||||
void ExecuteDmaFill(ushort data)
|
||||
{
|
||||
Console.WriteLine("DMA FILL REQD, WRITE {0:X4}, {1:X4} times, at {2:X4}", data, DmaLength, VdpDataAddr);
|
||||
Log.Note("VDP","DMA FILL REQD, WRITE {0:X4}, {1:X4} times, at {2:X4}", data, DmaLength, VdpDataAddr);
|
||||
|
||||
// TODO: Is the address really VdpDataAddr and not DMA source? I guess that makes sense.
|
||||
// TODO: It should spread this out, not do it all at once.
|
||||
// TODO: DMA can go to places besides just VRAM (eg CRAM, VSRAM)
|
||||
// TODO: Does DMA fill really use the actual increment register value?
|
||||
// TODO: DMA can go to places besides just VRAM (eg CRAM, VSRAM) ??? can it?
|
||||
// TODO: what is this genvdp.txt comment about accurate vdp fill emulation writing some other byte first?
|
||||
|
||||
int length = DmaLength;
|
||||
if (length == 0)
|
||||
length = 0x10000; // Really necessary?
|
||||
length = 0x10000;
|
||||
|
||||
byte fillByte = (byte)(data >> 8);
|
||||
|
||||
do
|
||||
{
|
||||
VRAM[VdpDataAddr & 0xFFFF] = fillByte;
|
||||
UpdatePatternBuffer(VdpDataAddr & 0xFFFF);
|
||||
VRAM[VdpDataAddr] = fillByte;
|
||||
UpdatePatternBuffer(VdpDataAddr);
|
||||
VdpDataAddr += Registers[15];
|
||||
} while (--length > 0);
|
||||
|
||||
|
@ -51,7 +50,7 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
|
||||
void Execute68000VramCopy()
|
||||
{
|
||||
Console.WriteLine("DMA 68000 -> VRAM COPY REQ'D. LENGTH {0:X4}, SOURCE {1:X4}", DmaLength, DmaSource);
|
||||
Log.Note("VDP", "DMA 68000 -> VRAM COPY REQ'D. LENGTH {0:X4}, SOURCE {1:X4}", DmaLength, DmaSource);
|
||||
|
||||
int length = DmaLength;
|
||||
if (length == 0)
|
||||
|
|
|
@ -8,15 +8,14 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
{
|
||||
if (ScanLine == 0)
|
||||
{
|
||||
for (int i = 0; i < FrameBuffer.Length; i++)
|
||||
FrameBuffer[i] = 0;
|
||||
Array.Clear(FrameBuffer, 0, FrameBuffer.Length);
|
||||
|
||||
//RenderPatterns();
|
||||
RenderPalette();
|
||||
RenderScrollA();
|
||||
RenderScrollB();
|
||||
RenderSprites();
|
||||
}
|
||||
RenderSprites();
|
||||
}
|
||||
|
||||
void RenderPalette()
|
||||
|
@ -76,33 +75,68 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
}
|
||||
}
|
||||
|
||||
static readonly int[] SpriteSizeTable = { 8, 16, 24, 32 };
|
||||
Sprite sprite;
|
||||
|
||||
void RenderSprites()
|
||||
{
|
||||
Sprite sprite = FetchSprite(0);
|
||||
/*if (sprite.X > 0)
|
||||
Console.WriteLine("doot");*/
|
||||
int scanLineBase = ScanLine * FrameWidth;
|
||||
int processedSprites = 0;
|
||||
|
||||
FetchSprite(0);
|
||||
while (true)
|
||||
{
|
||||
if (sprite.Y > ScanLine || sprite.Y+sprite.HeightPixels <= ScanLine)
|
||||
goto nextSprite;
|
||||
if (sprite.X + sprite.WidthPixels <= 0)
|
||||
goto nextSprite;
|
||||
|
||||
if (sprite.HeightCells == 2)
|
||||
sprite.HeightCells = 2;
|
||||
|
||||
int yline = ScanLine - sprite.Y;
|
||||
int paletteBase = sprite.Palette * 16;
|
||||
int pattern = sprite.PatternIndex + ((yline / 8));
|
||||
int x = sprite.X;
|
||||
|
||||
for (int xi = 0; xi < sprite.WidthPixels; xi++)
|
||||
{
|
||||
if (sprite.X + xi < 0 || sprite.X + xi > FrameWidth)
|
||||
continue;
|
||||
|
||||
int pixel = PatternBuffer[((pattern+((xi/8)*sprite.HeightCells)) * 64) + ((yline & 7) * 8) + (xi & 7)];
|
||||
if (pixel != 0)
|
||||
FrameBuffer[scanLineBase + sprite.X + xi] = Palette[paletteBase + pixel];
|
||||
}
|
||||
|
||||
nextSprite:
|
||||
if (sprite.Link == 0)
|
||||
break;
|
||||
if (++processedSprites > 80)
|
||||
break;
|
||||
FetchSprite(sprite.Link);
|
||||
}
|
||||
}
|
||||
|
||||
Sprite FetchSprite(int spriteNo)
|
||||
void FetchSprite(int spriteNo)
|
||||
{
|
||||
int satbase = SpriteAttributeTableAddr + (spriteNo*8);
|
||||
Sprite sprite = new Sprite();
|
||||
sprite.Y = (VRAM[satbase + 1] | (VRAM[satbase + 0] << 8) & 0x3FF) - 128;
|
||||
sprite.X = (VRAM[satbase + 7] | (VRAM[satbase + 6] << 8) & 0x3FF) - 128;
|
||||
sprite.Width = ((VRAM[satbase + 2] >> 2) & 3) + 1;
|
||||
sprite.Height = (VRAM[satbase + 2] & 3) + 1;
|
||||
sprite.Link = VRAM[satbase + 3] & 0x7F;
|
||||
sprite.PatternIndex = VRAM[satbase + 5] | (VRAM[satbase + 6] << 8) & 0x7FF;
|
||||
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.Palette = (VRAM[satbase + 5] >> 5) & 3;
|
||||
return sprite;
|
||||
}
|
||||
|
||||
|
||||
struct Sprite
|
||||
{
|
||||
public int X, Y;
|
||||
public int Width, Height;
|
||||
public int WidthPixels, HeightPixels;
|
||||
public int WidthCells, HeightCells;
|
||||
public int Link;
|
||||
public int Palette;
|
||||
public int PatternIndex;
|
||||
|
|
|
@ -24,23 +24,23 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
public bool CellBasedVertScroll { get { return (Registers[11] & 0x08) != 0; } }
|
||||
public bool Display40Mode { get { return (Registers[12] & 0x81) != 0; } }
|
||||
|
||||
private ushort NameTableAddrA;
|
||||
private ushort NameTableAddrB;
|
||||
private ushort NameTableAddrWindow;
|
||||
private ushort SpriteAttributeTableAddr;
|
||||
private ushort HScrollTableAddr;
|
||||
private byte NameTableWidth;
|
||||
private byte NameTableHeight;
|
||||
ushort NameTableAddrA;
|
||||
ushort NameTableAddrB;
|
||||
ushort NameTableAddrWindow;
|
||||
ushort SpriteAttributeTableAddr;
|
||||
ushort HScrollTableAddr;
|
||||
byte NameTableWidth;
|
||||
byte NameTableHeight;
|
||||
|
||||
private bool ControlWordPending;
|
||||
private ushort VdpDataAddr;
|
||||
private byte VdpDataCode;
|
||||
bool ControlWordPending;
|
||||
ushort VdpDataAddr;
|
||||
byte VdpDataCode;
|
||||
|
||||
private 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 void WriteVdpControl(ushort data)
|
||||
{
|
||||
//Console.WriteLine("[PC = {0:X6}] VDP: Control Write {1:X4}", /*Genesis._MainCPU.PC*/0, data);
|
||||
Log.Note("VDP", "VDP: Control Write {0:X4}", data);
|
||||
|
||||
if (ControlWordPending == false)
|
||||
{
|
||||
|
@ -77,28 +77,28 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
// what type of DMA?
|
||||
switch (Registers[23] >> 6)
|
||||
{
|
||||
case 2:
|
||||
Console.WriteLine("VRAM FILL");
|
||||
case 2:
|
||||
Log.Note("VDP", "VRAM FILL");
|
||||
DmaFillModePending = true;
|
||||
break;
|
||||
case 3:
|
||||
Console.WriteLine("VRAM COPY **** UNIMPLEMENTED ***");
|
||||
case 3:
|
||||
Log.Note("VDP", "VRAM COPY **** UNIMPLEMENTED ***");
|
||||
break;
|
||||
default:
|
||||
Console.WriteLine("68k->VRAM COPY **** UNIMPLEMENTED ***");
|
||||
Log.Note("VDP", "68k->VRAM COPY");
|
||||
Execute68000VramCopy();
|
||||
break;
|
||||
}
|
||||
Console.WriteLine("DMA LEN = "+DmaLength);
|
||||
Log.Note("VDP", "DMA LEN = " + DmaLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ushort ReadVdpControl()
|
||||
{
|
||||
//Console.WriteLine("VDP: Control Read");
|
||||
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);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -144,40 +144,67 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
|
||||
public ushort ReadVdpData()
|
||||
{
|
||||
//Console.WriteLine("VDP: Data Read");
|
||||
Console.WriteLine("VDP: Data Read");
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void WriteVdpRegister(int register, byte data)
|
||||
{
|
||||
//Console.WriteLine("Register {0}: {1:X2}", register, data);
|
||||
Log.Note("VDP", "Register {0}: {1:X2}", register, data);
|
||||
switch (register)
|
||||
{
|
||||
case 0x00:
|
||||
case 0x00: // Mode Set Register 1
|
||||
Registers[register] = data;
|
||||
Console.WriteLine("HINT enabled: "+ HInterruptsEnabled);
|
||||
//Log.Note("VDP", "HINT enabled: " + HInterruptsEnabled);
|
||||
break;
|
||||
case 0x01:
|
||||
|
||||
case 0x01: // Mode Set Register 2
|
||||
Registers[register] = data;
|
||||
Console.WriteLine("DmaEnabled: "+DmaEnabled);
|
||||
Console.WriteLine("VINT enabled: " + VInterruptEnabled);
|
||||
//Log.Note("VDP", "DisplayEnabled: " + DisplayEnabled);
|
||||
//Log.Note("VDP", "DmaEnabled: " + DmaEnabled);
|
||||
//Log.Note("VDP", "VINT enabled: " + VInterruptEnabled);
|
||||
break;
|
||||
|
||||
case 0x02: // Name Table Address for Layer A
|
||||
NameTableAddrA = (ushort) ((data & 0x38) << 10);
|
||||
Console.WriteLine("SET NTa A = {0:X4}",NameTableAddrA);
|
||||
//Log.Note("VDP", "SET NTa A = {0:X4}", NameTableAddrA);
|
||||
break;
|
||||
|
||||
case 0x03: // Name Table Address for Window
|
||||
NameTableAddrWindow = (ushort) ((data & 0x3E) << 10);
|
||||
Console.WriteLine("SET NTa W = {0:X4}", NameTableAddrWindow);
|
||||
//Log.Note("VDP", "SET NTa W = {0:X4}", NameTableAddrWindow);
|
||||
break;
|
||||
|
||||
case 0x04: // Name Table Address for Layer B
|
||||
NameTableAddrB = (ushort) (data << 13);
|
||||
Console.WriteLine("SET NTa B = {0:X4}", NameTableAddrB);
|
||||
//Log.Note("VDP", "SET NTa B = {0:X4}", NameTableAddrB);
|
||||
break;
|
||||
|
||||
case 0x05: // Sprite Attribute Table Address
|
||||
SpriteAttributeTableAddr = (ushort) (data << 9);
|
||||
Console.WriteLine("SET SAT attr = {0:X4}", SpriteAttributeTableAddr);
|
||||
//Log.Note("VDP", "SET SAT attr = {0:X4}", SpriteAttributeTableAddr);
|
||||
break;
|
||||
|
||||
case 0x0A: // H Interrupt Register
|
||||
//Log.Note("VDP", "HInt occurs every {0} lines.", data);
|
||||
break;
|
||||
|
||||
case 0x0B: // VScroll/HScroll modes
|
||||
/*if ((data & 4) != 0)
|
||||
Log.Note("VDP", "VSCroll Every 2 Cells Enabled");
|
||||
else
|
||||
Log.Note("VDP", "Full Screen VScroll");*/
|
||||
|
||||
int hscrollmode = data & 3;
|
||||
switch (hscrollmode)
|
||||
{
|
||||
//case 0: Log.Note("VDP", "Full Screen HScroll"); break;
|
||||
//case 1: Log.Note("VDP", "Prohibited HSCROLL mode!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); break;
|
||||
//case 2: Log.Note("VDP", "HScroll every 1 cell"); break;
|
||||
//case 3: Log.Note("VDP", "HScroll every 2 cell"); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0C: // Mode Set #4
|
||||
// TODO interlaced modes
|
||||
if ((data & 0x81) == 0)
|
||||
|
@ -187,7 +214,7 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
{
|
||||
FrameBuffer = new int[256*224];
|
||||
FrameWidth = 256;
|
||||
Console.WriteLine("SWITCH TO 32 CELL WIDE MODE");
|
||||
//Log.Note("VDP", "SWITCH TO 32 CELL WIDE MODE");
|
||||
}
|
||||
} else {
|
||||
// Display is 40 cells wide
|
||||
|
@ -195,18 +222,21 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
{
|
||||
FrameBuffer = new int[320*224];
|
||||
FrameWidth = 320;
|
||||
Console.WriteLine("SWITCH TO 40 CELL WIDE MODE");
|
||||
//Log.Note("VDP", "SWITCH TO 40 CELL WIDE MODE");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0D: // H Scroll Table Address
|
||||
HScrollTableAddr = (ushort) (data << 10);
|
||||
Console.WriteLine("SET HScrollTab attr = {0:X4}", HScrollTableAddr);
|
||||
//Log.Note("VDP", "SET HScrollTab attr = {0:X4}", HScrollTableAddr);
|
||||
break;
|
||||
case 0x0F:
|
||||
Console.WriteLine("Set Data Increment to "+data);
|
||||
|
||||
case 0x0F: // Auto Address Register Increment
|
||||
//Log.Note("VDP", "Set Data Increment to " + data);
|
||||
break;
|
||||
case 0x10:
|
||||
|
||||
case 0x10: // Nametable Dimensions
|
||||
switch (data & 0x03)
|
||||
{
|
||||
case 0: NameTableWidth = 32; break;
|
||||
|
@ -221,13 +251,49 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
case 2: NameTableHeight = 32; break; // invalid setting
|
||||
case 3: NameTableHeight = 128; break;
|
||||
}
|
||||
Console.WriteLine("Name Table Dimensions set to {0}x{1}", NameTableWidth, NameTableHeight);
|
||||
//Log.Note("VDP", "Name Table Dimensions set to {0}x{1}", NameTableWidth, NameTableHeight);
|
||||
break;
|
||||
|
||||
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");
|
||||
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");
|
||||
break;
|
||||
|
||||
case 0x13: // DMA Length Low
|
||||
Registers[register] = data;
|
||||
//Log.Note("VDP", "DMA Length = {0:X4}", DmaLength);
|
||||
break;
|
||||
|
||||
case 0x14: // DMA Length High
|
||||
Registers[register] = data;
|
||||
//Log.Note("VDP", "DMA Length = {0:X4}", DmaLength);
|
||||
break;
|
||||
|
||||
case 0x15: // DMA Source Low
|
||||
Registers[register] = data;
|
||||
//Log.Note("VDP", "DMA Source = {0:X6}", DmaSource);
|
||||
break;
|
||||
case 0x16: // DMA Source Mid
|
||||
Registers[register] = data;
|
||||
//Log.Note("VDP", "DMA Source = {0:X6}", DmaSource);
|
||||
break;
|
||||
case 0x17: // DMA Source High
|
||||
Registers[register] = data;
|
||||
//Log.Note("VDP", "DMA Source = {0:X6}", DmaSource);
|
||||
break;
|
||||
|
||||
}
|
||||
Registers[register] = data;
|
||||
}
|
||||
|
||||
private void ProcessPalette(int slot)
|
||||
void ProcessPalette(int slot)
|
||||
{
|
||||
byte r = PalXlatTable[(CRAM[slot] & 0x000F) >> 0];
|
||||
byte g = PalXlatTable[(CRAM[slot] & 0x00F0) >> 4];
|
||||
|
@ -235,7 +301,7 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
Palette[slot] = Colors.ARGB(r, g, b);
|
||||
}
|
||||
|
||||
private void UpdatePatternBuffer(int addr)
|
||||
void UpdatePatternBuffer(int addr)
|
||||
{
|
||||
PatternBuffer[(addr*2) + 1] = (byte) (VRAM[addr^1] & 0x0F);
|
||||
PatternBuffer[(addr*2) + 0] = (byte) (VRAM[addr^1] >> 4);
|
||||
|
|
|
@ -82,6 +82,7 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
for (int i = 0; i < rom.Length; i++)
|
||||
RomData[i] = rom[i];
|
||||
|
||||
SetupMemoryDomains();
|
||||
MainCPU.Reset();
|
||||
}
|
||||
|
||||
|
@ -91,7 +92,7 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
PSG.BeginFrame(SoundCPU.TotalExecutedCycles);
|
||||
for (VDP.ScanLine = 0; VDP.ScanLine < 262; VDP.ScanLine++)
|
||||
{
|
||||
Log.Error("VDP","FRAME {0}, SCANLINE {1}", Frame, VDP.ScanLine);
|
||||
//Log.Error("VDP","FRAME {0}, SCANLINE {1}", Frame, VDP.ScanLine);
|
||||
|
||||
if (VDP.ScanLine < 224)
|
||||
VDP.RenderLine();
|
||||
|
@ -179,8 +180,30 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
return new byte[0];
|
||||
}
|
||||
|
||||
public IList<MemoryDomain> MemoryDomains { get { throw new NotImplementedException(); } }
|
||||
public MemoryDomain MainMemory { get { throw new NotImplementedException(); } }
|
||||
IList<MemoryDomain> memoryDomains;
|
||||
|
||||
void SetupMemoryDomains()
|
||||
{
|
||||
var domains = new List<MemoryDomain>(3);
|
||||
var MainMemoryDomain = new MemoryDomain("68000 RAM", Ram.Length, Endian.Big,
|
||||
addr => Ram[addr & 0xFFFF],
|
||||
(addr, value) => Ram[addr & 0xFFFF] = value);
|
||||
var Z80Domain = new MemoryDomain("Z80 RAM", Z80Ram.Length, Endian.Little,
|
||||
addr => Z80Ram[addr & 0x1FFF],
|
||||
(addr, value) => { Z80Ram[addr & 0x1FFF] = value; });
|
||||
|
||||
var VRamDomain = new MemoryDomain("Video RAM", VDP.VRAM.Length, Endian.Big,
|
||||
addr => VDP.VRAM[addr & 0xFFFF],
|
||||
(addr, value) => VDP.VRAM[addr & 0xFFFF] = value);
|
||||
|
||||
domains.Add(MainMemoryDomain);
|
||||
domains.Add(Z80Domain);
|
||||
domains.Add(VRamDomain);
|
||||
memoryDomains = domains.AsReadOnly();
|
||||
}
|
||||
|
||||
public IList<MemoryDomain> MemoryDomains { get { return memoryDomains; } }
|
||||
public MemoryDomain MainMemory { get { return memoryDomains[0]; } }
|
||||
|
||||
public void Dispose() { }
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
|
||||
case 0x04: return IOPorts[0].Control;
|
||||
case 0x05: return IOPorts[1].Control;
|
||||
case 0x06: return 0xFF;// IOPorts[2].Control; TODO hack? returning FF fixes revenge of shinobi and strider. investigate later.
|
||||
case 0x06: return 0xFF;// return IOPorts[2].Control; //TODO hack? returning FF fixes revenge of shinobi and strider. investigate later.
|
||||
|
||||
case 0x07: return IOPorts[0].TxData;
|
||||
case 0x08: return IOPorts[0].RxData;
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
|
||||
if (address == 0xA11100) // Z80 BUS status
|
||||
{
|
||||
Console.WriteLine("QUERY z80 bus status. 68000 can access? " + (M68000HasZ80Bus && Z80Reset == false));
|
||||
//Console.WriteLine("QUERY z80 bus status. 68000 can access? " + (M68000HasZ80Bus && Z80Reset == false));
|
||||
return (sbyte) (M68000HasZ80Bus && Z80Reset == false ? 0 : 1);
|
||||
}
|
||||
|
||||
|
@ -69,13 +69,17 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
int maskedAddr;
|
||||
if (address < 0x400000) // Cartridge ROM
|
||||
return (RomData[address] << 24) | (RomData[address + 1] << 16) | (RomData[address + 2] << 8) | RomData[address + 3];
|
||||
|
||||
|
||||
if (address >= 0xE00000) // Work RAM
|
||||
{
|
||||
maskedAddr = address & 0xFFFF;
|
||||
return (Ram[maskedAddr] << 24) | (Ram[maskedAddr + 1] << 16) | (Ram[maskedAddr + 2] << 8) | Ram[maskedAddr + 3];
|
||||
}
|
||||
|
||||
// try to handle certain things separate if they need to be separate? otherwise handle as 2x readwords?
|
||||
{
|
||||
return ((ushort)ReadWord(address) | (ushort)(ReadWord(address + 2) << 16));
|
||||
}
|
||||
if (address == 0xA10008) return 0; // FIXME HACK for tg-sync.
|
||||
|
||||
Console.WriteLine("UNHANDLED READL {0:X6}", address);
|
||||
|
@ -105,7 +109,7 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
if (address == 0xA11100)
|
||||
{
|
||||
M68000HasZ80Bus = (value & 1) != 0;
|
||||
Console.WriteLine("68000 has the z80 bus: " + M68000HasZ80Bus);
|
||||
//Console.WriteLine("68000 has the z80 bus: " + M68000HasZ80Bus);
|
||||
return;
|
||||
}
|
||||
if (address == 0xA11200) // Z80 RESET
|
||||
|
@ -113,7 +117,7 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
Z80Reset = (value & 1) == 0;
|
||||
if (Z80Reset)
|
||||
SoundCPU.Reset();
|
||||
Console.WriteLine("z80 reset: " + Z80Reset);
|
||||
//Console.WriteLine("z80 reset: " + Z80Reset);
|
||||
return;
|
||||
}
|
||||
if (address >= 0xC00000)
|
||||
|
@ -170,7 +174,7 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
if (address == 0xA11100) // Z80 BUSREQ
|
||||
{
|
||||
M68000HasZ80Bus = (value & 0x100) != 0;
|
||||
Console.WriteLine("68000 has the z80 bus: " + M68000HasZ80Bus);
|
||||
//Console.WriteLine("68000 has the z80 bus: " + M68000HasZ80Bus);
|
||||
return;
|
||||
}
|
||||
if (address == 0xA11200) // Z80 RESET
|
||||
|
@ -178,7 +182,7 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
Z80Reset = (value & 0x100) == 0;
|
||||
if (Z80Reset)
|
||||
SoundCPU.Reset();
|
||||
Console.WriteLine("z80 reset: " + Z80Reset);
|
||||
//Console.WriteLine("z80 reset: " + Z80Reset);
|
||||
return;
|
||||
}
|
||||
Console.WriteLine("UNHANDLED WRITEW {0:X6}:{1:X4}", address, value);
|
||||
|
|
|
@ -16,13 +16,15 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
if (address >= 0x4000 && address < 0x6000)
|
||||
{
|
||||
//Console.WriteLine(" === Z80 READS FM STATUS ===");
|
||||
return YM2612.ReadStatus();
|
||||
return YM2612.ReadStatus(); // TODO: more than 1 read port probably?
|
||||
}
|
||||
if (address >= 0x8000)
|
||||
{
|
||||
// 68000 Bank region
|
||||
return (byte) ReadByte(BankRegion | (address & 0x7FFF));
|
||||
}
|
||||
if (address <= 0x6100) // read from bank address register - returns FF
|
||||
return 0xFF;
|
||||
Console.WriteLine("UNHANDLED Z80 READ {0:X4}",address);
|
||||
return 0xCD;
|
||||
}
|
||||
|
@ -37,18 +39,40 @@ namespace BizHawk.Emulation.Consoles.Sega
|
|||
}
|
||||
if (address >= 0x4000 && address < 0x6000)
|
||||
{
|
||||
//Console.WriteLine(" === Z80 WRITES Z80 {0:X4}:{1:X2} ===",address, value);
|
||||
//Console.WriteLine(" === Z80 WRITES YM2612 {0:X4}:{1:X2} ===",address, value);
|
||||
YM2612.Write(address & 3, value);
|
||||
return;
|
||||
}
|
||||
if (address == 0x6000)
|
||||
if (address < 0x6100)
|
||||
{
|
||||
BankRegion >>= 1;
|
||||
BankRegion |= (value & 1) << 23;
|
||||
BankRegion &= 0x00FF8000;
|
||||
Console.WriteLine("Bank pointing at {0:X8}",BankRegion);
|
||||
//Console.WriteLine("Bank pointing at {0:X8}",BankRegion);
|
||||
return;
|
||||
}
|
||||
if (address >= 0x7F00 && address < 0x7F20)
|
||||
{
|
||||
switch (address & 0x1F)
|
||||
{
|
||||
case 0x00:
|
||||
case 0x02:
|
||||
VDP.WriteVdpData((ushort) ((value<<8) | value));
|
||||
return;
|
||||
|
||||
case 0x04:
|
||||
case 0x06:
|
||||
VDP.WriteVdpControl((ushort)((value << 8) | value));
|
||||
return;
|
||||
|
||||
case 0x11:
|
||||
case 0x13:
|
||||
case 0x15:
|
||||
case 0x17:
|
||||
PSG.WritePsgData(value, SoundCPU.TotalExecutedCycles);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (address >= 0x8000)
|
||||
{
|
||||
WriteByte(BankRegion | (address & 0x7FFF), (sbyte) value);
|
||||
|
|
Loading…
Reference in New Issue