Beispiel #1
0
        public void TestAddition()
        {
            var m68k = new MC68000();

            // Move immidiate value long 4 into register D0
            m68k.Execute(0x203C, 4);
            // Add immidiate value long 8 with register D0
            // ADD.L #8,D0
            m68k.Execute(0xD0BC, 8);

            Assert.AreEqual(12u, m68k.D0);

            // Move immidiate value long 10 into register D1 and
            // Move immidiate value long 11 into register D2
            m68k.Execute(0x223C, 10);
            m68k.Execute(0x243C, 11);
            // Add D1 with the value of D2 (long)
            // ADD.L D2,D1
            m68k.Execute(0xD382);

            Assert.AreEqual(21u, m68k.D1);

            // ADDQ.L 4,D1
            m68k.Execute(0x5881);

            Assert.AreEqual(25u, m68k.D1);

            // ADDQ.L 8,D0
            m68k.Execute(0x5080);

            Assert.AreEqual(20u, m68k.D0);
        }
Beispiel #2
0
        public void TestSubtraction()
        {
            var m68k = new MC68000();

            // Move immidiate value long 73 into register D0
            m68k.Execute(0x203C, 73);
            // Subtract immidiate value long 4 with register D0
            m68k.Execute(0x90BC, 4);

            Assert.AreEqual(69u, m68k.D0);

            // Move immidiate value long 63 into register D1 and
            // Move immidiate value long 21 into register D2
            m68k.Execute(0x223C, 63);
            m68k.Execute(0x243C, 21);
            // Subtract D1 with the value of D2 (long)
            m68k.Execute(0x9282);

            Assert.AreEqual(42u, m68k.D1);

            // SUBQ.L 4,D1
            m68k.Execute(0x5981);

            Assert.AreEqual(38u, m68k.D1);

            // SUBQ.L 8,D1
            m68k.Execute(0x5181);

            Assert.AreEqual(30u, m68k.D1);
        }
Beispiel #3
0
        public static void Main(string[] args)
        {
            if (args is null || args.All(x => string.IsNullOrWhiteSpace(x)))
            {
                throw new ArgumentNullException(nameof(args));
            }

            int memSize = 512;

            if (args.Length == 1)
            {
                try
                {
                    memSize = int.Parse(args[0], CultureInfo.InvariantCulture);
                }
                catch (FormatException)
                {
                    Console.WriteLine($"Invalid number: {args[0]}");
                    Console.WriteLine("Usage: m68k.Monitor [memory size Kb]");
                    Environment.Exit(-1);
                }
            }

            Console.WriteLine("m68k Monitor v0.1 - Copyright 2008-2010 Tony Headford");
            using (var newMemory = new MemorySpace(memSize))
            {
                var newCpu = new MC68000();
                newCpu.SetAddressSpace(newMemory);
                newCpu.Reset();
                Monitor monitor = new Monitor(newCpu, newMemory);
                monitor.Run();
            }
        }
Beispiel #4
0
        public static void Run()
        {
            var m68k = new MC68000();
            var r    = new Random();

            while (true)
            {
                System.Threading.Thread.Sleep(150);

                // Operation code
                var op = (ushort)r.Next(ushort.MaxValue);
                // Operand
                var opr = (uint)r.Next(int.MaxValue);

                m68k.Execute(op, opr);

                Clear();

                WriteLine($" D0={m68k.D0:X8}  D1={m68k.D1:X8}  D2={m68k.D2:X8}  D3={m68k.D3:X8}");
                WriteLine($" D4={m68k.D4:X8}  D5={m68k.D5:X8}  D6={m68k.D6:X8}  D7={m68k.D7:X8}");
                WriteLine($" A0={m68k.A0:X8}  A1={m68k.A1:X8}  A2={m68k.A2:X8}  A3={m68k.A3:X8}");
                WriteLine($" A4={m68k.A4:X8}  A5={m68k.A5:X8}  A6={m68k.A6:X8}");
                WriteLine($"USP={m68k.USP:X6}  SSP={m68k.SSP:X6}  SR={m68k.SR:X4}");
                WriteLine();
                WriteLine($"{m68k.PC:X8}  {op:X4}  {opr:X8}");
            }
        }
Beispiel #5
0
 public AddTest1()
 {
     bus = new MemorySpace(1); //create 1kb of memory for the cpu
     cpu = new MC68000();
     cpu.AddressSpace = bus;
     cpu.Reset();
     cpu.SetAddrRegisterLong(7, 0x200);
 }
Beispiel #6
0
 private void TestSUBByteZeroFlag(MC68000 cpu, bool expectedZFlag, long d2_pre, long d2_post)
 {
     cpu.SetPC(4);
     cpu.SetDataRegisterLong(2, (int)d2_pre);
     cpu.Execute();
     Assert.Equal(d2_post, cpu.GetDataRegisterLong(2));
     Assert.Equal(0x00, cpu.GetDataRegisterByte(2));
     Assert.Equal(expectedZFlag, cpu.IsFlagSet(cpu.ZFlag));
 }
Beispiel #7
0
        public void TestRegisters()
        {
            var m68k = new MC68000();

            // Data
            m68k.Execute(0x203C, 1);
            Assert.AreEqual(1u, m68k.D0);
            m68k.Execute(0x223C, 2);
            Assert.AreEqual(2u, m68k.D1);
            m68k.Execute(0x243C, 3);
            Assert.AreEqual(3u, m68k.D2);
            m68k.Execute(0x263C, 4);
            Assert.AreEqual(4u, m68k.D3);
            m68k.Execute(0x283C, 5);
            Assert.AreEqual(5u, m68k.D4);
            m68k.Execute(0x2A3C, 6);
            Assert.AreEqual(6u, m68k.D5);
            m68k.Execute(0x2C3C, 7);
            Assert.AreEqual(7u, m68k.D6);
            m68k.Execute(0x2E3C, 8);
            Assert.AreEqual(8u, m68k.D7);

            // Address
            m68k.Execute(0x20BC, 11);
            Assert.AreEqual(11u, m68k.A0);
            m68k.Execute(0x22BC, 12);
            Assert.AreEqual(12u, m68k.A1);
            m68k.Execute(0x24BC, 13);
            Assert.AreEqual(13u, m68k.A2);
            m68k.Execute(0x26BC, 14);
            Assert.AreEqual(14u, m68k.A3);
            m68k.Execute(0x28BC, 15);
            Assert.AreEqual(15u, m68k.A4);
            m68k.Execute(0x2ABC, 16);
            Assert.AreEqual(16u, m68k.A5);
            m68k.Execute(0x2CBC, 17);
            Assert.AreEqual(17u, m68k.A6);

            /*m68k.Execute(0x2CBC, 18);
             * Assert.AreEqual(17u, m68k.A7);*/

            // The next two instructions is from a manual (mbsd_l2.pdf) from
            // Ricardo Gutierrez-Osuna, Wright State University

            // MOVE.L #$12,d0 | 00 10 000 000 111 100 | 203C 00000012
            m68k.Execute(0x203C, 0x12);
            Assert.AreEqual(0x12u, m68k.D0);

            // MOVE.B data,d1 | 00 01 001 000 111 001 | 1239 00002000
            // self note: This goes at the address 2000 stored in data (a variable?) and
            //            loads 24h into D1 (manually?)
            //            Is this due to a higher language?
            //m68k.Execute(0x1239, 0x2000);
            //Assert.AreEqual(24u, m68k.D1);
        }
        public AddressRegisterPreDecOperandTest()
        {
            //create 1kb of memory for the cpu
            bus = new MemorySpaceAnonymousInnerClass(this);

            cpu = new MC68000();
            cpu.AddressSpace = bus;
            cpu.Reset();
            cpu.SetAddrRegisterLong(7, 0x200);
            wordWrites.Clear();
        }
Beispiel #9
0
        public void TestBitwiseOperations()
        {
            // AND, OR, etc.
            var m68k = new MC68000();

            m68k.Execute(0x203C, 0x50); // D0: $50

            // ORI.L #$10,D0
            m68k.Execute(0x80, 0x12);

            Assert.AreEqual(0x52u, m68k.D0);
        }
Beispiel #10
0
        public void TestBitShifting()
        {
            var m68k = new MC68000();

            // Move immidiate value long 4 into register D0
            m68k.Execute(0x203C, 4);

            // Rotate long D0 to the left for 4 bits immidiately
            // ROXL 4,D0
            m68k.Execute(0xE990);

            Assert.AreEqual(64u, m68k.D0); //  4 << 4 = 64

            m68k.Execute(0x223C, 2);       // 2 -> D1

            // Rotate long D0 to the right from D1 (2 bits)
            // ROXL D1,D0
            m68k.Execute(0xE2B0);

            Assert.AreEqual(16u, m68k.D0); // 64 >> 2 = 16
        }
Beispiel #11
0
        private static void Main(string[] args)
        {
            Write("Creating MC68000... ");
            var m68k = new MC68000();

            WriteLine("OK");

            m68k.FlagIsSupervisor = true;
            //m68k.FlagTracingEnabled = true;

            WriteLine();
            WriteLine("What would you like to do?");
            WriteLine();
            WriteLine("1. Generate instructions randomly.");
            WriteLine("2. Interpret machine code.");
            WriteLine();

            string n = null;

            while (n == null || n.Length == 0)
            {
                Write("Input [1-2]: ");
                n = ReadLine();
            }

            switch (n[0])
            {
            case '1':
                RandomTester.Run();
                break;

            case '2':
                InterpreterPrompt.Enter();
                break;
            }
        }
Beispiel #12
0
        public void TestInput()
        {
            var m68k = new MC68000();

            Assert.AreEqual(0x2700u, m68k.SR);
        }
Beispiel #13
0
        public static void Enter()
        {
            var    m68k = new MC68000();
            string n;
            var    c = true; // Continue

            while (c)
            {
                n = null;
                do
                {
                    Write(">");
                    n = ReadLine();
                } while (n == null || n.Length == 0);

                if (!n.StartsWith("#")) // Remark/Comment
                {
                    switch (n[0])
                    {
                    case 'p':     // Print
                    {
                        var s = n.Split(
                            new[] { ' ' },
                            StringSplitOptions.RemoveEmptyEntries
                            );

                        switch (s.Length)
                        {
                        case 1:
                            WriteLine("No idea what to print.");
                            break;

                        case 2:
                            switch (s[1])         // Lazy..
                            {
                            case "d0":
                                WriteLine($"{m68k.D0:X8}");
                                break;

                            case "d1":
                                WriteLine($"{m68k.D1:X8}");
                                break;

                            case "d2":
                                WriteLine($"{m68k.D2:X8}");
                                break;

                            case "d3":
                                WriteLine($"{m68k.D3:X8}");
                                break;

                            case "d4":
                                WriteLine($"{m68k.D4:X8}");
                                break;

                            case "d5":
                                WriteLine($"{m68k.D5:X8}");
                                break;

                            case "d6":
                                WriteLine($"{m68k.D6:X8}");
                                break;

                            case "d7":
                                WriteLine($"{m68k.D7:X8}");
                                break;

                            case "a0":
                                WriteLine($"{m68k.A0:X8}");
                                break;

                            case "a1":
                                WriteLine($"{m68k.A1:X8}");
                                break;

                            case "a2":
                                WriteLine($"{m68k.A2:X8}");
                                break;

                            case "a3":
                                WriteLine($"{m68k.A3:X8}");
                                break;

                            case "a4":
                                WriteLine($"{m68k.A4:X8}");
                                break;

                            case "a5":
                                WriteLine($"{m68k.A5:X8}");
                                break;

                            case "a6":
                                WriteLine($"{m68k.A6:X8}");
                                break;

                            /*case "a7": // Already a TODO
                             * WriteLine($"{m68k.A7:X8}");
                             *  break;*/
                            case "sr":
                                WriteLine($"{m68k.SR:X4}");
                                break;

                            case "ssp":
                                WriteLine($"{m68k.SSP:X6}");
                                break;

                            case "usp":
                                WriteLine($"{m68k.USP:X6}");
                                break;

                            case "pc":
                                WriteLine($"{m68k.PC:X6}");
                                break;
                            /* MSP, IRP already a TODO */

                            default:
                                WriteLine("Unknown p argument.");
                                break;
                            }
                            break;

                        default:
                            WriteLine("Unsupported number of p arguments.");
                            break;
                        }
                    }
                    break;

                    case 't':     // Trace
                        WriteLine($" D0={m68k.D0:X8}  D1={m68k.D1:X8}  D2={m68k.D2:X8}  D3={m68k.D3:X8}");
                        WriteLine($" D4={m68k.D4:X8}  D5={m68k.D5:X8}  D6={m68k.D6:X8}  D7={m68k.D7:X8}");
                        WriteLine($" A0={m68k.A0:X8}  A1={m68k.A1:X8}  A2={m68k.A2:X8}  A3={m68k.A3:X8}");
                        WriteLine($" A4={m68k.A4:X8}  A5={m68k.A5:X8}  A6={m68k.A6:X8}");
                        WriteLine($" USP={m68k.USP:X6}  SSP={m68k.SSP:X6}  SR={m68k.SR:X4}");
                        WriteLine();
                        WriteLine($" PC={m68k.PC:X6}");
                        break;

                    case 'q':     // Quit
                        c = false;
                        break;

                    case 'h':     // Help
                    case '?':
                        WriteLine(" Usage:");
                        WriteLine("  <COMMAND> or <OPCODE> [<OPERAND>]");
                        WriteLine(" Note: Hexadecimal numbers must have the 0x prefix.");
                        WriteLine();
                        WriteLine(" COMMANDS:");
                        WriteLine("p <REGISTER>...Print register.");
                        WriteLine("t..............Print all registers.");
                        WriteLine();
                        WriteLine("?.........Brings this screen.");
                        WriteLine("q.........Quits.");
                        break;

                    default:
                    {
                        var s = n.Split(
                            new[] { ' ' },
                            StringSplitOptions.RemoveEmptyEntries
                            );

                        switch (s.Length)
                        {
                        // Case 0 is handled earlier.

                        case 1:
                            try
                            {
                                m68k.Execute(s[0].HexStringToUInt());
                            }
                            catch
                            {
                                WriteLine("Couldn't parse operation code.");
                            }
                            break;

                        case 2:
                        {
                            try
                            {
                                m68k.Execute(
                                    s[0].HexStringToUInt(),
                                    s[1].HexStringToUInt()
                                    );
                            }
                            catch
                            {
                                WriteLine("Couldn't parse operation code or operand.");
                            }
                        }
                        break;

                        default:
                            WriteLine("Too many operands");
                            break;
                        }
                    }
                    break;
                    }
                }
            }
        }
Beispiel #14
0
        public Genesis(CoreComm comm, GameInfo game, byte[] rom)
        {
            ServiceProvider = new BasicServiceProvider(this);
            CoreComm        = comm;
            MainCPU         = new MC68000();
            SoundCPU        = new Z80A();
            YM2612          = new YM2612()
            {
                MaxVolume = 23405
            };
            PSG = new SN76489()
            {
                MaxVolume = 4681
            };
            VDP = new GenVDP();
            VDP.DmaReadFrom68000 = ReadWord;
            (ServiceProvider as BasicServiceProvider).Register <IVideoProvider>(VDP);
            SoundMixer = new SoundMixer(YM2612, PSG);

            MainCPU.ReadByte    = ReadByte;
            MainCPU.ReadWord    = ReadWord;
            MainCPU.ReadLong    = ReadLong;
            MainCPU.WriteByte   = WriteByte;
            MainCPU.WriteWord   = WriteWord;
            MainCPU.WriteLong   = WriteLong;
            MainCPU.IrqCallback = InterruptCallback;

            // ---------------------- musashi -----------------------
#if MUSASHI
            _vdp    = vdpcallback;
            read8   = Read8;
            read16  = Read16;
            read32  = Read32;
            write8  = Write8;
            write16 = Write16;
            write32 = Write32;

            Musashi.RegisterVdpCallback(Marshal.GetFunctionPointerForDelegate(_vdp));
            Musashi.RegisterRead8(Marshal.GetFunctionPointerForDelegate(read8));
            Musashi.RegisterRead16(Marshal.GetFunctionPointerForDelegate(read16));
            Musashi.RegisterRead32(Marshal.GetFunctionPointerForDelegate(read32));
            Musashi.RegisterWrite8(Marshal.GetFunctionPointerForDelegate(write8));
            Musashi.RegisterWrite16(Marshal.GetFunctionPointerForDelegate(write16));
            Musashi.RegisterWrite32(Marshal.GetFunctionPointerForDelegate(write32));
#endif
            // ---------------------- musashi -----------------------

            SoundCPU.ReadMemory    = ReadMemoryZ80;
            SoundCPU.WriteMemory   = WriteMemoryZ80;
            SoundCPU.WriteHardware = (a, v) => { Console.WriteLine("Z80: Attempt I/O Write {0:X2}:{1:X2}", a, v); };
            SoundCPU.ReadHardware  = x => 0xFF;
            SoundCPU.IRQCallback   = () => SoundCPU.Interrupt = false;
            Z80Reset = true;
            RomData  = new byte[0x400000];
            for (int i = 0; i < rom.Length; i++)
            {
                RomData[i] = rom[i];
            }

            SetupMemoryDomains();
#if MUSASHI
            Musashi.Init();
            Musashi.Reset();
            VDP.GetPC = () => Musashi.PC;
#else
            MainCPU.Reset();
            VDP.GetPC = () => MainCPU.PC;
#endif
            InitializeCartHardware(game);
        }