From f7c15bfd0ff5cac3156bf03d5ffa35c86e45696e Mon Sep 17 00:00:00 2001 From: Kabuto Date: Mon, 28 Sep 2015 20:53:19 +0200 Subject: [PATCH] Fixed indentation and TODOs --- BizHawk.Emulation.Common/Database/Database.cs | 2 +- .../CPUs/MOS 6502X/Execute.cs | 8 +- .../Computers/Commodore64/C64.IDebuggable.cs | 186 +- .../Commodore64/C64.IDisassemblable.cs | 44 +- .../Computers/Commodore64/C64.Motherboard.cs | 8 +- .../Computers/Commodore64/C64.cs | 209 ++- .../CassettePort/CassettePortDevice.cs | 48 +- .../Commodore64/CassettePort/Tape.cs | 150 +- .../Computers/Commodore64/MOS/MOS6510.cs | 18 +- .../Computers/Commodore64/MOS/MOS6526-2.cs | 6 +- .../Computers/Commodore64/MOS/MOS6526.cs | 1582 ++++++++--------- .../Computers/Commodore64/MOS/MOS6581.cs | 2 +- .../Computers/Commodore64/MOS/Sid.cs | 6 +- .../Computers/Commodore64/MOS/Vic.Parse.cs | 4 +- .../Computers/Commodore64/MOS/Vic.cs | 6 +- 15 files changed, 1136 insertions(+), 1143 deletions(-) diff --git a/BizHawk.Emulation.Common/Database/Database.cs b/BizHawk.Emulation.Common/Database/Database.cs index 41c4f8eaf2..ee30a95d48 100644 --- a/BizHawk.Emulation.Common/Database/Database.cs +++ b/BizHawk.Emulation.Common/Database/Database.cs @@ -315,7 +315,7 @@ namespace BizHawk.Emulation.Common case ".T64": case ".G64": case ".CRT": - case ".TAP": + case ".TAP": game.System = "C64"; break; diff --git a/BizHawk.Emulation.Cores/CPUs/MOS 6502X/Execute.cs b/BizHawk.Emulation.Cores/CPUs/MOS 6502X/Execute.cs index 0c5e94c799..a79d0f8881 100644 --- a/BizHawk.Emulation.Cores/CPUs/MOS 6502X/Execute.cs +++ b/BizHawk.Emulation.Cores/CPUs/MOS 6502X/Execute.cs @@ -2932,9 +2932,9 @@ namespace BizHawk.Emulation.Cores.Components.M6502 mi++; } //ExecuteOne - public bool AtInstructionStart() - { - return Microcode[opcode][mi] >= Uop.End; - } + public bool AtInstructionStart() + { + return Microcode[opcode][mi] >= Uop.End; + } } } diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/C64.IDebuggable.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/C64.IDebuggable.cs index 6618958233..8e29874b02 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/C64.IDebuggable.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/C64.IDebuggable.cs @@ -51,110 +51,110 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64 } } - public bool CanStep(StepType type) - { - switch (type) - { - case StepType.Into: - case StepType.Over: - case StepType.Out: - return true; - default: - return false; - } - } + public bool CanStep(StepType type) + { + switch (type) + { + case StepType.Into: + case StepType.Over: + case StepType.Out: + return true; + default: + return false; + } + } - public void Step(StepType type) - { - switch (type) - { - case StepType.Into: - StepInto(); - break; - case StepType.Out: - StepOut(); - break; - case StepType.Over: - StepOver(); - break; - } - } + public void Step(StepType type) + { + switch (type) + { + case StepType.Into: + StepInto(); + break; + case StepType.Out: + StepOut(); + break; + case StepType.Over: + StepOver(); + break; + } + } - private void StepInto() - { - while (board.cpu.AtInstructionStart()) - { - DoCycle(); - } - while (!board.cpu.AtInstructionStart()) - { - DoCycle(); - } - } + private void StepInto() + { + while (board.cpu.AtInstructionStart()) + { + DoCycle(); + } + while (!board.cpu.AtInstructionStart()) + { + DoCycle(); + } + } - private void StepOver() - { - var instruction = board.cpu.Peek(board.cpu.PC); + private void StepOver() + { + var instruction = board.cpu.Peek(board.cpu.PC); - if (instruction == JSR) - { - var destination = board.cpu.PC + JSRSize; - while (board.cpu.PC != destination) - { - StepInto(); - } - } - else - { - StepInto(); - } - } + if (instruction == JSR) + { + var destination = board.cpu.PC + JSRSize; + while (board.cpu.PC != destination) + { + StepInto(); + } + } + else + { + StepInto(); + } + } - private void StepOut() - { - var instr = board.cpu.Peek(board.cpu.PC); + private void StepOut() + { + var instr = board.cpu.Peek(board.cpu.PC); - JSRCount = instr == JSR ? 1 : 0; + JSRCount = instr == JSR ? 1 : 0; - var bailOutFrame = Frame + 1; + var bailOutFrame = Frame + 1; - while (true) - { - StepInto(); - instr = board.cpu.Peek(board.cpu.PC); - if (instr == JSR) - { - JSRCount++; - } - else if ((instr == RTS || instr == RTI) && JSRCount <= 0) - { - StepInto(); - JSRCount = 0; - break; - } - else if (instr == RTS || instr == RTI) - { - JSRCount--; - } - else //Emergency Bailout Logic - { - if (Frame == bailOutFrame) - { - break; - } - } - } - } + while (true) + { + StepInto(); + instr = board.cpu.Peek(board.cpu.PC); + if (instr == JSR) + { + JSRCount++; + } + else if ((instr == RTS || instr == RTI) && JSRCount <= 0) + { + StepInto(); + JSRCount = 0; + break; + } + else if (instr == RTS || instr == RTI) + { + JSRCount--; + } + else //Emergency Bailout Logic + { + if (Frame == bailOutFrame) + { + break; + } + } + } + } - private int JSRCount = 0; + private int JSRCount = 0; - private const byte JSR = 0x20; - private const byte RTI = 0x40; - private const byte RTS = 0x60; + private const byte JSR = 0x20; + private const byte RTI = 0x40; + private const byte RTS = 0x60; - private const byte JSRSize = 3; + private const byte JSRSize = 3; - public IMemoryCallbackSystem MemoryCallbacks { get; private set; } - } + public IMemoryCallbackSystem MemoryCallbacks { get; private set; } + } } diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/C64.IDisassemblable.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/C64.IDisassemblable.cs index a24503805c..593b624e2f 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/C64.IDisassemblable.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/C64.IDisassemblable.cs @@ -5,32 +5,26 @@ using BizHawk.Emulation.Common; namespace BizHawk.Emulation.Cores.Computers.Commodore64 { - public partial class C64 : IDisassemblable - { - public string Cpu - { - get - { - return "6510"; - } - set - { - } - } + public partial class C64 : IDisassemblable + { + public string Cpu + { + get { return "6510"; } + } - public string PCRegisterName - { - get { return "PC"; } - } + public string PCRegisterName + { + get { return "PC"; } + } - public IEnumerable AvailableCpus - { - get { yield return "6510"; } - } + public IEnumerable AvailableCpus + { + get { yield return "6510"; } + } - public string Disassemble(MemoryDomain m, uint addr, out int length) - { - return Components.M6502.MOS6502X.Disassemble((ushort)addr, out length, (a) => m.PeekByte(a)); - } - } + public string Disassemble(MemoryDomain m, uint addr, out int length) + { + return Components.M6502.MOS6502X.Disassemble((ushort)addr, out length, (a) => m.PeekByte(a)); + } + } } diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/C64.Motherboard.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/C64.Motherboard.cs index e36539f7b7..9336a2b329 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/C64.Motherboard.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/C64.Motherboard.cs @@ -42,7 +42,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64 private C64 _c64; - public Motherboard(C64 c64, Region initRegion) + public Motherboard(C64 c64, DisplayType initRegion) { // note: roms need to be added on their own externally _c64 = c64; @@ -59,8 +59,8 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64 sid = MOS6581.Create(44100, initRegion); switch (initRegion) { - case Region.NTSC: vic = MOS6567.Create(); break; - case Region.PAL: vic = MOS6569.Create(); break; + case DisplayType.NTSC: vic = MOS6567.Create(); break; + case DisplayType.PAL: vic = MOS6569.Create(); break; } userPort = new UserPortDevice(); } @@ -102,7 +102,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64 sid.HardReset(); vic.HardReset(); userPort.HardReset(); - cassPort.HardReset(); + cassPort.HardReset(); // because of how mapping works, the cpu needs to be hard reset twice cpu.HardReset(); diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/C64.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/C64.cs index 81ab539f64..926e0f3eed 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/C64.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/C64.cs @@ -8,22 +8,15 @@ using System.Windows.Forms; namespace BizHawk.Emulation.Cores.Computers.Commodore64 { - // TODO: use the EMulation.Common Region enum - public enum Region - { - NTSC, - PAL - } - [CoreAttributes( "C64Hawk", "SaxxonPIke", isPorted: false, isReleased: false )] - [ServiceNotApplicable(typeof(IRegionable), typeof(ISettable<,>))] - sealed public partial class C64 : IEmulator, IStatable, IInputPollable, IDriveLight, IDebuggable, IDisassemblable - { + [ServiceNotApplicable(typeof(ISettable<,>))] + sealed public partial class C64 : IEmulator, IStatable, IInputPollable, IDriveLight, IDebuggable, IDisassemblable, IRegionable + { // framework public C64(CoreComm comm, GameInfo game, byte[] rom, string romextension) { @@ -34,37 +27,37 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64 inputFileInfo.Data = rom; inputFileInfo.Extension = romextension; CoreComm = comm; - Nullable region = queryUserForRegion(); - if (region == null) - { - throw new Exception("Can't construct new C64 because you didn't choose anything"); - } - Init(region.Value); + Region = queryUserForRegion(); + Init(Region); cyclesPerFrame = board.vic.CyclesPerFrame; SetupMemoryDomains(); - MemoryCallbacks = new MemoryCallbackSystem(); - HardReset(); + MemoryCallbacks = new MemoryCallbackSystem(); + HardReset(); (ServiceProvider as BasicServiceProvider).Register(board.vic); - } + } - private Nullable queryUserForRegion() - { - Form prompt = new Form() { Width = 160, Height = 120, FormBorderStyle = FormBorderStyle.FixedDialog, Text = "Region selector", StartPosition = FormStartPosition.CenterScreen }; - Label textLabel = new Label() { Left = 10, Top = 10, Width = 260, Text = "Please choose a region:" }; - RadioButton palButton = new RadioButton() { Left = 10, Top = 30, Width = 70, Text = "PAL", Checked = true }; - RadioButton ntscButton = new RadioButton() { Left = 80, Top = 30, Width = 70, Text = "NTSC" }; - Button confirmation = new Button() { Text = "Ok", Left = 40, Width = 80, Top = 60, DialogResult = DialogResult.OK }; - confirmation.Click += (sender, e) => { prompt.Close(); }; - prompt.Controls.Add(textLabel); - prompt.Controls.Add(palButton); - prompt.Controls.Add(ntscButton); - prompt.Controls.Add(confirmation); - prompt.AcceptButton = confirmation; + private DisplayType queryUserForRegion() + { + Form prompt = new Form() { Width = 160, Height = 120, FormBorderStyle = FormBorderStyle.FixedDialog, Text = "Region selector", StartPosition = FormStartPosition.CenterScreen }; + Label textLabel = new Label() { Left = 10, Top = 10, Width = 260, Text = "Please choose a region:" }; + RadioButton palButton = new RadioButton() { Left = 10, Top = 30, Width = 70, Text = "PAL", Checked = true }; + RadioButton ntscButton = new RadioButton() { Left = 80, Top = 30, Width = 70, Text = "NTSC" }; + Button confirmation = new Button() { Text = "Ok", Left = 40, Width = 80, Top = 60, DialogResult = DialogResult.OK }; + confirmation.Click += (sender, e) => { prompt.Close(); }; + prompt.Controls.Add(textLabel); + prompt.Controls.Add(palButton); + prompt.Controls.Add(ntscButton); + prompt.Controls.Add(confirmation); + prompt.AcceptButton = confirmation; - return prompt.ShowDialog() == DialogResult.OK ? palButton.Checked ? new Nullable(Region.PAL) : ntscButton.Checked ? new Nullable(Region.NTSC) : null : null; - } + if (prompt.ShowDialog() != DialogResult.OK || !palButton.Checked && !ntscButton.Checked) + { + throw new Exception("Can't construct new C64 because you didn't choose anything"); + } + return palButton.Checked ? DisplayType.PAL : DisplayType.NTSC; + } // internal variables private int _frame = 0; @@ -88,8 +81,8 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64 _frame = 0; _lagcount = 0; _islag = false; - frameCycles = 0; - } + frameCycles = 0; + } // audio/video public void EndAsyncSound() { } //TODO @@ -118,6 +111,12 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64 public IEmulatorServiceProvider ServiceProvider { get; private set; } + public DisplayType Region + { + get; + private set; + } + public void Dispose() { if (board.sid != null) @@ -127,69 +126,69 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64 } } - int frameCycles; + int frameCycles; - private void DoCycle() - { - if (frameCycles == 0) { - board.inputRead = false; - board.PollInput(); - board.cpu.LagCycles = 0; - } - - //disk.Execute(); - board.Execute(); - frameCycles++; - - // load PRG file if needed - if (loadPrg) - { - // check to see if cpu PC is at the BASIC warm start vector - if (board.cpu.PC == ((board.ram.Peek(0x0303) << 8) | board.ram.Peek(0x0302))) - { - //board.ram.Poke(0x0302, 0xAE); - //board.ram.Poke(0x0303, 0xA7); - ////board.ram.Poke(0x0302, board.ram.Peek(0x0308)); - ////board.ram.Poke(0x0303, board.ram.Peek(0x0309)); - - //if (inputFileInfo.Data.Length >= 6) - //{ - // board.ram.Poke(0x0039, inputFileInfo.Data[4]); - // board.ram.Poke(0x003A, inputFileInfo.Data[5]); - //} - PRG.Load(board.pla, inputFileInfo.Data); - loadPrg = false; - } - } - - if (frameCycles == cyclesPerFrame) - { - board.Flush(); - _islag = !board.inputRead; - - if (_islag) - _lagcount++; - frameCycles -= cyclesPerFrame; - _frame++; - - //Console.WriteLine("CPUPC: " + C64Util.ToHex(board.cpu.PC, 4) + " 1541PC: " + C64Util.ToHex(disk.PC, 4)); - - int test = board.cpu.LagCycles; - DriveLightOn = DriveLED; - } - } - - // process frame - public void FrameAdvance(bool render, bool rendersound) + // process frame + public void FrameAdvance(bool render, bool rendersound) { - do - { - DoCycle(); - } - while (frameCycles != 0); - } + do + { + DoCycle(); + } + while (frameCycles != 0); + } - private void HandleFirmwareError(string file) + private void DoCycle() + { + if (frameCycles == 0) { + board.inputRead = false; + board.PollInput(); + board.cpu.LagCycles = 0; + } + + //disk.Execute(); + board.Execute(); + frameCycles++; + + // load PRG file if needed + if (loadPrg) + { + // check to see if cpu PC is at the BASIC warm start vector + if (board.cpu.PC == ((board.ram.Peek(0x0303) << 8) | board.ram.Peek(0x0302))) + { + //board.ram.Poke(0x0302, 0xAE); + //board.ram.Poke(0x0303, 0xA7); + ////board.ram.Poke(0x0302, board.ram.Peek(0x0308)); + ////board.ram.Poke(0x0303, board.ram.Peek(0x0309)); + + //if (inputFileInfo.Data.Length >= 6) + //{ + // board.ram.Poke(0x0039, inputFileInfo.Data[4]); + // board.ram.Poke(0x003A, inputFileInfo.Data[5]); + //} + PRG.Load(board.pla, inputFileInfo.Data); + loadPrg = false; + } + } + + if (frameCycles == cyclesPerFrame) + { + board.Flush(); + _islag = !board.inputRead; + + if (_islag) + _lagcount++; + frameCycles -= cyclesPerFrame; + _frame++; + + //Console.WriteLine("CPUPC: " + C64Util.ToHex(board.cpu.PC, 4) + " 1541PC: " + C64Util.ToHex(disk.PC, 4)); + + int test = board.cpu.LagCycles; + DriveLightOn = DriveLED; + } + } + + private void HandleFirmwareError(string file) { System.Windows.Forms.MessageBox.Show("the C64 core is referencing a firmware file which could not be found. Please make sure it's in your configured C64 firmwares folder. The referenced filename is: " + file); throw new FileNotFoundException(); @@ -206,7 +205,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64 return result; } - private void Init(Region initRegion) + private void Init(DisplayType initRegion) { board = new Motherboard(this, initRegion); InitRoms(); @@ -228,13 +227,13 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64 { board.cartPort.Connect(cart); } - break; - case @".TAP": - CassettePort.Tape tape = CassettePort.Tape.Load(inputFileInfo.Data); - if (tape != null) - { - board.cassPort.Connect(tape); - } + break; + case @".TAP": + CassettePort.Tape tape = CassettePort.Tape.Load(inputFileInfo.Data); + if (tape != null) + { + board.cassPort.Connect(tape); + } break; case @".PRG": if (inputFileInfo.Data.Length > 2) @@ -261,5 +260,5 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64 board.HardReset(); //disk.HardReset(); } - } + } } diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/CassettePort/CassettePortDevice.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/CassettePort/CassettePortDevice.cs index 970b326e37..44aa71e893 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/CassettePort/CassettePortDevice.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/CassettePort/CassettePortDevice.cs @@ -9,33 +9,33 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.CassettePort { public class CassettePortDevice { - public Func ReadDataOutput; - public Func ReadMotor; - Commodore64.CassettePort.Tape tape; + public Func ReadDataOutput; + public Func ReadMotor; + Commodore64.CassettePort.Tape tape; - public void HardReset() - { - if (tape != null) tape.rewind(); - } + public void HardReset() + { + if (tape != null) tape.rewind(); + } - virtual public bool ReadDataInputBuffer() - { - return tape != null && !ReadMotor() ? tape.read() : true; - } + virtual public bool ReadDataInputBuffer() + { + return tape != null && !ReadMotor() ? tape.read() : true; + } - virtual public bool ReadSenseBuffer() - { - return tape == null; // Just assume that "play" is constantly pressed as long as a tape is inserted - } + virtual public bool ReadSenseBuffer() + { + return tape == null; // Just assume that "play" is constantly pressed as long as a tape is inserted + } - public void SyncState(Serializer ser) - { - SaveState.SyncObject(ser, this); - } + public void SyncState(Serializer ser) + { + SaveState.SyncObject(ser, this); + } - internal void Connect(Tape tape) - { - this.tape = tape; - } - } + internal void Connect(Tape tape) + { + this.tape = tape; + } + } } diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/CassettePort/Tape.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/CassettePort/Tape.cs index 9b0c786f9d..8bf85bae65 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/CassettePort/Tape.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/CassettePort/Tape.cs @@ -9,85 +9,85 @@ using BizHawk.Common; namespace BizHawk.Emulation.Cores.Computers.Commodore64.CassettePort { - /** - * This class represents a tape. Only TAP-style tapes are supported for now. - */ - class Tape - { - private byte[] tapeData; - private byte version; - private uint pos, cycle, start, end; + /** + * This class represents a tape. Only TAP-style tapes are supported for now. + */ + class Tape + { + private byte[] tapeData; + private byte version; + private uint pos, cycle, start, end; - public Tape(byte version, byte[] tapeData, uint start, uint end) - { - this.version = version; - this.tapeData = tapeData; - this.start = start; - this.end = end; - rewind(); - } + public Tape(byte version, byte[] tapeData, uint start, uint end) + { + this.version = version; + this.tapeData = tapeData; + this.start = start; + this.end = end; + rewind(); + } - // Rewinds the tape back to start - public void rewind() - { - pos = start; - cycle = 0; - } + // Rewinds the tape back to start + public void rewind() + { + pos = start; + cycle = 0; + } - // Reads from tape, this will tell the caller if the flag pin should be raised - public bool read() - { - if (cycle == 0) - { - Console.WriteLine("Tape @ " + pos.ToString()); - if (pos >= end) - { - return true; - } - else - { - cycle = ((uint)tapeData[pos++])*8; - if (cycle == 0) - { - if (version == 0) - { - cycle = 256 * 8; // unspecified overflow condition - } - else - { - cycle = BitConverter.ToUInt32(tapeData, (int)pos-1)>>8; - pos += 3; - if (cycle == 0) - { - throw new Exception("Bad tape data"); - } - } - } - } - } + // Reads from tape, this will tell the caller if the flag pin should be raised + public bool read() + { + if (cycle == 0) + { + Console.WriteLine("Tape @ " + pos.ToString()); + if (pos >= end) + { + return true; + } + else + { + cycle = ((uint)tapeData[pos++])*8; + if (cycle == 0) + { + if (version == 0) + { + cycle = 256 * 8; // unspecified overflow condition + } + else + { + cycle = BitConverter.ToUInt32(tapeData, (int)pos-1)>>8; + pos += 3; + if (cycle == 0) + { + throw new Exception("Bad tape data"); + } + } + } + } + } - // Send a single negative pulse at the end of a cycle - return --cycle != 0; - } + // Send a single negative pulse at the end of a cycle + return --cycle != 0; + } - // Try to construct a tape file from file data. Returns null if not a tape file, throws exceptions for bad tape files. - // (Note that some error conditions aren't caught right here.) - static public Tape Load(byte[] tapeFile) - { - Tape result = null; + // Try to construct a tape file from file data. Returns null if not a tape file, throws exceptions for bad tape files. + // (Note that some error conditions aren't caught right here.) + static public Tape Load(byte[] tapeFile) + { + Tape result = null; - if (System.Text.Encoding.ASCII.GetString(tapeFile, 0, 12) == "C64-TAPE-RAW") - { - byte version = tapeFile[12]; - if (version > 1) throw new Exception("This tape has an unsupported version"); - uint size = BitConverter.ToUInt32(tapeFile, 16); - if (size + 20 != tapeFile.Length) - { - throw new Exception("Tape file header specifies a length that doesn't match the file size"); - } - result = new Tape(version, tapeFile, 20, (uint)tapeFile.Length); - } - return result; - } - } + if (System.Text.Encoding.ASCII.GetString(tapeFile, 0, 12) == "C64-TAPE-RAW") + { + byte version = tapeFile[12]; + if (version > 1) throw new Exception("This tape has an unsupported version"); + uint size = BitConverter.ToUInt32(tapeFile, 16); + if (size + 20 != tapeFile.Length) + { + throw new Exception("Tape file header specifies a length that doesn't match the file size"); + } + result = new Tape(version, tapeFile, 20, (uint)tapeFile.Length); + } + return result; + } + } } diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/MOS6510.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/MOS6510.cs index 6149c4cf42..51cb927531 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/MOS6510.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/MOS6510.cs @@ -99,18 +99,18 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS } set { - lagCycles = value; - } - } + lagCycles = value; + } + } - internal bool AtInstructionStart() - { - return cpu.AtInstructionStart(); - } + internal bool AtInstructionStart() + { + return cpu.AtInstructionStart(); + } - // ------------------------------------ + // ------------------------------------ - public ushort PC + public ushort PC { get { diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/MOS6526-2.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/MOS6526-2.cs index bc0d060fb1..30a3bdfd9d 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/MOS6526-2.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/MOS6526-2.cs @@ -233,7 +233,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS LatchedPort portA; LatchedPort portB; - public MOS6526_2(Region region) + public MOS6526_2(Common.DisplayType region) { a = new CiaTimer(serialPortA, underFlowA); b = new CiaTimer(serialPortB, underFlowB); @@ -241,10 +241,10 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS portB = new LatchedPort(); switch (region) { - case Region.NTSC: + case Common.DisplayType.NTSC: tod_period = 14318181 / 140; break; - case Region.PAL: + case Common.DisplayType.PAL: tod_period = 17734472 / 180; break; } diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/MOS6526.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/MOS6526.cs index 341fd8a728..54df3fd29d 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/MOS6526.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/MOS6526.cs @@ -3,795 +3,795 @@ using BizHawk.Common; namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS { - // MOS technology 6526 "CIA" - // - // emulation notes: - // * CS, R/W and RS# pins are not emulated. (not needed) - // * A low RES pin is emulated via HardReset(). - - sealed public class MOS6526 - { - // ------------------------------------ - - enum InMode - { - Phase2, - CNT, - TimerAUnderflow, - TimerAUnderflowCNT - } - - enum OutMode - { - Pulse, - Toggle - } - - enum RunMode - { - Continuous, - Oneshot - } - - enum SPMode - { - Input, - Output - } - - static byte[] PBOnBit = new byte[] { 0x40, 0x80 }; - static byte[] PBOnMask = new byte[] { 0xBF, 0x7F }; - - // ------------------------------------ - - public Func ReadCNT; - public Func ReadFlag; - public Func ReadSP; - - // ------------------------------------ - - bool alarmSelect; - Region chipRegion; - bool cntPos; - bool enableIntAlarm; - bool enableIntFlag; - bool enableIntSP; - bool[] enableIntTimer; - bool intAlarm; - bool intFlag; - bool intSP; - bool[] intTimer; - bool pinCnt; - bool pinCntLast; - bool pinPC; - bool pinSP; - byte sr; - int[] timerDelay; - InMode[] timerInMode; - OutMode[] timerOutMode; - bool[] timerPortEnable; - bool[] timerPulse; - RunMode[] timerRunMode; - SPMode timerSPMode; - byte[] tod; - byte[] todAlarm; - bool todAlarmPM; - int todCounter; - int todCounterLatch; - bool todIn; - bool todPM; - bool oldFlag; - // ------------------------------------ - - public MOS6526(Region region) - { - chipRegion = region; - enableIntTimer = new bool[2]; - intTimer = new bool[2]; - timerDelay = new int[2]; - timerInMode = new InMode[2]; - timerOutMode = new OutMode[2]; - timerPortEnable = new bool[2]; - timerPulse = new bool[2]; - timerRunMode = new RunMode[2]; - tod = new byte[4]; - todAlarm = new byte[4]; - SetTodIn(chipRegion); - - portA = new LatchedPort(); - portB = new LatchedPort(); - timer = new int[2]; - timerLatch = new int[2]; - timerOn = new bool[2]; - underflow = new bool[2]; - - pinSP = true; - } - - // ------------------------------------ - - public void ExecutePhase1() - { - // unsure if the timer actually operates in ph1 - pinIRQ = !( - (intTimer[0] && enableIntTimer[0]) || - (intTimer[1] && enableIntTimer[1]) || - (intAlarm && enableIntAlarm) || - (intSP && enableIntSP) || - (intFlag && enableIntFlag) - ); - } - - public void ExecutePhase2() - { - { - bool sumCnt = ReadCNT(); - cntPos |= (!pinCntLast && sumCnt); - pinCntLast = sumCnt; - - pinPC = true; - TODRun(); - - if (timerPulse[0]) - { - portA.Latch &= PBOnMask[0]; - } - if (timerPulse[1]) - { - portB.Latch &= PBOnMask[1]; - } - - if (timerDelay[0] == 0) - TimerRun(0); - else - timerDelay[0]--; - - if (timerDelay[1] == 0) - TimerRun(1); - else - timerDelay[1]--; - - intAlarm |= ( - tod[0] == todAlarm[0] && - tod[1] == todAlarm[1] && - tod[2] == todAlarm[2] && - tod[3] == todAlarm[3] && - todPM == todAlarmPM); - - cntPos = false; - underflow[0] = false; - underflow[1] = false; - - bool newFlag = ReadFlag(); - intFlag |= oldFlag && !newFlag; - oldFlag = newFlag; - } - } - - public void HardReset() - { - HardResetInternal(); - alarmSelect = false; - cntPos = false; - enableIntAlarm = false; - enableIntFlag = false; - enableIntSP = false; - enableIntTimer[0] = false; - enableIntTimer[1] = false; - intAlarm = false; - intFlag = false; - intSP = false; - intTimer[0] = false; - intTimer[1] = false; - sr = 0; - timerDelay[0] = 0; - timerDelay[1] = 0; - timerInMode[0] = InMode.Phase2; - timerInMode[1] = InMode.Phase2; - timerOn[0] = false; - timerOn[1] = false; - timerOutMode[0] = OutMode.Pulse; - timerOutMode[1] = OutMode.Pulse; - timerPortEnable[0] = false; - timerPortEnable[1] = false; - timerPulse[0] = false; - timerPulse[1] = false; - timerRunMode[0] = RunMode.Continuous; - timerRunMode[1] = RunMode.Continuous; - timerSPMode = SPMode.Input; - tod[0] = 0; - tod[1] = 0; - tod[2] = 0; - tod[3] = 0x12; - todAlarm[0] = 0; - todAlarm[1] = 0; - todAlarm[2] = 0; - todAlarm[3] = 0; - todCounter = todCounterLatch; - todIn = (chipRegion == Region.PAL); - todPM = false; - - pinCnt = false; - pinPC = true; - } - - private void SetTodIn(Region region) - { - switch (region) - { - case Region.NTSC: - todCounterLatch = 14318181 / 140; - todIn = false; - break; - case Region.PAL: - todCounterLatch = 17734472 / 180; - todIn = true; - break; - } - } - - // ------------------------------------ - - private byte BCDAdd(byte i, byte j, out bool overflow) - { - - { - int lo; - int hi; - int result; - - lo = (i & 0x0F) + (j & 0x0F); - hi = (i & 0x70) + (j & 0x70); - if (lo > 0x09) - { - hi += 0x10; - lo += 0x06; - } - if (hi > 0x50) - { - hi += 0xA0; - } - overflow = hi >= 0x60; - result = (hi & 0x70) + (lo & 0x0F); - return (byte)(result & 0xFF); - } - } - - private void TimerRun(int index) - { - - { - if (timerOn[index]) - { - int t = timer[index]; - bool u = false; - - { - switch (timerInMode[index]) - { - case InMode.CNT: - // CNT positive - if (cntPos) - { - t--; - u = (t == 0); - intTimer[index] |= (t == 0); - } - break; - case InMode.Phase2: - // every clock - t--; - u = (t == 0); - intTimer[index] |= (t == 0); - break; - case InMode.TimerAUnderflow: - // every underflow[0] - if (underflow[0]) - { - t--; - u = (t == 0); - intTimer[index] |= (t == 0); - } - break; - case InMode.TimerAUnderflowCNT: - // every underflow[0] while CNT high - if (underflow[0] && pinCnt) - { - t--; - u = (t == 0); - intTimer[index] |= (t == 0); - } - break; - } - - // underflow? - if (u) - { - timerDelay[index] = 1; - t = timerLatch[index]; - if (timerRunMode[index] == RunMode.Oneshot) - timerOn[index] = false; - - if (timerPortEnable[index]) - { - // force port B bit to output - portB.Direction |= PBOnBit[index]; - switch (timerOutMode[index]) - { - case OutMode.Pulse: - timerPulse[index] = true; - portB.Latch |= PBOnBit[index]; - break; - case OutMode.Toggle: - portB.Latch ^= PBOnBit[index]; - break; - } - } - } - - underflow[index] = u; - timer[index] = t; - } - } - } - } - - private void TODRun() - { - - { - bool todV; - - if (todCounter == 0) - { - todCounter = todCounterLatch; - tod[0] = BCDAdd(tod[0], 1, out todV); - if (tod[0] >= 10) - { - tod[0] = 0; - tod[1] = BCDAdd(tod[1], 1, out todV); - if (todV) - { - tod[1] = 0; - tod[2] = BCDAdd(tod[2], 1, out todV); - if (todV) - { - tod[2] = 0; - tod[3] = BCDAdd(tod[3], 1, out todV); - if (tod[3] > 12) - { - tod[3] = 1; - } - else if (tod[3] == 12) - { - todPM = !todPM; - } - } - } - } - } - todCounter--; - } - } - - // ------------------------------------ - - public byte Peek(long addr) - { - return ReadRegister((int)addr & 0xF); - } - - public void Poke(long addr, byte val) - { - WriteRegister((int)(addr & 0xF), val); - } - - public byte Peek(int addr) - { - return ReadRegister((int)addr & 0xF); - } - - public void Poke(int addr, byte val) - { - WriteRegister((int)(addr & 0xF), val); - } - - public byte Read(int addr) - { - return Read(addr, 0xFF); - } - - public byte Read(int addr, byte mask) - { - addr &= 0xF; - byte val; - - switch (addr) - { - case 0x01: - val = ReadRegister(addr); - pinPC = false; - break; - case 0x0D: - val = ReadRegister(addr); - intTimer[0] = false; - intTimer[1] = false; - intAlarm = false; - intSP = false; - intFlag = false; - pinIRQ = true; - break; - default: - val = ReadRegister(addr); - break; - } - - val &= mask; - return val; - } - - public bool ReadCNTBuffer() - { - return pinCnt; - } - - public bool ReadPCBuffer() - { - return pinPC; - } - - private byte ReadRegister(int addr) - { - byte val = 0x00; //unused pin value - int timerVal; - - switch (addr) - { - case 0x0: - val = (byte)(portA.ReadInput(ReadPortA()) & PortAMask); - break; - case 0x1: - val = (byte)(portB.ReadInput(ReadPortB()) & PortBMask); - break; - case 0x2: - val = portA.Direction; - break; - case 0x3: - val = portB.Direction; - break; - case 0x4: - timerVal = ReadTimerValue(0); - val = (byte)(timerVal & 0xFF); - break; - case 0x5: - timerVal = ReadTimerValue(0); - val = (byte)(timerVal >> 8); - break; - case 0x6: - timerVal = ReadTimerValue(1); - val = (byte)(timerVal & 0xFF); - break; - case 0x7: - timerVal = ReadTimerValue(1); - val = (byte)(timerVal >> 8); - break; - case 0x8: - val = tod[0]; - break; - case 0x9: - val = tod[1]; - break; - case 0xA: - val = tod[2]; - break; - case 0xB: - val = tod[3]; - break; - case 0xC: - val = sr; - break; - case 0xD: - val = (byte)( - (intTimer[0] ? 0x01 : 0x00) | - (intTimer[1] ? 0x02 : 0x00) | - (intAlarm ? 0x04 : 0x00) | - (intSP ? 0x08 : 0x00) | - (intFlag ? 0x10 : 0x00) | - (!pinIRQ ? 0x80 : 0x00) - ); - break; - case 0xE: - val = (byte)( - (timerOn[0] ? 0x01 : 0x00) | - (timerPortEnable[0] ? 0x02 : 0x00) | - (todIn ? 0x80 : 0x00)); - if (timerOutMode[0] == OutMode.Toggle) - val |= 0x04; - if (timerRunMode[0] == RunMode.Oneshot) - val |= 0x08; - if (timerInMode[0] == InMode.CNT) - val |= 0x20; - if (timerSPMode == SPMode.Output) - val |= 0x40; - break; - case 0xF: - val = (byte)( - (timerOn[1] ? 0x01 : 0x00) | - (timerPortEnable[1] ? 0x02 : 0x00) | - (alarmSelect ? 0x80 : 0x00)); - if (timerOutMode[1] == OutMode.Toggle) - val |= 0x04; - if (timerRunMode[1] == RunMode.Oneshot) - val |= 0x08; - switch (timerInMode[1]) - { - case InMode.CNT: - val |= 0x20; - break; - case InMode.TimerAUnderflow: - val |= 0x40; - break; - case InMode.TimerAUnderflowCNT: - val |= 0x60; - break; - } - break; - } - - return val; - } - - public bool ReadSPBuffer() - { - return pinSP; - } - - private int ReadTimerValue(int index) - { - if (timerOn[index]) - { - if (timer[index] == 0) - return timerLatch[index]; - else - return timer[index]; - } - else - { - return timer[index]; - } - } - - public void SyncState(Serializer ser) - { - SaveState.SyncObject(ser, this); - } - - public void Write(int addr, byte val) - { - Write(addr, val, 0xFF); - } - - public void Write(int addr, byte val, byte mask) - { - addr &= 0xF; - val &= mask; - val |= (byte)(ReadRegister(addr) & ~mask); - - switch (addr) - { - case 0x1: - WriteRegister(addr, val); - pinPC = false; - break; - case 0x5: - WriteRegister(addr, val); - if (!timerOn[0]) - timer[0] = timerLatch[0]; - break; - case 0x7: - WriteRegister(addr, val); - if (!timerOn[1]) - timer[1] = timerLatch[1]; - break; - case 0xE: - WriteRegister(addr, val); - if ((val & 0x10) != 0) - timer[0] = timerLatch[0]; - break; - case 0xF: - WriteRegister(addr, val); - if ((val & 0x10) != 0) - timer[1] = timerLatch[1]; - break; - default: - WriteRegister(addr, val); - break; - } - } - - public void WriteRegister(int addr, byte val) - { - bool intReg; - - switch (addr) - { - case 0x0: - portA.Latch = val; - break; - case 0x1: - portB.Latch = val; - break; - case 0x2: - portA.Direction = val; - break; - case 0x3: - portB.Direction = val; - break; - case 0x4: - timerLatch[0] &= 0xFF00; - timerLatch[0] |= val; - break; - case 0x5: - timerLatch[0] &= 0x00FF; - timerLatch[0] |= val << 8; - break; - case 0x6: - timerLatch[1] &= 0xFF00; - timerLatch[1] |= val; - break; - case 0x7: - timerLatch[1] &= 0x00FF; - timerLatch[1] |= val << 8; - break; - case 0x8: - if (alarmSelect) - todAlarm[0] = (byte)(val & 0xF); - else - tod[0] = (byte)(val & 0xF); - break; - case 0x9: - if (alarmSelect) - todAlarm[1] = (byte)(val & 0x7F); - else - tod[1] = (byte)(val & 0x7F); - break; - case 0xA: - if (alarmSelect) - todAlarm[2] = (byte)(val & 0x7F); - else - tod[2] = (byte)(val & 0x7F); - break; - case 0xB: - if (alarmSelect) - { - todAlarm[3] = (byte)(val & 0x1F); - todAlarmPM = ((val & 0x80) != 0); - } - else - { - tod[3] = (byte)(val & 0x1F); - todPM = ((val & 0x80) != 0); - } - break; - case 0xC: - sr = val; - break; - case 0xD: - intReg = ((val & 0x80) != 0); - if ((val & 0x01) != 0) - enableIntTimer[0] = intReg; - if ((val & 0x02) != 0) - enableIntTimer[1] = intReg; - if ((val & 0x04) != 0) - enableIntAlarm = intReg; - if ((val & 0x08) != 0) - enableIntSP = intReg; - if ((val & 0x10) != 0) - enableIntFlag = intReg; - break; - case 0xE: - if ((val & 0x01) != 0 && !timerOn[0]) - timerDelay[0] = 2; - timerOn[0] = ((val & 0x01) != 0); - timerPortEnable[0] = ((val & 0x02) != 0); - timerOutMode[0] = ((val & 0x04) != 0) ? OutMode.Toggle : OutMode.Pulse; - timerRunMode[0] = ((val & 0x08) != 0) ? RunMode.Oneshot : RunMode.Continuous; - timerInMode[0] = ((val & 0x20) != 0) ? InMode.CNT : InMode.Phase2; - timerSPMode = ((val & 0x40) != 0) ? SPMode.Output : SPMode.Input; - todIn = ((val & 0x80) != 0); - break; - case 0xF: - if ((val & 0x01) != 0 && !timerOn[1]) - timerDelay[1] = 2; - timerOn[1] = ((val & 0x01) != 0); - timerPortEnable[1] = ((val & 0x02) != 0); - timerOutMode[1] = ((val & 0x04) != 0) ? OutMode.Toggle : OutMode.Pulse; - timerRunMode[1] = ((val & 0x08) != 0) ? RunMode.Oneshot : RunMode.Continuous; - switch (val & 0x60) - { - case 0x00: timerInMode[1] = InMode.Phase2; break; - case 0x20: timerInMode[1] = InMode.CNT; break; - case 0x40: timerInMode[1] = InMode.TimerAUnderflow; break; - case 0x60: timerInMode[1] = InMode.TimerAUnderflowCNT; break; - } - alarmSelect = ((val & 0x80) != 0); - break; - } - } - - // ------------------------------------ - - public byte PortAMask = 0xFF; - public byte PortBMask = 0xFF; - - bool pinIRQ; - LatchedPort portA; - LatchedPort portB; - int[] timer; - int[] timerLatch; - bool[] timerOn; - bool[] underflow; - - public Func ReadPortA = (() => { return 0xFF; }); - public Func ReadPortB = (() => { return 0xFF; }); - - void HardResetInternal() - { - timer[0] = 0xFFFF; - timer[1] = 0xFFFF; - timerLatch[0] = timer[0]; - timerLatch[1] = timer[1]; - pinIRQ = true; - } - - public byte PortAData - { - get - { - return portA.ReadOutput(); - } - } - - public byte PortADirection - { - get - { - return portA.Direction; - } - } - - public byte PortALatch - { - get - { - return portA.Latch; - } - } - - public byte PortBData - { - get - { - return portB.ReadOutput(); - } - } - - public byte PortBDirection - { - get - { - return portB.Direction; - } - } - - public byte PortBLatch - { - get - { - return portB.Latch; - } - } - - public bool ReadIRQBuffer() { return pinIRQ; } - } + // MOS technology 6526 "CIA" + // + // emulation notes: + // * CS, R/W and RS# pins are not emulated. (not needed) + // * A low RES pin is emulated via HardReset(). + + sealed public class MOS6526 + { + // ------------------------------------ + + enum InMode + { + Phase2, + CNT, + TimerAUnderflow, + TimerAUnderflowCNT + } + + enum OutMode + { + Pulse, + Toggle + } + + enum RunMode + { + Continuous, + Oneshot + } + + enum SPMode + { + Input, + Output + } + + static byte[] PBOnBit = new byte[] { 0x40, 0x80 }; + static byte[] PBOnMask = new byte[] { 0xBF, 0x7F }; + + // ------------------------------------ + + public Func ReadCNT; + public Func ReadFlag; + public Func ReadSP; + + // ------------------------------------ + + bool alarmSelect; + Common.DisplayType chipRegion; + bool cntPos; + bool enableIntAlarm; + bool enableIntFlag; + bool enableIntSP; + bool[] enableIntTimer; + bool intAlarm; + bool intFlag; + bool intSP; + bool[] intTimer; + bool pinCnt; + bool pinCntLast; + bool pinPC; + bool pinSP; + byte sr; + int[] timerDelay; + InMode[] timerInMode; + OutMode[] timerOutMode; + bool[] timerPortEnable; + bool[] timerPulse; + RunMode[] timerRunMode; + SPMode timerSPMode; + byte[] tod; + byte[] todAlarm; + bool todAlarmPM; + int todCounter; + int todCounterLatch; + bool todIn; + bool todPM; + bool oldFlag; + // ------------------------------------ + + public MOS6526(Common.DisplayType region) + { + chipRegion = region; + enableIntTimer = new bool[2]; + intTimer = new bool[2]; + timerDelay = new int[2]; + timerInMode = new InMode[2]; + timerOutMode = new OutMode[2]; + timerPortEnable = new bool[2]; + timerPulse = new bool[2]; + timerRunMode = new RunMode[2]; + tod = new byte[4]; + todAlarm = new byte[4]; + SetTodIn(chipRegion); + + portA = new LatchedPort(); + portB = new LatchedPort(); + timer = new int[2]; + timerLatch = new int[2]; + timerOn = new bool[2]; + underflow = new bool[2]; + + pinSP = true; + } + + // ------------------------------------ + + public void ExecutePhase1() + { + // unsure if the timer actually operates in ph1 + pinIRQ = !( + (intTimer[0] && enableIntTimer[0]) || + (intTimer[1] && enableIntTimer[1]) || + (intAlarm && enableIntAlarm) || + (intSP && enableIntSP) || + (intFlag && enableIntFlag) + ); + } + + public void ExecutePhase2() + { + { + bool sumCnt = ReadCNT(); + cntPos |= (!pinCntLast && sumCnt); + pinCntLast = sumCnt; + + pinPC = true; + TODRun(); + + if (timerPulse[0]) + { + portA.Latch &= PBOnMask[0]; + } + if (timerPulse[1]) + { + portB.Latch &= PBOnMask[1]; + } + + if (timerDelay[0] == 0) + TimerRun(0); + else + timerDelay[0]--; + + if (timerDelay[1] == 0) + TimerRun(1); + else + timerDelay[1]--; + + intAlarm |= ( + tod[0] == todAlarm[0] && + tod[1] == todAlarm[1] && + tod[2] == todAlarm[2] && + tod[3] == todAlarm[3] && + todPM == todAlarmPM); + + cntPos = false; + underflow[0] = false; + underflow[1] = false; + + bool newFlag = ReadFlag(); + intFlag |= oldFlag && !newFlag; + oldFlag = newFlag; + } + } + + public void HardReset() + { + HardResetInternal(); + alarmSelect = false; + cntPos = false; + enableIntAlarm = false; + enableIntFlag = false; + enableIntSP = false; + enableIntTimer[0] = false; + enableIntTimer[1] = false; + intAlarm = false; + intFlag = false; + intSP = false; + intTimer[0] = false; + intTimer[1] = false; + sr = 0; + timerDelay[0] = 0; + timerDelay[1] = 0; + timerInMode[0] = InMode.Phase2; + timerInMode[1] = InMode.Phase2; + timerOn[0] = false; + timerOn[1] = false; + timerOutMode[0] = OutMode.Pulse; + timerOutMode[1] = OutMode.Pulse; + timerPortEnable[0] = false; + timerPortEnable[1] = false; + timerPulse[0] = false; + timerPulse[1] = false; + timerRunMode[0] = RunMode.Continuous; + timerRunMode[1] = RunMode.Continuous; + timerSPMode = SPMode.Input; + tod[0] = 0; + tod[1] = 0; + tod[2] = 0; + tod[3] = 0x12; + todAlarm[0] = 0; + todAlarm[1] = 0; + todAlarm[2] = 0; + todAlarm[3] = 0; + todCounter = todCounterLatch; + todIn = (chipRegion == Common.DisplayType.PAL); + todPM = false; + + pinCnt = false; + pinPC = true; + } + + private void SetTodIn(Common.DisplayType region) + { + switch (region) + { + case Common.DisplayType.NTSC: + todCounterLatch = 14318181 / 140; + todIn = false; + break; + case Common.DisplayType.PAL: + todCounterLatch = 17734472 / 180; + todIn = true; + break; + } + } + + // ------------------------------------ + + private byte BCDAdd(byte i, byte j, out bool overflow) + { + + { + int lo; + int hi; + int result; + + lo = (i & 0x0F) + (j & 0x0F); + hi = (i & 0x70) + (j & 0x70); + if (lo > 0x09) + { + hi += 0x10; + lo += 0x06; + } + if (hi > 0x50) + { + hi += 0xA0; + } + overflow = hi >= 0x60; + result = (hi & 0x70) + (lo & 0x0F); + return (byte)(result & 0xFF); + } + } + + private void TimerRun(int index) + { + + { + if (timerOn[index]) + { + int t = timer[index]; + bool u = false; + + { + switch (timerInMode[index]) + { + case InMode.CNT: + // CNT positive + if (cntPos) + { + t--; + u = (t == 0); + intTimer[index] |= (t == 0); + } + break; + case InMode.Phase2: + // every clock + t--; + u = (t == 0); + intTimer[index] |= (t == 0); + break; + case InMode.TimerAUnderflow: + // every underflow[0] + if (underflow[0]) + { + t--; + u = (t == 0); + intTimer[index] |= (t == 0); + } + break; + case InMode.TimerAUnderflowCNT: + // every underflow[0] while CNT high + if (underflow[0] && pinCnt) + { + t--; + u = (t == 0); + intTimer[index] |= (t == 0); + } + break; + } + + // underflow? + if (u) + { + timerDelay[index] = 1; + t = timerLatch[index]; + if (timerRunMode[index] == RunMode.Oneshot) + timerOn[index] = false; + + if (timerPortEnable[index]) + { + // force port B bit to output + portB.Direction |= PBOnBit[index]; + switch (timerOutMode[index]) + { + case OutMode.Pulse: + timerPulse[index] = true; + portB.Latch |= PBOnBit[index]; + break; + case OutMode.Toggle: + portB.Latch ^= PBOnBit[index]; + break; + } + } + } + + underflow[index] = u; + timer[index] = t; + } + } + } + } + + private void TODRun() + { + + { + bool todV; + + if (todCounter == 0) + { + todCounter = todCounterLatch; + tod[0] = BCDAdd(tod[0], 1, out todV); + if (tod[0] >= 10) + { + tod[0] = 0; + tod[1] = BCDAdd(tod[1], 1, out todV); + if (todV) + { + tod[1] = 0; + tod[2] = BCDAdd(tod[2], 1, out todV); + if (todV) + { + tod[2] = 0; + tod[3] = BCDAdd(tod[3], 1, out todV); + if (tod[3] > 12) + { + tod[3] = 1; + } + else if (tod[3] == 12) + { + todPM = !todPM; + } + } + } + } + } + todCounter--; + } + } + + // ------------------------------------ + + public byte Peek(long addr) + { + return ReadRegister((int)addr & 0xF); + } + + public void Poke(long addr, byte val) + { + WriteRegister((int)(addr & 0xF), val); + } + + public byte Peek(int addr) + { + return ReadRegister((int)addr & 0xF); + } + + public void Poke(int addr, byte val) + { + WriteRegister((int)(addr & 0xF), val); + } + + public byte Read(int addr) + { + return Read(addr, 0xFF); + } + + public byte Read(int addr, byte mask) + { + addr &= 0xF; + byte val; + + switch (addr) + { + case 0x01: + val = ReadRegister(addr); + pinPC = false; + break; + case 0x0D: + val = ReadRegister(addr); + intTimer[0] = false; + intTimer[1] = false; + intAlarm = false; + intSP = false; + intFlag = false; + pinIRQ = true; + break; + default: + val = ReadRegister(addr); + break; + } + + val &= mask; + return val; + } + + public bool ReadCNTBuffer() + { + return pinCnt; + } + + public bool ReadPCBuffer() + { + return pinPC; + } + + private byte ReadRegister(int addr) + { + byte val = 0x00; //unused pin value + int timerVal; + + switch (addr) + { + case 0x0: + val = (byte)(portA.ReadInput(ReadPortA()) & PortAMask); + break; + case 0x1: + val = (byte)(portB.ReadInput(ReadPortB()) & PortBMask); + break; + case 0x2: + val = portA.Direction; + break; + case 0x3: + val = portB.Direction; + break; + case 0x4: + timerVal = ReadTimerValue(0); + val = (byte)(timerVal & 0xFF); + break; + case 0x5: + timerVal = ReadTimerValue(0); + val = (byte)(timerVal >> 8); + break; + case 0x6: + timerVal = ReadTimerValue(1); + val = (byte)(timerVal & 0xFF); + break; + case 0x7: + timerVal = ReadTimerValue(1); + val = (byte)(timerVal >> 8); + break; + case 0x8: + val = tod[0]; + break; + case 0x9: + val = tod[1]; + break; + case 0xA: + val = tod[2]; + break; + case 0xB: + val = tod[3]; + break; + case 0xC: + val = sr; + break; + case 0xD: + val = (byte)( + (intTimer[0] ? 0x01 : 0x00) | + (intTimer[1] ? 0x02 : 0x00) | + (intAlarm ? 0x04 : 0x00) | + (intSP ? 0x08 : 0x00) | + (intFlag ? 0x10 : 0x00) | + (!pinIRQ ? 0x80 : 0x00) + ); + break; + case 0xE: + val = (byte)( + (timerOn[0] ? 0x01 : 0x00) | + (timerPortEnable[0] ? 0x02 : 0x00) | + (todIn ? 0x80 : 0x00)); + if (timerOutMode[0] == OutMode.Toggle) + val |= 0x04; + if (timerRunMode[0] == RunMode.Oneshot) + val |= 0x08; + if (timerInMode[0] == InMode.CNT) + val |= 0x20; + if (timerSPMode == SPMode.Output) + val |= 0x40; + break; + case 0xF: + val = (byte)( + (timerOn[1] ? 0x01 : 0x00) | + (timerPortEnable[1] ? 0x02 : 0x00) | + (alarmSelect ? 0x80 : 0x00)); + if (timerOutMode[1] == OutMode.Toggle) + val |= 0x04; + if (timerRunMode[1] == RunMode.Oneshot) + val |= 0x08; + switch (timerInMode[1]) + { + case InMode.CNT: + val |= 0x20; + break; + case InMode.TimerAUnderflow: + val |= 0x40; + break; + case InMode.TimerAUnderflowCNT: + val |= 0x60; + break; + } + break; + } + + return val; + } + + public bool ReadSPBuffer() + { + return pinSP; + } + + private int ReadTimerValue(int index) + { + if (timerOn[index]) + { + if (timer[index] == 0) + return timerLatch[index]; + else + return timer[index]; + } + else + { + return timer[index]; + } + } + + public void SyncState(Serializer ser) + { + SaveState.SyncObject(ser, this); + } + + public void Write(int addr, byte val) + { + Write(addr, val, 0xFF); + } + + public void Write(int addr, byte val, byte mask) + { + addr &= 0xF; + val &= mask; + val |= (byte)(ReadRegister(addr) & ~mask); + + switch (addr) + { + case 0x1: + WriteRegister(addr, val); + pinPC = false; + break; + case 0x5: + WriteRegister(addr, val); + if (!timerOn[0]) + timer[0] = timerLatch[0]; + break; + case 0x7: + WriteRegister(addr, val); + if (!timerOn[1]) + timer[1] = timerLatch[1]; + break; + case 0xE: + WriteRegister(addr, val); + if ((val & 0x10) != 0) + timer[0] = timerLatch[0]; + break; + case 0xF: + WriteRegister(addr, val); + if ((val & 0x10) != 0) + timer[1] = timerLatch[1]; + break; + default: + WriteRegister(addr, val); + break; + } + } + + public void WriteRegister(int addr, byte val) + { + bool intReg; + + switch (addr) + { + case 0x0: + portA.Latch = val; + break; + case 0x1: + portB.Latch = val; + break; + case 0x2: + portA.Direction = val; + break; + case 0x3: + portB.Direction = val; + break; + case 0x4: + timerLatch[0] &= 0xFF00; + timerLatch[0] |= val; + break; + case 0x5: + timerLatch[0] &= 0x00FF; + timerLatch[0] |= val << 8; + break; + case 0x6: + timerLatch[1] &= 0xFF00; + timerLatch[1] |= val; + break; + case 0x7: + timerLatch[1] &= 0x00FF; + timerLatch[1] |= val << 8; + break; + case 0x8: + if (alarmSelect) + todAlarm[0] = (byte)(val & 0xF); + else + tod[0] = (byte)(val & 0xF); + break; + case 0x9: + if (alarmSelect) + todAlarm[1] = (byte)(val & 0x7F); + else + tod[1] = (byte)(val & 0x7F); + break; + case 0xA: + if (alarmSelect) + todAlarm[2] = (byte)(val & 0x7F); + else + tod[2] = (byte)(val & 0x7F); + break; + case 0xB: + if (alarmSelect) + { + todAlarm[3] = (byte)(val & 0x1F); + todAlarmPM = ((val & 0x80) != 0); + } + else + { + tod[3] = (byte)(val & 0x1F); + todPM = ((val & 0x80) != 0); + } + break; + case 0xC: + sr = val; + break; + case 0xD: + intReg = ((val & 0x80) != 0); + if ((val & 0x01) != 0) + enableIntTimer[0] = intReg; + if ((val & 0x02) != 0) + enableIntTimer[1] = intReg; + if ((val & 0x04) != 0) + enableIntAlarm = intReg; + if ((val & 0x08) != 0) + enableIntSP = intReg; + if ((val & 0x10) != 0) + enableIntFlag = intReg; + break; + case 0xE: + if ((val & 0x01) != 0 && !timerOn[0]) + timerDelay[0] = 2; + timerOn[0] = ((val & 0x01) != 0); + timerPortEnable[0] = ((val & 0x02) != 0); + timerOutMode[0] = ((val & 0x04) != 0) ? OutMode.Toggle : OutMode.Pulse; + timerRunMode[0] = ((val & 0x08) != 0) ? RunMode.Oneshot : RunMode.Continuous; + timerInMode[0] = ((val & 0x20) != 0) ? InMode.CNT : InMode.Phase2; + timerSPMode = ((val & 0x40) != 0) ? SPMode.Output : SPMode.Input; + todIn = ((val & 0x80) != 0); + break; + case 0xF: + if ((val & 0x01) != 0 && !timerOn[1]) + timerDelay[1] = 2; + timerOn[1] = ((val & 0x01) != 0); + timerPortEnable[1] = ((val & 0x02) != 0); + timerOutMode[1] = ((val & 0x04) != 0) ? OutMode.Toggle : OutMode.Pulse; + timerRunMode[1] = ((val & 0x08) != 0) ? RunMode.Oneshot : RunMode.Continuous; + switch (val & 0x60) + { + case 0x00: timerInMode[1] = InMode.Phase2; break; + case 0x20: timerInMode[1] = InMode.CNT; break; + case 0x40: timerInMode[1] = InMode.TimerAUnderflow; break; + case 0x60: timerInMode[1] = InMode.TimerAUnderflowCNT; break; + } + alarmSelect = ((val & 0x80) != 0); + break; + } + } + + // ------------------------------------ + + public byte PortAMask = 0xFF; + public byte PortBMask = 0xFF; + + bool pinIRQ; + LatchedPort portA; + LatchedPort portB; + int[] timer; + int[] timerLatch; + bool[] timerOn; + bool[] underflow; + + public Func ReadPortA = (() => { return 0xFF; }); + public Func ReadPortB = (() => { return 0xFF; }); + + void HardResetInternal() + { + timer[0] = 0xFFFF; + timer[1] = 0xFFFF; + timerLatch[0] = timer[0]; + timerLatch[1] = timer[1]; + pinIRQ = true; + } + + public byte PortAData + { + get + { + return portA.ReadOutput(); + } + } + + public byte PortADirection + { + get + { + return portA.Direction; + } + } + + public byte PortALatch + { + get + { + return portA.Latch; + } + } + + public byte PortBData + { + get + { + return portB.ReadOutput(); + } + } + + public byte PortBDirection + { + get + { + return portB.Direction; + } + } + + public byte PortBLatch + { + get + { + return portB.Latch; + } + } + + public bool ReadIRQBuffer() { return pinIRQ; } + } } diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/MOS6581.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/MOS6581.cs index 9485937697..dc7e2e70dc 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/MOS6581.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/MOS6581.cs @@ -4119,7 +4119,7 @@ } }; - static public Sid Create(int newSampleRate, Region newRegion) + static public Sid Create(int newSampleRate, Common.DisplayType newRegion) { return new Sid(waveTable, newSampleRate, newRegion); } diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Sid.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Sid.cs index d74e8fc828..9a9f51fd47 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Sid.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Sid.cs @@ -42,7 +42,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS public Func ReadPotX; public Func ReadPotY; - public Sid(int[][] newWaveformTable, int newSampleRate, Region newRegion) + public Sid(int[][] newWaveformTable, int newSampleRate, Common.DisplayType newRegion) { uint cyclesPerSec = 0; uint cyclesNum; @@ -51,8 +51,8 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS switch (newRegion) { - case Region.NTSC: cyclesNum = 14318181; cyclesDen = 14; break; - case Region.PAL: cyclesNum = 17734472; cyclesDen = 18; break; + case Common.DisplayType.NTSC: cyclesNum = 14318181; cyclesDen = 14; break; + case Common.DisplayType.PAL: cyclesNum = 17734472; cyclesDen = 18; break; default: return; } diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Parse.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Parse.cs index f510f09159..ac5d441678 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Parse.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.Parse.cs @@ -145,8 +145,8 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS } else if (parseba == 0x1000) { - pinBA = !badline; - } + pinBA = !badline; + } else { parsecycleBAsprite0 = (parseba & 0x000F); diff --git a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.cs b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.cs index f58517536b..c1bbf6a699 100644 --- a/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.cs +++ b/BizHawk.Emulation.Cores/Computers/Commodore64/MOS/Vic.cs @@ -74,9 +74,9 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS lastRasterLine = rasterLine; } - // display enable compare - if (rasterLine == 0) - badlineEnable = false; + // display enable compare + if (rasterLine == 0) + badlineEnable = false; if (rasterLine == 0x030) badlineEnable |= displayEnable;