mirror of
https://github.com/MoleskiCoder/EightBitNet.git
synced 2025-01-06 18:31:05 +00:00
first round of .net 9 analysis
This commit is contained in:
parent
b38462bddf
commit
0bc3cb9d03
@ -1,7 +1,7 @@
|
||||
// <copyright file="AbstractColourPalette.cs" company="Adrian Conlon">
|
||||
// Copyright (c) Adrian Conlon. All rights reserved.
|
||||
// </copyright>
|
||||
namespace EightBit.GameBoy
|
||||
namespace LR35902
|
||||
{
|
||||
public class AbstractColourPalette<T>
|
||||
{
|
||||
|
@ -1,11 +1,10 @@
|
||||
// <copyright file="Bus.cs" company="Adrian Conlon">
|
||||
// Copyright (c) Adrian Conlon. All rights reserved.
|
||||
// </copyright>
|
||||
namespace EightBit.GameBoy
|
||||
|
||||
namespace LR35902
|
||||
{
|
||||
using LR35902;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using EightBit;
|
||||
|
||||
public abstract class Bus : EightBit.Bus
|
||||
{
|
||||
@ -16,22 +15,19 @@ namespace EightBit.GameBoy
|
||||
public const int CyclesPerLine = CyclesPerFrame / TotalLineCount;
|
||||
public const int RomPageSize = 0x4000;
|
||||
|
||||
private readonly Rom bootRom = new(0x100); // 0x0000 - 0x00ff
|
||||
private readonly List<Rom> gameRomBanks = new(); // 0x0000 - 0x3fff, 0x4000 - 0x7fff (switchable)
|
||||
private readonly List<Ram> ramBanks = new(); // 0xa000 - 0xbfff (switchable)
|
||||
private readonly UnusedMemory unmapped2000 = new(0x2000, 0xff); // 0xa000 - 0xbfff
|
||||
private readonly Ram lowInternalRam = new(0x2000); // 0xc000 - 0xdfff (mirrored at 0xe000)
|
||||
private readonly UnusedMemory unmapped60 = new(0x60, 0xff); // 0xfea0 - 0xfeff
|
||||
private readonly Ram highInternalRam = new(0x80); // 0xff80 - 0xffff
|
||||
private readonly Rom bootRom = new(0x100); // 0x0000 - 0x00ff
|
||||
private readonly List<Rom> gameRomBanks = []; // 0x0000 - 0x3fff, 0x4000 - 0x7fff (switchable)
|
||||
private readonly List<Ram> ramBanks = []; // 0xa000 - 0xbfff (switchable)
|
||||
private readonly UnusedMemory unmapped2000 = new(0x2000, 0xff); // 0xa000 - 0xbfff
|
||||
private readonly Ram lowInternalRam = new(0x2000); // 0xc000 - 0xdfff (mirrored at 0xe000)
|
||||
private readonly UnusedMemory unmapped60 = new(0x60, 0xff); // 0xfea0 - 0xfeff
|
||||
private readonly Ram highInternalRam = new(0x80); // 0xff80 - 0xffff
|
||||
|
||||
private bool enabledLCD = false;
|
||||
|
||||
private bool disabledGameRom = false;
|
||||
|
||||
private bool rom = false;
|
||||
private bool banked = false;
|
||||
private bool ram = false;
|
||||
private bool battery = false;
|
||||
private bool enabledLCD;
|
||||
private bool rom;
|
||||
private bool banked;
|
||||
private bool ram;
|
||||
private bool battery;
|
||||
|
||||
private bool higherRomBank = true;
|
||||
private bool ramBankSwitching = false;
|
||||
@ -55,7 +51,7 @@ namespace EightBit.GameBoy
|
||||
|
||||
public IoRegisters IO { get; }
|
||||
|
||||
public bool GameRomDisabled => this.disabledGameRom;
|
||||
public bool GameRomDisabled { get; private set; } = false;
|
||||
|
||||
public bool GameRomEnabled => !this.GameRomDisabled;
|
||||
|
||||
@ -79,9 +75,9 @@ namespace EightBit.GameBoy
|
||||
this.CPU.LowerRESET();
|
||||
}
|
||||
|
||||
public void DisableGameRom() => this.disabledGameRom = true;
|
||||
public void DisableGameRom() => this.GameRomDisabled = true;
|
||||
|
||||
public void EnableGameRom() => this.disabledGameRom = false;
|
||||
public void EnableGameRom() => this.GameRomDisabled = false;
|
||||
|
||||
public void LoadBootRom(string path) => this.bootRom.Load(path);
|
||||
|
||||
@ -95,7 +91,7 @@ namespace EightBit.GameBoy
|
||||
for (var bank = 1; bank < banks; ++bank)
|
||||
{
|
||||
this.gameRomBanks.Add(new Rom());
|
||||
this.gameRomBanks[bank].Load(path, 0, bankSize * bank, bankSize);
|
||||
_ = this.gameRomBanks[bank].Load(path, 0, bankSize * bank, bankSize);
|
||||
}
|
||||
|
||||
this.ValidateCartridgeType();
|
||||
@ -116,17 +112,17 @@ namespace EightBit.GameBoy
|
||||
|
||||
public override MemoryMapping Mapping(ushort address)
|
||||
{
|
||||
if ((address < 0x100) && this.IO.BootRomEnabled)
|
||||
if (address < 0x100 && this.IO.BootRomEnabled)
|
||||
{
|
||||
return new MemoryMapping(this.bootRom, 0x0000, Mask.Sixteen, AccessLevel.ReadOnly);
|
||||
}
|
||||
|
||||
if ((address < 0x4000) && this.GameRomEnabled)
|
||||
if (address < 0x4000 && this.GameRomEnabled)
|
||||
{
|
||||
return new MemoryMapping(this.gameRomBanks[0], 0x0000, 0xffff, AccessLevel.ReadOnly);
|
||||
}
|
||||
|
||||
if ((address < 0x8000) && this.GameRomEnabled)
|
||||
if (address < 0x8000 && this.GameRomEnabled)
|
||||
{
|
||||
return new MemoryMapping(this.gameRomBanks[this.romBank], 0x4000, 0xffff, AccessLevel.ReadOnly);
|
||||
}
|
||||
@ -138,14 +134,9 @@ namespace EightBit.GameBoy
|
||||
|
||||
if (address < 0xc000)
|
||||
{
|
||||
if (this.ramBanks.Count == 0)
|
||||
{
|
||||
return new MemoryMapping(this.unmapped2000, 0xa000, 0xffff, AccessLevel.ReadOnly);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new MemoryMapping(this.ramBanks[this.ramBank], 0xa000, 0xffff, AccessLevel.ReadWrite);
|
||||
}
|
||||
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)
|
||||
@ -239,28 +230,19 @@ namespace EightBit.GameBoy
|
||||
this.rom = this.banked = this.ram = this.battery = false;
|
||||
|
||||
// ROM type
|
||||
switch (this.gameRomBanks[0].Peek(0x147))
|
||||
this.rom = this.gameRomBanks[0].Peek(0x147) switch
|
||||
{
|
||||
case (byte)CartridgeType.ROM:
|
||||
this.rom = true;
|
||||
break;
|
||||
case (byte)CartridgeType.ROM_MBC1:
|
||||
this.rom = this.banked = true;
|
||||
break;
|
||||
case (byte)CartridgeType.ROM_MBC1_RAM:
|
||||
this.rom = this.banked = this.ram = true;
|
||||
break;
|
||||
case (byte)CartridgeType.ROM_MBC1_RAM_BATTERY:
|
||||
this.rom = this.banked = this.ram = this.battery = true;
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException("Unhandled cartridge ROM type");
|
||||
}
|
||||
(byte)CartridgeType.ROM => true,
|
||||
(byte)CartridgeType.ROM_MBC1 => this.banked = true,
|
||||
(byte)CartridgeType.ROM_MBC1_RAM => this.banked = this.ram = true,
|
||||
(byte)CartridgeType.ROM_MBC1_RAM_BATTERY => this.banked = this.ram = this.battery = true,
|
||||
_ => throw new InvalidOperationException("Unhandled cartridge ROM type"),
|
||||
};
|
||||
|
||||
// ROM size
|
||||
{
|
||||
var gameRomBanks = 0;
|
||||
var romSizeSpecification = this.Peek(0x148);
|
||||
int gameRomBanks;
|
||||
switch (romSizeSpecification)
|
||||
{
|
||||
case 0x52:
|
||||
@ -278,7 +260,7 @@ namespace EightBit.GameBoy
|
||||
throw new InvalidOperationException("Invalid ROM size specification");
|
||||
}
|
||||
|
||||
gameRomBanks = 1 << (romSizeSpecification + 1);
|
||||
gameRomBanks = 1 << romSizeSpecification + 1;
|
||||
if (gameRomBanks != this.gameRomBanks.Count)
|
||||
{
|
||||
throw new InvalidOperationException("ROM size specification mismatch");
|
||||
@ -393,7 +375,7 @@ namespace EightBit.GameBoy
|
||||
this.allowed += suggested;
|
||||
if (this.enabledLCD)
|
||||
{
|
||||
if (((this.IO.Peek(IoRegisters.STAT) & (byte)Bits.Bit6) != 0) && (this.IO.Peek(IoRegisters.LYC) == this.IO.Peek(IoRegisters.LY)))
|
||||
if ((this.IO.Peek(IoRegisters.STAT) & (byte)Bits.Bit6) != 0 && this.IO.Peek(IoRegisters.LYC) == this.IO.Peek(IoRegisters.LY))
|
||||
{
|
||||
this.IO.TriggerInterrupt(Interrupts.DisplayControlStatus);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
// <copyright file="CartridgeType.cs" company="Adrian Conlon">
|
||||
// Copyright (c) Adrian Conlon. All rights reserved.
|
||||
// </copyright>
|
||||
namespace EightBit.GameBoy
|
||||
namespace LR35902
|
||||
{
|
||||
public enum CartridgeType
|
||||
{
|
||||
|
@ -1,18 +1,15 @@
|
||||
// <copyright file="CharacterDefinition.cs" company="Adrian Conlon">
|
||||
// Copyright (c) Adrian Conlon. All rights reserved.
|
||||
// </copyright>
|
||||
namespace EightBit.GameBoy
|
||||
{
|
||||
public sealed class CharacterDefinition
|
||||
{
|
||||
private readonly Ram vram;
|
||||
private readonly ushort address;
|
||||
|
||||
public CharacterDefinition(Ram vram, ushort address)
|
||||
{
|
||||
this.vram = vram;
|
||||
this.address = address;
|
||||
}
|
||||
namespace LR35902
|
||||
{
|
||||
using EightBit;
|
||||
|
||||
public sealed class CharacterDefinition(Ram vram, ushort address)
|
||||
{
|
||||
private readonly Ram vram = vram;
|
||||
private readonly ushort address = address;
|
||||
|
||||
public int[] Get(int row)
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
// <copyright file="ColourShades.cs" company="Adrian Conlon">
|
||||
// Copyright (c) Adrian Conlon. All rights reserved.
|
||||
// </copyright>
|
||||
namespace EightBit.GameBoy
|
||||
namespace LR35902
|
||||
{
|
||||
public enum ColourShades
|
||||
{
|
||||
|
@ -2,9 +2,9 @@
|
||||
// Copyright (c) Adrian Conlon. All rights reserved.
|
||||
// </copyright>
|
||||
|
||||
namespace EightBit.GameBoy
|
||||
namespace LR35902
|
||||
{
|
||||
using LR35902;
|
||||
using EightBit;
|
||||
|
||||
public enum IoRegister
|
||||
{
|
||||
@ -14,13 +14,11 @@ namespace EightBit.GameBoy
|
||||
Unused, // Unused!
|
||||
}
|
||||
|
||||
public class Disassembler
|
||||
public sealed class Disassembler(Bus bus)
|
||||
{
|
||||
private bool prefixCB = false;
|
||||
|
||||
public Disassembler(Bus bus) => this.Bus = bus;
|
||||
|
||||
public Bus Bus { get; }
|
||||
public Bus Bus { get; } = bus;
|
||||
|
||||
public static string AsFlag(byte value, byte flag, string represents) => (value & flag) != 0 ? represents : "-";
|
||||
|
||||
@ -69,224 +67,117 @@ namespace EightBit.GameBoy
|
||||
return this.Disassemble(cpu, cpu.PC.Word);
|
||||
}
|
||||
|
||||
private static string RP(int rp)
|
||||
private static string RP(int rp) => rp switch
|
||||
{
|
||||
switch (rp)
|
||||
{
|
||||
case 0:
|
||||
return "BC";
|
||||
case 1:
|
||||
return "DE";
|
||||
case 2:
|
||||
return "HL";
|
||||
case 3:
|
||||
return "SP";
|
||||
}
|
||||
0 => "BC",
|
||||
1 => "DE",
|
||||
2 => "HL",
|
||||
3 => "SP",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(rp)),
|
||||
};
|
||||
|
||||
throw new System.ArgumentOutOfRangeException(nameof(rp));
|
||||
}
|
||||
|
||||
private static string RP2(int rp)
|
||||
private static string RP2(int rp) => rp switch
|
||||
{
|
||||
switch (rp)
|
||||
{
|
||||
case 0:
|
||||
return "BC";
|
||||
case 1:
|
||||
return "DE";
|
||||
case 2:
|
||||
return "HL";
|
||||
case 3:
|
||||
return "AF";
|
||||
}
|
||||
0 => "BC",
|
||||
1 => "DE",
|
||||
2 => "HL",
|
||||
3 => "AF",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(rp)),
|
||||
};
|
||||
|
||||
throw new System.ArgumentOutOfRangeException(nameof(rp));
|
||||
}
|
||||
|
||||
private static string R(int r)
|
||||
private static string R(int r) => r switch
|
||||
{
|
||||
switch (r)
|
||||
{
|
||||
case 0:
|
||||
return "B";
|
||||
case 1:
|
||||
return "C";
|
||||
case 2:
|
||||
return "D";
|
||||
case 3:
|
||||
return "E";
|
||||
case 4:
|
||||
return "H";
|
||||
case 5:
|
||||
return "L";
|
||||
case 6:
|
||||
return "(HL)";
|
||||
case 7:
|
||||
return "A";
|
||||
}
|
||||
0 => "B",
|
||||
1 => "C",
|
||||
2 => "D",
|
||||
3 => "E",
|
||||
4 => "H",
|
||||
5 => "L",
|
||||
6 => "(HL)",
|
||||
7 => "A",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(r)),
|
||||
};
|
||||
|
||||
throw new System.ArgumentOutOfRangeException(nameof(r));
|
||||
}
|
||||
|
||||
private static string IO(byte value)
|
||||
private static string IO(byte value) => value switch
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
// Port/Mode Registers
|
||||
case IoRegisters.P1:
|
||||
return "P1";
|
||||
case IoRegisters.SB:
|
||||
return "SB";
|
||||
case IoRegisters.SC:
|
||||
return "SC";
|
||||
case IoRegisters.DIV:
|
||||
return "DIV";
|
||||
case IoRegisters.TIMA:
|
||||
return "TIMA";
|
||||
case IoRegisters.TMA:
|
||||
return "TMA";
|
||||
case IoRegisters.TAC:
|
||||
return "TAC";
|
||||
// Port/Mode Registers
|
||||
IoRegisters.P1 => "P1",
|
||||
IoRegisters.SB => "SB",
|
||||
IoRegisters.SC => "SC",
|
||||
IoRegisters.DIV => "DIV",
|
||||
IoRegisters.TIMA => "TIMA",
|
||||
IoRegisters.TMA => "TMA",
|
||||
IoRegisters.TAC => "TAC",
|
||||
// Interrupt Flags
|
||||
IoRegisters.IF => "IF",
|
||||
IoRegisters.IE => "IE",
|
||||
// LCD Display Registers
|
||||
IoRegisters.LCDC => "LCDC",
|
||||
IoRegisters.STAT => "STAT",
|
||||
IoRegisters.SCY => "SCY",
|
||||
IoRegisters.SCX => "SCX",
|
||||
IoRegisters.LY => "LY",
|
||||
IoRegisters.LYC => "LYC",
|
||||
IoRegisters.DMA => "DMA",
|
||||
IoRegisters.BGP => "BGP",
|
||||
IoRegisters.OBP0 => "OBP0",
|
||||
IoRegisters.OBP1 => "OBP1",
|
||||
IoRegisters.WY => "WY",
|
||||
IoRegisters.WX => "WX",
|
||||
// Sound Registers
|
||||
IoRegisters.NR10 => "NR10",
|
||||
IoRegisters.NR11 => "NR11",
|
||||
IoRegisters.NR12 => "NR12",
|
||||
IoRegisters.NR13 => "NR13",
|
||||
IoRegisters.NR14 => "NR14",
|
||||
IoRegisters.NR21 => "NR21",
|
||||
IoRegisters.NR22 => "NR22",
|
||||
IoRegisters.NR23 => "NR23",
|
||||
IoRegisters.NR24 => "NR24",
|
||||
IoRegisters.NR30 => "NR30",
|
||||
IoRegisters.NR31 => "NR31",
|
||||
IoRegisters.NR32 => "NR32",
|
||||
IoRegisters.NR33 => "NR33",
|
||||
IoRegisters.NR34 => "NR34",
|
||||
IoRegisters.NR41 => "NR41",
|
||||
IoRegisters.NR42 => "NR42",
|
||||
IoRegisters.NR43 => "NR43",
|
||||
IoRegisters.NR44 => "NR44",
|
||||
IoRegisters.NR50 => "NR50",
|
||||
IoRegisters.NR51 => "NR51",
|
||||
IoRegisters.NR52 => "NR52",
|
||||
IoRegisters.WAVE_PATTERN_RAM_START => "WAVE_PATTERN_RAM_START",
|
||||
IoRegisters.WAVE_PATTERN_RAM_END => "WAVE_PATTERN_RAM_END",
|
||||
// Boot rom control
|
||||
IoRegisters.BOOT_DISABLE => "BOOT_DISABLE",
|
||||
_ => $"{value:x2}",
|
||||
};
|
||||
|
||||
// Interrupt Flags
|
||||
case IoRegisters.IF:
|
||||
return "IF";
|
||||
case IoRegisters.IE:
|
||||
return "IE";
|
||||
|
||||
// LCD Display Registers
|
||||
case IoRegisters.LCDC:
|
||||
return "LCDC";
|
||||
case IoRegisters.STAT:
|
||||
return "STAT";
|
||||
case IoRegisters.SCY:
|
||||
return "SCY";
|
||||
case IoRegisters.SCX:
|
||||
return "SCX";
|
||||
case IoRegisters.LY:
|
||||
return "LY";
|
||||
case IoRegisters.LYC:
|
||||
return "LYC";
|
||||
case IoRegisters.DMA:
|
||||
return "DMA";
|
||||
case IoRegisters.BGP:
|
||||
return "BGP";
|
||||
case IoRegisters.OBP0:
|
||||
return "OBP0";
|
||||
case IoRegisters.OBP1:
|
||||
return "OBP1";
|
||||
case IoRegisters.WY:
|
||||
return "WY";
|
||||
case IoRegisters.WX:
|
||||
return "WX";
|
||||
|
||||
// Sound Registers
|
||||
case IoRegisters.NR10:
|
||||
return "NR10";
|
||||
case IoRegisters.NR11:
|
||||
return "NR11";
|
||||
case IoRegisters.NR12:
|
||||
return "NR12";
|
||||
case IoRegisters.NR13:
|
||||
return "NR13";
|
||||
case IoRegisters.NR14:
|
||||
return "NR14";
|
||||
case IoRegisters.NR21:
|
||||
return "NR21";
|
||||
case IoRegisters.NR22:
|
||||
return "NR22";
|
||||
case IoRegisters.NR23:
|
||||
return "NR23";
|
||||
case IoRegisters.NR24:
|
||||
return "NR24";
|
||||
case IoRegisters.NR30:
|
||||
return "NR30";
|
||||
case IoRegisters.NR31:
|
||||
return "NR31";
|
||||
case IoRegisters.NR32:
|
||||
return "NR32";
|
||||
case IoRegisters.NR33:
|
||||
return "NR33";
|
||||
case IoRegisters.NR34:
|
||||
return "NR34";
|
||||
case IoRegisters.NR41:
|
||||
return "NR41";
|
||||
case IoRegisters.NR42:
|
||||
return "NR42";
|
||||
case IoRegisters.NR43:
|
||||
return "NR43";
|
||||
case IoRegisters.NR44:
|
||||
return "NR44";
|
||||
case IoRegisters.NR50:
|
||||
return "NR50";
|
||||
case IoRegisters.NR51:
|
||||
return "NR51";
|
||||
case IoRegisters.NR52:
|
||||
return "NR52";
|
||||
|
||||
case IoRegisters.WAVE_PATTERN_RAM_START:
|
||||
return "WAVE_PATTERN_RAM_START";
|
||||
case IoRegisters.WAVE_PATTERN_RAM_END:
|
||||
return "WAVE_PATTERN_RAM_END";
|
||||
|
||||
// Boot rom control
|
||||
case IoRegisters.BOOT_DISABLE:
|
||||
return "BOOT_DISABLE";
|
||||
|
||||
default:
|
||||
return $"{value:x2}";
|
||||
}
|
||||
}
|
||||
|
||||
private static string CC(int flag)
|
||||
private static string CC(int flag) => flag switch
|
||||
{
|
||||
switch (flag)
|
||||
{
|
||||
case 0:
|
||||
return "NZ";
|
||||
case 1:
|
||||
return "Z";
|
||||
case 2:
|
||||
return "NC";
|
||||
case 3:
|
||||
return "C";
|
||||
case 4:
|
||||
return "PO";
|
||||
case 5:
|
||||
return "PE";
|
||||
case 6:
|
||||
return "P";
|
||||
case 7:
|
||||
return "M";
|
||||
}
|
||||
0 => "NZ",
|
||||
1 => "Z",
|
||||
2 => "NC",
|
||||
3 => "C",
|
||||
4 => "PO",
|
||||
5 => "PE",
|
||||
6 => "P",
|
||||
7 => "M",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(flag)),
|
||||
};
|
||||
|
||||
throw new System.ArgumentOutOfRangeException(nameof(flag));
|
||||
}
|
||||
|
||||
private static string ALU(int which)
|
||||
private static string ALU(int which) => which switch
|
||||
{
|
||||
switch (which)
|
||||
{
|
||||
case 0: // ADD A,n
|
||||
return "ADD";
|
||||
case 1: // ADC
|
||||
return "ADC";
|
||||
case 2: // SUB n
|
||||
return "SUB";
|
||||
case 3: // SBC A,n
|
||||
return "SBC";
|
||||
case 4: // AND n
|
||||
return "AND";
|
||||
case 5: // XOR n
|
||||
return "XOR";
|
||||
case 6: // OR n
|
||||
return "OR";
|
||||
case 7: // CP n
|
||||
return "CP";
|
||||
}
|
||||
|
||||
throw new System.ArgumentOutOfRangeException(nameof(which));
|
||||
}
|
||||
0 => "ADD", // ADD A,n
|
||||
1 => "ADC", // ADC
|
||||
2 => "SUB", // SUB n
|
||||
3 => "SBC", // SBC A,n
|
||||
4 => "AND", // AND n
|
||||
5 => "XOR", // XOR n
|
||||
6 => "OR", // OR n
|
||||
7 => "CP", // CP n
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(which)),
|
||||
};
|
||||
|
||||
private static string DisassembleCB(ref string specification, int x, int y, int z)
|
||||
{
|
||||
|
@ -1,26 +1,21 @@
|
||||
// <copyright file="Display.cs" company="Adrian Conlon">
|
||||
// Copyright (c) Adrian Conlon. All rights reserved.
|
||||
// </copyright>
|
||||
namespace EightBit.GameBoy
|
||||
|
||||
namespace LR35902
|
||||
{
|
||||
public sealed class Display<T>
|
||||
using EightBit;
|
||||
|
||||
public sealed class Display<T>(AbstractColourPalette<T> colours, Bus bus, Ram oam, Ram vram)
|
||||
{
|
||||
private readonly Bus bus;
|
||||
private readonly Ram oam;
|
||||
private readonly Ram vram;
|
||||
private readonly AbstractColourPalette<T> colours;
|
||||
private readonly Bus bus = bus;
|
||||
private readonly Ram oam = oam;
|
||||
private readonly Ram vram = vram;
|
||||
private readonly AbstractColourPalette<T> colours = colours;
|
||||
private readonly ObjectAttribute[] objectAttributes = new ObjectAttribute[40];
|
||||
private byte control;
|
||||
private byte scanLine = 0;
|
||||
|
||||
public Display(AbstractColourPalette<T> colours, Bus bus, Ram oam, Ram vram)
|
||||
{
|
||||
this.colours = colours;
|
||||
this.bus = bus;
|
||||
this.oam = oam;
|
||||
this.vram = vram;
|
||||
}
|
||||
|
||||
public T[] Pixels { get; } = new T[DisplayCharacteristics.PixelCount];
|
||||
|
||||
public void Render()
|
||||
@ -55,13 +50,13 @@ namespace EightBit.GameBoy
|
||||
private int[] CreatePalette(ushort address)
|
||||
{
|
||||
var raw = this.bus.IO.Peek(address);
|
||||
return new int[4]
|
||||
{
|
||||
return
|
||||
[
|
||||
raw & 0b11,
|
||||
(raw & 0b1100) >> 2,
|
||||
(raw & 0b110000) >> 4,
|
||||
(raw & 0b11000000) >> 6,
|
||||
};
|
||||
];
|
||||
}
|
||||
|
||||
private void RenderBackground()
|
||||
@ -114,7 +109,7 @@ namespace EightBit.GameBoy
|
||||
var spriteY = current.PositionY;
|
||||
var drawY = spriteY - 16;
|
||||
|
||||
if ((this.scanLine >= drawY) && (this.scanLine < (drawY + objBlockHeight)))
|
||||
if (this.scanLine >= drawY && this.scanLine < drawY + objBlockHeight)
|
||||
{
|
||||
var spriteX = current.PositionX;
|
||||
var drawX = spriteX - 8;
|
||||
@ -156,7 +151,7 @@ namespace EightBit.GameBoy
|
||||
}
|
||||
|
||||
var colour = rowDefinition[cx];
|
||||
if (!allowTransparencies || (allowTransparencies && (colour > 0)))
|
||||
if (!allowTransparencies || (allowTransparencies && colour > 0))
|
||||
{
|
||||
var outputPixel = lineAddress + x;
|
||||
this.Pixels[outputPixel] = this.colours.Colour(palette[colour]);
|
||||
|
@ -1,7 +1,7 @@
|
||||
// <copyright file="DisplayCharacteristics.cs" company="Adrian Conlon">
|
||||
// Copyright (c) Adrian Conlon. All rights reserved.
|
||||
// </copyright>
|
||||
namespace EightBit.GameBoy
|
||||
namespace LR35902
|
||||
{
|
||||
public static class DisplayCharacteristics
|
||||
{
|
||||
|
@ -1,10 +1,13 @@
|
||||
// <copyright file="Interrupts.cs" company="Adrian Conlon">
|
||||
// Copyright (c) Adrian Conlon. All rights reserved.
|
||||
// </copyright>
|
||||
namespace EightBit.GameBoy
|
||||
|
||||
namespace LR35902
|
||||
{
|
||||
using EightBit;
|
||||
|
||||
// IF and IE flags
|
||||
[System.Flags]
|
||||
[Flags]
|
||||
public enum Interrupts
|
||||
{
|
||||
None = 0,
|
||||
|
@ -1,11 +1,12 @@
|
||||
// <copyright file="IoRegisters.cs" company="Adrian Conlon">
|
||||
// Copyright (c) Adrian Conlon. All rights reserved.
|
||||
// </copyright>
|
||||
namespace EightBit.GameBoy
|
||||
{
|
||||
using System;
|
||||
|
||||
public sealed class IoRegisters : EightBit.Ram
|
||||
namespace LR35902
|
||||
{
|
||||
using EightBit;
|
||||
|
||||
public sealed class IoRegisters : Ram
|
||||
{
|
||||
public const int BASE = 0xFF00;
|
||||
|
||||
@ -174,7 +175,7 @@ namespace EightBit.GameBoy
|
||||
this.TimerCounter = Chip.LowByte(updated);
|
||||
}
|
||||
|
||||
public void IncrementLY() => this.Poke(LY, (byte)((this.Peek(LY) + 1) % GameBoy.Bus.TotalLineCount));
|
||||
public void IncrementLY() => this.Poke(LY, (byte)((this.Peek(LY) + 1) % Bus.TotalLineCount));
|
||||
|
||||
public void ResetLY() => this.Poke(LY, 0);
|
||||
|
||||
@ -288,7 +289,7 @@ namespace EightBit.GameBoy
|
||||
|
||||
private void TriggerKeypadInterrupt() => this.TriggerInterrupt(Interrupts.KeypadPressed);
|
||||
|
||||
private void Bus_WrittenByte(object? sender, System.EventArgs e)
|
||||
private void Bus_WrittenByte(object? sender, EventArgs e)
|
||||
{
|
||||
var address = this.bus.Address.Word;
|
||||
var value = this.bus.Data;
|
||||
@ -344,10 +345,10 @@ namespace EightBit.GameBoy
|
||||
}
|
||||
}
|
||||
|
||||
private void Bus_ReadingByte(object? sender, System.EventArgs e)
|
||||
private void Bus_ReadingByte(object? sender, EventArgs e)
|
||||
{
|
||||
var address = this.bus.Address.Word;
|
||||
var io = (address >= BASE) && (address < 0xff80);
|
||||
var io = address >= BASE && address < 0xff80;
|
||||
if (io)
|
||||
{
|
||||
var port = (ushort)(address - BASE);
|
||||
@ -359,10 +360,10 @@ namespace EightBit.GameBoy
|
||||
var directionKeys = this.scanP14 && !this.p14;
|
||||
var miscKeys = this.scanP15 && !this.p15;
|
||||
var live = directionKeys || miscKeys;
|
||||
var rightOrA = (live && !this.p10) ? 0 : Bits.Bit0;
|
||||
var leftOrB = (live && !this.p11) ? 0 : Bits.Bit1;
|
||||
var upOrSelect = (live && !this.p12) ? 0 : Bits.Bit2;
|
||||
var downOrStart = (live && !this.p13) ? 0 : Bits.Bit3;
|
||||
var rightOrA = live && !this.p10 ? 0 : Bits.Bit0;
|
||||
var leftOrB = live && !this.p11 ? 0 : Bits.Bit1;
|
||||
var upOrSelect = live && !this.p12 ? 0 : Bits.Bit2;
|
||||
var downOrStart = live && !this.p13 ? 0 : Bits.Bit3;
|
||||
var lowNibble = (byte)(rightOrA | leftOrB | upOrSelect | downOrStart);
|
||||
var highNibble = (byte)Chip.PromoteNibble((byte)Mask.Four);
|
||||
var value = (byte)(lowNibble | highNibble);
|
||||
|
@ -6,15 +6,15 @@ namespace LR35902.BlarggTest
|
||||
{
|
||||
using System;
|
||||
|
||||
internal class Board : EightBit.GameBoy.Bus
|
||||
internal class Board : Bus
|
||||
{
|
||||
private readonly Configuration configuration;
|
||||
private readonly EightBit.GameBoy.Disassembler disassembler;
|
||||
private readonly Disassembler disassembler;
|
||||
|
||||
public Board(Configuration configuration)
|
||||
{
|
||||
this.configuration = configuration;
|
||||
this.disassembler = new EightBit.GameBoy.Disassembler(this);
|
||||
this.disassembler = new Disassembler(this);
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
@ -34,7 +34,7 @@ namespace LR35902.BlarggTest
|
||||
{
|
||||
switch (this.Address.Word)
|
||||
{
|
||||
case EightBit.GameBoy.IoRegisters.BASE + EightBit.GameBoy.IoRegisters.SB:
|
||||
case IoRegisters.BASE + IoRegisters.SB:
|
||||
System.Console.Out.Write(Convert.ToChar(this.Data));
|
||||
break;
|
||||
default:
|
||||
@ -46,7 +46,7 @@ namespace LR35902.BlarggTest
|
||||
{
|
||||
if (this.IO.BootRomDisabled)
|
||||
{
|
||||
System.Console.Error.WriteLine($"{EightBit.GameBoy.Disassembler.State(this.CPU)} {this.disassembler.Disassemble(this.CPU)}");
|
||||
System.Console.Error.WriteLine($"{Disassembler.State(this.CPU)} {this.disassembler.Disassemble(this.CPU)}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
namespace Fuse
|
||||
{
|
||||
using LR35902;
|
||||
|
||||
public enum Register
|
||||
{
|
||||
AF,
|
||||
@ -14,7 +16,7 @@ namespace Fuse
|
||||
PC,
|
||||
}
|
||||
|
||||
public class TestRunner<T> : EightBit.GameBoy.Bus
|
||||
public class TestRunner<T> : LR35902.Bus
|
||||
where T : Fuse.IRegisterState, new()
|
||||
{
|
||||
private readonly Test<T> test;
|
||||
|
@ -5,8 +5,6 @@
|
||||
namespace LR35902
|
||||
{
|
||||
using EightBit;
|
||||
using EightBit.GameBoy;
|
||||
using Bus = EightBit.GameBoy.Bus;
|
||||
|
||||
public sealed class LR35902(Bus bus) : IntelProcessor(bus)
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
// <copyright file="LcdStatusMode.cs" company="Adrian Conlon">
|
||||
// Copyright (c) Adrian Conlon. All rights reserved.
|
||||
// </copyright>
|
||||
namespace EightBit.GameBoy
|
||||
namespace LR35902
|
||||
{
|
||||
public enum LcdStatusMode
|
||||
{
|
||||
|
@ -1,14 +1,10 @@
|
||||
// <copyright file="LcdStatusModeEventArgs.cs" company="Adrian Conlon">
|
||||
// Copyright (c) Adrian Conlon. All rights reserved.
|
||||
// </copyright>
|
||||
namespace EightBit.GameBoy
|
||||
namespace LR35902
|
||||
{
|
||||
using System;
|
||||
|
||||
public class LcdStatusModeEventArgs : EventArgs
|
||||
public class LcdStatusModeEventArgs(LcdStatusMode value) : EventArgs
|
||||
{
|
||||
public LcdStatusModeEventArgs(LcdStatusMode value) => this.Mode = value;
|
||||
|
||||
public LcdStatusMode Mode { get; }
|
||||
public LcdStatusMode Mode { get; } = value;
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,12 @@
|
||||
// <copyright file="LcdcControl.cs" company="Adrian Conlon">
|
||||
// Copyright (c) Adrian Conlon. All rights reserved.
|
||||
// </copyright>
|
||||
namespace EightBit.GameBoy
|
||||
|
||||
namespace LR35902
|
||||
{
|
||||
[System.Flags]
|
||||
using EightBit;
|
||||
|
||||
[Flags]
|
||||
public enum LcdcControls
|
||||
{
|
||||
None = 0,
|
||||
|
@ -1,8 +1,11 @@
|
||||
// <copyright file="ObjectAttribute.cs" company="Adrian Conlon">
|
||||
// Copyright (c) Adrian Conlon. All rights reserved.
|
||||
// </copyright>
|
||||
namespace EightBit.GameBoy
|
||||
|
||||
namespace LR35902
|
||||
{
|
||||
using EightBit;
|
||||
|
||||
public class ObjectAttribute
|
||||
{
|
||||
public ObjectAttribute()
|
||||
|
@ -1,9 +1,12 @@
|
||||
// <copyright file="StatusBits.cs" company="Adrian Conlon">
|
||||
// Copyright (c) Adrian Conlon. All rights reserved.
|
||||
// </copyright>
|
||||
namespace EightBit.GameBoy
|
||||
|
||||
namespace LR35902
|
||||
{
|
||||
[System.Flags]
|
||||
using EightBit;
|
||||
|
||||
[Flags]
|
||||
public enum StatusBits
|
||||
{
|
||||
None = 0,
|
||||
|
Loading…
Reference in New Issue
Block a user