Skip to content

Commit

Permalink
Revert "Revert "Started PSG emulator""
Browse files Browse the repository at this point in the history
This reverts commit 59033eb.
  • Loading branch information
rehsd committed Apr 30, 2022
1 parent 59033eb commit 253082b
Show file tree
Hide file tree
Showing 5 changed files with 241 additions and 4 deletions.
3 changes: 3 additions & 0 deletions Emulator_65816/GlobalSuppressions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@
[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>", Scope = "member", Target = "~M:Emul816or.mainForm.GetROM")]
[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>", Scope = "member", Target = "~M:Emul816or.mainForm.ReloadForm")]
[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>", Scope = "member", Target = "~M:Emul816or.LCD1602.#ctor(System.Windows.Forms.GroupBox)")]
[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>", Scope = "member", Target = "~M:Emul816or.PSG.Play")]
[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>", Scope = "member", Target = "~M:Emul816or.PSG.PlayTone(System.Int32,System.Int32)")]
[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>", Scope = "member", Target = "~M:Emul816or.PSG.PlayTone(System.Object)")]
158 changes: 158 additions & 0 deletions Emulator_65816/PSG.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
//represents a PSG: AY-3-8910 or YM2149
//register data: https://f.rdw.se/AY-3-8910-datasheet.pdf
//BC1 and BDIR coming from one VIA port
//Data on the other VIA port
//Starting with basic tones, only writing to PSGs. Reading from PSG I/O not supported.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace Emul816or
{
public class PSG
{
const uint size = 16;
const uint baseAddress = 0x100000;
private bool supports16bit = true;
//private bool bdir;
//private bool bc1;
//assuming bc2 is tied high
private byte currentRegister; //0x00-0x0F
//private byte incomingData; //hold incoming data prior to receiving appropriate bus control signals
//private byte outgoingData; //hold outgoing data prior to receiving appropriate bus control signals
private byte tempData;

byte[] RegisterValues;
Thread thread_PSG1_ChA;

public enum REGISTERS
{
Reg0_ChA_TonePeriod_Fine,
Reg1_ChA_TonePeriod_Course,
Reg2_ChB_TonePeriod_Fine,
Reg3_ChB_TonePeriod_Course,
Reg4_ChC_TonePeriod_Fine,
Reg5_ChC_TonePeriod_Course,
Reg6_NoisePeriod,
Reg7_EnableB,
Reg8_ChA_Amplitude,
Reg9_ChB_Amplitude,
RegA_ChC_Amplitude,
RegB_EnvelopePeriod_Fine,
RegC_EnvelopePeriod_Course,
RegD_EnvelopeShapeCycle,
RegE_IO_PortA_Data,
RegF_IO_PortB_Data
}
public uint Size
{
get => size;
}
public uint BaseAddress
{
get => baseAddress;
}
public void SetBusControl(bool BDIR, bool BC1)
{
//this.bdir = BDIR;
//this.bc1 = BC1;

//setreg = NACT -> writeValue -> INTAK -> NACT
//readdata = NACT -> changeDDRtoRead(00) -> writeZero -> DTB -> changeDDRtoWrite(FF) -> NACT
//writedata = NACT -> writeValue -> DWS -> NACT
if (!BDIR && !BC1) //inactive (NACT)
{
tempData = 0;
}
else if (!BDIR && BC1) //read (DTB)
{
//readdata
//not supported yet
tempData= RegisterValues[currentRegister];
}
else if (BDIR && !BC1) //write (DWS)
{
//writedata
RegisterValues[currentRegister] = tempData;
Play();
}
else if (BDIR && BC1) //latch (INTAK)
{
//setreg
if (tempData >= 0 && tempData <= 15)
{
currentRegister = tempData;
}
}
}
public Byte Value
{
get
{
return tempData;
}
set
{
tempData = value;
}
}
public bool Supports16Bit
{
get => supports16bit;
}

public PSG()
{
RegisterValues = new byte[16];
RegisterValues[(byte)PSG.REGISTERS.Reg0_ChA_TonePeriod_Fine] = 0;
RegisterValues[(byte)PSG.REGISTERS.Reg1_ChA_TonePeriod_Course] = 0;
RegisterValues[(byte)PSG.REGISTERS.Reg2_ChB_TonePeriod_Fine] = 0;
RegisterValues[(byte)PSG.REGISTERS.Reg3_ChB_TonePeriod_Course] = 0;
RegisterValues[(byte)PSG.REGISTERS.Reg4_ChC_TonePeriod_Fine] = 0;
RegisterValues[(byte)PSG.REGISTERS.Reg5_ChC_TonePeriod_Course] = 0;
RegisterValues[(byte)PSG.REGISTERS.Reg6_NoisePeriod] = 0; //not implementing yet
RegisterValues[(byte)PSG.REGISTERS.Reg7_EnableB] = 0b11111111; //turn off noise and tone
RegisterValues[(byte)PSG.REGISTERS.Reg8_ChA_Amplitude] = 15; //max volume
RegisterValues[(byte)PSG.REGISTERS.Reg9_ChB_Amplitude] = 15; //max volume
RegisterValues[(byte)PSG.REGISTERS.RegA_ChC_Amplitude] = 15; //max volume
RegisterValues[(byte)PSG.REGISTERS.RegB_EnvelopePeriod_Fine] = 0; //not implementing yet
RegisterValues[(byte)PSG.REGISTERS.RegC_EnvelopePeriod_Course] = 0; //not implementing yet
RegisterValues[(byte)PSG.REGISTERS.RegD_EnvelopeShapeCycle] = 0; //not implementing yet
RegisterValues[(byte)PSG.REGISTERS.RegE_IO_PortA_Data] = 0; //not implementing yet
RegisterValues[(byte)PSG.REGISTERS.RegF_IO_PortB_Data] = 0; //not implementing yet
}

private void Play()
{
//read all registers and update sound output of PSG
bool chAenable = !(Convert.ToBoolean(RegisterValues[(int)REGISTERS.Reg7_EnableB] & (byte)0x00000001));
if (chAenable)
{
int frequency = RegisterValues[(int)REGISTERS.Reg1_ChA_TonePeriod_Course];
//TO DO - Frequency calc based on Course and Fine
PSG p = new PSG();
thread_PSG1_ChA = new Thread(PSG.PlayTone);
thread_PSG1_ChA.Start(1000); //frequency
}
else
{
//turn off sound
if(thread_PSG1_ChA != null)
{
thread_PSG1_ChA.Interrupt();
}
}
}

public static void PlayTone(object data)
{
UInt16 i = (UInt16)((int)data & 0b0111111111111111);
//testing with Beep for now
//need to find a better way to play a tone, as multiple, simultaneous tones will be needed
Console.Beep(i,int.MaxValue-1);
}
}
}
4 changes: 3 additions & 1 deletion Emulator_65816/Sound.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System;
//represents dual-port SRAM used on my sound card
//primary 65816 systems submits commands/data to the sound card through the dual-port SRAM
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
Expand Down
26 changes: 23 additions & 3 deletions Emulator_65816/mainForm.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 54 additions & 0 deletions Emulator_65816/mainForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1314,5 +1314,59 @@ private void viewDebugLabelsToolStripMenuItem_Click(object sender, EventArgs e)
DebugLabelViewer frm = new DebugLabelViewer(debugLabels);
frm.Show();
}

private void testPSGToolStripMenuItem_Click(object sender, EventArgs e)
{
//setreg = NACT -> writeValue -> INTAK -> NACT
//readdata = NACT -> changeDDRtoRead(00) -> writeZero -> DTB -> changeDDRtoWrite(FF) -> NACT
//writedata = NACT -> writeValue -> DWS -> NACT

//bdir = 0, bc1 = 0 inactive (NACT)
//bdir = 0, bc1 = 1 read (DTB)
//bdir = 1, bc1 = 0 write (DWS)
//bdir = 1, bc1 = 1 latch (INTAK)

PSG p = new PSG();

//start a tone
p.SetBusControl(false, false); //NACT
p.Value = (byte)PSG.REGISTERS.Reg1_ChA_TonePeriod_Course; //writeValue
p.SetBusControl(true, true); //INTAK
p.SetBusControl(false, false); //NACT

p.SetBusControl(false, false); //NACT
p.Value = 7; //writeValue Course (0-15)
p.SetBusControl(true, false); //DWS
p.SetBusControl(false, false); //NACT

p.SetBusControl(false, false); //NACT
p.Value = (byte)PSG.REGISTERS.Reg0_ChA_TonePeriod_Fine; //writeValue
p.SetBusControl(true, true); //INTAK
p.SetBusControl(false, false); //NACT

p.SetBusControl(false, false); //NACT
p.Value = 127; //writeValue Fine (0-255)
p.SetBusControl(true, false); //DWS
p.SetBusControl(false, false); //NACT

p.SetBusControl(false, false); //NACT
p.Value = (byte)PSG.REGISTERS.Reg7_EnableB; //writeValue
p.SetBusControl(true, true); //INTAK
p.SetBusControl(false, false); //NACT

p.SetBusControl(false, false); //NACT
p.Value = 0b11111110; //writeValue //IO_B (1=write,0=read PSG IO Port), IO_A, Noise_C, Noise_B, Noise_A, Tone_C, Tone_B, Tone_A
p.SetBusControl(true, false); //DWS
p.SetBusControl(false, false); //NACT

System.Threading.Thread.Sleep(2000); //hold the tone

//register is still set to EnableB
p.SetBusControl(false, false); //NACT
p.Value = 0b11111111; //writeValue //IO_B (1=write,0=read PSG IO Port), IO_A, Noise_C, Noise_B, Noise_A, Tone_C, Tone_B, Tone_A
p.SetBusControl(true, false); //DWS
p.SetBusControl(false, false); //NACT

}
}
}

0 comments on commit 253082b

Please sign in to comment.