Mercurial > repos > blastem
comparison blastem.c @ 421:d0cacb4ade0b
Move IO code to a separate file and do a tiny bit of refactoring
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 25 Jun 2013 19:20:39 -0700 |
parents | dbf4e1c86f3c |
children | 642b2f8aee32 |
comparison
equal
deleted
inserted
replaced
420:9fb111b5641f | 421:d0cacb4ade0b |
---|---|
20 #define MCLKS_PER_YM MCLKS_PER_68K | 20 #define MCLKS_PER_YM MCLKS_PER_68K |
21 #define MCLKS_PER_Z80 15 | 21 #define MCLKS_PER_Z80 15 |
22 #define MCLKS_PER_PSG (MCLKS_PER_Z80*16) | 22 #define MCLKS_PER_PSG (MCLKS_PER_Z80*16) |
23 | 23 |
24 //TODO: Figure out the exact value for this | 24 //TODO: Figure out the exact value for this |
25 #define CYCLE_NEVER 0xFFFFFFFF | |
26 #define LINES_NTSC 262 | 25 #define LINES_NTSC 262 |
27 #define LINES_PAL 312 | 26 #define LINES_PAL 312 |
28 | 27 |
29 uint32_t mclks_per_frame = MCLKS_LINE*LINES_NTSC; | 28 uint32_t mclks_per_frame = MCLKS_LINE*LINES_NTSC; |
30 | 29 |
31 uint16_t cart[CARTRIDGE_WORDS]; | 30 uint16_t cart[CARTRIDGE_WORDS]; |
32 uint16_t ram[RAM_WORDS]; | 31 uint16_t ram[RAM_WORDS]; |
33 uint8_t z80_ram[Z80_RAM_BYTES]; | 32 uint8_t z80_ram[Z80_RAM_BYTES]; |
34 | |
35 io_port gamepad_1; | |
36 io_port gamepad_2; | |
37 | 33 |
38 int headless = 0; | 34 int headless = 0; |
39 int z80_enabled = 1; | 35 int z80_enabled = 1; |
40 int frame_limit = 0; | 36 int frame_limit = 0; |
41 | 37 |
228 break_on_sync |= wait_render_frame(v_context, frame_limit); | 224 break_on_sync |= wait_render_frame(v_context, frame_limit); |
229 } | 225 } |
230 frame++; | 226 frame++; |
231 mclks -= mclks_per_frame; | 227 mclks -= mclks_per_frame; |
232 vdp_adjust_cycles(v_context, mclks_per_frame); | 228 vdp_adjust_cycles(v_context, mclks_per_frame); |
233 io_adjust_cycles(&gamepad_1, context->current_cycle, mclks_per_frame/MCLKS_PER_68K); | 229 io_adjust_cycles(gen->ports, context->current_cycle, mclks_per_frame/MCLKS_PER_68K); |
234 io_adjust_cycles(&gamepad_2, context->current_cycle, mclks_per_frame/MCLKS_PER_68K); | 230 io_adjust_cycles(gen->ports+1, context->current_cycle, mclks_per_frame/MCLKS_PER_68K); |
231 io_adjust_cycles(gen->ports+2, context->current_cycle, mclks_per_frame/MCLKS_PER_68K); | |
235 if (busack_cycle != CYCLE_NEVER) { | 232 if (busack_cycle != CYCLE_NEVER) { |
236 if (busack_cycle > mclks_per_frame/MCLKS_PER_68K) { | 233 if (busack_cycle > mclks_per_frame/MCLKS_PER_68K) { |
237 busack_cycle -= mclks_per_frame/MCLKS_PER_68K; | 234 busack_cycle -= mclks_per_frame/MCLKS_PER_68K; |
238 } else { | 235 } else { |
239 busack_cycle = CYCLE_NEVER; | 236 busack_cycle = CYCLE_NEVER; |
286 if (v_context->cycles >= mclks_per_frame) { | 283 if (v_context->cycles >= mclks_per_frame) { |
287 if (!headless) { | 284 if (!headless) { |
288 wait_render_frame(v_context, frame_limit); | 285 wait_render_frame(v_context, frame_limit); |
289 } | 286 } |
290 vdp_adjust_cycles(v_context, mclks_per_frame); | 287 vdp_adjust_cycles(v_context, mclks_per_frame); |
291 io_adjust_cycles(&gamepad_1, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K); | 288 genesis_context * gen = context->system; |
292 io_adjust_cycles(&gamepad_2, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K); | 289 io_adjust_cycles(gen->ports, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K); |
290 io_adjust_cycles(gen->ports+1, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K); | |
291 io_adjust_cycles(gen->ports+2, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K); | |
293 if (busack_cycle != CYCLE_NEVER) { | 292 if (busack_cycle != CYCLE_NEVER) { |
294 if (busack_cycle > mclks_per_frame/MCLKS_PER_68K) { | 293 if (busack_cycle > mclks_per_frame/MCLKS_PER_68K) { |
295 busack_cycle -= mclks_per_frame/MCLKS_PER_68K; | 294 busack_cycle -= mclks_per_frame/MCLKS_PER_68K; |
296 } else { | 295 } else { |
297 busack_cycle = CYCLE_NEVER; | 296 busack_cycle = CYCLE_NEVER; |
311 if (v_context->cycles >= mclks_per_frame) { | 310 if (v_context->cycles >= mclks_per_frame) { |
312 if (!headless) { | 311 if (!headless) { |
313 wait_render_frame(v_context, frame_limit); | 312 wait_render_frame(v_context, frame_limit); |
314 } | 313 } |
315 vdp_adjust_cycles(v_context, mclks_per_frame); | 314 vdp_adjust_cycles(v_context, mclks_per_frame); |
316 io_adjust_cycles(&gamepad_1, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K); | 315 genesis_context * gen = context->system; |
317 io_adjust_cycles(&gamepad_2, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K); | 316 io_adjust_cycles(gen->ports, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K); |
317 io_adjust_cycles(gen->ports+1, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K); | |
318 io_adjust_cycles(gen->ports+2, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K); | |
318 if (busack_cycle != CYCLE_NEVER) { | 319 if (busack_cycle != CYCLE_NEVER) { |
319 if (busack_cycle > mclks_per_frame/MCLKS_PER_68K) { | 320 if (busack_cycle > mclks_per_frame/MCLKS_PER_68K) { |
320 busack_cycle -= mclks_per_frame/MCLKS_PER_68K; | 321 busack_cycle -= mclks_per_frame/MCLKS_PER_68K; |
321 } else { | 322 } else { |
322 busack_cycle = CYCLE_NEVER; | 323 busack_cycle = CYCLE_NEVER; |
419 } else { | 420 } else { |
420 return value >> 8; | 421 return value >> 8; |
421 } | 422 } |
422 } | 423 } |
423 | 424 |
424 #define TH 0x40 | |
425 #define TH_TIMEOUT 8000 | |
426 | |
427 void io_adjust_cycles(io_port * pad, uint32_t current_cycle, uint32_t deduction) | |
428 { | |
429 /*uint8_t control = pad->control | 0x80; | |
430 uint8_t th = control & pad->output; | |
431 if (pad->input[GAMEPAD_TH0] || pad->input[GAMEPAD_TH1]) { | |
432 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); | |
433 }*/ | |
434 if (current_cycle >= pad->timeout_cycle) { | |
435 pad->th_counter = 0; | |
436 } else { | |
437 pad->timeout_cycle -= deduction; | |
438 } | |
439 if (busack_cycle < CYCLE_NEVER && current_cycle < busack_cycle) { | |
440 busack_cycle -= deduction; | |
441 } | |
442 } | |
443 | |
444 void io_data_write(io_port * pad, m68k_context * context, uint8_t value) | |
445 { | |
446 if (pad->control & TH) { | |
447 //check if TH has changed | |
448 if ((pad->output & TH) ^ (value & TH)) { | |
449 if (context->current_cycle >= pad->timeout_cycle) { | |
450 pad->th_counter = 0; | |
451 } | |
452 if (!(value & TH)) { | |
453 pad->th_counter++; | |
454 } | |
455 pad->timeout_cycle = context->current_cycle + TH_TIMEOUT; | |
456 } | |
457 } | |
458 pad->output = value; | |
459 } | |
460 | |
461 uint8_t io_data_read(io_port * pad, m68k_context * context) | |
462 { | |
463 uint8_t control = pad->control | 0x80; | |
464 uint8_t th = control & pad->output; | |
465 uint8_t input; | |
466 if (context->current_cycle >= pad->timeout_cycle) { | |
467 pad->th_counter = 0; | |
468 } | |
469 /*if (pad->input[GAMEPAD_TH0] || pad->input[GAMEPAD_TH1]) { | |
470 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); | |
471 }*/ | |
472 if (th) { | |
473 if (pad->th_counter == 3) { | |
474 input = pad->input[GAMEPAD_EXTRA]; | |
475 } else { | |
476 input = pad->input[GAMEPAD_TH1]; | |
477 } | |
478 } else { | |
479 if (pad->th_counter == 3) { | |
480 input = pad->input[GAMEPAD_TH0] | 0xF; | |
481 } else if(pad->th_counter == 4) { | |
482 input = pad->input[GAMEPAD_TH0] & 0x30; | |
483 } else { | |
484 input = pad->input[GAMEPAD_TH0] | 0xC; | |
485 } | |
486 } | |
487 uint8_t value = ((~input) & (~control)) | (pad->output & control); | |
488 /*if (pad->input[GAMEPAD_TH0] || pad->input[GAMEPAD_TH1]) { | |
489 printf ("value: %X\n", value); | |
490 }*/ | |
491 return value; | |
492 } | |
493 | |
494 uint32_t zram_counter = 0; | 425 uint32_t zram_counter = 0; |
495 #define Z80_ACK_DELAY 3 | 426 #define Z80_ACK_DELAY 3 |
496 #define Z80_BUSY_DELAY 1//TODO: Find the actual value for this | 427 #define Z80_BUSY_DELAY 1//TODO: Find the actual value for this |
497 #define Z80_REQ_BUSY 1 | 428 #define Z80_REQ_BUSY 1 |
498 #define Z80_REQ_ACK 0 | 429 #define Z80_REQ_ACK 0 |
536 location &= 0x1FFF; | 467 location &= 0x1FFF; |
537 if (location < 0x100) { | 468 if (location < 0x100) { |
538 switch(location/2) | 469 switch(location/2) |
539 { | 470 { |
540 case 0x1: | 471 case 0x1: |
541 io_data_write(&gamepad_1, context, value); | 472 io_data_write(gen->ports, value, context->current_cycle); |
542 break; | 473 break; |
543 case 0x2: | 474 case 0x2: |
544 io_data_write(&gamepad_2, context, value); | 475 io_data_write(gen->ports+1, value, context->current_cycle); |
545 break; | 476 break; |
546 case 0x3://PORT C Data | 477 case 0x3: |
478 io_data_write(gen->ports+2, value, context->current_cycle); | |
547 break; | 479 break; |
548 case 0x4: | 480 case 0x4: |
549 gamepad_1.control = value; | 481 gen->ports[0].control = value; |
550 break; | 482 break; |
551 case 0x5: | 483 case 0x5: |
552 gamepad_2.control = value; | 484 gen->ports[1].control = value; |
485 break; | |
486 case 0x6: | |
487 gen->ports[2].control = value; | |
553 break; | 488 break; |
554 } | 489 } |
555 } else { | 490 } else { |
556 if (location == 0x1100) { | 491 if (location == 0x1100) { |
557 sync_z80(gen->z80, context->current_cycle * MCLKS_PER_68K); | 492 sync_z80(gen->z80, context->current_cycle * MCLKS_PER_68K); |
653 case 0x0: | 588 case 0x0: |
654 //version bits should be 0 for now since we're not emulating TMSS | 589 //version bits should be 0 for now since we're not emulating TMSS |
655 value = version_reg; | 590 value = version_reg; |
656 break; | 591 break; |
657 case 0x1: | 592 case 0x1: |
658 value = io_data_read(&gamepad_1, context); | 593 value = io_data_read(gen->ports, context->current_cycle); |
659 break; | 594 break; |
660 case 0x2: | 595 case 0x2: |
661 value = io_data_read(&gamepad_2, context); | 596 value = io_data_read(gen->ports+1, context->current_cycle); |
662 break; | 597 break; |
663 case 0x3://PORT C Data | 598 case 0x3: |
599 value = io_data_read(gen->ports+2, context->current_cycle); | |
664 break; | 600 break; |
665 case 0x4: | 601 case 0x4: |
666 value = gamepad_1.control; | 602 value = gen->ports[0].control; |
667 break; | 603 break; |
668 case 0x5: | 604 case 0x5: |
669 value = gamepad_2.control; | 605 value = gen->ports[1].control; |
670 break; | 606 break; |
671 case 0x6://PORT C control | 607 case 0x6: |
672 value = 0; | 608 value = gen->ports[2].control; |
673 break; | 609 break; |
674 default: | 610 default: |
675 value = 0xFF; | 611 value = 0xFF; |
676 } | 612 } |
677 } else { | 613 } else { |
842 context->mem_pointers[2] = cart + 0x200000/2; | 778 context->mem_pointers[2] = cart + 0x200000/2; |
843 } | 779 } |
844 } | 780 } |
845 } | 781 } |
846 return context; | 782 return context; |
847 } | |
848 | |
849 enum { | |
850 BIND_NONE, | |
851 BIND_GAMEPAD1, | |
852 BIND_GAMEPAD2, | |
853 BIND_UI | |
854 }; | |
855 | |
856 typedef enum { | |
857 UI_DEBUG_MODE_INC, | |
858 UI_DEBUG_PAL_INC, | |
859 UI_ENTER_DEBUGGER | |
860 } ui_action; | |
861 | |
862 typedef struct { | |
863 uint8_t bind_type; | |
864 uint8_t subtype_a; | |
865 uint8_t subtype_b; | |
866 uint8_t value; | |
867 } keybinding; | |
868 | |
869 typedef struct { | |
870 keybinding bindings[4]; | |
871 uint8_t state; | |
872 } joydpad; | |
873 | |
874 keybinding * bindings[256]; | |
875 keybinding * joybindings[MAX_JOYSTICKS]; | |
876 joydpad * joydpads[MAX_JOYSTICKS]; | |
877 const uint8_t dpadbits[] = {RENDER_DPAD_UP, RENDER_DPAD_DOWN, RENDER_DPAD_LEFT, RENDER_DPAD_RIGHT}; | |
878 | |
879 void bind_key(int keycode, uint8_t bind_type, uint8_t subtype_a, uint8_t subtype_b, uint8_t value) | |
880 { | |
881 int bucket = keycode >> 8 & 0xFF; | |
882 if (!bindings[bucket]) { | |
883 bindings[bucket] = malloc(sizeof(keybinding) * 256); | |
884 memset(bindings[bucket], 0, sizeof(keybinding) * 256); | |
885 } | |
886 int idx = keycode & 0xFF; | |
887 bindings[bucket][idx].bind_type = bind_type; | |
888 bindings[bucket][idx].subtype_a = subtype_a; | |
889 bindings[bucket][idx].subtype_b = subtype_b; | |
890 bindings[bucket][idx].value = value; | |
891 } | |
892 | |
893 void bind_button(int joystick, int button, uint8_t bind_type, uint8_t subtype_a, uint8_t subtype_b, uint8_t value) | |
894 { | |
895 if (joystick >= MAX_JOYSTICKS) { | |
896 return; | |
897 } | |
898 if (!joybindings[joystick]) { | |
899 int num = render_joystick_num_buttons(joystick); | |
900 if (!num) { | |
901 return; | |
902 } | |
903 joybindings[joystick] = malloc(sizeof(keybinding)*num); | |
904 memset(joybindings[joystick], 0, sizeof(keybinding)*num); | |
905 } | |
906 joybindings[joystick][button].bind_type = bind_type; | |
907 joybindings[joystick][button].subtype_a = subtype_a; | |
908 joybindings[joystick][button].subtype_b = subtype_b; | |
909 joybindings[joystick][button].value = value; | |
910 } | |
911 | |
912 void bind_dpad(int joystick, int dpad, int direction, uint8_t bind_type, uint8_t subtype_a, uint8_t subtype_b, uint8_t value) | |
913 { | |
914 if (joystick >= MAX_JOYSTICKS) { | |
915 return; | |
916 } | |
917 if (!joydpads[joystick]) { | |
918 int num = render_joystick_num_hats(joystick); | |
919 if (!num) { | |
920 return; | |
921 } | |
922 joydpads[joystick] = malloc(sizeof(joydpad)*num); | |
923 memset(joydpads[joystick], 0, sizeof(joydpad)*num); | |
924 } | |
925 for (int i = 0; i < 4; i ++) { | |
926 if (dpadbits[i] & direction) { | |
927 joydpads[joystick][dpad].bindings[i].bind_type = bind_type; | |
928 joydpads[joystick][dpad].bindings[i].subtype_a = subtype_a; | |
929 joydpads[joystick][dpad].bindings[i].subtype_b = subtype_b; | |
930 joydpads[joystick][dpad].bindings[i].value = value; | |
931 break; | |
932 } | |
933 } | |
934 } | |
935 | |
936 #define GAMEPAD_BUTTON(PRI_SLOT, SEC_SLOT, VALUE) (PRI_SLOT << 12 | SEC_SLOT << 8 | VALUE) | |
937 | |
938 #define DPAD_UP GAMEPAD_BUTTON(GAMEPAD_TH0, GAMEPAD_TH1, 0x01) | |
939 #define BUTTON_Z GAMEPAD_BUTTON(GAMEPAD_EXTRA, GAMEPAD_NONE, 0x01) | |
940 #define DPAD_DOWN GAMEPAD_BUTTON(GAMEPAD_TH0, GAMEPAD_TH1, 0x02) | |
941 #define BUTTON_Y GAMEPAD_BUTTON(GAMEPAD_EXTRA, GAMEPAD_NONE, 0x02) | |
942 #define DPAD_LEFT GAMEPAD_BUTTON(GAMEPAD_TH1, GAMEPAD_NONE, 0x04) | |
943 #define BUTTON_X GAMEPAD_BUTTON(GAMEPAD_EXTRA, GAMEPAD_NONE, 0x04) | |
944 #define DPAD_RIGHT GAMEPAD_BUTTON(GAMEPAD_TH1, GAMEPAD_NONE, 0x08) | |
945 #define BUTTON_MODE GAMEPAD_BUTTON(GAMEPAD_EXTRA, GAMEPAD_NONE, 0x08) | |
946 #define BUTTON_A GAMEPAD_BUTTON(GAMEPAD_TH0, GAMEPAD_NONE, 0x10) | |
947 #define BUTTON_B GAMEPAD_BUTTON(GAMEPAD_TH1, GAMEPAD_NONE, 0x10) | |
948 #define BUTTON_START GAMEPAD_BUTTON(GAMEPAD_TH0, GAMEPAD_NONE, 0x20) | |
949 #define BUTTON_C GAMEPAD_BUTTON(GAMEPAD_TH1, GAMEPAD_NONE, 0x20) | |
950 | |
951 void bind_gamepad(int keycode, int gamepadnum, int button) | |
952 { | |
953 | |
954 if (gamepadnum < 1 || gamepadnum > 2) { | |
955 return; | |
956 } | |
957 uint8_t bind_type = gamepadnum - 1 + BIND_GAMEPAD1; | |
958 bind_key(keycode, bind_type, button >> 12, button >> 8 & 0xF, button & 0xFF); | |
959 } | |
960 | |
961 void bind_button_gamepad(int joystick, int joybutton, int gamepadnum, int padbutton) | |
962 { | |
963 if (gamepadnum < 1 || gamepadnum > 2) { | |
964 return; | |
965 } | |
966 uint8_t bind_type = gamepadnum - 1 + BIND_GAMEPAD1; | |
967 bind_button(joystick, joybutton, bind_type, padbutton >> 12, padbutton >> 8 & 0xF, padbutton & 0xFF); | |
968 } | |
969 | |
970 void bind_dpad_gamepad(int joystick, int dpad, uint8_t direction, int gamepadnum, int button) | |
971 { | |
972 if (gamepadnum < 1 || gamepadnum > 2) { | |
973 return; | |
974 } | |
975 uint8_t bind_type = gamepadnum - 1 + BIND_GAMEPAD1; | |
976 bind_dpad(joystick, dpad, direction, bind_type, button >> 12, button >> 8 & 0xF, button & 0xFF); | |
977 } | |
978 | |
979 void bind_ui(int keycode, ui_action action) | |
980 { | |
981 bind_key(keycode, BIND_UI, action, 0, 0); | |
982 } | |
983 | |
984 void handle_binding_down(keybinding * binding) | |
985 { | |
986 switch(binding->bind_type) | |
987 { | |
988 case BIND_GAMEPAD1: | |
989 if (binding->subtype_a <= GAMEPAD_EXTRA) { | |
990 gamepad_1.input[binding->subtype_a] |= binding->value; | |
991 } | |
992 if (binding->subtype_b <= GAMEPAD_EXTRA) { | |
993 gamepad_1.input[binding->subtype_b] |= binding->value; | |
994 } | |
995 break; | |
996 case BIND_GAMEPAD2: | |
997 if (binding->subtype_a <= GAMEPAD_EXTRA) { | |
998 gamepad_2.input[binding->subtype_a] |= binding->value; | |
999 } | |
1000 if (binding->subtype_b <= GAMEPAD_EXTRA) { | |
1001 gamepad_2.input[binding->subtype_b] |= binding->value; | |
1002 } | |
1003 break; | |
1004 } | |
1005 } | |
1006 | |
1007 void handle_keydown(int keycode) | |
1008 { | |
1009 int bucket = keycode >> 8 & 0xFF; | |
1010 if (!bindings[bucket]) { | |
1011 return; | |
1012 } | |
1013 int idx = keycode & 0xFF; | |
1014 keybinding * binding = bindings[bucket] + idx; | |
1015 handle_binding_down(binding); | |
1016 } | |
1017 | |
1018 void handle_joydown(int joystick, int button) | |
1019 { | |
1020 if (!joybindings[joystick]) { | |
1021 return; | |
1022 } | |
1023 keybinding * binding = joybindings[joystick] + button; | |
1024 handle_binding_down(binding); | |
1025 } | |
1026 | |
1027 uint8_t ui_debug_mode = 0; | |
1028 uint8_t ui_debug_pal = 0; | |
1029 | |
1030 void handle_binding_up(keybinding * binding) | |
1031 { | |
1032 switch(binding->bind_type) | |
1033 { | |
1034 case BIND_GAMEPAD1: | |
1035 if (binding->subtype_a <= GAMEPAD_EXTRA) { | |
1036 gamepad_1.input[binding->subtype_a] &= ~binding->value; | |
1037 } | |
1038 if (binding->subtype_b <= GAMEPAD_EXTRA) { | |
1039 gamepad_1.input[binding->subtype_b] &= ~binding->value; | |
1040 } | |
1041 break; | |
1042 case BIND_GAMEPAD2: | |
1043 if (binding->subtype_a <= GAMEPAD_EXTRA) { | |
1044 gamepad_2.input[binding->subtype_a] &= ~binding->value; | |
1045 } | |
1046 if (binding->subtype_b <= GAMEPAD_EXTRA) { | |
1047 gamepad_2.input[binding->subtype_b] &= ~binding->value; | |
1048 } | |
1049 break; | |
1050 case BIND_UI: | |
1051 switch (binding->subtype_a) | |
1052 { | |
1053 case UI_DEBUG_MODE_INC: | |
1054 ui_debug_mode++; | |
1055 if (ui_debug_mode == 4) { | |
1056 ui_debug_mode = 0; | |
1057 } | |
1058 render_debug_mode(ui_debug_mode); | |
1059 break; | |
1060 case UI_DEBUG_PAL_INC: | |
1061 ui_debug_pal++; | |
1062 if (ui_debug_pal == 4) { | |
1063 ui_debug_pal = 0; | |
1064 } | |
1065 render_debug_pal(ui_debug_pal); | |
1066 break; | |
1067 case UI_ENTER_DEBUGGER: | |
1068 break_on_sync = 1; | |
1069 break; | |
1070 } | |
1071 break; | |
1072 } | |
1073 } | |
1074 | |
1075 void handle_keyup(int keycode) | |
1076 { | |
1077 int bucket = keycode >> 8 & 0xFF; | |
1078 if (!bindings[bucket]) { | |
1079 return; | |
1080 } | |
1081 int idx = keycode & 0xFF; | |
1082 keybinding * binding = bindings[bucket] + idx; | |
1083 handle_binding_up(binding); | |
1084 } | |
1085 | |
1086 void handle_joyup(int joystick, int button) | |
1087 { | |
1088 if (!joybindings[joystick]) { | |
1089 return; | |
1090 } | |
1091 keybinding * binding = joybindings[joystick] + button; | |
1092 handle_binding_up(binding); | |
1093 } | |
1094 | |
1095 void handle_joy_dpad(int joystick, int dpadnum, uint8_t value) | |
1096 { | |
1097 if (!joydpads[joystick]) { | |
1098 return; | |
1099 } | |
1100 joydpad * dpad = joydpads[joystick] + dpadnum; | |
1101 uint8_t newdown = (value ^ dpad->state) & value; | |
1102 uint8_t newup = ((~value) ^ (~dpad->state)) & (~value); | |
1103 dpad->state = value; | |
1104 for (int i = 0; i < 4; i++) { | |
1105 if (newdown & dpadbits[i]) { | |
1106 handle_binding_down(dpad->bindings + i); | |
1107 } else if(newup & dpadbits[i]) { | |
1108 handle_binding_up(dpad->bindings + i); | |
1109 } | |
1110 } | |
1111 } | |
1112 | |
1113 void set_keybindings() | |
1114 { | |
1115 bind_gamepad(RENDERKEY_UP, 1, DPAD_UP); | |
1116 bind_gamepad(RENDERKEY_DOWN, 1, DPAD_DOWN); | |
1117 bind_gamepad(RENDERKEY_LEFT, 1, DPAD_LEFT); | |
1118 bind_gamepad(RENDERKEY_RIGHT, 1, DPAD_RIGHT); | |
1119 bind_gamepad('a', 1, BUTTON_A); | |
1120 bind_gamepad('s', 1, BUTTON_B); | |
1121 bind_gamepad('d', 1, BUTTON_C); | |
1122 bind_gamepad('q', 1, BUTTON_X); | |
1123 bind_gamepad('w', 1, BUTTON_Y); | |
1124 bind_gamepad('e', 1, BUTTON_Z); | |
1125 bind_gamepad('\r', 1, BUTTON_START); | |
1126 bind_gamepad('f', 1, BUTTON_MODE); | |
1127 bind_ui('[', UI_DEBUG_MODE_INC); | |
1128 bind_ui(']', UI_DEBUG_PAL_INC); | |
1129 bind_ui('u', UI_ENTER_DEBUGGER); | |
1130 | |
1131 bind_dpad_gamepad(0, 0, RENDER_DPAD_UP, 2, DPAD_UP); | |
1132 bind_dpad_gamepad(0, 0, RENDER_DPAD_DOWN, 2, DPAD_DOWN); | |
1133 bind_dpad_gamepad(0, 0, RENDER_DPAD_LEFT, 2, DPAD_LEFT); | |
1134 bind_dpad_gamepad(0, 0, RENDER_DPAD_RIGHT, 2, DPAD_RIGHT); | |
1135 bind_button_gamepad(0, 0, 2, BUTTON_A); | |
1136 bind_button_gamepad(0, 1, 2, BUTTON_B); | |
1137 bind_button_gamepad(0, 2, 2, BUTTON_C); | |
1138 bind_button_gamepad(0, 3, 2, BUTTON_X); | |
1139 bind_button_gamepad(0, 4, 2, BUTTON_Y); | |
1140 bind_button_gamepad(0, 5, 2, BUTTON_Z); | |
1141 bind_button_gamepad(0, 6, 2, BUTTON_START); | |
1142 bind_button_gamepad(0, 7, 2, BUTTON_MODE); | |
1143 } | 783 } |
1144 | 784 |
1145 typedef struct bp_def { | 785 typedef struct bp_def { |
1146 struct bp_def * next; | 786 struct bp_def * next; |
1147 uint32_t address; | 787 uint32_t address; |
2129 z80_context z_context; | 1769 z80_context z_context; |
2130 x86_z80_options z_opts; | 1770 x86_z80_options z_opts; |
2131 init_x86_z80_opts(&z_opts); | 1771 init_x86_z80_opts(&z_opts); |
2132 init_z80_context(&z_context, &z_opts); | 1772 init_z80_context(&z_context, &z_opts); |
2133 | 1773 |
2134 genesis_context gen; | 1774 genesis_context gen; |
1775 memset(&gen, 0, sizeof(gen)); | |
2135 | 1776 |
2136 z_context.system = &gen; | 1777 z_context.system = &gen; |
2137 z_context.mem_pointers[0] = z80_ram; | 1778 z_context.mem_pointers[0] = z80_ram; |
2138 z_context.sync_cycle = z_context.target_cycle = mclks_per_frame/MCLKS_PER_Z80; | 1779 z_context.sync_cycle = z_context.target_cycle = mclks_per_frame/MCLKS_PER_Z80; |
2139 z_context.int_cycle = CYCLE_NEVER; | 1780 z_context.int_cycle = CYCLE_NEVER; |