1
0
mirror of https://github.com/livingcomputermuseum/ContrAlto.git synced 2026-02-22 15:18:06 +00:00

Initial pass at implementing Alto Music (Organ/DAC interfaces). Not currently functional. Fixed Nova diassembly to properly handle alto-specific instructions; fixed some annoyances with microcode disassembler.

This commit is contained in:
Josh Dersch
2016-05-12 18:31:22 -07:00
parent ddfe4f1940
commit 46d625586f
12 changed files with 345 additions and 152 deletions

View File

@@ -27,6 +27,7 @@ namespace Contralto
_displayController = new DisplayController(this);
_mouse = new Mouse();
_ethernetController = new EthernetController(this);
_musicInterface = new Music(this);
_cpu = new AltoCPU(this);
@@ -35,6 +36,7 @@ namespace Contralto
_memBus.AddDevice(_mem);
_memBus.AddDevice(_keyboard);
_memBus.AddDevice(_mouse);
_memBus.AddDevice(_musicInterface);
// Register devices that need clocks
_clockableDevices = new List<IClockable>();
@@ -58,6 +60,7 @@ namespace Contralto
_mouse.Reset();
_cpu.Reset();
_ethernetController.Reset();
_musicInterface.Reset();
UCodeMemory.Reset();
}
@@ -230,6 +233,7 @@ namespace Contralto
private DiskController _diskController;
private DisplayController _displayController;
private EthernetController _ethernetController;
private Music _musicInterface;
private Scheduler _scheduler;
private ulong _clocks;

View File

@@ -16,11 +16,7 @@ namespace Contralto.CPU.Nova
_altoIOTable = new Dictionary<ushort, string>();
_altoIOTable.Add(0x6210, "MUL");
_altoIOTable.Add(0x6211, "DIV");
_altoIOTable.Add(0x6000, "CYCLE");
_altoIOTable.Add(0x6900, "JSRII");
_altoIOTable.Add(0x6a00, "JSRIS");
_altoIOTable.Add(0x6e00, "CONVERT");
_altoIOTable.Add(0x6211, "DIV");
_altoIOTable.Add(0x6203, "RCLK");
_altoIOTable.Add(0x6204, "SIO");
_altoIOTable.Add(0x6205, "BLT");
@@ -61,8 +57,9 @@ namespace Contralto.CPU.Nova
disassembly = DisassembleLoadStore(address, instructionWord);
break;
case InstructionClass.IO:
disassembly = DisassembleIO(instructionWord);
case InstructionClass.AltoSpecific1:
case InstructionClass.AltoSpecific2:
disassembly = DisassembleAltoSpecific(address, instructionWord);
break;
default:
@@ -189,46 +186,50 @@ namespace Contralto.CPU.Nova
return d.ToString();
}
private static string DisassembleIO(ushort instructionWord)
private static string DisassembleAltoSpecific(ushort address, ushort instructionWord)
{
StringBuilder d = new StringBuilder();
//
// First see if this is an Alto-specific instruction; if so
// use those mnemonics. Otherwise decode as a Nova I/O instruction.
// Check for Alto-specific instructions that do not use the DISP field
//
if (_altoIOTable.ContainsKey(instructionWord))
{
return _altoIOTable[instructionWord];
}
// Accumulator
int ac = (instructionWord & 0x1800) >> 11;
// Transfer
IOTransfer trans = (IOTransfer)(instructionWord & 0x700);
// Control
IOControl cont = (IOControl)(instructionWord & 0xc0);
// Device code
int deviceCode = (instructionWord & 0x3f);
if (trans != IOTransfer.SKP)
{
d.AppendFormat("{0}{1} {2},{3}",
trans,
cont == IOControl.None ? String.Empty : cont.ToString(),
ac,
Conversion.ToOctal(deviceCode));
d.Append(_altoIOTable[instructionWord]);
}
else
{
d.AppendFormat("{0} {1}",
(IOSkip)cont,
Conversion.ToOctal(deviceCode));
}
//
// Check for Alto-specific instructions using the DISP field
int topBits = (instructionWord & 0xff00);
switch (topBits)
{
case 0x6000:
d.AppendFormat("CYCLE {0}", Conversion.ToOctal(instructionWord & 0xf));
break;
case 0x6900:
d.AppendFormat("JSRII {0} ;({1})",
Conversion.ToOctal((sbyte)(instructionWord & 0xff)),
Conversion.ToOctal(address + (sbyte)((instructionWord & 0xff))));
break;
case 0x6a00:
d.AppendFormat("JSRIS {0}", Conversion.ToOctal((sbyte)(instructionWord & 0xff)));
break;
case 0x6e00:
d.AppendFormat("CONVERT {0}", Conversion.ToOctal((sbyte)(instructionWord & 0xff)));
break;
default:
// Unimplemented, treated as a TRAP to either ROM or RAM.
d.Append("TRAP");
break;
}
}
return d.ToString();
}
@@ -286,7 +287,8 @@ namespace Contralto.CPU.Nova
MEM = 0x0000,
LDA = 0x2000,
STA = 0x4000,
IO = 0x6000,
AltoSpecific1 = 0x6000,
AltoSpecific2 = 0x7000,
}
private enum ALCFunctions
@@ -327,35 +329,7 @@ namespace Contralto.CPU.Nova
SNR = 0x5,
SEZ = 0x6,
SBN = 0x7,
}
private enum IOTransfer
{
NIO = 0x000,
DIA = 0x100,
DOA = 0x200,
DIB = 0x300,
DOB = 0x400,
DIC = 0x500,
DOC = 0x600,
SKP = 0x700,
}
private enum IOControl
{
None = 0x00,
S = 0x40,
C = 0x80,
P = 0xc0,
}
private enum IOSkip
{
SKPBN = 0x00,
SKPBZ = 0x40,
SKPDN = 0x80,
SKPDZ = 0xc0,
}
}
private enum MemFunction
{

View File

@@ -501,7 +501,7 @@ namespace Contralto.CPU
//
if (swMode)
{
// Log.Write(Logging.LogComponent.Microcode, "SWMODE: uPC {0}, next uPC {1} (NEXT is {2})", Conversion.ToOctal(_mpc), Conversion.ToOctal(instruction.NEXT | nextModifier), Conversion.ToOctal(instruction.NEXT));
//Log.Write(LogType.Verbose, LogComponent.Microcode, "SWMODE: uPC {0}, next uPC {1} (NEXT is {2})", Conversion.ToOctal(_mpc), Conversion.ToOctal(instruction.NEXT | nextModifier), Conversion.ToOctal(instruction.NEXT));
UCodeMemory.SwitchMode((ushort)(instruction.NEXT | nextModifier), _taskType);
}

View File

@@ -24,9 +24,8 @@ namespace Contralto.CPU
string source = string.Empty;
string operation = string.Empty;
string f1 = string.Empty;
string f2 = string.Empty;
string loadT = string.Empty;
string loadL = string.Empty;
string f2 = string.Empty;
string load = string.Empty;
// Select BUS data.
if (instruction.F1 != SpecialFunction1.Constant &&
@@ -36,7 +35,7 @@ namespace Contralto.CPU
switch (instruction.BS)
{
case BusSource.ReadR:
source = String.Format("R[{0}] ", Conversion.ToOctal((int)rSelect));
source = String.Format("$R{0} ", Conversion.ToOctal((int)rSelect));
break;
case BusSource.LoadR:
@@ -45,7 +44,7 @@ namespace Contralto.CPU
break;
case BusSource.None:
source = "177777(no source) ";
// nothing
break;
case BusSource.TaskSpecific1:
@@ -240,41 +239,61 @@ namespace Contralto.CPU
break;
}
loadT = String.Format("T<- {0}", loadTFromALU ? operation : source);
load = String.Format("T<- {0}", loadTFromALU ? operation : source);
}
// Load L (and M) from ALU
if (instruction.LoadL)
{
if (string.IsNullOrEmpty(loadT))
if (string.IsNullOrEmpty(load))
{
loadL = String.Format("L<- {0}", operation);
load = String.Format("L<- {0}", operation);
}
else
{
loadL = String.Format("L<- {0}", loadT);
load = String.Format("L<- {0}", load);
}
}
// Do writeback to selected R register from shifter output
if (loadR)
{
loadL = String.Format("R[{0}]<- {1}", Conversion.ToOctal((int)rSelect), loadL != String.Empty ? loadL : operation);
load = String.Format("$R{0}<- {1}",
Conversion.ToOctal((int)rSelect),
load != String.Empty ? load : operation);
}
// Do writeback to selected S register from M
if (loadS)
{
loadL = String.Format("S[{0}]<- {1}", Conversion.ToOctal((int)rSelect), loadL);
if (string.IsNullOrEmpty(load))
{
load = String.Format("$S{0}<- M",
Conversion.ToOctal((int)rSelect));
}
else
{
load = String.Format("$S{0}<- M, {1}",
Conversion.ToOctal((int)rSelect),
load);
}
}
if (!string.IsNullOrEmpty(loadL) || !string.IsNullOrEmpty(loadT))
if (!string.IsNullOrEmpty(load))
{
disassembly.AppendFormat("{0}{1}{2}{3} :{4}", f1, f2, loadT, loadL, Conversion.ToOctal(instruction.NEXT));
disassembly.AppendFormat("{0}{1}{2} :{3}",
f1,
f2,
load,
Conversion.ToOctal(instruction.NEXT));
}
else
{
disassembly.AppendFormat("{0}{1}{2} :{3}", f1, f2, operation, Conversion.ToOctal(instruction.NEXT));
disassembly.AppendFormat("{0}{1}{2} :{3}",
f1,
f2,
operation,
Conversion.ToOctal(instruction.NEXT));
}
@@ -326,7 +345,7 @@ namespace Contralto.CPU
{
case EmulatorBusSource.ReadSLocation:
loadS = false;
return String.Format("<-S[{0}]", Conversion.ToOctal((int)instruction.RSELECT));
return String.Format("$S{0}", Conversion.ToOctal((int)instruction.RSELECT));
case EmulatorBusSource.LoadSLocation:
loadS = true;

View File

@@ -118,6 +118,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="HighResTimer.cs" />
<Compile Include="IO\Music.cs" />
<Compile Include="IO\UDPEncapsulation.cs" />
<Compile Include="IO\IPacketEncapsulation.cs" />
<Compile Include="Properties\Resources.Designer.cs">

121
Contralto/IO/Music.cs Normal file
View File

@@ -0,0 +1,121 @@
using Contralto.CPU;
using Contralto.Logging;
using Contralto.Memory;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Contralto.IO
{
/// <summary>
/// Implements the hardware for Ted Kaehler's organ keyboard and DAC
/// </summary>
public class Music : IMemoryMappedDevice
{
public Music(AltoSystem system)
{
//_musicIo = new FileStream("c:\\alto\\mus.snd", FileMode.Create, FileAccess.ReadWrite);
_system = system;
Reset();
}
~Music()
{
//_musicIo.Close();
}
public void Reset()
{
_foo = true;
}
/// <summary>
/// Reads a word from the specified address.
/// </summary>
/// <param name="address"></param>
/// <param name="extendedMemory"></param>
/// <returns></returns>
public ushort Read(int address, TaskType task, bool extendedMemory)
{
// debug for kaehler's music st
Log.Write(LogType.Verbose, LogComponent.Music, "MUSIC (I/O) read from {0} by task {1} (bank {2}), Nova PC {3}",
Conversion.ToOctal(address),
task,
UCodeMemory.GetBank(task),
Conversion.ToOctal(_system.CPU.R[6]));
if (address == 0xfffe)
{
return _lastDac;
}
else
{
_foo = !_foo;
if (!_foo)
{
return 0x800;
}
else
{
return 0;
}
}
}
/// <summary>
/// Writes a word to the specified address.
/// </summary>
/// <param name="address"></param>
/// <param name="data"></param>
public void Load(int address, ushort data, TaskType task, bool extendedMemory)
{
Log.Write(LogType.Verbose, LogComponent.Music, "MUSIC (I/O) write to {0} ({1}) by task {2} (bank {3})",
Conversion.ToOctal(address),
Conversion.ToOctal(data),
task,
UCodeMemory.GetBank(task));
if (address == 0xfffe)
{
//_musicIo.WriteByte((byte)(data >> 8));
//_musicIo.WriteByte((byte)data);
_lastDac = data;
}
}
/// <summary>
/// Specifies the range (or ranges) of addresses decoded by this device.
/// </summary>
public MemoryRange[] Addresses
{
get { return _addresses; }
}
/// <summary>
/// From: http://bitsavers.org/pdf/xerox/alto/memos_1975/Reserved_Alto_Memory_Locations_Jan75.pdf
///
/// #177140 - #177157: Organ Keyboard (Organ Hardware - Kaehler)
/// #177776: Digital-Analog Converter (DAC Hardware - Kaehler)
/// </summary>
private readonly MemoryRange[] _addresses =
{
new MemoryRange(0xfe60, 0xfe6f), // Organ
new MemoryRange(0xfffe, 0xfffe) // DAC
};
private ushort _lastDac;
private AltoSystem _system;
private FileStream _musicIo;
private bool _foo;
}
}

View File

@@ -28,6 +28,7 @@ namespace Contralto.Logging
HostNetworkInterface = 0x2000,
EthernetPacket = 0x4000,
Configuration = 0x8000,
Music = 0x10000,
Debug = 0x40000000,
All = 0x7fffffff

View File

@@ -11,9 +11,9 @@ namespace Contralto.Memory
{
public MemoryRange(ushort start, ushort end)
{
if (!(end > start))
if (!(end >= start))
{
throw new ArgumentOutOfRangeException("end must be greater than start.");
throw new ArgumentOutOfRangeException("end must be greater than or equal to start.");
}
Start = start;

View File

@@ -55,11 +55,17 @@ namespace Contralto.Memory
}
else
{
/*
if (extendedMemory)
// debug for kaehler's music st
if (address == 0x1fe || address == 0x1ff) // music microcode
// || (address >= 0x7f00 && address <= 0x80ff)) // DAC buffer
{
Log.Write(LogComponent.Memory, "Extended memory read, bank {0} address {1}, read {2}", GetBankNumber(task, extendedMemory), Conversion.ToOctal(address), Conversion.ToOctal(_mem[address + 0x10000 * GetBankNumber(task, extendedMemory)]));
} */
System.Console.WriteLine("MUSIC read from {0} by task {1} in bank {2}.",
Conversion.ToOctal(address), task, UCodeMemory.GetBank(task));
}
*/
address += 0x10000 * GetBankNumber(task, extendedMemory);
return _mem[address];
}
@@ -79,12 +85,15 @@ namespace Contralto.Memory
else
{
/*
if (extendedMemory)
if (address == 0x1fe || address == 0x1ff || // music microcode
(address >= 0x7f00 && address <= 0x80ff)) // DAC buffer
{
Log.Write(LogComponent.Memory, "Extended memory write, bank {0} address {1}, data {2}", GetBankNumber(task, extendedMemory), Conversion.ToOctal(address), Conversion.ToOctal(data));
} */
address += 0x10000 * GetBankNumber(task, extendedMemory);
System.Console.WriteLine("MUSIC write to {0} ({1}) by task {2} in bank {3}.",
Conversion.ToOctal(address), Conversion.ToOctal(data), task, UCodeMemory.GetBank(task));
}
*/
address += 0x10000 * GetBankNumber(task, extendedMemory);
_mem[address] = data;
}
}

View File

@@ -1,6 +1,7 @@
using Contralto.CPU;
using System;
using System.Collections.Generic;
using System.IO;
namespace Contralto.Memory
{
@@ -21,9 +22,10 @@ namespace Contralto.Memory
public MemoryBus()
{
_bus = new Dictionary<ushort, IMemoryMappedDevice>(65536);
_systemType = Configuration.SystemType;
_systemType = Configuration.SystemType;
Reset();
}
}
public void AddDevice(IMemoryMappedDevice dev)
{
@@ -62,7 +64,7 @@ namespace Contralto.Memory
_doubleWordStore = false;
_doubleWordMixed = false;
_memoryOperationActive = false;
_extendedMemoryReference = false;
_extendedMemoryReference = false;
}
public ushort MAR
@@ -415,11 +417,11 @@ namespace Contralto.Memory
if (_bus.TryGetValue(address, out memoryMappedDevice))
{
return memoryMappedDevice.Read(address, task, extendedMemoryReference);
}
}
else
{
{
return 0;
}
}
}
}
@@ -445,7 +447,7 @@ namespace Contralto.Memory
if (_bus.TryGetValue(address, out memoryMappedDevice))
{
memoryMappedDevice.Load(address, data, task, extendedMemoryReference);
}
}
}
}

View File

@@ -89,10 +89,6 @@
this.MemoryJumpToAddress = new System.Windows.Forms.TextBox();
this.label3 = new System.Windows.Forms.Label();
this._memoryData = new System.Windows.Forms.DataGridView();
this.Bkpt = new System.Windows.Forms.DataGridViewCheckBoxColumn();
this.Address = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Data = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Disassembly = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.label1 = new System.Windows.Forms.Label();
this.ExecutionStateLabel = new System.Windows.Forms.Label();
this.ResetButton = new System.Windows.Forms.Button();
@@ -134,6 +130,12 @@
this.dataGridViewTextBoxColumn13 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.dataGridViewTextBoxColumn14 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.dataGridViewTextBoxColumn15 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.MemoryFindTextBox = new System.Windows.Forms.TextBox();
this.label4 = new System.Windows.Forms.Label();
this.Bkpt = new System.Windows.Forms.DataGridViewCheckBoxColumn();
this.Address = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Data = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Disassembly = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Microcode.SuspendLayout();
this.groupBox1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this._registerData)).BeginInit();
@@ -448,6 +450,8 @@
//
// groupBox4
//
this.groupBox4.Controls.Add(this.MemoryFindTextBox);
this.groupBox4.Controls.Add(this.label4);
this.groupBox4.Controls.Add(this.MemoryJumpToAddress);
this.groupBox4.Controls.Add(this.label3);
this.groupBox4.Controls.Add(this._memoryData);
@@ -519,49 +523,6 @@
this._memoryData.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.MemoryViewCellClick);
this._memoryData.CellValueNeeded += new System.Windows.Forms.DataGridViewCellValueEventHandler(this.OnMemoryCellValueNeeded);
//
// Bkpt
//
this.Bkpt.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.DisplayedCells;
this.Bkpt.FalseValue = "false";
this.Bkpt.HeaderText = "B";
this.Bkpt.Name = "Bkpt";
this.Bkpt.ReadOnly = true;
this.Bkpt.Resizable = System.Windows.Forms.DataGridViewTriState.False;
this.Bkpt.ToolTipText = "Breakpoint";
this.Bkpt.TrueValue = "true";
this.Bkpt.Width = 20;
//
// Address
//
this.Address.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.DisplayedCells;
this.Address.HeaderText = "Addr";
this.Address.MinimumWidth = 16;
this.Address.Name = "Address";
this.Address.ReadOnly = true;
this.Address.Resizable = System.Windows.Forms.DataGridViewTriState.False;
this.Address.ToolTipText = "Address";
this.Address.Width = 54;
//
// Data
//
this.Data.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.DisplayedCells;
this.Data.HeaderText = "Data";
this.Data.MinimumWidth = 16;
this.Data.Name = "Data";
this.Data.ReadOnly = true;
this.Data.Resizable = System.Windows.Forms.DataGridViewTriState.False;
this.Data.ToolTipText = "Data";
this.Data.Width = 55;
//
// Disassembly
//
this.Disassembly.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
this.Disassembly.HeaderText = "Disassembly";
this.Disassembly.Name = "Disassembly";
this.Disassembly.ReadOnly = true;
this.Disassembly.Resizable = System.Windows.Forms.DataGridViewTriState.False;
this.Disassembly.ToolTipText = "Disassembly";
//
// label1
//
this.label1.AutoSize = true;
@@ -1213,6 +1174,67 @@
this.dataGridViewTextBoxColumn15.Resizable = System.Windows.Forms.DataGridViewTriState.False;
this.dataGridViewTextBoxColumn15.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
//
// MemoryFindTextBox
//
this.MemoryFindTextBox.Location = new System.Drawing.Point(159, 294);
this.MemoryFindTextBox.Name = "MemoryFindTextBox";
this.MemoryFindTextBox.Size = new System.Drawing.Size(48, 20);
this.MemoryFindTextBox.TabIndex = 17;
this.MemoryFindTextBox.TabStop = false;
this.MemoryFindTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.OnMemoryFindKeyDown);
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(123, 297);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(30, 13);
this.label4.TabIndex = 16;
this.label4.Text = "Find:";
//
// Bkpt
//
this.Bkpt.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.DisplayedCells;
this.Bkpt.FalseValue = "false";
this.Bkpt.HeaderText = "B";
this.Bkpt.Name = "Bkpt";
this.Bkpt.ReadOnly = true;
this.Bkpt.Resizable = System.Windows.Forms.DataGridViewTriState.False;
this.Bkpt.ToolTipText = "Breakpoint";
this.Bkpt.TrueValue = "true";
this.Bkpt.Width = 20;
//
// Address
//
this.Address.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.DisplayedCellsExceptHeader;
this.Address.HeaderText = "Addr";
this.Address.MinimumWidth = 16;
this.Address.Name = "Address";
this.Address.ReadOnly = true;
this.Address.Resizable = System.Windows.Forms.DataGridViewTriState.False;
this.Address.ToolTipText = "Address";
this.Address.Width = 16;
//
// Data
//
this.Data.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.DisplayedCellsExceptHeader;
this.Data.HeaderText = "Data";
this.Data.MinimumWidth = 16;
this.Data.Name = "Data";
this.Data.ReadOnly = true;
this.Data.Resizable = System.Windows.Forms.DataGridViewTriState.False;
this.Data.ToolTipText = "Data";
this.Data.Width = 16;
//
// Disassembly
//
this.Disassembly.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
this.Disassembly.HeaderText = "Disassembly";
this.Disassembly.Name = "Disassembly";
this.Disassembly.ReadOnly = true;
this.Disassembly.Resizable = System.Windows.Forms.DataGridViewTriState.False;
this.Disassembly.ToolTipText = "Disassembly";
//
// Debugger
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@@ -1301,10 +1323,6 @@
private System.Windows.Forms.Button ResetButton;
private System.Windows.Forms.Button RunToNextTaskButton;
private System.Windows.Forms.Button NovaStep;
private System.Windows.Forms.DataGridViewCheckBoxColumn Bkpt;
private System.Windows.Forms.DataGridViewTextBoxColumn Address;
private System.Windows.Forms.DataGridViewTextBoxColumn Data;
private System.Windows.Forms.DataGridViewTextBoxColumn Disassembly;
private System.Windows.Forms.GroupBox groupBox6;
private System.Windows.Forms.DataGridView _reservedMemory;
private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn9;
@@ -1343,5 +1361,11 @@
private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn13;
private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn14;
private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn15;
private System.Windows.Forms.TextBox MemoryFindTextBox;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.DataGridViewCheckBoxColumn Bkpt;
private System.Windows.Forms.DataGridViewTextBoxColumn Address;
private System.Windows.Forms.DataGridViewTextBoxColumn Data;
private System.Windows.Forms.DataGridViewTextBoxColumn Disassembly;
}
}

View File

@@ -772,6 +772,39 @@ namespace Contralto
}
}
private void OnMemoryFindKeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Return ||
e.KeyCode == Keys.Enter)
{
try
{
UInt16 value = Convert.ToUInt16(MemoryFindTextBox.Text, 8);
// find the first address that contains this value
ushort address = 0;
if (_memoryData.SelectedRows.Count > 0)
{
// start at entry after selected line
address = (ushort)(_memoryData.SelectedRows[0].Index + 1);
}
for(int i=address;i<65536;i++)
{
if (_system.MemoryBus.DebugReadWord((ushort)i) == value)
{
HighlightNovaSourceLine((ushort)i);
break;
}
}
}
catch
{
// eh, just do nothing for now
}
}
}
private void OnStepButtonClicked(object sender, EventArgs e)
{
_execType = ExecutionType.Step;
@@ -891,13 +924,16 @@ namespace Contralto
// See if we need to stop here
if (_execAbort || // The Stop button was hit
_microcodeBreakpointEnabled[(int)UCodeMemory.GetBank(_system.CPU.CurrentTask.TaskType), _system.CPU.CurrentTask.MPC] || // A microcode breakpoint was hit
_microcodeBreakpointEnabled[
(int)UCodeMemory.GetBank(
_system.CPU.CurrentTask.TaskType),
_system.CPU.CurrentTask.MPC] || // A microcode breakpoint was hit
(_execType == ExecutionType.NextTask &&
_system.CPU.NextTask != null &&
_system.CPU.NextTask != _system.CPU.CurrentTask) || // The next task was switched to
(_system.CPU.CurrentTask.MPC == 0x10 && // MPC is 20(octal) meaning a new Nova instruction and...
(_novaBreakpointEnabled[_system.CPU.R[6]] || // A breakpoint is set here
_execType == ExecutionType.NextNovaInstruction))) // or we're running only a single Nova instruction.
_execType == ExecutionType.NextNovaInstruction))) // or we're running only a single Nova instruction.
{
// Stop here as we've hit a breakpoint or have been stopped
// Update UI to indicate where we stopped.
@@ -1411,6 +1447,8 @@ namespace Contralto
private bool[,] _microcodeBreakpointEnabled;
// Nova Debugger breakpoints; same as above
private bool[] _novaBreakpointEnabled;
private bool[] _novaBreakpointEnabled;
}
}