mirror of
https://github.com/MoleskiCoder/EightBitNet.git
synced 2026-01-22 16:16:17 +00:00
LR35902 analysis suggestions
This commit is contained in:
@@ -51,7 +51,7 @@ namespace LR35902
|
||||
|
||||
public IoRegisters IO { get; }
|
||||
|
||||
public bool GameRomDisabled { get; private set; } = false;
|
||||
public bool GameRomDisabled { get; private set; }
|
||||
|
||||
public bool GameRomEnabled => !this.GameRomDisabled;
|
||||
|
||||
@@ -115,56 +115,56 @@ namespace LR35902
|
||||
this.RunVerticalBlankLines(lines);
|
||||
}
|
||||
|
||||
public override MemoryMapping Mapping(ushort address)
|
||||
public override MemoryMapping Mapping(ushort absolute)
|
||||
{
|
||||
if (address < 0x100 && this.IO.BootRomEnabled)
|
||||
if (absolute < 0x100 && this.IO.BootRomEnabled)
|
||||
{
|
||||
return new MemoryMapping(this.bootRom, 0x0000, Mask.Sixteen, AccessLevel.ReadOnly);
|
||||
}
|
||||
|
||||
if (address < 0x4000 && this.GameRomEnabled)
|
||||
if (absolute < 0x4000 && this.GameRomEnabled)
|
||||
{
|
||||
return new MemoryMapping(this.gameRomBanks[0], 0x0000, 0xffff, AccessLevel.ReadOnly);
|
||||
}
|
||||
|
||||
if (address < 0x8000 && this.GameRomEnabled)
|
||||
if (absolute < 0x8000 && this.GameRomEnabled)
|
||||
{
|
||||
return new MemoryMapping(this.gameRomBanks[this.romBank], 0x4000, 0xffff, AccessLevel.ReadOnly);
|
||||
}
|
||||
|
||||
if (address < 0xa000)
|
||||
if (absolute < 0xa000)
|
||||
{
|
||||
return new MemoryMapping(this.VRAM, 0x8000, 0xffff, AccessLevel.ReadWrite);
|
||||
}
|
||||
|
||||
if (address < 0xc000)
|
||||
if (absolute < 0xc000)
|
||||
{
|
||||
return this.ramBanks.Count == 0
|
||||
? new MemoryMapping(this.unmapped2000, 0xa000, 0xffff, AccessLevel.ReadOnly)
|
||||
: new MemoryMapping(this.ramBanks[this.ramBank], 0xa000, 0xffff, AccessLevel.ReadWrite);
|
||||
}
|
||||
|
||||
if (address < 0xe000)
|
||||
if (absolute < 0xe000)
|
||||
{
|
||||
return new MemoryMapping(this.lowInternalRam, 0xc000, 0xffff, AccessLevel.ReadWrite);
|
||||
}
|
||||
|
||||
if (address < 0xfe00)
|
||||
if (absolute < 0xfe00)
|
||||
{
|
||||
return new MemoryMapping(this.lowInternalRam, 0xe000, 0xffff, AccessLevel.ReadWrite); // Low internal RAM mirror
|
||||
}
|
||||
|
||||
if (address < 0xfea0)
|
||||
if (absolute < 0xfea0)
|
||||
{
|
||||
return new MemoryMapping(this.OAMRAM, 0xfe00, 0xffff, AccessLevel.ReadWrite);
|
||||
}
|
||||
|
||||
if (address < IoRegisters.BASE)
|
||||
if (absolute < IoRegisters.BASE)
|
||||
{
|
||||
return new MemoryMapping(this.unmapped60, 0xfea0, 0xffff, AccessLevel.ReadOnly);
|
||||
}
|
||||
|
||||
if (address < 0xff80)
|
||||
if (absolute < 0xff80)
|
||||
{
|
||||
return new MemoryMapping(this.IO, IoRegisters.BASE, 0xffff, AccessLevel.ReadWrite);
|
||||
}
|
||||
@@ -193,7 +193,7 @@ namespace LR35902
|
||||
// Register 1: ROM bank code
|
||||
if (this.banked && this.higherRomBank)
|
||||
{
|
||||
// assert((address >= 0x2000) && (address < 0x4000));
|
||||
// assert((absolute >= 0x2000) && (absolute < 0x4000));
|
||||
// assert((value > 0) && (value < 0x20));
|
||||
this.romBank = value & (byte)Mask.Five;
|
||||
}
|
||||
@@ -226,6 +226,8 @@ namespace LR35902
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
namespace LR35902
|
||||
{
|
||||
using EightBit;
|
||||
using System.Globalization;
|
||||
|
||||
public enum IoRegister
|
||||
{
|
||||
@@ -16,7 +17,7 @@ namespace LR35902
|
||||
|
||||
public sealed class Disassembler(Bus bus)
|
||||
{
|
||||
private bool prefixCB = false;
|
||||
private bool prefixCB;
|
||||
|
||||
public Bus Bus { get; } = bus;
|
||||
|
||||
@@ -38,6 +39,8 @@ namespace LR35902
|
||||
|
||||
public static string State(LR35902 cpu)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(cpu);
|
||||
|
||||
var pc = cpu.PC;
|
||||
var sp = cpu.SP;
|
||||
|
||||
@@ -63,6 +66,7 @@ namespace LR35902
|
||||
|
||||
public string Disassemble(LR35902 cpu)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(cpu);
|
||||
this.prefixCB = false;
|
||||
return this.Disassemble(cpu, cpu.PC.Word);
|
||||
}
|
||||
@@ -211,6 +215,8 @@ namespace LR35902
|
||||
case 7:
|
||||
specification = $"SRL {R(z)}";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -223,6 +229,8 @@ namespace LR35902
|
||||
case 3: // SET y, r[z]
|
||||
specification = $"SET {y},{R(z)}";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return output;
|
||||
@@ -268,7 +276,7 @@ namespace LR35902
|
||||
}
|
||||
|
||||
output += '\t';
|
||||
output += string.Format(specification, (int)immediate, (int)absolute, relative, (int)displacement, indexedImmediate);
|
||||
output += string.Format(CultureInfo.InvariantCulture, specification, (int)immediate, (int)absolute, relative, (int)displacement, indexedImmediate);
|
||||
|
||||
switch (ioRegister)
|
||||
{
|
||||
@@ -283,6 +291,8 @@ namespace LR35902
|
||||
break;
|
||||
case IoRegister.Unused:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return output;
|
||||
@@ -330,6 +340,8 @@ namespace LR35902
|
||||
case 1: // ADD HL,rp
|
||||
specification = $"ADD HL,{RP(p)}";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -351,6 +363,8 @@ namespace LR35902
|
||||
case 3: // GB: LDD (HL),A
|
||||
specification = "LDD (HL),A";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -369,8 +383,12 @@ namespace LR35902
|
||||
case 3: // GB: LDD A,(HL)
|
||||
specification = "LDD A,(HL)";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -384,6 +402,8 @@ namespace LR35902
|
||||
case 1: // DEC rp
|
||||
specification = $"DEC {RP(p)}";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -424,8 +444,12 @@ namespace LR35902
|
||||
case 7:
|
||||
specification = "CCF";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -474,6 +498,8 @@ namespace LR35902
|
||||
specification = "LD HL,SP+{4}";
|
||||
dumpCount++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -498,8 +524,12 @@ namespace LR35902
|
||||
case 3: // LD SP,HL
|
||||
specification = "LD SP,HL";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -530,6 +560,8 @@ namespace LR35902
|
||||
specification = "LD A,({1:X4}H)";
|
||||
dumpCount += 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -550,6 +582,8 @@ namespace LR35902
|
||||
case 7: // EI
|
||||
specification = "EI";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -570,8 +604,12 @@ namespace LR35902
|
||||
specification = "CALL {1:X4}H";
|
||||
dumpCount += 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -583,8 +621,12 @@ namespace LR35902
|
||||
case 7: // Restart: RST y * 8
|
||||
specification = $"RST {y * 8:X2}";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace LR35902
|
||||
private readonly AbstractColourPalette<T> colours = colours;
|
||||
private readonly ObjectAttribute[] objectAttributes = new ObjectAttribute[40];
|
||||
private byte control;
|
||||
private byte scanLine = 0;
|
||||
private byte scanLine;
|
||||
|
||||
public T[] Pixels { get; } = new T[DisplayCharacteristics.PixelCount];
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ namespace LR35902
|
||||
|
||||
public event EventHandler<LcdStatusModeEventArgs>? DisplayStatusModeUpdated;
|
||||
|
||||
public bool BootRomDisabled { get; private set; } = false;
|
||||
public bool BootRomDisabled { get; private set; }
|
||||
|
||||
public bool BootRomEnabled => !this.BootRomDisabled;
|
||||
|
||||
@@ -335,6 +335,8 @@ namespace LR35902
|
||||
case BOOT_DISABLE:
|
||||
this.BootRomDisabled = value != 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// Copyright (c) Adrian Conlon. All rights reserved.
|
||||
// </copyright>
|
||||
|
||||
namespace Fuse
|
||||
namespace LR35902.FuseTest
|
||||
{
|
||||
public static class Program
|
||||
{
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
// <copyright file="RegisterState.cs" company="Adrian Conlon">
|
||||
// Copyright (c) Adrian Conlon. All rights reserved.
|
||||
// </copyright>
|
||||
namespace Fuse
|
||||
|
||||
namespace LR35902.FuseTest
|
||||
{
|
||||
using System;
|
||||
using Fuse;
|
||||
using System.Globalization;
|
||||
|
||||
public class RegisterState : AbstractRegisterState, IRegisterState
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
// Copyright (c) Adrian Conlon. All rights reserved.
|
||||
// </copyright>
|
||||
|
||||
namespace Fuse
|
||||
namespace LR35902.FuseTest
|
||||
{
|
||||
using LR35902;
|
||||
using Fuse;
|
||||
|
||||
public enum Register
|
||||
{
|
||||
@@ -16,19 +16,13 @@ namespace Fuse
|
||||
PC,
|
||||
}
|
||||
|
||||
public class TestRunner<T> : LR35902.Bus
|
||||
where T : Fuse.IRegisterState, new()
|
||||
public class TestRunner<T>(Test<T> test, Result<T> result) : Bus
|
||||
where T : IRegisterState, new()
|
||||
{
|
||||
private readonly Test<T> test;
|
||||
private readonly Result<T> result;
|
||||
private readonly Test<T> test = test;
|
||||
private readonly Result<T> result = result;
|
||||
private readonly EightBit.Ram ram = new(0x10000);
|
||||
|
||||
public TestRunner(Test<T> test, Result<T> result)
|
||||
{
|
||||
this.test = test;
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public bool Failed { get; private set; } = false;
|
||||
|
||||
public bool Unimplemented { get; private set; } = false;
|
||||
@@ -42,13 +36,13 @@ namespace Fuse
|
||||
var allowedCycles = this.test.RegisterState.TStates;
|
||||
try
|
||||
{
|
||||
this.CPU.Run(allowedCycles);
|
||||
_ = this.CPU.Run(allowedCycles);
|
||||
this.Check();
|
||||
}
|
||||
catch (System.InvalidOperationException error)
|
||||
catch (InvalidOperationException error)
|
||||
{
|
||||
this.Unimplemented = true;
|
||||
System.Console.Error.WriteLine($"**** Error: {error.Message}");
|
||||
Console.Error.WriteLine($"**** Error: {error.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +67,7 @@ namespace Fuse
|
||||
private static void DumpDifference(string description, byte expected, byte actual)
|
||||
{
|
||||
var output = $"**** {description}, Expected: {expected:x2}, Got {actual:x2}";
|
||||
System.Console.Error.WriteLine(output);
|
||||
Console.Error.WriteLine(output);
|
||||
}
|
||||
|
||||
private static void DumpDifference(string highDescription, string lowDescription, EightBit.Register16 expected, EightBit.Register16 actual)
|
||||
@@ -123,11 +117,11 @@ namespace Fuse
|
||||
|
||||
private void Check()
|
||||
{
|
||||
this.Checkregisters();
|
||||
this.CheckRegisters();
|
||||
this.CheckMemory();
|
||||
}
|
||||
|
||||
private void Checkregisters()
|
||||
private void CheckRegisters()
|
||||
{
|
||||
var expectedState = this.result.RegisterState;
|
||||
var expectedRegisters = expectedState.Registers;
|
||||
@@ -144,7 +138,7 @@ namespace Fuse
|
||||
if (!success)
|
||||
{
|
||||
this.Failed = true;
|
||||
System.Console.Error.WriteLine($"**** Failed test (Register): {this.test.Description}");
|
||||
Console.Error.WriteLine($"**** Failed test (Register): {this.test.Description}");
|
||||
|
||||
if (!af)
|
||||
{
|
||||
@@ -206,10 +200,10 @@ namespace Fuse
|
||||
if (first)
|
||||
{
|
||||
first = false;
|
||||
System.Console.Error.WriteLine($"**** Failed test (Memory): {this.test.Description}");
|
||||
Console.Error.WriteLine($"**** Failed test (Memory): {this.test.Description}");
|
||||
}
|
||||
|
||||
System.Console.Error.WriteLine($"**** Difference: Address: {address:x4} Expected: {expected:x2} Actual: {actual:x2}");
|
||||
Console.Error.WriteLine($"**** Difference: Address: {address:x4} Expected: {expected:x2} Actual: {actual:x2}");
|
||||
}
|
||||
|
||||
++address;
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
// <copyright file="TestSuite.cs" company="Adrian Conlon">
|
||||
// Copyright (c) Adrian Conlon. All rights reserved.
|
||||
// </copyright>
|
||||
namespace Fuse
|
||||
|
||||
namespace LR35902.FuseTest
|
||||
{
|
||||
using Fuse;
|
||||
|
||||
public class TestSuite<T>
|
||||
where T : Fuse.IRegisterState, new()
|
||||
where T : IRegisterState, new()
|
||||
{
|
||||
private readonly Tests<T> tests;
|
||||
private readonly Results<T> results;
|
||||
@@ -34,7 +37,7 @@ namespace Fuse
|
||||
foreach (var test in this.tests.Container)
|
||||
{
|
||||
var key = test.Key;
|
||||
System.Console.Out.WriteLine($"** Checking: {key}");
|
||||
Console.Out.WriteLine($"** Checking: {key}");
|
||||
|
||||
var input = test.Value;
|
||||
var result = this.results.Container[key];
|
||||
@@ -52,8 +55,8 @@ namespace Fuse
|
||||
}
|
||||
}
|
||||
|
||||
System.Console.Out.WriteLine($"+++ Failed test count: {failedCount}");
|
||||
System.Console.Out.WriteLine($"+++ Unimplemented test count: {unimplementedCount}");
|
||||
Console.Out.WriteLine($"+++ Failed test count: {failedCount}");
|
||||
Console.Out.WriteLine($"+++ Unimplemented test count: {unimplementedCount}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace LR35902
|
||||
{
|
||||
private readonly Bus bus = bus;
|
||||
private readonly Register16 af = new((int)Mask.Sixteen);
|
||||
private bool prefixCB = false;
|
||||
private bool prefixCB;
|
||||
|
||||
public int ClockCycles => this.Cycles * 4;
|
||||
|
||||
@@ -29,9 +29,9 @@ namespace LR35902
|
||||
|
||||
public override Register16 HL { get; } = new Register16((int)Mask.Sixteen);
|
||||
|
||||
private bool IME { get; set; } = false;
|
||||
private bool IME { get; set; }
|
||||
|
||||
private bool Stopped { get; set; } = false;
|
||||
private bool Stopped { get; set; }
|
||||
|
||||
public override void Execute()
|
||||
{
|
||||
@@ -130,7 +130,7 @@ namespace LR35902
|
||||
}
|
||||
}
|
||||
|
||||
private void TickMachine()
|
||||
private void TickMachine()
|
||||
{
|
||||
this.Tick(4);
|
||||
this.OnMachineTicked();
|
||||
@@ -156,8 +156,8 @@ namespace LR35902
|
||||
|
||||
protected override void JumpRelative(sbyte offset)
|
||||
{
|
||||
base.JumpRelative(offset);
|
||||
this.TickMachine();
|
||||
base.JumpRelative(offset);
|
||||
this.TickMachine();
|
||||
}
|
||||
|
||||
protected override bool JumpConditional(bool condition)
|
||||
@@ -166,12 +166,12 @@ namespace LR35902
|
||||
{
|
||||
this.TickMachine();
|
||||
}
|
||||
return condition;
|
||||
return condition;
|
||||
}
|
||||
|
||||
protected override bool ReturnConditional(bool condition)
|
||||
{
|
||||
_ = base.ReturnConditional(condition);
|
||||
_ = base.ReturnConditional(condition);
|
||||
this.TickMachine();
|
||||
return condition;
|
||||
}
|
||||
@@ -187,7 +187,7 @@ namespace LR35902
|
||||
|
||||
protected override void Return()
|
||||
{
|
||||
base.Return();
|
||||
base.Return();
|
||||
this.TickMachine();
|
||||
}
|
||||
|
||||
@@ -669,6 +669,8 @@ namespace LR35902
|
||||
this.EI();
|
||||
//this.Tick();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -690,6 +692,8 @@ namespace LR35902
|
||||
case 0: // CALL nn
|
||||
this.CallIndirect();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -740,6 +744,8 @@ namespace LR35902
|
||||
throw new InvalidOperationException("Invalid operation mode");
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<GenerateDocumentationFile>False</GenerateDocumentationFile>
|
||||
<SignAssembly>False</SignAssembly>
|
||||
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
|
||||
<AnalysisLevel>latest</AnalysisLevel>
|
||||
<AnalysisLevel>latest-all</AnalysisLevel>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace LR35902
|
||||
|
||||
public ObjectAttribute(Ram ram, ushort address)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(ram);
|
||||
this.PositionY = ram.Peek(address);
|
||||
this.PositionX = ram.Peek(++address);
|
||||
this.Pattern = ram.Peek(++address);
|
||||
|
||||
Reference in New Issue
Block a user