diff --git a/src/conio/Common.gmake b/src/conio/Common.gmake
index 8c21413b90cdec0431bc1d9c0d13fca202c1f1df..510992f5299126f2f60b732c96bc924b3e296588 100644
--- a/src/conio/Common.gmake
+++ b/src/conio/Common.gmake
@@ -76,6 +76,10 @@ else
  endif
 endif
 
+ifdef WITH_RETRO
+ CIOLIB-MT_CFLAGS += -DWITH_RETRO
+endif
+
 ifndef NO_X
  ifeq ($(shell pkg-config xrender --exists && echo YES), YES)
   CIOLIB-MT_CFLAGS += $(shell pkg-config xrender --cflags)
diff --git a/src/conio/GNUmakefile b/src/conio/GNUmakefile
index e08470b16296e277710aa728b532bfbb3463e898..101026b47acc6cd5ab2ae4b0e73374bdeb371587 100644
--- a/src/conio/GNUmakefile
+++ b/src/conio/GNUmakefile
@@ -28,6 +28,11 @@ ifdef WITH_SDL
  OBJS	+=      $(MTOBJODIR)$(DIRSEP)sdlfuncs$(OFILE)
 endif
 
+ifdef WITH_RETRO
+ NEED_BITMAP := 1
+ OBJS	+=	$(MTOBJODIR)$(DIRSEP)retro$(OFILE)
+endif
+
 ifeq ($(os),netbsd)
  ifndef USE_SYSTEM_CURSES
   CFLAGS	+=	-DN_CURSES_LIB
diff --git a/src/conio/ciolib.c b/src/conio/ciolib.c
index 50e18a3dfed30e6b3184243b36f1cac0c1fabd23..beab8f26c2046c79adaa05ccc55bb8c15c276076 100644
--- a/src/conio/ciolib.c
+++ b/src/conio/ciolib.c
@@ -52,6 +52,9 @@
  #include "curs_cio.h"
  #undef getch
 #endif
+#ifdef WITH_RETRO
+ #include "retro.h"
+#endif
 
 #include "bitmap_con.h"
 #include "ansi_cio.h"
@@ -435,6 +438,44 @@ static int try_conio_init(int mode)
 }
 #endif
 
+#ifdef WITH_RETRO
+static int try_retro_init(int mode)
+{
+	cio_api.mode=CIOLIB_MODE_RETRO;
+	cio_api.mouse=1;
+	cio_api.puttext=bitmap_puttext;
+	cio_api.vmem_puttext=bitmap_vmem_puttext;
+	cio_api.vmem_gettext=bitmap_vmem_gettext;
+	cio_api.gotoxy=bitmap_gotoxy;
+	cio_api.setcursortype=bitmap_setcursortype;
+	cio_api.setfont=bitmap_setfont;
+	cio_api.getfont=bitmap_getfont;
+	cio_api.loadfont=bitmap_loadfont;
+	cio_api.beep=retro_beep;
+	cio_api.movetext=bitmap_movetext;
+	cio_api.clreol=bitmap_clreol;
+	cio_api.clrscr=bitmap_clrscr;
+	cio_api.getcustomcursor=bitmap_getcustomcursor;
+	cio_api.setcustomcursor=bitmap_setcustomcursor;
+	cio_api.getvideoflags=bitmap_getvideoflags;
+	cio_api.setvideoflags=bitmap_setvideoflags;
+
+	cio_api.kbhit=retro_kbhit;
+	cio_api.getch=retro_getch;
+	cio_api.textmode=retro_textmode;
+	cio_api.setpalette=bitmap_setpalette;
+	cio_api.attr2palette=bitmap_attr2palette;
+	cio_api.setpixel=bitmap_setpixel;
+	cio_api.getpixels=bitmap_getpixels;
+	cio_api.setpixels=bitmap_setpixels;
+	cio_api.get_modepalette=bitmap_get_modepalette;
+	cio_api.set_modepalette=bitmap_set_modepalette;
+	cio_api.map_rgb = bitmap_map_rgb;
+	cio_api.replace_font = bitmap_replace_font;
+	return(1);
+}
+#endif
+
 /* Optional */
 CIOLIBEXPORT void suspendciolib(void)
 {
@@ -457,6 +498,13 @@ CIOLIBEXPORT int initciolib(int mode)
 			return(0);
 	}
 
+#ifdef WITH_RETRO
+	if (retro_set) {
+		if (!try_retro_init(mode))
+			return -1;
+	}
+	else {
+#endif
 	switch(mode) {
 		case CIOLIB_MODE_AUTO:
 #ifndef NO_X
@@ -519,6 +567,9 @@ CIOLIBEXPORT int initciolib(int mode)
 		fprintf(stderr,"CIOLIB initialization failed!\n");
 		return(-1);
 	}
+#ifdef WITH_RETRO
+	}
+#endif
 
 	initialized=1;
 	cio_textinfo.winleft=1;
diff --git a/src/conio/ciolib.h b/src/conio/ciolib.h
index e0bc6ad5f550583c69ef5dc80f116826c03f5a15..4f5239d8cbe4af08c25d57e73264d175a7304d49 100644
--- a/src/conio/ciolib.h
+++ b/src/conio/ciolib.h
@@ -67,6 +67,7 @@ enum {
 	,CIOLIB_MODE_SDL_FULLSCREEN
 	,CIOLIB_MODE_GDI
 	,CIOLIB_MODE_GDI_FULLSCREEN
+	,CIOLIB_MODE_RETRO
 };
 
 enum ciolib_mouse_ptr {
diff --git a/src/conio/retro.c b/src/conio/retro.c
new file mode 100644
index 0000000000000000000000000000000000000000..58bedc9dcdb778fe615291e99b799f5e318e32f4
--- /dev/null
+++ b/src/conio/retro.c
@@ -0,0 +1,276 @@
+#include <string.h>
+
+#define BITMAP_CIOLIB_DRIVER
+#include "bitmap_con.h"
+#include "ciolib.h"
+
+#include "genwrap.h"
+
+#include "libretro.h"
+
+#define KEYBUFSIZE 32
+static uint16_t keybuf[KEYBUFSIZE];
+static size_t keybufremove = 0;
+static size_t keybufadd = 0;
+static size_t keybuffill = 0;
+
+RETRO_CALLCONV void
+retro_keyboard(bool down, unsigned keycode, uint32_t character, uint16_t key_modifiers)
+{
+	fprintf(stderr, "%d, %u, %" PRIu32 ", %" PRIu16 "\n", down, keycode, character, key_modifiers);
+	if (down) {
+		// TODO: Map properly...
+		if (keybuffill < KEYBUFSIZE) {
+			keybuf[keybufadd++] = keycode;
+			keybuffill++;
+		}
+	}
+}
+
+static retro_environment_t env_cb;
+static retro_video_refresh_t video_cb;
+static retro_audio_sample_t audio_cb;
+static retro_audio_sample_batch_t audio_batch_cb;
+static retro_input_poll_t input_poll_cb;
+static retro_input_state_t input_state_cb;
+static enum retro_pixel_format rpf = RETRO_PIXEL_FORMAT_XRGB8888;
+static struct retro_keyboard_callback rkc = {
+	.callback = retro_keyboard
+};
+static bool no_game = true;
+bool retro_set = false;
+
+int main(int argc, char **argv);
+static void
+runmain(void *arg)
+{
+	static char *args[] = {
+		"syncterm"
+	};
+	main(0, args);
+}
+
+struct rectlist *last_rect = NULL;
+
+void
+retro_drawrect(struct rectlist *data)
+{
+	if (last_rect != NULL)
+		bitmap_drv_free_rect(last_rect);
+	last_rect = data;
+}
+
+void
+retro_flush(void)
+{
+}
+
+RETRO_API void
+retro_init(void)
+{
+	_beginthread(runmain, 0, NULL);
+	bitmap_drv_init(retro_drawrect, retro_flush);
+}
+
+RETRO_API void
+retro_deinit(void)
+{
+	/*
+	 * "The core must release all of its allocated resources before this function returns."
+	 * Heh heh heh... sure thing bud.
+	 */
+	for (;;)
+		SLEEP(1000);
+}
+
+RETRO_API unsigned
+retro_api_version(void)
+{
+	return RETRO_API_VERSION;
+}
+
+
+RETRO_API void
+retro_set_controller_port_device(unsigned port, unsigned device)
+{
+}
+
+RETRO_API void
+retro_get_system_info(struct retro_system_info *info)
+{
+	memset(info, 0, sizeof(struct retro_system_info));
+	info->library_name = ciolib_initial_program_class;
+	info->library_version = "0.1";
+}
+
+RETRO_API void
+retro_get_system_av_info(struct retro_system_av_info* info)
+{
+	memset(info, 0, sizeof(struct retro_system_av_info));
+	info->timing.fps = 60.0f;
+	info->timing.sample_rate = 44100; // standard audio sample rate
+	info->geometry.base_width = 640;
+	info->geometry.base_height = 400;
+	info->geometry.max_width = 640;
+	info->geometry.max_height = 400;
+	info->geometry.aspect_ratio = (float)4 / (float)3;
+}
+
+RETRO_API void
+retro_set_environment(retro_environment_t cb)
+{
+	env_cb = cb;
+	retro_set = true;
+	cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &rpf);
+	cb(RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK, &rkc);
+	cb(RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME, &no_game);
+	// RETRO_ENVIRONMENT_SET_FRAME_TIME_CALLBACK
+	// RETRO_ENVIRONMENT_SET_AUDIO_CALLBACK
+}
+
+RETRO_API void
+retro_set_audio_sample(retro_audio_sample_t cb)
+{
+	audio_cb = cb;
+}
+
+RETRO_API void
+retro_set_audio_sample_batch(retro_audio_sample_batch_t cb)
+{
+	audio_batch_cb = cb;
+}
+
+RETRO_API void
+retro_set_input_poll(retro_input_poll_t cb)
+{
+	input_poll_cb = cb;
+}
+
+RETRO_API void
+retro_set_input_state(retro_input_state_t cb)
+{
+	input_state_cb = cb;
+}
+
+RETRO_API void
+retro_set_video_refresh(retro_video_refresh_t cb)
+{
+	video_cb = cb;
+}
+
+RETRO_API void
+retro_reset(void)
+{
+}
+
+RETRO_API void
+audio_callback(void)
+{
+}
+
+RETRO_API void
+retro_run(void)
+{
+	video_cb(last_rect->data, last_rect->rect.width, last_rect->rect.height, last_rect->rect.width * sizeof(uint32_t));
+}
+
+RETRO_API size_t
+retro_serialize_size(void)
+{
+	return 0;
+}
+
+RETRO_API bool
+retro_serialize(void *data_, size_t size)
+{
+	return false;
+}
+
+RETRO_API bool
+retro_unserialize(const void *data_, size_t size)
+{
+	return false;
+}
+
+RETRO_API void
+retro_cheat_reset(void)
+{
+}
+
+RETRO_API void
+retro_cheat_set(unsigned index, bool enabled, const char *code)
+{
+}
+
+RETRO_API bool
+retro_load_game(const struct retro_game_info *info)
+{
+	return true;
+}
+
+RETRO_API bool
+retro_load_game_special(unsigned type, const struct retro_game_info *info, size_t num)
+{
+	return false;
+}
+
+RETRO_API void
+retro_unload_game(void)
+{
+}
+
+RETRO_API unsigned
+retro_get_region(void)
+{
+	return RETRO_REGION_NTSC;
+}
+
+RETRO_API void *
+retro_get_memory_data(unsigned id)
+{
+   return NULL;
+}
+
+RETRO_API size_t
+retro_get_memory_size(unsigned id)
+{
+   return 0;
+}
+
+////////
+
+void
+retro_beep(void)
+{
+}
+
+int
+retro_kbhit(void)
+{
+	return keybuffill;
+}
+
+int
+retro_getch(void)
+{
+	if (keybuffill == 0)
+		return 0;
+	int ret = keybuf[keybufremove];
+	keybufremove++;
+	keybuffill--;
+	return ret;
+}
+
+void
+retro_textmode(int mode)
+{
+	assert_rwlock_wrlock(&vstatlock);
+	bitmap_drv_init_mode(mode, NULL, NULL, 0, 0);
+	assert_rwlock_unlock(&vstatlock);
+	bitmap_drv_request_pixels();
+
+	return;
+}
+
+////////
+
diff --git a/src/conio/retro.h b/src/conio/retro.h
new file mode 100644
index 0000000000000000000000000000000000000000..7b70c3f55edef0a649b71193f7d741ace88a69c8
--- /dev/null
+++ b/src/conio/retro.h
@@ -0,0 +1,11 @@
+#ifndef RETRO_H
+#define RETRO_H
+
+extern bool retro_set;
+
+void retro_beep(void);
+int retro_kbhit(void);
+int retro_getch(void);
+void retro_textmode(int);
+
+#endif
diff --git a/src/syncterm/GNUmakefile b/src/syncterm/GNUmakefile
index 1a6e97586b62677eb7b495842d7ecb94c9a22bdd..8b41ce36bbe84ffce58dba11927fb8210b0aebd3 100644
--- a/src/syncterm/GNUmakefile
+++ b/src/syncterm/GNUmakefile
@@ -152,6 +152,10 @@ ifdef win
  EXTRA_LIBS += -luuid
 endif
 
+ifdef WITH_RETRO
+ LDFLAGS += -shared
+endif
+
 $(MTOBJODIR)$(DIRSEP)ciolib_res$(OFILE): ${CIOLIB-MT}
 	cd ${MTOBJODIR} && $(AR) -x ../${CIOLIB-MT} ciolib_res$(OFILE)
 
diff --git a/src/syncterm/ssh.c b/src/syncterm/ssh.c
index cfe0ad8a55e340066c7f8d6617efc475bd87f3bd..60ce1d6c62c70643daacd3efe246ec8b63076989 100644
--- a/src/syncterm/ssh.c
+++ b/src/syncterm/ssh.c
@@ -47,6 +47,7 @@ init_crypt(void)
 {
 	int status;
 
+#ifndef WITH_RETRO
 	status = cryptInit();
 	if (cryptStatusOK(status)) {
 		atexit(exit_crypt);
@@ -54,6 +55,7 @@ init_crypt(void)
 	}
 	if (cryptStatusError(status))
 		cryptlib_error_message(status, "initializing cryptlib");
+#endif
 }
 
 static int