# HG changeset patch # User Mike Pavone # Date 1372213239 25200 # Node ID d0cacb4ade0be6ad79934cc06e1caf5187a7bb36 # Parent 9fb111b5641f2b69cddedd65bee21f722cffd9ef Move IO code to a separate file and do a tiny bit of refactoring diff -r 9fb111b5641f -r d0cacb4ade0b blastem.c --- a/blastem.c Mon Jun 24 21:32:25 2013 -0700 +++ b/blastem.c Tue Jun 25 19:20:39 2013 -0700 @@ -22,7 +22,6 @@ #define MCLKS_PER_PSG (MCLKS_PER_Z80*16) //TODO: Figure out the exact value for this -#define CYCLE_NEVER 0xFFFFFFFF #define LINES_NTSC 262 #define LINES_PAL 312 @@ -32,9 +31,6 @@ uint16_t ram[RAM_WORDS]; uint8_t z80_ram[Z80_RAM_BYTES]; -io_port gamepad_1; -io_port gamepad_2; - int headless = 0; int z80_enabled = 1; int frame_limit = 0; @@ -230,8 +226,9 @@ frame++; mclks -= mclks_per_frame; vdp_adjust_cycles(v_context, mclks_per_frame); - io_adjust_cycles(&gamepad_1, context->current_cycle, mclks_per_frame/MCLKS_PER_68K); - io_adjust_cycles(&gamepad_2, context->current_cycle, mclks_per_frame/MCLKS_PER_68K); + io_adjust_cycles(gen->ports, context->current_cycle, mclks_per_frame/MCLKS_PER_68K); + io_adjust_cycles(gen->ports+1, context->current_cycle, mclks_per_frame/MCLKS_PER_68K); + io_adjust_cycles(gen->ports+2, context->current_cycle, mclks_per_frame/MCLKS_PER_68K); if (busack_cycle != CYCLE_NEVER) { if (busack_cycle > mclks_per_frame/MCLKS_PER_68K) { busack_cycle -= mclks_per_frame/MCLKS_PER_68K; @@ -288,8 +285,10 @@ wait_render_frame(v_context, frame_limit); } vdp_adjust_cycles(v_context, mclks_per_frame); - io_adjust_cycles(&gamepad_1, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K); - io_adjust_cycles(&gamepad_2, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K); + genesis_context * gen = context->system; + io_adjust_cycles(gen->ports, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K); + io_adjust_cycles(gen->ports+1, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K); + io_adjust_cycles(gen->ports+2, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K); if (busack_cycle != CYCLE_NEVER) { if (busack_cycle > mclks_per_frame/MCLKS_PER_68K) { busack_cycle -= mclks_per_frame/MCLKS_PER_68K; @@ -313,8 +312,10 @@ wait_render_frame(v_context, frame_limit); } vdp_adjust_cycles(v_context, mclks_per_frame); - io_adjust_cycles(&gamepad_1, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K); - io_adjust_cycles(&gamepad_2, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K); + genesis_context * gen = context->system; + io_adjust_cycles(gen->ports, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K); + io_adjust_cycles(gen->ports+1, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K); + io_adjust_cycles(gen->ports+2, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K); if (busack_cycle != CYCLE_NEVER) { if (busack_cycle > mclks_per_frame/MCLKS_PER_68K) { busack_cycle -= mclks_per_frame/MCLKS_PER_68K; @@ -421,76 +422,6 @@ } } -#define TH 0x40 -#define TH_TIMEOUT 8000 - -void io_adjust_cycles(io_port * pad, uint32_t current_cycle, uint32_t deduction) -{ - /*uint8_t control = pad->control | 0x80; - uint8_t th = control & pad->output; - if (pad->input[GAMEPAD_TH0] || pad->input[GAMEPAD_TH1]) { - printf("adjust_cycles | control: %X, TH: %X, GAMEPAD_TH0: %X, GAMEPAD_TH1: %X, TH Counter: %d, Timeout: %d, Cycle: %d\n", control, th, pad->input[GAMEPAD_TH0], pad->input[GAMEPAD_TH1], pad->th_counter,pad->timeout_cycle, current_cycle); - }*/ - if (current_cycle >= pad->timeout_cycle) { - pad->th_counter = 0; - } else { - pad->timeout_cycle -= deduction; - } - if (busack_cycle < CYCLE_NEVER && current_cycle < busack_cycle) { - busack_cycle -= deduction; - } -} - -void io_data_write(io_port * pad, m68k_context * context, uint8_t value) -{ - if (pad->control & TH) { - //check if TH has changed - if ((pad->output & TH) ^ (value & TH)) { - if (context->current_cycle >= pad->timeout_cycle) { - pad->th_counter = 0; - } - if (!(value & TH)) { - pad->th_counter++; - } - pad->timeout_cycle = context->current_cycle + TH_TIMEOUT; - } - } - pad->output = value; -} - -uint8_t io_data_read(io_port * pad, m68k_context * context) -{ - uint8_t control = pad->control | 0x80; - uint8_t th = control & pad->output; - uint8_t input; - if (context->current_cycle >= pad->timeout_cycle) { - pad->th_counter = 0; - } - /*if (pad->input[GAMEPAD_TH0] || pad->input[GAMEPAD_TH1]) { - printf("io_data_read | control: %X, TH: %X, GAMEPAD_TH0: %X, GAMEPAD_TH1: %X, TH Counter: %d, Timeout: %d, Cycle: %d\n", control, th, pad->input[GAMEPAD_TH0], pad->input[GAMEPAD_TH1], pad->th_counter,pad->timeout_cycle, context->current_cycle); - }*/ - if (th) { - if (pad->th_counter == 3) { - input = pad->input[GAMEPAD_EXTRA]; - } else { - input = pad->input[GAMEPAD_TH1]; - } - } else { - if (pad->th_counter == 3) { - input = pad->input[GAMEPAD_TH0] | 0xF; - } else if(pad->th_counter == 4) { - input = pad->input[GAMEPAD_TH0] & 0x30; - } else { - input = pad->input[GAMEPAD_TH0] | 0xC; - } - } - uint8_t value = ((~input) & (~control)) | (pad->output & control); - /*if (pad->input[GAMEPAD_TH0] || pad->input[GAMEPAD_TH1]) { - printf ("value: %X\n", value); - }*/ - return value; -} - uint32_t zram_counter = 0; #define Z80_ACK_DELAY 3 #define Z80_BUSY_DELAY 1//TODO: Find the actual value for this @@ -538,18 +469,22 @@ switch(location/2) { case 0x1: - io_data_write(&gamepad_1, context, value); + io_data_write(gen->ports, value, context->current_cycle); break; case 0x2: - io_data_write(&gamepad_2, context, value); + io_data_write(gen->ports+1, value, context->current_cycle); break; - case 0x3://PORT C Data + case 0x3: + io_data_write(gen->ports+2, value, context->current_cycle); break; case 0x4: - gamepad_1.control = value; + gen->ports[0].control = value; break; case 0x5: - gamepad_2.control = value; + gen->ports[1].control = value; + break; + case 0x6: + gen->ports[2].control = value; break; } } else { @@ -655,21 +590,22 @@ value = version_reg; break; case 0x1: - value = io_data_read(&gamepad_1, context); + value = io_data_read(gen->ports, context->current_cycle); break; case 0x2: - value = io_data_read(&gamepad_2, context); + value = io_data_read(gen->ports+1, context->current_cycle); break; - case 0x3://PORT C Data + case 0x3: + value = io_data_read(gen->ports+2, context->current_cycle); break; case 0x4: - value = gamepad_1.control; + value = gen->ports[0].control; break; case 0x5: - value = gamepad_2.control; + value = gen->ports[1].control; break; - case 0x6://PORT C control - value = 0; + case 0x6: + value = gen->ports[2].control; break; default: value = 0xFF; @@ -846,302 +782,6 @@ return context; } -enum { - BIND_NONE, - BIND_GAMEPAD1, - BIND_GAMEPAD2, - BIND_UI -}; - -typedef enum { - UI_DEBUG_MODE_INC, - UI_DEBUG_PAL_INC, - UI_ENTER_DEBUGGER -} ui_action; - -typedef struct { - uint8_t bind_type; - uint8_t subtype_a; - uint8_t subtype_b; - uint8_t value; -} keybinding; - -typedef struct { - keybinding bindings[4]; - uint8_t state; -} joydpad; - -keybinding * bindings[256]; -keybinding * joybindings[MAX_JOYSTICKS]; -joydpad * joydpads[MAX_JOYSTICKS]; -const uint8_t dpadbits[] = {RENDER_DPAD_UP, RENDER_DPAD_DOWN, RENDER_DPAD_LEFT, RENDER_DPAD_RIGHT}; - -void bind_key(int keycode, uint8_t bind_type, uint8_t subtype_a, uint8_t subtype_b, uint8_t value) -{ - int bucket = keycode >> 8 & 0xFF; - if (!bindings[bucket]) { - bindings[bucket] = malloc(sizeof(keybinding) * 256); - memset(bindings[bucket], 0, sizeof(keybinding) * 256); - } - int idx = keycode & 0xFF; - bindings[bucket][idx].bind_type = bind_type; - bindings[bucket][idx].subtype_a = subtype_a; - bindings[bucket][idx].subtype_b = subtype_b; - bindings[bucket][idx].value = value; -} - -void bind_button(int joystick, int button, uint8_t bind_type, uint8_t subtype_a, uint8_t subtype_b, uint8_t value) -{ - if (joystick >= MAX_JOYSTICKS) { - return; - } - if (!joybindings[joystick]) { - int num = render_joystick_num_buttons(joystick); - if (!num) { - return; - } - joybindings[joystick] = malloc(sizeof(keybinding)*num); - memset(joybindings[joystick], 0, sizeof(keybinding)*num); - } - joybindings[joystick][button].bind_type = bind_type; - joybindings[joystick][button].subtype_a = subtype_a; - joybindings[joystick][button].subtype_b = subtype_b; - joybindings[joystick][button].value = value; -} - -void bind_dpad(int joystick, int dpad, int direction, uint8_t bind_type, uint8_t subtype_a, uint8_t subtype_b, uint8_t value) -{ - if (joystick >= MAX_JOYSTICKS) { - return; - } - if (!joydpads[joystick]) { - int num = render_joystick_num_hats(joystick); - if (!num) { - return; - } - joydpads[joystick] = malloc(sizeof(joydpad)*num); - memset(joydpads[joystick], 0, sizeof(joydpad)*num); - } - for (int i = 0; i < 4; i ++) { - if (dpadbits[i] & direction) { - joydpads[joystick][dpad].bindings[i].bind_type = bind_type; - joydpads[joystick][dpad].bindings[i].subtype_a = subtype_a; - joydpads[joystick][dpad].bindings[i].subtype_b = subtype_b; - joydpads[joystick][dpad].bindings[i].value = value; - break; - } - } -} - -#define GAMEPAD_BUTTON(PRI_SLOT, SEC_SLOT, VALUE) (PRI_SLOT << 12 | SEC_SLOT << 8 | VALUE) - -#define DPAD_UP GAMEPAD_BUTTON(GAMEPAD_TH0, GAMEPAD_TH1, 0x01) -#define BUTTON_Z GAMEPAD_BUTTON(GAMEPAD_EXTRA, GAMEPAD_NONE, 0x01) -#define DPAD_DOWN GAMEPAD_BUTTON(GAMEPAD_TH0, GAMEPAD_TH1, 0x02) -#define BUTTON_Y GAMEPAD_BUTTON(GAMEPAD_EXTRA, GAMEPAD_NONE, 0x02) -#define DPAD_LEFT GAMEPAD_BUTTON(GAMEPAD_TH1, GAMEPAD_NONE, 0x04) -#define BUTTON_X GAMEPAD_BUTTON(GAMEPAD_EXTRA, GAMEPAD_NONE, 0x04) -#define DPAD_RIGHT GAMEPAD_BUTTON(GAMEPAD_TH1, GAMEPAD_NONE, 0x08) -#define BUTTON_MODE GAMEPAD_BUTTON(GAMEPAD_EXTRA, GAMEPAD_NONE, 0x08) -#define BUTTON_A GAMEPAD_BUTTON(GAMEPAD_TH0, GAMEPAD_NONE, 0x10) -#define BUTTON_B GAMEPAD_BUTTON(GAMEPAD_TH1, GAMEPAD_NONE, 0x10) -#define BUTTON_START GAMEPAD_BUTTON(GAMEPAD_TH0, GAMEPAD_NONE, 0x20) -#define BUTTON_C GAMEPAD_BUTTON(GAMEPAD_TH1, GAMEPAD_NONE, 0x20) - -void bind_gamepad(int keycode, int gamepadnum, int button) -{ - - if (gamepadnum < 1 || gamepadnum > 2) { - return; - } - uint8_t bind_type = gamepadnum - 1 + BIND_GAMEPAD1; - bind_key(keycode, bind_type, button >> 12, button >> 8 & 0xF, button & 0xFF); -} - -void bind_button_gamepad(int joystick, int joybutton, int gamepadnum, int padbutton) -{ - if (gamepadnum < 1 || gamepadnum > 2) { - return; - } - uint8_t bind_type = gamepadnum - 1 + BIND_GAMEPAD1; - bind_button(joystick, joybutton, bind_type, padbutton >> 12, padbutton >> 8 & 0xF, padbutton & 0xFF); -} - -void bind_dpad_gamepad(int joystick, int dpad, uint8_t direction, int gamepadnum, int button) -{ - if (gamepadnum < 1 || gamepadnum > 2) { - return; - } - uint8_t bind_type = gamepadnum - 1 + BIND_GAMEPAD1; - bind_dpad(joystick, dpad, direction, bind_type, button >> 12, button >> 8 & 0xF, button & 0xFF); -} - -void bind_ui(int keycode, ui_action action) -{ - bind_key(keycode, BIND_UI, action, 0, 0); -} - -void handle_binding_down(keybinding * binding) -{ - switch(binding->bind_type) - { - case BIND_GAMEPAD1: - if (binding->subtype_a <= GAMEPAD_EXTRA) { - gamepad_1.input[binding->subtype_a] |= binding->value; - } - if (binding->subtype_b <= GAMEPAD_EXTRA) { - gamepad_1.input[binding->subtype_b] |= binding->value; - } - break; - case BIND_GAMEPAD2: - if (binding->subtype_a <= GAMEPAD_EXTRA) { - gamepad_2.input[binding->subtype_a] |= binding->value; - } - if (binding->subtype_b <= GAMEPAD_EXTRA) { - gamepad_2.input[binding->subtype_b] |= binding->value; - } - break; - } -} - -void handle_keydown(int keycode) -{ - int bucket = keycode >> 8 & 0xFF; - if (!bindings[bucket]) { - return; - } - int idx = keycode & 0xFF; - keybinding * binding = bindings[bucket] + idx; - handle_binding_down(binding); -} - -void handle_joydown(int joystick, int button) -{ - if (!joybindings[joystick]) { - return; - } - keybinding * binding = joybindings[joystick] + button; - handle_binding_down(binding); -} - -uint8_t ui_debug_mode = 0; -uint8_t ui_debug_pal = 0; - -void handle_binding_up(keybinding * binding) -{ - switch(binding->bind_type) - { - case BIND_GAMEPAD1: - if (binding->subtype_a <= GAMEPAD_EXTRA) { - gamepad_1.input[binding->subtype_a] &= ~binding->value; - } - if (binding->subtype_b <= GAMEPAD_EXTRA) { - gamepad_1.input[binding->subtype_b] &= ~binding->value; - } - break; - case BIND_GAMEPAD2: - if (binding->subtype_a <= GAMEPAD_EXTRA) { - gamepad_2.input[binding->subtype_a] &= ~binding->value; - } - if (binding->subtype_b <= GAMEPAD_EXTRA) { - gamepad_2.input[binding->subtype_b] &= ~binding->value; - } - break; - case BIND_UI: - switch (binding->subtype_a) - { - case UI_DEBUG_MODE_INC: - ui_debug_mode++; - if (ui_debug_mode == 4) { - ui_debug_mode = 0; - } - render_debug_mode(ui_debug_mode); - break; - case UI_DEBUG_PAL_INC: - ui_debug_pal++; - if (ui_debug_pal == 4) { - ui_debug_pal = 0; - } - render_debug_pal(ui_debug_pal); - break; - case UI_ENTER_DEBUGGER: - break_on_sync = 1; - break; - } - break; - } -} - -void handle_keyup(int keycode) -{ - int bucket = keycode >> 8 & 0xFF; - if (!bindings[bucket]) { - return; - } - int idx = keycode & 0xFF; - keybinding * binding = bindings[bucket] + idx; - handle_binding_up(binding); -} - -void handle_joyup(int joystick, int button) -{ - if (!joybindings[joystick]) { - return; - } - keybinding * binding = joybindings[joystick] + button; - handle_binding_up(binding); -} - -void handle_joy_dpad(int joystick, int dpadnum, uint8_t value) -{ - if (!joydpads[joystick]) { - return; - } - joydpad * dpad = joydpads[joystick] + dpadnum; - uint8_t newdown = (value ^ dpad->state) & value; - uint8_t newup = ((~value) ^ (~dpad->state)) & (~value); - dpad->state = value; - for (int i = 0; i < 4; i++) { - if (newdown & dpadbits[i]) { - handle_binding_down(dpad->bindings + i); - } else if(newup & dpadbits[i]) { - handle_binding_up(dpad->bindings + i); - } - } -} - -void set_keybindings() -{ - bind_gamepad(RENDERKEY_UP, 1, DPAD_UP); - bind_gamepad(RENDERKEY_DOWN, 1, DPAD_DOWN); - bind_gamepad(RENDERKEY_LEFT, 1, DPAD_LEFT); - bind_gamepad(RENDERKEY_RIGHT, 1, DPAD_RIGHT); - bind_gamepad('a', 1, BUTTON_A); - bind_gamepad('s', 1, BUTTON_B); - bind_gamepad('d', 1, BUTTON_C); - bind_gamepad('q', 1, BUTTON_X); - bind_gamepad('w', 1, BUTTON_Y); - bind_gamepad('e', 1, BUTTON_Z); - bind_gamepad('\r', 1, BUTTON_START); - bind_gamepad('f', 1, BUTTON_MODE); - bind_ui('[', UI_DEBUG_MODE_INC); - bind_ui(']', UI_DEBUG_PAL_INC); - bind_ui('u', UI_ENTER_DEBUGGER); - - bind_dpad_gamepad(0, 0, RENDER_DPAD_UP, 2, DPAD_UP); - bind_dpad_gamepad(0, 0, RENDER_DPAD_DOWN, 2, DPAD_DOWN); - bind_dpad_gamepad(0, 0, RENDER_DPAD_LEFT, 2, DPAD_LEFT); - bind_dpad_gamepad(0, 0, RENDER_DPAD_RIGHT, 2, DPAD_RIGHT); - bind_button_gamepad(0, 0, 2, BUTTON_A); - bind_button_gamepad(0, 1, 2, BUTTON_B); - bind_button_gamepad(0, 2, 2, BUTTON_C); - bind_button_gamepad(0, 3, 2, BUTTON_X); - bind_button_gamepad(0, 4, 2, BUTTON_Y); - bind_button_gamepad(0, 5, 2, BUTTON_Z); - bind_button_gamepad(0, 6, 2, BUTTON_START); - bind_button_gamepad(0, 7, 2, BUTTON_MODE); -} - typedef struct bp_def { struct bp_def * next; uint32_t address; @@ -2131,7 +1771,8 @@ init_x86_z80_opts(&z_opts); init_z80_context(&z_context, &z_opts); - genesis_context gen; + genesis_context gen; + memset(&gen, 0, sizeof(gen)); z_context.system = &gen; z_context.mem_pointers[0] = z80_ram; diff -r 9fb111b5641f -r d0cacb4ade0b blastem.h --- a/blastem.h Mon Jun 24 21:32:25 2013 -0700 +++ b/blastem.h Tue Jun 25 19:20:39 2013 -0700 @@ -7,19 +7,14 @@ #include "ym2612.h" #include "vdp.h" #include "psg.h" - -typedef struct { - uint32_t th_counter; - uint32_t timeout_cycle; - uint8_t output; - uint8_t control; - uint8_t input[3]; -} io_port; +#include "io.h" #define RAM_FLAG_ODD 0x1800 #define RAM_FLAG_EVEN 0x1000 #define RAM_FLAG_BOTH 0x0000 +#define CYCLE_NEVER 0xFFFFFFFF + typedef struct { m68k_context *m68k; z80_context *z80; @@ -30,24 +25,14 @@ uint32_t save_ram_mask; uint32_t save_flags; uint8_t bank_regs[8]; + io_port ports[3]; } genesis_context; -#define GAMEPAD_TH0 0 -#define GAMEPAD_TH1 1 -#define GAMEPAD_EXTRA 2 -#define GAMEPAD_NONE 0xF +extern genesis_context * genesis; +extern int break_on_sync; -extern io_port gamepad_1; -extern io_port gamepad_2; - -void io_adjust_cycles(io_port * pad, uint32_t current_cycle, uint32_t deduction); uint16_t read_dma_value(uint32_t address); m68k_context * debugger(m68k_context * context, uint32_t address); -void handle_keydown(int keycode); -void handle_keyup(int keycode); -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); #endif //BLASTEM_H_ diff -r 9fb111b5641f -r d0cacb4ade0b gen_x86.h --- a/gen_x86.h Mon Jun 24 21:32:25 2013 -0700 +++ b/gen_x86.h Tue Jun 25 19:20:39 2013 -0700 @@ -110,6 +110,7 @@ uint8_t * sbb_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size); uint8_t * cmp_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size); uint8_t * add_irdisp8(uint8_t * out, int32_t val, uint8_t dst_base, int8_t disp, uint8_t size); +uint8_t * add_irdisp32(uint8_t * out, int32_t val, uint8_t dst_base, int32_t disp, uint8_t size); uint8_t * adc_irdisp8(uint8_t * out, int32_t val, uint8_t dst_base, int8_t disp, uint8_t size); uint8_t * or_irdisp8(uint8_t * out, int32_t val, uint8_t dst_base, int8_t disp, uint8_t size); uint8_t * xor_irdisp8(uint8_t * out, int32_t val, uint8_t dst_base, int8_t disp, uint8_t size); diff -r 9fb111b5641f -r d0cacb4ade0b io.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/io.c Tue Jun 25 19:20:39 2013 -0700 @@ -0,0 +1,354 @@ +#include "io.h" +#include "blastem.h" +#include "render.h" + +enum { + BIND_NONE, + BIND_GAMEPAD1, + BIND_GAMEPAD2, + BIND_UI +}; + +typedef enum { + UI_DEBUG_MODE_INC, + UI_DEBUG_PAL_INC, + UI_ENTER_DEBUGGER +} ui_action; + +typedef struct { + uint8_t bind_type; + uint8_t subtype_a; + uint8_t subtype_b; + uint8_t value; +} keybinding; + +typedef struct { + keybinding bindings[4]; + uint8_t state; +} joydpad; + +keybinding * bindings[256]; +keybinding * joybindings[MAX_JOYSTICKS]; +joydpad * joydpads[MAX_JOYSTICKS]; +const uint8_t dpadbits[] = {RENDER_DPAD_UP, RENDER_DPAD_DOWN, RENDER_DPAD_LEFT, RENDER_DPAD_RIGHT}; + +void bind_key(int keycode, uint8_t bind_type, uint8_t subtype_a, uint8_t subtype_b, uint8_t value) +{ + int bucket = keycode >> 8 & 0xFF; + if (!bindings[bucket]) { + bindings[bucket] = malloc(sizeof(keybinding) * 256); + memset(bindings[bucket], 0, sizeof(keybinding) * 256); + } + int idx = keycode & 0xFF; + bindings[bucket][idx].bind_type = bind_type; + bindings[bucket][idx].subtype_a = subtype_a; + bindings[bucket][idx].subtype_b = subtype_b; + bindings[bucket][idx].value = value; +} + +void bind_button(int joystick, int button, uint8_t bind_type, uint8_t subtype_a, uint8_t subtype_b, uint8_t value) +{ + if (joystick >= MAX_JOYSTICKS) { + return; + } + if (!joybindings[joystick]) { + int num = render_joystick_num_buttons(joystick); + if (!num) { + return; + } + joybindings[joystick] = malloc(sizeof(keybinding)*num); + memset(joybindings[joystick], 0, sizeof(keybinding)*num); + } + joybindings[joystick][button].bind_type = bind_type; + joybindings[joystick][button].subtype_a = subtype_a; + joybindings[joystick][button].subtype_b = subtype_b; + joybindings[joystick][button].value = value; +} + +void bind_dpad(int joystick, int dpad, int direction, uint8_t bind_type, uint8_t subtype_a, uint8_t subtype_b, uint8_t value) +{ + if (joystick >= MAX_JOYSTICKS) { + return; + } + if (!joydpads[joystick]) { + int num = render_joystick_num_hats(joystick); + if (!num) { + return; + } + joydpads[joystick] = malloc(sizeof(joydpad)*num); + memset(joydpads[joystick], 0, sizeof(joydpad)*num); + } + for (int i = 0; i < 4; i ++) { + if (dpadbits[i] & direction) { + joydpads[joystick][dpad].bindings[i].bind_type = bind_type; + joydpads[joystick][dpad].bindings[i].subtype_a = subtype_a; + joydpads[joystick][dpad].bindings[i].subtype_b = subtype_b; + joydpads[joystick][dpad].bindings[i].value = value; + break; + } + } +} + +#define GAMEPAD_BUTTON(PRI_SLOT, SEC_SLOT, VALUE) (PRI_SLOT << 12 | SEC_SLOT << 8 | VALUE) + +#define DPAD_UP GAMEPAD_BUTTON(GAMEPAD_TH0, GAMEPAD_TH1, 0x01) +#define BUTTON_Z GAMEPAD_BUTTON(GAMEPAD_EXTRA, GAMEPAD_NONE, 0x01) +#define DPAD_DOWN GAMEPAD_BUTTON(GAMEPAD_TH0, GAMEPAD_TH1, 0x02) +#define BUTTON_Y GAMEPAD_BUTTON(GAMEPAD_EXTRA, GAMEPAD_NONE, 0x02) +#define DPAD_LEFT GAMEPAD_BUTTON(GAMEPAD_TH1, GAMEPAD_NONE, 0x04) +#define BUTTON_X GAMEPAD_BUTTON(GAMEPAD_EXTRA, GAMEPAD_NONE, 0x04) +#define DPAD_RIGHT GAMEPAD_BUTTON(GAMEPAD_TH1, GAMEPAD_NONE, 0x08) +#define BUTTON_MODE GAMEPAD_BUTTON(GAMEPAD_EXTRA, GAMEPAD_NONE, 0x08) +#define BUTTON_A GAMEPAD_BUTTON(GAMEPAD_TH0, GAMEPAD_NONE, 0x10) +#define BUTTON_B GAMEPAD_BUTTON(GAMEPAD_TH1, GAMEPAD_NONE, 0x10) +#define BUTTON_START GAMEPAD_BUTTON(GAMEPAD_TH0, GAMEPAD_NONE, 0x20) +#define BUTTON_C GAMEPAD_BUTTON(GAMEPAD_TH1, GAMEPAD_NONE, 0x20) + +void bind_gamepad(int keycode, int gamepadnum, int button) +{ + + if (gamepadnum < 1 || gamepadnum > 2) { + return; + } + uint8_t bind_type = gamepadnum - 1 + BIND_GAMEPAD1; + bind_key(keycode, bind_type, button >> 12, button >> 8 & 0xF, button & 0xFF); +} + +void bind_button_gamepad(int joystick, int joybutton, int gamepadnum, int padbutton) +{ + if (gamepadnum < 1 || gamepadnum > 2) { + return; + } + uint8_t bind_type = gamepadnum - 1 + BIND_GAMEPAD1; + bind_button(joystick, joybutton, bind_type, padbutton >> 12, padbutton >> 8 & 0xF, padbutton & 0xFF); +} + +void bind_dpad_gamepad(int joystick, int dpad, uint8_t direction, int gamepadnum, int button) +{ + if (gamepadnum < 1 || gamepadnum > 2) { + return; + } + uint8_t bind_type = gamepadnum - 1 + BIND_GAMEPAD1; + bind_dpad(joystick, dpad, direction, bind_type, button >> 12, button >> 8 & 0xF, button & 0xFF); +} + +void bind_ui(int keycode, ui_action action) +{ + bind_key(keycode, BIND_UI, action, 0, 0); +} + +void handle_binding_down(keybinding * binding) +{ + switch(binding->bind_type) + { + case BIND_GAMEPAD1: + case BIND_GAMEPAD2: + if (binding->subtype_a <= GAMEPAD_EXTRA) { + genesis->ports[binding->bind_type - BIND_GAMEPAD1].input[binding->subtype_a] |= binding->value; + } + if (binding->subtype_b <= GAMEPAD_EXTRA) { + genesis->ports[binding->bind_type - BIND_GAMEPAD1].input[binding->subtype_b] |= binding->value; + } + break; + } +} + +void handle_keydown(int keycode) +{ + int bucket = keycode >> 8 & 0xFF; + if (!bindings[bucket]) { + return; + } + int idx = keycode & 0xFF; + keybinding * binding = bindings[bucket] + idx; + handle_binding_down(binding); +} + +void handle_joydown(int joystick, int button) +{ + if (!joybindings[joystick]) { + return; + } + keybinding * binding = joybindings[joystick] + button; + handle_binding_down(binding); +} + +uint8_t ui_debug_mode = 0; +uint8_t ui_debug_pal = 0; + +void handle_binding_up(keybinding * binding) +{ + switch(binding->bind_type) + { + case BIND_GAMEPAD1: + case BIND_GAMEPAD2: + if (binding->subtype_a <= GAMEPAD_EXTRA) { + genesis->ports[binding->bind_type - BIND_GAMEPAD1].input[binding->subtype_a] &= ~binding->value; + } + if (binding->subtype_b <= GAMEPAD_EXTRA) { + genesis->ports[binding->bind_type - BIND_GAMEPAD1].input[binding->subtype_b] &= ~binding->value; + } + break; + case BIND_UI: + switch (binding->subtype_a) + { + case UI_DEBUG_MODE_INC: + ui_debug_mode++; + if (ui_debug_mode == 4) { + ui_debug_mode = 0; + } + render_debug_mode(ui_debug_mode); + break; + case UI_DEBUG_PAL_INC: + ui_debug_pal++; + if (ui_debug_pal == 4) { + ui_debug_pal = 0; + } + render_debug_pal(ui_debug_pal); + break; + case UI_ENTER_DEBUGGER: + break_on_sync = 1; + break; + } + break; + } +} + +void handle_keyup(int keycode) +{ + int bucket = keycode >> 8 & 0xFF; + if (!bindings[bucket]) { + return; + } + int idx = keycode & 0xFF; + keybinding * binding = bindings[bucket] + idx; + handle_binding_up(binding); +} + +void handle_joyup(int joystick, int button) +{ + if (!joybindings[joystick]) { + return; + } + keybinding * binding = joybindings[joystick] + button; + handle_binding_up(binding); +} + +void handle_joy_dpad(int joystick, int dpadnum, uint8_t value) +{ + if (!joydpads[joystick]) { + return; + } + joydpad * dpad = joydpads[joystick] + dpadnum; + uint8_t newdown = (value ^ dpad->state) & value; + uint8_t newup = ((~value) ^ (~dpad->state)) & (~value); + dpad->state = value; + for (int i = 0; i < 4; i++) { + if (newdown & dpadbits[i]) { + handle_binding_down(dpad->bindings + i); + } else if(newup & dpadbits[i]) { + handle_binding_up(dpad->bindings + i); + } + } +} + +void set_keybindings() +{ + bind_gamepad(RENDERKEY_UP, 1, DPAD_UP); + bind_gamepad(RENDERKEY_DOWN, 1, DPAD_DOWN); + bind_gamepad(RENDERKEY_LEFT, 1, DPAD_LEFT); + bind_gamepad(RENDERKEY_RIGHT, 1, DPAD_RIGHT); + bind_gamepad('a', 1, BUTTON_A); + bind_gamepad('s', 1, BUTTON_B); + bind_gamepad('d', 1, BUTTON_C); + bind_gamepad('q', 1, BUTTON_X); + bind_gamepad('w', 1, BUTTON_Y); + bind_gamepad('e', 1, BUTTON_Z); + bind_gamepad('\r', 1, BUTTON_START); + bind_gamepad('f', 1, BUTTON_MODE); + bind_ui('[', UI_DEBUG_MODE_INC); + bind_ui(']', UI_DEBUG_PAL_INC); + bind_ui('u', UI_ENTER_DEBUGGER); + + bind_dpad_gamepad(0, 0, RENDER_DPAD_UP, 2, DPAD_UP); + bind_dpad_gamepad(0, 0, RENDER_DPAD_DOWN, 2, DPAD_DOWN); + bind_dpad_gamepad(0, 0, RENDER_DPAD_LEFT, 2, DPAD_LEFT); + bind_dpad_gamepad(0, 0, RENDER_DPAD_RIGHT, 2, DPAD_RIGHT); + bind_button_gamepad(0, 0, 2, BUTTON_A); + bind_button_gamepad(0, 1, 2, BUTTON_B); + bind_button_gamepad(0, 2, 2, BUTTON_C); + bind_button_gamepad(0, 3, 2, BUTTON_X); + bind_button_gamepad(0, 4, 2, BUTTON_Y); + bind_button_gamepad(0, 5, 2, BUTTON_Z); + bind_button_gamepad(0, 6, 2, BUTTON_START); + bind_button_gamepad(0, 7, 2, BUTTON_MODE); +} + +#define TH 0x40 +#define TH_TIMEOUT 8000 + +void io_adjust_cycles(io_port * pad, uint32_t current_cycle, uint32_t deduction) +{ + /*uint8_t control = pad->control | 0x80; + uint8_t th = control & pad->output; + if (pad->input[GAMEPAD_TH0] || pad->input[GAMEPAD_TH1]) { + printf("adjust_cycles | control: %X, TH: %X, GAMEPAD_TH0: %X, GAMEPAD_TH1: %X, TH Counter: %d, Timeout: %d, Cycle: %d\n", control, th, pad->input[GAMEPAD_TH0], pad->input[GAMEPAD_TH1], pad->th_counter,pad->timeout_cycle, current_cycle); + }*/ + if (current_cycle >= pad->timeout_cycle) { + pad->th_counter = 0; + } else { + pad->timeout_cycle -= deduction; + } +} + +void io_data_write(io_port * pad, uint8_t value, uint32_t current_cycle) +{ + if (pad->control & TH) { + //check if TH has changed + if ((pad->output & TH) ^ (value & TH)) { + if (current_cycle >= pad->timeout_cycle) { + pad->th_counter = 0; + } + if (!(value & TH)) { + pad->th_counter++; + } + pad->timeout_cycle = current_cycle + TH_TIMEOUT; + } + } + pad->output = value; +} + +uint8_t io_data_read(io_port * pad, uint32_t current_cycle) +{ + uint8_t control = pad->control | 0x80; + uint8_t th = control & pad->output; + uint8_t input; + if (current_cycle >= pad->timeout_cycle) { + pad->th_counter = 0; + } + /*if (pad->input[GAMEPAD_TH0] || pad->input[GAMEPAD_TH1]) { + printf("io_data_read | control: %X, TH: %X, GAMEPAD_TH0: %X, GAMEPAD_TH1: %X, TH Counter: %d, Timeout: %d, Cycle: %d\n", control, th, pad->input[GAMEPAD_TH0], pad->input[GAMEPAD_TH1], pad->th_counter,pad->timeout_cycle, context->current_cycle); + }*/ + if (th) { + if (pad->th_counter == 3) { + input = pad->input[GAMEPAD_EXTRA]; + } else { + input = pad->input[GAMEPAD_TH1]; + } + } else { + if (pad->th_counter == 3) { + input = pad->input[GAMEPAD_TH0] | 0xF; + } else if(pad->th_counter == 4) { + input = pad->input[GAMEPAD_TH0] & 0x30; + } else { + input = pad->input[GAMEPAD_TH0] | 0xC; + } + } + uint8_t value = ((~input) & (~control)) | (pad->output & control); + /*if (pad->input[GAMEPAD_TH0] || pad->input[GAMEPAD_TH1]) { + printf ("value: %X\n", value); + }*/ + return value; +} + + diff -r 9fb111b5641f -r d0cacb4ade0b io.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/io.h Tue Jun 25 19:20:39 2013 -0700 @@ -0,0 +1,29 @@ +#ifndef IO_H_ +#define IO_H_ +#include + +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 +#define GAMEPAD_NONE 0xF + +void set_keybindings(); +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); +void handle_keyup(int keycode); +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); + +#endif //IO_H_ + diff -r 9fb111b5641f -r d0cacb4ade0b render_sdl.c --- a/render_sdl.c Mon Jun 24 21:32:25 2013 -0700 +++ b/render_sdl.c Tue Jun 25 19:20:39 2013 -0700 @@ -2,6 +2,7 @@ #include #include "render.h" #include "blastem.h" +#include "io.h" SDL_Surface *screen; uint8_t render_dbg = 0;