diff --git a/Makefile.common b/Makefile.common
index 691851b525..65db082a1c 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -1272,7 +1272,9 @@ ifeq ($(HAVE_COCOA),1)
endif
ifneq ($(findstring DOS,$(OS)),)
- OBJ += gfx/drivers/vga_gfx.o gfx/drivers_font/vga_font.o
+ OBJ += gfx/drivers/vga_gfx.o gfx/drivers_font/vga_font.o \
+ input/drivers/dos_input.o input/drivers_joypad/dos_joypad.o \
+ frontend/drivers/platform_dos.o
ifeq ($(HAVE_MENU_COMMON), 1)
OBJ += menu/drivers_display/menu_display_vga.o
diff --git a/config.def.h b/config.def.h
index 8483c0b356..4be7b53a28 100644
--- a/config.def.h
+++ b/config.def.h
@@ -112,6 +112,7 @@ enum input_driver_enum
INPUT_COCOA,
INPUT_QNX,
INPUT_RWEBINPUT,
+ INPUT_DOS,
INPUT_NULL
};
@@ -129,6 +130,7 @@ enum joypad_driver_enum
JOYPAD_LINUXRAW,
JOYPAD_ANDROID,
JOYPAD_SDL,
+ JOYPAD_DOS,
JOYPAD_HID,
JOYPAD_QNX,
JOYPAD_NULL
@@ -320,6 +322,8 @@ enum record_driver_enum
#define INPUT_DEFAULT_DRIVER INPUT_SDL
#elif defined(HAVE_SDL2)
#define INPUT_DEFAULT_DRIVER INPUT_SDL2
+#elif defined(DJGPP)
+#define INPUT_DEFAULT_DRIVER INPUT_DOS
#else
#define INPUT_DEFAULT_DRIVER INPUT_NULL
#endif
@@ -348,6 +352,8 @@ enum record_driver_enum
#define JOYPAD_DEFAULT_DRIVER JOYPAD_ANDROID
#elif defined(HAVE_SDL) || defined(HAVE_SDL2)
#define JOYPAD_DEFAULT_DRIVER JOYPAD_SDL
+#elif defined(DJGPP)
+#define JOYPAD_DEFAULT_DRIVER JOYPAD_DOS
#elif defined(HAVE_HID)
#define JOYPAD_DEFAULT_DRIVER JOYPAD_HID
#elif defined(__QNX__)
diff --git a/configuration.c b/configuration.c
index ed64f08c65..c1645ebd93 100644
--- a/configuration.c
+++ b/configuration.c
@@ -376,6 +376,8 @@ const char *config_get_default_input(void)
return "qnx_input";
case INPUT_RWEBINPUT:
return "rwebinput";
+ case INPUT_DOS:
+ return "dos";
case INPUT_NULL:
break;
}
@@ -432,6 +434,8 @@ const char *config_get_default_joypad(void)
return "hid";
case JOYPAD_QNX:
return "qnx";
+ case JOYPAD_DOS:
+ return "dos";
case JOYPAD_NULL:
break;
}
diff --git a/frontend/drivers/platform_dos.c b/frontend/drivers/platform_dos.c
new file mode 100644
index 0000000000..e7c0af7e14
--- /dev/null
+++ b/frontend/drivers/platform_dos.c
@@ -0,0 +1,72 @@
+/* RetroArch - A frontend for libretro.
+ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
+ * Copyright (C) 2011-2017 - Daniel De Matteis
+ * Copyright (C) 2016-2017 - Brad Parker
+ *
+ * RetroArch is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ * * You should have received a copy of the GNU General Public License along with RetroArch.
+ * If not, see .
+ */
+
+#include
+#include
+
+#include "../frontend_driver.h"
+
+static void frontend_dos_init(void *data)
+{
+ printf("Loading RetroArch...\n");
+}
+
+static void frontend_dos_shutdown(bool unused)
+{
+ (void)unused;
+}
+
+static int frontend_dos_get_rating(void)
+{
+ return -1;
+}
+
+enum frontend_architecture frontend_dos_get_architecture(void)
+{
+ return FRONTEND_ARCH_X86;
+}
+
+static void frontend_dos_get_env_settings(int *argc, char *argv[],
+ void *data, void *params_data)
+{
+}
+
+frontend_ctx_driver_t frontend_ctx_dos = {
+ frontend_dos_get_env_settings,/* environment_get */
+ frontend_dos_init, /* init */
+ NULL, /* deinit */
+ NULL, /* exitspawn */
+ NULL, /* process_args */
+ NULL, /* exec */
+ NULL, /* set_fork */
+ frontend_dos_shutdown, /* shutdown */
+ NULL, /* get_name */
+ NULL, /* get_os */
+ frontend_dos_get_rating, /* get_rating */
+ NULL, /* load_content */
+ frontend_dos_get_architecture,/* get_architecture */
+ NULL, /* get_powerstate */
+ NULL, /* parse_drive_list */
+ NULL, /* get_mem_total */
+ NULL, /* get_mem_free */
+ NULL, /* install_signal_handler */
+ NULL, /* get_sighandler_state */
+ NULL, /* set_sighandler_state */
+ NULL, /* destroy_sighandler_state */
+ NULL, /* attach_console */
+ NULL, /* detach_console */
+ "dos",
+};
diff --git a/frontend/frontend_driver.c b/frontend/frontend_driver.c
index 88475d3f7d..d99005b887 100644
--- a/frontend/frontend_driver.c
+++ b/frontend/frontend_driver.c
@@ -63,6 +63,9 @@ static frontend_ctx_driver_t *frontend_ctx_drivers[] = {
#endif
#ifdef XENON
&frontend_ctx_xenon,
+#endif
+#ifdef DJGPP
+ &frontend_ctx_dos,
#endif
&frontend_ctx_null,
NULL
diff --git a/frontend/frontend_driver.h b/frontend/frontend_driver.h
index 776fa17de6..14193468d4 100644
--- a/frontend/frontend_driver.h
+++ b/frontend/frontend_driver.h
@@ -104,6 +104,7 @@ extern frontend_ctx_driver_t frontend_ctx_ctr;
extern frontend_ctx_driver_t frontend_ctx_win32;
extern frontend_ctx_driver_t frontend_ctx_xenon;
extern frontend_ctx_driver_t frontend_ctx_emscripten;
+extern frontend_ctx_driver_t frontend_ctx_dos;
extern frontend_ctx_driver_t frontend_ctx_null;
/**
diff --git a/griffin/griffin.c b/griffin/griffin.c
index c2f8b31a49..c24ac256a9 100644
--- a/griffin/griffin.c
+++ b/griffin/griffin.c
@@ -354,6 +354,8 @@ VIDEO DRIVER
#include "../gfx/drivers/ctr_gfx.c"
#elif defined(XENON)
#include "../gfx/drivers/xenon360_gfx.c"
+#elif defined(DJGPP)
+#include "../gfx/drivers/vga_gfx.c"
#endif
#include "../gfx/drivers/nullgfx.c"
@@ -466,6 +468,9 @@ INPUT
#include "../input/drivers_joypad/qnx_joypad.c"
#elif defined(EMSCRIPTEN)
#include "../input/drivers/rwebinput_input.c"
+#elif defined(DJGPP)
+#include "../input/drivers/dos_input.c"
+#include "../input/drivers_joypad/dos_joypad.c"
#endif
#ifdef HAVE_DINPUT
@@ -788,6 +793,8 @@ FRONTEND
#include "../frontend/drivers/platform_linux.c"
#elif defined(BSD) && !defined(__MACH__)
#include "../frontend/drivers/platform_bsd.c"
+#elif defined(DJGPP)
+#include "../frontend/drivers/platform_dos.c"
#endif
#include "../frontend/drivers/platform_null.c"
diff --git a/input/drivers/dos_input.c b/input/drivers/dos_input.c
new file mode 100644
index 0000000000..e9b65ad98d
--- /dev/null
+++ b/input/drivers/dos_input.c
@@ -0,0 +1,137 @@
+/* RetroArch - A frontend for libretro.
+ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
+ * Copyright (C) 2011-2017 - Daniel De Matteis
+ *
+ * RetroArch is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with RetroArch.
+ * If not, see .
+ */
+
+#include
+
+#include "../input_driver.h"
+#include "../input_joypad_driver.h"
+
+typedef struct dos_input
+{
+ const input_device_driver_t *joypad;
+ unsigned char normal_keys[256];
+ unsigned char extended_keys[256];
+} dos_input_t;
+
+static void dos_input_poll(void *data)
+{
+ dos_input_t *dos = (dos_input_t*)data;
+
+ if (dos->joypad)
+ dos->joypad->poll();
+}
+
+static int16_t dos_input_state(void *data,
+ rarch_joypad_info_t joypad_info,
+ const struct retro_keybind **binds,
+ unsigned port, unsigned device,
+ unsigned idx, unsigned id)
+{
+ dos_input_t *dos = (dos_input_t*)data;
+
+ if (port > 0)
+ return 0;
+
+ switch (device)
+ {
+ case RETRO_DEVICE_JOYPAD:
+ return input_joypad_pressed(dos->joypad, joypad_info, port, binds[port], id);
+ }
+
+ return 0;
+}
+
+static void dos_input_free_input(void *data)
+{
+ dos_input_t *dos = (dos_input_t*)data;
+
+ if (dos && dos->joypad)
+ dos->joypad->destroy();
+
+ if (data)
+ free(data);
+}
+
+static void* dos_input_init(const char *joypad_driver)
+{
+ dos_input_t *dos = (dos_input_t*)calloc(1, sizeof(*dos));
+
+ if (!dos)
+ return NULL;
+
+ dos->joypad = input_joypad_init_driver(joypad_driver, dos);
+
+ return dos;
+}
+
+static bool dos_input_meta_key_pressed(void *data, int key)
+{
+ return false;
+}
+
+static uint64_t dos_input_get_capabilities(void *data)
+{
+ uint64_t caps = 0;
+
+ caps |= UINT64_C(1) << RETRO_DEVICE_JOYPAD;
+ caps |= UINT64_C(1) << RETRO_DEVICE_KEYBOARD;
+
+ return caps;
+}
+
+static const input_device_driver_t *dos_input_get_joypad_driver(void *data)
+{
+ dos_input_t *dos = (dos_input_t*)data;
+ if (dos)
+ return dos->joypad;
+ return NULL;
+}
+
+static void dos_input_grab_mouse(void *data, bool state)
+{
+ (void)data;
+ (void)state;
+}
+
+static bool dos_input_set_rumble(void *data, unsigned port,
+ enum retro_rumble_effect effect, uint16_t strength)
+{
+ (void)data;
+ (void)port;
+ (void)effect;
+ (void)strength;
+
+ return false;
+}
+
+input_driver_t input_dos = {
+ dos_input_init,
+ dos_input_poll,
+ dos_input_state,
+ dos_input_meta_key_pressed,
+ dos_input_free_input,
+ NULL,
+ NULL,
+ dos_input_get_capabilities,
+ "dos",
+ dos_input_grab_mouse,
+ NULL,
+ dos_input_set_rumble,
+ dos_input_get_joypad_driver,
+ NULL,
+ NULL,
+ NULL
+};
diff --git a/input/drivers_joypad/ctr_joypad.c b/input/drivers_joypad/ctr_joypad.c
index a1022a6b2f..96dae5b509 100644
--- a/input/drivers_joypad/ctr_joypad.c
+++ b/input/drivers_joypad/ctr_joypad.c
@@ -184,6 +184,7 @@ static bool ctr_joypad_query_pad(unsigned pad)
static void ctr_joypad_destroy(void)
{
+ unhook_keyb_int();
}
input_device_driver_t ctr_joypad = {
diff --git a/input/drivers_joypad/dos_joypad.c b/input/drivers_joypad/dos_joypad.c
new file mode 100644
index 0000000000..af6f202fb8
--- /dev/null
+++ b/input/drivers_joypad/dos_joypad.c
@@ -0,0 +1,268 @@
+/* RetroArch - A frontend for libretro.
+ * Copyright (C) 2011-2017 - Daniel De Matteis
+ * Copyright (C) 2016-2017 - Brad Parker
+ *
+ * RetroArch is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with RetroArch.
+ * If not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+
+#include "../input_joypad_driver.h"
+#include "../input_driver.h"
+#include "../input_config.h"
+#include "../../tasks/tasks_internal.h"
+
+#define MAX_PADS 1
+
+#define END_FUNC(x) static void x##_End() { }
+
+#define LOCK_VAR(x) LockData((void*)&x, sizeof(x))
+#define LOCK_FUNC(x) LockCode(x, (int)x##_End - (int)x)
+
+static uint64_t dos_key_state[MAX_PADS];
+
+static unsigned char normal_keys[256];
+static unsigned char extended_keys[256];
+
+static _go32_dpmi_seginfo old_kbd_int;
+static _go32_dpmi_seginfo kbd_int;
+
+int LockData(void *a, int size)
+{
+ uint32_t baseaddr;
+ __dpmi_meminfo region;
+
+ if (__dpmi_get_segment_base_address(_my_ds(), &baseaddr) == -1)
+ return -1;
+
+ region.handle = 0;
+ region.size = size;
+ region.address = baseaddr + (uint32_t)a;
+
+ if (__dpmi_lock_linear_region(®ion) == -1)
+ return -1;
+
+ return 0;
+}
+
+int LockCode(void *a, int size)
+{
+ uint32_t baseaddr;
+ __dpmi_meminfo region;
+
+ if (__dpmi_get_segment_base_address(_my_cs(), &baseaddr) == -1)
+ return (-1);
+
+ region.handle = 0;
+ region.size = size;
+ region.address = baseaddr + (uint32_t)a;
+
+ if (__dpmi_lock_linear_region(®ion) == -1)
+ return (-1);
+
+ return 0;
+}
+
+static void keyb_int(void)
+{
+ static unsigned char buffer;
+ unsigned char rawcode;
+ unsigned char make_break;
+ int scancode;
+
+ rawcode = inp(0x60); /* read scancode from keyboard controller */
+ make_break = !(rawcode & 0x80); /* bit 7: 0 = make, 1 = break */
+ scancode = rawcode & 0x7F;
+
+ if (buffer == 0xE0)
+ {
+ /* second byte of an extended key */
+ if (scancode < 0x60)
+ {
+ extended_keys[scancode] = make_break;
+ }
+
+ buffer = 0;
+ }
+ else if (buffer >= 0xE1 && buffer <= 0xE2)
+ {
+ buffer = 0; /* ingore these extended keys */
+ }
+ else if (rawcode >= 0xE0 && rawcode <= 0xE2)
+ {
+ buffer = rawcode; /* first byte of an extended key */
+ }
+ else if (scancode < 0x60)
+ {
+ normal_keys[scancode] = make_break;
+ }
+
+ outp(0x20, 0x20); /* must send EOI to finish interrupt */
+}
+END_FUNC(keyb_int)
+
+/*static void free_keyb_buf()
+{
+ *(char*)(0x0040001A) = 0x20;
+ *(char*)(0x0040001C) = 0x20;
+}*/
+
+static void hook_keyb_int(void)
+{
+ _go32_dpmi_get_protected_mode_interrupt_vector(9, &old_kbd_int);
+
+ memset(&kbd_int, 0, sizeof(kbd_int));
+
+ LOCK_FUNC(keyb_int);
+ LOCK_VAR(normal_keys);
+ LOCK_VAR(extended_keys);
+
+ kbd_int.pm_selector = _go32_my_cs();
+ kbd_int.pm_offset = (uint32_t)&keyb_int;
+
+ _go32_dpmi_allocate_iret_wrapper(&kbd_int);
+
+ _go32_dpmi_set_protected_mode_interrupt_vector(9, &kbd_int);
+}
+
+static void unhook_keyb_int(void)
+{
+ if (old_kbd_int.pm_offset)
+ {
+ _go32_dpmi_set_protected_mode_interrupt_vector(9, &old_kbd_int);
+ _go32_dpmi_free_iret_wrapper(&kbd_int);
+
+ memset(&old_kbd_int, 0, sizeof(old_kbd_int));
+ }
+}
+
+static const char *dos_joypad_name(unsigned pad)
+{
+ return "DOS Controller";
+}
+
+static void dos_joypad_autodetect_add(unsigned autoconf_pad)
+{
+ if (!input_autoconfigure_connect(
+ dos_joypad_name(autoconf_pad),
+ NULL,
+ dos_joypad.ident,
+ autoconf_pad,
+ 0,
+ 0
+ ))
+ input_config_set_device_name(autoconf_pad, dos_joypad_name(autoconf_pad));
+}
+
+static bool dos_joypad_init(void *data)
+{
+ memset(dos_key_state, 0, sizeof(dos_key_state));
+
+ hook_keyb_int();
+
+ dos_joypad_autodetect_add(0);
+
+ (void)data;
+
+ return true;
+}
+
+static bool dos_joypad_button(unsigned port_num, uint16_t key)
+{
+ if (port_num >= MAX_PADS)
+ return false;
+
+ return (dos_key_state[port_num] & (UINT64_C(1) << key));
+}
+
+static uint64_t dos_joypad_get_buttons(unsigned port_num)
+{
+ if (port_num >= MAX_PADS)
+ return 0;
+ return dos_key_state[port_num];
+}
+
+static void dos_joypad_poll(void)
+{
+ uint32_t i;
+
+ for (i = 0; i < MAX_PADS; i++)
+ {
+ uint64_t *cur_state = &dos_key_state[i];
+
+ *cur_state = 0;
+ *cur_state |= extended_keys[75] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT : 0;
+ *cur_state |= extended_keys[77] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT : 0;
+ *cur_state |= extended_keys[72] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP : 0;
+ *cur_state |= extended_keys[80] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN : 0;
+ *cur_state |= normal_keys[28] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_START : 0; /* ENTER */
+ *cur_state |= normal_keys[54] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_SELECT : 0; /* RSHIFT */
+ *cur_state |= normal_keys[44] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_B : 0; /* Z */
+ *cur_state |= normal_keys[45] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_A : 0; /* X */
+ *cur_state |= normal_keys[30] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_Y : 0; /* A */
+ *cur_state |= normal_keys[31] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_X : 0; /* S */
+ *cur_state |= normal_keys[1] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_X : 0; /* S */
+
+ /**cur_state |= pad.b ? RETRO_DEVICE_ID_JOYPAD_A : 0;
+ *cur_state |= pad.a ? RETRO_DEVICE_ID_JOYPAD_B : 0;
+ *cur_state |= pad.y ? RETRO_DEVICE_ID_JOYPAD_X : 0;
+ *cur_state |= pad.x ? RETRO_DEVICE_ID_JOYPAD_Y : 0;
+ *cur_state |= pad.left ? RETRO_DEVICE_ID_JOYPAD_LEFT : 0;
+ *cur_state |= pad.right ? RETRO_DEVICE_ID_JOYPAD_RIGHT : 0;
+ *cur_state |= pad.up ? RETRO_DEVICE_ID_JOYPAD_UP : 0;
+ *cur_state |= pad.start ? RETRO_DEVICE_ID_JOYPAD_START : 0;
+ *cur_state |= pad.back ? RETRO_DEVICE_ID_JOYPAD_SELECT : 0;
+ *cur_state |= pad.lt ? RETRO_DEVICE_ID_JOYPAD_L : 0;
+ *cur_state |= pad.rt ? RETRO_DEVICE_ID_JOYPAD_R : 0;*/
+ }
+
+ /*free_keyb_buf();*/
+}
+
+static bool dos_joypad_query_pad(unsigned pad)
+{
+ return pad < MAX_USERS && dos_key_state[pad];
+}
+
+static int16_t dos_joypad_axis(unsigned port_num, uint32_t joyaxis)
+{
+ return 0;
+}
+
+static void dos_joypad_destroy(void)
+{
+ unhook_keyb_int();
+}
+
+input_device_driver_t dos_joypad = {
+ dos_joypad_init,
+ dos_joypad_query_pad,
+ dos_joypad_destroy,
+ dos_joypad_button,
+ dos_joypad_get_buttons,
+ dos_joypad_axis,
+ dos_joypad_poll,
+ NULL,
+ dos_joypad_name,
+ "dos",
+};
diff --git a/input/input_autodetect_builtin.c b/input/input_autodetect_builtin.c
index 579aad425b..0e0ea95ece 100644
--- a/input/input_autodetect_builtin.c
+++ b/input/input_autodetect_builtin.c
@@ -195,6 +195,30 @@ DECL_AXIS(r_x_minus, -2) \
DECL_AXIS(r_y_plus, -3) \
DECL_AXIS(r_y_minus, +3)
+#define DOSINPUT_DEFAULT_BINDS \
+DECL_BTN(a, 8) \
+DECL_BTN(b, 0) \
+DECL_BTN(x, 9) \
+DECL_BTN(y, 1) \
+DECL_BTN(start, 3) \
+DECL_BTN(select, 2) \
+DECL_BTN(up, 4) \
+DECL_BTN(down, 5) \
+DECL_BTN(left, 6) \
+DECL_BTN(right, 7) \
+DECL_BTN(l, 10) \
+DECL_BTN(r, 11) \
+DECL_BTN(l2, 12) \
+DECL_BTN(r2, 13) \
+DECL_AXIS(l_x_plus, +0) \
+DECL_AXIS(l_x_minus, -0) \
+DECL_AXIS(l_y_plus, +1) \
+DECL_AXIS(l_y_minus, -1) \
+DECL_AXIS(r_x_plus, +2) \
+DECL_AXIS(r_x_minus, -2) \
+DECL_AXIS(r_y_plus, -3) \
+DECL_AXIS(r_y_minus, +3)
+
#ifdef WIIU
#define WIIUINPUT_GAMEPAD_DEFAULT_BINDS \
@@ -503,6 +527,9 @@ const char* const input_builtin_autoconfs[] =
#ifdef _3DS
DECL_AUTOCONF_DEVICE("3DS Controller", "ctr", CTRINPUT_DEFAULT_BINDS),
#endif
+#ifdef DJGPP
+ DECL_AUTOCONF_DEVICE("DOS Controller", "dos", DOSINPUT_DEFAULT_BINDS),
+#endif
#ifdef GEKKO
DECL_AUTOCONF_DEVICE("GameCube Controller", "gx", GXINPUT_GAMECUBE_DEFAULT_BINDS),
#ifdef HW_RVL
diff --git a/input/input_driver.c b/input/input_driver.c
index 4997651cb2..518f6df1dd 100644
--- a/input/input_driver.c
+++ b/input/input_driver.c
@@ -89,6 +89,9 @@ static const input_driver_t *input_drivers[] = {
#endif
#ifdef EMSCRIPTEN
&input_rwebinput,
+#endif
+#ifdef DJGPP
+ &input_dos,
#endif
&input_null,
NULL,
diff --git a/input/input_driver.h b/input/input_driver.h
index 959d0296a4..3aab8dd92b 100644
--- a/input/input_driver.h
+++ b/input/input_driver.h
@@ -327,6 +327,7 @@ extern input_driver_t input_udev;
extern input_driver_t input_cocoa;
extern input_driver_t input_qnx;
extern input_driver_t input_rwebinput;
+extern input_driver_t input_dos;
extern input_driver_t input_null;
RETRO_END_DECLS
diff --git a/input/input_joypad_driver.c b/input/input_joypad_driver.c
index b868f7e01d..0ac05121f1 100644
--- a/input/input_joypad_driver.c
+++ b/input/input_joypad_driver.c
@@ -78,6 +78,9 @@ static input_device_driver_t *joypad_drivers[] = {
#ifdef HAVE_MFI
&mfi_joypad,
#endif
+#ifdef DJGPP
+ &dos_joypad,
+#endif
#ifdef HAVE_HID
&hid_joypad,
#endif
diff --git a/input/input_joypad_driver.h b/input/input_joypad_driver.h
index fb897426ea..d9f8382f1a 100644
--- a/input/input_joypad_driver.h
+++ b/input/input_joypad_driver.h
@@ -236,6 +236,7 @@ extern input_device_driver_t android_joypad;
extern input_device_driver_t qnx_joypad;
extern input_device_driver_t null_joypad;
extern input_device_driver_t mfi_joypad;
+extern input_device_driver_t dos_joypad;
RETRO_END_DECLS