diff --git a/Audio.cs b/Audio.cs deleted file mode 100644 index 7fcaaca85f..0000000000 --- a/Audio.cs +++ /dev/null @@ -1,213 +0,0 @@ -using System; - -using BizHawk.Common; -using BizHawk.Common.BufferExtensions; -using BizHawk.Emulation.Common; -using BizHawk.Common.NumberExtensions; - -namespace BizHawk.Emulation.Cores.Nintendo.GBHawk -{ - // Audio Emulation - public class Audio : ISoundProvider - { - public GBHawk Core { get; set; } - - public const int NR10 = 0; - public const int NR11 = 1; - public const int NR12 = 2; - public const int NR13 = 3; - public const int NR14 = 4; - public const int NR21 = 5; - public const int NR22 = 6; - public const int NR23 = 7; - public const int NR24 = 8; - public const int NR30 = 9; - public const int NR31 = 10; - public const int NR32 = 11; - public const int NR33 = 12; - public const int NR34 = 13; - public const int NR41 = 14; - public const int NR42 = 15; - public const int NR43 = 16; - public const int NR44 = 17; - public const int NR50 = 18; - public const int NR51 = 19; - public const int NR52 = 20; - - public static int[] unused_bits = new int[] { 0x80, 0x3F, 0x00, 0xFF, 0xBF, - 0x3F, 0x00, 0xFF, 0xBF, - 0x7F, 0xFF, 0x9F, 0xFF, 0xBF, - 0xFF, 0x00, 0x00, 0xBF, - 0x00, 0x00, 0x70}; - - public byte[] Audio_Regs = new byte[21]; - - public byte[] Wave_RAM = new byte [16]; - - - public byte ReadReg(int addr) - { - byte ret = 0; - - switch (addr) - { - case 0xFF10: ret = (byte)(Audio_Regs[NR10] | unused_bits[NR10]); break; // NR10 (sweep) - case 0xFF11: ret = (byte)(Audio_Regs[NR11] | unused_bits[NR11]); break; // NR11 (sound length / wave pattern duty %) - case 0xFF12: ret = (byte)(Audio_Regs[NR12] | unused_bits[NR12]); break; // NR12 (envelope) - case 0xFF13: ret = (byte)(Audio_Regs[NR13] | unused_bits[NR13]); break; // NR13 (freq low) - case 0xFF14: ret = (byte)(Audio_Regs[NR14] | unused_bits[NR14]); break; // NR14 (freq hi) - case 0xFF16: ret = (byte)(Audio_Regs[NR21] | unused_bits[NR21]); break; // NR21 (sound length / wave pattern duty %) - case 0xFF17: ret = (byte)(Audio_Regs[NR22] | unused_bits[NR22]); break; // NR22 (envelope) - case 0xFF18: ret = (byte)(Audio_Regs[NR23] | unused_bits[NR23]); break; // NR23 (freq low) - case 0xFF19: ret = (byte)(Audio_Regs[NR24] | unused_bits[NR24]); break; // NR24 (freq hi) - case 0xFF1A: ret = (byte)(Audio_Regs[NR30] | unused_bits[NR30]); break; // NR30 (on/off) - case 0xFF1B: ret = (byte)(Audio_Regs[NR31] | unused_bits[NR31]); break; // NR31 (length) - case 0xFF1C: ret = (byte)(Audio_Regs[NR32] | unused_bits[NR32]); break; // NR32 (level output) - case 0xFF1D: ret = (byte)(Audio_Regs[NR33] | unused_bits[NR33]); break; // NR33 (freq low) - case 0xFF1E: ret = (byte)(Audio_Regs[NR34] | unused_bits[NR34]); break; // NR34 (freq hi) - case 0xFF20: ret = (byte)(Audio_Regs[NR41] | unused_bits[NR41]); break; // NR41 (sweep) - case 0xFF21: ret = (byte)(Audio_Regs[NR42] | unused_bits[NR42]); break; // NR42 (sweep) - case 0xFF22: ret = (byte)(Audio_Regs[NR43] | unused_bits[NR43]); break; // NR43 (sweep) - case 0xFF23: ret = (byte)(Audio_Regs[NR44] | unused_bits[NR44]); break; // NR44 (sweep) - case 0xFF24: ret = (byte)(Audio_Regs[NR50] | unused_bits[NR50]); break; // NR50 (sweep) - case 0xFF25: ret = (byte)(Audio_Regs[NR51] | unused_bits[NR51]); break; // NR51 (sweep) - case 0xFF26: ret = (byte)(Audio_Regs[NR52] | unused_bits[NR52]); break; // NR52 (sweep) - - // wave ram table - case 0xFF30: - case 0xFF31: - case 0xFF32: - case 0xFF33: - case 0xFF34: - case 0xFF35: - case 0xFF36: - case 0xFF37: - case 0xFF38: - case 0xFF39: - case 0xFF3A: - case 0xFF3B: - case 0xFF3C: - case 0xFF3D: - case 0xFF3E: - case 0xFF3F: - ret = Wave_RAM[addr & 0x0F]; - break; - - } - - return ret; - } - - public void WriteReg(int addr, byte value) - { - switch (addr) - { - case 0xFF10: Audio_Regs[NR10] = value; break; // NR10 (sweep) - case 0xFF11: Audio_Regs[NR11] = value; break; // NR11 (sound length / wave pattern duty %) - case 0xFF12: Audio_Regs[NR12] = value; break; // NR12 (envelope) - case 0xFF13: Audio_Regs[NR13] = value; break; // NR13 (freq low) - case 0xFF14: Audio_Regs[NR14] = value; break; // NR14 (freq hi) - case 0xFF16: Audio_Regs[NR21] = value; break; // NR21 (sound length / wave pattern duty %) - case 0xFF17: Audio_Regs[NR22] = value; break; // NR22 (envelope) - case 0xFF18: Audio_Regs[NR23] = value; break; // NR23 (freq low) - case 0xFF19: Audio_Regs[NR24] = value; break; // NR24 (freq hi) - case 0xFF1A: Audio_Regs[NR30] = value; break; // NR30 (on/off) - case 0xFF1B: Audio_Regs[NR31] = value; break; // NR31 (length) - case 0xFF1C: Audio_Regs[NR32] = value; break; // NR32 (level output) - case 0xFF1D: Audio_Regs[NR33] = value; break; // NR33 (freq low) - case 0xFF1E: Audio_Regs[NR34] = value; break; // NR34 (freq hi) - case 0xFF20: Audio_Regs[NR41] = value; break; // NR41 (sweep) - case 0xFF21: Audio_Regs[NR42] = value; break; // NR42 (sweep) - case 0xFF22: Audio_Regs[NR43] = value; break; // NR43 (sweep) - case 0xFF23: Audio_Regs[NR44] = value; break; // NR44 (sweep) - case 0xFF24: Audio_Regs[NR50] = value; break; // NR50 (sweep) - case 0xFF25: Audio_Regs[NR51] = value; break; // NR51 (sweep) - case 0xFF26: Audio_Regs[NR52] = value; break; // NR52 (sweep) - - // wave ram table - case 0xFF30: - case 0xFF31: - case 0xFF32: - case 0xFF33: - case 0xFF34: - case 0xFF35: - case 0xFF36: - case 0xFF37: - case 0xFF38: - case 0xFF39: - case 0xFF3A: - case 0xFF3B: - case 0xFF3C: - case 0xFF3D: - case 0xFF3E: - case 0xFF3F: - Wave_RAM[addr & 0x0F] = value; - break; - - } - } - - public void tick() - { - - } - - public void reset() - { - Wave_RAM = new byte[16]; - - Audio_Regs = new byte[21]; - } - - public void SyncState(Serializer ser) - { - ser.Sync("Audio_Regs", ref Audio_Regs, false); - ser.Sync("Wave_Ram", ref Wave_RAM, false); - - } - - #region audio - - public bool CanProvideAsync => false; - - public int _spf; - public int AudioClocks; - - public void SetSyncMode(SyncSoundMode mode) - { - if (mode != SyncSoundMode.Sync) - { - throw new InvalidOperationException("Only Sync mode is supported."); - } - } - - public SyncSoundMode SyncMode => SyncSoundMode.Sync; - - public void GetSamplesSync(out short[] samples, out int nsamp) - { - short[] ret = new short[_spf * 2]; - nsamp = _spf; - GetSamples(ret); - samples = ret; - } - - public void GetSamplesAsync(short[] samples) - { - throw new NotSupportedException("Async is not available"); - } - - public void DiscardSamples() - { - AudioClocks = 0; - } - - // Exposing this as GetSamplesAsync would allow this to provide async sound - // However, it does nothing special for async sound so I don't see a point - private void GetSamples(short[] samples) - { - - } - - #endregion - } -} \ No newline at end of file diff --git a/GBHawk.IDebuggable.cs b/GBHawk.IDebuggable.cs deleted file mode 100644 index 543cecf962..0000000000 --- a/GBHawk.IDebuggable.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using System.Collections.Generic; - -using BizHawk.Emulation.Common; - -namespace BizHawk.Emulation.Cores.Nintendo.GBHawk -{ - public partial class GBHawk : IDebuggable - { - public IDictionary GetCpuFlagsAndRegisters() - { - return new Dictionary - { - /* - ["A"] = cpu.A, - ["X"] = cpu.X, - ["Y"] = cpu.Y, - ["S"] = cpu.S, - ["PC"] = cpu.PC, - ["Flag C"] = cpu.FlagC, - ["Flag Z"] = cpu.FlagZ, - ["Flag I"] = cpu.FlagI, - ["Flag D"] = cpu.FlagD, - ["Flag B"] = cpu.FlagB, - ["Flag V"] = cpu.FlagV, - ["Flag N"] = cpu.FlagN, - ["Flag T"] = cpu.FlagT - */ - }; - } - - public void SetCpuRegister(string register, int value) - { - switch (register) - { - default: - throw new InvalidOperationException(); - case "A": - //cpu.A = (byte)value; - break; - case "X": - //cpu.X = (byte)value; - break; - case "Y": - //cpu.Y = (byte)value; - break; - case "S": - //cpu.S = (byte)value; - break; - case "PC": - //cpu.PC = (ushort)value; - break; - case "Flag I": - //cpu.FlagI = value > 0; - break; - } - } - - public IMemoryCallbackSystem MemoryCallbacks { get; } = new MemoryCallbackSystem(); - - public bool CanStep(StepType type) - { - return false; - } - - [FeatureNotImplemented] - public void Step(StepType type) - { - throw new NotImplementedException(); - } - - public int TotalExecutedCycles - { - get { return cpu.TotalExecutedCycles; } - } - } -} diff --git a/GBHawk.IEmulator.cs b/GBHawk.IEmulator.cs deleted file mode 100644 index 189feb6af7..0000000000 --- a/GBHawk.IEmulator.cs +++ /dev/null @@ -1,156 +0,0 @@ -using BizHawk.Common.NumberExtensions; -using BizHawk.Emulation.Common; -using System; -using System.Collections.Generic; - -namespace BizHawk.Emulation.Cores.Nintendo.GBHawk -{ - public partial class GBHawk : IEmulator, IVideoProvider - { - public IEmulatorServiceProvider ServiceProvider { get; } - - public ControllerDefinition ControllerDefinition => _controllerDeck.Definition; - - public byte controller_state; - public byte controller_state_old; - public bool in_vblank_old; - public bool in_vblank; - public bool vblank_rise; - - public void FrameAdvance(IController controller, bool render, bool rendersound) - { - //Console.WriteLine("-----------------------FRAME-----------------------"); - - if (_tracer.Enabled) - { - cpu.TraceCallback = s => _tracer.Put(s); - } - else - { - cpu.TraceCallback = null; - } - - _frame++; - - if (controller.IsPressed("Power")) - { - // it seems that theMachine.Reset() doesn't clear ram, etc - // this should leave hsram intact but clear most other things - HardReset(); - } - - _islag = true; - - GetControllerState(controller); - - do_frame(); - - if (_islag) - { - _lagcount++; - } - } - - public void do_frame() - { - // gameboy frames can be variable lengths - // we want to end a frame when VBlank turns from false to true - int ticker = 0; - while (!vblank_rise && (ticker < 100000)) - { - audio.tick(); - timer.tick_1(); - ppu.tick(); - - cpu.ExecuteOne(ref REG_FF0F, REG_FFFF); - - timer.tick_2(); - - - if (in_vblank && !in_vblank_old) - { - vblank_rise = true; - } - ticker++; - in_vblank_old = in_vblank; - } - - vblank_rise = false; - } - - public void RunCPUCycle() - { - - } - - public void GetControllerState(IController controller) - { - InputCallbacks.Call(); - controller_state = _controllerDeck.ReadPort1(controller); - - // set interrupt flag if a pin went from high to low - if (controller_state < controller_state_old) - { - if (REG_FFFF.Bit(4)) { cpu.FlagI = true; } - REG_FF0F |= 0x10; - } - - controller_state_old = controller_state; - } - - public void serial_transfer() - { - if (serial_control.Bit(7) && !serial_start_old) - { - serial_start_old = true; - - // transfer out on byte of data - // needs to be modelled - } - } - - public int Frame => _frame; - - public string SystemId => "GB"; - - public bool DeterministicEmulation { get; set; } - - public void ResetCounters() - { - _frame = 0; - _lagcount = 0; - _islag = false; - } - - public CoreComm CoreComm { get; } - - public void Dispose() - { - - } - - - #region Video provider - - public int _frameHz = 60; - - public int[] _vidbuffer; - - public int[] GetVideoBuffer() - { - return _vidbuffer; - } - - public int VirtualWidth => 160; - public int VirtualHeight => 144; - public int BufferWidth => 160; - public int BufferHeight => 144; - public int BackgroundColor => unchecked((int)0xFF000000); - public int VsyncNumerator => _frameHz; - public int VsyncDenominator => 1; - - public static readonly uint[] color_palette = { 0xFFFFFFFF , 0xFFAAAAAA, 0xFF555555, 0xFF000000 }; - - #endregion - } -} diff --git a/GBHawk.IInputPollable.cs b/GBHawk.IInputPollable.cs deleted file mode 100644 index 30af4780c6..0000000000 --- a/GBHawk.IInputPollable.cs +++ /dev/null @@ -1,24 +0,0 @@ -using BizHawk.Emulation.Common; - -namespace BizHawk.Emulation.Cores.Nintendo.GBHawk -{ - public partial class GBHawk : IInputPollable - { - public int LagCount - { - get { return _lagcount; } - set { _lagcount = value; } - } - - public bool IsLagFrame - { - get { return _islag; } - set { _islag = value; } - } - - public IInputCallbackSystem InputCallbacks { get; } = new InputCallbackSystem(); - - public bool _islag = true; - private int _lagcount; - } -} diff --git a/GBHawk.IMemoryDomains.cs b/GBHawk.IMemoryDomains.cs deleted file mode 100644 index aa9ecf8b2e..0000000000 --- a/GBHawk.IMemoryDomains.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -using BizHawk.Emulation.Common; - -namespace BizHawk.Emulation.Cores.Nintendo.GBHawk -{ - public partial class GBHawk - { - private IMemoryDomains MemoryDomains; - - public void SetupMemoryDomains() - { - var domains = new List - { - new MemoryDomainDelegate( - "Main RAM", - RAM.Length, - MemoryDomain.Endian.Little, - addr => RAM[addr], - (addr, value) => RAM[addr] = value, - 1), - new MemoryDomainDelegate( - "Zero Page RAM", - ZP_RAM.Length, - MemoryDomain.Endian.Little, - addr => ZP_RAM[addr], - (addr, value) => ZP_RAM[addr] = value, - 1), - new MemoryDomainDelegate( - "System Bus", - 0X10000, - MemoryDomain.Endian.Little, - addr => PeekSystemBus(addr), - (addr, value) => PokeSystemBus(addr, value), - 1) - }; - - MemoryDomains = new MemoryDomainList(domains); - (ServiceProvider as BasicServiceProvider).Register(MemoryDomains); - } - - private byte PeekSystemBus(long addr) - { - ushort addr2 = (ushort)(addr & 0xFFFF); - return ReadMemory(addr2); - } - - private void PokeSystemBus(long addr, byte value) - { - ushort addr2 = (ushort)(addr & 0xFFFF); - WriteMemory(addr2, value); - } - } -} diff --git a/GBHawk.ISaveRam.cs b/GBHawk.ISaveRam.cs deleted file mode 100644 index 5936f9543c..0000000000 --- a/GBHawk.ISaveRam.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using BizHawk.Emulation.Common; - -namespace BizHawk.Emulation.Cores.Nintendo.GBHawk -{ - public partial class GBHawk : ISaveRam - { - public byte[] CloneSaveRam() - { - return (byte[])_sram.Clone(); - } - - public void StoreSaveRam(byte[] data) - { - Buffer.BlockCopy(data, 0, _sram, 0, data.Length); - } - - public bool SaveRamModified - { - get - { - return false; - } - } - } -} diff --git a/GBHawk.ISettable.cs b/GBHawk.ISettable.cs deleted file mode 100644 index 75a267bf62..0000000000 --- a/GBHawk.ISettable.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using System.ComponentModel; - -using Newtonsoft.Json; - -using BizHawk.Common; -using BizHawk.Emulation.Common; - -namespace BizHawk.Emulation.Cores.Nintendo.GBHawk -{ - public partial class GBHawk : IEmulator, IStatable, ISettable - { - public GBSettings GetSettings() - { - return _settings.Clone(); - } - - public GBSyncSettings GetSyncSettings() - { - return _syncSettings.Clone(); - } - - public bool PutSettings(GBSettings o) - { - _settings = o; - return false; - } - - public bool PutSyncSettings(GBSyncSettings o) - { - bool ret = GBSyncSettings.NeedsReboot(_syncSettings, o); - _syncSettings = o; - return ret; - } - - private GBSettings _settings = new GBSettings(); - public GBSyncSettings _syncSettings = new GBSyncSettings(); - - public class GBSettings - { - public GBSettings Clone() - { - return (GBSettings)MemberwiseClone(); - } - } - - public class GBSyncSettings - { - private string _port1 = GBHawkControllerDeck.DefaultControllerName; - - [JsonIgnore] - public string Port1 - { - get { return _port1; } - set - { - if (!GBHawkControllerDeck.ValidControllerTypes.ContainsKey(value)) - { - throw new InvalidOperationException("Invalid controller type: " + value); - } - - _port1 = value; - } - } - - public GBSyncSettings Clone() - { - return (GBSyncSettings)MemberwiseClone(); - } - - public static bool NeedsReboot(GBSyncSettings x, GBSyncSettings y) - { - return !DeepEquality.DeepEquals(x, y); - } - } - } -} diff --git a/GBHawk.IStatable.cs b/GBHawk.IStatable.cs deleted file mode 100644 index a50da0305a..0000000000 --- a/GBHawk.IStatable.cs +++ /dev/null @@ -1,102 +0,0 @@ -using System.IO; - -using BizHawk.Common; -using BizHawk.Emulation.Common; - -namespace BizHawk.Emulation.Cores.Nintendo.GBHawk -{ - public partial class GBHawk : IStatable - { - public bool BinarySaveStatesPreferred => true; - - public void SaveStateText(TextWriter writer) - { - SyncState(new Serializer(writer)); - } - - public void LoadStateText(TextReader reader) - { - SyncState(new Serializer(reader)); - } - - public void SaveStateBinary(BinaryWriter bw) - { - SyncState(new Serializer(bw)); - } - - public void LoadStateBinary(BinaryReader br) - { - SyncState(new Serializer(br)); - } - - public byte[] SaveStateBinary() - { - MemoryStream ms = new MemoryStream(); - BinaryWriter bw = new BinaryWriter(ms); - SaveStateBinary(bw); - bw.Flush(); - return ms.ToArray(); - } - - private void SyncState(Serializer ser) - { - byte[] core = null; - if (ser.IsWriter) - { - var ms = new MemoryStream(); - ms.Close(); - core = ms.ToArray(); - } - cpu.SyncState(ser); - mapper.SyncState(ser); - timer.SyncState(ser); - ppu.SyncState(ser); - audio.SyncState(ser); - - ser.BeginSection("Gameboy"); - ser.Sync("core", ref core, false); - ser.Sync("Lag", ref _lagcount); - ser.Sync("Frame", ref _frame); - ser.Sync("IsLag", ref _islag); - _controllerDeck.SyncState(ser); - - ser.Sync("controller_state", ref controller_state); - ser.Sync("controller_state_old", ref controller_state_old); - ser.Sync("in_vblank", ref in_vblank); - ser.Sync("in_vblank_old", ref in_vblank_old); - ser.Sync("vblank_rise", ref vblank_rise); - ser.Sync("GB_bios_register", ref GB_bios_register); - ser.Sync("input_register", ref input_register); - - ser.Sync("serial_control", ref serial_control); - ser.Sync("serial_data_out", ref serial_data_out); - ser.Sync("serial_data_in", ref serial_data_in); - ser.Sync("serial_start_old", ref serial_start_old); - - ser.Sync("REG_FFFF", ref REG_FFFF); - ser.Sync("REG_FF0F", ref REG_FF0F); - ser.Sync("enable_VBL", ref enable_VBL); - ser.Sync("enable_LCDC", ref enable_PRS); - ser.Sync("enable_TIMO", ref enable_TIMO); - ser.Sync("enable_SER", ref enable_SER); - ser.Sync("enable_STAT", ref enable_STAT); - - // memory domains - ser.Sync("RAM", ref RAM, false); - ser.Sync("ZP_RAM", ref ZP_RAM, false); - ser.Sync("CHR_RAM", ref CHR_RAM, false); - ser.Sync("BG_map_1", ref BG_map_1, false); - ser.Sync("BG_map_2", ref BG_map_2, false); - ser.Sync("OAM", ref OAM, false); - // probably a better way to do this - if (cart_RAM != null) - { - ser.Sync("cart_RAM", ref cart_RAM, false); - } - - - - ser.EndSection(); - } - } -} diff --git a/GBHawk.cs b/GBHawk.cs deleted file mode 100644 index 8a4ff534bf..0000000000 --- a/GBHawk.cs +++ /dev/null @@ -1,223 +0,0 @@ -using System; - -using BizHawk.Common.BufferExtensions; -using BizHawk.Emulation.Common; -using BizHawk.Emulation.Common.Components.LR35902; -using BizHawk.Common.NumberExtensions; - -namespace BizHawk.Emulation.Cores.Nintendo.GBHawk -{ - [Core( - "GBHawk", - "", - isPorted: false, - isReleased: true)] - [ServiceNotApplicable(typeof(ISettable<,>), typeof(IDriveLight))] - public partial class GBHawk : IEmulator, ISaveRam, IDebuggable, IStatable, IInputPollable, IRegionable, - ISettable - { - // this register controls whether or not the GB BIOS is mapped into memory - public byte GB_bios_register; - - public byte input_register; - - public byte serial_control; - public byte serial_data_out; - public byte serial_data_in; - public bool serial_start_old; - - // The unused bits in this register are still read/writable - public byte REG_FFFF; - // The unused bits in this register (interrupt flags) are always set - public byte REG_FF0F = 0xE0; - public bool enable_VBL; - public bool enable_STAT; - public bool enable_TIMO; - public bool enable_SER; - public bool enable_PRS; - - - // memory domains - public byte[] RAM = new byte[0x2000]; - public byte[] ZP_RAM = new byte[0x80]; - public byte[] CHR_RAM = new byte[0x1800]; - public byte[] BG_map_1 = new byte[0x400]; - public byte[] BG_map_2 = new byte[0x400]; - public byte[] OAM = new byte[0xA0]; - - public readonly byte[] _rom; - public readonly byte[] _bios; - public readonly byte[] _sram = new byte[2048]; - public readonly byte[] header = new byte[0x50]; - - public byte[] cart_RAM; - - private int _frame = 0; - - public MapperBase mapper; - - private readonly ITraceable _tracer; - - public LR35902 cpu; - public PPU ppu; - public Timer timer; - public Audio audio; - - [CoreConstructor("GB")] - public GBHawk(CoreComm comm, GameInfo game, byte[] rom, /*string gameDbFn,*/ object settings, object syncSettings) - { - var ser = new BasicServiceProvider(this); - - cpu = new LR35902 - { - ReadMemory = ReadMemory, - WriteMemory = WriteMemory, - PeekMemory = ReadMemory, - DummyReadMemory = ReadMemory, - OnExecFetch = ExecFetch - }; - ppu = new PPU(); - timer = new Timer(); - audio = new Audio(); - - CoreComm = comm; - - _settings = (GBSettings)settings ?? new GBSettings(); - _syncSettings = (GBSyncSettings)syncSettings ?? new GBSyncSettings(); - _controllerDeck = new GBHawkControllerDeck(_syncSettings.Port1); - - byte[] Bios = comm.CoreFileProvider.GetFirmware("GB", "World", false, "BIOS Not Found, Cannot Load"); - _bios = Bios; - - Buffer.BlockCopy(rom, 0x100, header, 0, 0x50); - - string hash_md5 = null; - hash_md5 = "md5:" + rom.HashMD5(0, rom.Length); - Console.WriteLine(hash_md5); - - _rom = rom; - Setup_Mapper(); - - _frameHz = 60; - - timer.Core = this; - audio.Core = this; - ppu.Core = this; - - ser.Register(this); - ser.Register(audio); - ServiceProvider = ser; - - _tracer = new TraceBuffer { Header = cpu.TraceHeader }; - ser.Register(_tracer); - - SetupMemoryDomains(); - HardReset(); - } - - public DisplayType Region => DisplayType.NTSC; - - private readonly GBHawkControllerDeck _controllerDeck; - - private void HardReset() - { - GB_bios_register = 0; // bios enable - in_vblank = true; // we start off in vblank since the LCD is off - in_vblank_old = true; - - Register_Reset(); - timer.Reset(); - ppu.Reset(); - - cpu.SetCallbacks(ReadMemory, ReadMemory, ReadMemory, WriteMemory); - - _vidbuffer = new int[VirtualWidth * VirtualHeight]; - } - - private void ExecFetch(ushort addr) - { - MemoryCallbacks.CallExecutes(addr); - } - - private void Setup_Mapper() - { - // setup up mapper based on header entry - switch (header[0x47]) - { - case 0x0: mapper = new MapperDefault(); break; - case 0x1: mapper = new MapperMBC1(); break; - case 0x2: mapper = new MapperMBC1(); break; - case 0x3: mapper = new MapperMBC1(); break; - case 0x5: mapper = new MapperMBC2(); break; - case 0x6: mapper = new MapperMBC2(); break; - case 0x8: mapper = new MapperDefault(); break; - case 0x9: mapper = new MapperDefault(); break; - case 0xB: mapper = new MapperMMM01(); break; - case 0xC: mapper = new MapperMMM01(); break; - case 0xD: mapper = new MapperMMM01(); break; - case 0xF: mapper = new MapperMBC3(); break; - case 0x10: mapper = new MapperMBC3(); break; - case 0x11: mapper = new MapperMBC3(); break; - case 0x12: mapper = new MapperMBC3(); break; - case 0x13: mapper = new MapperMBC3(); break; - case 0x19: mapper = new MapperMBC5(); break; - case 0x1A: mapper = new MapperMBC5(); break; - case 0x1B: mapper = new MapperMBC5(); break; - case 0x1C: mapper = new MapperMBC5(); break; - case 0x1D: mapper = new MapperMBC5(); break; - case 0x1E: mapper = new MapperMBC5(); break; - case 0x20: mapper = new MapperMBC6(); break; - case 0x22: mapper = new MapperMBC7(); break; - case 0xFC: mapper = new MapperCamera(); break; - case 0xFD: mapper = new MapperTAMA5(); break; - case 0xFE: mapper = new MapperHuC3(); break; - case 0xFF: mapper = new MapperHuC1(); break; - - case 0x4: - case 0x7: - case 0xA: - case 0xE: - case 0x14: - case 0x15: - case 0x16: - case 0x17: - case 0x18: - case 0x1F: - case 0x21: - default: - // mapper not implemented - throw new Exception("Mapper not implemented"); - break; - - } - - Console.Write("Mapper: "); - Console.WriteLine(header[0x47]); - - cart_RAM = null; - - switch (header[0x49]) - { - case 1: - cart_RAM = new byte[0x800]; - break; - case 2: - cart_RAM = new byte[0x2000]; - break; - case 3: - cart_RAM = new byte[0x8000]; - break; - case 4: - cart_RAM = new byte[0x20000]; - break; - case 5: - cart_RAM = new byte[0x10000]; - break; - - } - - mapper.Core = this; - mapper.Initialize(); - } - } -} diff --git a/GBHawkControllerDeck.cs b/GBHawkControllerDeck.cs deleted file mode 100644 index 464c4bfdcb..0000000000 --- a/GBHawkControllerDeck.cs +++ /dev/null @@ -1,76 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -using BizHawk.Common; -using BizHawk.Common.ReflectionExtensions; -using BizHawk.Emulation.Common; - -namespace BizHawk.Emulation.Cores.Nintendo.GBHawk -{ - public class GBHawkControllerDeck - { - public GBHawkControllerDeck(string controller1Name) - { - if (!ValidControllerTypes.ContainsKey(controller1Name)) - { - throw new InvalidOperationException("Invalid controller type: " + controller1Name); - } - - Port1 = (IPort)Activator.CreateInstance(ValidControllerTypes[controller1Name], 1); - - Definition = new ControllerDefinition - { - Name = Port1.Definition.Name, - BoolButtons = Port1.Definition.BoolButtons - .Concat(new[] - { - "Power", - "Reset", - }) - .ToList() - }; - - Definition.FloatControls.AddRange(Port1.Definition.FloatControls); - - Definition.FloatRanges.AddRange(Port1.Definition.FloatRanges); - } - - public byte ReadPort1(IController c) - { - return Port1.Read(c); - } - - public ControllerDefinition Definition { get; } - - public void SyncState(Serializer ser) - { - ser.BeginSection("Port1"); - Port1.SyncState(ser); - ser.EndSection(); - } - - private readonly IPort Port1; - - private static Dictionary _controllerTypes; - - public static Dictionary ValidControllerTypes - { - get - { - if (_controllerTypes == null) - { - _controllerTypes = typeof(GBHawkControllerDeck).Assembly - .GetTypes() - .Where(t => typeof(IPort).IsAssignableFrom(t)) - .Where(t => !t.IsAbstract && !t.IsInterface) - .ToDictionary(tkey => tkey.DisplayName()); - } - - return _controllerTypes; - } - } - - public static string DefaultControllerName => typeof(StandardControls).DisplayName(); - } -} diff --git a/GBHawkControllers.cs b/GBHawkControllers.cs deleted file mode 100644 index af504834c7..0000000000 --- a/GBHawkControllers.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; - -using BizHawk.Common; -using BizHawk.Emulation.Common; - -namespace BizHawk.Emulation.Cores.Nintendo.GBHawk -{ - /// - /// Represents a GB add on - /// - public interface IPort - { - byte Read(IController c); - - ControllerDefinition Definition { get; } - - void SyncState(Serializer ser); - - int PortNum { get; } - } - - [DisplayName("Standard controls")] - public class StandardControls : IPort - { - public StandardControls(int portNum) - { - PortNum = portNum; - Definition = new ControllerDefinition - { - Name = "Game Boy", - BoolButtons = BaseDefinition - .Select(b => "P" + PortNum + " " + b) - .ToList() - }; - } - - public int PortNum { get; } - - public ControllerDefinition Definition { get; } - - public byte Read(IController c) - { - byte result = 0xFF; - for (int i = 0; i < 8; i++) - { - if (c.IsPressed(Definition.BoolButtons[i])) - { - result -= (byte)(1 << i); - } - } - - return result; - } - - private static readonly string[] BaseDefinition = - { - "Right", "Left", "Up", "Down", "A", "B", "Select", "Start" - }; - - public void SyncState(Serializer ser) - { - //nothing - } - } -} \ No newline at end of file diff --git a/HW_Registers.cs b/HW_Registers.cs deleted file mode 100644 index 3e71185e35..0000000000 --- a/HW_Registers.cs +++ /dev/null @@ -1,283 +0,0 @@ -using System; -using BizHawk.Emulation.Common; -using BizHawk.Common.NumberExtensions; -using BizHawk.Common; - -namespace BizHawk.Emulation.Cores.Nintendo.GBHawk -{ - public partial class GBHawk - { - public byte Read_Registers(int addr) - { - byte ret = 0; - - switch (addr) - { - // Read Input - case 0xFF00: - _islag = false; - - input_register &= 0xF0; - if ((input_register & 0x30) == 0x20) - { - input_register |= (byte)(controller_state & 0xF); - } - else if ((input_register & 0x30) == 0x10) - { - input_register |= (byte)((controller_state & 0xF0) >> 4); - } - else if ((input_register & 0x30) == 0x30) - { - // if both polls are set, then a bit is zero if either or both pins are zero - byte temp = (byte)((controller_state & 0xF) & ((controller_state & 0xF0) >> 4)); - input_register |= temp; - } - else - { - input_register |= 0xF; - } - ret = input_register; - break; - - // Serial data port - case 0xFF01: - ret = serial_data_in; - break; - - // Serial port control - case 0xFF02: - ret = serial_control; - break; - - // Timer Registers - case 0xFF04: - case 0xFF05: - case 0xFF06: - case 0xFF07: - ret = timer.ReadReg(addr); - break; - - // Interrupt flags - case 0xFF0F: - ret = REG_FF0F; - break; - - // audio regs - case 0xFF10: - case 0xFF11: - case 0xFF12: - case 0xFF13: - case 0xFF14: - case 0xFF16: - case 0xFF17: - case 0xFF18: - case 0xFF19: - case 0xFF1A: - case 0xFF1B: - case 0xFF1C: - case 0xFF1D: - case 0xFF1E: - case 0xFF20: - case 0xFF21: - case 0xFF22: - case 0xFF23: - case 0xFF24: - case 0xFF25: - case 0xFF26: - case 0xFF30: - case 0xFF31: - case 0xFF32: - case 0xFF33: - case 0xFF34: - case 0xFF35: - case 0xFF36: - case 0xFF37: - case 0xFF38: - case 0xFF39: - case 0xFF3A: - case 0xFF3B: - case 0xFF3C: - case 0xFF3D: - case 0xFF3E: - case 0xFF3F: - ret = audio.ReadReg(addr); - break; - - // PPU Regs - case 0xFF40: - case 0xFF41: - case 0xFF42: - case 0xFF43: - case 0xFF44: - case 0xFF45: - case 0xFF46: - case 0xFF47: - case 0xFF48: - case 0xFF49: - case 0xFF4A: - case 0xFF4B: - ret = ppu.ReadReg(addr); - break; - - // Bios control register. Not sure if it is readable - case 0xFF50: - ret = 0xFF; - break; - - // interrupt control register - case 0xFFFF: - ret = REG_FFFF; - break; - - default: - ret = 0xFF; - break; - - } - return ret; - } - - public void Write_Registers(int addr, byte value) - { - switch (addr) - { - // select input - case 0xFF00: - input_register = (byte)(0xC0 | (value & 0x3F)); // top 2 bits always 1 - break; - - // Serial data port - case 0xFF01: - serial_data_out = value; - serial_data_in = serial_data_out; - break; - - // Serial port control - case 0xFF02: - serial_control = (byte)(0x7E | (value & 0x81)); // middle six bits always 1 - break; - - // Timer Registers - case 0xFF04: - case 0xFF05: - case 0xFF06: - case 0xFF07: - timer.WriteReg(addr, value); - break; - - // Interrupt flags - case 0xFF0F: - REG_FF0F = (byte)(0xE0 | value); - - // check if enabling any of the bits triggered an IRQ - for (int i = 0; i < 5; i++) - { - if (REG_FFFF.Bit(i) && REG_FF0F.Bit(i)) - { - cpu.FlagI = true; - } - } - - // if no bits are in common between flags and enables, de-assert the IRQ - if (((REG_FF0F & 0x1F) & REG_FFFF) == 0) { cpu.FlagI = false; } - - break; - - // audio regs - case 0xFF10: - case 0xFF11: - case 0xFF12: - case 0xFF13: - case 0xFF14: - case 0xFF16: - case 0xFF17: - case 0xFF18: - case 0xFF19: - case 0xFF1A: - case 0xFF1B: - case 0xFF1C: - case 0xFF1D: - case 0xFF1E: - case 0xFF20: - case 0xFF21: - case 0xFF22: - case 0xFF23: - case 0xFF24: - case 0xFF25: - case 0xFF26: - case 0xFF30: - case 0xFF31: - case 0xFF32: - case 0xFF33: - case 0xFF34: - case 0xFF35: - case 0xFF36: - case 0xFF37: - case 0xFF38: - case 0xFF39: - case 0xFF3A: - case 0xFF3B: - case 0xFF3C: - case 0xFF3D: - case 0xFF3E: - case 0xFF3F: - audio.WriteReg(addr, value); - break; - - // PPU Regs - case 0xFF40: - case 0xFF41: - case 0xFF42: - case 0xFF43: - case 0xFF44: - case 0xFF45: - case 0xFF46: - case 0xFF47: - case 0xFF48: - case 0xFF49: - case 0xFF4A: - case 0xFF4B: - ppu.WriteReg(addr, value); - break; - - // Bios control register. Writing 1 permanently disables BIOS until a power cycle occurs - case 0xFF50: - //Console.WriteLine(value); - if (GB_bios_register != 1) - { - GB_bios_register = value; - } - break; - - // interrupt control register - case 0xFFFF: - REG_FFFF = value; - enable_VBL = REG_FFFF.Bit(0); - enable_STAT = REG_FFFF.Bit(1); - enable_TIMO = REG_FFFF.Bit(2); - enable_SER = REG_FFFF.Bit(3); - enable_PRS = REG_FFFF.Bit(4); - - // check if enabling any of the bits triggered an IRQ - for (int i = 0; i < 5; i++) - { - if (REG_FFFF.Bit(i) && REG_FF0F.Bit(i)) - { - cpu.FlagI = true; - } - } - - // if no bits are in common between flags and enables, de-assert the IRQ - if (((REG_FF0F & 0x1F) & REG_FFFF) == 0) { cpu.FlagI = false; } - - break; - } - } - - public void Register_Reset() - { - input_register = 0xCF; // not reading any input - serial_control = 0x7E; - } - } -} diff --git a/Mappers/MapperBase.cs b/Mappers/MapperBase.cs deleted file mode 100644 index f7aeb7ddca..0000000000 --- a/Mappers/MapperBase.cs +++ /dev/null @@ -1,40 +0,0 @@ -using BizHawk.Common; -using System; - -namespace BizHawk.Emulation.Cores.Nintendo.GBHawk -{ - public class MapperBase - { - public GBHawk Core { get; set; } - - public virtual byte ReadMemory(ushort addr) - { - return 0; - } - - public virtual byte PeekMemory(ushort addr) - { - return 0; - } - - public virtual void WriteMemory(ushort addr, byte value) - { - } - - public virtual void PokeMemory(ushort addr, byte value) - { - } - - public virtual void SyncState(Serializer ser) - { - } - - public virtual void Dispose() - { - } - - public virtual void Initialize() - { - } - } -} diff --git a/Mappers/Mapper_Camera.cs b/Mappers/Mapper_Camera.cs deleted file mode 100644 index e247725259..0000000000 --- a/Mappers/Mapper_Camera.cs +++ /dev/null @@ -1,59 +0,0 @@ -using BizHawk.Common; -using BizHawk.Common.NumberExtensions; -using System; - -namespace BizHawk.Emulation.Cores.Nintendo.GBHawk -{ - // Default mapper with no bank switching - public class MapperCamera : MapperBase - { - public override void Initialize() - { - // nothing to initialize - } - - public override byte ReadMemory(ushort addr) - { - if (addr < 0x8000) - { - return Core._rom[addr]; - } - else - { - if (Core.cart_RAM != null) - { - return Core.cart_RAM[addr - 0xA000]; - } - else - { - return 0; - } - } - } - - public override byte PeekMemory(ushort addr) - { - return ReadMemory(addr); - } - - public override void WriteMemory(ushort addr, byte value) - { - if (addr < 0x8000) - { - // no mapping hardware available - } - else - { - if (Core.cart_RAM != null) - { - Core.cart_RAM[addr - 0xA000] = value; - } - } - } - - public override void PokeMemory(ushort addr, byte value) - { - WriteMemory(addr, value); - } - } -} diff --git a/Mappers/Mapper_Default.cs b/Mappers/Mapper_Default.cs deleted file mode 100644 index 609a696040..0000000000 --- a/Mappers/Mapper_Default.cs +++ /dev/null @@ -1,59 +0,0 @@ -using BizHawk.Common; -using BizHawk.Common.NumberExtensions; -using System; - -namespace BizHawk.Emulation.Cores.Nintendo.GBHawk -{ - // Default mapper with no bank switching - public class MapperDefault : MapperBase - { - public override void Initialize() - { - // nothing to initialize - } - - public override byte ReadMemory(ushort addr) - { - if (addr < 0x8000) - { - return Core._rom[addr]; - } - else - { - if (Core.cart_RAM != null) - { - return Core.cart_RAM[addr - 0xA000]; - } - else - { - return 0; - } - } - } - - public override byte PeekMemory(ushort addr) - { - return ReadMemory(addr); - } - - public override void WriteMemory(ushort addr, byte value) - { - if (addr < 0x8000) - { - // no mapping hardware available - } - else - { - if (Core.cart_RAM != null) - { - Core.cart_RAM[addr - 0xA000] = value; - } - } - } - - public override void PokeMemory(ushort addr, byte value) - { - WriteMemory(addr, value); - } - } -} diff --git a/Mappers/Mapper_HuC1.cs b/Mappers/Mapper_HuC1.cs deleted file mode 100644 index 0e33db1474..0000000000 --- a/Mappers/Mapper_HuC1.cs +++ /dev/null @@ -1,59 +0,0 @@ -using BizHawk.Common; -using BizHawk.Common.NumberExtensions; -using System; - -namespace BizHawk.Emulation.Cores.Nintendo.GBHawk -{ - // Default mapper with no bank switching - public class MapperHuC1 : MapperBase - { - public override void Initialize() - { - // nothing to initialize - } - - public override byte ReadMemory(ushort addr) - { - if (addr < 0x8000) - { - return Core._rom[addr]; - } - else - { - if (Core.cart_RAM != null) - { - return Core.cart_RAM[addr - 0xA000]; - } - else - { - return 0; - } - } - } - - public override byte PeekMemory(ushort addr) - { - return ReadMemory(addr); - } - - public override void WriteMemory(ushort addr, byte value) - { - if (addr < 0x8000) - { - // no mapping hardware available - } - else - { - if (Core.cart_RAM != null) - { - Core.cart_RAM[addr - 0xA000] = value; - } - } - } - - public override void PokeMemory(ushort addr, byte value) - { - WriteMemory(addr, value); - } - } -} diff --git a/Mappers/Mapper_HuC3.cs b/Mappers/Mapper_HuC3.cs deleted file mode 100644 index ff0e5cc6d1..0000000000 --- a/Mappers/Mapper_HuC3.cs +++ /dev/null @@ -1,59 +0,0 @@ -using BizHawk.Common; -using BizHawk.Common.NumberExtensions; -using System; - -namespace BizHawk.Emulation.Cores.Nintendo.GBHawk -{ - // Default mapper with no bank switching - public class MapperHuC3 : MapperBase - { - public override void Initialize() - { - // nothing to initialize - } - - public override byte ReadMemory(ushort addr) - { - if (addr < 0x8000) - { - return Core._rom[addr]; - } - else - { - if (Core.cart_RAM != null) - { - return Core.cart_RAM[addr - 0xA000]; - } - else - { - return 0; - } - } - } - - public override byte PeekMemory(ushort addr) - { - return ReadMemory(addr); - } - - public override void WriteMemory(ushort addr, byte value) - { - if (addr < 0x8000) - { - // no mapping hardware available - } - else - { - if (Core.cart_RAM != null) - { - Core.cart_RAM[addr - 0xA000] = value; - } - } - } - - public override void PokeMemory(ushort addr, byte value) - { - WriteMemory(addr, value); - } - } -} diff --git a/Mappers/Mapper_MBC1.cs b/Mappers/Mapper_MBC1.cs deleted file mode 100644 index 2a8bed26be..0000000000 --- a/Mappers/Mapper_MBC1.cs +++ /dev/null @@ -1,130 +0,0 @@ -using BizHawk.Common; -using BizHawk.Common.NumberExtensions; -using System; - -namespace BizHawk.Emulation.Cores.Nintendo.GBHawk -{ - // MBC1 with bank switching and RAM - public class MapperMBC1 : MapperBase - { - public int ROM_bank; - public int RAM_bank; - public bool RAM_enable; - public bool sel_mode; - - public override void Initialize() - { - ROM_bank = 1; - RAM_bank = 0; - RAM_enable = false; - sel_mode = false; - } - - public override byte ReadMemory(ushort addr) - { - if (addr < 0x4000) - { - // lowest bank is fixed - return Core._rom[addr]; - } - else if (addr < 0x8000) - { - return Core._rom[(addr - 0x4000) + ROM_bank * 0x4000]; - } - else - { - if (Core.cart_RAM != null) - { - if (RAM_enable) - { - return Core.cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000]; - } - else - { - return 0; - } - - } - else - { - return 0; - } - } - } - - public override byte PeekMemory(ushort addr) - { - return ReadMemory(addr); - } - - public override void WriteMemory(ushort addr, byte value) - { - if (addr < 0x8000) - { - if (addr < 0x2000) - { - RAM_enable = ((value & 0xA) == 0xA) ? true : false; - } - else if (addr < 0x4000) - { - value &= 0x1F; - - // writing zero gets translated to 1 - if (value == 0) { value = 1; } - - ROM_bank &= 0xE0; - ROM_bank |= value; - } - else if (addr < 0x6000) - { - if (sel_mode) - { - RAM_bank = value & 0x3; - } - else - { - ROM_bank &= 0x1F; - ROM_bank |= ((value & 3) << 5); - } - } - else - { - sel_mode = (value & 1) > 0; - - if (sel_mode) - { - ROM_bank &= 0x1F; - } - else - { - RAM_bank = 0; - } - } - } - else - { - if (Core.cart_RAM != null) - { - if (RAM_enable) - { - Core.cart_RAM[(addr - 0xA000) + RAM_bank * 0x2000] = value; - } - - } - } - } - - public override void PokeMemory(ushort addr, byte value) - { - WriteMemory(addr, value); - } - - public override void SyncState(Serializer ser) - { - ser.Sync("ROM_Bank", ref ROM_bank); - ser.Sync("RAM_Bank", ref RAM_bank); - ser.Sync("RAM_enable", ref RAM_enable); - ser.Sync("sel_mode", ref sel_mode); - } - } -} diff --git a/Mappers/Mapper_MBC2.cs b/Mappers/Mapper_MBC2.cs deleted file mode 100644 index 3130aaa469..0000000000 --- a/Mappers/Mapper_MBC2.cs +++ /dev/null @@ -1,59 +0,0 @@ -using BizHawk.Common; -using BizHawk.Common.NumberExtensions; -using System; - -namespace BizHawk.Emulation.Cores.Nintendo.GBHawk -{ - // Default mapper with no bank switching - public class MapperMBC2 : MapperBase - { - public override void Initialize() - { - // nothing to initialize - } - - public override byte ReadMemory(ushort addr) - { - if (addr < 0x8000) - { - return Core._rom[addr]; - } - else - { - if (Core.cart_RAM != null) - { - return Core.cart_RAM[addr - 0xA000]; - } - else - { - return 0; - } - } - } - - public override byte PeekMemory(ushort addr) - { - return ReadMemory(addr); - } - - public override void WriteMemory(ushort addr, byte value) - { - if (addr < 0x8000) - { - // no mapping hardware available - } - else - { - if (Core.cart_RAM != null) - { - Core.cart_RAM[addr - 0xA000] = value; - } - } - } - - public override void PokeMemory(ushort addr, byte value) - { - WriteMemory(addr, value); - } - } -} diff --git a/Mappers/Mapper_MBC3.cs b/Mappers/Mapper_MBC3.cs deleted file mode 100644 index 961f1769e4..0000000000 --- a/Mappers/Mapper_MBC3.cs +++ /dev/null @@ -1,59 +0,0 @@ -using BizHawk.Common; -using BizHawk.Common.NumberExtensions; -using System; - -namespace BizHawk.Emulation.Cores.Nintendo.GBHawk -{ - // Default mapper with no bank switching - public class MapperMBC3 : MapperBase - { - public override void Initialize() - { - // nothing to initialize - } - - public override byte ReadMemory(ushort addr) - { - if (addr < 0x8000) - { - return Core._rom[addr]; - } - else - { - if (Core.cart_RAM != null) - { - return Core.cart_RAM[addr - 0xA000]; - } - else - { - return 0; - } - } - } - - public override byte PeekMemory(ushort addr) - { - return ReadMemory(addr); - } - - public override void WriteMemory(ushort addr, byte value) - { - if (addr < 0x8000) - { - // no mapping hardware available - } - else - { - if (Core.cart_RAM != null) - { - Core.cart_RAM[addr - 0xA000] = value; - } - } - } - - public override void PokeMemory(ushort addr, byte value) - { - WriteMemory(addr, value); - } - } -} diff --git a/Mappers/Mapper_MBC5.cs b/Mappers/Mapper_MBC5.cs deleted file mode 100644 index 312c9dc108..0000000000 --- a/Mappers/Mapper_MBC5.cs +++ /dev/null @@ -1,59 +0,0 @@ -using BizHawk.Common; -using BizHawk.Common.NumberExtensions; -using System; - -namespace BizHawk.Emulation.Cores.Nintendo.GBHawk -{ - // Default mapper with no bank switching - public class MapperMBC5 : MapperBase - { - public override void Initialize() - { - // nothing to initialize - } - - public override byte ReadMemory(ushort addr) - { - if (addr < 0x8000) - { - return Core._rom[addr]; - } - else - { - if (Core.cart_RAM != null) - { - return Core.cart_RAM[addr - 0xA000]; - } - else - { - return 0; - } - } - } - - public override byte PeekMemory(ushort addr) - { - return ReadMemory(addr); - } - - public override void WriteMemory(ushort addr, byte value) - { - if (addr < 0x8000) - { - // no mapping hardware available - } - else - { - if (Core.cart_RAM != null) - { - Core.cart_RAM[addr - 0xA000] = value; - } - } - } - - public override void PokeMemory(ushort addr, byte value) - { - WriteMemory(addr, value); - } - } -} diff --git a/Mappers/Mapper_MBC6.cs b/Mappers/Mapper_MBC6.cs deleted file mode 100644 index 7f9624adb9..0000000000 --- a/Mappers/Mapper_MBC6.cs +++ /dev/null @@ -1,59 +0,0 @@ -using BizHawk.Common; -using BizHawk.Common.NumberExtensions; -using System; - -namespace BizHawk.Emulation.Cores.Nintendo.GBHawk -{ - // Default mapper with no bank switching - public class MapperMBC6 : MapperBase - { - public override void Initialize() - { - // nothing to initialize - } - - public override byte ReadMemory(ushort addr) - { - if (addr < 0x8000) - { - return Core._rom[addr]; - } - else - { - if (Core.cart_RAM != null) - { - return Core.cart_RAM[addr - 0xA000]; - } - else - { - return 0; - } - } - } - - public override byte PeekMemory(ushort addr) - { - return ReadMemory(addr); - } - - public override void WriteMemory(ushort addr, byte value) - { - if (addr < 0x8000) - { - // no mapping hardware available - } - else - { - if (Core.cart_RAM != null) - { - Core.cart_RAM[addr - 0xA000] = value; - } - } - } - - public override void PokeMemory(ushort addr, byte value) - { - WriteMemory(addr, value); - } - } -} diff --git a/Mappers/Mapper_MBC7.cs b/Mappers/Mapper_MBC7.cs deleted file mode 100644 index 40c9513b8b..0000000000 --- a/Mappers/Mapper_MBC7.cs +++ /dev/null @@ -1,59 +0,0 @@ -using BizHawk.Common; -using BizHawk.Common.NumberExtensions; -using System; - -namespace BizHawk.Emulation.Cores.Nintendo.GBHawk -{ - // Default mapper with no bank switching - public class MapperMBC7 : MapperBase - { - public override void Initialize() - { - // nothing to initialize - } - - public override byte ReadMemory(ushort addr) - { - if (addr < 0x8000) - { - return Core._rom[addr]; - } - else - { - if (Core.cart_RAM != null) - { - return Core.cart_RAM[addr - 0xA000]; - } - else - { - return 0; - } - } - } - - public override byte PeekMemory(ushort addr) - { - return ReadMemory(addr); - } - - public override void WriteMemory(ushort addr, byte value) - { - if (addr < 0x8000) - { - // no mapping hardware available - } - else - { - if (Core.cart_RAM != null) - { - Core.cart_RAM[addr - 0xA000] = value; - } - } - } - - public override void PokeMemory(ushort addr, byte value) - { - WriteMemory(addr, value); - } - } -} diff --git a/Mappers/Mapper_MMM01.cs b/Mappers/Mapper_MMM01.cs deleted file mode 100644 index 86c07e20ca..0000000000 --- a/Mappers/Mapper_MMM01.cs +++ /dev/null @@ -1,59 +0,0 @@ -using BizHawk.Common; -using BizHawk.Common.NumberExtensions; -using System; - -namespace BizHawk.Emulation.Cores.Nintendo.GBHawk -{ - // Default mapper with no bank switching - public class MapperMMM01 : MapperBase - { - public override void Initialize() - { - // nothing to initialize - } - - public override byte ReadMemory(ushort addr) - { - if (addr < 0x8000) - { - return Core._rom[addr]; - } - else - { - if (Core.cart_RAM != null) - { - return Core.cart_RAM[addr - 0xA000]; - } - else - { - return 0; - } - } - } - - public override byte PeekMemory(ushort addr) - { - return ReadMemory(addr); - } - - public override void WriteMemory(ushort addr, byte value) - { - if (addr < 0x8000) - { - // no mapping hardware available - } - else - { - if (Core.cart_RAM != null) - { - Core.cart_RAM[addr - 0xA000] = value; - } - } - } - - public override void PokeMemory(ushort addr, byte value) - { - WriteMemory(addr, value); - } - } -} diff --git a/Mappers/Mapper_TAMA5.cs b/Mappers/Mapper_TAMA5.cs deleted file mode 100644 index eed5909336..0000000000 --- a/Mappers/Mapper_TAMA5.cs +++ /dev/null @@ -1,59 +0,0 @@ -using BizHawk.Common; -using BizHawk.Common.NumberExtensions; -using System; - -namespace BizHawk.Emulation.Cores.Nintendo.GBHawk -{ - // Default mapper with no bank switching - public class MapperTAMA5 : MapperBase - { - public override void Initialize() - { - // nothing to initialize - } - - public override byte ReadMemory(ushort addr) - { - if (addr < 0x8000) - { - return Core._rom[addr]; - } - else - { - if (Core.cart_RAM != null) - { - return Core.cart_RAM[addr - 0xA000]; - } - else - { - return 0; - } - } - } - - public override byte PeekMemory(ushort addr) - { - return ReadMemory(addr); - } - - public override void WriteMemory(ushort addr, byte value) - { - if (addr < 0x8000) - { - // no mapping hardware available - } - else - { - if (Core.cart_RAM != null) - { - Core.cart_RAM[addr - 0xA000] = value; - } - } - } - - public override void PokeMemory(ushort addr, byte value) - { - WriteMemory(addr, value); - } - } -} diff --git a/Mappers/ReadMe.txt b/Mappers/ReadMe.txt deleted file mode 100644 index 0c94c8272c..0000000000 --- a/Mappers/ReadMe.txt +++ /dev/null @@ -1,3 +0,0 @@ -TODO: -Official Mappers -Unofficial Mappers diff --git a/MemoryMap.cs b/MemoryMap.cs deleted file mode 100644 index 8357ebe073..0000000000 --- a/MemoryMap.cs +++ /dev/null @@ -1,164 +0,0 @@ -using System; - -using BizHawk.Common.BufferExtensions; -using BizHawk.Emulation.Common; - - -/* - $FFFF Interrupt Enable Flag - $FF80-$FFFE Zero Page - 127 bytes - $FF00-$FF7F Hardware I/O Registers - $FEA0-$FEFF Unusable Memory - $FE00-$FE9F OAM - Object Attribute Memory - $E000-$FDFF Echo RAM - Reserved, Do Not Use - $D000-$DFFF Internal RAM - Bank 1-7 (switchable - CGB only) - $C000-$CFFF Internal RAM - Bank 0 (fixed) - $A000-$BFFF Cartridge RAM (If Available) - $9C00-$9FFF BG Map Data 2 - $9800-$9BFF BG Map Data 1 - $8000-$97FF Character RAM - $4000-$7FFF Cartridge ROM - Switchable Banks 1-xx - $0150-$3FFF Cartridge ROM - Bank 0 (fixed) - $0100-$014F Cartridge Header Area - $0000-$00FF Restart and Interrupt Vectors -*/ - -namespace BizHawk.Emulation.Cores.Nintendo.GBHawk -{ - public partial class GBHawk - { - public byte ReadMemory(ushort addr) - { - MemoryCallbacks.CallReads(addr); - - if (addr < 0x100) - { - // return Either BIOS ROM or Game ROM - if ((GB_bios_register & 0x1) == 0) - { - return _bios[addr]; // Return BIOS - } - else - { - return mapper.ReadMemory(addr); - } - } - else if (addr < 0x8000) - { - return mapper.ReadMemory(addr); - } - else if (addr < 0x9800) - { - return CHR_RAM[addr - 0x8000]; - } - else if (addr < 0x9C00) - { - return BG_map_1[addr - 0x9800]; - } - else if (addr < 0xA000) - { - return BG_map_2[addr - 0x9C00]; - } - else if (addr < 0xC000) - { - return mapper.ReadMemory(addr); - } - else if (addr < 0xE000) - { - return RAM[addr - 0xC000]; - } - else if (addr < 0xFE00) - { - return RAM[addr - 0xE000]; - } - else if (addr < 0xFEA0 && ppu.OAM_access) - { - return OAM[addr - 0xFE00]; - } - else if (addr < 0xFF00) - { - // unmapped memory, returns 0xFF - return 0xFF; - } - else if (addr < 0xFF80) - { - return Read_Registers(addr); - } - else if (addr < 0xFFFF) - { - return ZP_RAM[addr - 0xFF80]; - } - else - { - return Read_Registers(addr); - } - - } - - public void WriteMemory(ushort addr, byte value) - { - MemoryCallbacks.CallWrites(addr); - - if (addr < 0x100) - { - // return Either BIOS ROM or Game ROM - if ((GB_bios_register & 0x1) == 0) - { - // Can't write to BIOS region - } - else - { - mapper.WriteMemory(addr, value); - } - } - else if (addr < 0x8000) - { - mapper.WriteMemory(addr, value); - } - else if (addr < 0x9800) - { - CHR_RAM[addr - 0x8000] = value; - } - else if (addr < 0x9C00) - { - BG_map_1[addr - 0x9800] = value; - } - else if (addr < 0xA000) - { - BG_map_2[addr - 0x9C00] = value; - } - else if (addr < 0xC000) - { - mapper.WriteMemory(addr, value); - } - else if (addr < 0xE000) - { - RAM[addr - 0xC000] = value; - } - else if (addr < 0xFE00) - { - RAM[addr - 0xE000] = value; - } - else if (addr < 0xFEA0 && ppu.OAM_access) - { - OAM[addr - 0xFE00] = value; - } - else if (addr < 0xFF00) - { - // unmapped, writing has no effect - } - else if (addr < 0xFF80) - { - Write_Registers(addr, value); - } - else if (addr < 0xFFFF) - { - ZP_RAM[addr - 0xFF80] = value; - } - else - { - Write_Registers(addr, value); - } - } - } -} diff --git a/PPU.cs b/PPU.cs deleted file mode 100644 index 9170cf1128..0000000000 --- a/PPU.cs +++ /dev/null @@ -1,922 +0,0 @@ -using System; -using BizHawk.Emulation.Common; -using BizHawk.Common.NumberExtensions; -using BizHawk.Common; - -namespace BizHawk.Emulation.Cores.Nintendo.GBHawk -{ - public class PPU - { - public GBHawk Core { get; set; } - - //public byte BGP_l; - - // register variables - public byte LCDC; - public byte STAT; - public byte scroll_y; - public byte scroll_x; - public byte LY; - public byte LY_inc; - public byte LYC; - public byte DMA_addr; - public byte BGP; - public byte obj_pal_0; - public byte obj_pal_1; - public byte window_y; - public byte window_x; - public bool DMA_start; - public int DMA_clock; - public int DMA_inc; - public byte DMA_byte; - - // state variables - public int cycle; - public bool LYC_INT; - public bool HBL_INT; - public bool VBL_INT; - public bool OAM_INT; - public bool LCD_was_off; - public bool stat_line; - public bool stat_line_old; - public bool hbl_set_once; - // OAM scan - public bool OAM_access; - public int OAM_scan_index; - public int SL_sprites_index; - public int[] SL_sprites = new int[40]; - public int write_sprite; - // render - public bool VRAM_access; - public int read_case; - public int internal_cycle; - public int y_tile; - public int y_scroll_offset; - public int x_tile; - public int x_scroll_offset; - public int tile_byte; - public int sprite_fetch_cycles; - public bool fetch_sprite; - public int temp_fetch; - public int tile_inc; - public bool pre_render; - public byte[] tile_data = new byte[2]; - public byte[] tile_data_latch = new byte[2]; - public int latch_counter; - public bool latch_new_data; - public int render_counter; - public int render_offset; - public int pixel_counter; - public int pixel; - public byte[] sprite_data = new byte[2]; - public byte[] sprite_sel = new byte[2]; - public int sl_use_index; - public bool no_sprites; - public int sprite_fetch_index; - public int[] SL_sprites_ordered = new int[40]; // (x_end, data_low, data_high, attr) - public int index_used; - public int sprite_ordered_index; - public int bottom_index; - - public byte ReadReg(int addr) - { - byte ret = 0; - - switch (addr) - { - case 0xFF40: ret = LCDC; break; // LCDC - case 0xFF41: ret = STAT; break; // STAT - case 0xFF42: ret = scroll_y; break; // SCY - case 0xFF43: ret = scroll_x; break; // SCX - case 0xFF44: ret = LY; break; // LY - case 0xFF45: ret = LYC; break; // LYC - case 0xFF46: /*ret = DMA_addr; */ break; // DMA (not readable?) - case 0xFF47: ret = BGP; break; // BGP - case 0xFF48: ret = obj_pal_0; break; // OBP0 - case 0xFF49: ret = obj_pal_1; break; // OBP1 - case 0xFF4A: ret = window_y; break; // WY - case 0xFF4B: ret = window_x; break; // WX - } - - return ret; - } - - public void WriteReg(int addr, byte value) - { - switch (addr) - { - case 0xFF40: // LCDC - LCDC = value; - break; - case 0xFF41: // STAT - STAT = (byte)((value & 0xF8) | (STAT & 7) | 0x80); - break; - case 0xFF42: // SCY - scroll_y = value; - break; - case 0xFF43: // SCX - scroll_x = value; - // calculate the column number of the tile to start with - x_tile = (int)Math.Floor((float)(scroll_x) / 8); - break; - case 0xFF44: // LY - LY = 0; /*reset*/ - break; - case 0xFF45: // LYC - LYC = value; - if (LY != LYC) { STAT &= 0xFB; } - break; - case 0xFF46: // DMA - DMA_addr = value; - DMA_start = true; - DMA_clock = 0; - DMA_inc = 0; - break; - case 0xFF47: // BGP - BGP = value; - break; - case 0xFF48: // OBP0 - obj_pal_0 = value; - break; - case 0xFF49: // OBP1 - obj_pal_1 = value; - break; - case 0xFF4A: // WY - window_y = value; - break; - case 0xFF4B: // WX - window_x = value; - break; - } - } - - public void tick() - { - // tick DMA - if (DMA_start) - { - if (DMA_clock >= 4) - { - OAM_access = false; - if ((DMA_clock % 4) == 1) - { - // the cpu can't access memory during this time, but we still need the ppu to be able to. - DMA_start = false; - DMA_byte = Core.ReadMemory((ushort)((DMA_addr << 8) + DMA_inc)); - DMA_start = true; - } - else if ((DMA_clock % 4) == 3) - { - if ((DMA_inc % 4) == 3) - { - Core.OAM[DMA_inc] = DMA_byte; - } - else - { - Core.OAM[DMA_inc] = DMA_byte; - } - - if (DMA_inc < (0xA0 - 1)) { DMA_inc++; } - } - } - - DMA_clock++; - - if (DMA_clock==648) - { - DMA_start = false; - OAM_access = true; - } - } - - // the ppu only does anything if it is turned on via bit 7 of LCDC - if (LCDC.Bit(7)) - { - // exit vblank if LCD went from off to on - if (LCD_was_off) - { - //VBL_INT = false; - Core.in_vblank = false; - LCD_was_off = false; - - // we exit vblank into mode 0 for 4 cycles - // but no hblank interrupt, presumably this only happens transitioning from mode 3 to 0 - STAT &= 0xFC; - } - - // the VBL stat is continuously asserted - if ((LY >= 144)) - { - if (STAT.Bit(4)) - { - if ((cycle >= 4) && (LY == 144)) - { - VBL_INT = true; - } - else if (LY > 144) - { - VBL_INT = true; - } - } - - if ((cycle == 4) && (LY == 144)) { - - HBL_INT = false; - - // set STAT mode to 1 (VBlank) and interrupt flag if it is enabled - STAT &= 0xFC; - STAT |= 0x01; - - if (Core.REG_FFFF.Bit(0)) { Core.cpu.FlagI = true; } - Core.REG_FF0F |= 0x01; - } - - if ((LY >= 144) && (cycle == 4)) - { - // a special case of OAM mode 2 IRQ assertion, even though PPU Mode still is 1 - if (STAT.Bit(5)) { OAM_INT = true; } - } - - if ((LY == 153) && (cycle == 8)) - { - LY = 0; - LY_inc = 0; - Core.cpu.LY = LY; - } - } - - if (!Core.in_vblank) - { - if (cycle == 4) - { - // here mode 2 will be set to true and interrupts fired if enabled - STAT &= 0xFC; - STAT |= 0x2; - if (STAT.Bit(5)) { OAM_INT = true; } - - HBL_INT = false; - } - - if (cycle >= 4 && cycle < 84) - { - // here OAM scanning is performed - OAM_scan(cycle - 4); - } - else if (cycle >= 84 && LY < 144) - { - // render the screen and handle hblank - render(cycle - 84); - } - } - - - if ((LY_inc == 0)) - { - if (cycle == 12) - { - LYC_INT = false; - STAT &= 0xFB; - - // Special case of LY = LYC - if (LY == LYC) - { - // set STAT coincidence FLAG and interrupt flag if it is enabled - STAT |= 0x04; - if (STAT.Bit(6)) { LYC_INT = true; } - } - - // also a special case of OAM mode 2 IRQ assertion, even though PPU Mode still is 1 - if (STAT.Bit(5)) { OAM_INT = true; } - } - - if (cycle == 92) { OAM_INT = false; } - } - - // here LY=LYC will be asserted - if ((cycle == 4) && (LY != 0)) - { - LYC_INT = false; - STAT &= 0xFB; - - if (LY == LYC) - { - // set STAT coincidence FLAG and interrupt flag if it is enabled - STAT |= 0x04; - if (STAT.Bit(6)) { LYC_INT = true; } - } - } - - cycle++; - - if (cycle==456) - { - cycle = 0; - LY+=LY_inc; - - if (LY==0 && LY_inc == 0) - { - LY_inc = 1; - Core.in_vblank = false; - VBL_INT = false; - } - - Core.cpu.LY = LY; - - if (LY==144) - { - Core.in_vblank = true; - } - } - } - else - { - // screen disable sets STAT as though it were vblank, but there is no Stat IRQ asserted - STAT &= 0xFC; - STAT |= 0x01; - - VBL_INT = LYC_INT = HBL_INT = OAM_INT = false; - - Core.in_vblank = true; - - LCD_was_off = true; - - LY = 0; - Core.cpu.LY = LY; - - cycle = 0; - } - - // assert the STAT IRQ line if the line went from zero to 1 - stat_line = VBL_INT | LYC_INT | HBL_INT | OAM_INT; - - if (stat_line && !stat_line_old) - { - if (Core.REG_FFFF.Bit(1)) { Core.cpu.FlagI = true; } - Core.REG_FF0F |= 0x02; - } - - stat_line_old = stat_line; - - // process latch delays - //latch_delay(); - - } - - // might be needed, not sure yet - public void latch_delay() - { - //BGP_l = BGP; - } - - public void OAM_scan(int OAM_cycle) - { - // we are now in STAT mode 2 - // TODO: maybe stat mode 2 flags are set at cycle 0 on visible scanlines? - if (OAM_cycle == 0) - { - OAM_access = false; - OAM_scan_index = 0; - SL_sprites_index = 0; - write_sprite = 0; - } - - // the gameboy has 80 cycles to scan through 40 sprites, picking out the first 10 it finds to draw - // the following is a guessed at implmenentation based on how NES does it, it's probably pretty close - if (OAM_cycle < 10) - { - // start by clearing the sprite table (probably just clears X on hardware, but let's be safe here.) - SL_sprites[OAM_cycle * 4] = 0; - SL_sprites[OAM_cycle * 4 + 1] = 0; - SL_sprites[OAM_cycle * 4 + 2] = 0; - SL_sprites[OAM_cycle * 4 + 3] = 0; - } - else - { - if (write_sprite == 0) - { - if (OAM_scan_index < 40) - { - // (sprite Y - 16) equals LY, we have a sprite - if ((Core.OAM[OAM_scan_index * 4] - 16) <= LY && - ((Core.OAM[OAM_scan_index * 4] - 16) + 8 + (LCDC.Bit(2) ? 8 : 0)) > LY) - { - // always pick the first 10 in range sprites - if (SL_sprites_index < 10) - { - SL_sprites[SL_sprites_index * 4] = Core.OAM[OAM_scan_index * 4]; - - write_sprite = 1; - } - else - { - // if we already have 10 sprites, there's nothing to do, increment the index - OAM_scan_index++; - } - } - else - { - OAM_scan_index++; - } - } - } - else - { - SL_sprites[SL_sprites_index * 4 + write_sprite] = Core.OAM[OAM_scan_index * 4 + write_sprite]; - write_sprite++; - - if (write_sprite == 4) - { - write_sprite = 0; - SL_sprites_index++; - OAM_scan_index++; - } - } - } - } - - public void render(int render_cycle) - { - // we are now in STAT mode 3 - // NOTE: presumably the first necessary sprite is fetched at sprite evaulation - // i.e. just keeping track of the lowest x-value sprite - if (render_cycle == 0) - { - STAT &= 0xFC; - STAT |= 0x03; - OAM_INT = false; - - OAM_access = false; - VRAM_access = false; - OAM_scan_index = 0; - read_case = 0; - internal_cycle = 0; - pre_render = true; - tile_inc = 0; - pixel_counter = 0; - sl_use_index = 0; - index_used = 0; - bottom_index = 0; - sprite_ordered_index = 0; - fetch_sprite = false; - no_sprites = false; - - // calculate the row number of the tiles to be fetched - y_tile = ((int)Math.Floor((float)(scroll_y + LY) / 8)) % 32; - - if (SL_sprites_index == 0) - { - no_sprites = true; - } - } - - if (!pre_render && !fetch_sprite) - { - // start by fetching all the sprites that need to be fetched - if (!no_sprites) - { - for (int i = 0; i < SL_sprites_index; i++) - { - if ((pixel_counter >= (SL_sprites[i * 4 + 1] - 8)) && - (pixel_counter < SL_sprites[i * 4 + 1]) && - !index_used.Bit(i)) - { - fetch_sprite = true; - sprite_fetch_index = 0; - } - } - } - - if (!fetch_sprite) - { - // start shifting data into the LCD - if (render_counter >= (render_offset + 8)) - { - pixel = tile_data_latch[0].Bit(7 - (render_counter % 8)) ? 1 : 0; - pixel |= tile_data_latch[1].Bit(7 - (render_counter % 8)) ? 2 : 0; - pixel = (BGP >> (pixel * 2)) & 3; - // now we have the BG pixel, we next need the sprite pixel - if (!no_sprites) - { - bool have_sprite = false; - int i = bottom_index; - int s_pixel = 0; - int sprite_attr = 0; - - while (i < sprite_ordered_index) - { - if (SL_sprites_ordered[i * 4] == pixel_counter) - { - bottom_index++; - if (bottom_index == SL_sprites_index) { no_sprites = true; } - } - else if (!have_sprite) - { - // we can use the current sprite, so pick out a pixel for it - int t_index = pixel_counter - (SL_sprites_ordered[i * 4] - 8); - - t_index = 7 - t_index; - - sprite_data[0] = (byte)((SL_sprites_ordered[i * 4 + 1] >> t_index) & 1); - sprite_data[1] = (byte)(((SL_sprites_ordered[i * 4 + 2] >> t_index) & 1) << 1); - - s_pixel = sprite_data[0] + sprite_data[1]; - sprite_attr = SL_sprites_ordered[i * 4 + 3]; - - // pixel color of 0 is transparent, so if this is the case we dont have a pixel - if (s_pixel != 0) - { - have_sprite = true; - } - } - i++; - } - - if (have_sprite) - { - bool use_sprite = false; - if (LCDC.Bit(1)) - { - if (!sprite_attr.Bit(7)) - { - if (s_pixel != 0) { use_sprite = true; } - } - else if (pixel == 0) - { - use_sprite = true; - } - - if (!LCDC.Bit(0)) - { - use_sprite = true; - } - } - - if (use_sprite) - { - if (sprite_attr.Bit(4)) - { - pixel = (obj_pal_1 >> (s_pixel * 2)) & 3; - } - else - { - pixel = (obj_pal_0 >> (s_pixel * 2)) & 3; - } - } - } - } - - // based on sprite priority and pixel values, pick a final pixel color - Core._vidbuffer[LY * 160 + pixel_counter] = (int)GBHawk.color_palette[pixel]; - pixel_counter++; - - if (pixel_counter == 160) - { - read_case = 8; - hbl_set_once = true; - } - } - render_counter++; - } - } - - if (!fetch_sprite) - { - if (latch_new_data) - { - latch_new_data = false; - tile_data_latch[0] = tile_data[0]; - tile_data_latch[1] = tile_data[1]; - } - - switch (read_case) - { - case 0: // read a background tile - if ((internal_cycle % 2) == 0) - { - - temp_fetch = y_tile * 32 + (x_tile + tile_inc) % 32; - tile_byte = LCDC.Bit(3) ? Core.BG_map_2[temp_fetch] : Core.BG_map_1[temp_fetch]; - - } - else - { - if (!pre_render) - { - tile_inc++; - } - read_case = 1; - } - break; - - case 1: // read from tile graphics (0) - if ((internal_cycle % 2) == 0) - { - y_scroll_offset = (scroll_y + LY) % 8; - - if (LCDC.Bit(4)) - { - tile_data[0] = Core.CHR_RAM[tile_byte * 16 + y_scroll_offset * 2]; - } - else - { - // same as before except now tile byte represents a signed byte - if (tile_byte.Bit(7)) - { - tile_byte -= 256; - } - tile_data[0] = Core.CHR_RAM[0x1000 + tile_byte * 16 + y_scroll_offset * 2]; - } - - } - else - { - read_case = 2; - } - break; - - case 2: // read from tile graphics (1) - if ((internal_cycle % 2) == 0) - { - y_scroll_offset = (scroll_y + LY) % 8; - - if (LCDC.Bit(4)) - { - // if LCDC somehow changed between the two reads, make sure we have a positive number - if (tile_byte < 0) - { - tile_byte += 256; - } - - tile_data[1] = Core.CHR_RAM[tile_byte * 16 + y_scroll_offset * 2 + 1]; - } - else - { - // same as before except now tile byte represents a signed byte - if (tile_byte.Bit(7) && tile_byte > 0) - { - tile_byte -= 256; - } - - tile_data[1] = Core.CHR_RAM[0x1000 + tile_byte * 16 + y_scroll_offset * 2 + 1]; - } - - } - else - { - if (pre_render) - { - // here we set up rendering - pre_render = false; - render_offset = scroll_x % 8; - render_counter = -1; - latch_counter = 0; - read_case = 0; - } - else - { - read_case = 3; - } - - } - break; - - case 3: // read from sprite data - if ((internal_cycle % 2) == 0) - { - // nothing to do if not fetching - } - else - { - read_case = 0; - latch_new_data = true; - } - break; - - case 4: // read from window data - break; - - case 6: // read from tile graphics (for the window) - break; - - case 7: // read from tile graphics (for the window) - break; - - case 8: // done reading, we are now in phase 0 - - OAM_access = true; - VRAM_access = true; - - STAT &= 0xFC; - STAT |= 0x00; - pre_render = true; - if (hbl_set_once) - { - if (STAT.Bit(3)) { HBL_INT = true; } - hbl_set_once = false; - } - - break; - } - - internal_cycle++; - } - - if (fetch_sprite) - { - if (sprite_fetch_index < SL_sprites_index) - { - if (pixel_counter != 0) { - if ((pixel_counter == (SL_sprites[sprite_fetch_index * 4 + 1] - 8)) && - //(pixel_counter < SL_sprites[sprite_fetch_index * 4 + 1]) && - !index_used.Bit(sprite_fetch_index)) - { - sl_use_index = sprite_fetch_index; - process_sprite(); - SL_sprites_ordered[sprite_ordered_index * 4] = SL_sprites[sprite_fetch_index * 4 + 1]; - SL_sprites_ordered[sprite_ordered_index * 4 + 1] = sprite_sel[0]; - SL_sprites_ordered[sprite_ordered_index * 4 + 2] = sprite_sel[1]; - SL_sprites_ordered[sprite_ordered_index * 4 + 3] = SL_sprites[sprite_fetch_index * 4 + 3]; - sprite_ordered_index++; - index_used |= (1 << sl_use_index); - } - sprite_fetch_index++; - if (sprite_fetch_index == SL_sprites_index) { fetch_sprite = false; } - } - else - { - // whan pixel counter is 0, we want to scan all the points before 0 as well - // certainly non-physical but good enough for now - for (int j = -7; j < 1; j++) - { - for (int i = 0; i < SL_sprites_index; i++) - { - if ((j == (SL_sprites[i * 4 + 1] - 8)) && - !index_used.Bit(i)) - { - sl_use_index = i; - process_sprite(); - SL_sprites_ordered[sprite_ordered_index * 4] = SL_sprites[i * 4 + 1]; - SL_sprites_ordered[sprite_ordered_index * 4 + 1] = sprite_sel[0]; - SL_sprites_ordered[sprite_ordered_index * 4 + 2] = sprite_sel[1]; - SL_sprites_ordered[sprite_ordered_index * 4 + 3] = SL_sprites[i * 4 + 3]; - sprite_ordered_index++; - index_used |= (1 << sl_use_index); - } - } - } - fetch_sprite = false; - } - } - } - } - - public void Reset() - { - LCDC = 0; - STAT = 0x80; - scroll_y = 0; - scroll_x = 0; - LY = 0; - LYC = 0; - DMA_addr = 0; - BGP = 0; - obj_pal_0 = 0; - obj_pal_1 = 0; - window_y = 0; - window_x = 0; - LY_inc = 1; - - cycle = 0; - LYC_INT = false; - HBL_INT = false; - VBL_INT = false; - OAM_INT = false; - - stat_line = false; - stat_line_old = false; - } - - public void process_sprite() - { - int y; - - if (SL_sprites[sl_use_index * 4 + 3].Bit(6)) - { - if (LCDC.Bit(2)) - { - y = LY - (SL_sprites[sl_use_index * 4] - 16); - y = 15 - y; - sprite_sel[0] = Core.CHR_RAM[(SL_sprites[sl_use_index * 4 + 2] & 0xFE) * 16 + y * 2]; - sprite_sel[1] = Core.CHR_RAM[(SL_sprites[sl_use_index * 4 + 2] & 0xFE) * 16 + y * 2 + 1]; - } - else - { - y = LY - (SL_sprites[sl_use_index * 4] - 16); - y = 7 - y; - sprite_sel[0] = Core.CHR_RAM[SL_sprites[sl_use_index * 4 + 2] * 16 + y * 2]; - sprite_sel[1] = Core.CHR_RAM[SL_sprites[sl_use_index * 4 + 2] * 16 + y * 2 + 1]; - } - } - else - { - if (LCDC.Bit(2)) - { - y = LY - (SL_sprites[sl_use_index * 4] - 16); - sprite_sel[0] = Core.CHR_RAM[(SL_sprites[sl_use_index * 4 + 2] & 0xFE) * 16 + y * 2]; - sprite_sel[1] = Core.CHR_RAM[(SL_sprites[sl_use_index * 4 + 2] & 0xFE) * 16 + y * 2 + 1]; - } - else - { - y = LY - (SL_sprites[sl_use_index * 4] - 16); - sprite_sel[0] = Core.CHR_RAM[SL_sprites[sl_use_index * 4 + 2] * 16 + y * 2]; - sprite_sel[1] = Core.CHR_RAM[SL_sprites[sl_use_index * 4 + 2] * 16 + y * 2 + 1]; - } - } - - if (SL_sprites[sl_use_index * 4 + 3].Bit(5)) - { - int b0, b1, b2, b3, b4, b5, b6, b7 = 0; - for (int i = 0; i < 2; i++) - { - b0 = (sprite_sel[i] & 0x01) << 7; - b1 = (sprite_sel[i] & 0x02) << 5; - b2 = (sprite_sel[i] & 0x04) << 3; - b3 = (sprite_sel[i] & 0x08) << 1; - b4 = (sprite_sel[i] & 0x10) >> 1; - b5 = (sprite_sel[i] & 0x20) >> 3; - b6 = (sprite_sel[i] & 0x40) >> 5; - b7 = (sprite_sel[i] & 0x80) >> 7; - - sprite_sel[i] = (byte)(b0 | b1 | b2 | b3 | b4 | b5 | b6 | b7); - } - } - } - - public void SyncState(Serializer ser) - { - ser.Sync("LCDC", ref LCDC); - ser.Sync("STAT", ref STAT); - ser.Sync("scroll_y", ref scroll_y); - ser.Sync("scroll_x", ref scroll_x); - ser.Sync("LY", ref LY); - ser.Sync("LYinc", ref LY_inc); - ser.Sync("LYC", ref LYC); - ser.Sync("DMA_addr", ref DMA_addr); - ser.Sync("BGP", ref BGP); - ser.Sync("obj_pal_0", ref obj_pal_0); - ser.Sync("obj_pal_1", ref obj_pal_1); - ser.Sync("window_y", ref window_y); - ser.Sync("window_x", ref window_x); - ser.Sync("DMA_start", ref DMA_start); - ser.Sync("DMA_clock", ref DMA_clock); - ser.Sync("DMA_inc", ref DMA_inc); - ser.Sync("DMA_byte", ref DMA_byte); - - ser.Sync("LYC_INT", ref LYC_INT); - ser.Sync("HBL_INT", ref HBL_INT); - ser.Sync("VBL_INT", ref VBL_INT); - ser.Sync("OAM_INT", ref OAM_INT); - ser.Sync("stat_line", ref stat_line); - ser.Sync("stat_line_old", ref stat_line_old); - ser.Sync("hbl_set_once", ref hbl_set_once); - ser.Sync("LCD_was_off", ref LCD_was_off); - ser.Sync("OAM_access", ref OAM_access); - ser.Sync("OAM_scan_index", ref OAM_scan_index); - ser.Sync("SL_sprites_index", ref SL_sprites_index); - ser.Sync("SL_sprites", ref SL_sprites, false); - ser.Sync("write_sprite", ref write_sprite); - - ser.Sync("VRAM_access", ref VRAM_access); - ser.Sync("read_case", ref read_case); - ser.Sync("internal_cycle", ref internal_cycle); - ser.Sync("y_tile", ref y_tile); - ser.Sync("y_scroll_offset", ref y_scroll_offset); - ser.Sync("x_tile", ref x_tile); - ser.Sync("x_scroll_offset", ref x_scroll_offset); - ser.Sync("tile_byte", ref tile_byte); - ser.Sync("sprite_fetch_cycles", ref sprite_fetch_cycles); - ser.Sync("fetch_sprite", ref fetch_sprite); - ser.Sync("temp_fetch", ref temp_fetch); - ser.Sync("tile_inc", ref tile_inc); - ser.Sync("pre_render", ref pre_render); - ser.Sync("tile_data", ref tile_data, false); - ser.Sync("tile_data_latch", ref tile_data_latch, false); - ser.Sync("latch_counter", ref latch_counter); - ser.Sync("latch_new_data", ref latch_new_data); - ser.Sync("render_counter", ref render_counter); - ser.Sync("render_offset", ref render_offset); - ser.Sync("pixel_counter", ref pixel_counter); - ser.Sync("pixel", ref pixel); - ser.Sync("sprite_data", ref sprite_data, false); - ser.Sync("sl_use_index", ref sl_use_index); - ser.Sync("sprite_sel", ref sprite_sel, false); - ser.Sync("no_sprites", ref no_sprites); - ser.Sync("sprite_fetch_index", ref sprite_fetch_index); - ser.Sync("SL_sprites_ordered", ref SL_sprites_ordered, false); - ser.Sync("index_used", ref index_used); - ser.Sync("sprite_ordered_index", ref sprite_ordered_index); - ser.Sync("bottom_index", ref bottom_index); - - } - } -} diff --git a/Timer.cs b/Timer.cs deleted file mode 100644 index b243081d70..0000000000 --- a/Timer.cs +++ /dev/null @@ -1,175 +0,0 @@ -using BizHawk.Common; -using BizHawk.Common.NumberExtensions; -using System; - -namespace BizHawk.Emulation.Cores.Nintendo.GBHawk -{ - // Timer Emulation - public class Timer - { - public GBHawk Core { get; set; } - - public ushort divider_reg; - public byte timer_reload; - public byte timer; - public byte timer_old; - public byte timer_control; - public byte pending_reload; - public byte write_ignore; - public bool old_state; - public bool state; - public bool reload_block; - public bool TMA_coincidence; - - public byte ReadReg(int addr) - { - byte ret = 0; - - switch (addr) - { - case 0xFF04: ret = (byte)(divider_reg >> 8); break; // DIV register - case 0xFF05: ret = timer; break; // TIMA (Timer Counter) - case 0xFF06: ret = timer_reload; break; // TMA (Timer Modulo) - case 0xFF07: ret = timer_control; break; // TAC (Timer Control) - } - - return ret; - } - - public void WriteReg(int addr, byte value) - { - switch (addr) - { - // DIV register - case 0xFF04: - divider_reg = 0; - break; - - // TIMA (Timer Counter) - case 0xFF05: - if (write_ignore == 0) - { - timer_old = timer; - timer = value; - reload_block = true; - } - break; - - // TMA (Timer Modulo) - case 0xFF06: - timer_reload = value; - if (TMA_coincidence) - { - timer = timer_reload; - timer_old = timer; - } - break; - - // TAC (Timer Control) - case 0xFF07: - timer_control = (byte)((timer_control & 0xf8) | (value & 0x7)); // only bottom 3 bits function - break; - } - } - - public void tick_1() - { - if (write_ignore > 0) - { - write_ignore--; - if (write_ignore==0) - { - TMA_coincidence = false; - } - } - - if (pending_reload > 0) - { - pending_reload--; - if (pending_reload == 0 && !reload_block) - { - timer = timer_reload; - timer_old = timer; - write_ignore = 4; - TMA_coincidence = true; - - // set interrupts - if (Core.REG_FFFF.Bit(2)) { Core.cpu.FlagI = true; } - Core.REG_FF0F |= 0x04; - } - } - } - - public void tick_2() - { - divider_reg++; - - // pick a bit to test based on the current value of timer control - switch (timer_control & 3) - { - case 0: - state = divider_reg.Bit(9); - break; - case 1: - state = divider_reg.Bit(3); - break; - case 2: - state = divider_reg.Bit(5); - break; - case 3: - state = divider_reg.Bit(7); - break; - } - - // And it with the state of the timer on/off bit - state &= timer_control.Bit(2); - - // this procedure allows several glitchy timer ticks, since it only measures falling edge of the state - // so things like turning the timer off and resetting the divider will tick the timer - if (old_state && !state) - { - timer_old = timer; - timer++; - - // if overflow, set the interrupt flag and reload the timer (4 clocks later) - if (timer < timer_old) - { - pending_reload = 4; - reload_block = false; - } - } - - old_state = state; - } - - public void Reset() - { - divider_reg = 0; - timer_reload = 0; - timer = 0; - timer_old = 0; - timer_control = 0xF8; - pending_reload = 0; - write_ignore = 0; - old_state = false; - state = false; - reload_block = false; - TMA_coincidence = false; - } - - public void SyncState(Serializer ser) - { - ser.Sync("divider_reg", ref divider_reg); - ser.Sync("timer_reload", ref timer_reload); - ser.Sync("timer", ref timer); - ser.Sync("timer_old", ref timer_old); - ser.Sync("timer_control", ref timer_control); - ser.Sync("pending_reload", ref pending_reload); - ser.Sync("write_ignore", ref write_ignore); - ser.Sync("old_state", ref old_state); - ser.Sync("state", ref state); - ser.Sync("reload_block", ref reload_block); - ser.Sync("TMA_coincidence", ref TMA_coincidence); - } - } -} \ No newline at end of file