Skip to content

Commit

Permalink
Adding Stella as A2600 emulation core (#3911)
Browse files Browse the repository at this point in the history
* Adding initial version of the core

* Adding base files

* Trying to load waterbox now

* Adding stella

* Adding bk class

* Compiling bk interface to stella core

* Now compiling against Stella + SDL2-based BK backend

* Progress

* More progress

* Frame advancing (no render)

* Calling video update but crashing on zero div

* Now rendering to screen with correct palette

* Now rendering appropriately and with correct palette based on region

* Now reading controls

* Trying to capture audio

* Now adding audio

* Now polling inputs

* Now polling inputs

* Now reporting memory regions

* Added memory regions

* Removing debug prints

* Fixing indent

* Adding stella core

* Updating readme and make all cores

* Recovering ending comma

* Using heap alloc for sound buffer

* Removing unnecessary files

* Update src/BizHawk.Emulation.Cores/Consoles/Atari/Stella/Stella.IMemoryDomains.cs

Co-authored-by: James Groom <[email protected]>

* Update src/BizHawk.Emulation.Cores/Consoles/Atari/Stella/Stella.IMemoryDomains.cs

Co-authored-by: James Groom <[email protected]>

* Fix

* Restoring vscode

* Removing warning

* Update waterbox readme

* Fix Stella's `[Core]` attr

* Increased sound buffer size to 1Mb, as some games need more than 4K

---------

Co-authored-by: James Groom <[email protected]>
Co-authored-by: Morilli <[email protected]>
Co-authored-by: YoshiRulz <[email protected]>
  • Loading branch information
4 people authored Sep 11, 2024
1 parent a080086 commit bf8758e
Show file tree
Hide file tree
Showing 36 changed files with 3,203 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/make.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ jobs:
git submodule update --init gpgx/Genesis-Plus-GX;
git submodule update --init ../submodules/sameboy/libsameboy;
git submodule update --init uae/libretro-uae;
git submodule update --init stella/core;
- name: Download compiled waterbox
uses: actions/download-artifact@v4
with:
Expand Down Expand Up @@ -100,6 +101,7 @@ jobs:
Assets/dll/turbo.wbx.zst
Assets/dll/uzem.wbx.zst
Assets/dll/vb.wbx.zst
Assets/dll/stella.wbx.zst
Assets/dll/virtualjaguar.wbx.zst
build-mame:
Expand Down
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@
path = waterbox/gpgx/Genesis-Plus-GX
url = https://github.com/TASEmulators/Genesis-Plus-GX.git
branch = tasvideos-2.2
[submodule "waterbox/stella/core"]
path = waterbox/stella/core
url = https://github.com/TASEmulators/stella.git
branch = tasvideos-1
[submodule "waterbox/uae/libretro-uae"]
path = waterbox/uae/libretro-uae
url = https://github.com/TASEmulators/libretro-uae.git
Expand Down
Binary file added Assets/dll/stella.wbx.zst
Binary file not shown.
3 changes: 3 additions & 0 deletions src/BizHawk.Client.Common/config/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ public class Config
/// </remarks>
public static readonly IReadOnlyList<(string[] AppliesTo, string[] CoreNames)> CorePickerUIData = new List<(string[], string[])>
{
([ VSystemID.Raw.A26 ],
[ CoreNames.Stella, CoreNames.Atari2600Hawk ]),
([ VSystemID.Raw.Satellaview ],
[ CoreNames.Bsnes115, CoreNames.SubBsnes115 ]),
([ VSystemID.Raw.GB, VSystemID.Raw.GBC ],
Expand All @@ -49,6 +51,7 @@ public class Config
[ CoreNames.Snes9X, CoreNames.Bsnes115, CoreNames.SubBsnes115, CoreNames.Faust, CoreNames.Bsnes ]),
([ VSystemID.Raw.TI83 ],
[ CoreNames.Emu83, CoreNames.TI83Hawk ]),

};

public static Dictionary<string, string> GenDefaultCorePreferences()
Expand Down
3 changes: 2 additions & 1 deletion src/BizHawk.Emulation.Common/Enums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ public enum DisplayType
{
NTSC,
PAL,
Dendy
Dendy,
SECAM
}

/// <summary>
Expand Down
80 changes: 80 additions & 0 deletions src/BizHawk.Emulation.Cores/Consoles/Atari/Stella/LibStella.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
using System.Runtime.InteropServices;

using BizHawk.BizInvoke;

namespace BizHawk.Emulation.Cores.Consoles.Atari.Stella
{
public abstract class CInterface
{

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int load_archive_cb(string filename, IntPtr buffer, int maxsize);

[StructLayout(LayoutKind.Sequential)]
public class InitSettings
{
public uint dummy;
}

[BizImport(CallingConvention.Cdecl)]
public abstract void stella_get_audio(ref int n, ref IntPtr buffer);

[BizImport(CallingConvention.Cdecl)]
public abstract int stella_get_region();

[BizImport(CallingConvention.Cdecl)]
public abstract bool stella_init(
string fileName,
load_archive_cb feload_archive_cb,
[In]InitSettings settings);

[BizImport(CallingConvention.Cdecl)]
public abstract void stella_frame_advance(int port1, int port2, bool reset, bool power, bool leftDiffToggled, bool rightDiffToggled);

[BizImport(CallingConvention.Cdecl)]
public abstract void stella_get_video(out int w, out int h, out int pitch, ref IntPtr buffer);

[BizImport(CallingConvention.Cdecl)]
public abstract void stella_get_frame_rate(out int fps);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void input_cb();

[BizImport(CallingConvention.Cdecl)]
public abstract void stella_set_input_callback(input_cb cb);

[BizImport(CallingConvention.Cdecl)]
public abstract byte stella_peek_tia(uint addr);

[BizImport(CallingConvention.Cdecl)]
public abstract void stella_poke_tia(uint addr, byte value);

[BizImport(CallingConvention.Cdecl)]
public abstract byte stella_peek_m6532(uint addr);

[BizImport(CallingConvention.Cdecl)]
public abstract void stella_poke_m6532(uint addr, byte value);

[BizImport(CallingConvention.Cdecl)]
public abstract byte stella_peek_systembus(uint addr);

[BizImport(CallingConvention.Cdecl)]
public abstract void stella_poke_systembus(uint addr, byte value);

[BizImport(CallingConvention.Cdecl)]
public abstract uint stella_get_cartram_size();

[BizImport(CallingConvention.Cdecl)]
public abstract byte stella_peek_cartram(uint addr);

[BizImport(CallingConvention.Cdecl)]
public abstract void stella_poke_cartram(uint addr, byte value);

[BizImport(CallingConvention.Cdecl)]
public abstract void stella_get_mainram_ptr(ref IntPtr addr);

[BizImport(CallingConvention.Cdecl)]
public abstract IntPtr stella_get_cart_type();

}
}
99 changes: 99 additions & 0 deletions src/BizHawk.Emulation.Cores/Consoles/Atari/Stella/Stella.Core.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
using BizHawk.Emulation.Cores.Components.M6502;
using System.Runtime.CompilerServices;

namespace BizHawk.Emulation.Cores.Atari.Stella
{
public partial class Stella
{
internal struct CpuLink : IMOS6502XLink
{
public byte DummyReadMemory(ushort address) { return 0; }

public void OnExecFetch(ushort address) { }

public byte PeekMemory(ushort address) { return 0; }

public byte ReadMemory(ushort address) { return 0; }

public void WriteMemory(ushort address, byte value) { }
}

internal byte BaseReadMemory(ushort addr)
{
return 0;
}

internal byte BasePeekMemory(ushort addr)
{

return 0;
}

internal void BaseWriteMemory(ushort addr, byte value)
{
}

internal void BasePokeMemory(ushort addr, byte value)
{
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private byte ReadMemory(ushort addr)
{
return 0;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void WriteMemory(ushort addr, byte value)
{
}

internal void PokeMemory(ushort addr, byte value)
{
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ExecFetch(ushort addr)
{
}

private void RebootCore()
{
}

private void HardReset()
{
}

private void Cycle()
{
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal byte ReadControls1(bool peek)
{
return 0;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal byte ReadControls2(bool peek)
{
return 0;
}

internal int ReadPot1(int pot)
{
return 0;
}

internal int ReadPot2(int pot)
{
return 0;
}

internal byte ReadConsoleSwitches(bool peek)
{
return 0;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using BizHawk.Emulation.Common;

namespace BizHawk.Emulation.Cores.Atari.Stella
{
public partial class Stella : IEmulator
{
public IEmulatorServiceProvider ServiceProvider { get; }

public ControllerDefinition ControllerDefinition => _controllerDeck.Definition;

private bool _leftDifficultyToggled = false;
private bool _rightDifficultyToggled = false;

public bool FrameAdvance(IController controller, bool render, bool renderSound)
{

int port1 = _controllerDeck.ReadPort1(controller);
int port2 = _controllerDeck.ReadPort2(controller);

// Handle all the console controls here
bool powerPressed = false;
bool resetPressed = false;
if (controller.IsPressed("Power")) powerPressed = true;
if (controller.IsPressed("Reset")) resetPressed = true;
if (controller.IsPressed("Toggle Left Difficulty")) _leftDifficultyToggled = !_leftDifficultyToggled;
if (controller.IsPressed("Toggle Right Difficulty")) _rightDifficultyToggled = !_rightDifficultyToggled;

IsLagFrame = true;

Core.stella_frame_advance(port1, port2, resetPressed, powerPressed, _leftDifficultyToggled, _rightDifficultyToggled);

if (IsLagFrame)
LagCount++;

if (render)
UpdateVideo();

if (renderSound)
update_audio();

_frame++;

return true;
}

public int _frame;

public int Frame => _frame;

public string SystemId => VSystemID.Raw.A26;

public bool DeterministicEmulation => true;

public void ResetCounters()
{
_frame = 0;
LagCount = 0;
IsLagFrame = false;
}

public void Dispose()
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Consoles.Atari.Stella;

namespace BizHawk.Emulation.Cores.Atari.Stella
{
public partial class Stella : IInputPollable
{
public int LagCount { get; set; }

public bool IsLagFrame { get; set; }

public IInputCallbackSystem InputCallbacks => _inputCallbacks;

private readonly CInterface.input_cb _inputCallback;

private readonly InputCallbackSystem _inputCallbacks = new InputCallbackSystem();

private void input_callback()
{
InputCallbacks.Call();
IsLagFrame = false;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System.Collections.Generic;

using BizHawk.Emulation.Common;

namespace BizHawk.Emulation.Cores.Atari.Stella
{
public partial class Stella
{
internal IMemoryDomains MemoryDomains;
private uint _cartMemSize;

private void SetupMemoryDomains()
{
_cartMemSize = Core.stella_get_cartram_size();
var mainRamAddress = IntPtr.Zero;
var cartDPCRamAddress = IntPtr.Zero;
Core.stella_get_mainram_ptr(ref mainRamAddress);

var domains = new List<MemoryDomain>
{
new MemoryDomainDelegate(
"TIA",
16,
MemoryDomain.Endian.Little,
addr => Core.stella_peek_tia((uint)addr),
(addr, value) => Core.stella_poke_tia((uint)addr, value),
1),

new MemoryDomainDelegate(
"PIA",
1024,
MemoryDomain.Endian.Little,
addr => Core.stella_peek_m6532((uint)addr),
(addr, value) => Core.stella_poke_m6532((uint)addr, value),
1),

new MemoryDomainDelegate(
"System Bus",
65536,
MemoryDomain.Endian.Little,
addr => Core.stella_peek_systembus((uint) addr),
(addr, value) => Core.stella_poke_systembus((uint) addr, value),
1)
};

if (_cartMemSize > 0)
{
domains.Add(new MemoryDomainDelegate(
"Cart Ram",
_cartMemSize,
MemoryDomain.Endian.Little,
addr => Core.stella_peek_cartram((uint)addr),
(addr, value) => Core.stella_poke_cartram((uint)addr, value),
1));
}

MemoryDomainIntPtrMonitor mainRAM = new("Main RAM", MemoryDomain.Endian.Little, mainRamAddress, 128, true, 1, _elf);
domains.Add(mainRAM);

MemoryDomains = new MemoryDomainList(domains) { MainMemory = mainRAM };
((BasicServiceProvider)ServiceProvider).Register(MemoryDomains);
}
}
}
Loading

0 comments on commit bf8758e

Please sign in to comment.