GEN: Preliminary sprite rendering. hook up MemoryDomains.

This commit is contained in:
beirich 2011-10-16 06:23:15 +00:00
parent a95957dcf6
commit f8564bf8a7
7 changed files with 229 additions and 79 deletions

View File

@ -8,6 +8,7 @@ namespace BizHawk.Emulation.Consoles.Sega
public Func<int, short> DmaReadFrom68000; // TODO make ushort public Func<int, short> DmaReadFrom68000; // TODO make ushort
public int DmaLength { get { return Registers[19] | (Registers[20] << 8); } } public int DmaLength { get { return Registers[19] | (Registers[20] << 8); } }
public int DmaMode { get { return (Registers[23] >> 6) & 3; } }
public int DmaSource public int DmaSource
{ {
@ -21,28 +22,26 @@ namespace BizHawk.Emulation.Consoles.Sega
} }
} }
bool DmaFillModePending; bool DmaFillModePending;
void ExecuteDmaFill(ushort data) 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: It should spread this out, not do it all at once.
// TODO: DMA can go to places besides just VRAM (eg CRAM, VSRAM) // TODO: DMA can go to places besides just VRAM (eg CRAM, VSRAM) ??? can it?
// TODO: Does DMA fill really use the actual increment register value? // TODO: what is this genvdp.txt comment about accurate vdp fill emulation writing some other byte first?
int length = DmaLength; int length = DmaLength;
if (length == 0) if (length == 0)
length = 0x10000; // Really necessary? length = 0x10000;
byte fillByte = (byte)(data >> 8); byte fillByte = (byte)(data >> 8);
do do
{ {
VRAM[VdpDataAddr & 0xFFFF] = fillByte; VRAM[VdpDataAddr] = fillByte;
UpdatePatternBuffer(VdpDataAddr & 0xFFFF); UpdatePatternBuffer(VdpDataAddr);
VdpDataAddr += Registers[15]; VdpDataAddr += Registers[15];
} while (--length > 0); } while (--length > 0);
@ -51,7 +50,7 @@ namespace BizHawk.Emulation.Consoles.Sega
void Execute68000VramCopy() 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; int length = DmaLength;
if (length == 0) if (length == 0)

View File

@ -8,15 +8,14 @@ namespace BizHawk.Emulation.Consoles.Sega
{ {
if (ScanLine == 0) if (ScanLine == 0)
{ {
for (int i = 0; i < FrameBuffer.Length; i++) Array.Clear(FrameBuffer, 0, FrameBuffer.Length);
FrameBuffer[i] = 0;
//RenderPatterns(); //RenderPatterns();
RenderPalette(); RenderPalette();
RenderScrollA(); RenderScrollA();
RenderScrollB(); RenderScrollB();
RenderSprites();
} }
RenderSprites();
} }
void RenderPalette() void RenderPalette()
@ -76,33 +75,68 @@ namespace BizHawk.Emulation.Consoles.Sega
} }
} }
static readonly int[] SpriteSizeTable = { 8, 16, 24, 32 };
Sprite sprite;
void RenderSprites() void RenderSprites()
{ {
Sprite sprite = FetchSprite(0); int scanLineBase = ScanLine * FrameWidth;
/*if (sprite.X > 0) int processedSprites = 0;
Console.WriteLine("doot");*/
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); int satbase = SpriteAttributeTableAddr + (spriteNo*8);
Sprite sprite = new Sprite(); sprite.Y = (VRAM[satbase + 0] | (VRAM[satbase + 1] << 8) & 0x3FF) - 128;
sprite.Y = (VRAM[satbase + 1] | (VRAM[satbase + 0] << 8) & 0x3FF) - 128; sprite.X = (VRAM[satbase + 6] | (VRAM[satbase + 7] << 8) & 0x3FF) - 128;
sprite.X = (VRAM[satbase + 7] | (VRAM[satbase + 6] << 8) & 0x3FF) - 128; sprite.WidthPixels = SpriteSizeTable[(VRAM[satbase + 3] >> 2) & 3];
sprite.Width = ((VRAM[satbase + 2] >> 2) & 3) + 1; sprite.HeightPixels = SpriteSizeTable[VRAM[satbase + 3] & 3];
sprite.Height = (VRAM[satbase + 2] & 3) + 1; sprite.WidthCells = ((VRAM[satbase + 3] >> 2) & 3) + 1;
sprite.Link = VRAM[satbase + 3] & 0x7F; sprite.HeightCells = (VRAM[satbase + 3] & 3) + 1;
sprite.PatternIndex = VRAM[satbase + 5] | (VRAM[satbase + 6] << 8) & 0x7FF; sprite.Link = VRAM[satbase + 2] & 0x7F;
sprite.PatternIndex = (VRAM[satbase + 4] | (VRAM[satbase + 5] << 8)) & 0x7FF;
sprite.Palette = (VRAM[satbase + 5] >> 5) & 3; sprite.Palette = (VRAM[satbase + 5] >> 5) & 3;
return sprite;
} }
struct Sprite struct Sprite
{ {
public int X, Y; public int X, Y;
public int Width, Height; public int WidthPixels, HeightPixels;
public int WidthCells, HeightCells;
public int Link; public int Link;
public int Palette; public int Palette;
public int PatternIndex; public int PatternIndex;

View File

@ -24,23 +24,23 @@ namespace BizHawk.Emulation.Consoles.Sega
public bool CellBasedVertScroll { get { return (Registers[11] & 0x08) != 0; } } public bool CellBasedVertScroll { get { return (Registers[11] & 0x08) != 0; } }
public bool Display40Mode { get { return (Registers[12] & 0x81) != 0; } } public bool Display40Mode { get { return (Registers[12] & 0x81) != 0; } }
private ushort NameTableAddrA; ushort NameTableAddrA;
private ushort NameTableAddrB; ushort NameTableAddrB;
private ushort NameTableAddrWindow; ushort NameTableAddrWindow;
private ushort SpriteAttributeTableAddr; ushort SpriteAttributeTableAddr;
private ushort HScrollTableAddr; ushort HScrollTableAddr;
private byte NameTableWidth; byte NameTableWidth;
private byte NameTableHeight; byte NameTableHeight;
private bool ControlWordPending; bool ControlWordPending;
private ushort VdpDataAddr; ushort VdpDataAddr;
private byte VdpDataCode; 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) 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) if (ControlWordPending == false)
{ {
@ -77,28 +77,28 @@ namespace BizHawk.Emulation.Consoles.Sega
// what type of DMA? // what type of DMA?
switch (Registers[23] >> 6) switch (Registers[23] >> 6)
{ {
case 2: case 2:
Console.WriteLine("VRAM FILL"); Log.Note("VDP", "VRAM FILL");
DmaFillModePending = true; DmaFillModePending = true;
break; break;
case 3: case 3:
Console.WriteLine("VRAM COPY **** UNIMPLEMENTED ***"); Log.Note("VDP", "VRAM COPY **** UNIMPLEMENTED ***");
break; break;
default: default:
Console.WriteLine("68k->VRAM COPY **** UNIMPLEMENTED ***"); Log.Note("VDP", "68k->VRAM COPY");
Execute68000VramCopy(); Execute68000VramCopy();
break; break;
} }
Console.WriteLine("DMA LEN = "+DmaLength); Log.Note("VDP", "DMA LEN = " + DmaLength);
} }
} }
} }
public ushort ReadVdpControl() public ushort ReadVdpControl()
{ {
//Console.WriteLine("VDP: Control Read");
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);
return value; return value;
} }
@ -144,40 +144,67 @@ namespace BizHawk.Emulation.Consoles.Sega
public ushort ReadVdpData() public ushort ReadVdpData()
{ {
//Console.WriteLine("VDP: Data Read"); Console.WriteLine("VDP: Data Read");
return 0; return 0;
} }
public void WriteVdpRegister(int register, byte data) 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) switch (register)
{ {
case 0x00: case 0x00: // Mode Set Register 1
Registers[register] = data; Registers[register] = data;
Console.WriteLine("HINT enabled: "+ HInterruptsEnabled); //Log.Note("VDP", "HINT enabled: " + HInterruptsEnabled);
break; break;
case 0x01:
case 0x01: // Mode Set Register 2
Registers[register] = data; Registers[register] = data;
Console.WriteLine("DmaEnabled: "+DmaEnabled); //Log.Note("VDP", "DisplayEnabled: " + DisplayEnabled);
Console.WriteLine("VINT enabled: " + VInterruptEnabled); //Log.Note("VDP", "DmaEnabled: " + DmaEnabled);
//Log.Note("VDP", "VINT enabled: " + VInterruptEnabled);
break; break;
case 0x02: // Name Table Address for Layer A case 0x02: // Name Table Address for Layer A
NameTableAddrA = (ushort) ((data & 0x38) << 10); NameTableAddrA = (ushort) ((data & 0x38) << 10);
Console.WriteLine("SET NTa A = {0:X4}",NameTableAddrA); //Log.Note("VDP", "SET NTa A = {0:X4}", NameTableAddrA);
break; break;
case 0x03: // Name Table Address for Window case 0x03: // Name Table Address for Window
NameTableAddrWindow = (ushort) ((data & 0x3E) << 10); NameTableAddrWindow = (ushort) ((data & 0x3E) << 10);
Console.WriteLine("SET NTa W = {0:X4}", NameTableAddrWindow); //Log.Note("VDP", "SET NTa W = {0:X4}", NameTableAddrWindow);
break; break;
case 0x04: // Name Table Address for Layer B case 0x04: // Name Table Address for Layer B
NameTableAddrB = (ushort) (data << 13); NameTableAddrB = (ushort) (data << 13);
Console.WriteLine("SET NTa B = {0:X4}", NameTableAddrB); //Log.Note("VDP", "SET NTa B = {0:X4}", NameTableAddrB);
break; break;
case 0x05: // Sprite Attribute Table Address case 0x05: // Sprite Attribute Table Address
SpriteAttributeTableAddr = (ushort) (data << 9); SpriteAttributeTableAddr = (ushort) (data << 9);
Console.WriteLine("SET SAT attr = {0:X4}", SpriteAttributeTableAddr); //Log.Note("VDP", "SET SAT attr = {0:X4}", SpriteAttributeTableAddr);
break; 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 case 0x0C: // Mode Set #4
// TODO interlaced modes // TODO interlaced modes
if ((data & 0x81) == 0) if ((data & 0x81) == 0)
@ -187,7 +214,7 @@ namespace BizHawk.Emulation.Consoles.Sega
{ {
FrameBuffer = new int[256*224]; FrameBuffer = new int[256*224];
FrameWidth = 256; FrameWidth = 256;
Console.WriteLine("SWITCH TO 32 CELL WIDE MODE"); //Log.Note("VDP", "SWITCH TO 32 CELL WIDE MODE");
} }
} else { } else {
// Display is 40 cells wide // Display is 40 cells wide
@ -195,18 +222,21 @@ namespace BizHawk.Emulation.Consoles.Sega
{ {
FrameBuffer = new int[320*224]; FrameBuffer = new int[320*224];
FrameWidth = 320; FrameWidth = 320;
Console.WriteLine("SWITCH TO 40 CELL WIDE MODE"); //Log.Note("VDP", "SWITCH TO 40 CELL WIDE MODE");
} }
} }
break; break;
case 0x0D: // H Scroll Table Address case 0x0D: // H Scroll Table Address
HScrollTableAddr = (ushort) (data << 10); HScrollTableAddr = (ushort) (data << 10);
Console.WriteLine("SET HScrollTab attr = {0:X4}", HScrollTableAddr); //Log.Note("VDP", "SET HScrollTab attr = {0:X4}", HScrollTableAddr);
break; 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; break;
case 0x10:
case 0x10: // Nametable Dimensions
switch (data & 0x03) switch (data & 0x03)
{ {
case 0: NameTableWidth = 32; break; case 0: NameTableWidth = 32; break;
@ -221,13 +251,49 @@ namespace BizHawk.Emulation.Consoles.Sega
case 2: NameTableHeight = 32; break; // invalid setting case 2: NameTableHeight = 32; break; // invalid setting
case 3: NameTableHeight = 128; break; 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; 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; Registers[register] = data;
} }
private void ProcessPalette(int slot) void ProcessPalette(int slot)
{ {
byte r = PalXlatTable[(CRAM[slot] & 0x000F) >> 0]; byte r = PalXlatTable[(CRAM[slot] & 0x000F) >> 0];
byte g = PalXlatTable[(CRAM[slot] & 0x00F0) >> 4]; byte g = PalXlatTable[(CRAM[slot] & 0x00F0) >> 4];
@ -235,7 +301,7 @@ namespace BizHawk.Emulation.Consoles.Sega
Palette[slot] = Colors.ARGB(r, g, b); 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) + 1] = (byte) (VRAM[addr^1] & 0x0F);
PatternBuffer[(addr*2) + 0] = (byte) (VRAM[addr^1] >> 4); PatternBuffer[(addr*2) + 0] = (byte) (VRAM[addr^1] >> 4);

View File

@ -82,6 +82,7 @@ namespace BizHawk.Emulation.Consoles.Sega
for (int i = 0; i < rom.Length; i++) for (int i = 0; i < rom.Length; i++)
RomData[i] = rom[i]; RomData[i] = rom[i];
SetupMemoryDomains();
MainCPU.Reset(); MainCPU.Reset();
} }
@ -91,7 +92,7 @@ namespace BizHawk.Emulation.Consoles.Sega
PSG.BeginFrame(SoundCPU.TotalExecutedCycles); PSG.BeginFrame(SoundCPU.TotalExecutedCycles);
for (VDP.ScanLine = 0; VDP.ScanLine < 262; VDP.ScanLine++) 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) if (VDP.ScanLine < 224)
VDP.RenderLine(); VDP.RenderLine();
@ -179,8 +180,30 @@ namespace BizHawk.Emulation.Consoles.Sega
return new byte[0]; return new byte[0];
} }
public IList<MemoryDomain> MemoryDomains { get { throw new NotImplementedException(); } } IList<MemoryDomain> memoryDomains;
public MemoryDomain MainMemory { get { throw new NotImplementedException(); } }
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() { } public void Dispose() { }
} }

View File

@ -54,7 +54,7 @@
case 0x04: return IOPorts[0].Control; case 0x04: return IOPorts[0].Control;
case 0x05: return IOPorts[1].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 0x07: return IOPorts[0].TxData;
case 0x08: return IOPorts[0].RxData; case 0x08: return IOPorts[0].RxData;

View File

@ -16,7 +16,7 @@ namespace BizHawk.Emulation.Consoles.Sega
if (address == 0xA11100) // Z80 BUS status 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); return (sbyte) (M68000HasZ80Bus && Z80Reset == false ? 0 : 1);
} }
@ -69,13 +69,17 @@ namespace BizHawk.Emulation.Consoles.Sega
int maskedAddr; int maskedAddr;
if (address < 0x400000) // Cartridge ROM if (address < 0x400000) // Cartridge ROM
return (RomData[address] << 24) | (RomData[address + 1] << 16) | (RomData[address + 2] << 8) | RomData[address + 3]; return (RomData[address] << 24) | (RomData[address + 1] << 16) | (RomData[address + 2] << 8) | RomData[address + 3];
if (address >= 0xE00000) // Work RAM if (address >= 0xE00000) // Work RAM
{ {
maskedAddr = address & 0xFFFF; maskedAddr = address & 0xFFFF;
return (Ram[maskedAddr] << 24) | (Ram[maskedAddr + 1] << 16) | (Ram[maskedAddr + 2] << 8) | Ram[maskedAddr + 3]; 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. if (address == 0xA10008) return 0; // FIXME HACK for tg-sync.
Console.WriteLine("UNHANDLED READL {0:X6}", address); Console.WriteLine("UNHANDLED READL {0:X6}", address);
@ -105,7 +109,7 @@ namespace BizHawk.Emulation.Consoles.Sega
if (address == 0xA11100) if (address == 0xA11100)
{ {
M68000HasZ80Bus = (value & 1) != 0; M68000HasZ80Bus = (value & 1) != 0;
Console.WriteLine("68000 has the z80 bus: " + M68000HasZ80Bus); //Console.WriteLine("68000 has the z80 bus: " + M68000HasZ80Bus);
return; return;
} }
if (address == 0xA11200) // Z80 RESET if (address == 0xA11200) // Z80 RESET
@ -113,7 +117,7 @@ namespace BizHawk.Emulation.Consoles.Sega
Z80Reset = (value & 1) == 0; Z80Reset = (value & 1) == 0;
if (Z80Reset) if (Z80Reset)
SoundCPU.Reset(); SoundCPU.Reset();
Console.WriteLine("z80 reset: " + Z80Reset); //Console.WriteLine("z80 reset: " + Z80Reset);
return; return;
} }
if (address >= 0xC00000) if (address >= 0xC00000)
@ -170,7 +174,7 @@ namespace BizHawk.Emulation.Consoles.Sega
if (address == 0xA11100) // Z80 BUSREQ if (address == 0xA11100) // Z80 BUSREQ
{ {
M68000HasZ80Bus = (value & 0x100) != 0; M68000HasZ80Bus = (value & 0x100) != 0;
Console.WriteLine("68000 has the z80 bus: " + M68000HasZ80Bus); //Console.WriteLine("68000 has the z80 bus: " + M68000HasZ80Bus);
return; return;
} }
if (address == 0xA11200) // Z80 RESET if (address == 0xA11200) // Z80 RESET
@ -178,7 +182,7 @@ namespace BizHawk.Emulation.Consoles.Sega
Z80Reset = (value & 0x100) == 0; Z80Reset = (value & 0x100) == 0;
if (Z80Reset) if (Z80Reset)
SoundCPU.Reset(); SoundCPU.Reset();
Console.WriteLine("z80 reset: " + Z80Reset); //Console.WriteLine("z80 reset: " + Z80Reset);
return; return;
} }
Console.WriteLine("UNHANDLED WRITEW {0:X6}:{1:X4}", address, value); Console.WriteLine("UNHANDLED WRITEW {0:X6}:{1:X4}", address, value);

View File

@ -16,13 +16,15 @@ namespace BizHawk.Emulation.Consoles.Sega
if (address >= 0x4000 && address < 0x6000) if (address >= 0x4000 && address < 0x6000)
{ {
//Console.WriteLine(" === Z80 READS FM STATUS ==="); //Console.WriteLine(" === Z80 READS FM STATUS ===");
return YM2612.ReadStatus(); return YM2612.ReadStatus(); // TODO: more than 1 read port probably?
} }
if (address >= 0x8000) if (address >= 0x8000)
{ {
// 68000 Bank region // 68000 Bank region
return (byte) ReadByte(BankRegion | (address & 0x7FFF)); 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); Console.WriteLine("UNHANDLED Z80 READ {0:X4}",address);
return 0xCD; return 0xCD;
} }
@ -37,18 +39,40 @@ namespace BizHawk.Emulation.Consoles.Sega
} }
if (address >= 0x4000 && address < 0x6000) 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); YM2612.Write(address & 3, value);
return; return;
} }
if (address == 0x6000) if (address < 0x6100)
{ {
BankRegion >>= 1; BankRegion >>= 1;
BankRegion |= (value & 1) << 23; BankRegion |= (value & 1) << 23;
BankRegion &= 0x00FF8000; BankRegion &= 0x00FF8000;
Console.WriteLine("Bank pointing at {0:X8}",BankRegion); //Console.WriteLine("Bank pointing at {0:X8}",BankRegion);
return; 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) if (address >= 0x8000)
{ {
WriteByte(BankRegion | (address & 0x7FFF), (sbyte) value); WriteByte(BankRegion | (address & 0x7FFF), (sbyte) value);