From f1dbf23bce41727e33cec5fbfde30f729102fde7 Mon Sep 17 00:00:00 2001
From: saxxonpike <saxxonpike@gmail.com>
Date: Fri, 9 Nov 2012 18:44:05 +0000
Subject: [PATCH] commodore64: implement keyboard matrix (input is not
 connected, planned)

---
 BizHawk.Emulation/BizHawk.Emulation.csproj    |  1 +
 .../Computers/Commodore64/C64.cs              |  2 -
 .../Computers/Commodore64/DataPort.cs         | 13 +--
 .../Computers/Commodore64/Input.cs            | 83 +++++++++++++++++++
 .../Computers/Commodore64/MemBus.cs           |  4 -
 5 files changed, 92 insertions(+), 11 deletions(-)
 create mode 100644 BizHawk.Emulation/Computers/Commodore64/Input.cs

diff --git a/BizHawk.Emulation/BizHawk.Emulation.csproj b/BizHawk.Emulation/BizHawk.Emulation.csproj
index dddf4adbe9..7b504ed1cd 100644
--- a/BizHawk.Emulation/BizHawk.Emulation.csproj
+++ b/BizHawk.Emulation/BizHawk.Emulation.csproj
@@ -86,6 +86,7 @@
     <Compile Include="Computers\Commodore64\Cia.cs" />
     <Compile Include="Computers\Commodore64\DataPort.cs" />
     <Compile Include="Computers\Commodore64\IMedia.cs" />
+    <Compile Include="Computers\Commodore64\Input.cs" />
     <Compile Include="Computers\Commodore64\PRGFile.cs" />
     <Compile Include="Computers\Commodore64\MemBus.cs" />
     <Compile Include="Computers\Commodore64\Sid.cs" />
diff --git a/BizHawk.Emulation/Computers/Commodore64/C64.cs b/BizHawk.Emulation/Computers/Commodore64/C64.cs
index 96e828dc85..6b875d7013 100644
--- a/BizHawk.Emulation/Computers/Commodore64/C64.cs
+++ b/BizHawk.Emulation/Computers/Commodore64/C64.cs
@@ -101,8 +101,6 @@ namespace BizHawk.Emulation.Computers.Commodore64
 
 			for (int i = 0; i < cyclesPerFrame; i++)
 			{
-				mem.cia0PortA.Data = cia0portAData;
-				mem.cia0PortB.Data = cia0portBData;
 				cpu.IRQ = signal.CpuIRQ;
 				cpu.NMI = signal.CpuNMI;
 				if (signal.CpuAEC)
diff --git a/BizHawk.Emulation/Computers/Commodore64/DataPort.cs b/BizHawk.Emulation/Computers/Commodore64/DataPort.cs
index 55bc750e19..d8545130ca 100644
--- a/BizHawk.Emulation/Computers/Commodore64/DataPort.cs
+++ b/BizHawk.Emulation/Computers/Commodore64/DataPort.cs
@@ -7,13 +7,16 @@ namespace BizHawk.Emulation.Computers.Commodore64
 {
 	public class DirectionalDataPort
 	{
-		private int _data;
+		protected byte _data;
 		public byte Direction;
+		public Action<byte> WritePort;
 
 		public DirectionalDataPort(byte initData, byte initDirection)
 		{
 			_data = initData;
 			Direction = initDirection;
+			WritePort = WritePortDummy;
+			WritePort(_data);
 		}
 
 		public byte Data
@@ -24,14 +27,14 @@ namespace BizHawk.Emulation.Computers.Commodore64
 			}
 			set
 			{
-				_data &= ~Direction;
-				_data |= (value & Direction);
+				_data &= (byte)~Direction;
+				_data |= (byte)(value & Direction);
+				WritePort(_data);
 			}
 		}
 
-		public void ForceSetData(byte newData)
+		private void WritePortDummy(byte val)
 		{
-			_data = newData;
 		}
 	}
 }
diff --git a/BizHawk.Emulation/Computers/Commodore64/Input.cs b/BizHawk.Emulation/Computers/Commodore64/Input.cs
new file mode 100644
index 0000000000..70159440c2
--- /dev/null
+++ b/BizHawk.Emulation/Computers/Commodore64/Input.cs
@@ -0,0 +1,83 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BizHawk.Emulation.Computers.Commodore64
+{
+	public class Input
+	{
+		static string[,] keyboardMatrix = new string[,]
+		{
+			{"Key Insert/Delete", "Key Return", "Key Cursor Left/Right", "Key F7", "Key F1", "Key F3", "Key F5", "Cursor Up/Down"},
+			{"Key 3", "Key W", "Key A", "Key 4", "Key Z", "Key S", "Key E", "Key Left Shift"},
+
+		};
+
+		static string[,] joystickMatrix = new string[,]
+		{
+			{"P1 Up", "P1 Down", "P1 Left", "P1 Right", "P1 Button"},
+			{"P2 Up", "P2 Down", "P2 Left", "P2 Right", "P2 Button"}
+		};
+
+		private IController controller;
+		private byte[] joystickLatch = new byte[2];
+		private byte keyboardColumnData;
+		private byte[] keyboardLatch = new byte[8];
+		private byte keyboardRowData;
+
+		public Input(IController newController, Cia newCia)
+		{
+			controller = newController;
+
+			// attach input to a CIA I/O port
+			newCia.ports[0].WritePort = WritePortA;
+			newCia.ports[1].WritePort = WritePortB;
+		}
+
+		private byte GetJoystickBits(int index)
+		{
+			byte result = 0xE0;
+			result |= controller[joystickMatrix[index, 0]] ? (byte)0x00 : (byte)0x01;
+			result |= controller[joystickMatrix[index, 1]] ? (byte)0x00 : (byte)0x02;
+			result |= controller[joystickMatrix[index, 2]] ? (byte)0x00 : (byte)0x04;
+			result |= controller[joystickMatrix[index, 3]] ? (byte)0x00 : (byte)0x08;
+			result |= controller[joystickMatrix[index, 4]] ? (byte)0x00 : (byte)0x10;
+			return result;
+		}
+
+		private byte GetKeyboardBits(int row)
+		{
+			byte result;
+			result = controller[keyboardMatrix[row, 0]] ? (byte)0x00 : (byte)0x01;
+			result |= controller[keyboardMatrix[row, 1]] ? (byte)0x00 : (byte)0x02;
+			result |= controller[keyboardMatrix[row, 2]] ? (byte)0x00 : (byte)0x04;
+			result |= controller[keyboardMatrix[row, 3]] ? (byte)0x00 : (byte)0x08;
+			result |= controller[keyboardMatrix[row, 4]] ? (byte)0x00 : (byte)0x10;
+			result |= controller[keyboardMatrix[row, 5]] ? (byte)0x00 : (byte)0x20;
+			result |= controller[keyboardMatrix[row, 6]] ? (byte)0x00 : (byte)0x40;
+			result |= controller[keyboardMatrix[row, 7]] ? (byte)0x00 : (byte)0x80;
+			return result;
+		}
+
+		public void Poll()
+		{
+			for (int i = 0; i < 2; i++)
+				joystickLatch[i] = GetJoystickBits(i);
+			for (int i = 0; i < 8; i++)
+				keyboardLatch[i] = GetKeyboardBits(i);
+		}
+
+		public void WritePortA(byte data)
+		{
+			// keyboard matrix column select
+			keyboardColumnData = data;
+		}
+
+		public void WritePortB(byte data)
+		{
+			// keyboard matrix row select
+			keyboardRowData = data;
+		}
+	}
+}
\ No newline at end of file
diff --git a/BizHawk.Emulation/Computers/Commodore64/MemBus.cs b/BizHawk.Emulation/Computers/Commodore64/MemBus.cs
index f84882b17e..3aa31643a1 100644
--- a/BizHawk.Emulation/Computers/Commodore64/MemBus.cs
+++ b/BizHawk.Emulation/Computers/Commodore64/MemBus.cs
@@ -62,8 +62,6 @@ namespace BizHawk.Emulation.Computers.Commodore64
 
 		// registers
 		public byte busData;
-		public DirectionalDataPort cia0PortA = new DirectionalDataPort(0xFF, 0x00);
-		public DirectionalDataPort cia0PortB = new DirectionalDataPort(0xFF, 0x00);
 		public DirectionalDataPort cia1PortA = new DirectionalDataPort(0x7F, 0x00);
 		public DirectionalDataPort cia1PortB = new DirectionalDataPort(0xFF, 0x00);
 		public DirectionalDataPort cpuPort;
@@ -98,8 +96,6 @@ namespace BizHawk.Emulation.Computers.Commodore64
 			sid = newSid;
 			cia0 = newCia0;
 			cia1 = newCia1;
-			cia0.ports[0] = cia0PortA;
-			cia0.ports[1] = cia0PortB;
 			cia1.ports[0] = cia1PortA;
 			cia1.ports[1] = cia1PortB;