changeset 66:7a22a0e6c004

Gamepad support
author Mike Pavone <pavone@retrodev.com>
date Thu, 20 Dec 2012 00:44:59 -0800
parents aef6302770c2
children 534eb4976423
files blastem.h m68k_to_x86.c render_sdl.c runtime.S
diffstat 4 files changed, 172 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/blastem.h	Thu Dec 20 00:44:59 2012 -0800
@@ -0,0 +1,22 @@
+#ifndef BLASTEM_H_
+#define BLASTEM_H_
+
+typedef struct {
+	uint32_t th_counter;
+	uint32_t timeout_cycle;
+	uint8_t output;
+	uint8_t control;
+	uint8_t input[3];
+} io_port;
+
+#define GAMEPAD_TH0 0
+#define GAMEPAD_TH1 1
+#define GAMEPAD_EXTRA 2
+
+extern io_port gamepad_1;
+extern io_port gamepad_2;
+
+void io_adjust_cycles(io_port * pad, uint32_t current_cycle, uint32_t deduction);
+
+#endif //BLASTEM_H_
+
--- a/m68k_to_x86.c	Wed Dec 19 22:15:16 2012 -0800
+++ b/m68k_to_x86.c	Thu Dec 20 00:44:59 2012 -0800
@@ -906,6 +906,7 @@
 	if (inst->src.addr_mode == MODE_UNUSED) {
 		dst = m68k_save_result(inst, dst, opts);
 	}
+	return dst;
 }
 
 uint8_t * translate_m68k(uint8_t * dst, m68kinst * inst, x86_68k_options * opts)
--- a/render_sdl.c	Wed Dec 19 22:15:16 2012 -0800
+++ b/render_sdl.c	Thu Dec 20 00:44:59 2012 -0800
@@ -2,6 +2,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include "render.h"
+#include "blastem.h"
 
 SDL_Surface *screen;
 uint8_t render_dbg = 0;
@@ -160,28 +161,132 @@
 	}
 }
 
+#define DPAD_UP      0x01
+#define BUTTON_Z     0x01
+#define DPAD_DOWN    0x02
+#define BUTTON_Y     0x02
+#define DPAD_LEFT    0x04
+#define BUTTON_X     0x04
+#define DPAD_RIGHT   0x08
+#define BUTTON_MODE  0x08
+#define BUTTON_A     0x10
+#define BUTTON_B     0x10
+#define BUTTON_START 0x20
+#define BUTTON_C     0x20
+
 #define FRAME_DELAY 16
 #define MIN_DELAY 10
 uint32_t frame_counter = 0;
 uint32_t start = 0;
 void wait_render_frame(vdp_context * context)
 {
+	FILE * outfile;
 	SDL_Event event;
 	while(SDL_PollEvent(&event)) {
 		switch (event.type) {
 		case SDL_KEYDOWN:
-			//TODO: Update emulated gamepads
-			if (event.key.keysym.sym == SDLK_LEFTBRACKET) {
+			switch(event.key.keysym.sym)
+			{
+			case SDLK_LEFTBRACKET:
 				render_dbg++;
 				if (render_dbg == 3) {
 					render_dbg = 0;
 				}
-			} else if(event.key.keysym.sym == SDLK_t) {
-				FILE * outfile = fopen("state.gst", "wb");
+				break;
+			case SDLK_t:
+				outfile = fopen("state.gst", "wb");
 				fwrite("GST\0\0\0\xE0\x40", 1, 8, outfile);
 				vdp_save_state(context, outfile);
 				fclose(outfile);
 				puts("state saved to state.gst");
+				break;
+			case SDLK_RETURN:
+				gamepad_1.input[GAMEPAD_TH0] |= BUTTON_START;
+				break;
+			case SDLK_UP:
+				gamepad_1.input[GAMEPAD_TH0] |= DPAD_UP;
+				gamepad_1.input[GAMEPAD_TH1] |= DPAD_UP;
+				break;
+			case SDLK_DOWN:
+				gamepad_1.input[GAMEPAD_TH0] |= DPAD_DOWN;
+				gamepad_1.input[GAMEPAD_TH1] |= DPAD_DOWN;
+				break;
+			case SDLK_LEFT:
+				gamepad_1.input[GAMEPAD_TH1] |= DPAD_LEFT;
+				break;
+			case SDLK_RIGHT:
+				gamepad_1.input[GAMEPAD_TH1] |= DPAD_RIGHT;
+				break;
+			case SDLK_a:
+				gamepad_1.input[GAMEPAD_TH0] |= BUTTON_A;
+				//printf("BUTTON_A Dn | GAMEPAD_TH0: %X\n", gamepad_1.input[GAMEPAD_TH0]);
+				break;
+			case SDLK_s:
+				gamepad_1.input[GAMEPAD_TH1] |= BUTTON_B;
+				gamepad_1.input[GAMEPAD_EXTRA] |= BUTTON_B;
+				break;
+			case SDLK_d:
+				gamepad_1.input[GAMEPAD_TH1] |= BUTTON_C;
+				gamepad_1.input[GAMEPAD_EXTRA] |= BUTTON_C;
+				break;
+			case SDLK_q:
+				gamepad_1.input[GAMEPAD_EXTRA] |= BUTTON_X;
+				break;
+			case SDLK_w:
+				gamepad_1.input[GAMEPAD_EXTRA] |= BUTTON_Y;
+				break;
+			case SDLK_e:
+				gamepad_1.input[GAMEPAD_EXTRA] |= BUTTON_Z;
+				break;
+			case SDLK_f:
+				gamepad_1.input[GAMEPAD_EXTRA] |= BUTTON_MODE;
+				break;
+			}
+			break;
+		case SDL_KEYUP:
+			switch(event.key.keysym.sym)
+			{
+			case SDLK_RETURN:
+				gamepad_1.input[GAMEPAD_TH0] &= ~BUTTON_START;
+				break;
+			case SDLK_UP:
+				gamepad_1.input[GAMEPAD_TH0] &= ~DPAD_UP;
+				gamepad_1.input[GAMEPAD_TH1] &= ~DPAD_UP;
+				break;
+			case SDLK_DOWN:
+				gamepad_1.input[GAMEPAD_TH0] &= ~DPAD_DOWN;
+				gamepad_1.input[GAMEPAD_TH1] &= ~DPAD_DOWN;
+				break;
+			case SDLK_LEFT:
+				gamepad_1.input[GAMEPAD_TH1] &= ~DPAD_LEFT;
+				break;
+			case SDLK_RIGHT:
+				gamepad_1.input[GAMEPAD_TH1] &= ~DPAD_RIGHT;
+				break;
+			case SDLK_a:
+				gamepad_1.input[GAMEPAD_TH0] &= ~BUTTON_A;
+				//printf("BUTTON_A Up | GAMEPAD_TH0: %X\n", gamepad_1.input[GAMEPAD_TH0]);
+				break;
+			case SDLK_s:
+				gamepad_1.input[GAMEPAD_TH1] &= ~BUTTON_B;
+				gamepad_1.input[GAMEPAD_EXTRA] &= ~BUTTON_B;
+				break;
+			case SDLK_d:
+				gamepad_1.input[GAMEPAD_TH1] &= ~BUTTON_C;
+				gamepad_1.input[GAMEPAD_EXTRA] &= ~BUTTON_C;
+				break;
+			case SDLK_q:
+				gamepad_1.input[GAMEPAD_EXTRA] &= ~BUTTON_X;
+				break;
+			case SDLK_w:
+				gamepad_1.input[GAMEPAD_EXTRA] &= ~BUTTON_Y;
+				break;
+			case SDLK_e:
+				gamepad_1.input[GAMEPAD_EXTRA] &= ~BUTTON_Z;
+				break;
+			case SDLK_f:
+				gamepad_1.input[GAMEPAD_EXTRA] &= ~BUTTON_MODE;
+				break;
 			}
 			break;
 		case SDL_QUIT:
--- a/runtime.S	Wed Dec 19 22:15:16 2012 -0800
+++ b/runtime.S	Thu Dec 20 00:44:59 2012 -0800
@@ -25,6 +25,24 @@
 	mov 120(%rsi), %cx
 	ret
 	
+do_io_write:
+	call m68k_save_context
+	and $0xFF, %edi
+	mov %rcx, %rdx
+	call io_write
+	mov %rax, %rsi
+	call m68k_load_context
+	ret
+do_io_read:
+	mov %ecx, %edi
+	and $0xFF, %edi
+	call m68k_save_context
+	call io_read
+	mov %rax, %rsi
+	call m68k_load_context
+	mov 120(%rsi), %cl
+	ret
+	
 bad_access_msg:
 	.asciz "Program tried to access illegal 68K address %X\n"
 	
@@ -100,6 +118,14 @@
 	jle cart_wb
 	cmp $0xE00000, %edi
 	jge workram_wb
+	cmp $0xC00000, %edi
+	jge vdp_psg_wb
+	cmp $0xA10000, %edi
+	jl not_io_wb
+	cmp $0xA10100, %edi
+	jge not_io_wb
+	jmp do_io_write
+not_io_wb:
 	ret
 workram_wb:
 	and $0xFFFF, %rdi
@@ -108,6 +134,14 @@
 cart_wb:
 	mov %cl, (%r8, %rdi)
 	ret
+vdp_psg_wb:
+	push %rdx
+	mov %cl, %dl
+	and $0xFF, %cx
+	shl $8, %dx
+	or %dx, %cx
+	pop %rdx
+	jmp vdp_psg_w
 
 	.global m68k_write_long_lowfirst
 m68k_write_long_lowfirst:
@@ -192,6 +226,12 @@
 	jle cart_b
 	cmp $0xE00000, %ecx
 	jge workram_b
+	cmp $0xA10000, %ecx
+	jl not_io_b
+	cmp $0xA10100, %ecx
+	jge not_io_b
+	jmp do_io_read
+not_io_b:
 	xor %cl, %cl
 	dec %cl
 	ret