diff --git a/LR35902/Bus.cs b/LR35902/Bus.cs index d863015..299740e 100644 --- a/LR35902/Bus.cs +++ b/LR35902/Bus.cs @@ -83,15 +83,20 @@ namespace LR35902 public void LoadGameRom(string path) { - const int bankSize = 0x4000; this.gameRomBanks.Clear(); - this.gameRomBanks.Add(new Rom()); - var size = this.gameRomBanks[0].Load(path, 0, 0, bankSize); + + const int bankSize = 0x4000; + + var rom = new Rom(); + var size = rom.Load(path, 0, 0, bankSize); + this.gameRomBanks.Add(rom); + var banks = size / bankSize; for (var bank = 1; bank < banks; ++bank) { - this.gameRomBanks.Add(new Rom()); - _ = this.gameRomBanks[bank].Load(path, 0, bankSize * bank, bankSize); + var bankedROM = new Rom(); + _ = bankedROM.Load(path, 0, bankSize * bank, bankSize); + this.gameRomBanks.Add(bankedROM); } this.ValidateCartridgeType(); @@ -99,7 +104,7 @@ namespace LR35902 public void RunRasterLines() { - this.enabledLCD = (this.IO.Peek(IoRegisters.LCDC) & (byte)LcdcControls.LcdEnable) != 0; + this.enabledLCD = (this.IO.Peek(IoRegisters.LCDC) & (byte)LcdcControls.LCD_EN) != 0; this.IO.ResetLY(); this.RunRasterLines(DisplayCharacteristics.RasterHeight); } @@ -406,7 +411,7 @@ namespace LR35902 } else { - this.allowed -= this.CPU.Run(this.allowed); + this.allowed -= this.CPU.Run(CyclesPerLine); } } } diff --git a/LR35902/CharacterDefinition.cs b/LR35902/CharacterDefinition.cs index 6ead95a..c0d2e2b 100644 --- a/LR35902/CharacterDefinition.cs +++ b/LR35902/CharacterDefinition.cs @@ -22,12 +22,13 @@ namespace LR35902 for (var bit = 0; bit < 8; ++bit) { - var mask = 1 << bit; + var mask = Chip.Bit(bit); var bitLow = (planeLow & mask) != 0 ? 1 : 0; var bitHigh = (planeHigh & mask) != 0 ? 0b10 : 0; - returned[7 - bit] = bitHigh | bitLow; + var index = 7 - bit; + returned[index] = bitHigh | bitLow; } return returned; diff --git a/LR35902/Display.cs b/LR35902/Display.cs index 544565c..a17e974 100644 --- a/LR35902/Display.cs +++ b/LR35902/Display.cs @@ -24,14 +24,14 @@ namespace LR35902 if (this.scanLine < DisplayCharacteristics.RasterHeight) { this.control = this.bus.IO.Peek(IoRegisters.LCDC); - if ((this.control & (byte)LcdcControls.LcdEnable) != 0) + if ((this.control & (byte)LcdcControls.LCD_EN) != 0) { - if ((this.control & (byte)LcdcControls.DisplayBackground) != 0) + if ((this.control & (byte)LcdcControls.BG_EN) != 0) { this.RenderBackground(); } - if ((this.control & (byte)LcdcControls.ObjectEnable) != 0) + if ((this.control & (byte)LcdcControls.OBJ_EN) != 0) { this.RenderObjects(); } @@ -63,9 +63,9 @@ namespace LR35902 { var palette = this.CreatePalette(IoRegisters.BGP); - var window = (this.control & (byte)LcdcControls.WindowEnable) != 0; - var bgArea = (this.control & (byte)LcdcControls.BackgroundCodeAreaSelection) != 0 ? 0x1c00 : 0x1800; - var bgCharacters = (this.control & (byte)LcdcControls.BackgroundCharacterDataSelection) != 0 ? 0 : 0x800; + var window = (this.control & (byte)LcdcControls.WIN_EN) != 0; + var bgArea = (this.control & (byte)LcdcControls.BG_MAP) != 0 ? 0x1c00 : 0x1800; + var bgCharacters = (this.control & (byte)LcdcControls.TILE_SEL) != 0 ? 0 : 0x800; var wx = this.bus.IO.Peek(IoRegisters.WX); var wy = this.bus.IO.Peek(IoRegisters.WY); @@ -88,13 +88,16 @@ namespace LR35902 { var character = this.vram.Peek((ushort)address++); var definition = new CharacterDefinition(this.vram, (ushort)(bgCharacters + (16 * character))); - this.RenderTile(8, (column * 8) + offsetX, (row * 8) + offsetY, false, false, false, palette, definition); + this.RenderBackgroundTile( + (column * 8) + offsetX, (row * 8) + offsetY, + palette, + definition); } } private void RenderObjects() { - var objBlockHeight = (this.control & (byte)LcdcControls.ObjectBlockCompositionSelection) != 0 ? 16 : 8; + var objBlockHeight = (this.control & (byte)LcdcControls.OBJ_SIZE) != 0 ? 16 : 8; var palettes = new int[2][]; palettes[0] = this.CreatePalette(IoRegisters.OBP0); @@ -120,12 +123,45 @@ namespace LR35902 var flipX = current.FlipX; var flipY = current.FlipY; - this.RenderTile(objBlockHeight, drawX, drawY, flipX, flipY, true, palette, definition); + this.RenderSpriteTile( + objBlockHeight, + drawX, drawY, + flipX, flipY, + palette, + definition); } } } - private void RenderTile(int height, int drawX, int drawY, bool flipX, bool flipY, bool allowTransparencies, int[] palette, CharacterDefinition definition) + private void RenderSpriteTile( + int height, + int drawX, int drawY, + bool flipX, bool flipY, + int[] palette, + CharacterDefinition definition) => this.RenderTile( + height, + drawX, drawY, + flipX, flipY, true, + palette, + definition); + + private void RenderBackgroundTile( + int drawX, int drawY, + int[] palette, + CharacterDefinition definition) => this.RenderTile( + 8, + drawX, drawY, + false, false, false, + palette, + definition); + + private void RenderTile( + int height, + int drawX, int drawY, + bool flipX, bool flipY, + bool allowTransparencies, + int[] palette, + CharacterDefinition definition) { const int width = 8; const int flipMaskX = width - 1; diff --git a/LR35902/IoRegisters.cs b/LR35902/IoRegisters.cs index f44df03..6496b34 100644 --- a/LR35902/IoRegisters.cs +++ b/LR35902/IoRegisters.cs @@ -122,7 +122,7 @@ namespace LR35902 public void Reset() { this.Poke(NR52, 0xf1); - this.Poke(LCDC, (byte)(LcdcControls.DisplayBackground | LcdcControls.BackgroundCharacterDataSelection | LcdcControls.LcdEnable)); + this.Poke(LCDC, (byte)(LcdcControls.BG_EN | LcdcControls.TILE_SEL | LcdcControls.LCD_EN)); this.divCounter.Word = 0xabcc; this.timerCounter = 0; } @@ -168,7 +168,7 @@ namespace LR35902 public void UpdateLcdStatusMode(LcdStatusMode mode) { - var current = this.Peek(STAT) & unchecked((byte)~Mask.Two); + var current = this.Peek(STAT) & ~(byte)Mask.Two; this.Poke(STAT, (byte)(current | (int)mode)); this.OnDisplayStatusModeUpdated(mode); } @@ -273,6 +273,12 @@ namespace LR35902 private void ApplyMask(ushort address, byte masking) => this.Poke(address, (byte)(this.Peek(address) | ~masking)); + private void ApplyMask(ushort address, int masking) => this.ApplyMask(address, (byte)masking); + + private void ApplyMask(ushort address, Bits masking) => this.ApplyMask(address, (byte)masking); + + private void ApplyMask(ushort address, Mask masking) => this.ApplyMask(address, (byte)masking); + private void TriggerKeypadInterrupt() => this.TriggerInterrupt(Interrupts.KeypadPressed); private void Bus_WrittenByte(object? sender, EventArgs e) @@ -335,7 +341,7 @@ namespace LR35902 private void Bus_ReadingByte(object? sender, EventArgs e) { var address = this.bus.Address.Word; - var io = address >= BASE && address < 0xff80; + var io = address is >= BASE and < 0xff80; if (io) { var port = (ushort)(address - BASE); @@ -361,7 +367,7 @@ namespace LR35902 case SB: break; case SC: - this.ApplyMask(port, (byte)(Bits.Bit7 | Bits.Bit0)); + this.ApplyMask(port, Bits.Bit7 | Bits.Bit0); break; // Timer control @@ -370,19 +376,19 @@ namespace LR35902 case TMA: break; case TAC: - this.ApplyMask(port, (byte)Mask.Three); + this.ApplyMask(port, Mask.Three); break; // Interrupt Flags case IF: - this.ApplyMask(port, (byte)Mask.Five); + this.ApplyMask(port, Mask.Five); break; // LCD Display Registers case LCDC: break; case STAT: - this.ApplyMask(port, (byte)Mask.Seven); + this.ApplyMask(port, Mask.Seven); break; case SCY: case SCX: diff --git a/LR35902/LR35902.cs b/LR35902/LR35902.cs index f5e3b2d..35b8eb4 100644 --- a/LR35902/LR35902.cs +++ b/LR35902/LR35902.cs @@ -120,7 +120,6 @@ namespace LR35902 MachineTicked?.Invoke(this, EventArgs.Empty); this.bus.IO.IncrementTimers(); this.bus.IO.TransferDma(); - } private void TickMachine(int extra) diff --git a/LR35902/LcdcControl.cs b/LR35902/LcdcControl.cs index 3652b72..5e1a33d 100644 --- a/LR35902/LcdcControl.cs +++ b/LR35902/LcdcControl.cs @@ -10,13 +10,13 @@ namespace LR35902 public enum LcdcControls { None = 0, - DisplayBackground = Bits.Bit0, - ObjectEnable = Bits.Bit1, - ObjectBlockCompositionSelection = Bits.Bit2, - BackgroundCodeAreaSelection = Bits.Bit3, - BackgroundCharacterDataSelection = Bits.Bit4, - WindowEnable = Bits.Bit5, - WindowCodeAreaSelection = Bits.Bit6, - LcdEnable = Bits.Bit7, + BG_EN = Bits.Bit0, + OBJ_EN = Bits.Bit1, + OBJ_SIZE = Bits.Bit2, + BG_MAP = Bits.Bit3, + TILE_SEL = Bits.Bit4, + WIN_EN = Bits.Bit5, + WIN_MAP = Bits.Bit6, + LCD_EN = Bits.Bit7, } } diff --git a/LR35902/ObjectAttribute.cs b/LR35902/ObjectAttribute.cs index 91b3037..548be98 100644 --- a/LR35902/ObjectAttribute.cs +++ b/LR35902/ObjectAttribute.cs @@ -38,6 +38,6 @@ namespace LR35902 public bool FlipX => (this.Flags & (byte)Bits.Bit5) != 0; - public int Palette => (this.Flags & (byte)Bits.Bit4) >> 3; // TODO: Check this! + public int Palette => (this.Flags & (byte)Bits.Bit4) >> 4; } }