public void WriteMemoryZ80(ushort address, byte value) { if (address < 0x4000) { //Console.WriteLine("write z80 memory {0:X4}: {1:X2}",address, value); Z80Ram[address & 0x1FFF] = value; return; } if (address >= 0x4000 && address < 0x6000) { //Console.WriteLine(" === Z80 WRITES YM2612 {0:X4}:{1:X2} ===",address, value); YM2612.Write(address & 3, value, SoundCPU.TotalExecutedCycles); return; } if (address < 0x6100) { BankRegion >>= 1; BankRegion |= (value & 1) << 23; BankRegion &= 0x00FF8000; //Console.WriteLine("Bank pointing at {0:X8}",BankRegion); return; } if (address >= 0x7F00 && address < 0x7F20) { switch (address & 0x1F) { case 0x00: case 0x02: VDP.WriteVdpData((ushort)((value << 8) | value)); return; case 0x04: case 0x06: VDP.WriteVdpControl((ushort)((value << 8) | value)); return; case 0x11: case 0x13: case 0x15: case 0x17: PSG.WritePsgData(value, SoundCPU.TotalExecutedCycles); return; } } if (address >= 0x8000) { WriteByte(BankRegion | (address & 0x7FFF), (sbyte)value); return; } Console.WriteLine("UNHANDLED Z80 WRITE {0:X4}:{1:X2}", address, value); }
/// <summary> /// /// </summary> public FormYM2612Editor(YM2612 inst, YM2612Timbre timbre, bool singleSelect) : base(inst, timbre, singleSelect) { this.timbre = timbre; InitializeComponent(); Size = Settings.Default.YM2612EdSize; AddControl(new YM2612GeneralContainer(inst, timbre, "General")); AddControl(new YM2612OperatorContainer(timbre.Ops[0], "Operator 1")); AddControl(new YM2612OperatorContainer(timbre.Ops[1], "Operator 2")); AddControl(new YM2612OperatorContainer(timbre.Ops[2], "Operator 3")); AddControl(new YM2612OperatorContainer(timbre.Ops[3], "Operator 4")); }
public byte ReadMemoryZ80(ushort address) { if (address < 0x4000) { //Console.WriteLine("read z80 memory {0:X4}: {1:X2}",address, Z80Ram[address & 0x1FFF]); return(Z80Ram[address & 0x1FFF]); } if (address >= 0x4000 && address < 0x6000) { //Console.WriteLine(" === Z80 READS FM STATUS ==="); return(YM2612.ReadStatus(SoundCPU.TotalExecutedCycles)); // TODO: more than 1 read port probably? } if (address >= 0x8000) { // 68000 Bank region return((byte)ReadByte(BankRegion | (address & 0x7FFF))); } if (address <= 0x6100) // read from bank address register - returns FF { return(0xFF); } Console.WriteLine("UNHANDLED Z80 READ {0:X4}", address); return(0xCD); }
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); }
/// <summary> /// /// </summary> /// <param name="context"></param> /// <param name="provider"></param> /// <param name="value"></param> /// <returns></returns> public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) { IWindowsFormsEditorService editorService = null; if (provider != null) { editorService = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService; } if (editorService == null) { return(value); } bool singleSel = true; YM2612Timbre tim = context.Instance as YM2612Timbre; YM2612Timbre[] tims = value as YM2612Timbre[]; if (tims != null) { tim = tims[0]; singleSel = false; } YM2612 inst = null; try { //InstrumentManager.ExclusiveLockObject.EnterReadLock(); inst = InstrumentManager.FindParentInstrument(InstrumentType.YM2612, tim) as YM2612; } finally { //InstrumentManager.ExclusiveLockObject.ExitReadLock(); } if (inst != null) { if (singleSel) { var mmlValueGeneral = SimpleSerializer.SerializeProps(tim, nameof(tim.ALG), nameof(tim.FB), nameof(tim.AMS), nameof(tim.FMS), "GlobalSettings.EN", "GlobalSettings.LFOEN", "GlobalSettings.LFRQ" ); List <string> mmlValueOps = new List <string>(); for (int i = 0; i < tim.Ops.Length; i++) { var op = tim.Ops[i]; mmlValueOps.Add(SimpleSerializer.SerializeProps(op, nameof(op.EN), nameof(op.AR), nameof(op.D1R), nameof(op.D2R), nameof(op.RR), nameof(op.SL), nameof(op.TL), nameof(op.RS), nameof(op.MUL), nameof(op.DT1), nameof(op.AM), nameof(op.SSG) )); } FormYM2612Editor ed = new FormYM2612Editor(inst, tim, singleSel); { ed.MmlValueGeneral = mmlValueGeneral; ed.FormClosed += (s, e) => { if (ed.DialogResult == DialogResult.OK) { tim.Detailed = ed.MmlValueGeneral + "," + ed.MmlValueOps[0] + "," + ed.MmlValueOps[1] + "," + ed.MmlValueOps[2] + "," + ed.MmlValueOps[3]; } else if (ed.DialogResult == DialogResult.Cancel) { tim.Detailed = mmlValueGeneral + "," + mmlValueOps[0] + "," + mmlValueOps[1] + "," + mmlValueOps[2] + "," + mmlValueOps[3]; } }; ed.Show(); ed.Activated += (s, e) => { tim.Detailed = ed.MmlValueGeneral + "," + ed.MmlValueOps[0] + "," + ed.MmlValueOps[1] + "," + ed.MmlValueOps[2] + "," + ed.MmlValueOps[3]; }; } } else { using (FormYM2612Editor ed = new FormYM2612Editor(inst, tim, singleSel)) { string org = JsonConvert.SerializeObject(tims, Formatting.Indented); DialogResult dr = editorService.ShowDialog(ed); if (dr == DialogResult.OK || dr == DialogResult.Abort) { return(value); } else { return(JsonConvert.DeserializeObject <YM2612Timbre[]>(org)); } } } } return(value); // エディタ呼び出し直前の設定値をそのまま返す }