summaryrefslogtreecommitdiff
path: root/blastem.c
diff options
context:
space:
mode:
authorMike Pavone <pavone@retrodev.com>2013-06-25 19:20:39 -0700
committerMike Pavone <pavone@retrodev.com>2013-06-25 19:20:39 -0700
commit3caaed844a05a897e44df0685abfcbd1b162f862 (patch)
tree89596787e001cc65b41cb3b826e82350fd8d8ee2 /blastem.c
parentf8296ee1fa057adc180ed4d6a2066a841dbe74c4 (diff)
Move IO code to a separate file and do a tiny bit of refactoring
Diffstat (limited to 'blastem.c')
-rw-r--r--blastem.c419
1 files changed, 30 insertions, 389 deletions
diff --git a/blastem.c b/blastem.c
index 01be7db..2962f40 100644
--- a/blastem.c
+++ b/blastem.c
@@ -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 cart[CARTRIDGE_WORDS];
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 @@ m68k_context * sync_components(m68k_context * context, uint32_t address)
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 @@ m68k_context * vdp_port_write(uint32_t vdp_port, m68k_context * context, uint16_
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 @@ m68k_context * vdp_port_write(uint32_t vdp_port, m68k_context * context, uint16_
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 @@ uint8_t vdp_port_read_b(uint32_t vdp_port, m68k_context * context)
}
}
-#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 @@ m68k_context * io_write(uint32_t location, m68k_context * context, uint8_t value
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 @@ uint8_t io_read(uint32_t location, m68k_context * context)
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 @@ m68k_context * write_bank_reg_b(uint32_t address, m68k_context * context, uint8_
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 @@ int main(int argc, char ** argv)
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;