void *handle;
   int (*Init) (Uint32 flags);
   void (*Quit) (void);
-  SDL_Surface *(*SetVideoMode) (int width, int height, int bpp, Uint32 flags);
-  void (*WM_SetCaption) (const char *title, const char *icon);
   int (*ShowCursor) (int toggle);
   int (*LockSurface) (SDL_Surface *surface);
   void (*UnlockSurface) (SDL_Surface *surface);
+#if HAVE_SDL == 1
   void (*GetRGB) (Uint32 pixel, const SDL_PixelFormat * const fmt, Uint8 *r, Uint8 *g, Uint8 *b);
   Uint32 (*MapRGB) (const SDL_PixelFormat * const format, const Uint8 r, const Uint8 g, const Uint8 b);
+  SDL_Surface *(*SetVideoMode) (int width, int height, int bpp, Uint32 flags);
+  void (*WM_SetCaption) (const char *title, const char *icon);
   void (*UpdateRect) (SDL_Surface *screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h);
+#else
+  void (*GetRGB) (Uint32 pixel, const SDL_PixelFormat *fmt, Uint8 *r, Uint8 *g, Uint8 *b);
+  Uint32 (*MapRGB) (const SDL_PixelFormat *format, Uint8 r, Uint8 g, Uint8 b);
+  SDL_Window *(*CreateWindow) (const char *title, int x, int y, int w, int h, Uint32 flags);
+  SDL_Surface *(*GetWindowSurface) (SDL_Window *window);
+  SDL_PixelFormat *(*AllocFormat) (Uint32 pixel_format);
+  int (*UpdateWindowSurfaceRects) (SDL_Window *window, const SDL_Rect *rects, int numrects);
+#endif
 } sdl;
 
 static const char * const sdl_syms[] =
 {
   "SDL_Init",
   "SDL_Quit",
-  "SDL_SetVideoMode",
-  "SDL_WM_SetCaption",
   "SDL_ShowCursor",
   "SDL_LockSurface",
   "SDL_UnlockSurface",
   "SDL_GetRGB",
   "SDL_MapRGB",
+#if HAVE_SDL == 1
+  "SDL_SetVideoMode",
+  "SDL_WM_SetCaption",
   "SDL_UpdateRect",
+#else
+  "SDL_CreateWindow",
+  "SDL_GetWindowSurface",
+  "SDL_AllocFormat",
+  "SDL_UpdateWindowSurfaceRects",
+#endif
 };
 
 struct gui_state {
+#if HAVE_SDL == 2
+  SDL_Window *window;
+#endif
   SDL_Surface *screen;
   const SDL_PixelFormat *format;
   int throttle, throttle_limit;
   enum gui_color color;
+  int bytes_per_pixel;
   int curr_line;
 };
 
+static const char bfin_gui_window_title[] = "Blackfin GNU Simulator";
+
 /* Load the SDL lib on the fly to avoid hard linking against it.  */
 static int
 bfin_gui_sdl_setup (void)
 {
+  static const char libsdl_soname[] =
+#if HAVE_SDL == 1
+      "libSDL-1.2.so.0";
+#else
+      "libSDL2-2.0.so.0";
+#endif
   int i;
   uintptr_t **funcs;
 
   if (sdl.handle)
     return 0;
 
-  sdl.handle = dlopen ("libSDL-1.2.so.0", RTLD_LAZY);
+  sdl.handle = dlopen (libsdl_soname, RTLD_LAZY);
   if (sdl.handle == NULL)
     return -1;
 
   return 0;
 }
 
-static const SDL_PixelFormat *bfin_gui_color_format (enum gui_color color);
+static const SDL_PixelFormat *bfin_gui_color_format (enum gui_color color,
+                                                    int *bytes_per_pixel);
 
 void *
 bfin_gui_setup (void *state, int enabled, int width, int height,
        goto error;
 
       gui->color = color;
-      gui->format = bfin_gui_color_format (gui->color);
+      gui->format = bfin_gui_color_format (gui->color, &gui->bytes_per_pixel);
+#if HAVE_SDL == 1
+      sdl.WM_SetCaption (bfin_gui_window_title, NULL);
       gui->screen = sdl.SetVideoMode (width, height, 32,
                                      SDL_ANYFORMAT|SDL_HWSURFACE);
+#else
+      gui->window = sdl.CreateWindow (
+         bfin_gui_window_title, SDL_WINDOWPOS_CENTERED,
+         SDL_WINDOWPOS_CENTERED, width, height, 0);
+      if (!gui->window)
+       {
+         sdl.Quit();
+         goto error;
+       }
+
+      gui->screen = sdl.GetWindowSurface(gui->window);
+#endif
       if (!gui->screen)
        {
          sdl.Quit();
          goto error;
        }
 
-      sdl.WM_SetCaption ("GDB Blackfin Simulator", NULL);
       sdl.ShowCursor (0);
       gui->curr_line = 0;
       gui->throttle = 0;
 
 static int
 SDL_ConvertBlitLineFrom (const Uint8 *src, const SDL_PixelFormat * const format,
-                        SDL_Surface *dst, int dsty)
+#if HAVE_SDL == 2
+                        SDL_Window *win,
+#endif
+                        SDL_Surface *dst, int dsty, int bytes_per_pixel)
 {
   Uint8 r, g, b;
   Uint32 *pixels;
     {
       /* Exract the packed source pixel; RGB or BGR.  */
       Uint32 pix = 0;
-      for (j = 0; j < format->BytesPerPixel; ++j)
+      for (j = 0; j < bytes_per_pixel; ++j)
        if (format->Rshift)
          pix = (pix << 8) | src[j];
        else
       /* Translate into the screen pixel format.  */
       *pixels++ = sdl.MapRGB (dst->format, r, g, b);
 
-      src += format->BytesPerPixel;
+      src += bytes_per_pixel;
     }
 
   if (SDL_MUSTLOCK (dst))
     sdl.UnlockSurface (dst);
 
+#if HAVE_SDL == 1
   sdl.UpdateRect (dst, 0, dsty, dst->w, 1);
+#else
+  {
+    SDL_Rect rect = {
+      .x = 0,
+      .y = dsty,
+      .w = dst->w,
+      .h = 1,
+    };
+
+    sdl.UpdateWindowSurfaceRects (win, &rect, 1);
+  }
+#endif
 
   return 0;
 }
   if (gui->throttle)
     return 0;
 
-  ret = SDL_ConvertBlitLineFrom (source, gui->format, gui->screen,
-                                gui->curr_line);
+  ret = SDL_ConvertBlitLineFrom (source, gui->format,
+#if HAVE_SDL == 2
+                                gui->window,
+#endif
+                                gui->screen, gui->curr_line,
+                                gui->bytes_per_pixel);
   if (ret)
     return 0;
 
   return nr_bytes;
 }
 
+#if HAVE_SDL == 1
+
 #define FMASK(cnt, shift) (((1 << (cnt)) - 1) << (shift))
 #define _FORMAT(bpp, rcnt, gcnt, bcnt, acnt, rsh, gsh, bsh, ash) \
   NULL, bpp, (bpp)/8, 8-(rcnt), 8-(gcnt), 8-(bcnt), 8-(acnt), rsh, gsh, bsh, ash, \
 {
   FORMAT (5, 6, 5, 0, 11, 5, 0, 0)
 };
+#define SDL_PIXELFORMAT_RGB565 &sdl_rgb_565
+
 static const SDL_PixelFormat sdl_bgr_565 =
 {
   FORMAT (5, 6, 5, 0, 0, 5, 11, 0)
 };
+#define SDL_PIXELFORMAT_BGR565 &sdl_bgr_565
+
 static const SDL_PixelFormat sdl_rgb_888 =
 {
   FORMAT (8, 8, 8, 0, 16, 8, 0, 0)
 };
+#define SDL_PIXELFORMAT_RGB888 &sdl_rgb_888
+
 static const SDL_PixelFormat sdl_bgr_888 =
 {
   FORMAT (8, 8, 8, 0, 0, 8, 16, 0)
 };
+#define SDL_PIXELFORMAT_BGR888 &sdl_bgr_888
+
 static const SDL_PixelFormat sdl_rgba_8888 =
 {
   FORMAT (8, 8, 8, 8, 24, 16, 8, 0)
 };
+#define SDL_PIXELFORMAT_RGBA8888 &sdl_rgba_8888
+
+#endif
 
 static const struct {
   const char *name;
+  /* Since we declare the pixel formats above for SDL 1, we have the bpp
+     setting, but SDL 2 internally uses larger values for its own memory, so
+     we can't assume the Blackfin pixel format sizes always match SDL.  */
+  int bytes_per_pixel;
+#if HAVE_SDL == 1
   const SDL_PixelFormat *format;
+#else
+  Uint32 format;
+#endif
   enum gui_color color;
 } color_spaces[] = {
-  { "rgb565",   &sdl_rgb_565,   GUI_COLOR_RGB_565,   },
-  { "bgr565",   &sdl_bgr_565,   GUI_COLOR_BGR_565,   },
-  { "rgb888",   &sdl_rgb_888,   GUI_COLOR_RGB_888,   },
-  { "bgr888",   &sdl_bgr_888,   GUI_COLOR_BGR_888,   },
-  { "rgba8888", &sdl_rgba_8888, GUI_COLOR_RGBA_8888, },
+  { "rgb565",   2, SDL_PIXELFORMAT_RGB565,   GUI_COLOR_RGB_565,   },
+  { "bgr565",   2, SDL_PIXELFORMAT_BGR565,   GUI_COLOR_BGR_565,   },
+  { "rgb888",   3, SDL_PIXELFORMAT_RGB888,   GUI_COLOR_RGB_888,   },
+  { "bgr888",   3, SDL_PIXELFORMAT_BGR888,   GUI_COLOR_BGR_888,   },
+  { "rgba8888", 4, SDL_PIXELFORMAT_RGBA8888, GUI_COLOR_RGBA_8888, },
 };
 
 enum gui_color bfin_gui_color (const char *color)
   return GUI_COLOR_RGB_888;
 }
 
-static const SDL_PixelFormat *bfin_gui_color_format (enum gui_color color)
+static const SDL_PixelFormat *bfin_gui_color_format (enum gui_color color,
+                                                    int *bytes_per_pixel)
 {
   int i;
 
   for (i = 0; i < ARRAY_SIZE (color_spaces); ++i)
     if (color == color_spaces[i].color)
-      return color_spaces[i].format;
+      {
+       *bytes_per_pixel = color_spaces[i].bytes_per_pixel;
+#if HAVE_SDL == 1
+       return color_spaces[i].format;
+#else
+       return sdl.AllocFormat (color_spaces[i].format);
+#endif
+      }
 
   return NULL;
 }
 
 int bfin_gui_color_depth (enum gui_color color)
 {
-  const SDL_PixelFormat *format = bfin_gui_color_format (color);
-  return format ? format->BitsPerPixel : 0;
+  int bytes_per_pixel;
+  const SDL_PixelFormat *format = bfin_gui_color_format (color,
+                                                        &bytes_per_pixel);
+  return format ? bytes_per_pixel * 8 : 0;
 }
 
 #endif
 
 fi
 
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dl_dlopen=yes
+else
+  ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBDL 1
+_ACEOF
+
+  LIBS="-ldl $LIBS"
+
+fi
+
+if test "${ac_cv_lib_dl_dlopen}" = "yes"; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sdl2" >&5
+$as_echo_n "checking for sdl2... " >&6; }
+
+if test -n "$SDL_CFLAGS"; then
+    pkg_cv_SDL_CFLAGS="$SDL_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl2\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "sdl2") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_SDL_CFLAGS=`$PKG_CONFIG --cflags "sdl2" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$SDL_LIBS"; then
+    pkg_cv_SDL_LIBS="$SDL_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl2\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "sdl2") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_SDL_LIBS=`$PKG_CONFIG --libs "sdl2" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+if test $pkg_failed = no; then
+  pkg_save_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $pkg_cv_SDL_LIBS"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+else
+  pkg_failed=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  LDFLAGS=$pkg_save_LDFLAGS
+fi
+
+
+
+if test $pkg_failed = yes; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+               SDL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "sdl2" 2>&1`
+        else
+               SDL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "sdl2" 2>&1`
+        fi
+       # Put the nasty error message in config.log where it belongs
+       echo "$SDL_PKG_ERRORS" >&5
+
+
 
 pkg_failed=no
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sdl" >&5
        SDL_LIBS=$pkg_cv_SDL_LIBS
         { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
-         { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
-$as_echo_n "checking for dlopen in -ldl... " >&6; }
-if ${ac_cv_lib_dl_dlopen+:} false; then :
-  $as_echo_n "(cached) " >&6
+             SDL_CFLAGS="${SDL_CFLAGS} -DHAVE_SDL=1"
+      SDL_LIBS="-ldl"
+
+fi
+
+elif test $pkg_failed = untried; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sdl" >&5
+$as_echo_n "checking for sdl... " >&6; }
+
+if test -n "$SDL_CFLAGS"; then
+    pkg_cv_SDL_CFLAGS="$SDL_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "sdl") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_SDL_CFLAGS=`$PKG_CONFIG --cflags "sdl" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes
 else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldl  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$SDL_LIBS"; then
+    pkg_cv_SDL_LIBS="$SDL_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "sdl") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_SDL_LIBS=`$PKG_CONFIG --libs "sdl" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+if test $pkg_failed = no; then
+  pkg_save_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $pkg_cv_SDL_LIBS"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char dlopen ();
 int
 main ()
 {
-return dlopen ();
+
   ;
   return 0;
 }
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_dl_dlopen=yes
+
 else
-  ac_cv_lib_dl_dlopen=no
+  pkg_failed=yes
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
+  LDFLAGS=$pkg_save_LDFLAGS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
-$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
-if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
-      SDL_CFLAGS="${SDL_CFLAGS} -DHAVE_SDL"
-    SDL_LIBS="-ldl"
 
+
+
+if test $pkg_failed = yes; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
 else
-  SDL_CFLAGS= SDL_LIBS=
+        _pkg_short_errors_supported=no
 fi
+        if test $_pkg_short_errors_supported = yes; then
+               SDL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "sdl" 2>&1`
+        else
+               SDL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "sdl" 2>&1`
+        fi
+       # Put the nasty error message in config.log where it belongs
+       echo "$SDL_PKG_ERRORS" >&5
+
+       :
+elif test $pkg_failed = untried; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+       :
+else
+       SDL_CFLAGS=$pkg_cv_SDL_CFLAGS
+       SDL_LIBS=$pkg_cv_SDL_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+             SDL_CFLAGS="${SDL_CFLAGS} -DHAVE_SDL=1"
+      SDL_LIBS="-ldl"
 
+fi
+
+else
+       SDL_CFLAGS=$pkg_cv_SDL_CFLAGS
+       SDL_LIBS=$pkg_cv_SDL_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+           SDL_CFLAGS="${SDL_CFLAGS} -DHAVE_SDL=2"
+    SDL_LIBS="-ldl"
 
 fi
+else
+  SDL_CFLAGS=
+  SDL_LIBS=
+fi