diff options
author | Mike Pavone <pavone@retrodev.com> | 2012-12-20 00:44:59 -0800 |
---|---|---|
committer | Mike Pavone <pavone@retrodev.com> | 2012-12-20 00:44:59 -0800 |
commit | 45779ee397097f3249eb1a1a858c0f0ac02d3bba (patch) | |
tree | 01ee26e3746603d1077ba05b295498c0bde02cee | |
parent | a8cc92ea4de90aed27a5163eabb46114f1e16e25 (diff) |
Gamepad support
-rw-r--r-- | blastem.h | 22 | ||||
-rw-r--r-- | m68k_to_x86.c | 1 | ||||
-rw-r--r-- | render_sdl.c | 113 | ||||
-rw-r--r-- | runtime.S | 40 |
4 files changed, 172 insertions, 4 deletions
diff --git a/blastem.h b/blastem.h new file mode 100644 index 0000000..e79c904 --- /dev/null +++ b/blastem.h @@ -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 --git a/m68k_to_x86.c b/m68k_to_x86.c index d566b3a..3a84079 100644 --- a/m68k_to_x86.c +++ b/m68k_to_x86.c @@ -906,6 +906,7 @@ uint8_t * translate_shift(uint8_t * dst, m68kinst * inst, x86_ea *src_op, x86_ea 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 --git a/render_sdl.c b/render_sdl.c index 4e0b01e..36c3241 100644 --- a/render_sdl.c +++ b/render_sdl.c @@ -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 @@ void render_wait_quit(vdp_context * context) } } +#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: @@ -25,6 +25,24 @@ do_vdp_port_read: 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 @@ m68k_write_byte: 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 @@ workram_wb: 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 @@ m68k_read_byte_scratch1: 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 |