changeset 1028:56b1748a8473

Initial stab at Saturn keyboard support
author Michael Pavone <pavone@retrodev.com>
date Wed, 11 May 2016 01:15:54 -0700
parents 276cd582b728
children 4263dc9cf86d
files io.c io.h render_sdl.c stateview.c
diffstat 4 files changed, 140 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/io.c	Tue May 10 21:26:27 2016 -0700
+++ b/io.c	Wed May 11 01:15:54 2016 -0700
@@ -258,18 +258,18 @@
 
 void store_key_event(uint16_t code)
 {
-	if (keyboard_port) {
+	if (keyboard_port && keyboard_port->device.keyboard.write_pos != keyboard_port->device.keyboard.read_pos) {
+		//there's room in the buffer, record this event
+		keyboard_port->device.keyboard.events[keyboard_port->device.keyboard.write_pos] = code;
+		if (keyboard_port->device.keyboard.read_pos == 0xFF) {
+			//ring buffer was empty, update read_pos to indicate there is now data
+			keyboard_port->device.keyboard.read_pos = keyboard_port->device.keyboard.write_pos;
+		}
 		keyboard_port->device.keyboard.write_pos = (keyboard_port->device.keyboard.write_pos + 1) & 7;
-		if (keyboard_port->device.keyboard.write_pos == keyboard_port->device.keyboard.read_pos) {
-			//we've wrapped around to the read position, drop this event
-			keyboard_port->device.keyboard.write_pos = (keyboard_port->device.keyboard.write_pos - 1) & 7;
-			return;
-		}
-		keyboard_port->device.keyboard.events[keyboard_port->device.keyboard.write_pos] = code;
 	}
 }
 
-void handle_keydown(int keycode, char scancode)
+void handle_keydown(int keycode, uint8_t scancode)
 {
 	int bucket = keycode >> 15 & 0xFFFF;
 	if (!bindings[bucket]) {
@@ -404,7 +404,7 @@
 	}
 }
 
-void handle_keyup(int keycode, char scancode)
+void handle_keyup(int keycode, uint8_t scancode)
 {
 	int bucket = keycode >> 15 & 0xFFFF;
 	if (!bindings[bucket]) {
@@ -681,6 +681,10 @@
 		port->device.mouse.latched_y = 0;
 		port->device.mouse.ready_cycle = CYCLE_NEVER;
 		port->device.mouse.tr_counter = 0;
+	} else if(!strcmp(device_type, "saturn keyboard")) {
+		port->device_type = IO_SATURN_KEYBOARD;
+		port->device.keyboard.read_pos = 0xFF;
+		port->device.keyboard.write_pos = 0;
 	} else if(!strcmp(device_type, "sega_parallel")) {
 		port->device_type = IO_SEGA_PARALLEL;
 		port->device.stream.data_fd = -1;
@@ -1281,6 +1285,24 @@
 			}
 		}
 		break;
+	case IO_SATURN_KEYBOARD:
+		if (output & TH) {
+			//request is over
+			if (port->device.keyboard.tr_counter >= 10 && port->device.keyboard.read_pos != 0xFF) {
+				//remove scan code from buffer
+				port->device.keyboard.read_pos++;
+				port->device.keyboard.read_pos &= 7;
+				if (port->device.keyboard.read_pos == port->device.keyboard.write_pos) {
+					port->device.keyboard.read_pos = 0xFF;
+				}
+			}
+			port->device.keyboard.tr_counter = 0;
+		} else {
+			if ((output & TR) != (old_output & TR)) {
+				port->device.keyboard.tr_counter++;
+			}
+		}
+		break;
 #ifndef _WIN32
 	case IO_GENERIC:
 		wait_for_connection(port);
@@ -1397,6 +1419,78 @@
 		}
 		break;
 	}
+	case IO_SATURN_KEYBOARD:
+	{
+		if (th) {
+			input = 0x11;
+		} else {
+			uint8_t tr = output & TR;
+			uint16_t code = port->device.keyboard.read_pos == 0xFF ? 0 
+				: port->device.keyboard.events[port->device.keyboard.read_pos];
+			switch (port->device.keyboard.tr_counter)
+			{
+			case 0:
+				input = 1;
+				break;
+			case 1:
+				//Saturn peripheral ID
+				input = 3;
+				break;
+			case 2:
+				//data size
+				input = 4;
+				break;
+			case 3:
+				//d-pad
+				//TODO: set these based on keyboard state
+				input = 0xF;
+				break;
+			case 4:
+				//Start ABC
+				//TODO: set these based on keyboard state
+				input = 0xF;
+				break;
+			case 5:
+				//R XYZ
+				//TODO: set these based on keyboard state
+				input = 0xF;
+				break;
+			case 6:
+				//L and KBID
+				//TODO: set L based on keyboard state
+				input = 0x8;
+				break;
+			case 7:
+				//Capslock, Numlock, Scrolllock
+				//TODO: set these based on keyboard state
+				input = 0;
+				break;
+			case 8:
+				input = 6;
+				if (code & 0x100) {
+					//break
+					input |= 1;
+				} else if (code) {
+					input |= 8;
+				}
+				break;
+			case 9:
+				input = code >> 4 & 0xF;
+				break;
+			case 10:
+				input = code & 0xF;
+				break;
+			case 11:
+				input = 0;
+				break;
+			default:
+				input = 1;
+				break;
+			}
+			input |= ((port->device.keyboard.tr_counter & 1) == 0) << 4;
+		}
+		break;
+	}
 #ifndef _WIN32
 	case IO_SEGA_PARALLEL:
 		if (!th)
--- a/io.h	Tue May 10 21:26:27 2016 -0700
+++ b/io.h	Wed May 11 01:15:54 2016 -0700
@@ -50,6 +50,7 @@
 			uint16_t events[8];
 			uint8_t  read_pos;
 			uint8_t  write_pos;
+			uint8_t  tr_counter;
 		} keyboard;
 	} device;
 	uint8_t  output;
@@ -82,8 +83,8 @@
 void io_adjust_cycles(io_port * pad, uint32_t current_cycle, uint32_t deduction);
 void io_data_write(io_port * pad, uint8_t value, uint32_t current_cycle);
 uint8_t io_data_read(io_port * pad, uint32_t current_cycle);
-void handle_keydown(int keycode, char scancode);
-void handle_keyup(int keycode, char scancode);
+void handle_keydown(int keycode, uint8_t scancode);
+void handle_keyup(int keycode, uint8_t scancode);
 void handle_joydown(int joystick, int button);
 void handle_joyup(int joystick, int button);
 void handle_joy_dpad(int joystick, int dpad, uint8_t state);
--- a/render_sdl.c	Tue May 10 21:26:27 2016 -0700
+++ b/render_sdl.c	Wed May 11 01:15:54 2016 -0700
@@ -592,7 +592,38 @@
 	[SDL_SCANCODE_9] = 0x46,
 	[SDL_SCANCODE_0] = 0x45,
 	[SDL_SCANCODE_RETURN] = 0x5A,
-	[SDL_SCANCODE_SPACE] = 0x29
+	[SDL_SCANCODE_ESCAPE] = 0x76,
+	[SDL_SCANCODE_SPACE] = 0x29,
+	[SDL_SCANCODE_TAB] = 0x0D,
+	[SDL_SCANCODE_BACKSPACE] = 0x66,
+	[SDL_SCANCODE_F1] = 0x05,
+    [SDL_SCANCODE_F2] = 0x06,
+    [SDL_SCANCODE_F3] = 0x04,
+    [SDL_SCANCODE_F4] = 0x0C,
+    [SDL_SCANCODE_F5] = 0x03,
+    [SDL_SCANCODE_F6] = 0x0B,
+    [SDL_SCANCODE_F7] = 0x83,
+    [SDL_SCANCODE_F8] = 0x0A,
+    [SDL_SCANCODE_F9] = 0x01,
+    [SDL_SCANCODE_F10] = 0x09,
+    [SDL_SCANCODE_F11] = 0x78,
+    [SDL_SCANCODE_F12] = 0x07,
+	[SDL_SCANCODE_LCTRL] = 0x14,
+    [SDL_SCANCODE_LSHIFT] = 0x12,
+    [SDL_SCANCODE_LALT] = 0x11,
+	[SDL_SCANCODE_RSHIFT] = 0x59,
+	[SDL_SCANCODE_INSERT] = 0x81,
+	[SDL_SCANCODE_PAUSE] = 0x82,
+	[SDL_SCANCODE_PRINTSCREEN] = 0x84,
+	[SDL_SCANCODE_DELETE] = 0x85,
+	[SDL_SCANCODE_LEFT] = 0x86,
+	[SDL_SCANCODE_HOME] = 0x87,
+	[SDL_SCANCODE_END] = 0x88,
+	[SDL_SCANCODE_UP] = 0x89,
+	[SDL_SCANCODE_DOWN] = 0x8A,
+	[SDL_SCANCODE_PAGEUP] = 0x8B,
+	[SDL_SCANCODE_PAGEDOWN] = 0x8C,
+	[SDL_SCANCODE_RIGHT] = 0x8D
 };
 
 int32_t handle_event(SDL_Event *event)
--- a/stateview.c	Tue May 10 21:26:27 2016 -0700
+++ b/stateview.c	Wed May 11 01:15:54 2016 -0700
@@ -50,11 +50,11 @@
 {
 }
 
-void handle_keydown(int keycode)
+void handle_keydown(int keycode, uint8_t scancode)
 {
 }
 
-void handle_keyup(int keycode)
+void handle_keyup(int keycode, uint8_t scancode)
 {
 }