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:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
121
Contralto/IO/Music.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,7 @@ namespace Contralto.Logging
|
||||
HostNetworkInterface = 0x2000,
|
||||
EthernetPacket = 0x4000,
|
||||
Configuration = 0x8000,
|
||||
Music = 0x10000,
|
||||
|
||||
Debug = 0x40000000,
|
||||
All = 0x7fffffff
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
126
Contralto/UI/Debugger.Designer.cs
generated
126
Contralto/UI/Debugger.Designer.cs
generated
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user