Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 72 additions & 72 deletions Platforms/ZXBox.Blazor/Components/EmulatorComponent.razor.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.JSInterop;
using Microsoft.JSInterop.WebAssembly;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net.Http;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Timers;
using ZXBox.Core.Hardware.Input;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.JSInterop;
using Microsoft.JSInterop.WebAssembly;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net.Http;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Timers;
using ZXBox.Core.Hardware.Input;
using ZXBox.Hardware.Input;
using ZXBox.Hardware.Input.Joystick;
using ZXBox.Hardware.Output;
using ZXBox.Snapshot;
using ZXBox.Hardware.Output;
using ZXBox.Snapshot;

namespace ZXBox.Blazor.Pages
{
public partial class EmulatorComponentModel : ComponentBase, IAsyncDisposable
Expand Down Expand Up @@ -50,8 +50,8 @@ public ZXSpectrum GetZXSpectrum(RomEnum rom)
public void StartZXSpectrum(RomEnum rom)
{
speccy = GetZXSpectrum(rom);
speccy.InputHardware.Add(Keyboard);
speccy.InputHardware.Add(Keyboard);

kempston = new Kempston();
speccy.InputHardware.Add(kempston);
//48000 samples per second, 50 frames per second (20ms per frame) Mono
Expand All @@ -67,26 +67,26 @@ public void StartZXSpectrum(RomEnum rom)
public string TapeName { get; set; }
public async Task HandleFileSelected(InputFileChangeEventArgs args)
{
if (args.File.Name.ToLower().EndsWith(".tap"))
{
//Load the tape
var file = args.File;
var ms = new MemoryStream();
if (args.File.Name.ToLower().EndsWith(".tap"))
{
//Load the tape
var file = args.File;
var ms = new MemoryStream();
await file.OpenReadStream().CopyToAsync(ms);
tapePlayer.LoadTape(ms.ToArray());
TapeName = Path.GetFileNameWithoutExtension(args.File.Name);
}
else
{
var file = args.File;
var ms = new MemoryStream();
await file.OpenReadStream().CopyToAsync(ms);
var handler = FileFormatFactory.GetSnapShotHandler(file.Name);
var bytes = ms.ToArray();
handler.LoadSnapshot(bytes, speccy);
}
else
{
var file = args.File;
var ms = new MemoryStream();

await file.OpenReadStream().CopyToAsync(ms);

var handler = FileFormatFactory.GetSnapShotHandler(file.Name);
var bytes = ms.ToArray();
handler.LoadSnapshot(bytes, speccy);
}
}
[Inject]
HttpClient httpClient { get; set; }
Expand All @@ -104,37 +104,37 @@ public async Task LoadGame(string filename, string instructions)

private async void GameLoop_Elapsed(object sender, ElapsedEventArgs e)
{
Stopwatch sw = new Stopwatch();
//Get gamepads
kempston.Gamepads = await GamePadList.GetGamepadsAsync();
//Run JavaScriptInterop to find the currently pressed buttons
Stopwatch sw = new Stopwatch();

//Get gamepads
kempston.Gamepads = await GamePadList.GetGamepadsAsync();
//Run JavaScriptInterop to find the currently pressed buttons
Keyboard.KeyBuffer = await JSRuntime.InvokeAsync<List<string>>("getKeyStatus");
sw.Start();
speccy.DoIntructions(69888);
speccy.DoInstructions(69888);

beeper.GenerateSound();
await BufferSound();
Paint();
sw.Stop();
if (tapePlayer != null && tapePlayer.IsPlaying)
{
TapeStopped = false;
PercentLoaded = ((Convert.ToDouble(tapePlayer.CurrentTstate) / Convert.ToDouble(tapePlayer.TotalTstates)) * 100);
await InvokeAsync(() => StateHasChanged());
await BufferSound();

Paint();
sw.Stop();
if (tapePlayer != null && tapePlayer.IsPlaying)
{
TapeStopped = false;
PercentLoaded = ((Convert.ToDouble(tapePlayer.CurrentTstate) / Convert.ToDouble(tapePlayer.TotalTstates)) * 100);
await InvokeAsync(() => StateHasChanged());
}
if (!TapeStopped && !tapePlayer.IsPlaying)
{
TapeStopped = true;
await InvokeAsync(() => StateHasChanged());
if (!TapeStopped && !tapePlayer.IsPlaying)
{
TapeStopped = true;
await InvokeAsync(() => StateHasChanged());
}
}
bool TapeStopped = false;
GCHandle gchsound;
IntPtr pinnedsound;
WebAssemblyJSRuntime mono;
byte[] soundbytes;
}
bool TapeStopped = false;
GCHandle gchsound;
IntPtr pinnedsound;
WebAssemblyJSRuntime mono;
byte[] soundbytes;
protected async Task BufferSound()
{
soundbytes = beeper.GetSoundBuffer();
Expand All @@ -154,7 +154,7 @@ protected async override void OnAfterRender(bool firstRender)
base.OnAfterRender(firstRender);
}

GCHandle gchscreen;
GCHandle gchscreen;
IntPtr pinnedscreen;
//uint[] screen = new uint[68672]; //Height * width (256+20+20)*(192+20+20)
public async void Paint()
Expand All @@ -169,20 +169,20 @@ public async void Paint()
flashcounter--;
}

var screen = speccy.GetScreenInUint(flash);
//Allocate memory
var screen = speccy.GetScreenInUint(flash);

//Allocate memory
gchscreen = GCHandle.Alloc(screen, GCHandleType.Pinned);
pinnedscreen = gchscreen.AddrOfPinnedObject();
mono.InvokeUnmarshalled<IntPtr, string>("PaintCanvas", pinnedscreen);
gchscreen.Free();
}
public ValueTask DisposeAsync()
{
gameLoop.Stop();
gameLoop.Dispose();
return ValueTask.CompletedTask;
}
}

public ValueTask DisposeAsync()
{
gameLoop.Stop();
gameLoop.Dispose();
return ValueTask.CompletedTask;
}
}
}
8 changes: 5 additions & 3 deletions Platforms/ZXBox.Blazor/Hardware/Kempston.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace ZXBox.Hardware.Input.Joystick
/// <summary>
/// The Kempston joystick interface differs from the other common types in that it does not map to the ZX Spectrum keyboard directly. Rather, it maps to a particular hardware port (0x1f) and support must therefore be 'built-in' to the software. Fortunately, the Kempston joystick interface was enormously popular, and support was very easy to provide, making Kempston control a common, almost standard, feature of most games.
/// Assuming an appropriate interface is attached, reading from port 0x1f returns the current state of the Kempston joystick in the form 000FUDLR, with active bits high.
/// � www.worldofspectrum.com
/// � www.worldofspectrum.com
/// </summary>

public class Kempston:IInput
Expand All @@ -38,9 +38,11 @@ public bool Enabled

#region IInput Members

public int Input(int Port,int tact)
public void AddTStates(int tstates) { }

public byte Input(ushort Port,int tact)
{
int returnvalue = 0xFF;
byte returnvalue = 0xFF;
if ((Port &0xff) == 0x1f)
{
returnvalue = 0x0;
Expand Down
11 changes: 6 additions & 5 deletions Platforms/ZXBox.Blazor/Hardware/Keyboard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ public bool GetKeyStatus(string key)
return KeyBuffer.Any(k => k.ToLower() == key.ToLower());
}

public int Input(int Port, int tstates)
public void AddTStates(int tstates) { }

public byte Input(ushort Port, int tstates)
{

if ((Port & 0xFF) == 0xFE)
Expand Down Expand Up @@ -57,16 +59,15 @@ public int Input(int Port, int tstates)
right = true;
}

bool symbol = false;
int returnvalue = 0xFF;
var returnvalue = 0xFF;

//Special cace for any key
if (((Port >> 8) & 0xFF) == 0x01 || ((Port >> 8) & 0xFF) == 0x00 || ((Port >> 8) & 0xFF) == 0x02)
{ //Check for any key including joy, we might need to add more joy buttons later on

if (KeyBuffer.Count() > 0)
{
return returnvalue &= ~1;
return (byte)(returnvalue &= ~1);
}

}
Expand Down Expand Up @@ -197,7 +198,7 @@ public int Input(int Port, int tstates)
break;
}

return returnvalue;
return (byte)returnvalue;
}
return 0xFF;
}
Expand Down
8 changes: 4 additions & 4 deletions Platforms/ZXBox.Blazor/ZXBox.Blazor.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.0-preview.6.23329.11" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.0-preview.6.23329.11" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.1" PrivateAssets="all" />

<PackageReference Include="System.Net.Http.Json" Version="8.0.0-preview.6.23329.7" />
<PackageReference Include="Toolbelt.Blazor.Gamepad" Version="8.0.0.1" />
<PackageReference Include="System.Net.Http.Json" Version="8.0.0" />
<PackageReference Include="Toolbelt.Blazor.Gamepad" Version="9.0.0" />
</ItemGroup>

<ItemGroup>
Expand Down
14 changes: 7 additions & 7 deletions ZXBox.Core.Tests/CoreTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public static void RunTest()

public static bool TestInstruction(string file)
{
file = $"{Directory.GetParent(Directory.GetCurrentDirectory()).Parent.Parent.FullName}\\Testfiles\\" + file;
file = $"{Directory.GetParent(Directory.GetCurrentDirectory()).Parent.Parent.FullName}/Testfiles/" + file;
ZXSpectrum z80 = new ZXSpectrum();
z80.Reset();

Expand All @@ -45,15 +45,15 @@ public static bool TestInstruction(string file)
//z80.Memory = ts.Memory;
for(int m=0;m< ts.Memory.Length; m++)
{
z80.WriteByteToMemory(m, ts.Memory[m]);
z80.WriteByteToMemory((ushort)m, ts.Memory[m]);
}
z80.PC = ts.pc;
z80.R = ts.r;
z80.SP = ts.sp;

z80.DoIntructions(ts.end_tstates2);
z80.DoInstructions(ts.end_tstates2);

TestState tsout = TestfileHandler.ReadOUTFile(Path.GetDirectoryName(file) + "\\" + Path.GetFileNameWithoutExtension(file) + ".out", ts.Memory);
TestState tsout = TestfileHandler.ReadOUTFile(Path.GetDirectoryName(file) + "/" + Path.GetFileNameWithoutExtension(file) + ".out", ts.Memory);

//Compare
bool result = CoreTest.CompareFunction(tsout, ExtractState(z80));
Expand All @@ -71,7 +71,7 @@ public static bool CompareFunction(TestState ts, TestState z80)
//Assert.AreEqual(ts.af,z80.af,"af");
//Assert.AreEqual(ts.af_, z80.af_,"af_");

Assert.AreEqual(ts.bc,z80.bc,"bc");
Assert.AreEqual (ts.bc,z80.bc,"bc");
Assert.AreEqual (ts.bc_, z80.bc_,"bc_");

Assert.AreEqual (ts.de, z80.de,"de");
Expand All @@ -83,7 +83,7 @@ public static bool CompareFunction(TestState ts, TestState z80)
//Assert.AreEqual (ts.iff2 , z80.iff2, "iff2");
Assert.AreEqual (ts.im , z80.im, "im");
Assert.AreEqual (ts.ix , z80.ix, "ix");
Assert.AreEqual(ts.iy, z80.iy, "iy");
Assert.AreEqual( ts.iy, z80.iy, "iy");

//Not comparing this due to not fully implemented contended memory.
//Assert.AreEqual(ts.end_tstates2, z80.end_tstates2,"tstates2");
Expand Down Expand Up @@ -195,7 +195,7 @@ public static TestState ExtractState(Zilog.Z80 z80)
ts.iy = z80.IY;
for (int m = 0; m < ts.Memory.Length; m++)
{
ts.Memory[m] = z80.ReadByteFromMemory(m);
ts.Memory[m] = z80.ReadByteFromMemory((ushort)m);
}
ts.pc = z80.PC;
ts.r = z80.R;
Expand Down
4 changes: 2 additions & 2 deletions ZXBox.Core.Tests/GameBoy/GBFileFormatTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ public void LoadTileTest()
ff.LoadSnapshot(bytes, gb);
List<int> tiles = new List<int>();
//gb.PC = 0x100; //Entry point
gb.DoIntructions(1000000000);
for (int b = 0x8000; b <= 0x97FF; b++)
gb.DoInstructions(1000000000);
for (ushort b = 0x8000; b <= 0x97FF; b++)
{
tiles.Add(gb.ReadByteFromMemory(b));
}
Expand Down
7 changes: 4 additions & 3 deletions ZXBox.Core.Tests/TestState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ namespace ZXBox.Core.Tests
{
public class TestState
{
public int af, bc, de, hl, af_, bc_, de_, hl_, ix, iy, sp, pc;
public int i, r, im;
public ushort af, bc, de, hl, af_, bc_, de_, hl_, ix, iy, sp, pc;
public byte i, r;
public int im;
public bool iff1, iff2,halted;
public int end_tstates2;
public int[] Memory=new int[4*16 * 1024];
public byte[] Memory=new byte[4*16 * 1024];
}
}
Loading