diff --git a/BizHawk.Client.EmuHawk/config/ControllerConfig.cs b/BizHawk.Client.EmuHawk/config/ControllerConfig.cs
index 288d748b57..59e07f8119 100644
--- a/BizHawk.Client.EmuHawk/config/ControllerConfig.cs
+++ b/BizHawk.Client.EmuHawk/config/ControllerConfig.cs
@@ -28,7 +28,6 @@ namespace BizHawk.Client.EmuHawk
ControllerImages.Add("Dual Gameboy Controller", Properties.Resources.GBController);
ControllerImages.Add("SMS Controller", Properties.Resources.SMSController);
- ControllerImages.Add("Genesis 3-Button Controller", Properties.Resources.GENController);
ControllerImages.Add("GPGX Genesis Controller", Properties.Resources.GENController);
ControllerImages.Add("Saturn Controller", Properties.Resources.SaturnController);
diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
index f40253760d..ffd41c1f4d 100644
--- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
+++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
@@ -512,28 +512,28 @@
- MGBAHawk.cs
+ MGBAHawk.cs
- MGBAHawk.cs
+ MGBAHawk.cs
- MGBAHawk.cs
+ MGBAHawk.cs
- MGBAHawk.cs
+ MGBAHawk.cs
- MGBAHawk.cs
+ MGBAHawk.cs
- MGBAHawk.cs
+ MGBAHawk.cs
- MGBAHawk.cs
+ MGBAHawk.cs
- MGBAHawk.cs
+ MGBAHawk.cs
@@ -1001,12 +1001,6 @@
-
-
-
-
-
-
GPGX.cs
@@ -1259,12 +1253,6 @@
-
-
-
-
-
-
@@ -1282,7 +1270,6 @@
-
diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/Cart/EEPROM.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/Cart/EEPROM.cs
deleted file mode 100644
index 96d1e3f118..0000000000
--- a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/Cart/EEPROM.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-using System;
-using System.Globalization;
-
-using BizHawk.Emulation.Common;
-
-namespace BizHawk.Emulation.Cores.Sega.Genesis
-{
- partial class Genesis
- {
- // State
- bool EepromEnabled;
-
- int EepromSize;
- int EepromAddrMask;
- int SdaInAddr, SdaInBit;
- int SdaOutAddr, SdaOutBit;
- int SclAddr, SclBit;
-
- int SdaInCurrValue, SclCurrValue;
-
- // Code
-
- void InitializeEeprom(GameInfo game)
- {
- if (game["EEPROM"] == false)
- return;
-
- EepromEnabled = true;
- EepromAddrMask = game.GetHexValue("EEPROM_ADDR_MASK");
- EepromSize = EepromAddrMask + 1;
-
- var t = game.OptionValue("SDA_IN").Split(':');
- SdaInAddr = int.Parse(t[0], NumberStyles.HexNumber);
- SdaInBit = int.Parse(t[1]);
-
- t = game.OptionValue("SDA_OUT").Split(':');
- SdaOutAddr = int.Parse(t[0], NumberStyles.HexNumber);
- SdaOutBit = int.Parse(t[1]);
-
- t = game.OptionValue("SCL").Split(':');
- SclAddr = int.Parse(t[0], NumberStyles.HexNumber);
- SclBit = int.Parse(t[1]);
-
- SaveRAM = new byte[EepromSize];
-
- Console.WriteLine("EEPROM enabled. Size: ${0:X} SDA_IN: ${1:X}:{2} SDA_OUT: ${3:X}:{4}, SCL: ${5:X}:{6}",
- EepromSize, SdaInAddr, SdaInBit, SdaOutAddr, SdaOutBit, SclAddr, SclBit);
- }
-
- void WriteByteEeprom(int address, byte value)
- {
- if (address == SdaInAddr)
- {
- SdaInCurrValue = (value >> SdaInBit) & 1;
- Console.WriteLine("SDA_IN: {0}", SdaInCurrValue);
- }
- if (address == SclAddr)
- {
- SclCurrValue = (value >> SclBit) & 1;
- Console.WriteLine("SCL: {0}", SclCurrValue);
- }
-
- // todo: logic!
-
- }
- }
-}
diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/Cart/RomHeader.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/Cart/RomHeader.cs
deleted file mode 100644
index cf3652cefa..0000000000
--- a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/Cart/RomHeader.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-using System;
-using System.Text;
-
-namespace BizHawk.Emulation.Cores.Sega.Genesis
-{
- partial class Genesis
- {
- public string RH_Console { get { return GetRomString(0x100, 0x10); } }
- public string RH_Copyright { get { return GetRomString(0x110, 0x10); } }
- public string RH_NameDomestic { get { return GetRomString(0x120, 0x30); } }
- public string RH_NameExport { get { return GetRomString(0x150, 0x30); } }
- public int RH_RomSize { get { return GetRomLongWord(0x1A4); } }
- public string RH_Region { get { return GetRomString(0x1F0, 3); } }
-
- public bool RH_SRamPresent { get { return (RomData[0x1B2] & 0x40) != 0; } }
- public int RH_SRamCode { get { return (RomData[0x1B2] >> 3) & 3; } }
- public int RH_SRamStart { get { return GetRomLongWord(0x1B4); } }
- public int RH_SRamEnd { get { return GetRomLongWord(0x1B8); } }
-
- public string RH_SRamInterpretation()
- {
- switch (RH_SRamCode)
- {
- case 0: return "Even and odd addresses";
- case 2: return "Even addresses";
- case 3: return "Odd addresses";
- default: return "Invalid type";
- }
- }
-
- string GetRomString(int offset, int len)
- {
- return Encoding.ASCII.GetString(RomData, offset, len).Trim();
- }
-
- int GetRomLongWord(int offset)
- {
- return (RomData[offset] << 24) | (RomData[offset + 1] << 16) | (RomData[offset + 2] << 8) | RomData[offset + 3];
- }
-
- void LogCartInfo()
- {
- Console.WriteLine("==================");
- Console.WriteLine("ROM Cartridge Data");
- Console.WriteLine("==================");
- Console.WriteLine("System: {0}", RH_Console);
- Console.WriteLine("Copyright: {0}", RH_Copyright);
- Console.WriteLine("Name (Dom): {0}", RH_NameDomestic);
- Console.WriteLine("Name (Exp): {0}", RH_NameExport);
- Console.WriteLine("Region: {0}", RH_Region);
- Console.WriteLine("Rom Size: {0,7} (${0:X})", RH_RomSize);
- Console.WriteLine("SRAM Used: {0}", RH_SRamPresent);
- if (RH_SRamPresent)
- {
- Console.WriteLine("SRAM Start: {0,7} (${0:X})", RH_SRamStart);
- Console.WriteLine("SRAM End: {0,7} (${0:X})", RH_SRamEnd);
- Console.WriteLine("SRAM Type: {0}", RH_SRamInterpretation());
- }
- }
- }
-}
diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/Cart/SaveRAM.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/Cart/SaveRAM.cs
deleted file mode 100644
index d1947fb9a4..0000000000
--- a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/Cart/SaveRAM.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using System;
-using BizHawk.Emulation.Common;
-
-namespace BizHawk.Emulation.Cores.Sega.Genesis
-{
- partial class Genesis
- {
- bool SaveRamEnabled;
- bool SaveRamEveryOtherByte;
- int SaveRamStartOffset;
- int SaveRamEndOffset;
- int SaveRamLength;
-
- byte[] SaveRAM = new byte[0];
-
- void InitializeSaveRam(GameInfo game)
- {
- if (EepromEnabled)
- return;
-
- if (game["DisableSaveRam"] || RH_SRamPresent == false)
- return;
-
- SaveRamEnabled = true;
- SaveRamEveryOtherByte = RH_SRamCode != 0;
- SaveRamStartOffset = RH_SRamStart;
- SaveRamEndOffset = RH_SRamEnd;
-
- if (game["SaveRamStartOffset"])
- SaveRamStartOffset = game.GetHexValue("SaveRamStartOffset");
- if (game["SaveRamEndOffset"])
- SaveRamEndOffset = game.GetHexValue("SaveRamEndOffset");
-
- SaveRamLength = (SaveRamEndOffset - SaveRamStartOffset) + 1;
-
- if (SaveRamEveryOtherByte)
- SaveRamLength = ((SaveRamEndOffset - SaveRamStartOffset) / 2) + 1;
-
- SaveRAM = new byte[SaveRamLength];
-
- Console.WriteLine("SaveRAM enabled. Start: ${0:X6} End: ${1:X6} Length: ${2:X} Mode: {3}", SaveRamStartOffset, SaveRamEndOffset, SaveRamLength, RH_SRamInterpretation());
- }
-
- public byte[] CloneSaveRam() { return (byte[])SaveRAM.Clone(); }
- public void StoreSaveRam(byte[] data) { Array.Copy(data, SaveRAM, data.Length); }
-
- public bool SaveRamModified { get; private set; }
- }
-}
diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/Compat.txt b/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/Compat.txt
deleted file mode 100644
index 64889f2059..0000000000
--- a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/Compat.txt
+++ /dev/null
@@ -1,156 +0,0 @@
-68000:
-
-Timings:
-
- - MULU/MULS/DIVU/DIVS have funky timings.
- - How many cycles does TRAP take to execute?
- - How many cycles does it take to accept an interrupt?
- - AND has some funky timings when it comes to immediates?
-
-GAMES:
-
-Ahhh! Real monsters - no sound
-Adventures of Mighty Max - crashes memory mapper
-Air Diver - suffer from lack of 2cell vscroll
-Alien Storm.... gfx glitches. control glitches?
-Altered Beast: start with 0 health, 0 lives???
-Another World .. broken.. (E) tho
-Arcus Odyssey does UNHANDLED Z80 READs... is this a problem?
-Awesome Possum - controls are wrong
-Batman - flicker and music is messed
-Batman Forever - significant gfx issues
-Battle Squadron - crashes memory mapper woo!
-Blood Shot - FPS game - some texture corruption
-Bonkers - substantial gfx corruption
-Buck Rogers crashes in a fun way
-Burning Force - some gfx issues. works way better than it has in the past though!
-Cheese Cat-astrophe - crashes renderer!!
-Chester Cheetah - freezes when starting new game
-Chuck Rock - Music messed up
-Contra Hard Corps: Scrolling is messed up in level 1... used to work.
-Dashin' Desperados .. bottom screen messed up
-Death Duel crashes my renderer... (!)
-Decap Attack - Item select screen messed up
-Double Dragon doesn't boot
-Devilish/Bad Omen - intro messed up.... interesting debug target
-Dune... freezes in intro
-Exile - Immediate gfx issues... Debug target.
-F1 World Championship... Gfx issue at bottom of screen... quite cool working game though!
-Fatal Rewind - appears to do a read.w on FFFFFF... that would be an address error. read.l messes up too. Ergo: basically doesnt work.
-Final Blow - Music messed up
-Fire Shark - Messed up sound
-Flavio's Raster FX Test.. doesnt work
-Foreman for Real doent boot
-Galaxy Force II - gfx issue in level select screen, and in level-end "shoot the core" part
-Gargoyles... gameplay is nonfunctional
-Gauntlet 4 .. title screen messed. gfx corruption. immediately - debug target.
-Golden Axe - controls are jacked up
-Golden Axe 3 intro.... weirder than before for sure
-Grind Stormer
-Herzog Zwei .. doesnt boot fully
-Insector X .. title screen gfx issue
-James Pond 3 crash in intro
-Jim Power - gfx glitches
-Jurassic Park 2 - crashes in intro
-Lemmings: Sound is royally effed... gfx glitches.
-Marvel Land .. holy shit thats psychadelic
-Mega Turrican some gfx glitches
-Mortal Kombat...
-MUSHA: Intro music starts too soon. Suffers from lack of 2-cell-vertical-scroll mode.
-Out of This World... pretty substantially broken
-Outrun 2019, much more significant gfx issues.
-Outrun, minor gfx issue. maybe related to h-int timing?
-Outrunners, some gfx issues... but not as bad as you might think!!! apparently doesnt use interlace mode?
-Panorama Cotton still not working right
-Power Monger messed up
-RamboIII - intro gfx corrupted - MAYBE GOOD DEBUGGING TARGET
-Shining in the Darkness: Check out sprites in the tavern... very odd
-Sonic 2: Aside from lack of interlace mode, the shadows in the special stage are white....?
-Sonic 2: Something still amiss with title screen sprite masking
-Sonic 3 serious gfx glitches
-Star Control - Shit gets crazy
-Steel Empire - controls messed up. probably gfx issues also.
-Sub-Terrania some gfx issues in intro
-Super Hang-On - Sprite priority/masking isnt happening the way its supposed to on the tracks.
-Super Fantasy Zone: Sound totally boned, missing graphics
-TaleSpin - gfx glitches
-The Humans
-The Immortal
-Truxton - Sound is jaaaacked.
-Verytex - gfx issues
-Zero Tolerance - gfx bugs that didnt used to happen :(
-Zombies At My Neighbors: doesnt boot really
-Zoop doesnt boot
-
-
-======================================================
-Fixed Issues: (listed for regression testing purposes)
-======================================================
-
-(Sprites X/Y are 10-bit, but must be masked to 9-bit)
-- Dragon's Revenge.... ball sprite seems missing? of all the sprites to not show up...
-- Fire Shark - Sprites dont render... VERY similar to Truxton. Same engine?
-- Truxton - Sprites do not appear to be rendering.
-- Zero Wing - Sprites arent rendering.......
-
-Flavio's DMA test... DMAs when it shouldnt!! - Masking off too much of the VDP command code
-
-Fun-n-Games fails its fadeouts. -- Fixed CRAM reads. I failed math.
-
-Sonic Spinball executes a VSRAM read -- Implemented VSRAM reads.
-
-Bugs related to longword read/write VRAM. Multiple bugs were present including sign-extension and endians and crap.
- - Crusader of Centy- Text boxes messed up
- - Eternal Champions - immediate gfx corruption
- - Garfield... immediate gfx corruption. debug target.
- - Kid Chameleon - gfx corruption on bounce bricks and level-end effect
-
-Games to test window calculation on:
- - Road Blasters (doesnt use window, but Window & Nametable A are at same location)
- - Out of this World - Same as Road Blasters
- - Musha,Gaiares - Window at top
- - Eliminate Down - Window at bottom
- - Monster World 4, Wonder Boy in Monster World - Window at top - needs window scroll plane size adjustment
- - D&D Warriors of the Eternal Sun - Window at bottom and at sides
- - Truxton, Fire Shark - Window on Right
-
-======================================================
-
-TODO: non-instant DMA emulation
-TODO: Add 68000/VDP interrupt enable delay (one instruction, similar to After Burner/PCE)
-TODO: H-Ints timing possibly not correct... Some game raster effects work, others don't work as expected. (could be HVC tho)
-TODO: Test DMA/ VDP command words.... I'm not at all convinced that VRAM is always correct
-
-
-==============
-Notable games:
-==============
-
-Ghouls n Ghosts sets up the graphics planes backwards from normal, by setting the plane A to be low priority and Plane B to be high priority.
-If you have a bug in your priority code this may find it.
-
-Revenge of Shinobi will not play DAC sounds if YM2612 registers are not initialized to L/R channels enabled.
-
-Ballz doesnt really initialize hardly any VDP registers, relies on VDP registers powered-on to the correct values
-
-Contra appears to use VDP A0 set = byte-swap. Not sure if its important in anyway in that game, but the byte swap happens.
-
-Games that use VRAM->VRAM Copy: D&D Warriors of the Eternal Sun, MUSHA, Devilish, Viewpoint
-
-Games that require accurate VRAM fill emulation include Thunder Force IV,
- Contra Hard Corps, Revenge of Shinobi, Taiga Drama, and Sword of Vermillion.
-
-Sonic Spinball reads from VSRAM
-
-Games to test for sprite masking/overflow:
- - Sonic 1 title screen (uses overflow to mask)
- - Sonic 2 title screen (uses sprite mask modes)
- - Galaxy Force 2 level select (uses sprite mask)
- - Landstalker sprite masking (chests and such)
- - Nemesis test rom
-
-Games known to use 2-cell vertical scroll mode:
- - Air Diver
- - Exo Squad
- - Contra Hard Corps (giant robot boss on stage 1)
- - MUSHA (stage 3)
diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/GenVDP.DMA.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/GenVDP.DMA.cs
deleted file mode 100644
index 71ecf22dd1..0000000000
--- a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/GenVDP.DMA.cs
+++ /dev/null
@@ -1,112 +0,0 @@
-using System;
-using BizHawk.Common;
-
-namespace BizHawk.Emulation.Cores.Sega.Genesis
-{
- public partial class GenVDP
- {
- // TODO: make this a requirement of constructor?
- public Func 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
- {
- get
- {
- if ((Registers[23] & 0x80) == 0) // 68000 -> VRAM copy mode
- return ((Registers[21] << 1) | (Registers[22] << 9) | (Registers[23] << 17)) & 0xFFFFFE;
-
- // Else VRAM/VRAM copy mode
- return (Registers[21] | (Registers[22] << 8)) & 0xFFFFFE;
- }
- }
-
- bool DmaFillModePending;
-
- void ExecuteVramFill(ushort data)
- {
- if (data != 0)
- Console.WriteLine("fill word is not zero {0:X4}", data);
-
- Log.Note("VDP", "DMA FILL REQD, WRITE {0:X4}, {1:X4} times, at {2:X4}", data, DmaLength, VdpDataAddr);
-
- // TODO: It should spread this out, not do it all at once.
-
- int length = DmaLength;
- if (length == 0)
- length = 0x10000;
-
- byte fillByte = (byte)(data >> 8);
-
- do
- {
- VRAM[VdpDataAddr] = fillByte;
- Log.Note("VDP", "VRAM DMA FILL Write: [{0:X4}] = {1:X2}", VdpDataAddr, fillByte);
- UpdatePatternBuffer(VdpDataAddr);
- VdpDataAddr += Registers[15];
- } while (--length > 0);
-
- // TOOD: test if the length register updated? One would assume so...
- Registers[19] = 0;
- Registers[20] = 0;
-
- // TODO: Source registers should be incremented also (even for Fill)
-
- DmaFillModePending = false;
- }
-
- void Execute68000VramCopy()
- {
- Log.Note("VDP", "DMA 68000 -> VRAM COPY REQ'D. LENGTH {0:X4}, SOURCE {1:X4}", DmaLength, DmaSource);
-
- int length = DmaLength;
- if (length == 0)
- length = 0x10000;
-
- int source = DmaSource;
-
- do
- {
- ushort value = (ushort)DmaReadFrom68000(source);
- source += 2;
- // TODO funky source behavior
- WriteVdpData(value);
- } while (--length > 0);
-
- Registers[19] = 0;
- Registers[20] = 0;
-
- // TODO: update DMA source registers.
- // TODO: find correct number of 68k cycles to burn
- }
-
- void ExecuteVramVramCopy()
- {
- Log.Note("VDP", "DMA VRAM -> VRAM COPY REQ'D. LENGTH {0:X4}, SOURCE {1:X4}", DmaLength, DmaSource);
-
- int length = DmaLength;
- if (length == 0)
- length = 0x10000;
-
- int source = DmaSource;
-
- do
- {
- byte data = VRAM[source];
- VRAM[VdpDataAddr] = data;
- UpdatePatternBuffer(VdpDataAddr);
- Log.Note("VDP", "VRAM/VRAM Copy VRAM[{0:X4}] = {1:X2}", VdpDataAddr, data);
- source = (source + 1) & 0xFFFF;
- VdpDataAddr += Registers[0xF];
- } while (--length > 0);
-
- Registers[19] = 0;
- Registers[20] = 0;
-
- // TODO: length, source registers should be updated....
- // TODO: find correct number of 68k cycles to burn
- }
- }
-}
\ No newline at end of file
diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/GenVDP.Render.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/GenVDP.Render.cs
deleted file mode 100644
index 8474935ef4..0000000000
--- a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/GenVDP.Render.cs
+++ /dev/null
@@ -1,525 +0,0 @@
-using System;
-
-namespace BizHawk.Emulation.Cores.Sega.Genesis
-{
- public partial class GenVDP
- {
- // Priority buffer contents have the following values:
- // 0 = Backdrop color
- // 1 = Plane B Low Priority
- // 2 = Plane A Low Priority
- // 4 = Plane B High Priority
- // 5 = Plane A High Priority
- // 9 = Sprite has been drawn
-
- byte[] PriorityBuffer = new byte[320];
-
- static readonly byte[] PalXlatTable = { 0, 0, 36, 36, 73, 73, 109, 109, 145, 145, 182, 182, 219, 219, 255, 255 };
-
- public void RenderLine()
- {
- if (DisplayEnabled)
- {
- Array.Clear(PriorityBuffer, 0, 320);
-
- // TODO: I would like to be able to render Scroll A before Scroll B, in order to minimize overdraw.
- // But at the moment it complicates priority stuff.
-
- if (CellBasedVertScroll == false)
- {
- RenderScrollB();
- RenderScrollA();
- }
- else
- {
- RenderScrollBTwoCellVScroll();
- RenderScrollATwoCellVScroll();
- }
-
- RenderSpritesScanline();
- }
- else
- {
- // If display is disabled, fill in with background color.
- for (int i = 0; i < FrameWidth; i++)
- FrameBuffer[(ScanLine * FrameWidth) + i] = BackgroundColor;
- }
-
- //if (ScanLine == 223) // shrug
- // RenderPalette();
- }
-
- void RenderPalette()
- {
- for (int p = 0; p < 4; p++)
- for (int i = 0; i < 16; i++)
- FrameBuffer[(p * FrameWidth) + i] = Palette[(p * 16) + i];
- }
-
- void RenderScrollAScanline(int xScroll, int yScroll, int nameTableBase, int startPixel, int endPixel, bool window)
- {
- const int lowPriority = 2;
- const int highPriority = 5;
- int yTile = ((ScanLine + yScroll) / 8) % NameTableHeight;
- int nameTableWidth = NameTableWidth;
- if (window)
- nameTableWidth = (DisplayWidth == 40) ? 64 : 32;
-
- // this is hellllla slow. but not optimizing until we implement & understand
- // all scrolling modes, shadow & hilight, etc.
- // in thinking about this, you could convince me to optimize the PCE background renderer now.
- // Its way simple in comparison. But the PCE sprite renderer is way worse than gen.
- for (int x = startPixel; x < endPixel; x++)
- {
- int xTile = Math.Abs(((x + (1024 - xScroll)) / 8) % nameTableWidth);
- int xOfs = Math.Abs((x + (1024 - xScroll)) & 7);
- int yOfs = (ScanLine + yScroll) % 8;
- int cellOfs = nameTableBase + (yTile * nameTableWidth * 2) + (xTile * 2);
- int nameTableEntry = VRAM[cellOfs] | (VRAM[cellOfs + 1] << 8);
- int patternNo = nameTableEntry & 0x7FF;
- bool hFlip = ((nameTableEntry >> 11) & 1) != 0;
- bool vFlip = ((nameTableEntry >> 12) & 1) != 0;
- bool priority = ((nameTableEntry >> 15) & 1) != 0;
- int palette = (nameTableEntry >> 13) & 3;
-
- if (priority && PriorityBuffer[x] >= highPriority) continue;
- if (!priority && PriorityBuffer[x] >= lowPriority) continue;
-
- if (vFlip) yOfs = 7 - yOfs;
- if (hFlip) xOfs = 7 - xOfs;
-
- int texel = PatternBuffer[(patternNo * 64) + (yOfs * 8) + (xOfs)];
- if (texel == 0) continue;
- int pixel = Palette[(palette * 16) + texel];
- FrameBuffer[(ScanLine * FrameWidth) + x] = pixel;
- PriorityBuffer[x] = (byte)(priority ? highPriority : lowPriority);
- }
- }
-
- void RenderScrollAScanlineTwoCellVScroll(int xScroll, int nameTableBase, int startPixel, int endPixel, bool window)
- {
- const int lowPriority = 2;
- const int highPriority = 5;
-
- int fineHScroll = xScroll & 15;
- int nameTableWidth = NameTableWidth;
- if (window)
- nameTableWidth = (DisplayWidth == 40) ? 64 : 32;
-
- for (int x = startPixel; x < endPixel; x++)
- {
- int vsramUnitOffset = ((x - fineHScroll) / 16) % 40;
- int yScroll = VSRAM[vsramUnitOffset * 2] & 0x3FF;
- int yTile = ((ScanLine + yScroll) / 8) % NameTableHeight;
-
- int xTile = Math.Abs(((x + (1024 - xScroll)) / 8) % nameTableWidth);
- int xOfs = Math.Abs((x + (1024 - xScroll)) & 7);
- int yOfs = (ScanLine + yScroll) % 8;
- int cellOfs = nameTableBase + (yTile * nameTableWidth * 2) + (xTile * 2);
- int nameTableEntry = VRAM[cellOfs] | (VRAM[cellOfs + 1] << 8);
- int patternNo = nameTableEntry & 0x7FF;
- bool hFlip = ((nameTableEntry >> 11) & 1) != 0;
- bool vFlip = ((nameTableEntry >> 12) & 1) != 0;
- bool priority = ((nameTableEntry >> 15) & 1) != 0;
- int palette = (nameTableEntry >> 13) & 3;
-
- if (priority && PriorityBuffer[x] >= highPriority) continue;
- if (!priority && PriorityBuffer[x] >= lowPriority) continue;
-
- if (vFlip) yOfs = 7 - yOfs;
- if (hFlip) xOfs = 7 - xOfs;
-
- int texel = PatternBuffer[(patternNo * 64) + (yOfs * 8) + (xOfs)];
- if (texel == 0) continue;
- int pixel = Palette[(palette * 16) + texel];
- FrameBuffer[(ScanLine * FrameWidth) + x] = pixel;
- PriorityBuffer[x] = (byte)(priority ? highPriority : lowPriority);
- }
- }
-
- void CalculateWindowScanlines(out int startScanline, out int endScanline)
- {
- int data = Registers[0x12];
- int windowVPosition = data & 31;
- bool fromTop = (data & 0x80) == 0;
-
- if (windowVPosition == 0)
- {
- startScanline = -1;
- endScanline = -1;
- return;
- }
-
- if (fromTop)
- {
- startScanline = 0;
- endScanline = (windowVPosition * 8);
- }
- else
- {
- startScanline = windowVPosition * 8;
- endScanline = FrameHeight;
- }
- }
-
- void CalculateWindowPosition(out int startPixel, out int endPixel)
- {
- int data = Registers[0x11];
- int windowHPosition = (data & 31) * 2; // Window H position is set in 2-cell increments
- bool fromLeft = (data & 0x80) == 0;
-
- if (windowHPosition == 0)
- {
- startPixel = -1;
- endPixel = -1;
- return;
- }
-
- if (fromLeft)
- {
- startPixel = 0;
- endPixel = (windowHPosition * 8);
- if (endPixel > FrameWidth)
- endPixel = FrameWidth;
- }
- else
- {
- startPixel = windowHPosition * 8;
- endPixel = FrameWidth;
- if (startPixel > FrameWidth)
- {
- startPixel = -1;
- endPixel = -1;
- }
- }
- }
-
- void RenderScrollA()
- {
- // Calculate scroll offsets
-
- int hscroll = CalcHScrollPlaneA(ScanLine);
- int vscroll = VSRAM[0] & 0x3FF;
-
- // Calculate window dimensions
-
- int startWindowScanline, endWindowScanline;
- int startWindowPixel, endWindowPixel;
- CalculateWindowScanlines(out startWindowScanline, out endWindowScanline);
- CalculateWindowPosition(out startWindowPixel, out endWindowPixel);
-
- // Render scanline
-
- if (ScanLine >= startWindowScanline && ScanLine < endWindowScanline) // Window takes up whole scanline
- {
- RenderScrollAScanline(0, 0, NameTableAddrWindow, 0, FrameWidth, true);
- }
- else if (startWindowPixel != -1) // Window takes up partial scanline
- {
- if (startWindowPixel == 0) // Window grows from left side
- {
- RenderScrollAScanline(0, 0, NameTableAddrWindow, 0, endWindowPixel, true);
- RenderScrollAScanline(hscroll, vscroll, NameTableAddrA, endWindowPixel, FrameWidth, false);
- }
- else // Window grows from right side
- {
- RenderScrollAScanline(hscroll, vscroll, NameTableAddrA, 0, startWindowPixel, false);
- RenderScrollAScanline(0, 0, NameTableAddrWindow, startWindowPixel, FrameWidth, true);
- }
- }
- else // No window this scanline
- {
- RenderScrollAScanline(hscroll, vscroll, NameTableAddrA, 0, FrameWidth, false);
- }
- }
-
- void RenderScrollATwoCellVScroll()
- {
- // Calculate scroll offsets
-
- int hscroll = CalcHScrollPlaneA(ScanLine);
-
- // Calculate window dimensions
-
- int startWindowScanline, endWindowScanline;
- int startWindowPixel, endWindowPixel;
- CalculateWindowScanlines(out startWindowScanline, out endWindowScanline);
- CalculateWindowPosition(out startWindowPixel, out endWindowPixel);
-
- // Render scanline
-
- if (ScanLine >= startWindowScanline && ScanLine < endWindowScanline) // Window takes up whole scanline
- {
- RenderScrollAScanline(0, 0, NameTableAddrWindow, 0, FrameWidth, true);
- }
- else if (startWindowPixel != -1) // Window takes up partial scanline
- {
- if (startWindowPixel == 0) // Window grows from left side
- {
- RenderScrollAScanline(0, 0, NameTableAddrWindow, 0, endWindowPixel, true);
- RenderScrollAScanlineTwoCellVScroll(hscroll, NameTableAddrA, endWindowPixel, FrameWidth, false);
- }
- else // Window grows from right side
- {
- RenderScrollAScanlineTwoCellVScroll(hscroll, NameTableAddrA, 0, startWindowPixel, false);
- RenderScrollAScanline(0, 0, NameTableAddrWindow, startWindowPixel, FrameWidth, true);
- }
- }
- else // No window this scanline
- {
- RenderScrollAScanlineTwoCellVScroll(hscroll, NameTableAddrA, 0, FrameWidth, false);
- }
- }
-
- void RenderScrollB()
- {
- int bgColor = BackgroundColor;
- int xScroll = CalcHScrollPlaneB(ScanLine);
- int yScroll = VSRAM[1] & 0x3FF;
-
- const int lowPriority = 1;
- const int highPriority = 4;
-
- int yTile = ((ScanLine + yScroll) / 8) % NameTableHeight;
-
- // this is hellllla slow. but not optimizing until we implement & understand
- // all scrolling modes, shadow & hilight, etc.
- // in thinking about this, you could convince me to optimize the PCE background renderer now.
- // Its way simple in comparison. But the PCE sprite renderer is way worse than gen.
- for (int x = 0; x < FrameWidth; x++)
- {
- int xTile = Math.Abs(((x + (1024 - xScroll)) / 8) % NameTableWidth);
- int xOfs = Math.Abs((x + (1024 - xScroll)) & 7);
- int yOfs = (ScanLine + yScroll) % 8;
- int cellOfs = NameTableAddrB + (yTile * NameTableWidth * 2) + (xTile * 2);
- int nameTableEntry = VRAM[cellOfs] | (VRAM[cellOfs + 1] << 8);
- int patternNo = nameTableEntry & 0x7FF;
- bool hFlip = ((nameTableEntry >> 11) & 1) != 0;
- bool vFlip = ((nameTableEntry >> 12) & 1) != 0;
- bool priority = ((nameTableEntry >> 15) & 1) != 0;
- int palette = (nameTableEntry >> 13) & 3;
-
- if (priority && PriorityBuffer[x] >= highPriority) continue;
- if (!priority && PriorityBuffer[x] >= lowPriority) continue;
-
- if (vFlip) yOfs = 7 - yOfs;
- if (hFlip) xOfs = 7 - xOfs;
-
- int texel = PatternBuffer[(patternNo * 64) + (yOfs * 8) + (xOfs)];
- int pixel = Palette[(palette * 16) + texel];
- if (texel != 0)
- {
- FrameBuffer[(ScanLine * FrameWidth) + x] = pixel;
- PriorityBuffer[x] = (byte)(priority ? highPriority : lowPriority);
- }
- else
- {
- FrameBuffer[(ScanLine * FrameWidth) + x] = bgColor;
- }
- }
- }
-
- void RenderScrollBTwoCellVScroll()
- {
- int bgColor = BackgroundColor;
- int xScroll = CalcHScrollPlaneB(ScanLine);
- int fineHScroll = xScroll & 15;
-
- const int lowPriority = 1;
- const int highPriority = 4;
-
- for (int x = 0; x < FrameWidth; x++)
- {
- int vsramUnitOffset = ((x - fineHScroll) / 16) % 40;
- int yScroll = VSRAM[(vsramUnitOffset * 2) + 1] & 0x3FF;
- int yTile = ((ScanLine + yScroll) / 8) % NameTableHeight;
-
- int xTile = Math.Abs(((x + (1024 - xScroll)) / 8) % NameTableWidth);
- int xOfs = Math.Abs((x + (1024 - xScroll)) & 7);
- int yOfs = (ScanLine + yScroll) % 8;
- int cellOfs = NameTableAddrB + (yTile * NameTableWidth * 2) + (xTile * 2);
- int nameTableEntry = VRAM[cellOfs] | (VRAM[cellOfs + 1] << 8);
- int patternNo = nameTableEntry & 0x7FF;
- bool hFlip = ((nameTableEntry >> 11) & 1) != 0;
- bool vFlip = ((nameTableEntry >> 12) & 1) != 0;
- bool priority = ((nameTableEntry >> 15) & 1) != 0;
- int palette = (nameTableEntry >> 13) & 3;
-
- if (priority && PriorityBuffer[x] >= highPriority) continue;
- if (!priority && PriorityBuffer[x] >= lowPriority) continue;
-
- if (vFlip) yOfs = 7 - yOfs;
- if (hFlip) xOfs = 7 - xOfs;
-
- int texel = PatternBuffer[(patternNo * 64) + (yOfs * 8) + (xOfs)];
- int pixel = Palette[(palette * 16) + texel];
- if (texel != 0)
- {
- FrameBuffer[(ScanLine * FrameWidth) + x] = pixel;
- PriorityBuffer[x] = (byte)(priority ? highPriority : lowPriority);
- }
- else
- {
- FrameBuffer[(ScanLine * FrameWidth) + x] = bgColor;
- }
- }
- }
-
- static readonly int[] SpriteSizeTable = { 8, 16, 24, 32 };
- Sprite sprite;
-
- void RenderSpritesScanline()
- {
- int scanLineBase = ScanLine * FrameWidth;
- int processedSprites = 0;
- int processedSpritesThisLine = 0;
- int processedDotsThisLine = 0;
- bool spriteMaskPrecursor = false;
-
- // This is incredibly unoptimized. TODO...
-
- FetchSprite(0);
- while (true)
- {
- if (sprite.Y > ScanLine || sprite.Y + sprite.HeightPixels <= ScanLine)
- goto nextSprite;
-
- processedSpritesThisLine++;
- processedDotsThisLine += sprite.WidthPixels;
-
- if (sprite.X > -128)
- spriteMaskPrecursor = true;
-
- if (sprite.X == -128 && spriteMaskPrecursor)
- break; // apply sprite mask
-
- if (sprite.X + sprite.WidthPixels <= 0)
- goto nextSprite;
-
- if (sprite.HeightCells == 2)
- sprite.HeightCells = 2;
-
- int yline = ScanLine - sprite.Y;
- if (sprite.VFlip)
- yline = sprite.HeightPixels - 1 - yline;
- int paletteBase = sprite.Palette * 16;
- if (sprite.HFlip == false)
- {
- int pattern = sprite.PatternIndex + ((yline / 8));
-
- for (int xi = 0; xi < sprite.WidthPixels; xi++)
- {
- if (sprite.X + xi < 0 || sprite.X + xi >= FrameWidth)
- continue;
-
- if (sprite.Priority == false && PriorityBuffer[sprite.X + xi] >= 3) continue;
- if (PriorityBuffer[sprite.X + xi] == 9) 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];
- PriorityBuffer[sprite.X + xi] = 9;
- }
- }
- }
- else
- { // HFlip
- int pattern = sprite.PatternIndex + ((yline / 8)) + (sprite.HeightCells * (sprite.WidthCells - 1));
-
- for (int xi = 0; xi < sprite.WidthPixels; xi++)
- {
- if (sprite.X + xi < 0 || sprite.X + xi >= FrameWidth)
- continue;
-
- if (sprite.Priority == false && PriorityBuffer[sprite.X + xi] >= 3) continue;
- if (PriorityBuffer[sprite.X + xi] == 9) continue;
-
- int pixel = PatternBuffer[((pattern + ((-xi / 8) * sprite.HeightCells)) * 64) + ((yline & 7) * 8) + (7 - (xi & 7))];
- if (pixel != 0)
- {
- FrameBuffer[scanLineBase + sprite.X + xi] = Palette[paletteBase + pixel];
- PriorityBuffer[sprite.X + xi] = 9;
- }
- }
- }
-
- nextSprite:
- if (sprite.Link == 0)
- break;
- if (++processedSprites >= SpriteLimit)
- break;
- if (processedSpritesThisLine >= SpritePerLineLimit)
- break;
- if (processedDotsThisLine >= DotsPerLineLimit)
- break;
- if (DisplayWidth == 32 && sprite.Link >= 64)
- break;
- FetchSprite(sprite.Link);
- }
- }
-
- void FetchSprite(int spriteNo)
- {
- // Note - X/Y coordinates are 10-bits (3FF) but must be masked to 9-bits (1FF)
- // In interlace mode this behavior should change
-
- int SatBase = SpriteAttributeTableAddr + (spriteNo * 8);
- sprite.Y = (VRAM[SatBase + 0] | (VRAM[SatBase + 1] << 8) & 0x1FF) - 128;
- sprite.X = (VRAM[SatBase + 6] | (VRAM[SatBase + 7] << 8) & 0x1FF) - 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
- {
- public int X, Y;
- public int WidthPixels, HeightPixels;
- public int WidthCells, HeightCells;
- public int Link;
- public int Palette;
- public int PatternIndex;
- public bool Priority;
- public bool HFlip;
- public bool VFlip;
- }
-
- int CalcHScrollPlaneA(int line)
- {
- int ofs = 0;
- switch (Registers[11] & 3)
- {
- case 0: ofs = HScrollTableAddr; break;
- case 1: ofs = HScrollTableAddr + ((line & 7) * 4); break;
- case 2: ofs = HScrollTableAddr + ((line & ~7) * 4); break;
- case 3: ofs = HScrollTableAddr + (line * 4); break;
- }
-
- int value = VRAM[ofs] | (VRAM[ofs + 1] << 8);
- return value & 0x3FF;
- }
-
- int CalcHScrollPlaneB(int line)
- {
- int ofs = 0;
- switch (Registers[11] & 3)
- {
- case 0: ofs = HScrollTableAddr; break;
- case 1: ofs = HScrollTableAddr + ((line & 7) * 4); break;
- case 2: ofs = HScrollTableAddr + ((line & ~7) * 4); break;
- case 3: ofs = HScrollTableAddr + (line * 4); break;
- }
-
- int value = VRAM[ofs + 2] | (VRAM[ofs + 3] << 8);
- return value & 0x3FF;
- }
- }
-}
\ No newline at end of file
diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/GenVDP.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/GenVDP.cs
deleted file mode 100644
index bfe751b6ea..0000000000
--- a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/GenVDP.cs
+++ /dev/null
@@ -1,572 +0,0 @@
-using System;
-using System.IO;
-using System.Globalization;
-
-using BizHawk.Common;
-using BizHawk.Common.BufferExtensions;
-using BizHawk.Common.IOExtensions;
-using BizHawk.Emulation.Common;
-
-namespace BizHawk.Emulation.Cores.Sega.Genesis
-{
- public sealed partial class GenVDP : IVideoProvider
- {
- // Memory
- public byte[] VRAM = new byte[0x10000];
- public ushort[] CRAM = new ushort[64];
- public ushort[] VSRAM = new ushort[40];
- public byte[] Registers = new byte[0x20];
-
- public byte[] PatternBuffer = new byte[0x20000];
- public int[] Palette = new int[64];
- public int[] FrameBuffer = new int[320 * 224];
- public int FrameWidth = 320;
- public int FrameHeight = 224;
-
- public int ScanLine;
- public int HIntLineCounter;
-
- public bool HInterruptsEnabled { get { return (Registers[0] & 0x10) != 0; } }
- public bool DisplayEnabled { get { return (Registers[1] & 0x40) != 0; } }
- public bool VInterruptEnabled { get { return (Registers[1] & 0x20) != 0; } }
- public bool DmaEnabled { get { return (Registers[1] & 0x10) != 0; } }
- public bool CellBasedVertScroll { get { return (Registers[11] & 0x04) != 0; } }
-
- public bool InDisplayPeriod { get { return ScanLine < 224 && DisplayEnabled; } }
-
- ushort NameTableAddrA;
- ushort NameTableAddrB;
- ushort NameTableAddrWindow;
- ushort SpriteAttributeTableAddr;
- ushort HScrollTableAddr;
- int NameTableWidth = 32;
- int NameTableHeight = 32;
-
- int DisplayWidth;
- int SpriteLimit;
- int SpritePerLineLimit;
- int DotsPerLineLimit;
-
- bool ControlWordPending;
- 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 = 8;
-
- public ushort VdpStatusWord = 0x3400;
- public const int StatusHorizBlanking = 0x04;
- public const int StatusVerticalBlanking = 0x08;
- public const int StatusOddFrame = 0x10;
- public const int StatusSpriteCollision = 0x20;
- public const int StatusSpriteOverflow = 0x40;
- public const int StatusVerticalInterruptPending = 0x80;
-
- public bool VdpDebug = false;
-
- public Func GetPC;
-
- public GenVDP()
- {
- WriteVdpRegister(00, 0x04);
- WriteVdpRegister(01, 0x04);
- WriteVdpRegister(02, 0x30);
- WriteVdpRegister(03, 0x3C);
- WriteVdpRegister(04, 0x07);
- WriteVdpRegister(05, 0x67);
- WriteVdpRegister(10, 0xFF);
- WriteVdpRegister(12, 0x81);
- WriteVdpRegister(15, 0x02);
- Log.Note("VDP", "VDP init routine complete");
- }
-
- public ushort ReadVdp(int addr)
- {
- switch (addr)
- {
- case 0:
- case 2:
- return ReadVdpData();
- case 4:
- case 6:
- return ReadVdpControl();
- default:
- return ReadHVCounter();
- }
- }
-
- 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", "Control Write {0:X4} (PC={1:X6})", data, GetPC());
-
- if (ControlWordPending == false)
- {
- if ((data & 0xC000) == 0x8000)
- {
- int reg = (data >> 8) & 0x1F;
- byte value = (byte)(data & 0xFF);
- WriteVdpRegister(reg, value);
- VdpDataCode = 0;
- }
- else
- {
- ControlWordPending = true;
- VdpDataAddr &= 0xC000;
- VdpDataAddr |= (ushort)(data & 0x3FFF);
- VdpDataCode &= 0x3C;
- VdpDataCode |= (byte)(data >> 14);
- //Console.WriteLine("Address = {0:X4}", VdpDataAddr);
- //Console.WriteLine("Code = {0:X2}", VdpDataCode);
- }
- }
- else
- {
- ControlWordPending = false;
-
- // Update data address and code
- VdpDataAddr &= 0x3FFF;
- VdpDataAddr |= (ushort)((data & 0x03) << 14);
- //Console.WriteLine("Address = {0:X4}", VdpDataAddr);
- VdpDataCode &= 0x03;
- VdpDataCode |= (byte)((data >> 2) & 0x3C);
- //Log.Note("VDP", "Code = {0:X2}", VdpDataCode);
-
- if ((VdpDataCode & 0x20) != 0 && DmaEnabled) // DMA triggered
- {
- //Console.WriteLine("DMA TIME!");
-
- // what type of DMA?
- switch (Registers[23] >> 6)
- {
- case 2:
- Log.Note("VDP", "VRAM FILL");
- DmaFillModePending = true;
- break;
- case 3:
- Log.Error("VDP", "VRAM COPY *");
- ExecuteVramVramCopy();
- break;
- default:
- Execute68000VramCopy();
- break;
- }
- }
- }
- }
-
- public ushort ReadVdpControl()
- {
- VdpStatusWord |= 0x0200; // Fifo empty // TODO kill this, emulating the damn FIFO.
- ControlWordPending = false; // Hmm.. if this happens in an interrupt between 1st and 2nd word..
-
- // sprite overflow flag should clear.
- // sprite collision flag should clear.
-
- return VdpStatusWord;
- }
-
- public void WriteVdpData(ushort data)
- {
- Log.Note("VDP", "Data port write: {0:X4} (PC={1:X6})", data, GetPC());
- ControlWordPending = false;
-
- // byte-swap incoming data when A0 is set
- if ((VdpDataAddr & 1) != 0)
- {
- data = (ushort)((data >> 8) | (data << 8));
- Log.Error("VDP", "VRAM byte-swap is happening because A0 is not 0. [{0:X4}] = {1:X4}", VdpDataAddr, data);
- }
-
- switch (VdpDataCode & 0xF)
- {
- case CommandVramWrite: // VRAM Write
- VRAM[VdpDataAddr & 0xFFFE] = (byte)data;
- VRAM[(VdpDataAddr & 0xFFFE) + 1] = (byte)(data >> 8);
- //if (VdpDebug)
- Log.Note("VDP", "VRAM[{0:X4}] = {1:X4}", VdpDataAddr, data);
- UpdatePatternBuffer(VdpDataAddr & 0xFFFE);
- UpdatePatternBuffer((VdpDataAddr & 0xFFFE) + 1);
- VdpDataAddr += Registers[0x0F];
- break;
- case CommandCramWrite: // CRAM write
- CRAM[(VdpDataAddr / 2) % 64] = data;
- //if (VdpDebug)
- Log.Note("VDP", "CRAM[{0:X2}] = {1:X4}", (VdpDataAddr / 2) % 64, data);
- ProcessPalette((VdpDataAddr / 2) % 64);
- VdpDataAddr += Registers[0x0F];
- break;
- case CommandVsramWrite: // VSRAM write
- VSRAM[(VdpDataAddr / 2) % 40] = data;
- //if (VdpDebug)
- Log.Note("VDP", "VSRAM[{0:X2}] = {1:X4}", (VdpDataAddr / 2) % 40, data);
- VdpDataAddr += Registers[0x0F];
- break;
- default:
- Log.Error("VPD", "VDP DATA WRITE WITH UNHANDLED CODE!!! {0}", VdpDataCode & 7);
- break;
- }
-
- if (DmaFillModePending)
- {
- ExecuteVramFill(data);
- }
- }
-
- public ushort ReadVdpData()
- {
- int orig_addr = VdpDataAddr;
- ushort retval = 0xBEEF;
- switch (VdpDataCode & 0x0F)
- {
- case CommandVramRead:
- //if ((VdpDataAddr & 1) != 0) throw new Exception("VRAM read is not word-aligned. what do?");
- retval = VRAM[VdpDataAddr & 0xFFFE];
- retval |= (ushort)(VRAM[(VdpDataAddr & 0xFFFE) + 1] << 8);
- VdpDataAddr += Registers[0x0F];
- break;
- case CommandVsramRead:
- retval = VSRAM[(VdpDataAddr / 2) % 40];
- VdpDataAddr += Registers[0x0F];
- return retval;
- case CommandCramRead:
- retval = CRAM[(VdpDataAddr / 2) % 64];
- VdpDataAddr += Registers[0x0F];
- return retval;
- default:
- throw new Exception("VRAM read with unexpected code!!! " + (VdpDataCode & 0x0F));
- }
-
- Log.Note("VDP", "VDP Data Read from {0:X4} returning {1:X4}", orig_addr, retval);
- return retval;
- }
-
- ushort ReadHVCounter()
- {
- int vcounter = ScanLine;
- if (vcounter > 0xEA)
- vcounter -= 7;
- // TODO generalize this across multiple video modes and stuff.
-
- // TODO dont tie this to musashi cycle count.
- // Figure out a "clean" way to get cycle counter information available to VDP.
- // Oh screw that. The VDP and the cpu cycle counters are going to be intertwined pretty tightly.
- int hcounter = (488 - Native68000.Musashi.GetCyclesRemaining()) * 255 / 488;
- // FIXME: totally utterly wrong.
-
- ushort res = (ushort)((vcounter << 8) | (hcounter & 0xFF));
- //Console.WriteLine("READ HVC: V={0:X2} H={1:X2} ret={2:X4}", vcounter, hcounter, res);
-
- return res;
- }
-
- public void WriteVdpRegister(int register, byte data)
- {
- //if (VdpDebug)
- Log.Note("VDP", "Register {0}: {1:X2}", register, data);
- switch (register)
- {
- case 0x00: // Mode Set Register 1
- Registers[register] = data;
- //if (VdpDebug)
- //Log.Note("VDP", "HINT enabled: " + HInterruptsEnabled);
- break;
-
- case 0x01: // Mode Set Register 2
- //if (VdpDebug)
- //{
- // Registers[register] = data;
- // 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);
- //if (VdpDebug)
- //Log.Note("VDP", "SET NTa A = {0:X4}", NameTableAddrA);
- break;
-
- case 0x03: // Name Table Address for Window
- NameTableAddrWindow = (ushort)((data & 0x3E) << 10);
- //if (VdpDebug)
- //Log.Note("VDP", "SET NTa W = {0:X4}", NameTableAddrWindow);
- break;
-
- case 0x04: // Name Table Address for Layer B
- NameTableAddrB = (ushort)(data << 13);
- //if (VdpDebug)
- //Log.Note("VDP", "SET NTa B = {0:X4}", NameTableAddrB);
- break;
-
- case 0x05: // Sprite Attribute Table Address
- SpriteAttributeTableAddr = (ushort)(data << 9);
- //if (VdpDebug)
- //Log.Note("VDP", "SET SAT attr = {0:X4}", SpriteAttributeTableAddr);
- break;
-
- case 0x0A: // H Interrupt Register
- //if (VdpDebug)
- //Log.Note("VDP", "HInt occurs every {0} lines.", data);
- break;
-
- case 0x0B: // VScroll/HScroll modes
- //if (VdpDebug)
- //{
- // 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!!! But it'll work."); break;
- // case 2: Log.Note("VDP", "HScroll every 1 cell"); break;
- // case 3: Log.Note("VDP", "HScroll every line"); break;
- // }
- //}
- break;
-
- case 0x0C: // Mode Set #4
- // TODO interlaced modes
- if ((data & 0x81) == 0)
- {
- // Display is 32 cells wide
- if (DisplayWidth != 32)
- {
- FrameBuffer = new int[256 * 224];
- FrameWidth = 256;
- DisplayWidth = 32;
- SpriteLimit = 64;
- SpritePerLineLimit = 16;
- DotsPerLineLimit = 256;
- }
- }
- else
- {
- // Display is 40 cells wide
- if (DisplayWidth != 40)
- {
- FrameBuffer = new int[320 * 224];
- FrameWidth = 320;
- DisplayWidth = 40;
- SpriteLimit = 80;
- SpritePerLineLimit = 20;
- DotsPerLineLimit = 320;
- }
- }
- break;
-
- case 0x0D: // H Scroll Table Address
- HScrollTableAddr = (ushort)(data << 10);
- //if (VdpDebug)
- //Log.Note("VDP", "SET HScrollTab attr = {0:X4}", HScrollTableAddr);
- break;
-
- case 0x0F: // Auto Address Register Increment
- //if (VdpDebug)
- //Log.Note("VDP", "Set Data Increment to " + data);
- break;
-
- case 0x10: // Nametable Dimensions
- switch (data & 0x03)
- {
- case 0: NameTableWidth = 32; break;
- case 1: NameTableWidth = 64; break;
- case 2: NameTableWidth = 32; break; // invalid setting
- case 3: NameTableWidth = 128; break;
- }
- switch ((data >> 4) & 0x03)
- {
- case 0: NameTableHeight = 32; break;
- case 1: NameTableHeight = 64; break;
- case 2: NameTableHeight = 32; break; // invalid setting
- case 3: NameTableHeight = 128; break;
- }
- break;
-
- case 0x11: // Window H Position
- int whp = data & 31;
- bool fromright = (data & 0x80) != 0;
- //if (VdpDebug)
- //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;
- //if (VdpDebug)
- //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;
- }
-
- void ProcessPalette(int slot)
- {
- byte r = PalXlatTable[(CRAM[slot] & 0x000F) >> 0];
- byte g = PalXlatTable[(CRAM[slot] & 0x00F0) >> 4];
- byte b = PalXlatTable[(CRAM[slot] & 0x0F00) >> 8];
- Palette[slot] = Colors.ARGB(r, g, b);
- }
-
- void UpdatePatternBuffer(int addr)
- {
- PatternBuffer[(addr * 2) + 1] = (byte)(VRAM[addr ^ 1] & 0x0F);
- PatternBuffer[(addr * 2) + 0] = (byte)(VRAM[addr ^ 1] >> 4);
- }
-
- public int[] GetVideoBuffer()
- {
- return FrameBuffer;
- }
-
- public int VirtualWidth { get { return 320; } }
- public int VirtualHeight { get { return FrameHeight; } }
-
- public int BufferWidth
- {
- get { return FrameWidth; }
- }
-
- public int BufferHeight
- {
- get { return FrameHeight; }
- }
-
- public int BackgroundColor
- {
- get { return Palette[Registers[7] & 0x3F]; }
- }
-
- #region State Save/Load Code
-
- public void SaveStateText(TextWriter writer)
- {
- writer.WriteLine("[VDP]");
-
- writer.Write("VRAM ");
- VRAM.SaveAsHex(writer);
- writer.Write("CRAM ");
- CRAM.SaveAsHex(writer);
- writer.Write("VSRAM ");
- VSRAM.SaveAsHex(writer);
- writer.Write("Registers ");
- Registers.SaveAsHex(writer);
-
- writer.WriteLine("ControlWordPending {0}", ControlWordPending);
- writer.WriteLine("DmaFillModePending {0}", DmaFillModePending);
- writer.WriteLine("VdpDataAddr {0:X4}", VdpDataAddr);
- writer.WriteLine("VdpDataCode {0}", VdpDataCode);
-
- writer.WriteLine("[/VDP]");
- }
-
- public void LoadStateText(TextReader reader)
- {
- while (true)
- {
- string[] args = reader.ReadLine().Split(' ');
- if (args[0].Trim() == "") continue;
- if (args[0] == "[/VDP]") break;
- else if (args[0] == "VRAM") VRAM.ReadFromHex(args[1]);
- else if (args[0] == "CRAM") CRAM.ReadFromHex(args[1]);
- else if (args[0] == "VSRAM") VSRAM.ReadFromHex(args[1]);
- else if (args[0] == "Registers") Registers.ReadFromHex(args[1]);
- else if (args[0] == "ControlWordPending") ControlWordPending = bool.Parse(args[1]);
- else if (args[0] == "DmaFillModePending") DmaFillModePending = bool.Parse(args[1]);
- else if (args[0] == "VdpDataAddr") VdpDataAddr = ushort.Parse(args[1], NumberStyles.HexNumber);
- else if (args[0] == "VdpDataCode") VdpDataCode = byte.Parse(args[1]);
- else
- Console.WriteLine("Skipping unrecognized identifier " + args[0]);
- }
-
- for (int i = 0; i < CRAM.Length; i++)
- ProcessPalette(i);
- for (int i = 0; i < VRAM.Length; i++)
- UpdatePatternBuffer(i);
- for (int i = 0; i < Registers.Length; i++)
- WriteVdpRegister(i, Registers[i]);
- }
-
- public void SaveStateBinary(BinaryWriter writer)
- {
- writer.Write(VRAM);
- writer.Write(CRAM);
- writer.Write(VSRAM);
- writer.Write(Registers);
-
- writer.Write(ControlWordPending);
- writer.Write(DmaFillModePending);
- writer.Write(VdpDataAddr);
- writer.Write(VdpDataCode);
- }
-
- public void LoadStateBinary(BinaryReader reader)
- {
- VRAM = reader.ReadBytes(VRAM.Length);
- CRAM = reader.ReadUInt16s(CRAM.Length);
- VSRAM = reader.ReadUInt16s(VSRAM.Length);
- Registers = reader.ReadBytes(Registers.Length);
-
- ControlWordPending = reader.ReadBoolean();
- DmaFillModePending = reader.ReadBoolean();
- VdpDataAddr = reader.ReadUInt16();
- VdpDataCode = reader.ReadByte();
-
- for (int i = 0; i < CRAM.Length; i++)
- ProcessPalette(i);
- for (int i = 0; i < VRAM.Length; i++)
- UpdatePatternBuffer(i);
- for (int i = 0; i < Registers.Length; i++)
- WriteVdpRegister(i, Registers[i]);
- }
-
- #endregion
- }
-}
\ No newline at end of file
diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/Genesis.IO.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/Genesis.IO.cs
deleted file mode 100644
index e8233e54b3..0000000000
--- a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/Genesis.IO.cs
+++ /dev/null
@@ -1,132 +0,0 @@
-using BizHawk.Common;
-
-namespace BizHawk.Emulation.Cores.Sega.Genesis
-{
- partial class Genesis
- {
- bool SegaCD = false;
-
- class IOPort
- {
- public byte Data;
- public byte Control;
- public byte TxData;
- public byte RxData;
- public byte SCtrl;
- // TODO- a reference to connected device? That gets into the issue of configuring different types of controllers. :|
-
- public bool TH { get { return (Data & 0x40) != 0; } }
- }
-
- IOPort[] IOPorts = new IOPort[]
- {
- new IOPort { Data = 0x7F, TxData = 0xFF, RxData = 0xFF, SCtrl = 0xFF },
- new IOPort { Data = 0x7F, TxData = 0xFF, RxData = 0xFF, SCtrl = 0xFF },
- new IOPort { Data = 0x7F, TxData = 0xFF, RxData = 0xFF, SCtrl = 0xFF }
- };
-
- byte ReadIO(int offset)
- {
- offset >>= 1;
- offset &= 0x0F;
- if (offset > 1)
- Log.Note("CPU", "^^^ IO Read {0}: 00", offset);
- switch (offset)
- {
- case 0: // version
- byte value = (byte)(SegaCD ? 0x00 : 0x20);
- switch ((char)RomData[0x01F0])
- {
- case 'J': value |= 0x00; break;
- case 'U': value |= 0x80; break;
- case 'E': value |= 0xC0; break;
- case 'A': value |= 0xC0; break;
- case '4': value |= 0x80; break;
- default: value |= 0x80; break;
- }
- //value |= 1; // US
- Log.Note("CPU", "^^^ IO Read 0: {0:X2}", value);
- return value;
- case 1: // Port A
- lagged = false;
- ReadController(ref IOPorts[0].Data);
- Log.Note("CPU", "^^^ IO Read 1: {0:X2}", IOPorts[0].Data);
- return IOPorts[0].Data;
- case 2: return 0xFF;
- case 3: return 0xFF;
-
- case 0x04: return IOPorts[0].Control;
- case 0x05: return IOPorts[1].Control;
- case 0x06: return IOPorts[2].Control;
-
- case 0x07: return IOPorts[0].TxData;
- case 0x08: return IOPorts[0].RxData;
- case 0x09: return IOPorts[0].SCtrl;
-
- case 0x0A: return IOPorts[1].TxData;
- case 0x0B: return IOPorts[1].RxData;
- case 0x0C: return IOPorts[1].SCtrl;
-
- case 0x0D: return IOPorts[2].TxData;
- case 0x0E: return IOPorts[2].RxData;
- case 0x0F: return IOPorts[2].SCtrl;
- }
- Log.Note("CPU", "^^^ IO Read {0}: {1:X2}", offset, 0xFF);
- return 0xFF;
- }
-
- void WriteIO(int offset, int value)
- {
- offset >>= 1;
- offset &= 0x0F;
-
- switch (offset)
- {
- case 0x00: break;
-
- case 0x01: IOPorts[0].Data = (byte)value; break;
- case 0x02: IOPorts[1].Data = (byte)value; break;
- case 0x03: IOPorts[2].Data = (byte)value; break;
-
- case 0x04: IOPorts[0].Control = (byte)value; break;
- case 0x05: IOPorts[1].Control = (byte)value; break;
- case 0x06: IOPorts[2].Control = (byte)value; break;
-
- case 0x07: IOPorts[0].TxData = (byte)value; break;
- case 0x08: IOPorts[0].RxData = (byte)value; break;
- case 0x09: IOPorts[0].SCtrl = (byte)value; break;
-
- case 0x0A: IOPorts[1].TxData = (byte)value; break;
- case 0x0B: IOPorts[1].RxData = (byte)value; break;
- case 0x0C: IOPorts[1].SCtrl = (byte)value; break;
-
- case 0x0D: IOPorts[2].TxData = (byte)value; break;
- case 0x0E: IOPorts[2].RxData = (byte)value; break;
- case 0x0F: IOPorts[2].SCtrl = (byte)value; break;
- }
- }
-
- void ReadController(ref byte data)
- {
- InputCallbacks.Call();
- data &= 0xC0;
- if ((data & 0x40) != 0) // TH high
- {
- if (Controller.IsPressed("P1 Up") == false) data |= 0x01;
- if (Controller.IsPressed("P1 Down") == false) data |= 0x02;
- if (Controller.IsPressed("P1 Left") == false) data |= 0x04;
- if (Controller.IsPressed("P1 Right") == false) data |= 0x08;
- if (Controller.IsPressed("P1 B") == false) data |= 0x10;
- if (Controller.IsPressed("P1 C") == false) data |= 0x20;
- }
- else
- { // TH low
- if (Controller.IsPressed("P1 Up") == false) data |= 0x01;
- if (Controller.IsPressed("P1 Down") == false) data |= 0x02;
- if (Controller.IsPressed("P1 A") == false) data |= 0x10;
- if (Controller.IsPressed("P1 Start") == false) data |= 0x20;
- }
-
- }
- }
-}
\ No newline at end of file
diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/Genesis.Input.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/Genesis.Input.cs
deleted file mode 100644
index 890679d39e..0000000000
--- a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/Genesis.Input.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using BizHawk.Emulation.Common;
-
-namespace BizHawk.Emulation.Cores.Sega.Genesis
-{
- partial class Genesis
- {
- public static readonly ControllerDefinition GenesisController = new ControllerDefinition
- {
- Name = "Genesis 3-Button Controller",
- BoolButtons =
- {
- "Reset",
- "P1 Up", "P1 Down", "P1 Left", "P1 Right", "P1 A", "P1 B", "P1 C", "P1 Start"
- }
- };
-
- public ControllerDefinition ControllerDefinition { get { return GenesisController; } }
- public IController Controller { private get; set; }
- }
-}
\ No newline at end of file
diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/Genesis.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/Genesis.cs
deleted file mode 100644
index f20a97b41c..0000000000
--- a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/Genesis.cs
+++ /dev/null
@@ -1,495 +0,0 @@
-#define MUSASHI
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Runtime.InteropServices;
-
-using BizHawk.Common.BufferExtensions;
-
-using BizHawk.Emulation.Common;
-using BizHawk.Emulation.Common.Components;
-using BizHawk.Emulation.Cores.Components;
-using BizHawk.Emulation.Cores.Components.M68000;
-using BizHawk.Emulation.Cores.Components.Z80;
-using Native68000;
-
-namespace BizHawk.Emulation.Cores.Sega.Genesis
-{
- [CoreAttributes(
- "GenesisHawk",
- "Vecna",
- isPorted: false,
- isReleased: false
- )]
- public sealed partial class Genesis : IEmulator, ISaveRam, IStatable, IInputPollable
- {
- private int _lagcount = 0;
- private bool lagged = true;
- private bool islag = false;
-
- // ROM
- public byte[] RomData;
-
- // Machine stuff
- public MC68000 MainCPU;
- public Z80A SoundCPU;
- public GenVDP VDP;
- public SN76489 PSG;
- public YM2612 YM2612;
- public byte[] Ram = new byte[0x10000];
- public byte[] Z80Ram = new byte[0x2000];
-
- private bool M68000HasZ80Bus = false;
- private bool Z80Reset = false;
- private bool Z80Runnable { get { return (Z80Reset == false && M68000HasZ80Bus == false); } }
-
- private SoundMixer SoundMixer;
-
- [FeatureNotImplemented]
- public IInputCallbackSystem InputCallbacks { get { throw new NotImplementedException(); } }
-
- public void ResetCounters()
- {
- Frame = 0;
- _lagcount = 0;
- islag = false;
- }
-
- // Genesis timings:
- // 53,693,175 Machine clocks / sec
- // 7,670,454 Main 68000 cycles / sec (7 mclk divisor)
- // 3,579,545 Z80 cycles / sec (15 mclk divisor)
-
- // At 59.92 FPS:
- // 896,081 mclks / frame
- // 128,011 Main 68000 cycles / frame
- // 59,738 Z80 cycles / frame
-
- // At 262 lines/frame:
- // 3420 mclks / line
- // ~ 488.5 Main 68000 cycles / line
- // 228 Z80 cycles / line
-
- // Video characteristics:
- // 224 lines are active display. The remaining 38 lines are vertical blanking.
- // In H40 mode, the dot clock is 480 pixels per line.
- // 320 are active display, the remaining 160 are horizontal blanking.
- // A total of 3420 mclks per line, but 2560 mclks are active display and 860 mclks are blanking.
-
-#if MUSASHI
- VdpCallback _vdp;
- ReadCallback read8;
- ReadCallback read16;
- ReadCallback read32;
- WriteCallback write8;
- WriteCallback write16;
- WriteCallback write32;
-#endif
-
- public Genesis(CoreComm comm, GameInfo game, byte[] rom)
- {
- ServiceProvider = new BasicServiceProvider(this);
- CoreComm = comm;
- MainCPU = new MC68000();
- SoundCPU = new Z80A();
- YM2612 = new YM2612() { MaxVolume = 23405 };
- PSG = new SN76489() { MaxVolume = 4681 };
- VDP = new GenVDP();
- VDP.DmaReadFrom68000 = ReadWord;
- (ServiceProvider as BasicServiceProvider).Register(VDP);
- SoundMixer = new SoundMixer(YM2612, PSG);
-
- MainCPU.ReadByte = ReadByte;
- MainCPU.ReadWord = ReadWord;
- MainCPU.ReadLong = ReadLong;
- MainCPU.WriteByte = WriteByte;
- MainCPU.WriteWord = WriteWord;
- MainCPU.WriteLong = WriteLong;
- MainCPU.IrqCallback = InterruptCallback;
-
- // ---------------------- musashi -----------------------
-#if MUSASHI
- _vdp = vdpcallback;
- read8 = Read8;
- read16 = Read16;
- read32 = Read32;
- write8 = Write8;
- write16 = Write16;
- write32 = Write32;
-
- Musashi.RegisterVdpCallback(Marshal.GetFunctionPointerForDelegate(_vdp));
- Musashi.RegisterRead8(Marshal.GetFunctionPointerForDelegate(read8));
- Musashi.RegisterRead16(Marshal.GetFunctionPointerForDelegate(read16));
- Musashi.RegisterRead32(Marshal.GetFunctionPointerForDelegate(read32));
- Musashi.RegisterWrite8(Marshal.GetFunctionPointerForDelegate(write8));
- Musashi.RegisterWrite16(Marshal.GetFunctionPointerForDelegate(write16));
- Musashi.RegisterWrite32(Marshal.GetFunctionPointerForDelegate(write32));
-#endif
- // ---------------------- musashi -----------------------
-
- SoundCPU.ReadMemory = ReadMemoryZ80;
- SoundCPU.WriteMemory = WriteMemoryZ80;
- SoundCPU.WriteHardware = (a, v) => { Console.WriteLine("Z80: Attempt I/O Write {0:X2}:{1:X2}", a, v); };
- SoundCPU.ReadHardware = x => 0xFF;
- SoundCPU.IRQCallback = () => SoundCPU.Interrupt = false;
- Z80Reset = true;
- RomData = new byte[0x400000];
- for (int i = 0; i < rom.Length; i++)
- RomData[i] = rom[i];
-
- SetupMemoryDomains();
-#if MUSASHI
- Musashi.Init();
- Musashi.Reset();
- VDP.GetPC = () => Musashi.PC;
-#else
- MainCPU.Reset();
- VDP.GetPC = () => MainCPU.PC;
-#endif
- InitializeCartHardware(game);
- }
-
- public IEmulatorServiceProvider ServiceProvider { get; private set; }
-
- void InitializeCartHardware(GameInfo game)
- {
- LogCartInfo();
- InitializeEeprom(game);
- InitializeSaveRam(game);
- }
-
- public void FrameAdvance(bool render, bool rendersound)
- {
- lagged = true;
- Frame++;
- PSG.BeginFrame(SoundCPU.TotalExecutedCycles);
- YM2612.BeginFrame(SoundCPU.TotalExecutedCycles);
-
- // Do start-of-frame events
- VDP.HIntLineCounter = VDP.Registers[10];
- //VDP.VdpStatusWord &=
- unchecked { VDP.VdpStatusWord &= (ushort)~GenVDP.StatusVerticalBlanking; }
-
- for (VDP.ScanLine = 0; VDP.ScanLine < 262; VDP.ScanLine++)
- {
- //Log.Error("VDP","FRAME {0}, SCANLINE {1}", Frame, VDP.ScanLine);
-
- if (VDP.ScanLine < VDP.FrameHeight)
- VDP.RenderLine();
-
- Exec68k(365);
- RunZ80(171);
-
- // H-Int now?
-
- VDP.HIntLineCounter--;
- if (VDP.HIntLineCounter < 0 && VDP.ScanLine < 224) // FIXME
- {
- VDP.HIntLineCounter = VDP.Registers[10];
- VDP.VdpStatusWord |= GenVDP.StatusHorizBlanking;
-
- if (VDP.HInterruptsEnabled)
- {
- Set68kIrq(4);
- //Console.WriteLine("Fire hint!");
- }
-
- }
-
- Exec68k(488 - 365);
- RunZ80(228 - 171);
-
- if (VDP.ScanLine == 224)
- {
- VDP.VdpStatusWord |= GenVDP.StatusVerticalInterruptPending;
- VDP.VdpStatusWord |= GenVDP.StatusVerticalBlanking;
- Exec68k(16); // this is stupidly wrong.
- // End-frame stuff
- if (VDP.VInterruptEnabled)
- Set68kIrq(6);
-
- SoundCPU.Interrupt = true;
- //The INT output is asserted every frame for exactly one scanline, and it can't be disabled. A very short Z80 interrupt routine would be triggered multiple times if it finishes within 228 Z80 clock cycles. I think (but cannot recall the specifics) that some games have delay loops in the interrupt handler for this very reason.
- }
- }
- PSG.EndFrame(SoundCPU.TotalExecutedCycles);
- YM2612.EndFrame(SoundCPU.TotalExecutedCycles);
-
-
-
- if (lagged)
- {
- _lagcount++;
- islag = true;
- }
- else
- islag = false;
- }
-
- void Exec68k(int cycles)
- {
-#if MUSASHI
- Musashi.Execute(cycles);
-#else
- MainCPU.ExecuteCycles(cycles);
-#endif
- }
-
- void RunZ80(int cycles)
- {
- // I emulate the YM2612 synced to Z80 clock, for better or worse.
- // So we still need to keep the Z80 cycle count accurate even if the Z80 isn't running.
-
- if (Z80Runnable)
- SoundCPU.ExecuteCycles(cycles);
- else
- SoundCPU.TotalExecutedCycles += cycles;
- }
-
- void Set68kIrq(int irq)
- {
-#if MUSASHI
- Musashi.SetIRQ(irq);
-#else
- MainCPU.Interrupt = irq;
-#endif
- }
-
- public IDictionary GetCpuFlagsAndRegisters()
- {
- return new Dictionary
- {
- { "A-0", MainCPU.A[0].s32 },
- { "A-1", MainCPU.A[1].s32 },
- { "A-2", MainCPU.A[2].s32 },
- { "A-3", MainCPU.A[3].s32 },
- { "A-4", MainCPU.A[4].s32 },
- { "A-5", MainCPU.A[5].s32 },
- { "A-6", MainCPU.A[6].s32 },
- { "A-7", MainCPU.A[7].s32 },
-
- { "D-0", MainCPU.D[0].s32 },
- { "D-1", MainCPU.D[1].s32 },
- { "D-2", MainCPU.D[2].s32 },
- { "D-3", MainCPU.D[3].s32 },
- { "D-4", MainCPU.D[4].s32 },
- { "D-5", MainCPU.D[5].s32 },
- { "D-6", MainCPU.D[6].s32 },
- { "D-7", MainCPU.D[7].s32 },
-
- { "SR", MainCPU.SR },
-
- { "Flag X", MainCPU.X },
- { "Flag N", MainCPU.N },
- { "Flag Z", MainCPU.Z },
- { "Flag V", MainCPU.V },
- { "Flag C", MainCPU.C }
- };
- }
-
- int vdpcallback(int level) // Musashi handler
- {
- InterruptCallback(level);
- return -1;
- }
-
- void InterruptCallback(int level)
- {
- unchecked { VDP.VdpStatusWord &= (ushort)~GenVDP.StatusVerticalInterruptPending; }
- }
-
- public CoreComm CoreComm { get; private set; }
-
- // TODO: Implement ISoundProvider
- /*
- public IAsyncSoundProvider SoundProvider
- {
- get { return SoundMixer; }
- }
-
- public ISyncSoundProvider SyncSoundProvider { get { return new FakeSyncSound(SoundMixer, 735); } }
- */
-
- public int Frame { get; set; }
- public int LagCount { get { return _lagcount; } set { _lagcount = value; } }
- public bool IsLagFrame { get { return islag; } set { islag = value; } }
- public bool DeterministicEmulation { get { return true; } }
- public string SystemId { get { return "GEN"; } }
-
- public void SaveStateText(TextWriter writer)
- {
- var buf = new byte[141501 + SaveRAM.Length];
- var stream = new MemoryStream(buf);
- var bwriter = new BinaryWriter(stream);
- SaveStateBinary(bwriter);
-
- writer.WriteLine("Version 1");
- writer.Write("BigFatBlob ");
- buf.SaveAsHex(writer);
-
- /*writer.WriteLine("[MegaDrive]");
- MainCPU.SaveStateText(writer, "Main68K");
- SoundCPU.SaveStateText(writer);
- PSG.SaveStateText(writer);
- VDP.SaveStateText(writer);
- writer.WriteLine("Frame {0}", Frame);
- writer.WriteLine("Lag {0}", _lagcount);
- writer.WriteLine("IsLag {0}", islag);
- writer.Write("MainRAM ");
- Ram.SaveAsHex(writer);
- writer.Write("Z80RAM ");
- Z80Ram.SaveAsHex(writer);
- writer.WriteLine("[/MegaDrive]");*/
- }
-
- public void LoadStateText(TextReader reader)
- {
- var buf = new byte[141501 + SaveRAM.Length];
- var version = reader.ReadLine();
- if (version != "Version 1")
- throw new Exception("Not a valid state vesrion! sorry! your state is bad! Robust states will be added later!");
- var omgstate = reader.ReadLine().Split(' ')[1];
- buf.ReadFromHex(omgstate);
- LoadStateBinary(new BinaryReader(new MemoryStream(buf)));
-
- /*while (true)
- {
- string[] args = reader.ReadLine().Split(' ');
- if (args[0].Trim() == "") continue;
- if (args[0] == "[MegaDrive]") continue;
- if (args[0] == "[/MegaDrive]") break;
- if (args[0] == "MainRAM")
- Ram.ReadFromHex(args[1]);
- else if (args[0] == "Z80RAM")
- Z80Ram.ReadFromHex(args[1]);
- else if (args[0] == "[Main68K]")
- MainCPU.LoadStateText(reader, "Main68K");
- else if (args[0] == "[Z80]")
- SoundCPU.LoadStateText(reader);
- else if (args[0] == "Frame")
- Frame = int.Parse(args[1]);
- else if (args[0] == "Lag")
- _lagcount = int.Parse(args[1]);
- else if (args[0] == "IsLag")
- islag = bool.Parse(args[1]);
- else if (args[0] == "[PSG]")
- PSG.LoadStateText(reader);
- else if (args[0] == "[VDP]")
- VDP.LoadStateText(reader);
- else
- Console.WriteLine("Skipping unrecognized identifier " + args[0]);
- }*/
- }
-
- public void SaveStateBinary(BinaryWriter writer)
- {
- Musashi.SaveStateBinary(writer); // 124
- //SoundCPU.SaveStateBinary(writer); // 46 TODO fix this, there is no way to invoke this core from the UI for testing anyway.
- //PSG.SaveStateBinary(writer); // 15
- VDP.SaveStateBinary(writer); // 65781
- YM2612.SaveStateBinary(writer); // 1785
-
- writer.Write(Ram); // 65535
- writer.Write(Z80Ram); // 8192
-
- writer.Write(Frame); // 4
- writer.Write(M68000HasZ80Bus); // 1
- writer.Write(Z80Reset); // 1
- writer.Write(BankRegion); // 4
-
- for (int i = 0; i < 3; i++)
- {
- writer.Write(IOPorts[i].Data);
- writer.Write(IOPorts[i].TxData);
- writer.Write(IOPorts[i].RxData);
- writer.Write(IOPorts[i].SCtrl);
- }
-
- if (SaveRAM.Length > 0)
- writer.Write(SaveRAM);
-
- // TODO: EEPROM/cart HW state
- // TODO: lag counter crap
- }
-
- public void LoadStateBinary(BinaryReader reader)
- {
- Musashi.LoadStateBinary(reader);
- //SoundCPU.LoadStateBinary(reader);
- //PSG.LoadStateBinary(reader);
- VDP.LoadStateBinary(reader);
- YM2612.LoadStateBinary(reader);
-
- Ram = reader.ReadBytes(Ram.Length);
- Z80Ram = reader.ReadBytes(Z80Ram.Length);
-
- Frame = reader.ReadInt32();
- M68000HasZ80Bus = reader.ReadBoolean();
- Z80Reset = reader.ReadBoolean();
- BankRegion = reader.ReadInt32();
-
- for (int i = 0; i < 3; i++)
- {
- IOPorts[i].Data = reader.ReadByte();
- IOPorts[i].TxData = reader.ReadByte();
- IOPorts[i].RxData = reader.ReadByte();
- IOPorts[i].SCtrl = reader.ReadByte();
- }
-
- if (SaveRAM.Length > 0)
- SaveRAM = reader.ReadBytes(SaveRAM.Length);
- }
-
- public byte[] SaveStateBinary()
- {
- var buf = new byte[141501 + SaveRAM.Length];
- var stream = new MemoryStream(buf);
- var writer = new BinaryWriter(stream);
- SaveStateBinary(writer);
- //Console.WriteLine("buf len = {0}", stream.Position);
- writer.Close();
- return buf;
- }
-
- public bool BinarySaveStatesPreferred { get { return false; } }
-
- //MemoryDomainList memoryDomains;
-
- void SetupMemoryDomains()
- {
- /*
- var domains = new List(3);
- var MainMemoryDomain = new MemoryDomain("Main RAM", Ram.Length, MemoryDomain.Endian.Big,
- addr => Ram[addr & 0xFFFF],
- (addr, value) => Ram[addr & 0xFFFF] = value);
- var Z80Domain = new MemoryDomain("Z80 RAM", Z80Ram.Length, MemoryDomain.Endian.Little,
- addr => Z80Ram[addr & 0x1FFF],
- (addr, value) => { Z80Ram[addr & 0x1FFF] = value; });
-
- var VRamDomain = new MemoryDomain("Video RAM", VDP.VRAM.Length, MemoryDomain.Endian.Big,
- addr => VDP.VRAM[addr & 0xFFFF],
- (addr, value) => VDP.VRAM[addr & 0xFFFF] = value);
-
- var RomDomain = new MemoryDomain("MD CART", RomData.Length, MemoryDomain.Endian.Big,
- addr => RomData[addr], //adelikat: For speed considerations, I didn't mask this, every tool that uses memory domains is smart enough not to overflow, if I'm wrong let me know!
- (addr, value) => RomData[addr & (RomData.Length - 1)] = value);
-
- var SystemBusDomain = new MemoryDomain("System Bus", 0x1000000, MemoryDomain.Endian.Big,
- addr => (byte)ReadByte((int)addr),
- (addr, value) => Write8((uint)addr, (uint)value));
-
- domains.Add(MainMemoryDomain);
- domains.Add(Z80Domain);
- domains.Add(VRamDomain);
- domains.Add(RomDomain);
- domains.Add(SystemBusDomain);
- memoryDomains = new MemoryDomainList(domains);
- (ServiceProvider as BasicServiceProvider).Register(memoryDomains);
- */
- throw new NotImplementedException();
- }
-
- public void Dispose() { }
- }
-}
diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/MemoryMap.68000.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/MemoryMap.68000.cs
deleted file mode 100644
index 26d89235ad..0000000000
--- a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/MemoryMap.68000.cs
+++ /dev/null
@@ -1,254 +0,0 @@
-using System;
-
-namespace BizHawk.Emulation.Cores.Sega.Genesis
-{
- partial class Genesis
- {
- public sbyte ReadByte(int address)
- {
- address &= 0x00FFFFFF;
-
- if (address < 0x200000)
- return (sbyte)RomData[address];
-
- if (address < 0x400000)
- {
- if (SaveRamEnabled && address >= SaveRamStartOffset && address < SaveRamEndOffset)
- {
- if (SaveRamEveryOtherByte)
- return (sbyte)SaveRAM[(address - SaveRamStartOffset) >> 1];
- else
- return (sbyte)SaveRAM[address - SaveRamStartOffset];
- }
- return (sbyte)RomData[address];
- }
-
- if (address >= 0xE00000)
- return (sbyte)Ram[address & 0xFFFF];
-
- if (address == 0xA11100) // Z80 BUS status
- {
- //Console.WriteLine("QUERY z80 bus status. 68000 can access? " + (M68000HasZ80Bus && Z80Reset == false));
- return (sbyte)(M68000HasZ80Bus && Z80Reset == false ? 0 : 1);
- }
-
- if (address >= 0xA10000 && address <= 0xA1001F)
- return (sbyte)ReadIO(address);
-
- if ((address & 0xFF0000) == 0xA00000)
- return (sbyte)ReadMemoryZ80((ushort)(address & 0x7FFF));
-
- if (address >= 0xC00000 && address < 0xC00010)
- {
- //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
- }
-
- Console.WriteLine("UNHANDLED READB {0:X6}", address);
- return 0x7D;
- }
-
- public short ReadWord(int address)
- {
- address &= 0x00FFFFFF;
-
- int maskedAddr;
- if (address < 0x400000)
- return (short)((RomData[address] << 8) | RomData[address + 1]);
-
- if (address >= 0xE00000) // Work RAM
- {
- maskedAddr = address & 0xFFFE;
- return (short)((Ram[maskedAddr] << 8) | Ram[maskedAddr + 1]);
- }
-
- if (address >= 0xC00000 && address < 0xC00010)
- return (short)VDP.ReadVdp(address & 0x0E);
-
- if (address >= 0xA10000 && address <= 0xA1001F)
- return (sbyte)ReadIO(address);
-
- if (address == 0xA11100) // Z80 BUS status
- return (short)(M68000HasZ80Bus && Z80Reset == false ? 0x0000 : 0x0100);
-
- Console.WriteLine("UNHANDLED READW {0:X6}", address);
- return 0x7DCD;
- }
-
- public int ReadLong(int address)
- {
- address &= 0x00FFFFFF;
-
- 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];
- }
-
- if (address >= 0xC00000)
- {
- //Console.WriteLine("long-read from VDP");
- short msw = ReadWord(address);
- short msl = ReadWord(address + 2);
- return (msw << 16) | (ushort)msl;
- }
-
- // 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);
- //return 0x7DCDCDCD;
- }
-
- public void WriteByte(int address, sbyte value)
- {
- address &= 0x00FFFFFF;
-
- if (address >= 0xE00000) // Work RAM
- {
- //Console.WriteLine("MEM[{0:X4}] change from {1:X2} to {2:X2}", address & 0xFFFF, Ram[address & 0xFFFF], value);
- Ram[address & 0xFFFF] = (byte)value;
- return;
- }
- if ((address & 0xFF0000) == 0xA00000)
- {
- WriteMemoryZ80((ushort)(address & 0x7FFF), (byte)value);
- return;
- }
- if (address >= 0xA10000 && address <= 0xA1001F)
- {
- WriteIO(address, value);
- return;
- }
- if (address == 0xA11100)
- {
- M68000HasZ80Bus = (value & 1) != 0;
- //Console.WriteLine("68000 has the z80 bus: " + M68000HasZ80Bus);
- return;
- }
- if (address == 0xA11200) // Z80 RESET
- {
- Z80Reset = (value & 1) == 0;
- if (Z80Reset)
- SoundCPU.SoftReset();
- //Console.WriteLine("z80 reset: " + Z80Reset);
- return;
- }
- if (address >= 0xC00000 && address < 0xC00010)
- {
- // when writing to VDP in byte mode, the LSB is duplicated into the MSB
- 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;
- }
-
- if (SaveRamEnabled && address >= SaveRamStartOffset && address < SaveRamEndOffset)
- {
- if (SaveRamEveryOtherByte)
- SaveRAM[(address - SaveRamStartOffset) >> 1] = (byte)value;
- else
- SaveRAM[address - SaveRamStartOffset] = (byte)value;
-
- SaveRamModified = true;
- return;
- }
-
- if (EepromEnabled && (address == SclAddr || address == SdaInAddr))
- {
- WriteByteEeprom(address, (byte)value);
- return;
-
- }
-
- Console.WriteLine("UNHANDLED WRITEB {0:X6}:{1:X2}", address, value);
- }
-
- public void WriteWord(int address, short value)
- {
- address &= 0x00FFFFFF;
-
- if (address >= 0xE00000) // Work RAM
- {
- //Console.WriteLine("MEM[{0:X4}] change to {1:X4}", address & 0xFFFF, value);
- Ram[(address & 0xFFFF) + 0] = (byte)(value >> 8);
- Ram[(address & 0xFFFF) + 1] = (byte)value;
- return;
- }
- if (address >= 0xC00000)
- {
- switch (address & 0x1F)
- {
- case 0x00:
- case 0x02:
- VDP.WriteVdpData((ushort)value);
- return;
- case 0x04:
- case 0x06:
- VDP.WriteVdpControl((ushort)value);
- return;
- }
- }
- if (address == 0xA11100) // Z80 BUSREQ
- {
- M68000HasZ80Bus = (value & 0x100) != 0;
- //Console.WriteLine("68000 has the z80 bus: " + M68000HasZ80Bus);
- return;
- }
- if (address == 0xA11200) // Z80 RESET
- {
- Z80Reset = (value & 0x100) == 0;
- if (Z80Reset)
- SoundCPU.SoftReset();
- //Console.WriteLine("z80 reset: " + Z80Reset);
- return;
- }
- Console.WriteLine("UNHANDLED WRITEW {0:X6}:{1:X4}", address, value);
- }
-
- public void WriteLong(int address, int value)
- {
- address &= 0x00FFFFFF;
-
- if (address >= 0xE00000) // Work RAM
- {
- //Console.WriteLine("MEM[{0:X4}] change to {1:X8}", address & 0xFFFF, value);
- Ram[(address & 0xFFFF) + 0] = (byte)(value >> 24);
- Ram[(address & 0xFFFF) + 1] = (byte)(value >> 16);
- Ram[(address & 0xFFFF) + 2] = (byte)(value >> 8);
- Ram[(address & 0xFFFF) + 3] = (byte)value;
- return;
- }
- if (address >= 0xC00000)
- {
- WriteWord(address, (short)(value >> 16));
- WriteWord(address + 2, (short)value);
- return;
- }
-
- 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); }
- }
-}
diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/MemoryMap.Z80.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/MemoryMap.Z80.cs
deleted file mode 100644
index 51cacdacc8..0000000000
--- a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/MemoryMap.Z80.cs
+++ /dev/null
@@ -1,84 +0,0 @@
-using System;
-
-namespace BizHawk.Emulation.Cores.Sega.Genesis
-{
- partial class Genesis
- {
- private int BankRegion;
-
- public byte ReadMemoryZ80(ushort address)
- {
- if (address < 0x4000)
- {
- //Console.WriteLine("read z80 memory {0:X4}: {1:X2}",address, Z80Ram[address & 0x1FFF]);
- return Z80Ram[address & 0x1FFF];
- }
- if (address >= 0x4000 && address < 0x6000)
- {
- //Console.WriteLine(" === Z80 READS FM STATUS ===");
- return YM2612.ReadStatus(SoundCPU.TotalExecutedCycles); // 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;
- }
-
- public void WriteMemoryZ80(ushort address, byte value)
- {
- if (address < 0x4000)
- {
- //Console.WriteLine("write z80 memory {0:X4}: {1:X2}",address, value);
- Z80Ram[address & 0x1FFF] = value;
- return;
- }
- if (address >= 0x4000 && address < 0x6000)
- {
- //Console.WriteLine(" === Z80 WRITES YM2612 {0:X4}:{1:X2} ===",address, value);
- YM2612.Write(address & 3, value, SoundCPU.TotalExecutedCycles);
- return;
- }
- if (address < 0x6100)
- {
- BankRegion >>= 1;
- BankRegion |= (value & 1) << 23;
- BankRegion &= 0x00FF8000;
- //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);
- return;
- }
- Console.WriteLine("UNHANDLED Z80 WRITE {0:X4}:{1:X2}", address, value);
- }
- }
-}
diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/Native68000/Musashi.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/Native68000/Musashi.cs
deleted file mode 100644
index 6493555494..0000000000
--- a/BizHawk.Emulation.Cores/Consoles/Sega/Genesis/Native68000/Musashi.cs
+++ /dev/null
@@ -1,92 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-using System.IO;
-
-namespace Native68000
-{
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- delegate int VdpCallback(int i);
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- delegate uint ReadCallback(uint a);
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- delegate void WriteCallback(uint a, uint v);
-
- public class Musashi
- {
- [DllImport("MusashiDLL.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern void RegisterVdpCallback(IntPtr callback);
-
- [DllImport("MusashiDLL.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern void RegisterRead8(IntPtr callback);
-
- [DllImport("MusashiDLL.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern void RegisterRead16(IntPtr callback);
-
- [DllImport("MusashiDLL.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern void RegisterRead32(IntPtr callback);
-
- [DllImport("MusashiDLL.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern void RegisterWrite8(IntPtr callback);
-
- [DllImport("MusashiDLL.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern void RegisterWrite16(IntPtr callback);
-
- [DllImport("MusashiDLL.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern void RegisterWrite32(IntPtr callback);
-
- [DllImport("MusashiDLL.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern void Init();
-
- [DllImport("MusashiDLL.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern void Reset();
-
- [DllImport("MusashiDLL.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern void SetIRQ(int level);
-
- [DllImport("MusashiDLL.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern int Execute(int cycles);
-
- [DllImport("MusashiDLL.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern int QueryCpuState(int regcode);
-
- [DllImport("MusashiDLL.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern void SetCpuState(int regcode, int value);
-
- [DllImport("MusashiDLL.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern int GetCyclesRemaining();
-
- public static int D0 { get { return QueryCpuState(0); } }
- public static int D1 { get { return QueryCpuState(1); } }
- public static int D2 { get { return QueryCpuState(2); } }
- public static int D3 { get { return QueryCpuState(3); } }
- public static int D4 { get { return QueryCpuState(4); } }
- public static int D5 { get { return QueryCpuState(5); } }
- public static int D6 { get { return QueryCpuState(6); } }
- public static int D7 { get { return QueryCpuState(7); } }
-
- public static int A0 { get { return QueryCpuState(8); } }
- public static int A1 { get { return QueryCpuState(9); } }
- public static int A2 { get { return QueryCpuState(10); } }
- public static int A3 { get { return QueryCpuState(11); } }
- public static int A4 { get { return QueryCpuState(12); } }
- public static int A5 { get { return QueryCpuState(13); } }
- public static int A6 { get { return QueryCpuState(14); } }
- public static int A7 { get { return QueryCpuState(15); } }
-
- public static int PC { get { return QueryCpuState(16); } }
- public static int SR { get { return QueryCpuState(17); } }
- public static int SP { get { return QueryCpuState(18); } }
-
- public static void SaveStateBinary(BinaryWriter writer)
- {
- for (int i=0; i<31; i++)
- writer.Write(QueryCpuState(i));
- }
-
- public static void LoadStateBinary(BinaryReader reader)
- {
- for (int i = 0; i < 31; i++)
- SetCpuState(i, reader.ReadInt32());
- }
- }
-}
\ No newline at end of file