Skip to content

Commit

Permalink
Initial stab at keyboard beeper.
Browse files Browse the repository at this point in the history
  • Loading branch information
livingcomputermuseum committed May 25, 2019
1 parent 1c24c46 commit e1a2b54
Show file tree
Hide file tree
Showing 9 changed files with 163 additions and 50 deletions.
1 change: 1 addition & 0 deletions D/Darkstar.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@
<Compile Include="Display\DisplayController.cs" />
<Compile Include="Ethernet\HostEthernet.cs" />
<Compile Include="Ethernet\IPacketInterface.cs" />
<Compile Include="IOP\Tone.cs" />
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
Expand Down
45 changes: 3 additions & 42 deletions D/Ethernet/EthernetController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public void HostInterfaceChanged()
public int EtherDisp()
{
//
// Pin 139(YIODisp.1) : Hooked to "Attn," which appear to be whether any attention is needed by the receiver
// Pin 139(YIODisp.1) : Hooked to "Attn," which indicates whether any attention is needed by the receiver
// or transmitter.
// Pin 39(YIODisp.0) : "(schematic) Must be zero for the transmitting inner loop uCode. It is also used to
// determine if the Option card is plugged in."
Expand Down Expand Up @@ -343,8 +343,8 @@ public ushort EIData(int cycle)
//
if (_fifo.Count > 0)
{
//ss
// if cycle == 2 we dequeue the next item from the FIFO;
//
// If cycle == 2 we dequeue the next item from the FIFO;
// otherwise the last-dequeued item is returned.
// (See OPT schematic, sheet 6:
// "<-EIData not in Cycle2 is rereading EIData in the case
Expand All @@ -359,8 +359,6 @@ public ushort EIData(int cycle)

if (Log.Enabled) Log.Write(LogComponent.EthernetReceive, " <-EIData: Returning FIFO word 0x{0:x4}. FIFO count is now {1}",
value, _fifo.Count);

_debugPacket.Add(value);
}
else
{
Expand Down Expand Up @@ -389,41 +387,6 @@ public ushort EIData(int cycle)
_rxEvenLen = _loopBack || _localLoop ? true : _evenPacketLength;

if (Log.Enabled) Log.Write(LogComponent.EthernetReceive, " <-EIData: completing transfer.");

if (Log.Enabled)
{
StringBuilder sb = new StringBuilder();
int byteNum = 0;
StringBuilder dataLine = new StringBuilder();
StringBuilder asciiLine = new StringBuilder();
dataLine.AppendFormat("000: ");

for (int i = 0; i < _debugPacket.Count; i++)
{
dataLine.AppendFormat("{0:x2} {1:x2}", (_debugPacket[i] >> 8), _debugPacket[i] & 0xff);
asciiLine.Append(GetPrintableChar((byte)(_debugPacket[i] >> 8)));
asciiLine.Append(GetPrintableChar((byte)_debugPacket[i]));

byteNum++;
if ((byteNum % 16) == 0)
{
Log.Write(LogComponent.EthernetPacket, "{0} {1}", dataLine.ToString(), asciiLine.ToString());
dataLine.Clear();
asciiLine.Clear();
dataLine.AppendFormat("{0:x3}: ", i + 1);
byteNum = 0;
}
}

if (byteNum > 0)
{
Log.Write(LogComponent.EthernetPacket, "{0} {1}", dataLine.ToString(), asciiLine.ToString());
}

Log.Write(LogComponent.EthernetPacket, "");
}

_debugPacket.Clear();
}

UpdateWakeup();
Expand Down Expand Up @@ -1019,7 +982,5 @@ private enum ReceiverState
//
private IPacketInterface _hostInterface;
private Queue<ushort> _outputPacket;

private List<ushort> _debugPacket = new List<ushort>();
}
}
4 changes: 2 additions & 2 deletions D/IO/FloppyDrive.cs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ private void IndexCallback(ulong skewNsec, object context)
if (DriveSelect && IsLoaded && !_index)
{
// Raise the index signal, hold for a short period.
_index = true;
_index = true;
_system.Scheduler.Schedule(_indexDuration, IndexCallback);

if (Log.Enabled) Log.Write(LogComponent.IOPFloppy, "Disk rotation complete, raising INDEX signal for 10us.");
Expand All @@ -179,7 +179,7 @@ private void IndexCallback(ulong skewNsec, object context)

// Index signal and timing
private bool _index;
private ulong _indexInterval = 250 * Conversion.MsecToNsec; // 1/5 second at 300rpm
private ulong _indexInterval = 250 * Conversion.MsecToNsec; // 1/5 second at 300rpm - we slow this down just a bit.
private ulong _indexDuration = 10 * Conversion.UsecToNsec; // 10uSec duration for index signal.
}
}
9 changes: 8 additions & 1 deletion D/IOP/IOProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public IOProcessor(DSystem system)
_floppyController = new FloppyController(_floppyDrive, _system);
_dma = new DMAController(this);
_tty = new Printer();
_tone = new Tone();

//
// Register DMA devices with controller
Expand All @@ -65,7 +66,7 @@ public IOProcessor(DSystem system)
_io.RegisterDevice(_floppyController);
_io.RegisterDevice(_dma);
_io.RegisterDevice(_system.CP);
//_io.RegisterDevice(_tty);
_io.RegisterDevice(_tty);

Reset();
}
Expand Down Expand Up @@ -142,6 +143,11 @@ public Printer Printer
get { return _tty; }
}

public Tone Tone
{
get { return _tone; }
}

private i8085 _cpu;
private IOPIOBus _io;
private I8085MemoryBus _mem;
Expand All @@ -155,6 +161,7 @@ public Printer Printer
private Keyboard _keyboard;
private Mouse _mouse;
private Printer _tty;
private Tone _tone;
private DSystem _system;

//
Expand Down
29 changes: 29 additions & 0 deletions D/IOP/MiscIO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,24 @@ public void WritePort(int port, byte value)
{
switch (port)
{
case 0x8d:
// i8253 Timer channel #1 - used to set the Keyboard bell (tone) frequency.
// This is a 16-bit value loaded one byte at a time, LSB first.
// Send the word off to the tone generator.
_iop.Tone.LoadInterval(value);
break;

case 0x8f:
// i8253 Timer Mode.
// This is used to control the timer used for the Keyboard bell
// and for the USART. It specifies which timer will be active,
// how that timer's interval is loaded, and what the output waveform
// looks like.
// At this time there's no particular reason to pay attention to what
// gets written here, as we don't actually emulate the i8253.
if (Log.Enabled) Log.Write(LogComponent.IOPMisc, "Misc IO port Timer Mode written {0:x2}", value);
break;

case 0xd0:
//
// DMA Test Register
Expand Down Expand Up @@ -160,6 +178,15 @@ public void WritePort(int port, byte value)
if (Log.Enabled) Log.Write(LogComponent.IOPMisc, "Misc IO Keyboard data clock.");
}

if ((value & 0x20) != 0)
{
_iop.Tone.EnableTone();
}
else
{
_iop.Tone.DisableTone();
}

if ((value & 0x10) != 0)
{
_iop.Keyboard.EnableDiagnosticMode();
Expand Down Expand Up @@ -401,6 +428,8 @@ private void DoMiscClock(byte clockFlags)

private readonly int[] _writePorts = new int[]
{
0x8d, // i8253 Timer Control 1 (Tone frequency)
0x8f, // i8253 Timer Mode
0xd0, // DMA Test Register
0xe9, // KB, MP, TOD clocks (write)
0xea, // Clear TOD interrupt (write)
Expand Down
91 changes: 91 additions & 0 deletions D/IOP/Tone.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
using D.Logging;
using SDL2;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace D.IOP
{
/// <summary>
/// Implements the tone generator used to generate simple beeps.
/// This is driven by an i8253 programmable interval timer.
/// </summary>
public class Tone
{
public Tone()
{
Reset();
}

public void Reset()
{
_lsb = 0;
_loadLSB = true;
_frequency = 0.0;
_enabled = false;
_sampleOn = false;
_periodInSamples = 0;
}

public void LoadInterval(byte value)
{
if (_loadLSB)
{
_lsb = value;
}
else
{
//;Frequency constant (1843.2/f, f in kHz)
_frequency = ((value << 8) | value) / 1.8432;
if (Log.Enabled) Log.Write(LogComponent.Tone, "Tone frequency set to {0}", _frequency);
_periodInSamples = (44100.0 / _frequency) / 2;
}

_loadLSB = false;
}

public void EnableTone()
{
if (Log.Enabled) Log.Write(LogComponent.Tone, "Tone enabled.", _frequency);
_enabled = true;
}

public void DisableTone()
{
// if (Log.Enabled) Log.Write(LogComponent.Tone, "Tone disabled.", _frequency);
_enabled = false;
}

public void AudioCallback(IntPtr userData, IntPtr stream, int length)
{
byte[] samples = new byte[length];

for (int i = 0; i < length; i++)
{
_position++;

if (_position > _periodInSamples)
{
_position -= _periodInSamples;
_sampleOn = !_sampleOn;
}

samples[i] = (byte)(_enabled ? (_sampleOn ? 0xff : 0x00) : 0x00);
}

// Marshal.Copy(samples, 0, stream, length);
}

private bool _loadLSB;
private byte _lsb;

private double _frequency;
private bool _enabled;
private double _position;
private double _periodInSamples;
private bool _sampleOn;
}
}
9 changes: 6 additions & 3 deletions D/Logging/Log.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ public enum LogComponent
EthernetReceive = 0x8000000,
EthernetPacket = 0x10000000,

// Keyboard tone
Tone = 0x20000000,

// Configuration
Configuration = 0x40000000,

Expand Down Expand Up @@ -108,9 +111,9 @@ public static class Log
{
static Log()
{
Enabled = false;
_components = LogComponent.None;
_type = LogType.None;
Enabled = true;
_components = LogComponent.Tone | LogComponent.IOPPrinter;
_type = LogType.All;
_logIndex = 0;
}

Expand Down
2 changes: 1 addition & 1 deletion D/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ static void Main(string[] args)

// Cons up a system to run stuff on.
DSystem system = new DSystem();
system.Reset();
system.Reset();

//
// Start the UI, this will not return from ShowDialog
Expand Down
23 changes: 22 additions & 1 deletion D/UI/DWindow-IO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE


using D.IOP;
using D.Logging;
using SDL2;
using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -974,7 +975,7 @@ private void InitializeSDL()
int retVal;

// Get SDL humming
if ((retVal = SDL.SDL_Init(SDL.SDL_INIT_VIDEO)) < 0)
if ((retVal = SDL.SDL_Init(SDL.SDL_INIT_EVERYTHING)) < 0)
{
throw new InvalidOperationException(String.Format("SDL_Init failed. Error {0:x}", retVal));
}
Expand Down Expand Up @@ -1028,6 +1029,26 @@ private void InitializeSDL()
_renderEventType = SDL.SDL_RegisterEvents(1);
_renderEvent = new SDL.SDL_Event();
_renderEvent.type = (SDL.SDL_EventType)_renderEventType;



SDL.SDL_AudioSpec desired = new SDL.SDL_AudioSpec();
SDL.SDL_AudioSpec obtained = new SDL.SDL_AudioSpec();

desired.freq = 44100;
desired.format = SDL.AUDIO_U8;
desired.channels = 1;
desired.callback = _system.IOP.Tone.AudioCallback;
desired.samples = 1;

uint deviceId = SDL.SDL_OpenAudioDevice(null, 0, ref desired, out obtained, 0);


SDL.SDL_PauseAudioDevice(deviceId, 0);

if (Log.Enabled) Log.Write(LogComponent.Tone, "SDL Audio initialized, device id {0}", deviceId);


}

private void CreateDisplayTexture(bool filter)
Expand Down

0 comments on commit e1a2b54

Please sign in to comment.