# HG changeset patch # User Mike Pavone # Date 1355993099 28800 # Node ID 7a22a0e6c004bca9d7e351f86d79137316826ef4 # Parent aef6302770c2f4728207a7e20e0b5058a52b81da Gamepad support diff -r aef6302770c2 -r 7a22a0e6c004 blastem.h --- /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_ + diff -r aef6302770c2 -r 7a22a0e6c004 m68k_to_x86.c --- 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) diff -r aef6302770c2 -r 7a22a0e6c004 render_sdl.c --- 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 #include #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: diff -r aef6302770c2 -r 7a22a0e6c004 runtime.S --- 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