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); }
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); }
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(); } }
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}"); } }
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); }
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)); }
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(); }
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); }
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 }
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; } }
public void TestInput() { var m68k = new MC68000(); Assert.AreEqual(0x2700u, m68k.SR); }
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; } } } }
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); }