using Contralto.CPU; using Contralto.Logging; using Contralto.Memory; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Contralto.IO { /// /// Implements the Organ Keyboard interface used by the ST-74 /// Music System. Very little is known about the hardware at this time, /// so most of this is speculation or based on disassembly/reverse-engineering /// of the music system code. /// /// This is currently a stub that implements the bare minimum to make the /// music system think there's a keyboard attached to the system. /// public class OrganKeyboard : IMemoryMappedDevice { public OrganKeyboard(AltoSystem system) { _system = system; Reset(); } public void Reset() { // // Initialize keyboard registers. // Based on disassembly of the Nova code that drives the keyboard // interface, the top 6 bits are active low. // for (int i = 0; i < 16; i++) { _keyData[i] = (ushort)(0xfc00); } } /// /// Reads a word from the specified address. /// /// /// /// public ushort Read(int address, TaskType task, bool extendedMemory) { Log.Write(LogType.Verbose, LogComponent.Organ, "Organ read from {0} by task {1} (bank {2}), Nova PC {3}", Conversion.ToOctal(address), task, UCodeMemory.GetBank(task), Conversion.ToOctal(_system.CPU.R[6])); return _keyData[address - 0xfe60]; } /// /// Writes a word to the specified address. /// /// /// public void Load(int address, ushort data, TaskType task, bool extendedMemory) { // The registers are write-only as far as I've been able to ascertain. Log.Write(LogType.Verbose, LogComponent.Organ, "Unexpected organ write to {0} ({1}) by task {2} (bank {3})", Conversion.ToOctal(address), Conversion.ToOctal(data), task, UCodeMemory.GetBank(task)); } /// /// Specifies the range (or ranges) of addresses decoded by this device. /// public MemoryRange[] Addresses { get { return _addresses; } } /// /// From: http://bitsavers.org/pdf/xerox/alto/memos_1975/Reserved_Alto_Memory_Locations_Jan75.pdf /// /// #177140 - #177157: Organ Keyboard (Organ Hardware - Kaehler) /// private readonly MemoryRange[] _addresses = { new MemoryRange(0xfe60, 0xfe6f), }; private ushort[] _keyData = new ushort[16]; private AltoSystem _system; } }