diff --git a/FoenixIDETester/CpuTests.cs b/FoenixIDETester/CpuTests.cs index f1f6c69..e59e016 100644 --- a/FoenixIDETester/CpuTests.cs +++ b/FoenixIDETester/CpuTests.cs @@ -13,18 +13,16 @@ namespace FoenixIDETester public class CpuTests { CPU cpu; - MemoryManager mgr; + MemoryManager MemMgr; [TestInitialize] public void Setup() { - mgr = new MemoryManager + MemMgr = new MemoryManager { - RAM = new MemoryRAM(0, 3 * 0x20_0000), - CODEC = new CodecRAM(1025, 1), - INTERRUPT = new InterruptController(MemoryMap.INT_PENDING_REG0, 4) + RAM = new MemoryRAM(0, 3 * 0x20_0000) }; - cpu = new CPU(mgr); + cpu = new CPU(MemMgr); cpu.SetEmulationMode(); Assert.AreEqual(1, cpu.A.Width); Assert.AreEqual(1, cpu.X.Width); @@ -35,8 +33,8 @@ public void Setup() public void LoadAccumulatorWith99() { // By default the CPU must be in 6502 emulation mode - mgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); // LDA Immediate - mgr.RAM.WriteByte(cpu.PC + 1, 0x99); // #$99 + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); // LDA Immediate + MemMgr.RAM.WriteByte(cpu.PC + 1, 0x99); // #$99 int PC = cpu.PC; cpu.ExecuteNext(); Assert.AreEqual(0x99, cpu.A.Value); @@ -46,7 +44,7 @@ public void LoadAccumulatorWith99() [TestMethod] public void ClearCarry() { - mgr.RAM.WriteByte(cpu.PC, OpcodeList.CLC_Implied); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.CLC_Implied); cpu.ExecuteNext(); Assert.IsFalse(cpu.Flags.Carry); } @@ -61,8 +59,8 @@ public void LoadCheckCarrySetForOverflowAbsolute() { LoadAccumulatorWith99(); ClearCarry(); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.ADC_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 0x78); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.ADC_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 0x78); cpu.ExecuteNext(); Assert.AreEqual(0x11, cpu.A.Value); Assert.IsFalse(cpu.Flags.oVerflow, "Overflow should be false"); @@ -78,10 +76,10 @@ public void LoadCheckCarrySetForOverflowDirectPage() { LoadAccumulatorWith99(); // Write a value that will cause an overflow in the addition - A is $99 - mgr.RAM.WriteByte(0x56, 0x78); + MemMgr.RAM.WriteByte(0x56, 0x78); ClearCarry(); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.ADC_DirectPage); - mgr.RAM.WriteByte(cpu.PC + 1, 0x56); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.ADC_DirectPage); + MemMgr.RAM.WriteByte(cpu.PC + 1, 0x56); cpu.ExecuteNext(); Assert.AreEqual(0x11, cpu.A.Value); Assert.IsFalse(cpu.Flags.oVerflow, "Overflow should be false"); @@ -103,32 +101,32 @@ public void RunCarrySetTest() { cpu.PC = 0; // lda #1 - mgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); // LDA Immediate - mgr.RAM.WriteByte(cpu.PC + 1, 1); // #1 + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); // LDA Immediate + MemMgr.RAM.WriteByte(cpu.PC + 1, 1); // #1 cpu.ExecuteNext(); // sta z_B byte z_B = 0x20; - mgr.RAM.WriteByte(cpu.PC, OpcodeList.STA_DirectPage); - mgr.RAM.WriteByte(cpu.PC + 1, z_B); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.STA_DirectPage); + MemMgr.RAM.WriteByte(cpu.PC + 1, z_B); cpu.ExecuteNext(); // lda #255 - mgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); // LDA Immediate - mgr.RAM.WriteByte(cpu.PC + 1, 255); // #255 + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); // LDA Immediate + MemMgr.RAM.WriteByte(cpu.PC + 1, 255); // #255 cpu.ExecuteNext(); // adc z_B - mgr.RAM.WriteByte(cpu.PC, OpcodeList.ADC_DirectPage); - mgr.RAM.WriteByte(cpu.PC + 1, z_B); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.ADC_DirectPage); + MemMgr.RAM.WriteByte(cpu.PC + 1, z_B); cpu.ExecuteNext(); Assert.IsTrue(cpu.Flags.Zero); Assert.IsTrue(cpu.Flags.Carry); // sta z_C byte z_C = 0x21; - mgr.RAM.WriteByte(cpu.PC, OpcodeList.STA_DirectPage); - mgr.RAM.WriteByte(cpu.PC + 1, z_C); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.STA_DirectPage); + MemMgr.RAM.WriteByte(cpu.PC + 1, z_C); cpu.ExecuteNext(); - Assert.AreEqual(0, mgr.RAM.ReadByte(z_C)); + Assert.AreEqual(0, MemMgr.RAM.ReadByte(z_C)); } // CLC @@ -146,70 +144,70 @@ public void RunCarrySetTest() public void RunStackIndirectWithIndex() { ClearCarry(); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.XCE_Implied); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.XCE_Implied); cpu.ExecuteNext(); Assert.IsFalse(cpu.Flags.Emulation); Assert.IsTrue(cpu.Flags.Carry); // REP #$30 - mgr.RAM.WriteByte(cpu.PC, OpcodeList.REP_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 0x30); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.REP_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 0x30); cpu.ExecuteNext(); Assert.AreEqual(2, cpu.A.Width); Assert.AreEqual(2, cpu.X.Width); // LDA #$234 - mgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); - mgr.RAM.WriteWord(cpu.PC + 1, 0x234); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); + MemMgr.RAM.WriteWord(cpu.PC + 1, 0x234); cpu.ExecuteNext(); Assert.AreEqual(0x234, cpu.A.Value); Assert.AreEqual(0, cpu.S.Value); // TCS - exchange accumulator with stack - mgr.RAM.WriteByte(cpu.PC, OpcodeList.TCS_Implied); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.TCS_Implied); cpu.ExecuteNext(); Assert.AreEqual(0x234, cpu.S.Value); // LDA #$123 - mgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); - mgr.RAM.WriteWord(cpu.PC + 1, 0x123); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); + MemMgr.RAM.WriteWord(cpu.PC + 1, 0x123); cpu.ExecuteNext(); Assert.AreEqual(0x123, cpu.A.Value); // STA $237 - mgr.RAM.WriteByte(cpu.PC, OpcodeList.STA_Absolute); - mgr.RAM.WriteWord(cpu.PC + 1, 0x237); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.STA_Absolute); + MemMgr.RAM.WriteWord(cpu.PC + 1, 0x237); cpu.ExecuteNext(); // LDA #$678 - mgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); - mgr.RAM.WriteWord(cpu.PC + 1, 0x678); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); + MemMgr.RAM.WriteWord(cpu.PC + 1, 0x678); cpu.ExecuteNext(); Assert.AreEqual(0x678, cpu.A.Value); // STA $239 - mgr.RAM.WriteByte(cpu.PC, OpcodeList.STA_Absolute); - mgr.RAM.WriteWord(cpu.PC + 1, 0x239); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.STA_Absolute); + MemMgr.RAM.WriteWord(cpu.PC + 1, 0x239); cpu.ExecuteNext(); // LDY #$10 - mgr.RAM.WriteByte(cpu.PC, OpcodeList.LDY_Immediate); - mgr.RAM.WriteWord(cpu.PC + 1, 0x10); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.LDY_Immediate); + MemMgr.RAM.WriteWord(cpu.PC + 1, 0x10); cpu.ExecuteNext(); Assert.AreEqual(0x10, cpu.Y.Value); // LDA #$FE23 - mgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); - mgr.RAM.WriteWord(cpu.PC + 1, 0xFE23); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); + MemMgr.RAM.WriteWord(cpu.PC + 1, 0xFE23); cpu.ExecuteNext(); Assert.AreEqual(0xFE23, cpu.A.Value); // STA (3,s),y - store - mgr.RAM.WriteByte(cpu.PC, OpcodeList.STA_StackRelativeIndirectIndexedWithY); - mgr.RAM.WriteByte(cpu.PC + 1, 3); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.STA_StackRelativeIndirectIndexedWithY); + MemMgr.RAM.WriteByte(cpu.PC + 1, 3); cpu.ExecuteNext(); - Assert.AreEqual(0x23, mgr.RAM.ReadByte(0x133)); - Assert.AreEqual(0xFE, mgr.RAM.ReadByte(0x134)); + Assert.AreEqual(0x23, MemMgr.RAM.ReadByte(0x133)); + Assert.AreEqual(0xFE, MemMgr.RAM.ReadByte(0x134)); } /* @@ -220,19 +218,19 @@ public void RunStackIndirectWithIndex() [TestMethod] public void CompareIndexSetsNegative() { - mgr.RAM.WriteByte(cpu.PC, OpcodeList.LDY_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 0x98); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.LDY_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 0x98); cpu.ExecuteNext(); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.CPY_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 0); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.CPY_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 0); cpu.ExecuteNext(); Assert.IsTrue(cpu.Flags.Negative); // most significan bit is set Assert.IsFalse(cpu.Flags.Zero); Assert.IsTrue(cpu.Flags.Carry); // no borrow required - mgr.RAM.WriteByte(cpu.PC, OpcodeList.CPY_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 0x9A); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.CPY_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 0x9A); cpu.ExecuteNext(); Assert.IsTrue(cpu.Flags.Negative); // most significan bit is set Assert.IsFalse(cpu.Flags.Zero); @@ -252,26 +250,26 @@ public void CompareIndexSetsNegative() [TestMethod] public void Substract() { - mgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 0xE9); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 0xE9); cpu.ExecuteNext(); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.SEC_Implied); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.SEC_Implied); cpu.ExecuteNext(); Assert.IsTrue(cpu.Flags.Carry); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.SBC_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 0x39); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.SBC_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 0x39); cpu.ExecuteNext(); Assert.AreEqual(0xB0, cpu.A.Value); Assert.IsTrue(cpu.Flags.Carry); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.SEC_Implied); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.SEC_Implied); cpu.ExecuteNext(); Assert.IsTrue(cpu.Flags.Carry); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.SBC_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 0xc0); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.SBC_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 0xc0); cpu.ExecuteNext(); Assert.AreEqual(0xF0, cpu.A.Value); Assert.IsFalse(cpu.Flags.Carry); @@ -298,23 +296,23 @@ public void SubstractIndexed() byte bar = 0x93; // This is a page 0 address byte foo_address = 0xA0; - mgr.RAM.WriteByte(foo_address, foo); - mgr.RAM.WriteByte(foo_address + 1, bar); + MemMgr.RAM.WriteByte(foo_address, foo); + MemMgr.RAM.WriteByte(foo_address + 1, bar); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.LDX_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 0); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.LDX_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 0); cpu.ExecuteNext(); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 0xE9); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 0xE9); cpu.ExecuteNext(); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.SEC_Implied); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.SEC_Implied); cpu.ExecuteNext(); Assert.IsTrue(cpu.Flags.Carry); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.SBC_AbsoluteIndexedWithX); - mgr.RAM.WriteByte(cpu.PC + 1, foo_address); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.SBC_AbsoluteIndexedWithX); + MemMgr.RAM.WriteByte(cpu.PC + 1, foo_address); cpu.ExecuteNext(); Assert.IsTrue(cpu.Flags.Carry); } @@ -331,39 +329,39 @@ public void SubstractIndexed() [TestMethod] public void AbsoluteIndexedByBank() { - mgr.RAM.WriteWord(0x2_0328, 0xEE55); + MemMgr.RAM.WriteWord(0x2_0328, 0xEE55); // Go native - mgr.RAM.WriteByte(cpu.PC, OpcodeList.XCE_Implied); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.XCE_Implied); cpu.ExecuteNext(); Assert.IsFalse(cpu.Flags.Emulation); // Set A short (X is long) - mgr.RAM.WriteByte(cpu.PC, OpcodeList.SEP_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 0x20); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.SEP_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 0x20); cpu.ExecuteNext(); Assert.AreEqual(1, cpu.A.Width); Assert.AreEqual(2, cpu.X.Width); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 2); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 2); cpu.ExecuteNext(); Assert.AreEqual(2, cpu.A.Value); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.PHA_StackImplied); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.PHA_StackImplied); cpu.ExecuteNext(); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.PLB_StackImplied); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.PLB_StackImplied); cpu.ExecuteNext(); Assert.AreEqual(2, cpu.DataBank.Value); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.LDX_Immediate); - mgr.RAM.WriteWord(cpu.PC + 1, 0x125); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.LDX_Immediate); + MemMgr.RAM.WriteWord(cpu.PC + 1, 0x125); cpu.ExecuteNext(); Assert.AreEqual(0x125, cpu.X.Value); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.LDY_AbsoluteIndexedWithX); - mgr.RAM.WriteWord(cpu.PC + 1, 0x203); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.LDY_AbsoluteIndexedWithX); + MemMgr.RAM.WriteWord(cpu.PC + 1, 0x203); cpu.ExecuteNext(); Assert.AreEqual(0xEE55, cpu.Y.Value); } @@ -383,10 +381,10 @@ public void TestBit() cpu.SetEmulationMode(); cpu.DataBank.Value = 0x12; // set the value in memory - mgr.RAM.WriteByte(0x12_ABCD, 0x9C); + MemMgr.RAM.WriteByte(0x12_ABCD, 0x9C); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.BIT_Absolute); - mgr.RAM.WriteWord(cpu.PC + 1, 0xABCD); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.BIT_Absolute); + MemMgr.RAM.WriteWord(cpu.PC + 1, 0xABCD); cpu.ExecuteNext(); Assert.IsTrue(cpu.Flags.Negative); @@ -410,7 +408,7 @@ public void TestTransfer() cpu.A.Value = 0x1234; cpu.X.Value = 0xABCD; - mgr.RAM.WriteByte(cpu.PC, OpcodeList.TXA_Implied); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.TXA_Implied); cpu.ExecuteNext(); Assert.IsTrue(cpu.Flags.Negative); Assert.IsFalse(cpu.Flags.Zero); @@ -425,13 +423,13 @@ public void TestTransfer() [TestMethod] public void TestOverflowADC1() { - mgr.RAM.WriteByte(cpu.PC, OpcodeList.CLC_Implied); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.CLC_Implied); cpu.ExecuteNext(); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 1); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 1); cpu.ExecuteNext(); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.ADC_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 1); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.ADC_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 1); cpu.ExecuteNext(); Assert.AreEqual(2, cpu.A.Value); Assert.IsFalse(cpu.Flags.Carry); @@ -446,13 +444,13 @@ public void TestOverflowADC1() [TestMethod] public void TestOverflowADC2() { - mgr.RAM.WriteByte(cpu.PC, OpcodeList.CLC_Implied); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.CLC_Implied); cpu.ExecuteNext(); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 1); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 1); cpu.ExecuteNext(); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.ADC_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 0xFF); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.ADC_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 0xFF); cpu.ExecuteNext(); Assert.AreEqual(0, cpu.A.Value); Assert.IsTrue(cpu.Flags.Carry, "Carry should be true"); @@ -467,13 +465,13 @@ public void TestOverflowADC2() [TestMethod] public void TestOverflowADC3() { - mgr.RAM.WriteByte(cpu.PC, OpcodeList.CLC_Implied); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.CLC_Implied); cpu.ExecuteNext(); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 0x7F); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 0x7F); cpu.ExecuteNext(); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.ADC_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 0x1); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.ADC_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 0x1); cpu.ExecuteNext(); Assert.AreEqual(0x80, cpu.A.Value); Assert.IsFalse(cpu.Flags.Carry, "Carry should be false"); @@ -489,13 +487,13 @@ public void TestOverflowADC3() [TestMethod] public void TestOverflowADC4() { - mgr.RAM.WriteByte(cpu.PC, OpcodeList.CLC_Implied); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.CLC_Implied); cpu.ExecuteNext(); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 0x80); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 0x80); cpu.ExecuteNext(); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.ADC_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 0xFF); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.ADC_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 0xFF); cpu.ExecuteNext(); Assert.AreEqual(0x7F, cpu.A.Value); Assert.IsTrue(cpu.Flags.Carry, "Carry should be true"); @@ -511,13 +509,13 @@ public void TestOverflowADC4() [TestMethod] public void TestOverflowSBC5() { - mgr.RAM.WriteByte(cpu.PC, OpcodeList.SEC_Implied); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.SEC_Implied); cpu.ExecuteNext(); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 0x0); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 0x0); cpu.ExecuteNext(); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.SBC_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 0x1); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.SBC_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 0x1); cpu.ExecuteNext(); Assert.AreEqual(0xFF, cpu.A.Value); Assert.IsFalse(cpu.Flags.Carry, "Carry should be false"); @@ -534,13 +532,13 @@ public void TestOverflowSBC5() [TestMethod] public void TestOverflowSBC6() { - mgr.RAM.WriteByte(cpu.PC, OpcodeList.SEC_Implied); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.SEC_Implied); cpu.ExecuteNext(); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 0x80); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 0x80); cpu.ExecuteNext(); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.SBC_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 0x1); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.SBC_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 0x1); cpu.ExecuteNext(); Assert.AreEqual(0x7F, cpu.A.Value); Assert.IsTrue(cpu.Flags.Carry, "Carry should be true"); @@ -556,13 +554,13 @@ public void TestOverflowSBC6() [TestMethod] public void TestOverflowSBC7() { - mgr.RAM.WriteByte(cpu.PC, OpcodeList.SEC_Implied); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.SEC_Implied); cpu.ExecuteNext(); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 0x7F); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 0x7F); cpu.ExecuteNext(); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.SBC_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 0xFF); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.SBC_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 0xFF); cpu.ExecuteNext(); Assert.AreEqual(0x80, cpu.A.Value); Assert.IsFalse(cpu.Flags.Carry, "Carry should be false"); @@ -577,13 +575,13 @@ public void TestOverflowSBC7() [TestMethod] public void TestOverflowADC8() { - mgr.RAM.WriteByte(cpu.PC, OpcodeList.SEC_Implied); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.SEC_Implied); cpu.ExecuteNext(); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 0x3F); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 0x3F); cpu.ExecuteNext(); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.ADC_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 0x40); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.ADC_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 0x40); cpu.ExecuteNext(); Assert.AreEqual(0x80, cpu.A.Value); Assert.IsFalse(cpu.Flags.Carry, "Carry should be false"); @@ -598,13 +596,13 @@ public void TestOverflowADC8() [TestMethod] public void TestOverflowSBC9() { - mgr.RAM.WriteByte(cpu.PC, OpcodeList.CLC_Implied); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.CLC_Implied); cpu.ExecuteNext(); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 0xC0); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.LDA_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 0xC0); cpu.ExecuteNext(); - mgr.RAM.WriteByte(cpu.PC, OpcodeList.SBC_Immediate); - mgr.RAM.WriteByte(cpu.PC + 1, 0x40); + MemMgr.RAM.WriteByte(cpu.PC, OpcodeList.SBC_Immediate); + MemMgr.RAM.WriteByte(cpu.PC + 1, 0x40); cpu.ExecuteNext(); Assert.AreEqual(0x7F, cpu.A.Value); Assert.IsTrue(cpu.Flags.Carry, "Carry should be true"); diff --git a/Main/Devices/TimerRegister.cs b/Main/Devices/TimerRegister.cs index 7706098..5f30c2c 100644 --- a/Main/Devices/TimerRegister.cs +++ b/Main/Devices/TimerRegister.cs @@ -1,4 +1,5 @@ -using System; +using FoenixIDE.Timers; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -8,17 +9,56 @@ namespace FoenixIDE.Simulator.Devices { public class TimerRegister : MemoryLocations.MemoryRAM { + private MultimediaTimer hiresTimer = null; + + public delegate void RaiseInterruptFunction(); + public RaiseInterruptFunction TimerInterruptDelegate; + const int CPU_FREQ = 14318000; + public TimerRegister(int StartAddress, int Length) : base(StartAddress, Length) { + hiresTimer = new MultimediaTimer(1000); + hiresTimer.Elapsed += new MultimediaElapsedEventHandler(Timer_Tick); } public override void WriteByte(int Address, byte Value) { // Address 0 is control register + data[Address] = Value; if (Address == 0) { + bool enabled = (Value & 1) != 0; + if (enabled) + { + hiresTimer.Start(); + } + else + { + hiresTimer.Stop(); + } + } + else if (Address > 4 && Address < 8) + { + // Calculate interval in milliseconds + int longInterval = data[5] + (data[6] << 8) + (data[7] << 16); + double msInterval = (double)(longInterval) * 1000/ (double)CPU_FREQ; + uint adjInterval = (uint)msInterval; + if (adjInterval==0) + { + hiresTimer.Interval = 1; + } + else + { + hiresTimer.Interval = adjInterval; + } + } } + + void Timer_Tick(object sender, EventArgs e) + { + TimerInterruptDelegate?.Invoke(); + } } } diff --git a/Main/FoenixSystem.cs b/Main/FoenixSystem.cs index b639976..6f5b881 100644 --- a/Main/FoenixSystem.cs +++ b/Main/FoenixSystem.cs @@ -88,6 +88,9 @@ public FoenixSystem(Gpu gpu, BoardVersion version, string DefaultKernel) // Write bytes $9F in the joystick registers to mean that they are not installed. MemMgr.WriteWord(0xAFE800, 0x9F9F); MemMgr.WriteWord(0xAFE802, 0x9F9F); + MemMgr.TIMER0.TimerInterruptDelegate += TimerEvent0; + MemMgr.TIMER1.TimerInterruptDelegate += TimerEvent1; + MemMgr.TIMER2.TimerInterruptDelegate += TimerEvent2; } private void CPU_SimulatorCommand(int EventID) @@ -102,6 +105,43 @@ private void CPU_SimulatorCommand(int EventID) } } + private void TimerEvent0() + { + byte mask = MemMgr.ReadByte(MemoryLocations.MemoryMap.INT_MASK_REG0); + if (!CPU.DebugPause && !CPU.Flags.IrqDisable && ((~mask & (byte)Register0.FNX0_INT02_TMR0) == (byte)Register0.FNX0_INT02_TMR0)) + { + // Set the Timer0 Interrupt + byte IRQ0 = MemMgr.ReadByte(MemoryLocations.MemoryMap.INT_PENDING_REG0); + IRQ0 |= (byte)Register0.FNX0_INT02_TMR0; + MemMgr.WriteByte(MemoryLocations.MemoryMap.INT_PENDING_REG0, IRQ0); + CPU.Pins.IRQ = true; + } + } + private void TimerEvent1() + { + byte mask = MemMgr.ReadByte(MemoryLocations.MemoryMap.INT_MASK_REG0); + if (!CPU.DebugPause && !CPU.Flags.IrqDisable && ((~mask & (byte)Register0.FNX0_INT03_TMR1) == (byte)Register0.FNX0_INT03_TMR1)) + { + // Set the Timer1 Interrupt + byte IRQ0 = MemMgr.ReadByte(MemoryLocations.MemoryMap.INT_PENDING_REG0); + IRQ0 |= (byte)Register0.FNX0_INT03_TMR1; + MemMgr.WriteByte(MemoryLocations.MemoryMap.INT_PENDING_REG0, IRQ0); + CPU.Pins.IRQ = true; + } + } + private void TimerEvent2() + { + byte mask = MemMgr.ReadByte(MemoryLocations.MemoryMap.INT_MASK_REG0); + if (!CPU.DebugPause && !CPU.Flags.IrqDisable && ((~mask & (byte)Register0.FNX0_INT04_TMR2) == (byte)Register0.FNX0_INT04_TMR2)) + { + // Set the Timer2 Interrupt + byte IRQ0 = MemMgr.ReadByte(MemoryLocations.MemoryMap.INT_PENDING_REG0); + IRQ0 |= (byte)Register0.FNX0_INT04_TMR2; + MemMgr.WriteByte(MemoryLocations.MemoryMap.INT_PENDING_REG0, IRQ0); + CPU.Pins.IRQ = true; + } + } + public BoardVersion GetVersion() { return boardVersion; diff --git a/Main/MemoryLocations/MemoryManager.cs b/Main/MemoryLocations/MemoryManager.cs index 02dad63..a692cbb 100644 --- a/Main/MemoryLocations/MemoryManager.cs +++ b/Main/MemoryLocations/MemoryManager.cs @@ -75,16 +75,7 @@ public int EndAddress /// public void GetDeviceAt(int Address, out IMappable Device, out int DeviceAddress) { - //foreach (IMappable device in devices) - //{ - // if (Address >= device.StartAddress && Address < device.EndAddress) - // { - // Device = device; - // DeviceAddress = Address - device.StartAddress; - // return; - // } - //} - if (Address == CODEC.StartAddress) + if (Address == MemoryMap.CODEC_WR_CTRL_FMX) { Device = CODEC; DeviceAddress = 0; @@ -96,25 +87,25 @@ public void GetDeviceAt(int Address, out IMappable Device, out int DeviceAddress DeviceAddress = Address - MATH.StartAddress; return; } - if (Address >= INTERRUPT.StartAddress && Address <= INTERRUPT.EndAddress) + if (Address >= MemoryMap.INT_PENDING_REG0 && Address <= MemoryMap.INT_PENDING_REG0 + 3) { Device = INTERRUPT; DeviceAddress = Address - INTERRUPT.StartAddress; return; } - if (Address >= TIMER0.StartAddress && Address <= TIMER0.EndAddress) + if (Address >= MemoryMap.TIMER0_CTRL_REG && Address <= MemoryMap.TIMER0_CTRL_REG + 7) { Device = TIMER0; DeviceAddress = Address - TIMER0.StartAddress; return; } - if (Address >= TIMER1.StartAddress && Address <= TIMER1.EndAddress) + if (Address >= MemoryMap.TIMER1_CTRL_REG && Address <= MemoryMap.TIMER1_CTRL_REG + 7) { Device = TIMER1; DeviceAddress = Address - TIMER1.StartAddress; return; } - if (Address >= TIMER2.StartAddress && Address <= TIMER2.EndAddress) + if (Address >= MemoryMap.TIMER2_CTRL_REG && Address <= MemoryMap.TIMER2_CTRL_REG + 7) { Device = TIMER2; DeviceAddress = Address - TIMER2.StartAddress; diff --git a/Main/Processor/CPU.cs b/Main/Processor/CPU.cs index 100d8c5..ad54ad6 100644 --- a/Main/Processor/CPU.cs +++ b/Main/Processor/CPU.cs @@ -56,7 +56,7 @@ public partial class CPU /// private DateTime checkStartTime = DateTime.Now; - public MemoryManager Memory = null; + public MemoryManager MemMgr = null; public Thread CPUThread = null; public event Operations.SimulatorCommandEvent SimulatorCommand; @@ -91,9 +91,9 @@ public int[] Snapshot } } - public CPU(MemoryManager newMemory) + public CPU(MemoryManager mm) { - Memory = newMemory; + MemMgr = mm; clockSpeed = 14000000; clockCyles = 0; Operations operations = new Operations(this); @@ -153,7 +153,7 @@ public bool ExecuteNext() } // TODO - if pc > RAM size, then throw an exception - CurrentOpcode = opcodes[Memory.RAM.ReadByte(PC)]; + CurrentOpcode = opcodes[MemMgr.RAM.ReadByte(PC)]; OpcodeLength = CurrentOpcode.Length; OpcodeCycles = 1; SignatureBytes = ReadSignature(OpcodeLength, PC); @@ -182,7 +182,7 @@ public void Halt() public void Reset() { Pins.VectorPull = true; - Memory.VectorPull = true; + MemMgr.VectorPull = true; SetEmulationMode(); Flags.Value = 0; @@ -194,12 +194,12 @@ public void Reset() DirectPage.Value = 0; //ProgramBank.Value = 0; - PC = Memory.ReadWord(MemoryMap.VECTOR_ERESET); + PC = MemMgr.ReadWord(MemoryMap.VECTOR_ERESET); Flags.IrqDisable = true; Pins.IRQ = false; Pins.VectorPull = false; - Memory.VectorPull = false; + MemMgr.VectorPull = false; Waiting = false; } @@ -237,7 +237,7 @@ public void SyncFlags() /// public OpCode PreFetch() { - return opcodes[Memory[PC]]; + return opcodes[MemMgr[PC]]; } public int ReadSignature(int length, int pc) @@ -245,11 +245,11 @@ public int ReadSignature(int length, int pc) switch (length) { case 2: - return Memory.RAM.ReadByte(pc + 1); + return MemMgr.RAM.ReadByte(pc + 1); case 3: - return Memory.RAM.ReadWord(pc + 1); + return MemMgr.RAM.ReadWord(pc + 1); case 4: - return Memory.RAM.ReadLong(pc + 1); + return MemMgr.RAM.ReadLong(pc + 1); } return 0; @@ -291,7 +291,7 @@ private int GetPointerDirect(int baseAddress, Register Index = null) int addr = DirectPage.Value + baseAddress; if (Index != null) addr += Index.Value; - int pointer = Memory.ReadWord(addr); + int pointer = MemMgr.ReadWord(addr); return DataBank.GetLongAddress(pointer); } @@ -306,7 +306,7 @@ private int GetPointerLong(int baseAddress, Register Index = null) int addr = baseAddress; if (Index != null) addr += Index.Value; - return DataBank.GetLongAddress(Memory.ReadWord(addr)); + return DataBank.GetLongAddress(MemMgr.ReadWord(addr)); } #endregion @@ -333,7 +333,7 @@ public void JumpLong(int addr) public void JumpVector(int VectorAddress) { - int addr = Memory.ReadWord(VectorAddress); + int addr = MemMgr.ReadWord(VectorAddress); //ProgramBank.Value = 0; //PC.Value = addr; PC = addr; @@ -357,7 +357,7 @@ public void Push(int value, int bytes) throw new Exception("bytes must be between 1 and 3. Got " + bytes.ToString()); Stack.Value -= bytes; - Memory.Write(Stack.Value + 1, value, bytes); + MemMgr.Write(Stack.Value + 1, value, bytes); } public void Push(Register Reg, int Offset) @@ -375,7 +375,7 @@ public int Pull(int bytes) if (bytes < 1 || bytes > 3) throw new Exception("bytes must be between 1 and 3. got " + bytes.ToString()); - int ret = Memory.Read(Stack.Value + 1, bytes); + int ret = MemMgr.Read(Stack.Value + 1, bytes); Stack.Value += bytes; return ret; diff --git a/Main/Processor/Operations.cs b/Main/Processor/Operations.cs index d8baac9..96e0066 100644 --- a/Main/Processor/Operations.cs +++ b/Main/Processor/Operations.cs @@ -39,7 +39,7 @@ public void Reset() //cpu.ProgramBank.Reset(); //cpu.PC.Reset(); - cpu.PC = cpu.Memory.ReadWord(MemoryMap.VECTOR_RESET); + cpu.PC = cpu.MemMgr.ReadWord(MemoryMap.VECTOR_RESET); } /// @@ -169,7 +169,7 @@ public int GetValue(AddressModes mode, int signatureBytes, int width) case AddressModes.StackRelative: return GetAbsoluteLong(cpu.Stack.Value + signatureBytes); case AddressModes.StackRelativeIndirectIndexedWithY: - return GetAbsoluteLong(cpu.Memory.ReadWord(cpu.Stack.Value + signatureBytes) + cpu.Y.Value); + return GetAbsoluteLong(cpu.MemMgr.ReadWord(cpu.Stack.Value + signatureBytes) + cpu.Y.Value); case AddressModes.StackProgramCounterRelativeLong: throw new NotImplementedException(); } @@ -179,16 +179,16 @@ public int GetValue(AddressModes mode, int signatureBytes, int width) private int GetDirectIndirect(int Address) { int addr = cpu.DirectPage.GetLongAddress(Address); - int ptr = cpu.Memory.ReadWord(addr); + int ptr = cpu.MemMgr.ReadWord(addr); ptr = cpu.DataBank.GetLongAddress(ptr); - return cpu.Memory.ReadWord(ptr); + return cpu.MemMgr.ReadWord(ptr); } private int GetDirectIndirectLong(int Address) { int addr = cpu.DirectPage.GetLongAddress(Address); - int ptr = cpu.Memory.ReadLong(addr); - return cpu.Memory.ReadWord(ptr); + int ptr = cpu.MemMgr.ReadLong(addr); + return cpu.MemMgr.ReadWord(ptr); } private int GetDirectPageIndirectIndexedLong(int Address, Register Y) @@ -196,8 +196,8 @@ private int GetDirectPageIndirectIndexedLong(int Address, Register Y) int addr = cpu.DirectPage.GetLongAddress(Address); // This effective address can overflow into the next bank. - int ptr = cpu.Memory.ReadLong(addr) + Y.Value; - return (cpu.A.Width == 1) ? cpu.Memory.ReadByte(ptr) : cpu.Memory.ReadWord(ptr); + int ptr = cpu.MemMgr.ReadLong(addr) + Y.Value; + return (cpu.A.Width == 1) ? cpu.MemMgr.ReadByte(ptr) : cpu.MemMgr.ReadWord(ptr); } /// @@ -211,9 +211,9 @@ private int GetDirectPageIndirectIndexed(int Address, Register Y) // The indirect address must be in Bank 0 int addr = cpu.DirectPage.GetLongAddress(Address) & 0xFFFF; - int ptr = cpu.Memory.ReadWord(addr) + Y.Value; + int ptr = cpu.MemMgr.ReadWord(addr) + Y.Value; ptr = cpu.DataBank.GetLongAddress(ptr); - return (cpu.A.Width == 1) ? cpu.Memory.ReadByte(ptr) : cpu.Memory.ReadWord(ptr); + return (cpu.A.Width == 1) ? cpu.MemMgr.ReadByte(ptr) : cpu.MemMgr.ReadWord(ptr); } /// @@ -225,19 +225,19 @@ private int GetDirectPageIndirectIndexed(int Address, Register Y) private int GetDirectIndexedIndirect(int Address, Register X) { int addr = cpu.DirectPage.GetLongAddress(Address + X.Value); - int ptr = cpu.Memory.ReadWord(addr); + int ptr = cpu.MemMgr.ReadWord(addr); ptr = cpu.DataBank.GetLongAddress(ptr); - return (cpu.A.Width == 1) ? cpu.Memory.ReadByte(ptr) : cpu.Memory.ReadWord(ptr); + return (cpu.A.Width == 1) ? cpu.MemMgr.ReadByte(ptr) : cpu.MemMgr.ReadWord(ptr); } private int GetAbsoluteLong(int Address) { - return (cpu.A.Width == 1) ? cpu.Memory.ReadByte(Address) : cpu.Memory.ReadWord(Address); + return (cpu.A.Width == 1) ? cpu.MemMgr.ReadByte(Address) : cpu.MemMgr.ReadWord(Address); } private int GetAbsoluteLongIndexed(int Address, Register Index) { - return (cpu.A.Width == 1) ? cpu.Memory.ReadByte(Address + Index.Value) : cpu.Memory.ReadWord(Address + Index.Value); + return (cpu.A.Width == 1) ? cpu.MemMgr.ReadByte(Address + Index.Value) : cpu.MemMgr.ReadWord(Address + Index.Value); } /// @@ -249,7 +249,7 @@ private int GetAbsoluteLongIndexed(int Address, Register Index) /// private int GetAbsolute(int Address, Register bank, int width) { - return (width == 1) ? cpu.Memory.ReadByte(bank.GetLongAddress(Address)) : cpu.Memory.ReadWord(bank.GetLongAddress(Address)); + return (width == 1) ? cpu.MemMgr.ReadByte(bank.GetLongAddress(Address)) : cpu.MemMgr.ReadWord(bank.GetLongAddress(Address)); } /// @@ -265,14 +265,14 @@ private int GetIndexed(int Address, Register bank, Register Index, int width) int addr = Address; addr = bank.GetLongAddress(Address); addr = addr + Index.Value; - return (width == 1) ? cpu.Memory.ReadByte(addr) : cpu.Memory.ReadWord(addr); + return (width == 1) ? cpu.MemMgr.ReadByte(addr) : cpu.MemMgr.ReadWord(addr); } public int GetAbsoluteIndirectAddressLong(int Address) { int addr = cpu.DirectPage.GetLongAddress(Address); - int ptr = cpu.Memory.ReadLong(addr); - return cpu.Memory.ReadWord(ptr); + int ptr = cpu.MemMgr.ReadLong(addr); + return cpu.MemMgr.ReadWord(ptr); } /// @@ -286,7 +286,7 @@ public int GetAbsoluteIndirectAddressLong(int Address) private int GetJumpAbsoluteIndexedIndirect(int Address, Register Index) { int addr = Address + Index.Value; - int ptr = cpu.Memory.ReadWord(addr); + int ptr = cpu.MemMgr.ReadWord(addr); //return cpu.ProgramBank.GetLongAddress(ptr); return (cpu.PC & 0xFF_0000) + ptr; } @@ -343,7 +343,7 @@ public void ExecuteTSBTRB(byte instruction, AddressModes addressMode, int signat { case OpcodeList.TSB_Absolute: case OpcodeList.TSB_DirectPage: - cpu.Memory.Write(addr, val | cpu.A.Value, cpu.A.Width); + cpu.MemMgr.Write(addr, val | cpu.A.Value, cpu.A.Width); break; case OpcodeList.TRB_Absolute: case OpcodeList.TRB_DirectPage: @@ -351,7 +351,7 @@ public void ExecuteTSBTRB(byte instruction, AddressModes addressMode, int signat // AND to get bits that are both 1 // XOR to force thoses off in memory. int mask = val & cpu.A.Value; - cpu.Memory.Write(addr, val ^ mask, cpu.A.Width); + cpu.MemMgr.Write(addr, val ^ mask, cpu.A.Width); break; default: throw new NotImplementedException("ExecuteTSBTRB() opcode not implemented: " + instruction.ToString("X2")); @@ -431,7 +431,7 @@ public void ExecuteShift(byte instruction, AddressModes addressMode, int signatu if (addressMode == AddressModes.Accumulator) cpu.A.Value = val; else - cpu.Memory.Write(addr, val, cpu.A.Width); + cpu.MemMgr.Write(addr, val, cpu.A.Width); } public void ExecuteStack(byte instruction, AddressModes addressMode, int signature) @@ -490,7 +490,7 @@ public void ExecuteStack(byte instruction, AddressModes addressMode, int signatu case OpcodeList.PEI_StackDirectPageIndirect: // Read the word at direct page address specified by operand - in Bank 0 int addr = cpu.DirectPage.GetLongAddress(signature & 0xFF) & 0xFFFF; - cpu.Push(cpu.Memory.ReadWord(addr), 2); + cpu.Push(cpu.MemMgr.ReadWord(addr), 2); break; case OpcodeList.PER_StackProgramCounterRelativeLong: int effRelAddr = (cpu.PC + signature) & 0xFFFF; @@ -611,12 +611,12 @@ public void ExecuteINCDEC(byte instruction, AddressModes addressMode, int signat bval--; if (cpu.A.Width == 1) { - cpu.Memory.WriteByte(addr, (byte)bval); + cpu.MemMgr.WriteByte(addr, (byte)bval); cpu.Flags.SetNZ(bval, 1); } else { - cpu.Memory.WriteWord(addr, bval); + cpu.MemMgr.WriteWord(addr, bval); cpu.Flags.SetNZ(bval, 2); } @@ -635,12 +635,12 @@ public void ExecuteINCDEC(byte instruction, AddressModes addressMode, int signat bval++; if (cpu.A.Width == 1) { - cpu.Memory.WriteByte(addr, (byte)bval); + cpu.MemMgr.WriteByte(addr, (byte)bval); cpu.Flags.SetNZ(bval, 1); } else { - cpu.Memory.WriteWord(addr, bval); + cpu.MemMgr.WriteWord(addr, bval); cpu.Flags.SetNZ(bval, 2); } @@ -704,25 +704,25 @@ private int GetAddress(AddressModes addressMode, int SignatureBytes, RegisterBan return cpu.DirectPage.GetLongAddress(SignatureBytes + cpu.Y.Value); case AddressModes.DirectPageIndexedIndirectWithX: addr = cpu.DirectPage.GetLongAddress(SignatureBytes) + cpu.X.Value; - ptr = cpu.Memory.ReadWord(addr); + ptr = cpu.MemMgr.ReadWord(addr); //return cpu.ProgramBank.GetLongAddress(ptr); return (cpu.PC & 0xFF_0000) + ptr; case AddressModes.DirectPageIndirect: addr = cpu.DirectPage.GetLongAddress(SignatureBytes); - ptr = cpu.Memory.ReadWord(addr); + ptr = cpu.MemMgr.ReadWord(addr); return cpu.DataBank.GetLongAddress(ptr); case AddressModes.DirectPageIndirectIndexedWithY: addr = cpu.DirectPage.GetLongAddress(SignatureBytes); - ptr = cpu.Memory.ReadWord(addr) + cpu.Y.Value; + ptr = cpu.MemMgr.ReadWord(addr) + cpu.Y.Value; //return cpu.ProgramBank.GetLongAddress(ptr); return (cpu.PC & 0xFF_0000) + ptr; case AddressModes.DirectPageIndirectLong: addr = cpu.DirectPage.GetLongAddress(SignatureBytes); - ptr = cpu.Memory.ReadLong(addr); + ptr = cpu.MemMgr.ReadLong(addr); return ptr; case AddressModes.DirectPageIndirectLongIndexedWithY: addr = cpu.DirectPage.GetLongAddress(SignatureBytes); - ptr = cpu.Memory.ReadLong(addr) + cpu.Y.Value; + ptr = cpu.MemMgr.ReadLong(addr) + cpu.Y.Value; return ptr; case AddressModes.ProgramCounterRelative: ptr = MakeSignedByte((byte)SignatureBytes); @@ -742,24 +742,24 @@ private int GetAddress(AddressModes addressMode, int SignatureBytes, RegisterBan case AddressModes.StackRelativeIndirectIndexedWithY: int bankOffset = Bank.Value << 16; addr = bankOffset + (cpu.Stack.Value + SignatureBytes); - return bankOffset + cpu.Memory.ReadWord(addr) + cpu.Y.Value; + return bankOffset + cpu.MemMgr.ReadWord(addr) + cpu.Y.Value; case AddressModes.StackProgramCounterRelativeLong: return SignatureBytes; // Jump and JSR indirect references vectors located in Bank 0 case AddressModes.JmpAbsoluteIndirect: addr = SignatureBytes; - ptr = cpu.Memory.ReadWord(addr); + ptr = cpu.MemMgr.ReadWord(addr); //return cpu.ProgramBank.GetLongAddress(ptr); return (cpu.PC & 0xFF_0000) + ptr; case AddressModes.JmpAbsoluteIndirectLong: addr = SignatureBytes; - ptr = cpu.Memory.ReadLong(addr); + ptr = cpu.MemMgr.ReadLong(addr); return ptr; case AddressModes.JmpAbsoluteIndexedIndirectWithX: addr = SignatureBytes + cpu.X.Value; //ptr = cpu.Memory.ReadWord(cpu.ProgramBank.GetLongAddress(addr)); - ptr = cpu.Memory.ReadWord((cpu.PC & 0xFF_0000) + addr); + ptr = cpu.MemMgr.ReadWord((cpu.PC & 0xFF_0000) + addr); //return cpu.ProgramBank.GetLongAddress(ptr); return (cpu.PC & 0xFF_0000) + ptr; case AddressModes.Accumulator: @@ -989,7 +989,7 @@ public void ExecuteBlockMove(byte instruction, AddressModes addressMode, int sig // The addresses must remain in the correct bank, so the addresses will wrap int sourceAddr = sourceBank + cpu.X.Value; int destAddr = destBank + cpu.Y.Value; - cpu.Memory[destAddr] = cpu.Memory[sourceAddr]; + cpu.MemMgr[destAddr] = cpu.MemMgr[sourceAddr]; cpu.X.Value += dir; cpu.Y.Value += dir; cpu.A.Value--; @@ -1056,25 +1056,25 @@ private int HexVal(int bcd) public void ExecuteSTZ(byte instruction, AddressModes addressMode, int signature) { int addr = GetAddress(addressMode, signature, cpu.DataBank); - cpu.Memory.Write(addr, 0, cpu.A.Width); + cpu.MemMgr.Write(addr, 0, cpu.A.Width); } public void ExecuteSTA(byte instruction, AddressModes addressMode, int signature) { int addr = GetAddress(addressMode, signature, cpu.DataBank); - cpu.Memory.Write(addr, cpu.A.Value, cpu.A.Width); + cpu.MemMgr.Write(addr, cpu.A.Value, cpu.A.Width); } public void ExecuteSTY(byte instruction, AddressModes addressMode, int signature) { int addr = GetAddress(addressMode, signature, cpu.DataBank); - cpu.Memory.Write(addr, cpu.Y.Value, cpu.Y.Width); + cpu.MemMgr.Write(addr, cpu.Y.Value, cpu.Y.Width); } public void ExecuteSTX(byte instruction, AddressModes addressMode, int signature) { int addr = GetAddress(addressMode, signature, cpu.DataBank); - cpu.Memory.Write(addr, cpu.X.Value, cpu.X.Width); + cpu.MemMgr.Write(addr, cpu.X.Value, cpu.X.Width); } public void ExecuteLDA(byte instruction, AddressModes addressMode, int signature) diff --git a/Main/UI/CPUWindow.cs b/Main/UI/CPUWindow.cs index fd47087..673f467 100644 --- a/Main/UI/CPUWindow.cs +++ b/Main/UI/CPUWindow.cs @@ -540,7 +540,7 @@ public void UpdateStackDisplay() while (i > 0) { int address = kernel.CPU.Stack.Value + i; - stackText.AppendText(address.ToString("X4") + " " + kernel.CPU.Memory[address].ToString("X2") + "\r\n"); + stackText.AppendText(address.ToString("X4") + " " + kernel.CPU.MemMgr[address].ToString("X2") + "\r\n"); i--; } } diff --git a/Main/UI/MainWindow.Designer.cs b/Main/UI/MainWindow.Designer.cs index 410cff4..6f66a00 100644 --- a/Main/UI/MainWindow.Designer.cs +++ b/Main/UI/MainWindow.Designer.cs @@ -177,7 +177,7 @@ private void InitializeComponent() this.SDCardPath.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold); this.SDCardPath.Name = "SDCardPath"; this.SDCardPath.Overflow = System.Windows.Forms.ToolStripItemOverflow.Always; - this.SDCardPath.Size = new System.Drawing.Size(230, 23); + this.SDCardPath.Size = new System.Drawing.Size(261, 23); this.SDCardPath.Spring = true; this.SDCardPath.Text = "SD Card Disabled"; this.SDCardPath.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; diff --git a/Main/UI/MainWindow.cs b/Main/UI/MainWindow.cs index 6cf34df..297845b 100644 --- a/Main/UI/MainWindow.cs +++ b/Main/UI/MainWindow.cs @@ -183,7 +183,7 @@ private void ShowMemoryWindow() { memoryWindow = new MemoryWindow { - Memory = kernel.CPU.Memory, + Memory = kernel.CPU.MemMgr, Left = debugWindow.Left, Top = debugWindow.Top + debugWindow.Height }; @@ -248,7 +248,7 @@ private void LoadImageToolStripMenuItem_Click(object sender, EventArgs e) BitmapLoader loader = new BitmapLoader { StartPosition = FormStartPosition.CenterParent, - Memory = kernel.CPU.Memory, + Memory = kernel.CPU.MemMgr, ResChecker = ResChecker }; loader.ShowDialog(this); @@ -499,7 +499,7 @@ public void RestartMenuItemClick(object sender, EventArgs e) debugWindow.SetKernel(kernel); debugWindow.ClearTrace(); SetDipSwitchMemory(); - memoryWindow.Memory = kernel.CPU.Memory; + memoryWindow.Memory = kernel.CPU.MemMgr; memoryWindow.UpdateMCRButtons(); // Restart the CPU @@ -519,7 +519,7 @@ private void DebugToolStripMenuItem_Click(object sender, EventArgs e) debugWindow.SetKernel(kernel); debugWindow.ClearTrace(); SetDipSwitchMemory(); - memoryWindow.Memory = kernel.CPU.Memory; + memoryWindow.Memory = kernel.CPU.MemMgr; memoryWindow.UpdateMCRButtons(); debugWindow.Refresh(); } diff --git a/Main/UI/TileEditor.cs b/Main/UI/TileEditor.cs index 39e7ab5..f8d8dd5 100644 --- a/Main/UI/TileEditor.cs +++ b/Main/UI/TileEditor.cs @@ -21,7 +21,7 @@ public partial class TileEditor : Form private const int TILE_WIDTH = 17; private int selectedTilemap = 0; - private MemoryManager memory; + private MemoryManager MemMgr; private Pen whitePen = new Pen(Color.White); private Pen yellowPen = new Pen(Color.Yellow); @@ -49,9 +49,9 @@ private void TilesetViewer_MouseMove(object sender, MouseEventArgs e) TilesetViewer.Refresh(); } - public void SetMemory(MemoryManager memMgr) + public void SetMemory(MemoryManager mm) { - memory = memMgr; + MemMgr = mm; } /** @@ -65,14 +65,14 @@ private void TilesetViewer_Paint(object sender, PaintEventArgs e) BitmapData bitmapData = frameBuffer.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); IntPtr p = bitmapData.Scan0; int stride = bitmapData.Stride; - int[] graphicsLUT = Display.Gpu.LoadLUT(memory.VICKY); + int[] graphicsLUT = Display.Gpu.LoadLUT(MemMgr.VICKY); int lut = LutList.SelectedIndex; int tilesetAddress = Convert.ToInt32(TilesetAddress.Text, 16) - 0xB0_0000; for (int y = 0; y < 256; y++) { for (int x = 0; x < 256; x++) { - byte pixel = memory.VIDEO.ReadByte(tilesetAddress + y * 256 + x); + byte pixel = MemMgr.VIDEO.ReadByte(tilesetAddress + y * 256 + x); if (pixel != 0) { int color = graphicsLUT[lut * 256 + pixel]; @@ -119,19 +119,19 @@ public void Tilemap0Button_Click(object sender, EventArgs e) int addrOffset = MemoryLocations.MemoryMap.TILE_CONTROL_REGISTER_ADDR + selectedTilemap * 12; // show if the tilemap is enabled - ignore the LUT, it's not used - int ControlReg = memory.ReadByte(addrOffset); + int ControlReg = MemMgr.ReadByte(addrOffset); TilemapEnabledCheckbox.Checked = (ControlReg & 1) != 0; // address in memory - int tilemapAddr = memory.ReadLong(addrOffset + 1); + int tilemapAddr = MemMgr.ReadLong(addrOffset + 1); TilemapAddress.Text = (tilemapAddr + 0xB0_0000).ToString("X6"); - int width = memory.ReadWord(addrOffset + 4); - int height = memory.ReadWord(addrOffset + 6); + int width = MemMgr.ReadWord(addrOffset + 4); + int height = MemMgr.ReadWord(addrOffset + 6); Width.Text = width.ToString(); Height.Text = height.ToString(); - int windowX = memory.ReadWord(addrOffset + 8); - int windowY = memory.ReadWord(addrOffset + 10); + int windowX = MemMgr.ReadWord(addrOffset + 8); + int windowY = MemMgr.ReadWord(addrOffset + 10); WindowX.Text = windowX.ToString(); WindowY.Text = windowY.ToString(); } @@ -148,18 +148,18 @@ public void TileClicked_Click(Point tile) { // Write the tile value byte value = (byte)(selectedY * 16 + selectedX); - memory.WriteByte(tilemapAddress + offset, value); + MemMgr.WriteByte(tilemapAddress + offset, value); // Write the tileset and LUT - this way we can mix tiles from multiple tilesets in a single map - memory.WriteByte(tilemapAddress + offset + 1, (byte)((LutList.SelectedIndex << 3) + TilesetList.SelectedIndex)); + MemMgr.WriteByte(tilemapAddress + offset + 1, (byte)((LutList.SelectedIndex << 3) + TilesetList.SelectedIndex)); } } private void TilemapEnabledCheckbox_Click(object sender, EventArgs e) { int addrOffset = MemoryLocations.MemoryMap.TILE_CONTROL_REGISTER_ADDR + selectedTilemap * 12; - byte ControlReg = memory.ReadByte(addrOffset); + byte ControlReg = MemMgr.ReadByte(addrOffset); ControlReg = (byte)((ControlReg & 0xF0) + (TilemapEnabledCheckbox.Checked ? 1 : 0)); - memory.WriteByte(addrOffset, ControlReg); + MemMgr.WriteByte(addrOffset, ControlReg); } private void TileEditor_KeyDown(object sender, KeyEventArgs e) @@ -177,7 +177,7 @@ private void ClearTilemapButton_Click(object sender, EventArgs e) int height = Convert.ToInt32(Height.Text); for (int i = 0; i < width * height * 2; i++) { - memory.WriteByte(tilemapAddress + i, 0); + MemMgr.WriteByte(tilemapAddress + i, 0); } } @@ -197,7 +197,7 @@ private void SaveTilemapButton_Click(object sender, EventArgs e) int height = Convert.ToInt32(Height.Text); for (int i = 0; i < width * height * 2; i++) { - byte value = memory.ReadByte(tilemapAddress + i); + byte value = MemMgr.ReadByte(tilemapAddress + i); dataFile.WriteByte(value); } dataFile.Close(); @@ -208,7 +208,7 @@ private void LutList_SelectedIndexChanged(object sender, EventArgs e) { int tilesetBaseAddr = MemoryLocations.MemoryMap.TILESET_BASE_ADDR + TilesetList.SelectedIndex * 4; byte ConfigRegister = (byte)((Stride256Checkbox.Checked? 8:0) + LutList.SelectedIndex); - memory.WriteByte(tilesetBaseAddr + 3, ConfigRegister); + MemMgr.WriteByte(tilesetBaseAddr + 3, ConfigRegister); TilesetViewer.Refresh(); } @@ -219,7 +219,7 @@ private void TilesetAddress_TextChanged(object sender, EventArgs e) int offsetAddress = newAddress - 0xB0_0000; if (offsetAddress > -1) { - memory.WriteLong(tilesetBaseAddr, offsetAddress); + MemMgr.WriteLong(tilesetBaseAddr, offsetAddress); } } @@ -230,7 +230,7 @@ private void TilemapAddress_TextChanged(object sender, EventArgs e) int offsetAddress = newAddress - 0xB0_0000; if (offsetAddress > -1) { - memory.WriteLong(tilemapBaseAddr + 1, offsetAddress); + MemMgr.WriteLong(tilemapBaseAddr + 1, offsetAddress); } } @@ -240,7 +240,7 @@ private void Width_TextChanged(object sender, EventArgs e) if (Width.Text.Length > 0) { int newValue = Convert.ToInt32(Width.Text) & 0x3FF; - memory.WriteWord(tilemapBaseAddr + 4, newValue); + MemMgr.WriteWord(tilemapBaseAddr + 4, newValue); } } @@ -250,7 +250,7 @@ private void Height_TextChanged(object sender, EventArgs e) if (Height.Text.Length > 0) { int newValue = Convert.ToInt32(Height.Text) & 0x3FF; - memory.WriteWord(tilemapBaseAddr + 6, newValue); + MemMgr.WriteWord(tilemapBaseAddr + 6, newValue); } } @@ -260,7 +260,7 @@ private void WindowX_TextChanged(object sender, EventArgs e) if (WindowX.Text.Length > 0) { int newValue = Convert.ToInt32(WindowX.Text) & 0x3FF; - memory.WriteWord(tilemapBaseAddr + 8, newValue); + MemMgr.WriteWord(tilemapBaseAddr + 8, newValue); } } @@ -270,22 +270,22 @@ private void WindowY_TextChanged(object sender, EventArgs e) if (WindowY.Text.Length > 0) { int newValue = Convert.ToInt32(WindowY.Text) & 0x3FF; - memory.WriteWord(tilemapBaseAddr + 10, newValue); + MemMgr.WriteWord(tilemapBaseAddr + 10, newValue); } } private void TilemapEnabledCheckbox_CheckedChanged(object sender, EventArgs e) { int tilemapBaseAddr = MemoryLocations.MemoryMap.TILE_CONTROL_REGISTER_ADDR + selectedTilemap * 12; - memory.WriteByte(tilemapBaseAddr, (byte)(TilemapEnabledCheckbox.Checked ? 1 : 0)); + MemMgr.WriteByte(tilemapBaseAddr, (byte)(TilemapEnabledCheckbox.Checked ? 1 : 0)); } private void TilesetList_SelectedIndexChanged(object sender, EventArgs e) { int tilesetBaseAddr = MemoryLocations.MemoryMap.TILESET_BASE_ADDR + TilesetList.SelectedIndex * 4; - int tilesetAddr = memory.ReadLong(tilesetBaseAddr); + int tilesetAddr = MemMgr.ReadLong(tilesetBaseAddr); TilesetAddress.Text = (tilesetAddr + 0xB0_0000).ToString("X6"); - int cfgReg = memory.ReadByte(tilesetBaseAddr + 3); + int cfgReg = MemMgr.ReadByte(tilesetBaseAddr + 3); Stride256Checkbox.Checked = (cfgReg & 8) != 0; LutList.SelectedIndex = cfgReg & 7; } diff --git a/Main/UI/UploaderWindow.cs b/Main/UI/UploaderWindow.cs index 30eda21..99b868d 100644 --- a/Main/UI/UploaderWindow.cs +++ b/Main/UI/UploaderWindow.cs @@ -378,7 +378,7 @@ private void SendBinaryButton_Click(object sender, EventArgs e) byte[] DataBuffer = new byte[transmissionSize]; // Maximum 2 MB, example from $0 to $1F:FFFF. for (int start = blockAddress; start < blockAddress + transmissionSize; start++) { - DataBuffer[offset++] = kernel.CPU.Memory.ReadByte(start); + DataBuffer[offset++] = kernel.CPU.MemMgr.ReadByte(start); } SendData(DataBuffer, FnxAddressPtr, transmissionSize); // Update the Reset Vectors from the Binary Files Considering that the Files Keeps the Vector @ $00:FF00 diff --git a/Release Notes.txt b/Release Notes.txt index 78dc348..23b8c94 100644 --- a/Release Notes.txt +++ b/Release Notes.txt @@ -1,3 +1,7 @@ +Release 0.5.4.0 +--------------- +Handling Timer interrupts. Only the CHARGE registers are used to determine the interval. Minimum interval allowed is 1 millisecond. + Release 0.5.3.3 --------------- Fixed several issues with the tile editor. diff --git a/bin/Release/FoenixIDE.exe b/bin/Release/FoenixIDE.exe index e82e362..dd648db 100644 Binary files a/bin/Release/FoenixIDE.exe and b/bin/Release/FoenixIDE.exe differ