diff --git a/.gitignore b/.gitignore
index 8e6d3e86a..e1dce7f74 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,6 +20,7 @@ build/
 src/macosx/M6502.ins
 *.dSYM
 .vscode/c_cpp_properties.json
+.vscode/settings.json
 src/windows/sdl/*
 src/windows/x64/*
 src/windows/Win32/*
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 000000000..164c78f75
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,68 @@
+.core-defs:
+  variables:
+    JNI_PATH: src/libretro
+    CORENAME: stella
+
+include:
+  - template: Jobs/Code-Quality.gitlab-ci.yml
+  - project: 'libretro-infrastructure/ci-templates'
+    file: '/libnx-static.yml'
+  - project: 'libretro-infrastructure/ci-templates'
+    file: '/linux-x64.yml'
+  - project: 'libretro-infrastructure/ci-templates'
+    file: '/windows-x64-mingw.yml'
+  - project: 'libretro-infrastructure/ci-templates'
+    file: '/android-jni.yml'
+
+stages:
+  - build-prepare
+  - build-shared
+  - build-static
+  - test
+
+#Desktop
+libretro-build-linux-x64:
+  extends:
+    - .core-defs
+    - .libretro-linux-x64-make-default
+  variables:
+    MAKEFILE_PATH: src/libretro
+    MAKEFILE: Makefile
+
+libretro-build-windows-x64:
+  extends:
+    - .core-defs
+    - .libretro-windows-x64-mingw-make-default
+  variables:
+    MAKEFILE_PATH: src/libretro
+    MAKEFILE: Makefile
+    
+# Android
+android-armeabi-v7a:
+  extends:
+    - .core-defs
+    - .libretro-android-jni-armeabi-v7a
+
+android-arm64-v8a:
+  extends:
+    - .core-defs
+    - .libretro-android-jni-arm64-v8a
+
+android-x86_64:
+  extends:
+    - .core-defs
+    - .libretro-android-jni-x86_64
+    
+android-x86:
+  extends:
+    - .core-defs
+    - .libretro-android-jni-x86
+
+# Static
+libretro-build-libnx-aarch64:
+  extends:
+    - .core-defs
+    - .libretro-libnx-static-retroarch-master
+  variables:
+    MAKEFILE_PATH: src/libretro
+    MAKEFILE: Makefile
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 40ad65881..a55c4e90c 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -93,6 +93,11 @@
         "vector": "cpp",
         "memory_resource": "cpp",
         "cfenv": "cpp",
-        "cinttypes": "cpp"
+        "cinttypes": "cpp",
+        "filesystem": "cpp",
+        "forward_list": "cpp",
+        "regex": "cpp",
+        "valarray": "cpp",
+        "ranges": "cpp"
     }
 }
diff --git a/Announce.txt b/Announce.txt
index 2262f7975..60eb2f147 100644
--- a/Announce.txt
+++ b/Announce.txt
@@ -9,7 +9,7 @@
      SSSS     ttt  eeeee llll llll  aaaaa
 
 ===========================================================================
-                Release 6.2.1 for Linux, macOS and Windows
+                Release 6.4 for Linux, macOS and Windows
 ===========================================================================
 
 The Atari 2600 Video Computer System (VCS), introduced in 1977, was the
@@ -21,27 +21,25 @@ all of your favourite Atari 2600 games again!  Stella was originally
 developed for Linux by Bradford W. Mott, however, it has been ported to a
 number of other platforms and is currently maintained by Stephen Anthony.
 
-This is the 6.2.1 release of Stella for Linux, macOS and Windows.  The
+This is the 6.4 release of Stella for Linux, macOS and Windows.  The
 distributions currently available are:
 
-  * Binaries for Windows Vista/7/8/10 :
-      Stella-6.2.1-win32.exe   (32-bit EXE installer)
-      Stella-6.2.1-x64.exe     (64-bit EXE installer)
-      Stella-6.2.1-windows.zip (32/64 bit versions)
+  * Binaries for Windows 7/8/10 :
+      Stella-6.4-win32.exe   (32-bit EXE installer)
+      Stella-6.4-x64.exe     (64-bit EXE installer)
+      Stella-6.4-windows.zip (32/64 bit versions)
 
   * Binary distribution for macOS 10.7 and above :
-      Stella-6.2.1-macos.dmg (64-bit Intel)
+      Stella-6.4-macos.dmg (64-bit Intel)
 
-  * Binary distribution in 32-bit & 64-bit Ubuntu DEB format :
-      stella_6.2.1-1_i386.deb
-      stella_6.2.1-1_amd64.deb
+  * Binary distribution for 64-bit Ubuntu :
+      stella_6.4-1_amd64.deb
 
-  * Binary distribution in 32-bit & 64-bit RPM format :
-      stella-6.2.1-2.i386.rpm
-      stella-6.2.1-2.x86_64.rpm
+  * Binary distribution for 64-bit Redhat :
+      stella-6.4-2.x86_64.rpm
 
   * Source code distribution for all platforms :
-      stella-6.2.1-src.tar.xz
+      stella-6.4-src.tar.xz
 
 
 Distribution Site
diff --git a/Changes.txt b/Changes.txt
index b0691039e..6140d6f59 100644
--- a/Changes.txt
+++ b/Changes.txt
@@ -12,11 +12,65 @@
                               Release History
 ===========================================================================
 
-6.2.1 to 6.3 (XXXX XX, 2020)
+6.4 to 6.5 (December XX, 2020)
+
+  * Enhanced cut/copy/paste	for text editing. (TODO: PromptWidget)
+
+  * Added undo and redo to text editing. (TODO: PromptWidget)
+
+  * Added wildcard support to launcher dialog filter.
+
+  * Added option to search subdirectories in launcher.
+
+  * Added static tooltips to some UI items.
+
+  * Added dynamic tooltips to most debugger items.
+
+  * Increased sample size for CDFJ+.
+
+  * Fixed autofire bug for trackball controllers.
+
+  * Codebase now uses C++17 features.
+
+-Have fun!
+
+
+6.3 to 6.4 (November 2, 2020)
+
+  * Added basic (entire and single line only) text cut/copy and paste.
+
+  * Added color parameters to 'Custom' palette.
+
+  * Some improvements to AtariVox-USB adaptor functionality:
+    - Made serial port used for an AtariVox-USB adaptor editable.
+    - Autodetection of serial ports no longer messes up devices plugged
+      into other serial ports.
+
+  * Added CPU load stats to debugger.  Related to this, added debugger
+    pseudo-registers '_ftimreadcycles' and '_fwsynccycles' to show the
+    number of cycles since the start of frame under certain circumstances
+    (see manual for more details).
+
+  * Fixed bug with aspect correction and fullscreen mode; snapshots from
+    such a mode are now pixel-exact.
+
+  * Fixed a bug that caused CDF ROMs to crash on the Retron77 and reduced
+    ARM emulation performance for CDF ROMs on other platforms.
+
+  * Fixed crash with missing or incorrectly sized SaveKey data file, and
+    with certain functions not working (erase pages, erase entire EEPROM).
+
+  * Fixed Atari mouse autodetection.
+
+  * Fixed bug in ROM launcher, with last ROM selected not being remembered
+    when exiting and re-entering a directory.
+
+
+6.2.1 to 6.3 (October 7, 2020)
 
   * Added adjustable autofire.
 
-  * Added 'Dark' UI theme. (TODO: DOC)
+  * Added 'Dark' UI theme.
 
   * Extended global hotkeys for debug options.
 
@@ -37,19 +91,34 @@
     are no longer corrupted/cut off.  This includes properly supporting the
     2600-daptor II, which is flashable to an AVox-USB converter.
 
+  * Added auto-detection of the serial port used for an AtariVox-USB adaptor.
+
+  * Added QuadTari controller support.
+
   * Added option to select the audio device.
 
+  * Added support for CDFJ+ bankswitching type.
+
+  * Further enhanced UA bankswitching to support more Brazilian carts.
+
   * Added option to display detected settings info when a ROM is loaded.
 
-  * Added another oddball TIA glitch option for delayed background color. (TODO: DOC)
+  * Added another oddball TIA glitch option for delayed background color.
+
+  * Added option to disable aspect ratio correct scaling.
+
+  * Added debugger pseudo-registers '_timwrapread' and '_timwrapwrite',
+    which are set when the RIOT timer is read/written on timer wraparound,
+    respectively.
+
+  * Bankswitching schemes BUS, DPC+ and CDFx now work when startup bank
+    randomization is enabled (these schemes now ignore that setting).
 
   * Replaced "Re-disassemble" with "Disassemble @ current line" in debugger.
 
   * Fixed bug when taking fullscreen snapshots; the dimensions were
     sometimes cut off.
 
--Have fun!
-
 
 6.2.1 to 6.2.2 (August 25, 2020)
 
diff --git a/Makefile b/Makefile
index 168ae178d..d9dc607c9 100644
--- a/Makefile
+++ b/Makefile
@@ -48,11 +48,11 @@ endif
 CXXFLAGS+= -Wall -Wextra -Wno-unused-parameter
 
 ifdef HAVE_GCC
-  CXXFLAGS+= -Wno-multichar -Wunused -fno-rtti -Woverloaded-virtual -Wnon-virtual-dtor -std=c++14
+  CXXFLAGS+= -Wno-multichar -Wunused -Woverloaded-virtual -Wnon-virtual-dtor -std=c++17
 endif
 
 ifdef HAVE_CLANG
-  CXXFLAGS+= -Wno-multichar -Wunused -fno-rtti -Woverloaded-virtual -Wnon-virtual-dtor -std=c++14
+  CXXFLAGS+= -Wno-multichar -Wunused -Woverloaded-virtual -Wnon-virtual-dtor -std=c++17
 endif
 
 ifdef CLANG_WARNINGS
@@ -81,8 +81,8 @@ else
 endif
 
 ifdef RELEASE
-  CXXFLAGS += -flto
-  LDFLAGS += -flto
+  CXXFLAGS += -flto -fno-rtti
+  LDFLAGS += -flto -fno-rtti
 endif
 
 #######################################################################
diff --git a/configure b/configure
index 31281ec4c..fbc3c1b39 100755
--- a/configure
+++ b/configure
@@ -385,7 +385,7 @@ else
 	fi
 
 	for compiler in $compilers; do
-		if test_compiler "$compiler -std=c++14"; then
+		if test_compiler "$compiler -std=c++17"; then
 			CXX=$compiler
 			echo $CXX
 			break
@@ -580,6 +580,10 @@ else
 		darwin*)
 			DEFINES="$DEFINES -DUNIX -DDARWIN"
 			_host_os=darwin
+			if test "$have_clang" = yes; then
+				CXXFLAGS="$CXXFLAGS -Wno-documentation-unknown-command -Wno-documentation-pedantic -Wno-poison-system-directories"
+				CXXFLAGS="$CXXFLAGS -Wno-unknown-warning-option"
+			fi
 			;;
 		irix*)
 			DEFINES="$DEFINES -DUNIX"
@@ -821,8 +825,9 @@ CHEAT="$SRC/cheat"
 LIBPNG="$SRC/libpng"
 ZLIB="$SRC/zlib"
 SQLITE="$SRC/common/repository/sqlite"
+JSON="$SRC/json"
 
-INCLUDES="-I$CORE -I$COMMON -I$TV -I$TIA -I$TIA_FRAME_MANAGER"
+INCLUDES="-I$CORE -I$COMMON -I$TV -I$TIA -I$TIA_FRAME_MANAGER -I$JSON"
 
 INCLUDES="$INCLUDES `$_sdlconfig --cflags`"
 if test "$_build_static" = yes ; then
diff --git a/debian/changelog b/debian/changelog
index 75c7267b6..d1456ede4 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,17 @@
+stella (6.4) stable; urgency=high
+
+  * Version 6.4 release
+
+ -- Stephen Anthony <sa666666@gmail.com>  Mon, 2 Nov 2020 17:09:59 -0230
+
+
+stella (6.3-1) stable; urgency=high
+
+  * Version 6.3 release
+
+ -- Stephen Anthony <sa666666@gmail.com>  Wed, 7 Oct 2020 17:09:59 -0230
+
+
 stella (6.2.1-1) stable; urgency=high
 
   * Version 6.2.1 release
diff --git a/debian/compat b/debian/compat
index ec635144f..f599e28b8 100644
--- a/debian/compat
+++ b/debian/compat
@@ -1 +1 @@
-9
+10
diff --git a/debian/control b/debian/control
index 4d19b476f..9106212fe 100644
--- a/debian/control
+++ b/debian/control
@@ -1,17 +1,39 @@
 Source: stella
-Section: games
-Priority: optional
 Maintainer: Stephen Anthony <sa666666@gmail.com>
-Standards-Version: 3.7.2
-Build-Depends: debhelper (>= 5.0.0), libsdl2-dev, libpng-dev
+Section: otherosfs
+Priority: optional
+Build-Depends: debhelper (>= 10~),
+               libpng-dev,
+               libsdl2-dev,
+               zlib1g-dev
+Standards-Version: 4.5.0
+Vcs-Browser: https://github.com/stella-emu/stella/
+Vcs-Git: https://github.com/stella-emu/stella.git
+Homepage: https://stella-emu.github.io
+Rules-Requires-Root: no
 
 Package: stella
 Architecture: any
-Depends: ${shlibs:Depends}
+Depends: ${misc:Depends},
+         ${shlibs:Depends}
+Recommends: joystick (>= 1:1.5.1)
+Pre-Depends: ${misc:Pre-Depends}
 Description: Atari 2600 Emulator for SDL2
- The Atari 2600 Video Computer System (VCS), introduced in 1977, was
- the most popular home video game system of the early 1980's.  This
- emulator will run most Atari ROM images, so that you can play your
- favorite old Atari 2600 games on your PC.
+ Stella is a portable emulator of the old Atari 2600 video-game
+ console. You can play most Atari 2600 games with it.
  .
- Homepage: https://stella-emu.github.io
+ Stella's features include:
+  * emulation of Atari 2600 joysticks, keyboards, paddles and driving
+    controllers using the host system's input peripherals;
+  * emulation of trackballs, joysticks, booster grips, driving
+    controllers and the Amiga Mouse using the host system's mouse;
+  * support for real Atari 2600 controllers using the Stelladaptor,
+    2600-daptor or 2600-daptor II;
+  * support for real Atari 7800 controllers using the 2600-daptor II;
+  * support for the speech portion of a real AtariVox device;
+  * support for Supercharger single-load and multi-load games;
+  * emulation of CRT TV features, including texturing, colour bleed,
+    RF noise and phosphor burn-off (requires OpenGL).
+ .
+ An extensive debugger is included, with the Distella disassembler.
+
diff --git a/debian/copyright b/debian/copyright
index 129ab1224..9658cf4e9 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -1,29 +1,205 @@
-This package was debianized first by Tom Lear <tom@ticking.accesscom.com> on
-Thu,  7 Oct 1999 08:57:16 -0700.
+Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0
+Upstream-Name: stella
+Source: https://stella-emu.github.io
+Copyright: 1995-2020 Bradford W. Mott, Stephen Anthony and the Stella Team
+License: GPL-2+
 
-It was downloaded from <https://stella-emu.github.io>
+Files: *
+Copyright: 1995-2020 Bradford W. Mott, Stephen Anthony and the Stella
+		     Team
+License: GPL-2+
 
-Copyright Holder(s): Bradford W. Mott <bwmott@acm.org> and the Stella Team
+Files: debian/*
+Copyright: 1998-2004 Tom Lear <tom@trap.mtview.ca.us>
+	   2006 Mario Iseli <admin@marioiseli.com>
+	   2010-2020 Stephen Kitt <skitt@debian.org>
+License: GPL-2+
 
-License:
+Files:
+ src/common/Stack.hxx
+ src/emucore/FrameBuffer.hxx
+ src/emucore/FSNode.*
+ src/gui/*
+Copyright: 2002-2004 The ScummVM project
+License: GPL-2+
 
-   Copyright (C) 1995-2010 Bradford W. Mott <bwmott@acm.org>
-   and the Stella Team
+Files: src/common/ZipHandler.hxx
+Copyright: Aaron Giles
+License: BSD-3
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ .
+     * Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+     * Redistributions in binary form must reproduce the above
+       copyright notice, this list of conditions and the following
+       disclaimer in the documentation and/or other materials provided
+       with the distribution.
+     * Neither the name 'MAME' nor the names of its contributors may
+       be used to endorse or promote products derived from this
+       software without specific prior written permission.
+ .
+ THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-   This package 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 Foundation; either version 2 of the License, or
-   (at your option) any later version.
+Files: src/emucore/MD5.cxx
+Copyright: 1991-1992, RSA Data Security, Inc.
+License: RSA
+ License to copy and use this software is granted provided that it is
+ identified as the "RSA Data Security, Inc. MD5 Message-Digest
+ Algorithm" in all material mentioning or referencing this software or
+ this function.
+ .
+ License is also granted to make and use derivative works provided
+ that such works are identified as "derived from the RSA Data
+ Security, Inc. MD5 Message-Digest Algorithm" in all material
+ mentioning or referencing the derived work.
+ .
+ RSA Data Security, Inc. makes no representations concerning either
+ the merchantability of this software or the suitability of this
+ software for any particular purpose. It is provided "as is" without
+ express or implied warranty of any kind.
+ .
+ These notices must be retained in any copies of any part of this
+ documentation and/or software.
 
-   This package 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.
+Files: src/libpng/*
+Copyright: 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+	   1996-1997 Andreas Dilger
+	   1998-2013 Glenn Randers-Pehrson
+License: libpng
+ The PNG Reference Library is supplied "AS IS".  The Contributing
+ Authors and Group 42, Inc. disclaim all warranties, expressed or
+ implied, including, without limitation, the warranties of
+ merchantability and of fitness for any purpose.  The Contributing
+ Authors and Group 42, Inc. assume no liability for direct, indirect,
+ incidental, special, exemplary, or consequential damages, which may
+ result from the use of the PNG Reference Library, even if advised of
+ the possibility of such damage.
+ .
+ Permission is hereby granted to use, copy, modify, and distribute
+ this source code, or portions hereof, for any purpose, without fee,
+ subject to the following restrictions:
+ .
+   1. The origin of this source code must not be misrepresented.
+ .
+   2. Altered versions must be plainly marked as such and must not be
+      misrepresented as being the original source.
+ .
+   3. This Copyright notice may not be removed or altered from any
+      source or altered source distribution.
+ .
+ The Contributing Authors and Group 42, Inc. specifically permit,
+ without fee, and encourage the use of this source code as a component
+ to supporting the PNG file format in commercial products.  If you use
+ this source code in a product, acknowledgment is not required but
+ would be appreciated.
+ .
+ There is no warranty against interference with your enjoyment of the
+ library or against infringement.  There is no warranty that our
+ efforts or the library will fulfill any of your particular purposes
+ or needs.  This library is provided with all faults, and the entire
+ risk of satisfactory quality, performance, accuracy, and effort is
+ with the user.
 
-   You should have received a copy of the GNU General Public License
-   along with this package; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+Files: src/libretro/libretro.h
+Copyright: 2010-2017 The RetroArch team
+License: MIT
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+ .
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+ .
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
 
-On Debian systems, the complete text of the GNU General
-Public License can be found in `/usr/share/common-licenses/GPL'.
+Files: src/macos/*
+Copyright: 2005-2006 Mark Grebe
+License: GPL-2+
 
+Files: src/tools/convbdf.c
+Copyright: 2002 Greg Haerr
+License: GPL-2+
+
+Files: src/tools/evdev-joystick/*
+Copyright: 2016 Stephen Anthony
+License: GPL-2
+ This package is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2, as
+ published by the Free Software Foundation.
+ .
+ This package 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 this package; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
+ USA.
+ .
+ On Debian systems, the complete text of the GNU General Public
+ License version 2 can be found in
+ `/usr/share/common-licenses/GPL-2'.
+
+Files: src/zlib/*
+Copyright: 1995-2012, 2016 Jean-loup Gailly and Mark Adler
+License: zlib
+ This software is provided 'as-is', without any express or implied
+ warranty.  In no event will the authors be held liable for any
+ damages arising from the use of this software.
+ .
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute
+ it freely, subject to the following restrictions:
+ .
+ 1. The origin of this software must not be misrepresented; you must
+    not claim that you wrote the original software. If you use this
+    software in a product, an acknowledgment in the product
+    documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must
+    not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source
+    distribution.
+
+License: GPL-2+
+ This package 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 Foundation; either version 2 of the License, or (at
+ your option) any later version.
+ .
+ This package 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 this package; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
+ USA.
+ .
+ On Debian systems, the complete text of the GNU General Public
+ License version 2 can be found in
+ `/usr/share/common-licenses/GPL-2'.
diff --git a/debian/dirs b/debian/dirs
deleted file mode 100644
index e77248175..000000000
--- a/debian/dirs
+++ /dev/null
@@ -1 +0,0 @@
-usr/bin
diff --git a/debian/doc-base b/debian/doc-base
new file mode 100644
index 000000000..dd94cd309
--- /dev/null
+++ b/debian/doc-base
@@ -0,0 +1,9 @@
+Document: stella
+Title: Stella Manual
+Author: The Stella Team
+Abstract: Documentation for the Stella Atari 2600 VCS emulator.
+Section: Emulators
+
+Format: HTML
+Index: /usr/share/doc/stella/index.html
+Files: /usr/share/doc/stella/*.html
diff --git a/debian/rules b/debian/rules
index 2e9b442c1..8277e8a69 100755
--- a/debian/rules
+++ b/debian/rules
@@ -4,67 +4,26 @@
 # Uncomment this to turn on verbose mode.
 #export DH_VERBOSE=1
 
-# These are used for cross-compiling and for saving the configure script
-# from having to guess our platform (since we know it already)
-DEB_HOST_GNU_TYPE   ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
-DEB_BUILD_GNU_TYPE  ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
-DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH)
+export DEB_BUILD_MAINT_OPTIONS = hardening=+all
 
-CFLAGS = -Wall
+include /usr/share/dpkg/architecture.mk
+DPKG_EXPORT_BUILDTOOLS=1
+-include /usr/share/dpkg/buildtools.mk
 
-ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
-	CXXFLAGS += -O0
-else
-	CXXFLAGS += -O2
-endif
+%:
+	dh $@ --with autotools_dev
 
-config.status: configure
-	dh_testdir
-	CXXFLAGS="$(CXXFLAGS)" ./configure --prefix=/usr --enable-release
+override_dh_auto_clean:
+# Generate the minimal config.mak required for "make distclean"
+	test -f config.mak || echo "RM_REC := rm -f -r" > config.mak
+	dh_auto_clean
 
-build: build-stamp
+override_dh_auto_configure:
+	./configure --prefix=/usr $(if $(filter $(DEB_BUILD_ARCH),$(DEB_HOST_ARCH)),,--host=$(DEB_HOST_GNU_TYPE)) --enable-release
 
-build-stamp:  config.status
-	dh_testdir
-	$(MAKE)
-	touch build-stamp
-
-clean:
-	dh_testdir
-	dh_testroot
-	rm -f build-stamp
-	-$(MAKE) distclean
-
-	dh_clean
-
-install: build
-	dh_testdir
-	dh_testroot
-	dh_clean -k
-	dh_installdirs
-
-	$(MAKE) install DESTDIR=$(CURDIR)/debian/stella
-
-# Build architecture-independent files here.
-binary-indep: build install
-# We have nothing to do by default.
-
-binary-arch: build install
-	dh_testdir
-	dh_testroot
-	dh_installchangelogs Changes.txt
-	dh_installdocs
-	dh_installmenu
-#	dh_installman $(CURDIR)/debian/stella.6
-	dh_link
-	dh_strip
-	dh_compress
-	dh_fixperms
-	dh_installdeb
-	dh_shlibdeps
-	dh_gencontrol
-	dh_md5sums
-	dh_builddeb
-
-binary: binary-indep binary-arch
-.PHONY: build clean binary-indep binary-arch binary install
+override_dh_auto_install:
+	dh_auto_install
+	# This is also installed as the upstream changelog
+	rm $(CURDIR)/debian/stella/usr/share/doc/stella/Changes.txt
+	# This is overridden by the copyright file
+	rm $(CURDIR)/debian/stella/usr/share/doc/stella/License.txt
diff --git a/debian/watch b/debian/watch
index 8cdd8c1ec..b507d13a8 100644
--- a/debian/watch
+++ b/debian/watch
@@ -1,2 +1,4 @@
-version=3
-http://sf.net/stella/stella-(.*)-src\.tar\.gz
+version=4
+opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%stella-$1.tar.gz%" \
+    https://github.com/stella-emu/stella/tags \
+    (?:.*?/)?v?(\d[\d.]*)\.tar\.gz debian uupdate
diff --git a/docs/debugger.html b/docs/debugger.html
index 7e51a0333..b1fdac37e 100644
--- a/docs/debugger.html
+++ b/docs/debugger.html
@@ -15,7 +15,7 @@
 <body>
 
   <center><b><font size="7">Stella</font></b></center>
-  <center><h4><b>Release 6.2.1</b></h4></center>
+  <center><h4><b>Release 6.4</b></h4></center>
   <center><h1><b>Integrated Debugger</b></h1></center>
   <center><h4><b>(a work in progress)</b></h4></center>
   <br>
@@ -227,6 +227,14 @@ tabs from left-to-right, Shift + Control/Cmd + Tab cycles right-to-left.
 Pressing Tab (or Shift + Tab) cycles between widgets in the current tab (except
 for in the Prompt Tab, where 'tab' is used for something else).</p>
 
+<p>Note for the GUI display:
+<ul>
+<li>Hexadecimal values are either not prefixed or with '$'.</li>
+<li>Decimal values are prefixed with '#'.</li>
+<li>Binary values are prefixed with '%'.</li>
+</ul>
+</p>
+
 <p>You can also enter the debugger at emulator startup by use the 'debug'
 command on the command line, or alternatively within the ROM launcher in
 'Power-on options':
@@ -753,10 +761,14 @@ that holds 'number of scanlines' on an actual console).</p>
 <tr><td> _cycleslo</td><td> Lower 32 bits of number of cycles since emulation started</td></tr>
 <tr><td> _fcount</td><td> Number of frames since emulation started</td></tr>
 <tr><td> _fcycles</td><td> Number of cycles since frame started</td></tr>
+<tr><td> _ftimreadcycles</td><td>Number of cycles used by timer reads since frame started</td></tr>
+<tr><td> _fwsynccycles</td><td>Number of cycles skipped by WSYNC since frame started</td></tr>
 <tr><td> _icycles</td><td> Number of cycles of last instruction</td></tr>
 <tr><td> _scan</td><td> Current scanline count</td></tr>
 <tr><td> _scanend</td><td> Scanline count at end of last frame</td></tr>
 <tr><td> _scycles</td><td> Number of cycles in current scanline</td></tr>
+<tr><td> _timwrapread</td><td> Timer read wrapped on this cycle</td></tr>
+<tr><td> _timwrapwrite</td><td> Timer write wrapped on this cycle</td></tr>
 <tr><td> _vblank</td><td> Whether vertical blank is enabled (1 or 0)</td></tr>
 <tr><td> _vsync</td><td> Whether vertical sync is enabled (1 or 0)</td></tr>
 </table>
@@ -1131,16 +1143,20 @@ as illustrated:</p>
 <!-- /////////////////////////////////////////////////////////////////////////  -->
 <br>
 <h2><a name="TIAInfo"><u>(F)</u> TIA Information</a></h2>
-<p>To the right of the <a href="#TIADisplay"><b>TIA Display</b></a> area, TIA information is displayed:</p>
+<p>To the right of the <a href="#TIADisplay"><b>TIA Display</b></a> area, TIA information is displayed (all values are decimal):</p>
 <p><img src="graphics/debugger_tiainfo.png"></p>
 <p>The indicators are as follows (note that all these are read-only):</p>
 <ul>
-<li><b>Frame Count</b>: The number of frames since this ROM was loaded or reset.</li>
-<li><b>Frame Cycle</b>: The number of CPU cycles that have been executed this frame since
+<li><b>Frame Cycls</b>: The number of CPU cycles that have been executed this frame since
+VSYNC was cleared at scanline 0.</li>
+<li><b>WSync Cycls</b>: The number of CPU cycles that have been skipped by WSYNC this frame since
+VSYNC was cleared at scanline 0.</li>
+<li><b>Timer Cycls</b>: The number of CPU cycles (approximately) that have been used by timer read loops since
 VSYNC was cleared at scanline 0.</li>
 <li><b>Total</b>: The total number of CPU cycles since this ROM was loaded or reset.</li>
 <li><b>Delta</b>: The number of CPU cycles that have been executed since the last debugger
 interrupt.</li>
+<li><b>Frame Cnt.</b>: The number of frames since this ROM was loaded or reset.</li>
 <li><b>Scanline</b>: The scanline that's currently being drawn, and the count from the
 previous frame. Scanline 0 is the one on which VSYNC is cleared (after being set for
 3 scanlines, as per the Stella Programmer's Guide).</li>
@@ -1273,10 +1289,9 @@ are lost (they will NOT end up in the Carry flag).</p>
 <p>This is a spreadsheet-like GUI for inspecting and changing the contents
 of the 2600's zero-page RAM.</p>
 <p>You can navigate with either the mouse or the keyboard arrow keys.
-To change a RAM location, either double-click on it or press Enter while
-it's highlighted. Enter the new value (hex only for now, sorry), then
-press Enter to make the change. If you change your mind, press Escape
-and the original value will be restored. The currently selected RAM cell
+To change a RAM location, either double-click on it or press 'Enter' while
+it's highlighted. Enter the new value (hex, other formats using the bottom textboxes), then
+press 'Enter' to make the change. The currently selected RAM cell
 can also be changed by using the
 <a href="#DataOpButtons"><b>Data Operations Buttons</b></a> or the associated
 shortcut keys.</p>
@@ -1287,7 +1302,8 @@ more comprehensive. It will undo <b>all</b> operations on <b>all</b> cells
 since you first made a change.</p>
 <p>The UI objects at the bottom refer to the currently selected RAM cell.
 The 'Label' textbox shows the label attached to this RAM location (if any),
-and the other two textboxes show the decimal and binary equivalent value.</p>
+and the other three textboxes show the hex, decimal and binary equivalent value.
+The values can be edited here too.</p>
 
 <p>The remaining buttons to the right are further explained in the next section.</p>
 
@@ -1569,7 +1585,7 @@ Go ahead and try to change something!</p>
 <p>If applicable, this area shows a detailed breakdown of any extra RAM supported by
 the bankswitching scheme. Since the bankswitch schemes can greatly vary in operation,
 this tab will be different for each scheme, but its specific functionality should be
-self-explanatory. An example of both F8SC (8K Atari + ram) and DPC (Pitfall II) is
+self-explanatory. An example of both F6SC (16K Atari + ram) and DPC (Pitfall II) is
 as follows:</p>
 
 <p><img src="graphics/debugger_ram-f8sc.png"></p>
diff --git a/docs/graphics/debugger_bankcomplex.png b/docs/graphics/debugger_bankcomplex.png
index fd8a087dc..ae200386d 100644
Binary files a/docs/graphics/debugger_bankcomplex.png and b/docs/graphics/debugger_bankcomplex.png differ
diff --git a/docs/graphics/debugger_banksimple.png b/docs/graphics/debugger_banksimple.png
index a5f1092d9..67f16c0cc 100644
Binary files a/docs/graphics/debugger_banksimple.png and b/docs/graphics/debugger_banksimple.png differ
diff --git a/docs/graphics/debugger_cpuregs.png b/docs/graphics/debugger_cpuregs.png
index feb238c1b..4d868df92 100644
Binary files a/docs/graphics/debugger_cpuregs.png and b/docs/graphics/debugger_cpuregs.png differ
diff --git a/docs/graphics/debugger_iotab.png b/docs/graphics/debugger_iotab.png
index 170fc47b3..a83fd33ad 100644
Binary files a/docs/graphics/debugger_iotab.png and b/docs/graphics/debugger_iotab.png differ
diff --git a/docs/graphics/debugger_main.png b/docs/graphics/debugger_main.png
index c59f1a345..2064cd85a 100644
Binary files a/docs/graphics/debugger_main.png and b/docs/graphics/debugger_main.png differ
diff --git a/docs/graphics/debugger_ram-dpc.png b/docs/graphics/debugger_ram-dpc.png
index 97f682626..3a2e94943 100644
Binary files a/docs/graphics/debugger_ram-dpc.png and b/docs/graphics/debugger_ram-dpc.png differ
diff --git a/docs/graphics/debugger_ram-f8sc.png b/docs/graphics/debugger_ram-f8sc.png
index dc8b231a8..4ebb9e75a 100644
Binary files a/docs/graphics/debugger_ram-f8sc.png and b/docs/graphics/debugger_ram-f8sc.png differ
diff --git a/docs/graphics/debugger_ram.png b/docs/graphics/debugger_ram.png
index efdc8531b..a5711bf02 100644
Binary files a/docs/graphics/debugger_ram.png and b/docs/graphics/debugger_ram.png differ
diff --git a/docs/graphics/debugger_ramsearch.png b/docs/graphics/debugger_ramsearch.png
index 9041ca0a1..a6ed37b8f 100644
Binary files a/docs/graphics/debugger_ramsearch.png and b/docs/graphics/debugger_ramsearch.png differ
diff --git a/docs/graphics/debugger_tiainfo.png b/docs/graphics/debugger_tiainfo.png
index e19f4ea4a..3ef48b425 100644
Binary files a/docs/graphics/debugger_tiainfo.png and b/docs/graphics/debugger_tiainfo.png differ
diff --git a/docs/graphics/eventmapping.png b/docs/graphics/eventmapping.png
index f9b089b6d..f1cef67ac 100644
Binary files a/docs/graphics/eventmapping.png and b/docs/graphics/eventmapping.png differ
diff --git a/docs/graphics/eventmapping_combo.png b/docs/graphics/eventmapping_combo.png
index 18d461971..a8bc4d8cd 100644
Binary files a/docs/graphics/eventmapping_combo.png and b/docs/graphics/eventmapping_combo.png differ
diff --git a/docs/graphics/eventmapping_devsports.png b/docs/graphics/eventmapping_devsports.png
index 9b3da3ebc..536caf4f4 100644
Binary files a/docs/graphics/eventmapping_devsports.png and b/docs/graphics/eventmapping_devsports.png differ
diff --git a/docs/graphics/eventmapping_mouse.png b/docs/graphics/eventmapping_mouse.png
index daac75b09..760b4eac3 100644
Binary files a/docs/graphics/eventmapping_mouse.png and b/docs/graphics/eventmapping_mouse.png differ
diff --git a/docs/graphics/eventmapping_remap.png b/docs/graphics/eventmapping_remap.png
index 34df62937..442dfead6 100644
Binary files a/docs/graphics/eventmapping_remap.png and b/docs/graphics/eventmapping_remap.png differ
diff --git a/docs/graphics/launcher_override.png b/docs/graphics/launcher_override.png
index 17302c994..a4b3b4221 100644
Binary files a/docs/graphics/launcher_override.png and b/docs/graphics/launcher_override.png differ
diff --git a/docs/graphics/logs.png b/docs/graphics/logs.png
index 202272ad5..195eeed28 100644
Binary files a/docs/graphics/logs.png and b/docs/graphics/logs.png differ
diff --git a/docs/graphics/options_audio.png b/docs/graphics/options_audio.png
index e46d77b87..174bc3701 100644
Binary files a/docs/graphics/options_audio.png and b/docs/graphics/options_audio.png differ
diff --git a/docs/graphics/options_developer.png b/docs/graphics/options_developer.png
index f405818b1..f39e894b8 100644
Binary files a/docs/graphics/options_developer.png and b/docs/graphics/options_developer.png differ
diff --git a/docs/graphics/options_developer_debugger.png b/docs/graphics/options_developer_debugger.png
index dfa8cbd73..4ad4d42d7 100644
Binary files a/docs/graphics/options_developer_debugger.png and b/docs/graphics/options_developer_debugger.png differ
diff --git a/docs/graphics/options_developer_emulation.png b/docs/graphics/options_developer_emulation.png
index 977893402..0b2f32d65 100644
Binary files a/docs/graphics/options_developer_emulation.png and b/docs/graphics/options_developer_emulation.png differ
diff --git a/docs/graphics/options_developer_tia.png b/docs/graphics/options_developer_tia.png
index ee3a3973c..dbacdc877 100644
Binary files a/docs/graphics/options_developer_tia.png and b/docs/graphics/options_developer_tia.png differ
diff --git a/docs/graphics/options_developer_timemachine.png b/docs/graphics/options_developer_timemachine.png
index 498f83c0f..d912666bc 100644
Binary files a/docs/graphics/options_developer_timemachine.png and b/docs/graphics/options_developer_timemachine.png differ
diff --git a/docs/graphics/options_developer_video.png b/docs/graphics/options_developer_video.png
index 0bc3393f4..42b55dff8 100644
Binary files a/docs/graphics/options_developer_video.png and b/docs/graphics/options_developer_video.png differ
diff --git a/docs/graphics/options_gameinfo_controller.png b/docs/graphics/options_gameinfo_controller.png
index fe5adb275..2714e5407 100644
Binary files a/docs/graphics/options_gameinfo_controller.png and b/docs/graphics/options_gameinfo_controller.png differ
diff --git a/docs/graphics/options_gameinfo_emulation.png b/docs/graphics/options_gameinfo_emulation.png
index 221a08fa5..55c1e6893 100644
Binary files a/docs/graphics/options_gameinfo_emulation.png and b/docs/graphics/options_gameinfo_emulation.png differ
diff --git a/docs/graphics/options_gameinfo_quadtari.png b/docs/graphics/options_gameinfo_quadtari.png
new file mode 100644
index 000000000..04fba7f06
Binary files /dev/null and b/docs/graphics/options_gameinfo_quadtari.png differ
diff --git a/docs/graphics/options_misc.png b/docs/graphics/options_misc.png
index 1faa756b5..704b7b5de 100644
Binary files a/docs/graphics/options_misc.png and b/docs/graphics/options_misc.png differ
diff --git a/docs/graphics/options_misc_dark.png b/docs/graphics/options_misc_dark.png
new file mode 100644
index 000000000..79fad1166
Binary files /dev/null and b/docs/graphics/options_misc_dark.png differ
diff --git a/docs/graphics/options_ui.png b/docs/graphics/options_ui.png
index 54ed568fc..70712d2b6 100644
Binary files a/docs/graphics/options_ui.png and b/docs/graphics/options_ui.png differ
diff --git a/docs/graphics/options_video.png b/docs/graphics/options_video.png
index 58654148a..193bc4804 100644
Binary files a/docs/graphics/options_video.png and b/docs/graphics/options_video.png differ
diff --git a/docs/graphics/options_video_palettes.png b/docs/graphics/options_video_palettes.png
index dae0cf7ee..d965b45b3 100644
Binary files a/docs/graphics/options_video_palettes.png and b/docs/graphics/options_video_palettes.png differ
diff --git a/docs/graphics/options_video_tv.png b/docs/graphics/options_video_tv.png
index 5ce3c3f2a..01b460842 100644
Binary files a/docs/graphics/options_video_tv.png and b/docs/graphics/options_video_tv.png differ
diff --git a/docs/graphics/resources/debugger_main.pdn b/docs/graphics/resources/debugger_main.pdn
index 6c864a2a4..16d370b08 100644
Binary files a/docs/graphics/resources/debugger_main.pdn and b/docs/graphics/resources/debugger_main.pdn differ
diff --git a/docs/graphics/rominfo_1x_large.png b/docs/graphics/rominfo_1x_large.png
index e5b08d857..5a0133404 100644
Binary files a/docs/graphics/rominfo_1x_large.png and b/docs/graphics/rominfo_1x_large.png differ
diff --git a/docs/graphics/rominfo_1x_small.png b/docs/graphics/rominfo_1x_small.png
index 6ee356745..99d23e135 100644
Binary files a/docs/graphics/rominfo_1x_small.png and b/docs/graphics/rominfo_1x_small.png differ
diff --git a/docs/graphics/rominfo_2x_small.png b/docs/graphics/rominfo_2x_small.png
index da610bba0..7c53384b2 100644
Binary files a/docs/graphics/rominfo_2x_small.png and b/docs/graphics/rominfo_2x_small.png differ
diff --git a/docs/index.html b/docs/index.html
index 89bee1158..369598e23 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -19,7 +19,7 @@
   <br><br>
   <center><h2><b>A multi-platform Atari 2600 VCS emulator</b></h2></center>
 
-  <center><h4><b>Release 6.2.1</b></h4></center>
+  <center><h4><b>Release 6.4</b></h4></center>
   <br><br>
 
   <center><h2><b>User's Guide</b></h2></center>
@@ -70,7 +70,7 @@
 
   <br><br><br>
 
-  <center><b>February 1999 - June 2020</b></center>
+  <center><b>February 1999 - November 2020</b></center>
     <center><b>The Stella Team</b></center>
   <center><b><a href="https://stella-emu.github.io">Stella Homepage</a></b></center>
 
@@ -260,7 +260,7 @@
   <h2><b><a name="Features">Features</a></b></h2>
 
   <ul>
-    <li>High speed emulation using optimized C++14 code</li>
+    <li>High speed emulation using optimized C++17 code</li>
     <li>Supports high quality TIA emulation using the cycle-exact TIA core from
       <a href="https://github.com/6502ts/6502.ts">6502.ts</a> by
       Christian Speckner</li>
@@ -268,24 +268,15 @@
       Atari 2600 FPGA project, including cycle-exact audio, analog interference
       from mixing of audio channels, as well as stereo sound support; dynamic
       sound resampling is also included</li>
-    <li>Emulates the Atari 2600 Joystick Controllers using your computer's keyboard,
+    <li>Emulates the Atari 2600 Joystick, Paddle, Driving, CBS BoosterGrip, Sega Genesis, QuadTari controllers using your computer's keyboard,
       joysticks or mouse</li>
-    <li>Emulates the Atari 2600 Keyboard Controllers using your computer's keyboard</li>
-    <li>Emulates the Atari 2600 Paddle Controllers using your computer's mouse, keyboard
-      or joysticks</li>
-    <li>Emulates the Atari 2600 Driving Controllers using your computer's keyboard,
-      joysticks or mouse</li>
-    <li>Emulates the CBS BoosterGrip Controller using your computer's keyboard,
-      joysticks or mouse</li>
-    <li>Emulates the Sega Genesis Controller using your computer's keyboard,
-      joysticks or mouse</li>
-    <li>Emulates CX22/CX80 style trackballs and Amiga/Atari Mouse using your
+    <li>Emulates CX22/CX80 style Trackballs, Amiga/Atari Mouse, Mindlink controller and the Light Gun using your
       computer's mouse</li>
+    <li>Emulates the Atari 2600 Keyboard controllers using your computer's keyboard</li>
     <li>Emulates <a href="http://en.wikipedia.org/wiki/CompuMate">Spectravideo CompuMate</a> system using your computer's keyboard,
       including mapping of CompuMate 'Backspace', 'Space' and 'Enter' functionality to
       to the actual keys on your keyboard</li>
-    <li>Emulates the Mindlink Controller and the Light Gun using your computer's mouse</li>
-  <li>Supports autodetection for most common controller types</li>
+    <li>Supports autodetection for most common controller types</li>
     <li>Support for real Atari 2600 controllers using the
       <a href="http://www.grandideastudio.com/portfolio/stelladaptor-2600">Stelladaptor</a> and
       <a href="http://2600-daptor.com">2600-daptor/2600-daptor II</a></li>
@@ -296,7 +287,7 @@
       AtariVox</a> and <a href="http://www.vectrex.biz/MemCard.htm">SaveKey</a> controllers,
       as well as FLASH support in various cartridge schemes</li>
     <li>Supports all known bankswitching schemes (let us know if there's one we missed)</li>
-    <li>Supports DPC+/CDF(J) bankswitching schemes from the <a href="http://harmony.atariage.com">Harmony Cart</a>,
+    <li>Supports DPC+/CDF(J)(+) bankswitching schemes from the <a href="http://harmony.atariage.com">Harmony Cart</a>,
       including <a href="http://thumbulator.blogspot.ca">partial emulation of the ARM processor</a></li>
     <li>Supports cartridge autodetection for almost all bankswitching schemes</li>
     <li>Supports using ROM filename extensions to force specific bankswitching schemes</li>
@@ -359,7 +350,7 @@
     <li>OpenGL capable video card</li>
     <li>Other architectures (MIPS, PPC, PPC64, etc.) have been confirmed to work,
       but aren't as well tested as i386/x86_64</li>
-    <li>GNU g++ v/6 or Clang v/3.9 (with C++14 support) and the make utility are required for compiling the Stella source code</li>
+    <li>GNU g++ v/7 or Clang v/5 (with C++17 support) and the make utility are required for compiling the Stella source code</li>
   </ul>
 
   <p>
@@ -377,7 +368,7 @@
   <p>
   <h3><b><u>Windows</u></b></h3>
 
-  <p>The Windows version of Stella is designed to work on Windows Vista/7/8/10
+  <p>The Windows version of Stella is designed to work on Windows 7/8/10
   with the following:</p>
 
   <ul>
@@ -1373,8 +1364,8 @@
     </tr>
     <tr>
       <td>Toggle windowed/fullscreen mode</td>
-      <td>Alt + Enter</td>
-      <td>Cmd + Enter</td>
+      <td>Alt + Return</td>
+      <td>Cmd + Return</td>
     </tr>
     <tr>
       <td>Toggle adapting display refresh rate to game frame rate
@@ -1403,6 +1394,11 @@
       <td>Alt + PageUp</td>
       <td>Cmd-Fn + Up arrow</td>
     </tr>
+    <tr>
+      <td>Toggle aspect ratio correct scaling</td>
+      <td>Control + c</td>
+      <td>Control + c</td>
+    </tr>
     <tr>
       <td><i>Decrease</i> vertical display size</td>
       <td>Shift-Alt + PageUp</td>
@@ -1761,11 +1757,6 @@
       <td>Backspace</td>
       <td>Backspace</td>
     </tr>
-    <tr>
-      <td>Go to parent directory (UI mode)</td>
-      <td>Backspace</td>
-      <td>Backspace</td>
-    </tr>
     <tr>
       <td><i>Decrease</i> emulation speed (disables 'Turbo' mode)</td>
       <td>Shift-Control + s</td>
@@ -1793,7 +1784,7 @@
     </tr>
 
     <tr>
-      <td>Switch mouse between controller emulation modes</br>(see <b>Game Properties - <a href="#Controller">Controller</a></b>)</td>
+      <td>Switch mouse between controller emulation modes</br>(see <b><a href="#Controller">Controller Properties</a></b>)</td>
       <td>Control + 0</td>
       <td>Control + 0</td>
     </tr>
@@ -1810,13 +1801,13 @@
     </tr>
     <tr>
       <td>Save continuous PNG snapshots</br>(per interval defined in <a href="#Snapshots"><b>Snapshot Settings</b></a>)</td>
-      <td>Alt + s</td>
-      <td>Cmd + s</td>
+      <td>Control-Alt + s</td>
+      <td>Control-Cmd + s</td>
     </tr>
     <tr>
       <td>Save continuous PNG snapshots (every frame)</td>
-      <td>Shift-Alt + s</td>
-      <td>Shift-Cmd + s</td>
+      <td>Shift-Control-Alt + s</td>
+      <td>Shift-Control-Cmd + s</td>
     </tr>
 
     <tr>
@@ -1871,25 +1862,237 @@
     </tr>
   </table>
 
+  <p><b>UI Keys (can be remapped)</b></p>
+
+  <table BORDER=2 cellpadding=4>
+    <tr>
+      <th>Function</th>
+      <th>Key (Standard)</th>
+      <th>Key (macOS)</th>
+    </tr>
+    <tr>
+      <td>Move Up</td>
+      <td>Up arrow</td>
+      <td>Up arrow</td>
+    </tr>
+    <tr>
+      <td>Move Down</td>
+      <td>Down arrow</td>
+      <td>Down arrow</td>
+    </tr>
+    <tr>
+      <td>Move Left</td>
+      <td>Left arrow</td>
+      <td>Left arrow</td>
+    </tr>
+    <tr>
+      <td>Move Right</td>
+      <td>Right arrow</td>
+      <td>Right arrow</td>
+    </tr>
+    <tr>
+      <td>Move Home</td>
+      <td>Home</td>
+      <td>Home</td>
+    </tr>
+    <tr>
+      <td>Move End</td>
+      <td>End</td>
+      <td>End</td>
+    </tr>
+    <tr>
+      <td>Move Page Up</td>
+      <td>Page Up</td>
+      <td>Page Up</td>
+    </tr>
+    <tr>
+      <td>Move Page Down</td>
+      <td>Page Down</td>
+      <td>Page Down</td>
+    </tr>
+    <tr>
+      <td>OK</td>
+      <td>-</td>
+      <td>-</td>
+    </tr>
+    <tr>
+      <td>Cancel</td>
+      <td>Escape</td>
+      <td>Escape</td>
+    </tr>
+    <tr>
+      <td>Select item</td>
+      <td>Return/Enter/Space</td>
+      <td>Return/Enter/Space</td>
+    </tr>
+    <tr>
+      <td>Move to previous object</td>
+      <td>Shift + Tab</td>
+      <td>Shift + Tab</td>
+    </tr>
+    <tr>
+      <td>Move to next object</td>
+      <td>Tab</td>
+      <td>Tab</td>
+    </tr>
+    <tr>
+      <td>Move to previous tab</td>
+      <td>Shift-Control + Tab</td>
+      <td>Shift-Control + Tab</td>
+    </tr>
+    <tr>
+      <td>Move to next tab</td>
+      <td>Control + Tab</td>
+      <td>Control + Tab</td>
+    </tr>
+    <tr>
+      <td>Go to parent directory</td>
+      <td>Backspace</td>
+      <td>Backspace</td>
+    </tr>
+    <tr>
+      <td>Toggle windowed/fullscreen mode</td>
+      <td>Alt + Return</td>
+      <td>Cmd + Return</td>
+    </tr>
+    <tr>
+      <td>Exit emulator</td>
+      <td>Control + q</td>
+      <td>Cmd + q</td>
+    </tr>
+  </table>
+
   <p><b>UI Keys in Text Editing areas (cannot be remapped)</b></p>
 
   <table BORDER=2 cellpadding=4>
-    <tr><th>Key</th><th>Editor Function</th></tr>
-    <tr><td>Home</td><td>Move cursor to beginning of line</td></tr>
-    <tr><td>End</td><td>Move cursor to end of line</td></tr>
-    <tr><td>Delete</td><td>Remove character to right of cursor</td></tr>
-    <tr><td>Backspace</td><td>Remove character to left of cursor</td></tr>
-    <tr><td>Control-a</td><td>Same function as 'Home'</td></tr>
-    <tr><td>Control-e</td><td>Same function as 'End'</td></tr>
-    <tr><td>Control-d</td><td>Same function as 'Delete'</td></tr>
-    <tr><td>Control-k</td><td>Remove all characters from cursor to end of line</td></tr>
-    <tr><td>Control-u</td><td>Remove all characters from cursor to beginning of line</td></tr>
-    <tr><td>Control-w</td><td>Remove entire word to left of cursor</td></tr>
-    <tr><td>Control-Left</td><td>Move cursor to beginning of word to the left</td></tr>
-    <tr><td>Control-Right</td><td>Move cursor to beginning of word to the right</td></tr>
-    <tr><td>Control-c</td><td>Copy entire line to clipboard (not complete)</td></tr>
-    <tr><td>Control-v</td><td>Paste clipboard contents (not complete)</td></tr>
+    <tr>
+      <th>Function</th>
+      <th>Key (Standard)</th>
+      <th>Key (macOS)</th>
+    </tr>
+    <tr>
+      <td>Move cursor to previous character</td>
+      <td>Left arrow</td>
+      <td>Left arrow</td>
+    </tr>
+    <tr>
+      <td>Move cursor to next character</td>
+      <td>Right arrow</td>
+      <td>Right arrow</td>
+    </tr>
+    <tr>
+      <td>Move cursor to beginning of current word</td>
+      <td>Control + Left arrow</td>
+      <td>Option + Left arrow</td>
+    </tr>
+    <tr>
+      <td>Move cursor to beginning of next word</td>
+      <td>Control + Right arrow</td>
+      <td>Option + Right arrow</td>
+    </tr>
+    <tr>
+      <td>Move cursor to beginning of line</td>
+      <td>Home</td>
+      <td>Home, Control + a, Command + Left arrow</td>
+    </tr>
+    <tr>
+      <td>Move cursor to end of line</td>
+      <td>End</td>
+      <td>End, Control + e, Command + Right arrow</td>
+    </tr>
+    <tr>
+      <td>Delete character to left of cursor</td>
+      <td>Backspace</td>
+      <td>Backspace</td>
+    </tr>
+    <tr>
+      <td>Delete character to right of cursor</td>
+      <td>Delete, Control + d</td>
+      <td>Delete, Control + d</td>
+    </tr>
+    <tr>
+      <td>Delete word to left of cursor</td>
+      <td>Control + Backspace, Control + w</td>
+      <td>Option + Backspace, Control + w</td>
+    </tr>
+    <tr>
+      <td>Delete word to right of cursor</td>
+      <td>Control + Delete, Alt + d</td>
+      <td>Option + Delete</td>
+    </tr>
+    <tr>
+      <td>Delete all text to beginning of line</td>
+      <td>Control + Home, Control + u</td>
+      <td>Command + Backspace, Control + u</td>
+    </tr>
+    <tr>
+      <td>Delete all text to end of line</td>
+      <td>Control + End, Control + k</td>
+      <td>Control + k</td>
+    </tr>
+    <tr>
+      <td>Select character to left of cursor</td>
+      <td>Shift + Left arrow</td>
+      <td>Shift + Left arrow</td>
+    </tr>
+    <tr>
+      <td>Select character to right of cursor</td>
+      <td>Shift + Right arrow</td>
+      <td>Shift + Right arrow</td>
+    </tr>
+    <tr>
+      <td>Select all text to beginning of current word</td>
+      <td>Shift-Control + Left arrow</td>
+      <td>Shift-Option + Left arrow</td>
+    </tr>
+    <tr>
+      <td>Select all text to beginning of next word</td>
+      <td>Shift-Control + Right arrow</td>
+      <td>Shift-Option + Right arrow</td>
+    </tr>
+    <tr>
+      <td>Select all text to beginning of line</td>
+      <td>Shift + Home</td>
+      <td>Shift + Home, Shift-Control + a, Shift-Command + Left arrow</td>
+    </tr>
+    <tr>
+      <td>Select all text to end of line</td>
+      <td>Shift + End</td>
+      <td>Shift + End, Shift-Control + e, Shift-Command + Right arrow</td>
+    </tr>
+    <tr>
+      <td>Select all text</td>
+      <td>Control + a</td>
+      <td>Command + a</td>
+    </tr>
+    <tr>
+      <td>Cut selected text</td>
+      <td>Control + x, Shift + Delete</td>
+      <td>Command + x</td>
+    </tr>
+    <tr>
+      <td>Copy selected text</td>
+      <td>Control + c, Control + Insert</td>
+      <td>Command + c</td>
+    </tr>
+    <tr>
+      <td>Paste at cursor and replace selection</td>
+      <td>Control + v, Shift + Insert</td>
+      <td>Command + v</td>
+    </tr>
+    <tr>
+      <td>Undo last operation</td>
+      <td>Control + z</td>
+      <td>Command + z</td>
+    </tr>
+    <tr>
+      <td>Redo last operation</td>
+      <td>Control + y, Shift-Control + z</td>
+      <td>Command + y, Shift-Command + z</td>
+    </tr>
   </table>
+  </br>
+
   </blockquote></br>
 
   <h2><b><a name="ControlMap">Controller Map</a></b></h2>
@@ -2085,9 +2288,9 @@
   <blockquote>
 
   <p>In addition to the built in ROM launcher, Stella can also be used from the
-  commandline (assuming your operating system has a commandline).</p>
+  command line (assuming your operating system has a command line).</p>
 
-  <p>To run Stella from the commandline, use the following format:</p>
+  <p>To run Stella from the command line, use the following format:</p>
 
   <pre>   stella [options ...] ROM_FILENAME</pre>
 
@@ -2119,24 +2322,24 @@
 
     <tr>
       <td><pre>-center &lt;1|0&gt;</pre></td>
-      <td>Centers all windows (if possible).</td>
+      <td>Center all windows (if possible).</td>
     </tr>
 
     <tr>
       <td><pre>-windowedpos &lt;XxY&gt;</pre></td>
-      <td>Sets the window position in windowed emulator mode.</td>
+      <td>Set the window position in windowed emulator mode.</td>
     </tr>
 
     <tr>
       <td><pre>-display &lt;number&gt;</pre></td>
-      <td>Sets the display for Stella's emulator.</td>
+      <td>Set the display for Stella's emulator.</td>
     </tr>
 
     <tr>
       <td><pre>-palette &lt;standard|z26|user|custom&gt;</pre></td>
       <td>Set the palette to either normal Stella, the one used in the z26
         emulator, a user-defined palette, or a custom palette generated
-        from user-defined phase shifts.</td>
+        from user-defined parameters.</td>
     </tr>
 
     <tr>
@@ -2149,6 +2352,36 @@
       <td>Adjust phase shift of 'custom' PAL palette.</td>
     </tr>
 
+    <tr>
+      <td><pre>-pal.red_scale &lt;number&gt;</pre></td>
+      <td>Adjust red scale of 'custom' palette (range -1.0 to 1.0).</td>
+    </tr>
+
+    <tr>
+      <td><pre>-pal.red_shift &lt;number&gt;</pre></td>
+      <td>Adjust red shift of 'custom' palette (range -22.5 to 22.5).</td>
+    </tr>
+
+    <tr>
+      <td><pre>-pal.green_scale &lt;number&gt;</pre></td>
+      <td>Adjust green scale of 'custom' palette (range -1.0 to 1.0).</td>
+    </tr>
+
+    <tr>
+      <td><pre>-pal.green_shift &lt;number&gt;</pre></td>
+      <td>Adjust green shift of 'custom' palette (range -22.5 to 22.5).</td>
+    </tr>
+
+    <tr>
+      <td><pre>-pal.blue_scale &lt;number&gt;</pre></td>
+      <td>Adjust blue scale of 'custom' palette (range -1.0 to 1.0).</td>
+    </tr>
+
+    <tr>
+      <td><pre>-pal.blue_shift &lt;number&gt;</pre></td>
+      <td>Adjust blue shift of 'custom' palette (range -22.5 to 22.5).</td>
+    </tr>
+
     <tr>
       <td><pre>-pal.hue &lt;number&gt;</pre></td>
       <td>Adjust hue of current palette (range -1.0 to 1.0).</td>
@@ -2191,108 +2424,113 @@
         shown.</td>
     </tr>
 
-  <tr>
-    <td><pre>-audio.enabled &lt;1|0&gt;</pre></td>
-    <td>Enable or disable sound generation.</td>
-  </tr>
+    <tr>
+      <td><pre>-audio.enabled &lt;1|0&gt;</pre></td>
+      <td>Enable or disable sound generation.</td>
+    </tr>
 
-  <tr>
-    <td><pre>-audio.volume &lt;0 - 100&gt;</pre></td>
-    <td>Set the volume.</td>
-  </tr>
+    <tr>
+      <td><pre>-audio.volume &lt;0 - 100&gt;</pre></td>
+      <td>Set the volume.</td>
+    </tr>
 
-  <tr>
-    <td><pre>-audio.device &lt;number&gt;</pre></td>
-    <td>Set the audio device (0 = default).</td>
-  </tr>
+    <tr>
+      <td><pre>-audio.device &lt;number&gt;</pre></td>
+      <td>Set the audio device (0 = default).</td>
+    </tr>
 
-  <tr>
-    <td><pre>-audio.preset &lt;1 - 5&gt;</pre></td>
-    <td>Set an audio preset. Numbers in sequence represent presets for
-    'custom', 'low quality, medium lag', 'high quality, medium lag',
-    'high quality, low lag' and 'ultra quality, minimal lag'.</td>
-  </tr>
+    <tr>
+      <td><pre>-audio.preset &lt;1 - 5&gt;</pre></td>
+      <td>Set an audio preset. Numbers in sequence represent presets for
+      'custom', 'low quality, medium lag', 'high quality, medium lag',
+      'high quality, low lag' and 'ultra quality, minimal lag'.</td>
+    </tr>
 
-  <tr>
-    <td><pre>-audio.fragment_size &lt;128|256|512|1024|2048|4096&gt;</pre></td>
-    <td>Set the number of samples in a single fragment processed by the audio driver.</td>
-  </tr>
+    <tr>
+      <td><pre>-audio.fragment_size &lt;128|256|512|1024|2048|4096&gt;</pre></td>
+      <td>Set the number of samples in a single fragment processed by the audio driver.</td>
+    </tr>
 
-  <tr>
-    <td><pre>-audio.sample_rate &lt;44100|48000|96000&gt;</pre></td>
-    <td>Set sound sample output frequency.</td>
-  </tr>
+    <tr>
+      <td><pre>-audio.sample_rate &lt;44100|48000|96000&gt;</pre></td>
+      <td>Set sound sample output frequency.</td>
+    </tr>
 
-  <tr>
-    <td><pre>-audio.resampling_quality &lt;1|2|3&gt;</pre></td>
-    <td>Set resampling quality to low (1), high (2) or ultra (3).</td>
-  </tr>
+    <tr>
+      <td><pre>-audio.resampling_quality &lt;1|2|3&gt;</pre></td>
+      <td>Set resampling quality to low (1), high (2) or ultra (3).</td>
+    </tr>
 
-  <tr>
-    <td><pre>-audio.headroom &lt;0 - 20&gt;</pre></td>
-    <td>Set number of additional half-frames to prebuffer.</td>
-  </tr>
+    <tr>
+      <td><pre>-audio.headroom &lt;0 - 20&gt;</pre></td>
+      <td>Set number of additional half-frames to prebuffer.</td>
+    </tr>
 
-  <tr>
-    <td><pre>-audio.buffer_size &lt;0 - 20&gt;</pre></td>
-    <td>Set maximum number of additional half-frames to buffer.</td>
-  </tr>
+    <tr>
+      <td><pre>-audio.buffer_size &lt;0 - 20&gt;</pre></td>
+      <td>Set maximum number of additional half-frames to buffer.</td>
+    </tr>
 
-  <tr>
-    <td><pre>-audio.stereo &lt;1|0&gt;</pre></td>
-    <td>Enable or disable stereo mode for all ROMs.</td>
-  </tr>
+    <tr>
+      <td><pre>-audio.stereo &lt;1|0&gt;</pre></td>
+      <td>Enable or disable stereo mode for all ROMs.</td>
+    </tr>
 
-  <tr>
-    <td><pre>-audio.dpc_pitch &lt;10000 - 30000&gt;</pre></td>
-    <td>Set the pitch of Pitfall II music.</td>
-  </tr>
+    <tr>
+      <td><pre>-audio.dpc_pitch &lt;10000 - 30000&gt;</pre></td>
+      <td>Set the pitch of Pitfall II music.</td>
+    </tr>
 
-  <tr>
-    <td><pre>-tia.zoom &lt;zoom&gt;</pre></td>
-    <td>Use the specified zoom level (integer) while in TIA/emulation mode.
-    </td>
-  </tr>
+    <tr>
+      <td><pre>-tia.zoom &lt;zoom&gt;</pre></td>
+      <td>Use the specified zoom level (integer) while in TIA/emulation mode.
+      </td>
+    </tr>
 
-  <tr>
-    <td><pre>-tia.vsizeadjust &lt;-5 - 5&gt;</pre></td>
-    <td>Adjust the display height of the TIA image
-    </td>
-  </tr>
+    <tr>
+      <td><pre>-tia.vsizeadjust &lt;-5 - 5&gt;</pre></td>
+      <td>Adjust the display height of the TIA image
+      </td>
+    </tr>
 
-  <tr>
-    <td><pre>-tia.inter &lt;1|0&gt;</pre></td>
-    <td>Use interpolation for the TIA image (results in blending/smoothing
-      of the image).</td>
-  </tr>
+    <tr>
+      <td><pre>-tia.inter &lt;1|0&gt;</pre></td>
+      <td>Use interpolation for the TIA image (results in blending/smoothing
+        of the image).</td>
+    </tr>
 
-  <tr>
-    <td><pre>-tia.fs_stretch &lt;1|0&gt;</pre></td>
-    <td>Stretch TIA image completely while in fullscreen mode, vs. keeping the correct
-      aspect ratio.</td>
-  </tr>
+    <tr>
+      <td><pre>-tia.fs_stretch &lt;1|0&gt;</pre></td>
+      <td>Stretch TIA image completely while in fullscreen mode, vs. keeping the correct
+        aspect ratio.</td>
+    </tr>
 
-  <tr>
-    <td><pre>-tia.fs_refresh &lt;1|0&gt;</pre></td>
-    <td>While in fullscreen mode, adapt the display's refresh rate to the game's frame rate
-      to minimize judder.</br>
-      Note: Not available for macOS.</td>
-  </tr>
+    <tr>
+      <td><pre>-tia.fs_refresh &lt;1|0&gt;</pre></td>
+      <td>While in fullscreen mode, adapt the display's refresh rate to the game's frame rate
+        to minimize judder.</br>
+        Note: Not available for macOS.</td>
+    </tr>
 
-  <tr>
-    <td><pre>-tia.fs_overscan &lt;0 - 10&gt;</pre></td>
-    <td>Add overscan to TIA image while in fullscreen mode</td>
+    <tr>
+      <td><pre>-tia.fs_overscan &lt;0 - 10&gt;</pre></td>
+      <td>Add overscan to TIA image while in fullscreen mode</td>
     </tr>
 
     <tr>
       <td><pre>-tia.dbgcolors &lt;roygbp&gt;</pre></td>
-      <td>Assigns the colours (R)ed, (O)range, (Y)ellow, (G)reen, (B)lue and (P)urple
+      <td>Assign the colours (R)ed, (O)range, (Y)ellow, (G)reen, (B)lue and (P)urple
         to each graphical register P0/M0/P1/M1/PF/BL, respectively. Currently,
         these change be changed around to apply different colours to the
         respective register.
       </td>
     </tr>
 
+    <tr>
+      <td><pre>-tia.correct_aspect &lt;1|0&gt;</pre></td>
+      <td>Enable aspect ratio correct scaling.</td>
+    </tr>
+
     <tr>
       <td><pre>-tv.filter &lt;0 - 5&gt;</pre></td>
       <td>Blargg TV effects, 0 is disabled, next numbers in
@@ -2332,7 +2570,7 @@
 
     <tr>
       <td><pre>-tv.phosphor &lt;always|byrom&gt;</pre></td>
-      <td>Determines how phosphor mode is enabled. If 'always', then the
+      <td>Determine how phosphor mode is enabled. If 'always', then the
         ROM properties entry is ignored, and phosphor mode is always turned
         on. Otherwise, the ROM properties determine whether phosphor mode
         is used for each ROM.
@@ -2354,7 +2592,7 @@
 
     <tr>
       <td><pre>-tv.scanlines &lt;0 - 100&gt;</pre></td>
-      <td>TV effects scanline intensity, where 0 means completely off. Note: No scanlines in 1x mode snapshots.</td>
+      <td>Set TV effects scanline intensity, where 0 means completely off. Note: No scanlines in 1x mode snapshots.</td>
     </tr>
 
     <tr>
@@ -2364,17 +2602,17 @@
 
     <tr>
       <td><pre>-loglevel &lt;0|1|2&gt;</pre></td>
-      <td>Indicates level of logging to perform while the application is running. Zero completely disables logging (except for serious errors), while the remaining numbers show increasingly more detail.</td>
+      <td>Indicate level of logging to perform while the application is running. Zero completely disables logging (except for serious errors), while the remaining numbers show increasingly more detail.</td>
     </tr>
 
     <tr>
       <td><pre>-logtoconsole &lt;1|0&gt;</pre></td>
-      <td>Indicates that logged output should be printed to the console/commandline as it's being collected. An internal log will still be kept, and the amount of logging is still controlled by 'loglevel'.</td>
+      <td>Indicate that logged output should be printed to the console/command line as it's being collected. An internal log will still be kept, and the amount of logging is still controlled by 'loglevel'.</td>
     </tr>
 
     <tr>
       <td><pre>-joydeadzone &lt;number&gt;</pre></td>
-      <td>Sets the joystick axis deadzone area for analog joysticks/gamepads.
+      <td>Set the joystick axis deadzone area for analog joysticks/gamepads.
         All values within the deadzone are treated as zero-axis values,
         while only those values outside are registered as valid input.
         Accepts a number from 0 - 29, and uses the formula
@@ -2419,17 +2657,17 @@
 
     <tr>
       <td><pre>-modcombo &lt;1|0&gt;</pre></td>
-      <td>Use modifier(Shift/Alt/Control)-x key combos. This is normally enabled,
-      since the 'Quit' command is tied to 'Control-q'. However, there are times
+      <td>Use modifier(Shift/Alt/Control) + x key combos. This is normally enabled,
+      since the 'Quit' command is tied to 'Control + q'. However, there are times
       when you want to disable them.</br>
       E.g. a 2-player game is using either the 'f' or 'r' keys for movement,
       and pressing Control (for Fire) will perform an unwanted action
-      associated with Control-r or Control-f default keys.</td>
+      associated with 'Control + r' or 'Control + f' default keys.</td>
     </tr>
 
     <tr>
       <td><pre>-saport &lt;lr|rl&gt;</pre></td>
-      <td>Determines how to enumerate the Stelladaptor/2600-daptor devices in the
+      <td>Determine how to enumerate the Stelladaptor/2600-daptor devices in the
       order they are found: 'lr' means first is left port, second is right port,
       'rl' means the opposite.</td>
     </tr>
@@ -2475,7 +2713,7 @@
 
     <tr>
       <td><pre>-grabmouse &lt;1|0&gt;</pre></td>
-      <td>Locks the mouse cursor in the game window in emulation mode.</td>
+      <td>Lock the mouse cursor in the game window in emulation mode.</td>
     </tr>
 
     <tr>
@@ -2541,7 +2779,7 @@
 
     <tr>
       <td><pre>-listrominfo</pre></td>
-      <td>Prints relevant contents of the Stella ROM database, one ROM per line,
+      <td>Print relevant contents of the Stella ROM database, one ROM per line,
         and then exit Stella. This can be used for external frontends.</td>
     </tr>
 
@@ -2553,12 +2791,12 @@
 
     <tr>
       <td><pre>-launcherpos &lt;XxY&gt;</pre></td>
-      <td>Sets the window position in windowed ROM launcher mode.</td>
+      <td>Set the window position in windowed ROM launcher mode.</td>
     </tr>
 
     <tr>
       <td><pre>-launcherdisplay &lt;number&gt;</pre></td>
-      <td>Sets the display for the ROM launcher.</td>
+      <td>Set the display for the ROM launcher.</td>
     </tr>
 
     <tr>
@@ -2585,7 +2823,7 @@
     </tr>
 
     <tr>
-      <td><pre>-uipalette &lt;standard|classic|light&gt;</pre></td>
+      <td><pre>-uipalette &lt;standard|classic|light|dark&gt;</pre></td>
       <td>Use the specified palette for UI elements.</td>
     </tr>
 
@@ -2601,7 +2839,7 @@
 
     <tr>
       <td><pre>-hidpi &lt;0|1&gt;</pre></td>
-      <td>Enables the HiDPI mode which scales the UI by a factor of two.</td>
+      <td>Enable the HiDPI mode which scales the UI by a factor of two.</td>
     </tr>
 
     <tr>
@@ -2688,13 +2926,13 @@
 
     <tr>
       <td><pre>-dis.gfxformat &lt;2|16&gt;</pre></td>
-      <td>Sets the base to use for displaying GFX sections in the disassembler.
+      <td>Set the base to use for displaying GFX sections in the disassembler.
       </td>
     </tr>
 
     <tr>
       <td><pre>-dis.showaddr &lt;1|0&gt;</pre></td>
-      <td>Shows/hides opcode addresses in the disassembler.</td>
+      <td>Show/hide opcode addresses in the disassembler.</td>
     </tr>
 
     <tr>
@@ -2704,12 +2942,12 @@
 
     <tr>
       <td><pre>-dbg.pos &lt;XxY&gt;</pre></td>
-      <td>Sets the window position in windowed debugger mode.</td>
+      <td>Set the window position in windowed debugger mode.</td>
     </tr>
 
     <tr>
       <td><pre>-dbg.display &lt;number&gt;</pre></td>
-      <td>Sets the display for the debugger.</td>
+      <td>Set the display for the debugger.</td>
     </tr>
 
     <tr>
@@ -2778,7 +3016,7 @@
 
     <tr>
       <td><pre>-bs &lt;type&gt;</pre></td>
-      <td>Set "Cart.Type" property. See the <a href="#Properties"><b>Game Properties</b></a> section
+      <td>Set "Cart.Type" property. See the <a href="#Emulation"><b>Emulation Properties</b></a> section
         for valid types.</td>
     </tr>
 
@@ -2819,20 +3057,51 @@
 
     <tr>
       <td><pre>-lc &lt;type&gt;</pre></td>
-      <td>Set "Controller.Left" property. See the <a href="#Properties"><b>Game Properties</b></a>
+      <td>Set "Controller.Left" property. See the <a href="#Controller"><b>Controller Properties</b></a>
+        section for valid types.</td>
+    </tr>
+
+    <tr>
+      <td><pre>-lq1 &lt;type&gt;</pre></td>
+      <td>Set "Controller.Left1" property for QuadTari. See the <a href="#Quadtari"><b>QuadTari Properties</b></a>
+        section for valid types.</td>
+    </tr>
+
+    <tr>
+      <td><pre>-lq2 &lt;type&gt;</pre></td>
+      <td>Set "Controller.Left2" property for QuadTari. See the <a href="#Quadtari"><b>QuadTari Properties</b></a>
         section for valid types.</td>
     </tr>
 
     <tr>
       <td><pre>-rc &lt;type&gt;</pre></td>
-      <td>Set "Controller.Right" property. See the <a href="#Properties"><b>Game Properties</b></a>
+      <td>Set "Controller.Right" property. See the <a href="#Controller"><b>Controller Properties</b></a>
+        section for valid types.</td>
+    </tr>
+
+
+    <tr>
+      <td><pre>-rq1 &lt;type&gt;</pre></td>
+      <td>Set "Controller.Right1" property for QuadTari. See the <a href="#Quadtari"><b>QuadTari Properties</b></a>
+        section for valid types.</td>
+    </tr>
+
+    <tr>
+      <td><pre>-rq2 &lt;type&gt;</pre></td>
+      <td>Set "Controller.Right2" property for QuadTari. See the <a href="#Quadtari"><b>QuadTari Properties</b></a>
         section for valid types.</td>
     </tr>
 
     <tr>
       <td><pre>-bc &lt;type&gt;</pre></td>
-      <td>Sets both "Controller.Left" and "Controller.Right" properties.
-        See the <a href="#Properties"><b>Game Properties</b></a> section for valid types.</td>
+      <td>Set both "Controller.Left" and "Controller.Right" properties.
+        See the <a href="#Controller"><b>Controller Properties</b></a> section for valid types.</td>
+    </tr>
+
+    <tr>
+      <td><pre>-aq &lt;type&gt;</pre></td>
+      <td>Set "Controller.Left1", "Controller.Left2", "Controller.Right1" and "Controller.Right2" properties for QuadTari.
+        See the <a href="#Quadtari"><b>QuadTari Properties</b></a> section for valid types.</td>
     </tr>
 
     <tr>
@@ -2853,12 +3122,12 @@
     <tr>
       <td><pre>-ma &lt;Auto|XY&gt;</pre></td>
       <td>Set "Controller.MouseAxis" property.
-        See the <a href="#Properties"><b>Game Properties</b></a> section for valid types.</td>
+        See the <a href="#Controller"><b>Controller Properties</b></a> section for valid types.</td>
     </tr>
 
     <tr>
       <td><pre>-format &lt;format&gt;</pre></td>
-      <td>Set "Display.Format" property. See the <a href="#Properties"><b>Game Properties</b></a> section
+      <td>Set "Display.Format" property. See the <a href="#Emulation"><b>Emulation Properties</b></a> section
         for valid formats.</td></td>
     </tr>
 
@@ -2940,7 +3209,7 @@
       <td>When enabled, each read or write access to the AtariVox/SaveKey EEPROM is
         signalled by a message.</td>
     </tr><tr>
-      <td><pre>-dev.tia.type &lt;standard|koolaidman|</br>  cosmicark|pesco|quickstep|heman|custom&gt;</pre></td>
+      <td><pre>-dev.tia.type &lt;standard|koolaidman|cosmicark|</br>  pesco|quickstep|indy500|heman|custom&gt;</pre></td>
       <td>Set emulated TIA type.</td>
     </tr><tr>
       <td><pre>-dev.tia.plinvphase &lt;1|0&gt;</pre></td>
@@ -2957,6 +3226,9 @@
     </tr><tr>
       <td><pre>-dev.tia.delaypfcolor &lt;1|0&gt;</pre></td>
       <td>Enable/disable playfield color delayed by one color clock (colored step borders in Quick Step!).</td>
+    </tr><tr>
+      <td><pre>-dev.tia.delaybkcolor &lt;1|0&gt;</pre></td>
+      <td>Enable/disable background color delayed by one color clock (stray pixels in Indy 500 menu hack).</td>
     </tr><tr>
       <td><pre>-dev.tia.delayplswap &lt;1|0&gt;</pre></td>
       <td>Enable/disable player swap delayed by one color clock (He-Man title glitch).</td>
@@ -3017,17 +3289,19 @@
       <td>&nbsp;&nbsp;&nbsp;&nbsp;</td>
       <td valign="top">
         <table border="1" cellpadding="4">
-          <tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">CommandLine</a></th></tr>
-          <tr><td>Renderer</td><td>Use specified rendering mode</td><td>-video</td></tr>
-          <tr><td>Interpolation</td><td>Enable interpolation of the TIA image</td><td>-tia.inter</td></tr>
-          <tr><td>Zoom</td><td>Zoom level of the TIA image</td><td>-tia.zoom</td></tr>
+          <tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">Command Line</a></th></tr>
+          <tr><td>Renderer</td><td>Use specified rendering mode.</td><td>-video</td></tr>
+          <tr><td>Interpolation</td><td>Enable interpolation of the TIA image.</td><td>-tia.inter</td></tr>
+          <tr><td>Zoom</td><td>Adjust the zoom level of the TIA image</td><td>-tia.zoom</td></tr>
           <tr><td>Fullscreen</td><td>Self-explanatory - Note that colors may slightly change.
                   This depends on the OS and renderer used.</td><td>-fullscreen</td></tr>
           <tr><td>Stretch</td><td>In fullscreen mode, completely fill screen with the TIA image.</td><td>-tia.fs_stretch</td></tr>
           <tr><td>Adapt display...</td><td>In fullscreen mode, adapt the display's refresh rate to the game's frame rate to minimize judder.
                   </br>Note: Not available for macOS.</td><td>-tia.fs_refresh</td></tr>
-          <tr><td>Overscan</td><td>In fullscreen mode, add overscan to the TIA image</td><td>-tia.fs_overscan</td></tr>
-          <tr><td>V-Size adjust</td><td>Adjust height of the TIA image</td><td>-tia.vsizeadjust</td></tr>
+          <tr><td>Overscan</td><td>In fullscreen mode, add overscan to the TIA image.</td><td>-tia.fs_overscan</td></tr>
+          <tr><td>Correct aspect ratio</td><td>Enable aspect ratio correct scaling.
+                  </br>Note: Creates a cleaner looking TIA image when disabled (like z26 and old versions of Stella) vs. a correctly emulated aspect ratio when enabled.</td><td>-tia.correct_aspect</td></tr>
+          <tr><td>V-Size adjust</td><td>Adjust the height of the TIA image.</td><td>-tia.vsizeadjust</td></tr>
         </table>
       </td>
     </tr>
@@ -3041,10 +3315,13 @@
       <td>&nbsp;&nbsp;&nbsp;&nbsp;</td>
       <td valign="top">
         <table border="1" cellpadding="4">
-          <tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">CommandLine</a></th></tr>
+          <tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">Command Line</a></th></tr>
           <tr><td>Palette</td><td>Palette used for emulation mode</td><td>-palette</td></tr>
-          <tr><td>NTSC phase</td><td>Adjust phase shift for 'Custom' NTSC palette</td><td>-pal.phase_ntsc</td></tr>
-          <tr><td>PAL phase</td><td>Adjust phase shift for 'Custom' PAL palette</td><td>-pal.phase_pal</td></tr>
+          <tr><td>NTSC phase</td><td>Adjust phase shift of 'Custom' NTSC palette</td><td>-pal.phase_ntsc</td></tr>
+          <tr><td>PAL phase</td><td>Adjust phase shift of 'Custom' PAL palette</td><td>-pal.phase_pal</td></tr>
+          <tr><td>R</td><td>Adjust red scale and shift of 'Custom' palette</td><td>-pal.red_scale, -pal.red_shift</td></tr>
+          <tr><td>G</td><td>Adjust green scale and shift of 'Custom' palette</td><td>-pal.green_scale, -pal.green_shift</td></tr>
+          <tr><td>B</td><td>Adjust blue scale and shift of 'Custom' palette</td><td>-pal.blue_scale, -pal.blue_shift</td></tr>
           <tr><td>Hue</td><td>Adjust hue of currently selected palette</td><td>-pal.hue</td></tr>
           <tr><td>Saturation</td><td>Adjust saturation of currently selected palette</td><td>-pal.saturation</td></tr>
           <tr><td>Contrast</td><td>Adjust contrast of currently selected palette</td><td>-pal.contrast</td></tr>
@@ -3063,7 +3340,7 @@
       <td>&nbsp;&nbsp;&nbsp;&nbsp;</td>
       <td valign="top">
         <table border="1" cellpadding="4">
-          <tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">CommandLine</a></th></tr>
+          <tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">Command Line</a></th></tr>
           <tr><td>TV mode</td><td>Disable TV effects, or select TV preset</td><td>-tv.filter</td></tr>
           <tr><td>Adjustable sliders</td><td>Set specific attribute in 'Custom' TV mode</td><td>-tv.sharpness, -tv.resolution, etc.</td></tr>
           <tr><td>Phosphor for all ROMs</td><td>Enable phosphor mode for all ROMs</td><td>-tv.phosphor</td></tr>
@@ -3089,7 +3366,7 @@
       <td>&nbsp;&nbsp;&nbsp;&nbsp;</td>
       <td valign="top">
         <table border="1" cellpadding="4">
-          <tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">CommandLine</a></th></tr>
+          <tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">Command Line</a></th></tr>
           <tr><td>Enable audio</td><td>Self-explanatory</td><td>-audio.enabled</td></tr>
           <tr><td>Volume</td><td>Self-explanatory</td><td>-audio.volume</td></tr>
           <tr><td>Device</td><td>Use the specified audio device.</td><td>-audio.device</td></tr>
@@ -3134,7 +3411,7 @@
       <td>&nbsp;&nbsp;&nbsp;&nbsp;</td>
       <td valign="top">
         <table border="1" cellpadding="4">
-          <tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">CommandLine</a></th></tr>
+          <tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">Command Line</a></th></tr>
           <tr><td>Emulation speed</td><td>Emulation speed</td><td>-speed</td></tr>
           <tr><td>VSync</td><td>Enable vertical synced updates</td><td>-vsync</td></tr>
           <tr><td>Turbo</td><td>Enable 'Turbo' mode for maximum emulation speed. This overwrites 'Emulation speed' setting and disables 'VSync'.</td><td>-turbo</td></tr>
@@ -3181,7 +3458,7 @@
       <td>&nbsp;&nbsp;&nbsp;&nbsp;</td>
       <td valign="top">
         <table border="1" cellpadding="4">
-          <tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">CommandLine</a></th></tr>
+          <tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">Command Line</a></th></tr>
           <tr><td>Theme</td><td>Theme to use for UI elements (see examples)</td><td>-uipalette</td></tr>
           <tr><td>Dialogs font</td><td>The font used in the dialogs</td><td>-dialogfont</td></tr>
           <tr><td>HiDPI mode</td><td>Scale the UI by a factor of two when enabled</td><td>-hidpi</td></tr>
@@ -3200,6 +3477,9 @@
       <td>&nbsp;&nbsp;&nbsp;&nbsp;</td>
       <td><img src="graphics/options_misc_light.png"></td>
     </tr>
+    <tr>
+      <td><img src="graphics/options_misc_dark.png"></td>
+    </tr>
   </table>
   <br>
   <table border="5" cellpadding="2" frame="box" rules="none">
@@ -3219,7 +3499,7 @@
       <td>&nbsp;&nbsp;&nbsp;&nbsp;</td>
       <td valign="top">
         <table border="1" cellpadding="4">
-          <tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">CommandLine</a></th></tr>
+          <tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">Command Line</a></th></tr>
           <tr><td>Save path</td><td>Specifies where to save snapshots</td><td>-snapsavedir</td></tr>
         <!--<tr><td>Load path</td><td>Specifies where to load snapshots</td><td>-snaploaddir</td></tr>  -->
           <tr><td>Continuous snapshot interval</td><td>Interval (in seconds) between snapshots</td><td>-ssinterval</td></tr>
@@ -3332,7 +3612,7 @@
       <td>&nbsp;&nbsp;&nbsp;&nbsp;</td>
       <td valign="top">
         <table border="1" cellpadding="4">
-          <tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">CommandLine</a></th></tr>
+          <tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">Command Line</a></th></tr>
           <tr><td>Joystick deadzone size</td><td>Deadzone area for axes on joysticks/gamepads</td><td>-joydeadzone</td></tr>
           <tr><td>(Analog paddle) Sensitivity</td><td>Sensitivity of an analog paddle</td><td>-psense</td></tr>
           <tr><td>Analog paddle) Dejitter averaging</td><td>Strength of paddle input averaging, suppresses mouse jitter</td><td>-dejitter.base</td></tr>
@@ -3357,7 +3637,7 @@
       <td>&nbsp;&nbsp;&nbsp;&nbsp;</td>
       <td valign="top">
         <table border="1" cellpadding="4">
-          <tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">CommandLine</a></th></tr>
+          <tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">Command Line</a></th></tr>
           <tr><td>Use mouse as ...</td><td>Allow the mouse to emulate various controllers</td><td>-usemouse</td></tr>
           <tr><td>(Sensitivity) Paddle</td><td>Sensitivity used when emulating a paddle using a mouse</td><td>-msense</td></tr>
           <tr><td>(Sensitivity) Trackball</td><td>Sensitivity used when emulating a trackball device using a mouse</td><td>-tsense</td></tr>
@@ -3409,15 +3689,29 @@
   <p>ROM Info Viewer width at 50% , UI sized 1280x900, large launcher font:</p>
   <img src="graphics/rominfo_2x_small.png">
 
-  <p>The text box in the upper right corner can be used to narrow down the
-  results in the ROM listing. When this box is empty, all files are shown
-  (subject to the restrictions from the filtering option, explained below).
-  Typing characters here will show only those files that match that
-  pattern. For example, typing 'Activision' will show only files that
-  contain the word 'Activision' in their name. This is very useful for
-  quickly finding a group of related ROMs. Note that the search is not
-  case sensitive, so you don't need to worry about capital or lower-case
-  letters.</p>
+  <p>The dialog items at the top can be used to define the listed files:</p>
+
+  <ul>
+    <li>
+      The 'Show all files' checkbox allows displaying files which do not
+      have a valid ROM extension.
+    </li><li>
+      If 'Incl. subdirectories' is checked, Stella will list matching files
+      from all subdirectories too.
+    </li><li>
+      The 'Filter' text box can be used to narrow down the results in the
+      ROM listing. When this box is empty, all files are shown. Typing
+      characters here will show only those files that match that
+      pattern. For example, typing 'Activision' will show only files that
+      contain the word 'Activision' in their name. This is very useful for
+      quickly finding a group of related ROMs.</br>
+      Note that the search is not case sensitive, so you don't need to worry
+      about capital or lower-case letters. You also can use '*' and '?' as
+      wildcards. E.g. for '(198?)*atari' only ROMs from the 1980s made by
+      Atari will be listed.
+    </li>
+  </ul>
+  </br>
 
   <h3><b><a name="ROMLauncherContextMenu">ROM Launcher Context Menu</a></b></h3>
 
@@ -3455,14 +3749,8 @@
     </tr>
   </table>
     </li>
-    <br><li><b>Show only ROM files</b>: Selecting this reloads the current listing,
-    showing only files that have a valid ROM extension.</li>
-
-    <br><li><b>Show all files</b>: Selecting this reloads the current listing,
-    showing <i>all</i> files (with no restriction on file name).</li>
-
     <br><li><b>Reload listing</b>: Selecting this performs a reload of the
-    current listing. It is an alternative to pressing the Control-r
+    current listing. It is an alternative to pressing the 'Control + r'
     key combo.</li>
   </ol></p>
   </blockquote></br>
@@ -3529,7 +3817,7 @@
     <li>Any other devices will be ignored.</li>
 
     <li>The assignment ordering of Stelladaptor/2600-daptor to port can be redefined with
-    'saport' (see description in <a href="#CommandLine"><b>Using the Command Line</b></a>) and dynamically with the 'Control-1' key
+    'saport' (see description in <a href="#CommandLine"><b>Using the Command Line</b></a>) and dynamically with the 'Control + 1' key
     combo.</li>
   </ul>
   </blockquote></br>
@@ -3544,7 +3832,7 @@
   which allow your particular operating system to 'see' the device (configuring
   this is outside the scope of this document). Once your operating system
   properly detects the AtariVox, you will need to tell Stella which serial
-  port it is connected to. This is done by using the '-avoxport' commandline
+  port it is connected to. This is done by using the '-avoxport' command line
   argument, or by setting it in the UI under the 'Devices & Ports' tab in
   <b>Advanced Configuration - <a href="#Remapping">Input Devices</a></b>.</p>
 
@@ -3606,7 +3894,7 @@
       <td>&nbsp;&nbsp;&nbsp;&nbsp;</td>
       <td valign="top">
         <table border="1" cellpadding="4">
-          <tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">CommandLine</a></th></tr>
+          <tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">Command Line</a></th></tr>
           <tr><td>Player/Developer settings</td><td>Selects the active settings set</td><td>-dev.settings</td></tr>
           <tr><td>Console info overlay</td><td>Overlay console info on the TIA image during emulation.</td><td>-plr.stats<br/>-dev.stats</td></tr>
           <tr><td>Detected settings info</td><td>Display detected settings when a ROM is loaded.</td><td>-plr.detectedinfo<br/>-dev.detectedinfo</td></tr>
@@ -3621,7 +3909,7 @@
             <td><span style="white-space:nowrap">-dev.rwportbreak</span></td>
           </tr>
           <tr>
-            <td>Break on write to ...</td>
+            <td>Break on writes to ...</td>
             <td>A write to a read port interrupts emulation and the debugger is entered.</td>
             <td><span style="white-space:nowrap">-dev.wrportbreak</span></td>
           </tr>
@@ -3643,17 +3931,20 @@
       <td>&nbsp;&nbsp;&nbsp;&nbsp;</td>
       <td valign="top">
         <table border="1" cellpadding="4">
-    <tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">CommandLine</a></th></tr>
+    <tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">Command Line</a></th></tr>
     <tr><td>Chip type</td><td>Type of emulated TIA chip. Allows testing for
       TIA versions which exhibit timing problems in certain games. The
       'Custom' option allows testing for glitch combinations.</td><td>-dev.tia.type</td></tr>
     <tr><td>Inverted HMOVE clock...</td><td>Emulates the Kool-Aid Man
       collision and Cosmic Ark stars glitches for the given objects.</td>
       <td>-dev.tia.plinvphase</br>-dev.tia.msinvphase</br>-dev.tia.blinvphase</td></tr>
-    <tr><td>Delayed Playfield</td><td>Emulates playfield registers delayed
+    <tr><td>Delayed Playfield</td><td>Emulates playfield register changes delayed
       by one color clock. This e.g. causes glitches in Pesco (stray playfield
-      pixel) and Quick Step! (colored step borders)</td>
+      pixel) and Quick Step! (colored step borders).</td>
       <td>-dev.tia.delaypfbits</br>-dev.tia.delaypfcolor</td></tr>
+    <tr><td>Delayed Background</td><td>Emulates background color register changes delayed
+      by one color clock. This causes stray pixel in the Indy 500 menu hack.</td>
+      <td>-dev.tia.delaybkcolor</td></tr>
     <tr><td>Delayed VDEL... swap for</td><td>Emulates a VDELP0/P1/BL swap
       delayed by one color clock. This e.g cause glitches in the He-Man title
       screen.</td>
@@ -3670,7 +3961,7 @@
       <td>&nbsp;&nbsp;&nbsp;&nbsp;</td>
       <td valign="top">
         <table border="1" cellpadding="4">
-          <tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">CommandLine</a></th></tr>
+          <tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">Command Line</a></th></tr>
           <tr><td>Jitter/roll effect</td><td>Emulate screen roll with inconsistent scanline count</td><td>-plr.tv.jitter<br/>-dev.tv.jitter</td></tr>
           <tr><td>(Jitter/roll) Recovery</td><td>Determines recovery time for screen rolling</td><td><span style="white-space:nowrap">-plr.tv.jitter_recovery<br/>-dev.tv.jitter_recovery</span></td></tr>
           <tr><td>PAL color-loss</td><td>Use PAL color-loss effect</td><td>-plr.colorloss<br/>-dev.colorloss</td></tr>
@@ -3698,7 +3989,7 @@
       <td valign="top">
         <table border="1" cellpadding="4">
           <tr>
-            <th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">CommandLine</a></th>
+            <th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">Command Line</a></th>
           </tr><tr>
             <td>Time Machine</td>
             <td>
@@ -3752,7 +4043,7 @@
       <td>&nbsp;&nbsp;&nbsp;&nbsp;</td>
       <td valign="top">
         <table border="1" cellpadding="4">
-          <tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">CommandLine</a></th></tr>
+          <tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">Command Line</a></th></tr>
           <tr><td>Font size</td><td>Self-explanatory</td><td>-dbg.fontsize</td></tr>
           <tr><td>Font style</td><td>Self-explanatory</td><td>-dbg.fontstyle</td></tr>
           <tr><td>Debugger width/height</td><td>Self-explanatory</td><td>-dbg.res</td></tr>
@@ -3775,7 +4066,7 @@
     <a href="#DeveloperCommandLine">Developer Commands</a></b> for more information.</li>
 
     <li>Viewing TIA/console information overlaid on the TIA image. This option
-    can be enabled from the commandline or using the Alt-L key combo,
+    can be enabled from the command line or using the Alt-L key combo,
     and is extremely useful for viewing the current scanline count and associated
     frames per second, bankswitch and display formats, etc. The following shows
     an example of this information:
@@ -3967,7 +4258,7 @@ Ms Pac-Man (Stella extended codes):
 
   <p>Stella maintains a log of its operations when the program first starts up, and
   while it is running. In older releases, this information was only viewable from the
-  commandline. However, the current release allows
+  command line. However, the current release allows
   you to see this information from within the UI. This can be selected from the main
   Options menu, where it is labelled "System Logs". Clicking on the button will show
   a window similar to the following:</p>
@@ -3988,7 +4279,7 @@ Ms Pac-Man (Stella extended codes):
 
   <p>The log levels are self-explanatory (None, Basic, Verbose). The "Print to console"
   option emulates the behaviour of older versions of Stella, whereby the logged output
-  is also shown on the commandline from which Stella was launched (if it was launched
+  is also shown on the command line from which Stella was launched (if it was launched
   in that fashion). Finally, the current contents of the system log can be saved to your
   home directory by clicking the "Save log to disk" button.</p>
   </blockquote></br>
@@ -4039,19 +4330,20 @@ Ms Pac-Man (Stella extended codes):
   <p>Each block in a property file consists of a set of properties for a single
   game. Stella supports the properties described below:</p>
 
+  <h3><a name="Emulation"><b>Emulation Properties</b></a></h3>
   <p>
-    <a><img src="graphics/options_gameinfo_emulation.png"></a>
+    <img src="graphics/options_gameinfo_emulation.png">
   </p>
   <table CELLSPACING="10">
 
   <tr>
-    <td VALIGN="TOP"><a name="PropertiesCartType"><i>Cart.Type:</i></a></td>
+    <td VALIGN="TOP"><a name="PropertiesCartType"><i>Cart.Type</i></a></td>
     <td>Indicates the bank-switching type for the game.
       The value of this property must be either <b>Auto</b> or one of the following
       (for more information about bank-switching see Kevin Horton's <a href="http://kevtris.org/files/sizes.txt">2600 bankswitching
       document</a> or the documentation in each cartridge's source code file) types. Types marked
       as (&#185;) do currently have no reliable auto-detection, those marked as (&#178;)
-      are not fully supported in the debugger:
+      are not fully supported in the debugger.
       <table cellpadding="2" border="1">
         <tr><th>&nbsp;Type&nbsp;</th><th>Description</th><th>File Extension<br>(to force type)</th></tr>
         <tr><td>0840 </td><td>8K ECONObanking </td><td>.084, .0840</td></tr>
@@ -4074,7 +4366,7 @@ Ms Pac-Man (Stella extended codes):
         <tr><td>BF </td><td>CPUWIZ 256K </td><td>.BF </td></tr>
         <tr><td>BFSC </td><td>CPUWIZ 256K + RAM</td><td>.BFS, .BFSC </td></tr>
         <tr><td>BUS </td><td>Experimental</td><td>.BUS </td></tr>
-        <tr><td>CDF </td><td>Chris, Darrell, Fred (includes CDFJ)</td><td>.CDF </td></tr>
+        <tr><td>CDF </td><td>Chris, Darrell, Fred (includes CDFJ/CDFJ+)</td><td>.CDF </td></tr>
         <tr><td>CM &#185;</td><td>Spectravideo CompuMate </td><td>.CM </td></tr>
         <tr><td>CTY &#178;</td><td>CDW - Chetiry </td><td>.CTY </td></tr>
         <tr><td>CV </td><td>CommaVid extra RAM </td><td>.CV </td></tr>
@@ -4110,12 +4402,12 @@ Ms Pac-Man (Stella extended codes):
     </tr>
 
     <tr>
-      <td VALIGN="TOP"><i>Cart.StartBank:</i></td>
+      <td VALIGN="TOP"><i>Cart.StartBank</i></td>
       <td>Indicates which bank to use for reading the reset vector.</td>
     </tr>
 
     <tr>
-      <td VALIGN="TOP"><i>Display.Format:</i></td>
+      <td VALIGN="TOP"><i>Display.Format</i></td>
       <td>Indicates the television format the game was designed for. The value
       must be <b>Auto</b> or one of the following. Types marked as (&#185;)
       do currently have no reliable auto-detection. A format can be enforced
@@ -4132,27 +4424,27 @@ Ms Pac-Man (Stella extended codes):
     </tr>
 
     <tr>
-      <td VALIGN="TOP"><i>Display.VCenter:</i></td>
+      <td VALIGN="TOP"><i>Display.VCenter</i></td>
       <td>Indicates the offset for the vertical center of the display.
       The value must be <i>n</i> such that -20 &lt;= <i>n</i> &lt;= 20.
       </td>
     </tr>
 
     <tr>
-      <td VALIGN="TOP"><i>Display.Phosphor:</i></td>
+      <td VALIGN="TOP"><i>Display.Phosphor</i></td>
       <td>Indicates whether the phosphor effect should be emulated or not.
         The value must be <b>Yes</b> or <b>No</b>.</td>
     </tr>
 
     <tr>
-      <td VALIGN="TOP"><i>Display.PPBlend:</i></td>
+      <td VALIGN="TOP"><i>Display.PPBlend</i></td>
       <td>Indicates the amount of blending which will occur while using the
       phosphor effect. The value must be <i>n</i> such that 0 &lt;= <i>n</i>
       &lt;= 100. The default value is whatever is specified for tv.phosblend.</td>
     </tr>
 
     <tr>
-      <td VALIGN="TOP"><i>Cart.Sound:</i></td>
+      <td VALIGN="TOP"><i>Cart.Sound</i></td>
       <td>Indicates if the game should use 1 or 2 channels for sound output.
       All original Atari 2600 machines supported 1 channel only,
       but some homebrew games have been written to take advantage of stereo
@@ -4165,37 +4457,42 @@ Ms Pac-Man (Stella extended codes):
   <p><b>Note:</b> Items marked as '*' are deprecated, and will probably be
   removed in a future release.</p>
 -->
+  <h3><a name="Consoler"><b>Console Properties</b></a></h3>
   <p>
-    <a><img src="graphics/options_gameinfo_console.png"></a>
+    <img src="graphics/options_gameinfo_console.png">
   </p>
 
   <table CELLSPACING="10">
     <tr>
-      <td VALIGN="TOP"><i>Console.TVType:</i></td>
+      <td VALIGN="TOP"><i>Console.TVType</i></td>
       <td>Indicates the default television setting for the
       game. The value must be <b>Color</b> or <b>BW</b>.</td>
     </tr>
 
     <tr>
-      <td VALIGN="TOP"><i>Console.LeftDiff:</i></td>
+      <td VALIGN="TOP"><i>Console.LeftDiff</i></td>
       <td>Indicates the default difficulty setting for the left
       player. The value must be <b>A</b> or <b>B</b>.</td>
     </tr>
 
     <tr>
-      <td VALIGN="TOP"><i>Console.RightDiff:</i></td>
+      <td VALIGN="TOP"><i>Console.RightDiff</i></td>
       <td>Indicates the default difficulty setting for the
       right player. The value must be <b>A</b> or <b>B</b>.</td>
     </tr>
   </table>
   </br>
 
+  <h3><a name="Controller"><b>Controller Properties</b></a></h3>
   <p>
-    <a name="Controller"><img src="graphics/options_gameinfo_controller.png"></a>
+    <img src="graphics/options_gameinfo_controller.png">
   </p>
   <table CELLSPACING="10">
     <tr>
-      <td VALIGN="TOP"><i>Controller.Left:</i><br><i>Controller.Right:</i></td>
+      <td VALIGN="TOP">
+        <i>Controller.Left</i><br>
+        <i>Controller.Right</i><br>
+      </td>
       <td>Indicates what type of controller the left and right player
       uses. The value must be either <b>Auto</b> or one of the following types. Types marked
       as (&#185;) do not have auto-detection yet.
@@ -4215,14 +4512,15 @@ Ms Pac-Man (Stella extended codes):
         <tr><td>SaveKey</td><td>A 32K EEPROM for saving high scores, etc. (the EEPROM portion of an AtariVox).</td></tr>
         <tr><td>Genesis </td><td>Sega Genesis controller, which can be used similar to a BoosterGrip, giving an extra button.</td></tr>
         <tr><td>CompuMate &#185</td><td>Spectravideo CompuMate (if either left or right is set, CompuMate is used for both).</td></tr>
-    <tr><td>Lightgun</td><td>Atari XG-1 compatible Light Gun</td></tr>
+        <tr><td>Lightgun</td><td>Atari XG-1 compatible Light Gun</td></tr>
         <tr><td>Mindlink &#185</td><td>Mindlink controller.</td></tr>
-    <tr><td>KidVid &#185</td><td>KidVid controller, limitted suport (8, 9 and 0 start the games).</td></tr>
+        <tr><td>KidVid &#185</td><td>KidVid controller, limited support (8, 9 and 0 start the games).</td></tr>
+        <tr><td>QuadTari</td><td><a href="#Quadtari">QuadTari</a> controller, limited support (see below).</td></tr>
       </table></td>
     </tr>
 
     <tr>
-      <td VALIGN="TOP"><i>Console.SwapPorts:</i></td>
+      <td VALIGN="TOP"><i>Console.SwapPorts</i></td>
       <td>Indicates that the left and right ports should be
       swapped internally. This is used for ROMs like 'Raiders of the Lost Ark' where the
       Player 0 joystick is plugged into the right joystick port.
@@ -4230,7 +4528,7 @@ Ms Pac-Man (Stella extended codes):
     </tr>
 
     <tr>
-      <td VALIGN="TOP"><i>Controller.SwapPaddles:</i></td>
+      <td VALIGN="TOP"><i>Controller.SwapPaddles</i></td>
       <td>Indicates that the left and right paddles in
       a particular port should be swapped. This is used for ROMs like
       'Demons to Diamonds' where the default paddle is paddle 1, not
@@ -4240,17 +4538,17 @@ Ms Pac-Man (Stella extended codes):
     </tr>
 
     <tr>
-      <td VALIGN="TOP"><i>Controller.PaddlesXCenter:</i></td>
+      <td VALIGN="TOP"><i>Controller.PaddlesXCenter</i></td>
       <td>Defines the horizontal center of the paddles (range -10..30).</td>
     </tr>
 
     <tr>
-      <td VALIGN="TOP"><i>Controller.PaddlesYCenter:</i></td>
+      <td VALIGN="TOP"><i>Controller.PaddlesYCenter</i></td>
       <td>Defines the vertical center of the paddles (range -10..30).</td>
     </tr>
 
     <tr>
-      <td VALIGN="TOP"><i>Controller.MouseAxis:</i></td>
+      <td VALIGN="TOP"><i>Controller.MouseAxis</i></td>
       <td>Indicates how the mouse should emulate virtual controllers.
       In 'Auto' mode, the system decides how to best use the mouse. Otherwise,
       XY indicates how to use the X/Y axis (ie, 02 is paddle0/paddle2).
@@ -4268,7 +4566,7 @@ Ms Pac-Man (Stella extended codes):
         <tr><td>7 </td><td>MindLink 1</td></tr>
       </table>
       An <I>optional</I> second parameter (default of 100) indicates how much
-      of the paddle range that the mouse should emulate.
+      of the paddle range the mouse should emulate.
       </td>
     </tr>
 
@@ -4279,19 +4577,46 @@ Ms Pac-Man (Stella extended codes):
   </table>
   </br>
 
+  <h3><a name="Quadtari"><b>QuadTari Properties</b></h3></a>
   <p>
-    <a><img src="graphics/options_gameinfo_cartridge.png"></a>
+    <img src="graphics/options_gameinfo_quadtari.png">
   </p>
   <table CELLSPACING="10">
     <tr>
-      <td VALIGN="TOP"><i>Cart.Name:</i></td>
+      <td VALIGN="TOP">
+        <i>Controller.Left1</i><br>
+        <i>Controller.Left2</i><br>
+        <i>Controller.Right1</i><br>
+        <i>Controller.Right2</i><br>
+      </td>
+      <td>Indicates which controllers are plugged into one of the four QuadTari ports.
+      The value must be one of the following types.
+      <table cellpadding="2" border="1">
+        <tr><th>&nbsp;Type&nbsp;</th><th>Description</th></tr>
+        <tr><td>Joystick</td><td>Atari's famous black joystick that was originally included with the system.</td></tr>
+        <tr><td>Paddles </td><td>Standard paddle controllers, only (up to 8) fire buttons supported for QuadTari.</td></tr>
+        <tr><td>Driving</td><td>Looks like a paddle, but allows 360� movement. Only one unit per connector, unlike paddles which were sold in pairs.</td></tr>
+        <tr><td><a href="http://atariage.com/store/index.php?l=product_list&c=98">AtariVox</a></td><td>A SpeakJet based unlimited-vocabulary speech/sound synthesizer with 32K EEPROM.</td></tr>
+        <tr><td>SaveKey</td><td>A 32K EEPROM for saving high scores, etc. (the EEPROM portion of an AtariVox).</td></tr>
+      </table></td>
+    </tr>
+  </table>
+  </br>
+
+  <h3><a name="Cartridge"><b>Cartridge Properties</b></h3></a>
+  <p>
+    <img src="graphics/options_gameinfo_cartridge.png">
+  </p>
+  <table CELLSPACING="10">
+    <tr>
+      <td VALIGN="TOP"><i>Cart.Name</i></td>
       <td>Indicates the actual name of the game. When you save snapshots,
         load/save state files, or use the <a href="#ROMAudit"><b>ROM Audit Mode</b></a> functionality,
         this is the name that will be used for the respective file(s).</td>
     </tr>
 
     <tr>
-      <td VALIGN="TOP"><i>Cart.MD5:</i></td>
+      <td VALIGN="TOP"><i>Cart.MD5</i></td>
       <td>Indicates the MD5 checksum of the ROM image as a
       string of hexadecimal digits. Stella uses this property while
       attempting to match a game with its block of properties. If the
@@ -4302,22 +4627,22 @@ Ms Pac-Man (Stella extended codes):
     </tr>
 
     <tr>
-      <td VALIGN="TOP"><i>Cart.Manufacturer:</i></td>
+      <td VALIGN="TOP"><i>Cart.Manufacturer</i></td>
       <td>Indicates the game's manufacturer.</td>
     </tr>
 
     <tr>
-      <td VALIGN="TOP"><i>Cart.ModelNo:</i></td>
+      <td VALIGN="TOP"><i>Cart.ModelNo</i></td>
       <td>Indicates the manufacturer's model number for the game.</td>
     </tr>
 
     <tr>
-      <td VALIGN="TOP"><i>Cart.Rarity:</i></td>
+      <td VALIGN="TOP"><i>Cart.Rarity</i></td>
       <td>Indicates how rare a cartridge is, based on the scale described on AtariAge.</td>
     </tr>
 
     <tr>
-      <td VALIGN="TOP"><i>Cart.Note:</i></td>
+      <td VALIGN="TOP"><i>Cart.Note</i></td>
       <td>Contains any special notes about playing the game.</td>
     </tr>
 
diff --git a/docs/index_r77.html b/docs/index_r77.html
index cc15b11ab..ed6e9bc84 100644
--- a/docs/index_r77.html
+++ b/docs/index_r77.html
@@ -58,7 +58,7 @@
 
   <center><h1>Stella for RetroN 77</h1></center>
   <center><h2>Atari 2600 VCS emulator</h2></center>
-  <center>Release 6.2.1</center>
+  <center>Release 6.4</center>
   <center><h2>Quick Navigation Guide</h2></center>
   <br/>
 
diff --git a/src/cheat/CheatCodeDialog.cxx b/src/cheat/CheatCodeDialog.cxx
index 09ac1cd3c..481dcbcd5 100644
--- a/src/cheat/CheatCodeDialog.cxx
+++ b/src/cheat/CheatCodeDialog.cxx
@@ -100,6 +100,7 @@ CheatCodeDialog::CheatCodeDialog(OSystem& osystem, DialogContainer& parent,
     return (c >= 'a' && c <= 'f') || (c >= '0' && c <= '9');
   };
   myCheatInput->setTextFilter(f1, 1);
+  myCheatInput->setToolTip("See Stella documentation for details.", 1);
 
   addToFocusList(wid);
 
diff --git a/src/common/EventHandlerSDL2.cxx b/src/common/EventHandlerSDL2.cxx
index 2e8b60323..86d4dad89 100644
--- a/src/common/EventHandlerSDL2.cxx
+++ b/src/common/EventHandlerSDL2.cxx
@@ -27,6 +27,15 @@ EventHandlerSDL2::EventHandlerSDL2(OSystem& osystem)
 {
   ASSERT_MAIN_THREAD;
 
+#ifdef GUI_SUPPORT
+  {
+    ostringstream buf;
+    myQwertz = int('y') == int(SDL_GetKeyFromScancode(SDL_Scancode(KBDK_Z)));
+    buf << "Keyboard: " << (myQwertz ? "QWERTZ" : "QWERTY");
+    Logger::debug(buf.str());
+  }
+#endif
+
 #ifdef JOYSTICK_SUPPORT
   if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0)
   {
@@ -36,6 +45,8 @@ EventHandlerSDL2::EventHandlerSDL2(OSystem& osystem)
   }
   Logger::debug("EventHandlerSDL2::EventHandlerSDL2 SDL_INIT_JOYSTICK");
 #endif
+
+  SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1");
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -58,6 +69,23 @@ void EventHandlerSDL2::enableTextEvents(bool enable)
     SDL_StopTextInput();
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void EventHandlerSDL2::copyText(const string& text) const
+{
+  SDL_SetClipboardText(text.c_str());
+};
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+string EventHandlerSDL2::pasteText(string& text) const
+{
+  if(SDL_HasClipboardText())
+    text = SDL_GetClipboardText();
+  else
+    text = "";
+
+  return text;
+};
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void EventHandlerSDL2::pollEvent()
 {
diff --git a/src/common/EventHandlerSDL2.hxx b/src/common/EventHandlerSDL2.hxx
index 2fea58371..0c5301749 100644
--- a/src/common/EventHandlerSDL2.hxx
+++ b/src/common/EventHandlerSDL2.hxx
@@ -44,6 +44,12 @@ class EventHandlerSDL2 : public EventHandler
     */
     void enableTextEvents(bool enable) override;
 
+    /**
+      Clipboard methods.
+    */
+    void copyText(const string& text) const override;
+    string pasteText(string& text) const override;
+
     /**
       Collects and dispatches any pending SDL2 events.
     */
diff --git a/src/common/FrameBufferSDL2.cxx b/src/common/FBBackendSDL2.cxx
similarity index 76%
rename from src/common/FrameBufferSDL2.cxx
rename to src/common/FBBackendSDL2.cxx
index 24b038d01..643c099e9 100644
--- a/src/common/FrameBufferSDL2.cxx
+++ b/src/common/FBBackendSDL2.cxx
@@ -27,11 +27,11 @@
 
 #include "ThreadDebugging.hxx"
 #include "FBSurfaceSDL2.hxx"
-#include "FrameBufferSDL2.hxx"
+#include "FBBackendSDL2.hxx"
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-FrameBufferSDL2::FrameBufferSDL2(OSystem& osystem)
-  : FrameBuffer(osystem)
+FBBackendSDL2::FBBackendSDL2(OSystem& osystem)
+  : myOSystem(osystem)
 {
   ASSERT_MAIN_THREAD;
 
@@ -43,7 +43,7 @@ FrameBufferSDL2::FrameBufferSDL2(OSystem& osystem)
     Logger::error(buf.str());
     throw runtime_error("FATAL ERROR");
   }
-  Logger::debug("FrameBufferSDL2::FrameBufferSDL2 SDL_Init()");
+  Logger::debug("FBBackendSDL2::FBBackendSDL2 SDL_Init()");
 
   // We need a pixel format for palette value calculations
   // It's done this way (vs directly accessing a FBSurfaceSDL2 object)
@@ -53,7 +53,7 @@ FrameBufferSDL2::FrameBufferSDL2(OSystem& osystem)
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-FrameBufferSDL2::~FrameBufferSDL2()
+FBBackendSDL2::~FBBackendSDL2()
 {
   ASSERT_MAIN_THREAD;
 
@@ -61,12 +61,6 @@ FrameBufferSDL2::~FrameBufferSDL2()
 
   if(myRenderer)
   {
-    // Make sure to free surfaces/textures before destroying the renderer itself
-    // Most platforms are fine with doing this in either order, but it seems
-    // that OpenBSD in particular crashes when attempting to destroy textures
-    // *after* the renderer is already destroyed
-    freeSurfaces();
-
     SDL_DestroyRenderer(myRenderer);
     myRenderer = nullptr;
   }
@@ -81,9 +75,9 @@ FrameBufferSDL2::~FrameBufferSDL2()
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void FrameBufferSDL2::queryHardware(vector<Common::Size>& fullscreenRes,
-                                    vector<Common::Size>& windowedRes,
-                                    VariantList& renderers)
+void FBBackendSDL2::queryHardware(vector<Common::Size>& fullscreenRes,
+                                  vector<Common::Size>& windowedRes,
+                                  VariantList& renderers)
 {
   ASSERT_MAIN_THREAD;
 
@@ -105,7 +99,7 @@ void FrameBufferSDL2::queryHardware(vector<Common::Size>& fullscreenRes,
 
     string lastRes = "";
 
-    for (int m = 0; m < numModes; m++)
+    for(int m = 0; m < numModes; ++m)
     {
       SDL_DisplayMode mode;
       ostringstream res;
@@ -196,7 +190,7 @@ void FrameBufferSDL2::queryHardware(vector<Common::Size>& fullscreenRes,
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-bool FrameBufferSDL2::isCurrentWindowPositioned() const
+bool FBBackendSDL2::isCurrentWindowPositioned() const
 {
   ASSERT_MAIN_THREAD;
 
@@ -205,7 +199,7 @@ bool FrameBufferSDL2::isCurrentWindowPositioned() const
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Common::Point FrameBufferSDL2::getCurrentWindowPos() const
+Common::Point FBBackendSDL2::getCurrentWindowPos() const
 {
   ASSERT_MAIN_THREAD;
 
@@ -217,7 +211,7 @@ Common::Point FrameBufferSDL2::getCurrentWindowPos() const
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Int32 FrameBufferSDL2::getCurrentDisplayIndex() const
+Int32 FBBackendSDL2::getCurrentDisplayIndex() const
 {
   ASSERT_MAIN_THREAD;
 
@@ -225,7 +219,8 @@ Int32 FrameBufferSDL2::getCurrentDisplayIndex() const
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode)
+bool FBBackendSDL2::setVideoMode(const VideoModeHandler::Mode& mode,
+                                 int winIdx, const Common::Point& winPos)
 {
   ASSERT_MAIN_THREAD;
 
@@ -235,26 +230,22 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode)
 
   const bool fullScreen = mode.fsIndex != -1;
   bool forceCreateRenderer = false;
-
-  // Get windowed window's last display
-  Int32 displayIndex = std::min(myNumDisplays, myOSystem.settings().getInt(getDisplayKey()));
-  // Get windowed window's last position
-  myWindowedPos = myOSystem.settings().getPoint(getPositionKey());
+  Int32 displayIndex = std::min(myNumDisplays, winIdx);
 
   int posX, posY;
 
   myCenter = myOSystem.settings().getBool("center");
-  if (myCenter)
+  if(myCenter)
     posX = posY = SDL_WINDOWPOS_CENTERED_DISPLAY(displayIndex);
   else
   {
-    posX = myWindowedPos.x;
-    posY = myWindowedPos.y;
+    posX = winPos.x;
+    posY = winPos.y;
 
     // Make sure the window is at least partially visibile
     int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
 
-    for (int display = SDL_GetNumVideoDisplays() - 1; display >= 0; display--)
+    for(int display = SDL_GetNumVideoDisplays() - 1; display >= 0; --display)
     {
       SDL_Rect rect;
 
@@ -266,22 +257,28 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode)
         y1 = std::max(y1, rect.y + rect.h);
       }
     }
-    posX = BSPF::clamp(posX, x0 - Int32(mode.screen.w) + 50, x1 - 50);
+    posX = BSPF::clamp(posX, x0 - Int32(mode.screenS.w) + 50, x1 - 50);
     posY = BSPF::clamp(posY, y0 + 50, y1 - 50);
   }
 
 #ifdef ADAPTABLE_REFRESH_SUPPORT
   SDL_DisplayMode adaptedSdlMode;
-  const bool shouldAdapt = fullScreen && myOSystem.settings().getBool("tia.fs_refresh")
-    && gameRefreshRate()
+  const int gameRefreshRate =
+      myOSystem.hasConsole() ? myOSystem.console().gameRefreshRate() : 0;
+  const bool shouldAdapt = fullScreen
+    && myOSystem.settings().getBool("tia.fs_refresh")
+    && gameRefreshRate
     // take care of 59.94 Hz
-    && refreshRate() % gameRefreshRate() != 0 && refreshRate() % (gameRefreshRate() - 1) != 0;
-  const bool adaptRefresh = shouldAdapt && adaptRefreshRate(displayIndex, adaptedSdlMode);
+    && refreshRate() % gameRefreshRate != 0
+    && refreshRate() % (gameRefreshRate - 1) != 0;
+  const bool adaptRefresh = shouldAdapt &&
+      adaptRefreshRate(displayIndex, adaptedSdlMode);
 #else
   const bool adaptRefresh = false;
 #endif
   const uInt32 flags = SDL_WINDOW_ALLOW_HIGHDPI
-    | (fullScreen ? adaptRefresh ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
+    | (fullScreen ? adaptRefresh ? SDL_WINDOW_FULLSCREEN :
+    SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
 
   // Don't re-create the window if its display and size hasn't changed,
   // as it's not necessary, and causes flashing in fullscreen mode
@@ -291,8 +288,8 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode)
     int w, h;
 
     SDL_GetWindowSize(myWindow, &w, &h);
-    if(d != displayIndex || uInt32(w) != mode.screen.w || uInt32(h) != mode.screen.h
-       || adaptRefresh)
+    if(d != displayIndex || uInt32(w) != mode.screenS.w ||
+       uInt32(h) != mode.screenS.h || adaptRefresh)
     {
       SDL_DestroyWindow(myWindow);
       myWindow = nullptr;
@@ -302,14 +299,14 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode)
   if(myWindow)
   {
     // Even though window size stayed the same, the title may have changed
-    SDL_SetWindowTitle(myWindow, title.c_str());
+    SDL_SetWindowTitle(myWindow, myScreenTitle.c_str());
     SDL_SetWindowPosition(myWindow, posX, posY);
   }
   else
   {
     forceCreateRenderer = true;
-    myWindow = SDL_CreateWindow(title.c_str(), posX, posY,
-                                mode.screen.w, mode.screen.h, flags);
+    myWindow = SDL_CreateWindow(myScreenTitle.c_str(), posX, posY,
+                                mode.screenS.w, mode.screenS.h, flags);
     if(myWindow == nullptr)
     {
       string msg = "ERROR: Unable to open SDL window: " + string(SDL_GetError());
@@ -332,7 +329,8 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode)
     {
       ostringstream msg;
 
-      msg << "Display refresh rate changed to " << adaptedSdlMode.refresh_rate << " Hz";
+      msg << "Display refresh rate changed to "
+          << adaptedSdlMode.refresh_rate << " Hz";
       Logger::info(msg.str());
     }
   }
@@ -342,8 +340,11 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode)
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-bool FrameBufferSDL2::adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& adaptedSdlMode)
+bool FBBackendSDL2::adaptRefreshRate(Int32 displayIndex,
+                                     SDL_DisplayMode& adaptedSdlMode)
 {
+  ASSERT_MAIN_THREAD;
+
   SDL_DisplayMode sdlMode;
 
   if(SDL_GetCurrentDisplayMode(displayIndex, &sdlMode) != 0)
@@ -353,7 +354,8 @@ bool FrameBufferSDL2::adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& adap
   }
 
   const int currentRefreshRate = sdlMode.refresh_rate;
-  const int wantedRefreshRate = gameRefreshRate();
+  const int wantedRefreshRate =
+      myOSystem.hasConsole() ? myOSystem.console().gameRefreshRate() : 0;
   // Take care of rounded refresh rates (e.g. 59.94 Hz)
   float factor = std::min(float(currentRefreshRate) / wantedRefreshRate,
                           float(currentRefreshRate) / (wantedRefreshRate - 1));
@@ -397,8 +399,10 @@ bool FrameBufferSDL2::adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& adap
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-bool FrameBufferSDL2::createRenderer(bool force)
+bool FBBackendSDL2::createRenderer(bool force)
 {
+  ASSERT_MAIN_THREAD;
+
   // A new renderer is only created when necessary:
   // - new myWindow (force = true)
   // - no renderer existing
@@ -450,7 +454,7 @@ bool FrameBufferSDL2::createRenderer(bool force)
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void FrameBufferSDL2::setTitle(const string& title)
+void FBBackendSDL2::setTitle(const string& title)
 {
   ASSERT_MAIN_THREAD;
 
@@ -461,7 +465,7 @@ void FrameBufferSDL2::setTitle(const string& title)
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-string FrameBufferSDL2::about() const
+string FBBackendSDL2::about() const
 {
   ASSERT_MAIN_THREAD;
 
@@ -483,7 +487,7 @@ string FrameBufferSDL2::about() const
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void FrameBufferSDL2::showCursor(bool show)
+void FBBackendSDL2::showCursor(bool show)
 {
   ASSERT_MAIN_THREAD;
 
@@ -491,7 +495,7 @@ void FrameBufferSDL2::showCursor(bool show)
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void FrameBufferSDL2::grabMouse(bool grab)
+void FBBackendSDL2::grabMouse(bool grab)
 {
   ASSERT_MAIN_THREAD;
 
@@ -499,7 +503,7 @@ void FrameBufferSDL2::grabMouse(bool grab)
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-bool FrameBufferSDL2::fullScreen() const
+bool FBBackendSDL2::fullScreen() const
 {
   ASSERT_MAIN_THREAD;
 
@@ -511,7 +515,7 @@ bool FrameBufferSDL2::fullScreen() const
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-int FrameBufferSDL2::refreshRate() const
+int FBBackendSDL2::refreshRate() const
 {
   ASSERT_MAIN_THREAD;
 
@@ -528,20 +532,7 @@ int FrameBufferSDL2::refreshRate() const
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-int FrameBufferSDL2::gameRefreshRate() const
-{
-  if(myOSystem.hasConsole())
-  {
-    const string format = myOSystem.console().getFormatString();
-    const bool isNtsc = format == "NTSC" || format == "PAL60" || format == "SECAM60";
-
-    return isNtsc ? 60 : 50; // The code will take care of 59/49 Hz
-  }
-  return 0;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void FrameBufferSDL2::renderToScreen()
+void FBBackendSDL2::renderToScreen()
 {
   ASSERT_MAIN_THREAD;
 
@@ -550,7 +541,7 @@ void FrameBufferSDL2::renderToScreen()
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void FrameBufferSDL2::setWindowIcon()
+void FBBackendSDL2::setWindowIcon()
 {
 #if !defined(BSPF_MACOS) && !defined(RETRON77)
 #include "stella_icon.hxx"
@@ -564,19 +555,20 @@ void FrameBufferSDL2::setWindowIcon()
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-unique_ptr<FBSurface> FrameBufferSDL2::createSurface(
+unique_ptr<FBSurface> FBBackendSDL2::createSurface(
   uInt32 w,
   uInt32 h,
-  FrameBuffer::ScalingInterpolation interpolation,
+  ScalingInterpolation inter,
   const uInt32* data
 ) const
 {
-  return make_unique<FBSurfaceSDL2>(const_cast<FrameBufferSDL2&>(*this), w, h, interpolation, data);
+  return make_unique<FBSurfaceSDL2>
+      (const_cast<FBBackendSDL2&>(*this), w, h, inter, data);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void FrameBufferSDL2::readPixels(uInt8* pixels, uInt32 pitch,
-                                 const Common::Rect& rect) const
+void FBBackendSDL2::readPixels(uInt8* pixels, uInt32 pitch,
+                               const Common::Rect& rect) const
 {
   ASSERT_MAIN_THREAD;
 
@@ -588,7 +580,7 @@ void FrameBufferSDL2::readPixels(uInt8* pixels, uInt32 pitch,
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void FrameBufferSDL2::clear()
+void FBBackendSDL2::clear()
 {
   ASSERT_MAIN_THREAD;
 
@@ -596,49 +588,34 @@ void FrameBufferSDL2::clear()
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-SDL_Renderer* FrameBufferSDL2::renderer()
-{
-  return myRenderer;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-bool FrameBufferSDL2::isInitialized() const
-{
-  return myRenderer != nullptr;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-const SDL_PixelFormat& FrameBufferSDL2::pixelFormat() const
-{
-  return *myPixelFormat;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void FrameBufferSDL2::detectFeatures()
+void FBBackendSDL2::detectFeatures()
 {
   myRenderTargetSupport = detectRenderTargetSupport();
 
-  if (myRenderer) {
-    if (!myRenderTargetSupport) {
-      Logger::info("Render targets are not supported --- QIS not available");
-    }
-  }
+  if(myRenderer && !myRenderTargetSupport)
+    Logger::info("Render targets are not supported --- QIS not available");
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-bool FrameBufferSDL2::detectRenderTargetSupport()
+bool FBBackendSDL2::detectRenderTargetSupport()
 {
-  if (myRenderer == nullptr) return false;
+  ASSERT_MAIN_THREAD;
+
+  if(myRenderer == nullptr)
+    return false;
 
   SDL_RendererInfo info;
-
   SDL_GetRendererInfo(myRenderer, &info);
 
-  if (!(info.flags & SDL_RENDERER_TARGETTEXTURE)) return false;
+  if(!(info.flags & SDL_RENDERER_TARGETTEXTURE))
+    return false;
 
-  SDL_Texture* tex = SDL_CreateTexture(myRenderer, myPixelFormat->format, SDL_TEXTUREACCESS_TARGET, 16, 16);
+  SDL_Texture* tex =
+      SDL_CreateTexture(myRenderer, myPixelFormat->format,
+                        SDL_TEXTUREACCESS_TARGET, 16, 16);
 
-  if (!tex) return false;
+  if(!tex)
+    return false;
 
   int sdlError = SDL_SetRenderTarget(myRenderer, tex);
   SDL_SetRenderTarget(myRenderer, nullptr);
@@ -649,20 +626,17 @@ bool FrameBufferSDL2::detectRenderTargetSupport()
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-bool FrameBufferSDL2::hasRenderTargetSupport() const
+void FBBackendSDL2::determineDimensions()
 {
-  return myRenderTargetSupport;
-}
+  ASSERT_MAIN_THREAD;
 
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void FrameBufferSDL2::determineDimensions()
-{
   SDL_GetWindowSize(myWindow, &myWindowW, &myWindowH);
 
-  if (myRenderer == nullptr) {
+  if(myRenderer == nullptr)
+  {
     myRenderW = myWindowW;
     myRenderH = myWindowH;
-  } else {
-    SDL_GetRendererOutputSize(myRenderer, &myRenderW, &myRenderH);
   }
+  else
+    SDL_GetRendererOutputSize(myRenderer, &myRenderW, &myRenderH);
 }
diff --git a/src/common/FrameBufferSDL2.hxx b/src/common/FBBackendSDL2.hxx
similarity index 75%
rename from src/common/FrameBufferSDL2.hxx
rename to src/common/FBBackendSDL2.hxx
index 0b3386d08..67a5a2a57 100644
--- a/src/common/FrameBufferSDL2.hxx
+++ b/src/common/FBBackendSDL2.hxx
@@ -15,8 +15,8 @@
 // this file, and for a DISCLAIMER OF ALL WARRANTIES.
 //============================================================================
 
-#ifndef FRAMEBUFFER_SDL2_HXX
-#define FRAMEBUFFER_SDL2_HXX
+#ifndef FB_BACKEND_SDL2_HXX
+#define FB_BACKEND_SDL2_HXX
 
 #include "SDL_lib.hxx"
 
@@ -24,27 +24,55 @@ class OSystem;
 class FBSurfaceSDL2;
 
 #include "bspf.hxx"
-#include "FrameBuffer.hxx"
+#include "FBBackend.hxx"
 
 /**
-  This class implements a standard SDL2 2D, hardware accelerated framebuffer.
-  Behind the scenes, it may be using Direct3D, OpenGL(ES), etc.
+  This class implements a standard SDL2 2D, hardware accelerated framebuffer
+  backend.  Behind the scenes, it may be using Direct3D, OpenGL(ES), etc.
 
   @author  Stephen Anthony
 */
-class FrameBufferSDL2 : public FrameBuffer
+class FBBackendSDL2 : public FBBackend
 {
   public:
     /**
       Creates a new SDL2 framebuffer
     */
-    explicit FrameBufferSDL2(OSystem& osystem);
-    ~FrameBufferSDL2() override;
+    explicit FBBackendSDL2(OSystem& osystem);
+    ~FBBackendSDL2() override;
 
-    //////////////////////////////////////////////////////////////////////
-    // The following are derived from public methods in FrameBuffer.hxx
-    //////////////////////////////////////////////////////////////////////
+  public:
+    /**
+      Get a pointer to the SDL renderer.
+     */
+    SDL_Renderer* renderer() { return myRenderer; }
 
+    /**
+      Is the renderer initialized?
+     */
+    bool isInitialized() const { return myRenderer != nullptr; }
+
+    /**
+      Get the SDL pixel format.
+     */
+    const SDL_PixelFormat& pixelFormat() const { return *myPixelFormat; }
+
+    /**
+      Does the renderer support render targets?
+     */
+    bool hasRenderTargetSupport() const { return myRenderTargetSupport; }
+
+    /**
+      Transform from window to renderer coordinates, x direction
+     */
+    int scaleX(int x) const override { return (x * myRenderW) / myWindowW; }
+
+    /**
+      Transform from window to renderer coordinates, y direction
+     */
+    int scaleY(int y) const override { return (y * myRenderH) / myWindowH; }
+
+  protected:
     /**
       Updates window title.
 
@@ -93,7 +121,8 @@ class FrameBufferSDL2 : public FrameBuffer
       @param pitch   The pitch (in bytes) for the pixel data
       @param rect    The bounding rectangle for the buffer
     */
-    void readPixels(uInt8* buffer, uInt32 pitch, const Common::Rect& rect) const override;
+    void readPixels(uInt8* buffer, uInt32 pitch,
+                    const Common::Rect& rect) const override;
 
     /**
       This method is called to query if the current window is not centered
@@ -110,6 +139,7 @@ class FrameBufferSDL2 : public FrameBuffer
       @return  The position of the currently displayed window
     */
     Common::Point getCurrentWindowPos() const override;
+
     /**
       This method is called to query the video hardware for the index
       of the display the current window is displayed on
@@ -124,40 +154,6 @@ class FrameBufferSDL2 : public FrameBuffer
     */
     void clear() override;
 
-    /**
-      Get a pointer to the SDL renderer.
-     */
-    SDL_Renderer* renderer();
-
-    /**
-      Get the SDL pixel format.
-     */
-    const SDL_PixelFormat& pixelFormat() const;
-
-    /**
-      Is the renderer initialized?
-     */
-    bool isInitialized() const;
-
-    /**
-      Does the renderer support render targets?
-     */
-    bool hasRenderTargetSupport() const;
-
-    /**
-      Transform from window to renderer coordinates, x direction
-     */
-    int scaleX(int x) const override { return (x * myRenderW) / myWindowW; }
-
-    /**
-      Transform from window to renderer coordinates, y direction
-     */
-    int scaleY(int y) const override { return (y * myRenderH) / myWindowH; }
-
-  protected:
-    //////////////////////////////////////////////////////////////////////
-    // The following are derived from protected methods in FrameBuffer.hxx
-    //////////////////////////////////////////////////////////////////////
     /**
       This method is called to query and initialize the video hardware
       for desktop and fullscreen resolution information.  Since several
@@ -174,45 +170,28 @@ class FrameBufferSDL2 : public FrameBuffer
     /**
       This method is called to change to the given video mode.
 
-      @param title The title for the created window
-      @param mode  The video mode to use
+      @param mode   The video mode to use
+      @param winIdx The display/monitor that the window last opened on
+      @param winPos The position that the window last opened at
 
       @return  False on any errors, else true
     */
-    bool setVideoMode(const string& title, const VideoMode& mode) override;
-
-    /**
-      Checks if the display refresh rate should be adapted to game refresh rate in (real) fullscreen mode
-
-      @param displayIndex   The display which should be checked
-      @param adaptedSdlMode The best matching mode if the refresh rate should be changed
-
-      @return  True if the refresh rate should be changed
-    */
-    bool adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& adaptedSdlMode);
-
-    /**
-      Create a new renderer if required
-
-      @param force  If true, force new renderer creation
-
-      @return  False on any errors, else true
-    */
-    bool createRenderer(bool force);
+    bool setVideoMode(const VideoModeHandler::Mode& mode,
+                      int winIdx, const Common::Point& winPos) override;
 
     /**
       This method is called to create a surface with the given attributes.
 
-      @param w                The requested width of the new surface.
-      @param h                The requested height of the new surface.
-      @param interpolation    Interpolation mode
-      @param data             If non-null, use the given data values as a static surface
+      @param w      The requested width of the new surface.
+      @param h      The requested height of the new surface.
+      @param inter  Interpolation mode
+      @param data   If non-null, use the given data values as a static surface
     */
     unique_ptr<FBSurface>
         createSurface(
           uInt32 w,
           uInt32 h,
-          FrameBuffer::ScalingInterpolation interpolation,
+          ScalingInterpolation inter,
           const uInt32* data
         ) const override;
 
@@ -222,28 +201,49 @@ class FrameBufferSDL2 : public FrameBuffer
     void grabMouse(bool grab) override;
 
     /**
-      Set the icon for the main SDL window.
-    */
-    void setWindowIcon() override;
-
-    /**
-      This method is called to provide information about the FrameBuffer.
+      This method is called to provide information about the backend.
     */
     string about() const override;
 
+    /**
+      Create a new renderer if required.
+
+      @param force  If true, force new renderer creation
+
+      @return  False on any errors, else true
+    */
+    bool createRenderer(bool force);
+
     /**
       This method must be called after all drawing is done, and indicates
       that the buffers should be pushed to the physical screen.
     */
     void renderToScreen() override;
 
+    /**
+      Retrieve the current display's refresh rate, or 0 if no window.
+    */
+    int refreshRate() const override;
+
+    /**
+      Checks if the display refresh rate should be adapted to game refresh
+      rate in (real) fullscreen mode.
+
+      @param displayIndex   The display which should be checked
+      @param adaptedSdlMode The best matching mode if the refresh rate
+                            should be changed
+
+      @return  True if the refresh rate should be changed
+    */
+    bool adaptRefreshRate(Int32 displayIndex, SDL_DisplayMode& adaptedSdlMode);
+
     /**
       After the renderer has been created, detect the features it supports.
      */
     void detectFeatures();
 
     /**
-      Detect render target support;
+      Detect render target support.
      */
     bool detectRenderTargetSupport();
 
@@ -253,16 +253,13 @@ class FrameBufferSDL2 : public FrameBuffer
     void determineDimensions();
 
     /**
-      Retrieve the current display's refresh rate, or 0 if no window
+      Set the icon for the main SDL window.
     */
-    int refreshRate() const override;
-
-    /**
-      Retrieve the current game's refresh rate, or 60 if no game
-    */
-    int gameRefreshRate() const;
+    void setWindowIcon();
 
   private:
+    OSystem& myOSystem;
+
     // The SDL video buffer
     SDL_Window* myWindow{nullptr};
     SDL_Renderer* myRenderer{nullptr};
@@ -273,22 +270,25 @@ class FrameBufferSDL2 : public FrameBuffer
     // Center setting of current window
     bool myCenter{false};
 
-    // last position of windowed window
-    Common::Point myWindowedPos;
-
     // Does the renderer support render targets?
     bool myRenderTargetSupport{false};
 
+    // Title of the main window/screen
+    string myScreenTitle;
+
+    // Number of displays
+    int myNumDisplays{1};
+
     // Window and renderer dimensions
     int myWindowW{0}, myWindowH{0}, myRenderW{0}, myRenderH{0};
 
   private:
     // Following constructors and assignment operators not supported
-    FrameBufferSDL2() = delete;
-    FrameBufferSDL2(const FrameBufferSDL2&) = delete;
-    FrameBufferSDL2(FrameBufferSDL2&&) = delete;
-    FrameBufferSDL2& operator=(const FrameBufferSDL2&) = delete;
-    FrameBufferSDL2& operator=(FrameBufferSDL2&&) = delete;
+    FBBackendSDL2() = delete;
+    FBBackendSDL2(const FBBackendSDL2&) = delete;
+    FBBackendSDL2(FBBackendSDL2&&) = delete;
+    FBBackendSDL2& operator=(const FBBackendSDL2&) = delete;
+    FBBackendSDL2& operator=(FBBackendSDL2&&) = delete;
 };
 
 #endif
diff --git a/src/common/FBSurfaceSDL2.cxx b/src/common/FBSurfaceSDL2.cxx
index 94483a22b..7f0ddb7d7 100644
--- a/src/common/FBSurfaceSDL2.cxx
+++ b/src/common/FBSurfaceSDL2.cxx
@@ -22,16 +22,16 @@
 #include "sdl_blitter/BlitterFactory.hxx"
 
 namespace {
-  BlitterFactory::ScalingAlgorithm scalingAlgorithm(FrameBuffer::ScalingInterpolation interpolation)
+  BlitterFactory::ScalingAlgorithm scalingAlgorithm(ScalingInterpolation inter)
   {
-    switch (interpolation) {
-      case FrameBuffer::ScalingInterpolation::none:
+    switch (inter) {
+      case ScalingInterpolation::none:
         return BlitterFactory::ScalingAlgorithm::nearestNeighbour;
 
-      case FrameBuffer::ScalingInterpolation::blur:
+      case ScalingInterpolation::blur:
         return BlitterFactory::ScalingAlgorithm::bilinear;
 
-      case FrameBuffer::ScalingInterpolation::sharp:
+      case ScalingInterpolation::sharp:
         return BlitterFactory::ScalingAlgorithm::quasiInteger;
 
       default:
@@ -41,12 +41,12 @@ namespace {
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-FBSurfaceSDL2::FBSurfaceSDL2(FrameBufferSDL2& buffer,
+FBSurfaceSDL2::FBSurfaceSDL2(FBBackendSDL2& backend,
                              uInt32 width, uInt32 height,
-                             FrameBuffer::ScalingInterpolation interpolation,
+                             ScalingInterpolation inter,
                              const uInt32* staticData)
-  : myFB(buffer),
-    myInterpolationMode(interpolation)
+  : myBackend(backend),
+    myInterpolationMode(inter)
 {
   createSurface(width, height, staticData);
 }
@@ -104,41 +104,49 @@ const Common::Rect& FBSurfaceSDL2::dstRect() const
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void FBSurfaceSDL2::setSrcPos(uInt32 x, uInt32 y)
 {
-  if(x != static_cast<uInt32>(mySrcR.x) || y != static_cast<uInt32>(mySrcR.y))
-  {
-    setSrcPosInternal(x, y);
+  if(setSrcPosInternal(x, y))
     reinitializeBlitter();
-  }
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void FBSurfaceSDL2::setSrcSize(uInt32 w, uInt32 h)
 {
-  if(w != static_cast<uInt32>(mySrcR.w) || h != static_cast<uInt32>(mySrcR.h))
-  {
-    setSrcSizeInternal(w, h);
+  if(setSrcSizeInternal(w, h))
+    reinitializeBlitter();
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void FBSurfaceSDL2::setSrcRect(const Common::Rect& r)
+{
+  const bool posChanged = setSrcPosInternal(r.x(), r.y()),
+             sizeChanged = setSrcSizeInternal(r.w(), r.h());
+
+  if(posChanged || sizeChanged)
     reinitializeBlitter();
-  }
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void FBSurfaceSDL2::setDstPos(uInt32 x, uInt32 y)
 {
-  if(x != static_cast<uInt32>(myDstR.x) || y != static_cast<uInt32>(myDstR.y))
-  {
-    setDstPosInternal(x, y);
+  if(setDstPosInternal(x, y))
     reinitializeBlitter();
-  }
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void FBSurfaceSDL2::setDstSize(uInt32 w, uInt32 h)
 {
-  if(w != static_cast<uInt32>(myDstR.w) || h != static_cast<uInt32>(myDstR.h))
-  {
-    setDstSizeInternal(w, h);
+  if(setDstSizeInternal(w, h))
+    reinitializeBlitter();
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void FBSurfaceSDL2::setDstRect(const Common::Rect& r)
+{
+  const bool posChanged = setDstPosInternal(r.x(), r.y()),
+             sizeChanged = setDstSizeInternal(r.w(), r.h());
+
+  if(posChanged || sizeChanged)
     reinitializeBlitter();
-  }
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -176,6 +184,22 @@ void FBSurfaceSDL2::invalidate()
   SDL_FillRect(mySurface, nullptr, 0);
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void FBSurfaceSDL2::invalidateRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h)
+{
+  ASSERT_MAIN_THREAD;
+
+  // Clear the rectangle
+  SDL_Rect tmp;
+  tmp.x = x;
+  tmp.y = y;
+  tmp.w = w;
+  tmp.h = h;
+  // Note: Transparency has to be 0 to clear the rectangle foreground
+  //  without affecting the background display.
+  SDL_FillRect(mySurface, &tmp, 0);
+}
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void FBSurfaceSDL2::free()
 {
@@ -214,7 +238,7 @@ void FBSurfaceSDL2::createSurface(uInt32 width, uInt32 height,
   ASSERT_MAIN_THREAD;
 
   // Create a surface in the same format as the parent GL class
-  const SDL_PixelFormat& pf = myFB.pixelFormat();
+  const SDL_PixelFormat& pf = myBackend.pixelFormat();
 
   mySurface = SDL_CreateRGBSurface(0, width, height,
       pf.BitsPerPixel, pf.Rmask, pf.Gmask, pf.Bmask, pf.Amask);
@@ -242,11 +266,13 @@ void FBSurfaceSDL2::createSurface(uInt32 width, uInt32 height,
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void FBSurfaceSDL2::reinitializeBlitter()
 {
-  if (!myBlitter && myFB.isInitialized())
-    myBlitter = BlitterFactory::createBlitter(myFB, scalingAlgorithm(myInterpolationMode));
+  if (!myBlitter && myBackend.isInitialized())
+    myBlitter = BlitterFactory::createBlitter(
+        myBackend, scalingAlgorithm(myInterpolationMode));
 
   if (myBlitter)
-    myBlitter->reinitialize(mySrcR, myDstR, myAttributes, myIsStatic ? mySurface : nullptr);
+    myBlitter->reinitialize(mySrcR, myDstR, myAttributes,
+                            myIsStatic ? mySurface : nullptr);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -256,7 +282,7 @@ void FBSurfaceSDL2::applyAttributes()
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void FBSurfaceSDL2::setScalingInterpolation(FrameBuffer::ScalingInterpolation interpolation)
+void FBSurfaceSDL2::setScalingInterpolation(ScalingInterpolation interpolation)
 {
   if (interpolation == myInterpolationMode) return;
 
diff --git a/src/common/FBSurfaceSDL2.hxx b/src/common/FBSurfaceSDL2.hxx
index 62e9d96a2..d8bfa0029 100644
--- a/src/common/FBSurfaceSDL2.hxx
+++ b/src/common/FBSurfaceSDL2.hxx
@@ -20,7 +20,7 @@
 
 #include "bspf.hxx"
 #include "FBSurface.hxx"
-#include "FrameBufferSDL2.hxx"
+#include "FBBackendSDL2.hxx"
 #include "sdl_blitter/Blitter.hxx"
 
 /**
@@ -32,9 +32,8 @@
 class FBSurfaceSDL2 : public FBSurface
 {
   public:
-    FBSurfaceSDL2(FrameBufferSDL2& buffer, uInt32 width, uInt32 height,
-                  FrameBuffer::ScalingInterpolation interpolation,
-                  const uInt32* staticData);
+    FBSurfaceSDL2(FBBackendSDL2& backend, uInt32 width, uInt32 height,
+                  ScalingInterpolation inter, const uInt32* staticData);
     ~FBSurfaceSDL2() override;
 
     // Most of the surface drawing primitives are implemented in FBSurface;
@@ -49,38 +48,63 @@ class FBSurfaceSDL2 : public FBSurface
     const Common::Rect& dstRect() const override;
     void setSrcPos(uInt32 x, uInt32 y) override;
     void setSrcSize(uInt32 w, uInt32 h) override;
+    void setSrcRect(const Common::Rect& r) override;
     void setDstPos(uInt32 x, uInt32 y) override;
     void setDstSize(uInt32 w, uInt32 h) override;
+    void setDstRect(const Common::Rect& r) override;
+
     void setVisible(bool visible) override;
 
     void translateCoords(Int32& x, Int32& y) const override;
     bool render() override;
     void invalidate() override;
+    void invalidateRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h) override;
+
     void free() override;
     void reload() override;
     void resize(uInt32 width, uInt32 height) override;
 
-    void setScalingInterpolation(FrameBuffer::ScalingInterpolation) override;
+    void setScalingInterpolation(ScalingInterpolation) override;
 
   protected:
     void applyAttributes() override;
 
   private:
-    inline void setSrcPosInternal(uInt32 x, uInt32 y) {
-      mySrcR.x = x;  mySrcR.y = y;
-      mySrcGUIR.moveTo(x, y);
+    inline bool setSrcPosInternal(uInt32 x, uInt32 y) {
+      if(x != static_cast<uInt32>(mySrcR.x) || y != static_cast<uInt32>(mySrcR.y))
+      {
+        mySrcR.x = x;  mySrcR.y = y;
+        mySrcGUIR.moveTo(x, y);
+        return true;
+      }
+      return false;
     }
-    inline void setSrcSizeInternal(uInt32 w, uInt32 h) {
-      mySrcR.w = w;  mySrcR.h = h;
-      mySrcGUIR.setWidth(w);  mySrcGUIR.setHeight(h);
+    inline bool setSrcSizeInternal(uInt32 w, uInt32 h) {
+      if(w != static_cast<uInt32>(mySrcR.w) || h != static_cast<uInt32>(mySrcR.h))
+      {
+        mySrcR.w = w;  mySrcR.h = h;
+        mySrcGUIR.setWidth(w);  mySrcGUIR.setHeight(h);
+        return true;
+      }
+      return false;
     }
-    inline void setDstPosInternal(uInt32 x, uInt32 y) {
-      myDstR.x = x;  myDstR.y = y;
-      myDstGUIR.moveTo(x, y);
+    inline bool setDstPosInternal(uInt32 x, uInt32 y) {
+      if(x != static_cast<uInt32>(myDstR.x) || y != static_cast<uInt32>(myDstR.y))
+      {
+        myDstR.x = x;  myDstR.y = y;
+        myDstGUIR.moveTo(x, y);
+        return true;
+      }
+      return false;
     }
-    inline void setDstSizeInternal(uInt32 w, uInt32 h) {
-      myDstR.w = w;  myDstR.h = h;
-      myDstGUIR.setWidth(w);  myDstGUIR.setHeight(h);
+    inline bool setDstSizeInternal(uInt32 w, uInt32 h) {
+      if(w != static_cast<uInt32>(myDstR.w) || h != static_cast<uInt32>(myDstR.h))
+      {
+        myDstR.w = w;  myDstR.h = h;
+        myDstGUIR.setWidth(w);  myDstGUIR.setHeight(h);
+        return true;
+      }
+      return false;
     }
 
     void createSurface(uInt32 width, uInt32 height, const uInt32* data);
@@ -95,14 +119,14 @@ class FBSurfaceSDL2 : public FBSurface
     FBSurfaceSDL2& operator=(FBSurfaceSDL2&&) = delete;
 
   private:
-    FrameBufferSDL2& myFB;
+    FBBackendSDL2& myBackend;
 
     unique_ptr<Blitter> myBlitter;
-    FrameBuffer::ScalingInterpolation myInterpolationMode
-        {FrameBuffer::ScalingInterpolation::none};
+    ScalingInterpolation myInterpolationMode
+        {ScalingInterpolation::none};
 
     SDL_Surface* mySurface{nullptr};
-    SDL_Rect mySrcR{0, 0, 0, 0}, myDstR{0, 0, 0, 0};
+    SDL_Rect mySrcR{-1, -1, -1, -1}, myDstR{-1, -1, -1, -1};
 
     bool myIsVisible{true};
     bool myIsStatic{false};
diff --git a/src/common/JoyMap.cxx b/src/common/JoyMap.cxx
index 266dd5e74..6b8c95b42 100644
--- a/src/common/JoyMap.cxx
+++ b/src/common/JoyMap.cxx
@@ -16,6 +16,10 @@
 //============================================================================
 
 #include "JoyMap.hxx"
+#include "jsonDefinitions.hxx"
+#include "Logger.hxx"
+
+using json = nlohmann::json;
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void JoyMap::add(const Event::Type event, const JoyMapping& mapping)
@@ -183,67 +187,105 @@ JoyMap::JoyMappingArray JoyMap::getEventMapping(const Event::Type event, const E
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-string JoyMap::saveMapping(const EventMode mode) const
+json JoyMap::saveMapping(const EventMode mode) const
 {
-  using MapType = std::pair<JoyMapping, Event::Type>;
-  std::vector<MapType> sortedMap(myMap.begin(), myMap.end());
+  json eventMappings = json::array();
 
-  std::sort(sortedMap.begin(), sortedMap.end(),
-    [](const MapType& a, const MapType& b)
-    {
-      // Event::Type first
-      if(a.second != b.second)
-        return a.second < b.second;
+  for (auto& item: myMap) {
+    if (item.first.mode != mode) continue;
 
-      if(a.first.button != b.first.button)
-        return a.first.button < b.first.button;
+    json eventMapping = json::object();
 
-      if(a.first.axis != b.first.axis)
-        return a.first.axis < b.first.axis;
+    eventMapping["event"] = item.second;
 
-      if(a.first.adir != b.first.adir)
-        return a.first.adir < b.first.adir;
+    if (item.first.button != JOY_CTRL_NONE) eventMapping["button"] = item.first.button;
 
-      if(a.first.hat != b.first.hat)
-        return a.first.hat < b.first.hat;
-
-      return a.first.hdir < b.first.hdir;
+    if (item.first.axis != JoyAxis::NONE) {
+      eventMapping["axis"] = item.first.axis;
+      eventMapping["axisDirection"] = item.first.adir;
     }
-  );
 
-  ostringstream buf;
-
-  for (auto item : sortedMap)
-  {
-    if (item.first.mode == mode)
-    {
-      if (buf.str() != "")
-        buf << "|";
-      buf << item.second << ":" << item.first.button << ","
-        << int(item.first.axis) << "," << int(item.first.adir) << ","
-        << item.first.hat << "," << int(item.first.hdir);
+    if (item.first.hat != -1) {
+      eventMapping["hat"] = item.first.hat;
+      eventMapping["hatDirection"] = item.first.hdir;
     }
+
+    eventMappings.push_back(eventMapping);
   }
-  return buf.str();
+
+  return eventMappings;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-int JoyMap::loadMapping(string& list, const EventMode mode)
+int JoyMap::loadMapping(const json& eventMappings, const EventMode mode)
 {
+  int i = 0;
+
+  for (const json& eventMapping: eventMappings) {
+    int button = eventMapping.contains("button") ? eventMapping.at("button").get<int>() : JOY_CTRL_NONE;
+    JoyAxis axis = eventMapping.contains("axis") ? eventMapping.at("axis").get<JoyAxis>() : JoyAxis::NONE;
+    JoyDir axisDirection = eventMapping.contains("axis") ? eventMapping.at("axisDirection").get<JoyDir>() : JoyDir::NONE;
+    int hat = eventMapping.contains("hat") ? eventMapping.at("hat").get<int>() : -1;
+    JoyHatDir hatDirection = eventMapping.contains("hat") ? eventMapping.at("hatDirection").get<JoyHatDir>() : JoyHatDir::CENTER;
+
+    try {
+      add(
+        eventMapping.at("event").get<Event::Type>(),
+        mode,
+        button,
+        axis,
+        axisDirection,
+        hat,
+        hatDirection
+      );
+
+      i++;
+    } catch (json::exception) {
+      Logger::error("ignoring invalid joystick event");
+    }
+  }
+
+  return i;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+json JoyMap::convertLegacyMapping(string list)
+{
+  json eventMappings = json::array();
+
   // Since istringstream swallows whitespace, we have to make the
   // delimiters be spaces
   std::replace(list.begin(), list.end(), '|', ' ');
   std::replace(list.begin(), list.end(), ':', ' ');
   std::replace(list.begin(), list.end(), ',', ' ');
+
   istringstream buf(list);
-  int event, button, axis, adir, hat, hdir, i = 0;
+  int event, button, axis, adir, hat, hdir;
 
   while (buf >> event && buf >> button
          && buf >> axis && buf >> adir
-         && buf >> hat && buf >> hdir && ++i)
-    add(Event::Type(event), EventMode(mode), button, JoyAxis(axis), JoyDir(adir), hat, JoyHatDir(hdir));
+         && buf >> hat && buf >> hdir)
+  {
+    json eventMapping = json::object();
 
-  return i;
+    eventMapping["event"] = Event::Type(event);
+
+    if (button != JOY_CTRL_NONE) eventMapping["button"] = button;
+
+    if (JoyAxis(axis) != JoyAxis::NONE) {
+      eventMapping["axis"] = JoyAxis(axis);
+      eventMapping["axisDirection"] = JoyDir(adir);
+    }
+
+    if (hat != -1) {
+      eventMapping["hat"] = hat;
+      eventMapping["hatDirection"] = JoyHatDir(hdir);
+    }
+
+    eventMappings.push_back(eventMapping);
+  }
+
+  return eventMappings;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/common/JoyMap.hxx b/src/common/JoyMap.hxx
index e3cc7ff7a..6bf87009e 100644
--- a/src/common/JoyMap.hxx
+++ b/src/common/JoyMap.hxx
@@ -22,6 +22,7 @@
 
 #include "Event.hxx"
 #include "EventHandlerConstants.hxx"
+#include "json.hxx"
 
 /**
   This class handles controller mappings in Stella.
@@ -110,8 +111,10 @@ class JoyMap
 
     JoyMappingArray getEventMapping(const Event::Type event, const EventMode mode) const;
 
-    string saveMapping(const EventMode mode) const;
-    int loadMapping(string& list, const EventMode mode);
+    nlohmann::json saveMapping(const EventMode mode) const;
+    int loadMapping(const nlohmann::json& eventMappings, const EventMode mode);
+
+    static nlohmann::json convertLegacyMapping(string list);
 
     /** Erase all mappings for given mode */
     void eraseMode(const EventMode mode);
diff --git a/src/common/KeyMap.cxx b/src/common/KeyMap.cxx
index 47b34dc9c..2e493b331 100644
--- a/src/common/KeyMap.cxx
+++ b/src/common/KeyMap.cxx
@@ -16,8 +16,12 @@
 //============================================================================
 
 #include "KeyMap.hxx"
+#include "Logger.hxx"
+#include "jsonDefinitions.hxx"
 #include <map>
 
+using json = nlohmann::json;
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void KeyMap::add(const Event::Type event, const Mapping& mapping)
 {
@@ -169,54 +173,74 @@ KeyMap::MappingArray KeyMap::getEventMapping(const Event::Type event, const Even
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-string KeyMap::saveMapping(const EventMode mode) const
+json KeyMap::saveMapping(const EventMode mode) const
 {
-  using MapType = std::pair<Mapping, Event::Type>;
-  std::vector<MapType> sortedMap(myMap.begin(), myMap.end());
+  json mappings = json::array();
 
-  std::sort(sortedMap.begin(), sortedMap.end(),
-    [](const MapType& a, const MapType& b)
-    {
-      // Event::Type first
-      if(a.second != b.second)
-        return a.second < b.second;
+  for (auto item : myMap) {
+    if (item.first.mode != mode) continue;
 
-      if(a.first.key != b.first.key)
-        return a.first.key < b.first.key;
+    json mapping = json::object();
 
-      return a.first.mod < b.first.mod;
-    }
-  );
+    mapping["event"] = item.second;
+    mapping["key"] = item.first.key;
 
-  ostringstream buf;
+    if (item.first.mod != StellaMod::KBDM_NONE)
+      mapping["mod"] = item.first.mod;
 
-  for (auto item : sortedMap)
-  {
-    if (item.first.mode == mode)
-    {
-      if (buf.str() != "")
-        buf << "|";
-      buf << item.second << ":" << item.first.key << "," << item.first.mod;
-    }
+    mappings.push_back(mapping);
   }
-  return buf.str();
+
+  return mappings;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-int KeyMap::loadMapping(string& list, const EventMode mode)
+int KeyMap::loadMapping(const json& mappings, const EventMode mode) {
+  int i = 0;
+
+  for (const json& mapping: mappings) {
+    try {
+      add(
+        mapping.at("event").get<Event::Type>(),
+        mode,
+        mapping.at("key").get<StellaKey>(),
+        mapping.contains("mod") ? mapping.at("mod").get<StellaMod>() : StellaMod::KBDM_NONE
+      );
+
+      i++;
+    } catch (json::exception) {
+      Logger::error("ignoring bad keyboard mapping");
+    }
+  }
+
+  return i;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+json KeyMap::convertLegacyMapping(string list)
 {
+  json convertedMapping = json::array();
+
   // Since istringstream swallows whitespace, we have to make the
   // delimiters be spaces
   std::replace(list.begin(), list.end(), '|', ' ');
   std::replace(list.begin(), list.end(), ':', ' ');
   std::replace(list.begin(), list.end(), ',', ' ');
   istringstream buf(list);
-  int event, key, mod, i = 0;
+  int event, key, mod;
 
-  while (buf >> event && buf >> key && buf >> mod && ++i)
-    add(Event::Type(event), mode, key, mod);
+  while (buf >> event && buf >> key && buf >> mod) {
+    json mapping = json::object();
 
-  return i;
+    mapping["event"] = Event::Type(event);
+    mapping["key"] = StellaKey(key);
+
+    if (StellaMod(mod) != StellaMod::KBDM_NONE) mapping["mod"] = StellaMod(mod);
+
+    convertedMapping.push_back(mapping);
+  }
+
+  return convertedMapping;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/common/KeyMap.hxx b/src/common/KeyMap.hxx
index 0b7eff2fe..b5805225f 100644
--- a/src/common/KeyMap.hxx
+++ b/src/common/KeyMap.hxx
@@ -22,6 +22,7 @@
 #include "Event.hxx"
 #include "EventHandlerConstants.hxx"
 #include "StellaKeys.hxx"
+#include "json.hxx"
 
 /**
   This class handles keyboard mappings in Stella.
@@ -86,8 +87,10 @@ class KeyMap
 
     MappingArray getEventMapping(const Event::Type event, const EventMode mode) const;
 
-    string saveMapping(const EventMode mode) const;
-    int loadMapping(string& list, const EventMode mode);
+    nlohmann::json saveMapping(const EventMode mode) const;
+    int loadMapping(const nlohmann::json& mapping, const EventMode mode);
+
+    static nlohmann::json convertLegacyMapping(string list);
 
     /** Erase all mappings for given mode */
     void eraseMode(const EventMode mode);
diff --git a/src/common/MediaFactory.hxx b/src/common/MediaFactory.hxx
index ad18685cb..8360d9b38 100644
--- a/src/common/MediaFactory.hxx
+++ b/src/common/MediaFactory.hxx
@@ -51,10 +51,10 @@
 
 #if defined(__LIB_RETRO__)
   #include "EventHandlerLIBRETRO.hxx"
-  #include "FrameBufferLIBRETRO.hxx"
+  #include "FBBackendLIBRETRO.hxx"
 #elif defined(SDL_SUPPORT)
   #include "EventHandlerSDL2.hxx"
-  #include "FrameBufferSDL2.hxx"
+  #include "FBBackendSDL2.hxx"
 #else
   #error Unsupported backend!
 #endif
@@ -128,12 +128,12 @@ class MediaFactory
     #endif
     }
 
-    static unique_ptr<FrameBuffer> createVideo(OSystem& osystem)
+    static unique_ptr<FBBackend> createVideoBackend(OSystem& osystem)
     {
     #if defined(__LIB_RETRO__)
-      return make_unique<FrameBufferLIBRETRO>(osystem);
+      return make_unique<FBBackendLIBRETRO>(osystem);
     #elif defined(SDL_SUPPORT)
-      return make_unique<FrameBufferSDL2>(osystem);
+      return make_unique<FBBackendSDL2>(osystem);
     #else
       #error Unsupported platform for FrameBuffer!
     #endif
diff --git a/src/common/PJoystickHandler.cxx b/src/common/PJoystickHandler.cxx
index f9c616921..323caea1c 100644
--- a/src/common/PJoystickHandler.cxx
+++ b/src/common/PJoystickHandler.cxx
@@ -22,12 +22,13 @@
 #include "Settings.hxx"
 #include "EventHandler.hxx"
 #include "PJoystickHandler.hxx"
+#include "Logger.hxx"
 
 #ifdef GUI_SUPPORT
   #include "DialogContainer.hxx"
 #endif
 
-static constexpr char CTRL_DELIM = '^';
+using json = nlohmann::json;
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 PhysicalJoystickHandler::PhysicalJoystickHandler(
@@ -35,25 +36,54 @@ PhysicalJoystickHandler::PhysicalJoystickHandler(
   : myOSystem(system),
     myHandler(handler)
 {
-  Int32 version = myOSystem.settings().getInt("event_ver");
-  // Load previously saved joystick mapping (if any) from settings
-  istringstream buf(myOSystem.settings().getString("joymap"));
+  if(myOSystem.settings().getInt("event_ver") != Event::VERSION) {
+    Logger::info("event version mismatch; dropping previous joystick mappings");
+
+    return;
+  }
+
+  json mappings;
+  const string& serializedMapping = myOSystem.settings().getString("joymap");
+
+  try {
+    mappings = json::parse(serializedMapping);
+  } catch (json::exception) {
+    Logger::info("converting legacy joystick mappings");
+
+    mappings = convertLegacyMapping(serializedMapping);
+  }
+
+  for (const json& mapping: mappings) {
+    if (!mapping.contains("name")) {
+      Logger::error("ignoring bad joystick mapping");
+      continue;
+    }
+
+    myDatabase.emplace(mapping.at("name").get<string>(), StickInfo(mapping));
+  }
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+json PhysicalJoystickHandler::convertLegacyMapping(const string& mapping)
+{
+  constexpr char CTRL_DELIM = '^';
+
+  istringstream buf(mapping);
   string joymap, joyname;
 
-  // First compare if event list version has changed, and disregard the entire
-  // mapping if true
   getline(buf, joymap, CTRL_DELIM); // event list size, ignore
-  if(version == Event::VERSION)
+
+  json convertedMapping = json::array();
+
+  while(getline(buf, joymap, CTRL_DELIM))
   {
-    // Otherwise, put each joystick mapping entry into the database
-    while(getline(buf, joymap, CTRL_DELIM))
-    {
-      istringstream namebuf(joymap);
-      getline(namebuf, joyname, PhysicalJoystick::MODE_DELIM);
-      if(joyname.length() != 0)
-        myDatabase.emplace(joyname, StickInfo(joymap));
-    }
+    istringstream namebuf(joymap);
+    getline(namebuf, joyname, PhysicalJoystick::MODE_DELIM);
+
+    convertedMapping.push_back(PhysicalJoystick::convertLegacyMapping(joymap, joyname));
   }
+
+  return convertedMapping;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -526,15 +556,16 @@ void PhysicalJoystickHandler::saveMapping()
 {
   // Save the joystick mapping hash table, making sure to update it with
   // any changes that have been made during the program run
-  ostringstream joybuf;
+  json mapping = json::array();
 
   for(const auto& i: myDatabase)
   {
-    const string& map = i.second.joy ? i.second.joy->getMap() : i.second.mapping;
-    if(map != "")
-      joybuf << CTRL_DELIM << map;
+    json map = i.second.joy ? i.second.joy->getMap() : i.second.mapping;
+
+    if (!map.is_null()) mapping.emplace_back(map);
   }
-  myOSystem.settings().setValue("joymap", joybuf.str());
+
+  myOSystem.settings().setValue("joymap", mapping.dump());
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/common/PJoystickHandler.hxx b/src/common/PJoystickHandler.hxx
index fe7aad585..8e43bdf97 100644
--- a/src/common/PJoystickHandler.hxx
+++ b/src/common/PJoystickHandler.hxx
@@ -28,6 +28,7 @@ class Event;
 #include "EventHandlerConstants.hxx"
 #include "PhysicalJoystick.hxx"
 #include "Variant.hxx"
+#include "json.hxx"
 
 using PhysicalJoystickPtr = shared_ptr<PhysicalJoystick>;
 
@@ -48,10 +49,10 @@ class PhysicalJoystickHandler
   private:
     struct StickInfo
     {
-      StickInfo(const string& map = EmptyString, PhysicalJoystickPtr stick = nullptr)
+      StickInfo(const nlohmann::json& map = nullptr, PhysicalJoystickPtr stick = nullptr)
         : mapping(map), joy(std::move(stick)) {}
 
-      string mapping;
+      nlohmann::json mapping;
       PhysicalJoystickPtr joy;
 
       friend ostream& operator<<(ostream& os, const StickInfo& si) {
@@ -63,6 +64,8 @@ class PhysicalJoystickHandler
   public:
     PhysicalJoystickHandler(OSystem& system, EventHandler& handler);
 
+    static nlohmann::json convertLegacyMapping(const string& mapping);
+
     /** Return stick ID on success, -1 on failure. */
     int add(const PhysicalJoystickPtr& stick);
     bool remove(int id);
diff --git a/src/common/PKeyboardHandler.cxx b/src/common/PKeyboardHandler.cxx
index 7532a1632..108a620b9 100644
--- a/src/common/PKeyboardHandler.cxx
+++ b/src/common/PKeyboardHandler.cxx
@@ -19,6 +19,9 @@
 #include "Console.hxx"
 #include "EventHandler.hxx"
 #include "PKeyboardHandler.hxx"
+#include "json.hxx"
+
+using json = nlohmann::json;
 
 #ifdef DEBUGGER_SUPPORT
   #include "Debugger.hxx"
@@ -29,6 +32,8 @@
 
 #if defined(BSPF_MACOS) || defined(MACOS_KEYS)
 static constexpr int MOD3 = KBDM_GUI;
+static constexpr int CMD = KBDM_GUI;
+static constexpr int OPTION = KBDM_ALT;
 #else
 static constexpr int MOD3 = KBDM_ALT;
 #endif
@@ -44,22 +49,42 @@ PhysicalKeyboardHandler::PhysicalKeyboardHandler(OSystem& system, EventHandler&
   // Compare if event list version has changed so that key maps became invalid
   if (version == Event::VERSION)
   {
-    string list = myOSystem.settings().getString("keymap_emu");
-    myKeyMap.loadMapping(list, EventMode::kCommonMode);
-    list = myOSystem.settings().getString("keymap_joy");
-    myKeyMap.loadMapping(list, EventMode::kJoystickMode);
-    list = myOSystem.settings().getString("keymap_pad");
-    myKeyMap.loadMapping(list, EventMode::kPaddlesMode);
-    list = myOSystem.settings().getString("keymap_key");
-    myKeyMap.loadMapping(list, EventMode::kKeypadMode);
-    list = myOSystem.settings().getString("keymap_ui");
-    myKeyMap.loadMapping(list, EventMode::kMenuMode);
+    loadSerializedMappings(myOSystem.settings().getString("keymap_emu"), EventMode::kCommonMode);
+    loadSerializedMappings(myOSystem.settings().getString("keymap_joy"), EventMode::kJoystickMode);
+    loadSerializedMappings(myOSystem.settings().getString("keymap_pad"), EventMode::kPaddlesMode);
+    loadSerializedMappings(myOSystem.settings().getString("keymap_key"), EventMode::kKeypadMode);
+    loadSerializedMappings(myOSystem.settings().getString("keymap_ui"), EventMode::kMenuMode);
+
     updateDefaults = true;
   }
+
   myKeyMap.enableMod() = myOSystem.settings().getBool("modcombo");
 
   setDefaultMapping(Event::NoType, EventMode::kEmulationMode, updateDefaults);
   setDefaultMapping(Event::NoType, EventMode::kMenuMode, updateDefaults);
+#ifdef GUI_SUPPORT
+  setDefaultMapping(Event::NoType, EventMode::kEditMode, updateDefaults);
+#endif // DEBUG
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void PhysicalKeyboardHandler::loadSerializedMappings(const string& serializedMapping, EventMode mode)
+{
+  json mapping;
+
+  try {
+    mapping = json::parse(serializedMapping);
+  } catch (json::exception) {
+    Logger::info("converting legacy keyboard mappings");
+
+    mapping = KeyMap::convertLegacyMapping(serializedMapping);
+  }
+
+  try {
+    myKeyMap.loadMapping(mapping, mode);
+  } catch (json::exception) {
+    Logger::error("ignoring bad keyboard mappings");
+  }
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -99,6 +124,17 @@ void PhysicalKeyboardHandler::setDefaultKey(EventMapping map, Event::Type event,
   // Otherwise, only reset the given event
   bool eraseAll = !updateDefaults && (event == Event::NoType);
 
+#ifdef GUI_SUPPORT
+  // Swap Y and Z for QWERTZ keyboards
+  if(mode == EventMode::kEditMode && myHandler.isQwertz())
+  {
+    if(map.key == KBDK_Z)
+      map.key = KBDK_Y;
+    else if(map.key == KBDK_Y)
+      map.key = KBDK_Z;
+  }
+#endif
+
   if (updateDefaults)
   {
     // if there is no existing mapping for the event and
@@ -151,13 +187,22 @@ void PhysicalKeyboardHandler::setDefaultMapping(Event::Type event, EventMode mod
         setDefaultKey(item, event, EventMode::kMenuMode, updateDefaults);
       break;
 
+  #ifdef GUI_SUPPORT
+    case EventMode::kEditMode:
+      // Edit mode events are always set because they are not saved
+      for(const auto& item: FixedEditMapping)
+        setDefaultKey(item, event, EventMode::kEditMode);
+      break;
+  #endif
+
     default:
       break;
   }
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void PhysicalKeyboardHandler::defineControllerMappings(const Controller::Type type, Controller::Jack port)
+void PhysicalKeyboardHandler::defineControllerMappings(
+    const Controller::Type type, Controller::Jack port)
 {
   // determine controller events to use
   switch(type)
@@ -199,7 +244,8 @@ void PhysicalKeyboardHandler::enableEmulationMappings()
   myKeyMap.eraseMode(EventMode::kEmulationMode);
   enableCommonMappings();
 
-  // enable right mode first, so that in case of mapping clashes the left controller has preference
+  // enable right mode first, so that in case of mapping clashes the left
+  // controller has preference
   switch (myRightMode)
   {
     case EventMode::kPaddlesMode:
@@ -253,14 +299,16 @@ void PhysicalKeyboardHandler::enableCommonMappings()
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void PhysicalKeyboardHandler::enableMappings(const Event::EventSet& events, EventMode mode)
+void PhysicalKeyboardHandler::enableMappings(const Event::EventSet& events,
+                                             EventMode mode)
 {
   for (const auto& event : events)
     enableMapping(event, mode);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void PhysicalKeyboardHandler::enableMapping(const Event::Type event, EventMode mode)
+void PhysicalKeyboardHandler::enableMapping(const Event::Type event,
+                                            EventMode mode)
 {
   // copy from controller mode into emulation mode
   KeyMap::MappingArray mappings = myKeyMap.getEventMapping(event, mode);
@@ -270,7 +318,8 @@ void PhysicalKeyboardHandler::enableMapping(const Event::Type event, EventMode m
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-EventMode PhysicalKeyboardHandler::getEventMode(const Event::Type event, const EventMode mode) const
+EventMode PhysicalKeyboardHandler::getEventMode(const Event::Type event,
+                                                const EventMode mode) const
 {
   if (mode == EventMode::kEmulationMode)
   {
@@ -328,11 +377,11 @@ void PhysicalKeyboardHandler::eraseMapping(Event::Type event, EventMode mode)
 void PhysicalKeyboardHandler::saveMapping()
 {
   myOSystem.settings().setValue("event_ver", Event::VERSION);
-  myOSystem.settings().setValue("keymap_emu", myKeyMap.saveMapping(EventMode::kCommonMode));
-  myOSystem.settings().setValue("keymap_joy", myKeyMap.saveMapping(EventMode::kJoystickMode));
-  myOSystem.settings().setValue("keymap_pad", myKeyMap.saveMapping(EventMode::kPaddlesMode));
-  myOSystem.settings().setValue("keymap_key", myKeyMap.saveMapping(EventMode::kKeypadMode));
-  myOSystem.settings().setValue("keymap_ui", myKeyMap.saveMapping(EventMode::kMenuMode));
+  myOSystem.settings().setValue("keymap_emu", myKeyMap.saveMapping(EventMode::kCommonMode).dump());
+  myOSystem.settings().setValue("keymap_joy", myKeyMap.saveMapping(EventMode::kJoystickMode).dump());
+  myOSystem.settings().setValue("keymap_pad", myKeyMap.saveMapping(EventMode::kPaddlesMode).dump());
+  myOSystem.settings().setValue("keymap_key", myKeyMap.saveMapping(EventMode::kKeypadMode).dump());
+  myOSystem.settings().setValue("keymap_ui", myKeyMap.saveMapping(EventMode::kMenuMode).dump());
   enableEmulationMappings();
 }
 
@@ -356,7 +405,7 @@ bool PhysicalKeyboardHandler::addMapping(Event::Type event, EventMode mode,
       myKeyMap.erase(EventMode::kKeypadMode, key, mod);
       myKeyMap.erase(EventMode::kCompuMateMode, key, mod);
     }
-    else if(evMode != EventMode::kMenuMode)
+    else if(evMode != EventMode::kMenuMode && evMode != EventMode::kEditMode)
     {
       // erase identical mapping for kCommonMode
       myKeyMap.erase(EventMode::kCommonMode, key, mod);
@@ -371,11 +420,12 @@ bool PhysicalKeyboardHandler::addMapping(Event::Type event, EventMode mode,
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void PhysicalKeyboardHandler::handleEvent(StellaKey key, StellaMod mod, bool pressed, bool repeated)
+void PhysicalKeyboardHandler::handleEvent(StellaKey key, StellaMod mod,
+                                          bool pressed, bool repeated)
 {
 #ifdef BSPF_UNIX
   // Swallow KBDK_TAB under certain conditions
-  // See commments on 'myAltKeyCounter' for more information
+  // See comments on 'myAltKeyCounter' for more information
   if(myAltKeyCounter > 1 && key == KBDK_TAB)
   {
     myAltKeyCounter = 0;
@@ -431,7 +481,8 @@ void PhysicalKeyboardHandler::handleEvent(StellaKey key, StellaMod mod, bool pre
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultCommonMapping = {
+PhysicalKeyboardHandler::EventMappingArray
+PhysicalKeyboardHandler::DefaultCommonMapping = {
   {Event::ConsoleSelect,            KBDK_F1},
   {Event::ConsoleReset,             KBDK_F2},
   {Event::ConsoleColor,             KBDK_F3},
@@ -470,6 +521,7 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultCommo
   {Event::VCenterIncrease,          KBDK_PAGEDOWN, MOD3},
   {Event::VSizeAdjustDecrease,      KBDK_PAGEDOWN, KBDM_SHIFT | MOD3},
   {Event::VSizeAdjustIncrease,      KBDK_PAGEUP, KBDM_SHIFT | MOD3},
+  {Event::ToggleCorrectAspectRatio, KBDK_C, KBDM_CTRL},
   {Event::VolumeDecrease,           KBDK_LEFTBRACKET, MOD3},
   {Event::VolumeIncrease,           KBDK_RIGHTBRACKET, MOD3},
   {Event::SoundToggle,              KBDK_RIGHTBRACKET, KBDM_CTRL},
@@ -533,8 +585,8 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultCommo
   {Event::ToggleTimeMachine,        KBDK_T, MOD3},
 
 #ifdef PNG_SUPPORT
-  {Event::ToggleContSnapshots,      KBDK_S, MOD3},
-  {Event::ToggleContSnapshotsFrame, KBDK_S, KBDM_SHIFT | MOD3},
+  {Event::ToggleContSnapshots,      KBDK_S, MOD3 | KBDM_CTRL},
+  {Event::ToggleContSnapshotsFrame, KBDK_S, KBDM_SHIFT | MOD3 | KBDM_CTRL},
 #endif
 
   {Event::DecreaseAutoFire,         KBDK_A, KBDM_SHIFT | KBDM_CTRL},
@@ -586,12 +638,14 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultCommo
 };
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultMenuMapping = {
+PhysicalKeyboardHandler::EventMappingArray
+PhysicalKeyboardHandler::DefaultMenuMapping = {
   {Event::UIUp,                     KBDK_UP},
   {Event::UIDown,                   KBDK_DOWN},
   {Event::UILeft,                   KBDK_LEFT},
   {Event::UIRight,                  KBDK_RIGHT},
   {Event::UISelect,                 KBDK_RETURN},
+  {Event::UISelect,                 KBDK_SPACE},
 
   {Event::UIHome,                   KBDK_HOME},
   {Event::UIEnd,                    KBDK_END},
@@ -639,6 +693,88 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultMenuM
 #endif
 };
 
+#ifdef GUI_SUPPORT
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+PhysicalKeyboardHandler::EventMappingArray
+PhysicalKeyboardHandler::FixedEditMapping = {
+  {Event::MoveLeftChar,             KBDK_LEFT},
+  {Event::MoveRightChar,            KBDK_RIGHT},
+  {Event::SelectLeftChar,           KBDK_LEFT, KBDM_SHIFT},
+  {Event::SelectRightChar,          KBDK_RIGHT, KBDM_SHIFT},
+#if defined(BSPF_MACOS) || defined(MACOS_KEYS)
+  {Event::MoveLeftWord,             KBDK_LEFT, OPTION},
+  {Event::MoveRightWord,            KBDK_RIGHT, OPTION},
+  {Event::MoveHome,                 KBDK_HOME},
+  {Event::MoveHome,                 KBDK_A, KBDM_CTRL},
+  {Event::MoveHome,                 KBDK_LEFT, CMD},
+  {Event::MoveEnd,                  KBDK_END},
+  {Event::MoveEnd,                  KBDK_E, KBDM_CTRL},
+  {Event::MoveEnd,                  KBDK_RIGHT, CMD},
+  {Event::SelectLeftWord,           KBDK_LEFT, KBDM_SHIFT | OPTION},
+  {Event::SelectRightWord,          KBDK_RIGHT, KBDM_SHIFT | OPTION},
+  {Event::SelectHome,               KBDK_HOME, KBDM_SHIFT},
+  {Event::SelectHome,               KBDK_LEFT, KBDM_SHIFT | CMD},
+  {Event::SelectHome,               KBDK_A, KBDM_CTRL | KBDM_SHIFT},
+  {Event::SelectEnd,                KBDK_E, KBDM_SHIFT | KBDM_CTRL},
+  {Event::SelectEnd,                KBDK_RIGHT, KBDM_SHIFT | CMD},
+  {Event::SelectEnd,                KBDK_END, KBDM_SHIFT},
+  {Event::SelectAll,                KBDK_A, CMD},
+  {Event::Delete,                   KBDK_DELETE},
+  {Event::Delete,                   KBDK_D, KBDM_CTRL},
+  {Event::DeleteLeftWord,           KBDK_W, KBDM_CTRL},
+  {Event::DeleteLeftWord,           KBDK_BACKSPACE, OPTION},
+  {Event::DeleteRightWord,          KBDK_DELETE, OPTION},
+  {Event::DeleteHome,               KBDK_U, KBDM_CTRL},
+  {Event::DeleteHome,               KBDK_BACKSPACE, CMD},
+  {Event::DeleteEnd,                KBDK_K, KBDM_CTRL},
+  {Event::Backspace,                KBDK_BACKSPACE},
+  {Event::Undo,                     KBDK_Z, CMD},
+  {Event::Redo,                     KBDK_Y, CMD},
+  {Event::Redo,                     KBDK_Z, KBDM_SHIFT | CMD},
+  {Event::Cut,                      KBDK_X, CMD},
+  {Event::Copy,                     KBDK_C, CMD},
+  {Event::Paste,                    KBDK_V, CMD},
+#else
+  {Event::MoveLeftWord,             KBDK_LEFT, KBDM_CTRL},
+  {Event::MoveRightWord,            KBDK_RIGHT, KBDM_CTRL},
+  {Event::MoveHome,                 KBDK_HOME},
+  {Event::MoveEnd,                  KBDK_END},
+  {Event::SelectLeftWord,           KBDK_LEFT, KBDM_SHIFT | KBDM_CTRL},
+  {Event::SelectRightWord,          KBDK_RIGHT, KBDM_SHIFT | KBDM_CTRL},
+  {Event::SelectHome,               KBDK_HOME, KBDM_SHIFT},
+  {Event::SelectEnd,                KBDK_END, KBDM_SHIFT},
+  {Event::SelectAll,                KBDK_A, KBDM_CTRL},
+  {Event::Delete,                   KBDK_DELETE},
+  {Event::Delete,                   KBDK_KP_PERIOD},
+  {Event::Delete,                   KBDK_D, KBDM_CTRL},
+  {Event::DeleteLeftWord,           KBDK_BACKSPACE, KBDM_CTRL},
+  {Event::DeleteLeftWord,           KBDK_W, KBDM_CTRL},
+  {Event::DeleteRightWord,          KBDK_DELETE, KBDM_CTRL},
+  {Event::DeleteRightWord,          KBDK_D, KBDM_ALT},
+  {Event::DeleteHome,               KBDK_HOME, KBDM_CTRL},
+  {Event::DeleteHome,               KBDK_U, KBDM_CTRL},
+  {Event::DeleteEnd,                KBDK_END, KBDM_CTRL},
+  {Event::DeleteEnd,                KBDK_K, KBDM_CTRL},
+  {Event::Backspace,                KBDK_BACKSPACE},
+  {Event::Undo,                     KBDK_Z, KBDM_CTRL},
+  {Event::Undo,                     KBDK_BACKSPACE, KBDM_ALT},
+  {Event::Redo,                     KBDK_Y, KBDM_CTRL},
+  {Event::Redo,                     KBDK_Z, KBDM_SHIFT | KBDM_CTRL},
+  {Event::Redo,                     KBDK_BACKSPACE, KBDM_SHIFT | KBDM_ALT},
+  {Event::Cut,                      KBDK_X, KBDM_CTRL},
+  {Event::Cut,                      KBDK_DELETE, KBDM_SHIFT},
+  {Event::Cut,                      KBDK_KP_PERIOD, KBDM_SHIFT},
+  {Event::Copy,                     KBDK_C, KBDM_CTRL},
+  {Event::Copy,                     KBDK_INSERT, KBDM_CTRL},
+  {Event::Paste,                    KBDK_V, KBDM_CTRL},
+  {Event::Paste,                    KBDK_INSERT, KBDM_SHIFT},
+#endif
+  {Event::EndEdit,                  KBDK_RETURN},
+  {Event::EndEdit,                  KBDK_KP_ENTER},
+  {Event::AbortEdit,                KBDK_ESCAPE},
+};
+#endif
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultJoystickMapping = {
   {Event::JoystickZeroUp,           KBDK_UP},
@@ -658,6 +794,7 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultJoyst
   {Event::JoystickZeroFire9,        KBDK_5},
   {Event::JoystickZeroFire9,        KBDK_RCTRL},
   {Event::JoystickZeroFire9,        KBDK_KP_3},
+
   {Event::JoystickOneUp,            KBDK_Y},
   {Event::JoystickOneDown,          KBDK_H},
   {Event::JoystickOneLeft,          KBDK_G},
@@ -665,10 +802,27 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultJoyst
   {Event::JoystickOneFire,          KBDK_F},
   {Event::JoystickOneFire5,         KBDK_6},
   {Event::JoystickOneFire9,         KBDK_7},
+
+  {Event::JoystickTwoUp,            KBDK_UP, KBDM_SHIFT},
+  {Event::JoystickTwoDown,          KBDK_DOWN, KBDM_SHIFT},
+  {Event::JoystickTwoLeft,          KBDK_LEFT, KBDM_SHIFT},
+  {Event::JoystickTwoRight,         KBDK_RIGHT, KBDM_SHIFT},
+  {Event::JoystickTwoUp,            KBDK_KP_8, KBDM_SHIFT},
+  {Event::JoystickTwoDown,          KBDK_KP_2, KBDM_SHIFT},
+  {Event::JoystickTwoLeft,          KBDK_KP_4, KBDM_SHIFT},
+  {Event::JoystickTwoRight,         KBDK_KP_6, KBDM_SHIFT},
+  {Event::JoystickTwoFire,          KBDK_SPACE, KBDM_SHIFT},
+
+  {Event::JoystickThreeUp,          KBDK_Y, KBDM_SHIFT},
+  {Event::JoystickThreeDown,        KBDK_H, KBDM_SHIFT},
+  {Event::JoystickThreeLeft,        KBDK_G, KBDM_SHIFT},
+  {Event::JoystickThreeRight,       KBDK_J, KBDM_SHIFT},
+  {Event::JoystickThreeFire,        KBDK_F, KBDM_SHIFT},
 };
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultPaddleMapping = {
+PhysicalKeyboardHandler::EventMappingArray
+PhysicalKeyboardHandler::DefaultPaddleMapping = {
   {Event::PaddleZeroDecrease,       KBDK_RIGHT},
   {Event::PaddleZeroIncrease,       KBDK_LEFT},
   {Event::PaddleZeroFire,           KBDK_SPACE},
@@ -690,7 +844,8 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultPaddl
 };
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultKeypadMapping = {
+PhysicalKeyboardHandler::EventMappingArray
+PhysicalKeyboardHandler::DefaultKeypadMapping = {
   {Event::KeyboardZero1,            KBDK_1},
   {Event::KeyboardZero2,            KBDK_2},
   {Event::KeyboardZero3,            KBDK_3},
@@ -719,7 +874,8 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultKeypa
 };
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::CompuMateMapping = {
+PhysicalKeyboardHandler::EventMappingArray
+PhysicalKeyboardHandler::CompuMateMapping = {
   {Event::CompuMateShift,         KBDK_LSHIFT},
   {Event::CompuMateShift,         KBDK_RSHIFT},
   {Event::CompuMateFunc,          KBDK_LCTRL},
diff --git a/src/common/PKeyboardHandler.hxx b/src/common/PKeyboardHandler.hxx
index ede6aa55a..b285f619b 100644
--- a/src/common/PKeyboardHandler.hxx
+++ b/src/common/PKeyboardHandler.hxx
@@ -45,6 +45,8 @@ class PhysicalKeyboardHandler
 
     PhysicalKeyboardHandler(OSystem& system, EventHandler& handler);
 
+    void loadSerializedMappings(const string& serializedMappings, EventMode mode);
+
     void setDefaultMapping(Event::Type type, EventMode mode, bool updateDefaults = false);
 
     /** define mappings for current controllers */
@@ -106,6 +108,7 @@ class PhysicalKeyboardHandler
     void enableMappings(const Event::EventSet& events, EventMode mode);
     void enableMapping(const Event::Type event, EventMode mode);
 
+  private:
     OSystem& myOSystem;
     EventHandler& myHandler;
 
@@ -132,6 +135,9 @@ class PhysicalKeyboardHandler
 
     // Controller menu and common emulation mappings
     static EventMappingArray DefaultMenuMapping;
+  #ifdef GUI_SUPPORT
+    static EventMappingArray FixedEditMapping;
+  #endif
     static EventMappingArray DefaultCommonMapping;
     // Controller specific mappings
     static EventMappingArray DefaultJoystickMapping;
diff --git a/src/common/PNGLibrary.cxx b/src/common/PNGLibrary.cxx
index ae7d3390f..2a6f84d6a 100644
--- a/src/common/PNGLibrary.cxx
+++ b/src/common/PNGLibrary.cxx
@@ -267,7 +267,7 @@ void PNGLibrary::toggleContinuousSnapshots(bool perFrame)
       buf << "Enabling snapshots in " << interval << " second intervals";
       interval *= uInt32(myOSystem.frameRate());
     }
-    myOSystem.frameBuffer().showMessage(buf.str());
+    myOSystem.frameBuffer().showTextMessage(buf.str());
     setContinuousSnapInterval(interval);
   }
   else
@@ -276,7 +276,7 @@ void PNGLibrary::toggleContinuousSnapshots(bool perFrame)
     buf << "Disabling snapshots, generated "
       << (mySnapCounter / mySnapInterval)
       << " files";
-    myOSystem.frameBuffer().showMessage(buf.str());
+    myOSystem.frameBuffer().showTextMessage(buf.str());
     setContinuousSnapInterval(0);
   }
 }
@@ -296,7 +296,6 @@ void PNGLibrary::takeSnapshot(uInt32 number)
 
   // Figure out the correct snapshot name
   string filename;
-  bool showmessage = number == 0;
   string sspath = myOSystem.snapshotSaveDir().getPath() +
       (myOSystem.settings().getString("snapname") != "int" ?
           myOSystem.romFile().getNameWithExt("")
@@ -347,9 +346,9 @@ void PNGLibrary::takeSnapshot(uInt32 number)
   VarList::push_back(comments, "TV Effects", myOSystem.frameBuffer().tiaSurface().effectsInfo());
 
   // Now create a PNG snapshot
+  string message = "Snapshot saved";
   if(myOSystem.settings().getBool("ss1x"))
   {
-    string message = "Snapshot saved";
     try
     {
       Common::Rect rect;
@@ -360,8 +359,6 @@ void PNGLibrary::takeSnapshot(uInt32 number)
     {
       message = e.what();
     }
-    if(showmessage)
-      myOSystem.frameBuffer().showMessage(message);
   }
   else
   {
@@ -369,7 +366,6 @@ void PNGLibrary::takeSnapshot(uInt32 number)
     myOSystem.frameBuffer().enableMessages(false);
     myOSystem.frameBuffer().tiaSurface().renderForSnapshot();
 
-    string message = "Snapshot saved";
     try
     {
       myOSystem.png().saveImage(filename, comments);
@@ -381,9 +377,8 @@ void PNGLibrary::takeSnapshot(uInt32 number)
 
     // Re-enable old messages
     myOSystem.frameBuffer().enableMessages(true);
-    if(showmessage)
-      myOSystem.frameBuffer().showMessage(message);
   }
+  myOSystem.frameBuffer().showTextMessage(message);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/common/PaletteHandler.cxx b/src/common/PaletteHandler.cxx
index 030ff4d9e..f13c18ab1 100644
--- a/src/common/PaletteHandler.cxx
+++ b/src/common/PaletteHandler.cxx
@@ -69,35 +69,69 @@ void PaletteHandler::cyclePalette(int direction)
   const string palette = toPaletteName(PaletteType(type));
   const string message = MESSAGES[type] + " palette";
 
-  myOSystem.frameBuffer().showMessage(message);
+  myOSystem.frameBuffer().showTextMessage(message);
 
   setPalette(palette);
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool PaletteHandler::isCustomAdjustable() const
+{
+  return myCurrentAdjustable >= CUSTOM_START
+    && myCurrentAdjustable <= CUSTOM_END;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool PaletteHandler::isPhaseShift() const
+{
+  return myCurrentAdjustable == PHASE_SHIFT;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool PaletteHandler::isRGBScale() const
+{
+  return myCurrentAdjustable >= RED_SCALE && myCurrentAdjustable <= BLUE_SCALE;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool PaletteHandler::isRGBShift() const
+{
+  return myCurrentAdjustable >= RED_SHIFT && myCurrentAdjustable <= BLUE_SHIFT;
+}
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void PaletteHandler::showAdjustableMessage()
 {
-  const bool isPhaseShift = myAdjustables[myCurrentAdjustable].value == nullptr;
   ostringstream msg, buf;
 
   msg << "Palette " << myAdjustables[myCurrentAdjustable].name;
-  if(isPhaseShift)
+  if(isPhaseShift())
   {
     const ConsoleTiming timing = myOSystem.console().timing();
     const bool isNTSC = timing == ConsoleTiming::ntsc;
     const float value =
         myOSystem.console().timing() == ConsoleTiming::pal ? myPhasePAL : myPhaseNTSC;
     buf << std::fixed << std::setprecision(1) << value << DEGREE;
-    myOSystem.frameBuffer().showMessage(
+    myOSystem.frameBuffer().showGaugeMessage(
         "Palette phase shift", buf.str(), value,
-        (isNTSC ? DEF_NTSC_SHIFT : DEF_PAL_SHIFT) - MAX_SHIFT,
-        (isNTSC ? DEF_NTSC_SHIFT : DEF_PAL_SHIFT) + MAX_SHIFT);
+        (isNTSC ? DEF_NTSC_SHIFT : DEF_PAL_SHIFT) - MAX_PHASE_SHIFT,
+        (isNTSC ? DEF_NTSC_SHIFT : DEF_PAL_SHIFT) + MAX_PHASE_SHIFT);
+  }
+  else if(isRGBShift())
+  {
+    const float value = *myAdjustables[myCurrentAdjustable].value;
+
+    buf << std::fixed << std::setprecision(1) << value << DEGREE;
+    myOSystem.frameBuffer().showGaugeMessage(
+      msg.str(), buf.str(), value, -MAX_RGB_SHIFT, +MAX_RGB_SHIFT);
   }
   else
   {
-    const int value = scaleTo100(*myAdjustables[myCurrentAdjustable].value);
+    const int value = isRGBScale()
+      ? scaleRGBTo100(*myAdjustables[myCurrentAdjustable].value)
+      : scaleTo100(*myAdjustables[myCurrentAdjustable].value);
     buf << value << "%";
-    myOSystem.frameBuffer().showMessage(
+    myOSystem.frameBuffer().showGaugeMessage(
       msg.str(), buf.str(), value);
   }
 }
@@ -106,15 +140,15 @@ void PaletteHandler::showAdjustableMessage()
 void PaletteHandler::cycleAdjustable(int direction)
 {
   const bool isCustomPalette = SETTING_CUSTOM == myOSystem.settings().getString("palette");
-  bool isPhaseShift;
+  bool isCustomAdj;
 
   do {
     myCurrentAdjustable = BSPF::clampw(int(myCurrentAdjustable + direction), 0, NUM_ADJUSTABLES - 1);
-    isPhaseShift = myAdjustables[myCurrentAdjustable].value == nullptr;
+    isCustomAdj = isCustomAdjustable();
     // skip phase shift when 'Custom' palette is not selected
-    if(!direction && isPhaseShift && !isCustomPalette)
+    if(!direction && isCustomAdj && !isCustomPalette)
       myCurrentAdjustable++;
-  } while(isPhaseShift && !isCustomPalette);
+  } while(isCustomAdj && !isCustomPalette);
 
   showAdjustableMessage();
 }
@@ -122,29 +156,38 @@ void PaletteHandler::cycleAdjustable(int direction)
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void PaletteHandler::changeAdjustable(int adjustable, int direction)
 {
-  const bool isCustomPalette = SETTING_CUSTOM == myOSystem.settings().getString("palette");
-  const bool isPhaseShift = myAdjustables[adjustable].value == nullptr;
-
   myCurrentAdjustable = adjustable;
-  if(isPhaseShift && !isCustomPalette)
-    myCurrentAdjustable++;
-
   changeCurrentAdjustable(direction);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void PaletteHandler::changeCurrentAdjustable(int direction)
 {
-  if(myAdjustables[myCurrentAdjustable].value == nullptr)
+  if(isPhaseShift())
     changeColorPhaseShift(direction);
   else
   {
-    int newVal = scaleTo100(*myAdjustables[myCurrentAdjustable].value);
+    if(isRGBScale())
+    {
+      int newVal = scaleRGBTo100(*myAdjustables[myCurrentAdjustable].value);
 
-    newVal = BSPF::clamp(newVal + direction * 1, 0, 100);
+      newVal = BSPF::clamp(newVal + direction * 1, 0, 100);
+      *myAdjustables[myCurrentAdjustable].value = scaleRGBFrom100(newVal);
+    }
+    else if(isRGBShift())
+    {
+      float newShift = *myAdjustables[myCurrentAdjustable].value;
 
-    *myAdjustables[myCurrentAdjustable].value = scaleFrom100(newVal);
+      newShift = BSPF::clamp(newShift + direction * 0.5F, -MAX_RGB_SHIFT, MAX_RGB_SHIFT);
+      *myAdjustables[myCurrentAdjustable].value = newShift;
+    }
+    else
+    {
+      int newVal = scaleTo100(*myAdjustables[myCurrentAdjustable].value);
 
+      newVal = BSPF::clamp(newVal + direction * 1, 0, 100);
+      *myAdjustables[myCurrentAdjustable].value = scaleFrom100(newVal);
+    }
     showAdjustableMessage();
     setPalette();
   }
@@ -162,7 +205,7 @@ void PaletteHandler::changeColorPhaseShift(int direction)
     const float shift = isNTSC ? DEF_NTSC_SHIFT : DEF_PAL_SHIFT;
     float newPhase = isNTSC ? myPhaseNTSC : myPhasePAL;
 
-    newPhase = BSPF::clamp(newPhase + direction * 0.3F, shift - MAX_SHIFT, shift + MAX_SHIFT);
+    newPhase = BSPF::clamp(newPhase + direction * 0.3F, shift - MAX_PHASE_SHIFT, shift + MAX_PHASE_SHIFT);
 
     if(isNTSC)
       myPhaseNTSC = newPhase;
@@ -181,15 +224,21 @@ void PaletteHandler::loadConfig(const Settings& settings)
 {
   // Load adjustables
   myPhaseNTSC   = BSPF::clamp(settings.getFloat("pal.phase_ntsc"),
-                              DEF_NTSC_SHIFT - MAX_SHIFT, DEF_NTSC_SHIFT + MAX_SHIFT);
+                              DEF_NTSC_SHIFT - MAX_PHASE_SHIFT, DEF_NTSC_SHIFT + MAX_PHASE_SHIFT);
   myPhasePAL    = BSPF::clamp(settings.getFloat("pal.phase_pal"),
-                              DEF_PAL_SHIFT - MAX_SHIFT, DEF_PAL_SHIFT + MAX_SHIFT);
+                              DEF_PAL_SHIFT - MAX_PHASE_SHIFT, DEF_PAL_SHIFT + MAX_PHASE_SHIFT);
+  myRedScale    = BSPF::clamp(settings.getFloat("pal.red_scale"),   -1.0F, 1.0F) + 1.F;
+  myGreenScale  = BSPF::clamp(settings.getFloat("pal.green_scale"), -1.0F, 1.0F) + 1.F;
+  myBlueScale   = BSPF::clamp(settings.getFloat("pal.blue_scale"),  -1.0F, 1.0F) + 1.F;
+  myRedShift    = BSPF::clamp(settings.getFloat("pal.red_shift"),   -MAX_RGB_SHIFT, MAX_RGB_SHIFT);
+  myGreenShift  = BSPF::clamp(settings.getFloat("pal.green_shift"), -MAX_RGB_SHIFT, MAX_RGB_SHIFT);
+  myBlueShift   = BSPF::clamp(settings.getFloat("pal.blue_shift"),  -MAX_RGB_SHIFT, MAX_RGB_SHIFT);
 
-  myHue         = BSPF::clamp(settings.getFloat("pal.hue"), -1.0F, 1.0F);
-  mySaturation  = BSPF::clamp(settings.getFloat("pal.saturation"), -1.0F, 1.0F);
-  myContrast    = BSPF::clamp(settings.getFloat("pal.contrast"), -1.0F, 1.0F);
-  myBrightness  = BSPF::clamp(settings.getFloat("pal.brightness"), -1.0F, 1.0F);
-  myGamma       = BSPF::clamp(settings.getFloat("pal.gamma"), -1.0F, 1.0F);
+  myHue         = BSPF::clamp(settings.getFloat("pal.hue"),         -1.0F, 1.0F);
+  mySaturation  = BSPF::clamp(settings.getFloat("pal.saturation"),  -1.0F, 1.0F);
+  myContrast    = BSPF::clamp(settings.getFloat("pal.contrast"),    -1.0F, 1.0F);
+  myBrightness  = BSPF::clamp(settings.getFloat("pal.brightness"),  -1.0F, 1.0F);
+  myGamma       = BSPF::clamp(settings.getFloat("pal.gamma"),       -1.0F, 1.0F);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -198,6 +247,12 @@ void PaletteHandler::saveConfig(Settings& settings) const
   // Save adjustables
   settings.setValue("pal.phase_ntsc", myPhaseNTSC);
   settings.setValue("pal.phase_pal", myPhasePAL);
+  settings.setValue("pal.red_scale", myRedScale - 1.F);
+  settings.setValue("pal.green_scale", myGreenScale - 1.F);
+  settings.setValue("pal.blue_scale", myBlueScale - 1.F);
+  settings.setValue("pal.red_shift", myRedShift);
+  settings.setValue("pal.green_shift", myGreenShift);
+  settings.setValue("pal.blue_shift", myBlueShift);
 
   settings.setValue("pal.hue", myHue);
   settings.setValue("pal.saturation", mySaturation);
@@ -209,8 +264,14 @@ void PaletteHandler::saveConfig(Settings& settings) const
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void PaletteHandler::setAdjustables(const Adjustable& adjustable)
 {
-  myPhaseNTSC   = adjustable.phaseNtsc / 10.F;
-  myPhasePAL    = adjustable.phasePal / 10.F;
+  myPhaseNTSC   = scaleFromAngles(adjustable.phaseNtsc);
+  myPhasePAL    = scaleFromAngles(adjustable.phasePal);
+  myRedScale    = scaleRGBFrom100(adjustable.redScale);
+  myGreenScale  = scaleRGBFrom100(adjustable.greenScale);
+  myBlueScale   = scaleRGBFrom100(adjustable.blueScale);
+  myRedShift    = scaleFromAngles(adjustable.redShift);
+  myGreenShift  = scaleFromAngles(adjustable.greenShift);
+  myBlueShift   = scaleFromAngles(adjustable.blueShift);
 
   myHue         = scaleFrom100(adjustable.hue);
   mySaturation  = scaleFrom100(adjustable.saturation);
@@ -222,8 +283,14 @@ void PaletteHandler::setAdjustables(const Adjustable& adjustable)
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void PaletteHandler::getAdjustables(Adjustable& adjustable) const
 {
-  adjustable.phaseNtsc   = myPhaseNTSC * 10.F;
-  adjustable.phasePal    = myPhasePAL * 10.F;
+  adjustable.phaseNtsc   = scaleToAngles(myPhaseNTSC);
+  adjustable.phasePal    = scaleToAngles(myPhasePAL);
+  adjustable.redScale    = scaleRGBTo100(myRedScale);
+  adjustable.greenScale  = scaleRGBTo100(myGreenScale);
+  adjustable.blueScale   = scaleRGBTo100(myBlueScale);
+  adjustable.redShift    = scaleToAngles(myRedShift);
+  adjustable.greenShift  = scaleToAngles(myGreenShift);
+  adjustable.blueShift   = scaleToAngles(myBlueShift);
 
   adjustable.hue         = scaleTo100(myHue);
   adjustable.saturation  = scaleTo100(mySaturation);
@@ -371,10 +438,9 @@ void PaletteHandler::generateCustomPalette(ConsoleTiming timing)
   constexpr int NUM_LUMA = 8;
   constexpr float SATURATION = 0.25F; // default saturation
 
-  float color[NUM_CHROMA][2] = {{0.0F}};
-
   if(timing == ConsoleTiming::ntsc)
   {
+    vector2d IQ[NUM_CHROMA];
     // YIQ is YUV shifted by 33�
     constexpr float offset = 33 * BSPF::PI_f / 180;
     const float shift = myPhaseNTSC * BSPF::PI_f / 180;
@@ -382,22 +448,23 @@ void PaletteHandler::generateCustomPalette(ConsoleTiming timing)
     // color 0 is grayscale
     for(int chroma = 1; chroma < NUM_CHROMA; chroma++)
     {
-      color[chroma][0] = SATURATION * sinf(offset + shift * (chroma - 1));
-      color[chroma][1] = SATURATION * cosf(offset + shift * (chroma - 1) - BSPF::PI_f);
+      IQ[chroma] = vector2d(SATURATION * sinf(offset + shift * (chroma - 1)),
+                            SATURATION * cosf(offset + shift * (chroma - 1) - BSPF::PI_f));
     }
+    const vector2d IQR = scale(rotate(vector2d(+0.956F, +0.621F), myRedShift),   myRedScale);
+    const vector2d IQG = scale(rotate(vector2d(-0.272F, -0.647F), myGreenShift), myGreenScale);
+    const vector2d IQB = scale(rotate(vector2d(-1.106F, +1.703F), myBlueShift),  myBlueScale);
 
     for(int chroma = 0; chroma < NUM_CHROMA; chroma++)
     {
-      const float I = color[chroma][0];
-      const float Q = color[chroma][1];
-
       for(int luma = 0; luma < NUM_LUMA; luma++)
       {
         const float Y = 0.05F + luma / 8.24F; // 0.05..~0.90
 
-        float R = Y + 0.956F * I + 0.621F * Q;
-        float G = Y - 0.272F * I - 0.647F * Q;
-        float B = Y - 1.106F * I + 1.703F * Q;
+        float R = Y + dotProduct(IQ[chroma], IQR);
+        float G = Y + dotProduct(IQ[chroma], IQG);
+        float B = Y + dotProduct(IQ[chroma], IQB);
+
 
         if(R < 0) R = 0;
         if(G < 0) G = 0;
@@ -420,35 +487,37 @@ void PaletteHandler::generateCustomPalette(ConsoleTiming timing)
     constexpr float offset = BSPF::PI_f;
     const float shift = myPhasePAL * BSPF::PI_f / 180;
     constexpr float fixedShift = 22.5F * BSPF::PI_f / 180;
+    vector2d UV[NUM_CHROMA];
 
     // colors 0, 1, 14 and 15 are grayscale
     for(int chroma = 2; chroma < NUM_CHROMA - 2; chroma++)
     {
       int idx = NUM_CHROMA - 1 - chroma;
-      color[idx][0] = SATURATION * sinf(offset - fixedShift * chroma);
+
+      UV[idx].x = SATURATION * sinf(offset - fixedShift * chroma);
       if ((idx & 1) == 0)
-        color[idx][1] = SATURATION * sinf(offset - shift * (chroma - 3.5F) / 2.F);
+        UV[idx].y = SATURATION * sinf(offset - shift * (chroma - 3.5F) / 2.F);
       else
-        color[idx][1] = SATURATION * -sinf(offset - shift * chroma / 2.F);
+        UV[idx].y = SATURATION * -sinf(offset - shift * chroma / 2.F);
     }
+    // Most sources
+    const vector2d UVR = scale(rotate(vector2d( 0.000F, +1.403F), myRedShift),   myRedScale);
+    const vector2d UVG = scale(rotate(vector2d(-0.344F, -0.714F), myGreenShift), myGreenScale);
+    const vector2d UVB = scale(rotate(vector2d(+0.714F,  0.000F), myBlueShift),  myBlueScale);
+    // German Wikipedia, huh???
+    //float R = Y + 1 / 0.877 * V;
+    //float B = Y + 1 / 0.493 * U;
+    //float G = 1.704 * Y - 0.590 * R - 0.194 * B;
 
     for(int chroma = 0; chroma < NUM_CHROMA; chroma++)
     {
-      const float U = color[chroma][0];
-      const float V = color[chroma][1];
-
       for(int luma = 0; luma < NUM_LUMA; luma++)
       {
         const float Y = 0.05F + luma / 8.24F; // 0.05..~0.90
 
-        // Most sources
-        float R = Y + 1.403F * V;
-        float G = Y - 0.344F * U - 0.714F * V;
-        float B = Y + 1.770F * U;
-        // German Wikipedia, huh???
-        //float B = Y + 1 / 0.493 * U;
-        //float R = Y + 1 / 0.877 * V;
-        //float G = 1.704 * Y - 0.590 * R - 0.194 * B;
+        float R = Y + dotProduct(UV[chroma], UVR);
+        float G = Y + dotProduct(UV[chroma], UVG);
+        float B = Y + dotProduct(UV[chroma], UVB);
 
         if(R < 0) R = 0.0;
         if(G < 0) G = 0.0;
@@ -491,6 +560,28 @@ void PaletteHandler::adjustHueSaturation(int& R, int& G, int& B, float H, float
   B = BSPF::clamp(b, 0.F, 255.F);
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+PaletteHandler::vector2d PaletteHandler::rotate(const PaletteHandler::vector2d& vec, float angle) const
+{
+  const float r = angle * BSPF::PI_f / 180;
+
+  return PaletteHandler::vector2d(vec.x * cosf(r) - vec.y * sinf(r),
+                                  vec.x * sinf(r) + vec.y * cosf(r));
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+PaletteHandler::vector2d PaletteHandler::scale(const PaletteHandler::vector2d& vec, float factor) const
+{
+  return PaletteHandler::vector2d(vec.x * factor, vec.y * factor);
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+float PaletteHandler::dotProduct(const PaletteHandler::vector2d& vec1,
+                                 const PaletteHandler::vector2d& vec2) const
+{
+  return vec1.x * vec2.x + vec1.y * vec2.y;
+}
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 const PaletteArray PaletteHandler::ourNTSCPalette = {
   0x000000, 0, 0x4a4a4a, 0, 0x6f6f6f, 0, 0x8e8e8e, 0,
diff --git a/src/common/PaletteHandler.hxx b/src/common/PaletteHandler.hxx
index 956fcf9b3..42ba37cfc 100644
--- a/src/common/PaletteHandler.hxx
+++ b/src/common/PaletteHandler.hxx
@@ -35,20 +35,32 @@ class PaletteHandler
     // Phase shift default and limits
     static constexpr float DEF_NTSC_SHIFT = 26.2F;
     static constexpr float DEF_PAL_SHIFT = 31.3F; // ~= 360 / 11.5
-    static constexpr float MAX_SHIFT = 4.5F;
+    static constexpr float MAX_PHASE_SHIFT = 4.5F;
+    static constexpr float DEF_RGB_SHIFT = 0.0F;
+    static constexpr float MAX_RGB_SHIFT = 22.5F;
 
     enum Adjustables {
       PHASE_SHIFT,
+      RED_SCALE,
+      GREEN_SCALE,
+      BLUE_SCALE,
+      RED_SHIFT,
+      GREEN_SHIFT,
+      BLUE_SHIFT,
       HUE,
       SATURATION,
       CONTRAST,
       BRIGHTNESS,
-      GAMMA
+      GAMMA,
+      CUSTOM_START = PHASE_SHIFT,
+      CUSTOM_END = BLUE_SHIFT,
     };
 
     // Externally used adjustment parameters
     struct Adjustable {
-      float phaseNtsc{0.F}, phasePal{0.F};
+      float phaseNtsc{0.F}, phasePal{0.F},
+        redScale{0.F}, greenScale{0.F}, blueScale{0.F},
+        redShift{0.F}, greenShift{0.F}, blueShift{0.F};
       uInt32 hue{0}, saturation{0}, contrast{0}, brightness{0}, gamma{0};
     };
 
@@ -108,6 +120,7 @@ class PaletteHandler
     */
     void setPalette();
 
+
   private:
     static constexpr char DEGREE = 0x1c;
 
@@ -121,12 +134,43 @@ class PaletteHandler
       MaxType = Custom
     };
 
+    struct vector2d {
+      float x{0.F};
+      float y{0.F};
+
+      explicit vector2d(float _x = 0.F, float _y = 0.F)
+        : x(_x), y(_y) { }
+    };
+
+    /**
+      Convert RGB adjustables from/to 100% scale
+    */
+    static constexpr float scaleRGBFrom100(float x) { return x / 50.F; }
+    static constexpr uInt32 scaleRGBTo100(float x) { return uInt32(50.0001F * (x - 0.F)); }
+
+    /**
+      Convert angles
+    */
+    static constexpr float scaleFromAngles(float x) { return x / 10.F; }
+    static constexpr Int32 scaleToAngles(float x) { return uInt32(10.F * x); }
+
     /**
       Convert adjustables from/to 100% scale
     */
     static constexpr float scaleFrom100(float x) { return (x / 50.F) - 1.F; }
     static constexpr uInt32 scaleTo100(float x)  { return uInt32(50.0001F * (x + 1.F)); }
 
+    /**
+      Check for 'Custom' palette only adjustables
+    */
+    bool isCustomAdjustable() const;
+
+    bool isPhaseShift() const;
+
+    bool isRGBScale() const;
+
+    bool isRGBShift() const;
+
     /**
       Convert palette settings name to enumeration.
 
@@ -186,6 +230,21 @@ class PaletteHandler
     */
     void adjustHueSaturation(int& R, int& G, int& B, float H, float S);
 
+    /**
+      Rotate a 2D vector.
+    */
+    vector2d rotate(const vector2d& vec, float angle) const;
+
+    /**
+      Scale a 2D vector.
+    */
+    vector2d scale(const vector2d& vec, float factor) const;
+
+    /**
+      Get the dot product of two 2D vectors.
+    */
+    float dotProduct(const vector2d& vec1, const vector2d& vec2) const;
+
     /**
       Loads a user-defined palette file (from OSystem::paletteFile), filling the
       appropriate user-defined palette arrays.
@@ -193,7 +252,7 @@ class PaletteHandler
     void loadUserPalette();
 
   private:
-    static constexpr int NUM_ADJUSTABLES = 6;
+    static constexpr int NUM_ADJUSTABLES = 12;
 
     OSystem& myOSystem;
 
@@ -207,6 +266,12 @@ class PaletteHandler
     const std::array<AdjustableTag, NUM_ADJUSTABLES> myAdjustables =
     { {
       { "phase shift", nullptr },
+      { "red scale", &myRedScale },
+      { "green scale", &myGreenScale },
+      { "blue scale", &myBlueScale },
+      { "red shift", &myRedShift },
+      { "green shift", &myGreenShift },
+      { "blue shift", &myBlueShift },
       { "hue", &myHue },
       { "saturation", &mySaturation },
       { "contrast", &myContrast },
@@ -217,6 +282,14 @@ class PaletteHandler
     // NTSC and PAL color phase shifts
     float myPhaseNTSC{DEF_NTSC_SHIFT};
     float myPhasePAL{DEF_PAL_SHIFT};
+    // Color intensities
+    float myRedScale{1.0F};
+    float myGreenScale{1.0F};
+    float myBlueScale{1.0F};
+    // Color shifts
+    float myRedShift{0.0F};
+    float myGreenShift{0.0F};
+    float myBlueShift{0.0F};
     // range -1.0 to +1.0 (as in AtariNTSC)
     // Basic parameters
     float myHue{0.0F};        // -1 = -180 degrees     +1 = +180 degrees
diff --git a/src/common/PhysicalJoystick.cxx b/src/common/PhysicalJoystick.cxx
index b784c45ae..488d1f318 100644
--- a/src/common/PhysicalJoystick.cxx
+++ b/src/common/PhysicalJoystick.cxx
@@ -22,6 +22,24 @@
 #include "Vec.hxx"
 #include "bspf.hxx"
 #include "PhysicalJoystick.hxx"
+#include "jsonDefinitions.hxx"
+#include "Logger.hxx"
+
+using json = nlohmann::json;
+
+namespace {
+  string jsonName(EventMode eventMode) {
+    return json(eventMode).get<string>();
+  }
+
+  EventMode eventModeFromJsonName(const string& name) {
+    EventMode result;
+
+    from_json(json(name), result);
+
+    return result;
+  }
+}
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void PhysicalJoystick::initialize(int index, const string& desc,
@@ -45,30 +63,56 @@ void PhysicalJoystick::initialize(int index, const string& desc,
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-string PhysicalJoystick::getMap() const
+json PhysicalJoystick::getMap() const
 {
-  // The mapping structure (for remappable devices) is defined as follows:
-  // <NAME>'>'<MODE>['|'(<EVENT>':'<BUTTON>','<AXIS>','<VALUE>)|(<EVENT>':'<BUTTON>','<HAT>','<HATDIR>)]
+  json mapping = json::object();
 
-  ostringstream joybuf;
+  mapping["name"] = name;
 
-  joybuf << name;
-  joybuf << MODE_DELIM << int(EventMode::kMenuMode) << "|" << joyMap.saveMapping(EventMode::kMenuMode);
-  joybuf << MODE_DELIM << int(EventMode::kJoystickMode) << "|" << joyMap.saveMapping(EventMode::kJoystickMode);
-  joybuf << MODE_DELIM << int(EventMode::kPaddlesMode) << "|" << joyMap.saveMapping(EventMode::kPaddlesMode);
-  joybuf << MODE_DELIM << int(EventMode::kKeypadMode) << "|" << joyMap.saveMapping(EventMode::kKeypadMode);
-  joybuf << MODE_DELIM << int(EventMode::kCommonMode) << "|" << joyMap.saveMapping(EventMode::kCommonMode);
+  for (auto& mode: {
+    EventMode::kMenuMode, EventMode::kJoystickMode, EventMode::kPaddlesMode, EventMode::kKeypadMode, EventMode::kCommonMode
+  })
+    mapping[jsonName(mode)] = joyMap.saveMapping(mode);
 
-  return joybuf.str();
+  return mapping;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-bool PhysicalJoystick::setMap(const string& mapString)
+bool PhysicalJoystick::setMap(const json& map)
 {
-  istringstream buf(mapString);
-  string map;
   int i = 0;
 
+  for (auto& entry: map.items()) {
+    if (entry.key() == "name") continue;
+
+    try {
+      joyMap.loadMapping(entry.value(), eventModeFromJsonName(entry.key()));
+    } catch (json::exception) {
+      Logger::error("ignoring invalid json mapping for " + entry.key());
+    }
+
+    i++;
+  }
+
+  if(i != 5)
+  {
+    Logger::error("invalid controller mappings found for " +
+      ((map.contains("name") && map.at("name").is_string()) ? ("stick " + map["name"].get<string>()) : "unknown stick")
+    );
+
+    return false;
+  }
+
+  return true;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+json PhysicalJoystick::convertLegacyMapping(const string& mapping, const string& name)
+{
+  istringstream buf(mapping);
+  json convertedMapping = json::object();
+  string map;
+
   // Skip joystick name
   getline(buf, map, MODE_DELIM);
 
@@ -84,17 +128,14 @@ bool PhysicalJoystick::setMap(const string& mapString)
     // Remove leading "<mode>|" string
     map.erase(0, 2);
 
-    joyMap.loadMapping(map, EventMode(mode));
-    i++;
-  }
-  // Brief error checking
-  if(i != 5)
-  {
-    cerr << "ERROR: Invalid controller mappings found" << endl;
-    return false;
+    json mappingForMode = JoyMap::convertLegacyMapping(map);
+
+    convertedMapping[jsonName(EventMode(mode))] = mappingForMode;
   }
 
-  return true;
+  convertedMapping["name"] = name;
+
+  return convertedMapping;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/common/PhysicalJoystick.hxx b/src/common/PhysicalJoystick.hxx
index a5f54970e..454008f51 100644
--- a/src/common/PhysicalJoystick.hxx
+++ b/src/common/PhysicalJoystick.hxx
@@ -21,6 +21,7 @@
 #include "Event.hxx"
 #include "EventHandlerConstants.hxx"
 #include "JoyMap.hxx"
+#include "json.hxx"
 
 /**
   An abstraction of a physical (real) joystick in Stella.
@@ -44,8 +45,11 @@ class PhysicalJoystick
   public:
     PhysicalJoystick() = default;
 
-    string getMap() const;
-    bool setMap(const string& map);
+    nlohmann::json getMap() const;
+    bool setMap(const nlohmann::json& map);
+
+    static nlohmann::json convertLegacyMapping(const string& mapping, const string& name);
+
     void eraseMap(EventMode mode);
     void eraseEvent(Event::Type event, EventMode mode);
     string about() const;
diff --git a/src/common/Rect.hxx b/src/common/Rect.hxx
index 5243740f2..708de9d86 100644
--- a/src/common/Rect.hxx
+++ b/src/common/Rect.hxx
@@ -44,8 +44,8 @@ struct Point
     if(c != 'x')
       x = y = 0;
   }
-  bool operator==(const Point & p) const { return x == p.x && y == p.y; }
-  bool operator!=(const Point & p) const { return x != p.x || y != p.y; }
+  bool operator==(const Point& p) const { return x == p.x && y == p.y; }
+  bool operator!=(const Point& p) const { return !(*this == p);        }
 
   friend ostream& operator<<(ostream& os, const Point& p) {
     os << p.x << "x" << p.y;
@@ -69,12 +69,17 @@ struct Size
   }
   bool valid() const { return w > 0 && h > 0; }
 
+  void clamp(uInt32 lower_w, uInt32 upper_w, uInt32 lower_h, uInt32 upper_h) {
+    w = BSPF::clamp(w, lower_w, upper_w);
+    h = BSPF::clamp(h, lower_h, upper_h);
+  }
+
   bool operator==(const Size& s) const { return w == s.w && h == s.h; }
-  bool operator!=(const Size& s) const { return w != s.w || h != s.h; }
-  bool operator<(const Size& s)  const { return w < s.w && h < s.h;   }
-  bool operator<=(const Size& s) const { return w <= s.w && h <= s.h; }
-  bool operator>(const Size& s)  const { return w > s.w && h > s.h;   }
-  bool operator>=(const Size& s) const { return w >= s.w && h >= s.h; }
+  bool operator< (const Size& s) const { return w <  s.w && h <  s.h; }
+  bool operator> (const Size& s) const { return w >  s.w || h >  s.h; }
+  bool operator!=(const Size& s) const { return !(*this == s); }
+  bool operator<=(const Size& s) const { return !(*this >  s); }
+  bool operator>=(const Size& s) const { return !(*this <  s); }
 
   friend ostream& operator<<(ostream& os, const Size& s) {
     os << s.w << "x" << s.h;
@@ -170,6 +175,11 @@ struct Rect
       return r.left != x || r.top != y;
     }
 
+    bool operator==(const Rect& r) const {
+      return top == r.top && left == r.left && bottom == r.bottom && right == r.right;
+    }
+    bool operator!=(const Rect& r) const { return !(*this == r); }
+
     friend ostream& operator<<(ostream& os, const Rect& r) {
       os << r.point() << "," << r.size();
       return os;
diff --git a/src/common/RewindManager.cxx b/src/common/RewindManager.cxx
index 70fa481d7..044bc57e9 100644
--- a/src/common/RewindManager.cxx
+++ b/src/common/RewindManager.cxx
@@ -37,7 +37,6 @@ RewindManager::RewindManager(OSystem& system, StateManager& statemgr)
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void RewindManager::setup()
 {
-  myStateSize = 0;
   myLastTimeMachineAdd = false;
 
   const string& prefix = myOSystem.settings().getBool("dev.settings") ? "dev." : "plr.";
@@ -138,7 +137,6 @@ bool RewindManager::addState(const string& message, bool timeMachine)
   s.rewind();  // rewind Serializer internal buffers
   if(myStateManager.saveState(s) && myOSystem.console().tia().saveDisplay(s))
   {
-    myStateSize = std::max(myStateSize, uInt32(s.size()));
     state.message = message;
     state.cycles = myOSystem.console().tia().cycles();
     myLastTimeMachineAdd = timeMachine;
@@ -183,7 +181,7 @@ uInt32 RewindManager::rewindStates(uInt32 numStates)
 
   if(myOSystem.eventHandler().state() != EventHandlerState::TIMEMACHINE
      && myOSystem.eventHandler().state() != EventHandlerState::PLAYBACK)
-    myOSystem.frameBuffer().showMessage(message);
+    myOSystem.frameBuffer().showTextMessage(message);
   return i;
 }
 
@@ -218,7 +216,7 @@ uInt32 RewindManager::unwindStates(uInt32 numStates)
 
   if(myOSystem.eventHandler().state() != EventHandlerState::TIMEMACHINE
      && myOSystem.eventHandler().state() != EventHandlerState::PLAYBACK)
-    myOSystem.frameBuffer().showMessage(message);
+    myOSystem.frameBuffer().showTextMessage(message);
   return i;
 }
 
@@ -256,18 +254,22 @@ string RewindManager::saveAllStates()
     buf.str("");
     out.putString(STATE_HEADER);
     out.putShort(numStates);
-    out.putInt(myStateSize);
 
-    unique_ptr<uInt8[]> buffer = make_unique<uInt8[]>(myStateSize);
     for (uInt32 i = 0; i < numStates; ++i)
     {
       RewindState& state = myStateList.current();
       Serializer& s = state.data;
+      uInt32 stateSize = uInt32(s.size());
+      unique_ptr<uInt8[]> buffer = make_unique<uInt8[]>(stateSize);
+
+      out.putInt(stateSize);
+
       // Rewind Serializer internal buffers
       s.rewind();
+
       // Save state
-      s.getByteArray(buffer.get(), myStateSize);
-      out.putByteArray(buffer.get(), myStateSize);
+      s.getByteArray(buffer.get(), stateSize);
+      out.putByteArray(buffer.get(), stateSize);
       out.putString(state.message);
       out.putLong(state.cycles);
 
@@ -310,25 +312,27 @@ string RewindManager::loadAllStates()
     if (in.getString() != STATE_HEADER)
       return "Incompatible all states file";
     numStates = in.getShort();
-    myStateSize = in.getInt();
 
-    unique_ptr<uInt8[]> buffer = make_unique<uInt8[]>(myStateSize);
     for (uInt32 i = 0; i < numStates; ++i)
     {
       if (myStateList.full())
         compressStates();
 
+      uInt32 stateSize = in.getInt();
+      unique_ptr<uInt8[]> buffer = make_unique<uInt8[]>(stateSize);
+
       // Add new state at the end of the list (queue adds at end)
       // This updates the 'current' iterator inside the list
       myStateList.addLast();
       RewindState& state = myStateList.current();
       Serializer& s = state.data;
+
       // Rewind Serializer internal buffers
       s.rewind();
 
       // Fill new state with saved values
-      in.getByteArray(buffer.get(), myStateSize);
-      s.putByteArray(buffer.get(), myStateSize);
+      in.getByteArray(buffer.get(), stateSize);
+      s.putByteArray(buffer.get(), stateSize);
       state.message = in.getString();
       state.cycles = in.getLong();
     }
diff --git a/src/common/RewindManager.hxx b/src/common/RewindManager.hxx
index 619af7264..5f53083f7 100644
--- a/src/common/RewindManager.hxx
+++ b/src/common/RewindManager.hxx
@@ -144,7 +144,6 @@ class RewindManager
     bool atLast() const  { return myStateList.atLast();  }
     void resize(uInt32 size) { myStateList.resize(size); }
     void clear() {
-      myStateSize = 0;
       myStateList.clear();
     }
 
@@ -176,7 +175,6 @@ class RewindManager
     uInt64 myHorizon{0};
     double myFactor{0.0};
     bool   myLastTimeMachineAdd{false};
-    uInt32 myStateSize{0};
 
     struct RewindState {
       Serializer data;  // actual save state
diff --git a/src/common/SoundSDL2.cxx b/src/common/SoundSDL2.cxx
index af99d3f2c..40b95b0f0 100644
--- a/src/common/SoundSDL2.cxx
+++ b/src/common/SoundSDL2.cxx
@@ -117,7 +117,7 @@ bool SoundSDL2::openDevice()
   if(myIsInitializedFlag)
     SDL_CloseAudioDevice(myDevice);
 
-  myDeviceId = BSPF::clamp(myAudioSettings.device(), 0u, uInt32(myDevices.size() - 1));
+  myDeviceId = BSPF::clamp(myAudioSettings.device(), 0U, uInt32(myDevices.size() - 1));
   const char* device = myDeviceId ? myDevices.at(myDeviceId).first.c_str() : nullptr;
 
   myDevice = SDL_OpenAudioDevice(device, 0, &desired, &myHardwareSpec,
@@ -224,7 +224,7 @@ bool SoundSDL2::toggleMute()
   string message = "Sound ";
   message += enabled ? "unmuted" : "muted";
 
-  myOSystem.frameBuffer().showMessage(message);
+  myOSystem.frameBuffer().showTextMessage(message);
 
   //ostringstream strval;
   //uInt32 volume;
@@ -282,7 +282,7 @@ void SoundSDL2::adjustVolume(int direction)
     strval << percent << "%";
   else
     strval << "Off";
-  myOSystem.frameBuffer().showMessage("Volume", strval.str(), percent);
+  myOSystem.frameBuffer().showGaugeMessage("Volume", strval.str(), percent);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/common/StateManager.cxx b/src/common/StateManager.cxx
index a4add0889..956f62409 100644
--- a/src/common/StateManager.cxx
+++ b/src/common/StateManager.cxx
@@ -132,9 +132,9 @@ void StateManager::toggleTimeMachine()
 
   myActiveMode = myActiveMode == Mode::TimeMachine ? Mode::Off : Mode::TimeMachine;
   if(myActiveMode == Mode::TimeMachine)
-    myOSystem.frameBuffer().showMessage("Time Machine enabled");
+    myOSystem.frameBuffer().showTextMessage("Time Machine enabled");
   else
-    myOSystem.frameBuffer().showMessage("Time Machine disabled");
+    myOSystem.frameBuffer().showTextMessage("Time Machine disabled");
   myOSystem.settings().setValue(devSettings ? "dev.timemachine" : "plr.timemachine", myActiveMode == Mode::TimeMachine);
 }
 
@@ -215,7 +215,7 @@ void StateManager::loadState(int slot)
     {
       buf.str("");
       buf << "Can't open/load from state file " << slot;
-      myOSystem.frameBuffer().showMessage(buf.str());
+      myOSystem.frameBuffer().showTextMessage(buf.str());
       return;
     }
 
@@ -239,7 +239,7 @@ void StateManager::loadState(int slot)
       buf << "Invalid data in state " << slot << " file";
     }
 
-    myOSystem.frameBuffer().showMessage(buf.str());
+    myOSystem.frameBuffer().showTextMessage(buf.str());
   }
 }
 
@@ -261,7 +261,7 @@ void StateManager::saveState(int slot)
     {
       buf.str("");
       buf << "Can't open/save to state file " << slot;
-      myOSystem.frameBuffer().showMessage(buf.str());
+      myOSystem.frameBuffer().showTextMessage(buf.str());
       return;
     }
 
@@ -274,7 +274,7 @@ void StateManager::saveState(int slot)
     catch(...)
     {
       buf << "Error saving state " << slot;
-      myOSystem.frameBuffer().showMessage(buf.str());
+      myOSystem.frameBuffer().showTextMessage(buf.str());
       return;
     }
 
@@ -292,7 +292,7 @@ void StateManager::saveState(int slot)
     else
       buf << "Error saving state " << slot;
 
-    myOSystem.frameBuffer().showMessage(buf.str());
+    myOSystem.frameBuffer().showTextMessage(buf.str());
   }
 }
 
@@ -307,7 +307,7 @@ void StateManager::changeState(int direction)
     buf << "Changed to state slot " << myCurrentSlot;
   else
     buf << "State slot " << myCurrentSlot;
-  myOSystem.frameBuffer().showMessage(buf.str());
+  myOSystem.frameBuffer().showTextMessage(buf.str());
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -318,7 +318,7 @@ void StateManager::toggleAutoSlot()
   // Print appropriate message
   ostringstream buf;
   buf << "Automatic slot change " << (autoSlot ? "enabled" : "disabled");
-  myOSystem.frameBuffer().showMessage(buf.str());
+  myOSystem.frameBuffer().showTextMessage(buf.str());
 
   myOSystem.settings().setValue("autoslot", autoSlot);
 }
diff --git a/src/common/Version.hxx b/src/common/Version.hxx
index 22801ca3a..2d6bf8db8 100644
--- a/src/common/Version.hxx
+++ b/src/common/Version.hxx
@@ -18,7 +18,7 @@
 #ifndef VERSION_HXX
 #define VERSION_HXX
 
-#define STELLA_VERSION "6.3_pre"
-#define STELLA_BUILD "6091"
+#define STELLA_VERSION "6.5_pre"
+#define STELLA_BUILD "6238"
 
 #endif
diff --git a/src/common/VideoModeHandler.cxx b/src/common/VideoModeHandler.cxx
new file mode 100644
index 000000000..e15b12b1c
--- /dev/null
+++ b/src/common/VideoModeHandler.cxx
@@ -0,0 +1,165 @@
+//============================================================================
+//
+//   SSSS    tt          lll  lll
+//  SS  SS   tt           ll   ll
+//  SS     tttttt  eeee   ll   ll   aaaa
+//   SSSS    tt   ee  ee  ll   ll      aa
+//      SS   tt   eeeeee  ll   ll   aaaaa  --  "An Atari 2600 VCS Emulator"
+//  SS  SS   tt   ee      ll   ll  aa  aa
+//   SSSS     ttt  eeeee llll llll  aaaaa
+//
+// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
+// and the Stella Team
+//
+// See the file "License.txt" for information on usage and redistribution of
+// this file, and for a DISCLAIMER OF ALL WARRANTIES.
+//============================================================================
+
+#include "Settings.hxx"
+#include "VideoModeHandler.hxx"
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void VideoModeHandler::setImageSize(const Common::Size& image)
+{
+  myImage = image;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void VideoModeHandler::setDisplaySize(const Common::Size& display, Int32 fsIndex)
+{
+  myDisplay = display;
+  myFSIndex = fsIndex;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+const VideoModeHandler::Mode&
+VideoModeHandler::buildMode(const Settings& settings, bool inTIAMode)
+{
+  const bool windowedRequested = myFSIndex == -1;
+
+  // TIA mode allows zooming at non-integral factors in most cases
+  if(inTIAMode)
+  {
+    if(windowedRequested)
+    {
+      const float zoom = settings.getFloat("tia.zoom");
+      ostringstream desc;
+      desc << (zoom * 100) << "%";
+
+      // Image and screen (aka window) dimensions are the same
+      // Overscan is not applicable in this mode
+      myMode = Mode(myImage.w * zoom, myImage.h * zoom, Mode::Stretch::Fill,
+                    myFSIndex, desc.str(), zoom);
+    }
+    else
+    {
+      const float overscan = 1 - settings.getInt("tia.fs_overscan") / 100.0;
+
+      // First calculate maximum zoom that keeps aspect ratio
+      const float scaleX = float(myImage.w) / myDisplay.w,
+                  scaleY = float(myImage.h) / myDisplay.h;
+      float zoom = 1.F / std::max(scaleX, scaleY);
+
+      // When aspect ratio correction is off, we want pixel-exact images,
+      // so we default to integer zooming
+      if(!settings.getBool("tia.correct_aspect"))
+        zoom = static_cast<uInt32>(zoom);
+
+      if(!settings.getBool("tia.fs_stretch"))  // preserve aspect, use all space
+      {
+        myMode = Mode(myImage.w * zoom, myImage.h * zoom,
+                      myDisplay.w, myDisplay.h,
+                      Mode::Stretch::Preserve, myFSIndex,
+                      "Fullscreen: Preserve aspect, no stretch", zoom, overscan);
+      }
+      else  // ignore aspect, use all space
+      {
+        myMode = Mode(myImage.w * zoom, myImage.h * zoom,
+                      myDisplay.w, myDisplay.h,
+                      Mode::Stretch::Fill, myFSIndex,
+                      "Fullscreen: Ignore aspect, full stretch", zoom, overscan);
+      }
+    }
+  }
+  else  // UI mode (no zooming)
+  {
+    if(windowedRequested)
+      myMode = Mode(myImage.w, myImage.h, Mode::Stretch::None);
+    else
+      myMode = Mode(myImage.w, myImage.h, myDisplay.w, myDisplay.h,
+                    Mode::Stretch::None, myFSIndex);
+  }
+
+  return myMode;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+VideoModeHandler::Mode::Mode(uInt32 iw, uInt32 ih, Stretch smode,
+                             Int32 fsindex, const string& desc,
+                             float zoomLevel)
+  : Mode(iw, ih, iw, ih, smode, fsindex, desc, zoomLevel)
+{
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+VideoModeHandler::Mode::Mode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh,
+                             Stretch smode, Int32 fsindex, const string& desc,
+                             float zoomLevel, float overscan)
+  : stretch(smode),
+    description(desc),
+    zoom(zoomLevel),
+    fsIndex(fsindex)
+{
+  // First set default size and positioning
+  screenS = Common::Size(sw, sh);
+
+  // Now resize based on windowed/fullscreen mode and stretch factor
+  if(fsIndex != -1)  // fullscreen mode
+  {
+    switch(stretch)
+    {
+      case Stretch::Preserve:
+        iw *= overscan;
+        ih *= overscan;
+        break;
+
+      case Stretch::Fill:
+        // Scale to all available space
+        iw = screenS.w * overscan;
+        ih = screenS.h * overscan;
+        break;
+
+      case Stretch::None:
+        // Don't do any scaling at all
+        iw = std::min(iw, screenS.w) * overscan;
+        ih = std::min(ih, screenS.h) * overscan;
+        break;
+    }
+  }
+  else
+  {
+    // In windowed mode, currently the size is scaled to the screen
+    // TODO - this may be updated if/when we allow variable-sized windows
+    switch(stretch)
+    {
+      case Stretch::Preserve:
+      case Stretch::Fill:
+        screenS.w = iw;
+        screenS.h = ih;
+        break;
+
+      case Stretch::None:
+        break;  // Do not change image or screen rects whatsoever
+    }
+  }
+
+  // Now re-calculate the dimensions
+  iw = std::min(iw, screenS.w);
+  ih = std::min(ih, screenS.h);
+
+  imageR.moveTo((screenS.w - iw) >> 1, (screenS.h - ih) >> 1);
+  imageR.setWidth(iw);
+  imageR.setHeight(ih);
+
+  screenR = Common::Rect(screenS);
+}
diff --git a/src/common/VideoModeHandler.hxx b/src/common/VideoModeHandler.hxx
new file mode 100644
index 000000000..8d179dec2
--- /dev/null
+++ b/src/common/VideoModeHandler.hxx
@@ -0,0 +1,113 @@
+//============================================================================
+//
+//   SSSS    tt          lll  lll
+//  SS  SS   tt           ll   ll
+//  SS     tttttt  eeee   ll   ll   aaaa
+//   SSSS    tt   ee  ee  ll   ll      aa
+//      SS   tt   eeeeee  ll   ll   aaaaa  --  "An Atari 2600 VCS Emulator"
+//  SS  SS   tt   ee      ll   ll  aa  aa
+//   SSSS     ttt  eeeee llll llll  aaaaa
+//
+// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
+// and the Stella Team
+//
+// See the file "License.txt" for information on usage and redistribution of
+// this file, and for a DISCLAIMER OF ALL WARRANTIES.
+//============================================================================
+
+#ifndef VIDEO_MODE_HANDLER_HXX
+#define VIDEO_MODE_HANDLER_HXX
+
+class Settings;
+
+#include "Rect.hxx"
+#include "bspf.hxx"
+
+class VideoModeHandler
+{
+  public:
+    // Contains all relevant info for the dimensions of a video screen
+    // Also takes care of the case when the image should be 'centered'
+    // within the given screen:
+    //   'image' is the image dimensions into the screen
+    //   'screen' are the dimensions of the screen itself
+    struct Mode
+    {
+      enum class Stretch {
+        Preserve,   // Stretch to fill all available space; preserve aspect ratio
+        Fill,       // Stretch to fill all available space
+        None        // No stretching (1x zoom)
+      };
+
+      Common::Rect imageR;
+      Common::Rect screenR;
+      Common::Size screenS;
+      Stretch stretch{Mode::Stretch::None};
+      string description;
+      float zoom{1.F};
+      Int32 fsIndex{-1};  // -1 indicates windowed mode
+
+      Mode() = default;
+      Mode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh, Stretch smode,
+           Int32 fsindex = -1, const string& desc = "",
+           float zoomLevel = 1.F, float overscan = 1.F);
+      Mode(uInt32 iw, uInt32 ih, Stretch smode, Int32 fsindex = -1,
+           const string& desc = "", float zoomLevel = 1.F);
+
+      friend ostream& operator<<(ostream& os, const Mode& vm)
+      {
+        os << "image=" << vm.imageR << "  screen=" << vm.screenS
+           << "  stretch=" << (vm.stretch == Stretch::Preserve ? "preserve" :
+                               vm.stretch == Stretch::Fill ? "fill" : "none")
+           << "  desc=" << vm.description << "  zoom=" << vm.zoom
+           << "  fsIndex= " << vm.fsIndex;
+        return os;
+      }
+    };
+
+  public:
+    VideoModeHandler() = default;
+
+    /**
+      Set the base size of the image. Scaling can be applied to this,
+      which will change the effective size.
+
+      @param image  The base dimensions of the image
+    */
+    void setImageSize(const Common::Size& image);
+
+    /**
+      Set the size of the display.  This could be either the desktop size,
+      or the size of the monitor currently active.
+
+      @param display  The dimensions of the enclosing display
+      @param fsIndex  Fullscreen mode in use (-1 indicates windowed mode)
+    */
+    void setDisplaySize(const Common::Size& display, Int32 fsIndex = -1);
+
+    /**
+      Build a video mode based on the given parameters, assuming that
+      setImageSize and setDisplaySize have been previously called.
+
+      @param settings  Used to query various options that affect video mode
+      @param inTIAMode Whether the video mode is being used for TIA emulation
+
+      @return  A video mode based on the given criteria
+    */
+    const VideoModeHandler::Mode& buildMode(const Settings& settings,
+                                            bool inTIAMode);
+
+  private:
+    Common::Size myImage, myDisplay;
+    Int32 myFSIndex{-1};
+
+    Mode myMode;
+
+  private:
+    VideoModeHandler(const VideoModeHandler&) = delete;
+    VideoModeHandler(VideoModeHandler&&) = delete;
+    VideoModeHandler& operator=(const VideoModeHandler&) = delete;
+    VideoModeHandler& operator=(const VideoModeHandler&&) = delete;
+};
+
+#endif // VIDEO_MODE_HANDLER_HXX
diff --git a/src/common/bspf.hxx b/src/common/bspf.hxx
index b23f6475b..d03174558 100644
--- a/src/common/bspf.hxx
+++ b/src/common/bspf.hxx
@@ -93,6 +93,14 @@ constexpr size_t operator "" _KB(unsigned long long size)
    return static_cast<size_t>(size * 1024);
 }
 
+// Output contents of a vector
+template<typename T>
+std::ostream& operator<< (std::ostream& out, const std::vector<T>& v) {
+  for(const auto& elem: v)
+    out << elem << " ";
+  return out;
+}
+
 static const string EmptyString("");
 
 // This is defined by some systems, but Stella has other uses for it
@@ -160,6 +168,12 @@ namespace BSPF
     return (val < lower) ? upper : (val > upper) ? lower : val;
   }
 
+  // Test whether the vector contains the given value
+  template<typename T>
+  bool contains(const std::vector<T>& v, const T& elem) {
+    return !(v.empty() || std::find(v.begin(), v.end(), elem) == v.end());
+  }
+
   // Convert string to given case
   inline const string& toUpperCase(string& s)
   {
diff --git a/src/common/jsonDefinitions.hxx b/src/common/jsonDefinitions.hxx
new file mode 100644
index 000000000..595789845
--- /dev/null
+++ b/src/common/jsonDefinitions.hxx
@@ -0,0 +1,609 @@
+#ifndef JSON_DEFINITIONS_HXX
+#define JSON_DEFINITIONS_HXX
+
+#include "EventHandlerConstants.hxx"
+#include "Event.hxx"
+#include "json.hxx"
+#include "StellaKeys.hxx"
+
+NLOHMANN_JSON_SERIALIZE_ENUM(JoyAxis, {
+  {JoyAxis::NONE, nullptr},
+  {JoyAxis::X, "x"},
+  {JoyAxis::Y, "y"},
+  {JoyAxis::Z, "z"},
+  {JoyAxis::A3, "a3"}
+})
+
+NLOHMANN_JSON_SERIALIZE_ENUM(JoyDir, {
+  {JoyDir::NONE, nullptr},
+  {JoyDir::ANALOG, "analog"},
+  {JoyDir::NEG, "negative"},
+  {JoyDir::POS, "position"}
+})
+
+NLOHMANN_JSON_SERIALIZE_ENUM(JoyHatDir, {
+  {JoyHatDir::CENTER, "center"},
+  {JoyHatDir::DOWN, "down"},
+  {JoyHatDir::LEFT, "left"},
+  {JoyHatDir::RIGHT, "right"},
+  {JoyHatDir::UP, "up"}
+});
+
+NLOHMANN_JSON_SERIALIZE_ENUM(EventMode, {
+  {EventMode::kEditMode, "kEditMode"},
+  {EventMode::kMenuMode, "kMenuMode"},
+  {EventMode::kEmulationMode, "kEmulationMode"},
+  {EventMode::kJoystickMode, "kJoystickMode"},
+  {EventMode::kPaddlesMode, "kPaddlesMode"},
+  {EventMode::kKeypadMode, "kKeypadMode"},
+  {EventMode::kCompuMateMode, "kCompuMateMode"},
+  {EventMode::kCommonMode, "kCommonMode"},
+  {EventMode::kNumModes, "kNumModes"},
+});
+
+NLOHMANN_JSON_SERIALIZE_ENUM(Event::Type, {
+  {Event::NoType, "NoType"},
+  {Event::ConsoleColor, "ConsoleColor"},
+  {Event::ConsoleBlackWhite, "ConsoleBlackWhite"},
+  {Event::ConsoleColorToggle, "ConsoleColorToggle"},
+  {Event::Console7800Pause, "Console7800Pause"},
+  {Event::ConsoleLeftDiffA, "ConsoleLeftDiffA"},
+  {Event::ConsoleLeftDiffB, "ConsoleLeftDiffB"},
+  {Event::ConsoleLeftDiffToggle, "ConsoleLeftDiffToggle"},
+  {Event::ConsoleRightDiffA, "ConsoleRightDiffA"},
+  {Event::ConsoleRightDiffB, "ConsoleRightDiffB"},
+  {Event::ConsoleRightDiffToggle, "ConsoleRightDiffToggle"},
+  {Event::ConsoleSelect, "ConsoleSelect"},
+  {Event::ConsoleReset, "ConsoleReset"},
+  {Event::JoystickZeroUp, "JoystickZeroUp"},
+  {Event::JoystickZeroDown, "JoystickZeroDown"},
+  {Event::JoystickZeroLeft, "JoystickZeroLeft"},
+  {Event::JoystickZeroRight, "JoystickZeroRight"},
+  {Event::JoystickZeroFire, "JoystickZeroFire"},
+  {Event::JoystickZeroFire5, "JoystickZeroFire5"},
+  {Event::JoystickZeroFire9, "JoystickZeroFire9"},
+  {Event::JoystickOneUp, "JoystickOneUp"},
+  {Event::JoystickOneDown, "JoystickOneDown"},
+  {Event::JoystickOneLeft, "JoystickOneLeft"},
+  {Event::JoystickOneRight, "JoystickOneRight"},
+  {Event::JoystickOneFire, "JoystickOneFire"},
+  {Event::JoystickOneFire5, "JoystickOneFire5"},
+  {Event::JoystickOneFire9, "JoystickOneFire9"},
+  {Event::PaddleZeroDecrease, "PaddleZeroDecrease"},
+  {Event::PaddleZeroIncrease, "PaddleZeroIncrease"},
+  {Event::PaddleZeroAnalog, "PaddleZeroAnalog"},
+  {Event::PaddleZeroFire, "PaddleZeroFire"},
+  {Event::PaddleOneDecrease, "PaddleOneDecrease"},
+  {Event::PaddleOneIncrease, "PaddleOneIncrease"},
+  {Event::PaddleOneAnalog, "PaddleOneAnalog"},
+  {Event::PaddleOneFire, "PaddleOneFire"},
+  {Event::PaddleTwoDecrease, "PaddleTwoDecrease"},
+  {Event::PaddleTwoIncrease, "PaddleTwoIncrease"},
+  {Event::PaddleTwoAnalog, "PaddleTwoAnalog"},
+  {Event::PaddleTwoFire, "PaddleTwoFire"},
+  {Event::PaddleThreeDecrease, "PaddleThreeDecrease"},
+  {Event::PaddleThreeIncrease, "PaddleThreeIncrease"},
+  {Event::PaddleThreeAnalog, "PaddleThreeAnalog"},
+  {Event::PaddleThreeFire, "PaddleThreeFire"},
+  {Event::KeyboardZero1, "KeyboardZero1"},
+  {Event::KeyboardZero2, "KeyboardZero2"},
+  {Event::KeyboardZero3, "KeyboardZero3"},
+  {Event::KeyboardZero4, "KeyboardZero4"},
+  {Event::KeyboardZero5, "KeyboardZero5"},
+  {Event::KeyboardZero6, "KeyboardZero6"},
+  {Event::KeyboardZero7, "KeyboardZero7"},
+  {Event::KeyboardZero8, "KeyboardZero8"},
+  {Event::KeyboardZero9, "KeyboardZero9"},
+  {Event::KeyboardZeroStar, "KeyboardZeroStar"},
+  {Event::KeyboardZero0, "KeyboardZero0"},
+  {Event::KeyboardZeroPound, "KeyboardZeroPound"},
+  {Event::KeyboardOne1, "KeyboardOne1"},
+  {Event::KeyboardOne2, "KeyboardOne2"},
+  {Event::KeyboardOne3, "KeyboardOne3"},
+  {Event::KeyboardOne4, "KeyboardOne4"},
+  {Event::KeyboardOne5, "KeyboardOne5"},
+  {Event::KeyboardOne6, "KeyboardOne6"},
+  {Event::KeyboardOne7, "KeyboardOne7"},
+  {Event::KeyboardOne8, "KeyboardOne8"},
+  {Event::KeyboardOne9, "KeyboardOne9"},
+  {Event::KeyboardOneStar, "KeyboardOneStar"},
+  {Event::KeyboardOne0, "KeyboardOne0"},
+  {Event::KeyboardOnePound, "KeyboardOnePound"},
+  {Event::CompuMateFunc, "CompuMateFunc"},
+  {Event::CompuMateShift, "CompuMateShift"},
+  {Event::CompuMate0, "CompuMate0"},
+  {Event::CompuMate1, "CompuMate1"},
+  {Event::CompuMate2, "CompuMate2"},
+  {Event::CompuMate3, "CompuMate3"},
+  {Event::CompuMate4, "CompuMate4"},
+  {Event::CompuMate5, "CompuMate5"},
+  {Event::CompuMate6, "CompuMate6"},
+  {Event::CompuMate7, "CompuMate7"},
+  {Event::CompuMate8, "CompuMate8"},
+  {Event::CompuMate9, "CompuMate9"},
+  {Event::CompuMateA, "CompuMateA"},
+  {Event::CompuMateB, "CompuMateB"},
+  {Event::CompuMateC, "CompuMateC"},
+  {Event::CompuMateD, "CompuMateD"},
+  {Event::CompuMateE, "CompuMateE"},
+  {Event::CompuMateF, "CompuMateF"},
+  {Event::CompuMateG, "CompuMateG"},
+  {Event::CompuMateH, "CompuMateH"},
+  {Event::CompuMateI, "CompuMateI"},
+  {Event::CompuMateJ, "CompuMateJ"},
+  {Event::CompuMateK, "CompuMateK"},
+  {Event::CompuMateL, "CompuMateL"},
+  {Event::CompuMateM, "CompuMateM"},
+  {Event::CompuMateN, "CompuMateN"},
+  {Event::CompuMateO, "CompuMateO"},
+  {Event::CompuMateP, "CompuMateP"},
+  {Event::CompuMateQ, "CompuMateQ"},
+  {Event::CompuMateR, "CompuMateR"},
+  {Event::CompuMateS, "CompuMateS"},
+  {Event::CompuMateT, "CompuMateT"},
+  {Event::CompuMateU, "CompuMateU"},
+  {Event::CompuMateV, "CompuMateV"},
+  {Event::CompuMateW, "CompuMateW"},
+  {Event::CompuMateX, "CompuMateX"},
+  {Event::CompuMateY, "CompuMateY"},
+  {Event::CompuMateZ, "CompuMateZ"},
+  {Event::CompuMateComma, "CompuMateComma"},
+  {Event::CompuMatePeriod, "CompuMatePeriod"},
+  {Event::CompuMateEnter, "CompuMateEnter"},
+  {Event::CompuMateSpace, "CompuMateSpace"},
+  {Event::CompuMateQuestion, "CompuMateQuestion"},
+  {Event::CompuMateLeftBracket, "CompuMateLeftBracket"},
+  {Event::CompuMateRightBracket, "CompuMateRightBracket"},
+  {Event::CompuMateMinus, "CompuMateMinus"},
+  {Event::CompuMateQuote, "CompuMateQuote"},
+  {Event::CompuMateBackspace, "CompuMateBackspace"},
+  {Event::CompuMateEquals, "CompuMateEquals"},
+  {Event::CompuMatePlus, "CompuMatePlus"},
+  {Event::CompuMateSlash, "CompuMateSlash"},
+  {Event::Combo1, "Combo1"},
+  {Event::Combo2, "Combo2"},
+  {Event::Combo3, "Combo3"},
+  {Event::Combo4, "Combo4"},
+  {Event::Combo5, "Combo5"},
+  {Event::Combo6, "Combo6"},
+  {Event::Combo7, "Combo7"},
+  {Event::Combo8, "Combo8"},
+  {Event::Combo9, "Combo9"},
+  {Event::Combo10, "Combo10"},
+  {Event::Combo11, "Combo11"},
+  {Event::Combo12, "Combo12"},
+  {Event::Combo13, "Combo13"},
+  {Event::Combo14, "Combo14"},
+  {Event::Combo15, "Combo15"},
+  {Event::Combo16, "Combo16"},
+  {Event::UIUp, "UIUp"},
+  {Event::UIDown, "UIDown"},
+  {Event::UILeft, "UILeft"},
+  {Event::UIRight, "UIRight"},
+  {Event::UIHome, "UIHome"},
+  {Event::UIEnd, "UIEnd"},
+  {Event::UIPgUp, "UIPgUp"},
+  {Event::UIPgDown, "UIPgDown"},
+  {Event::UISelect, "UISelect"},
+  {Event::UINavPrev, "UINavPrev"},
+  {Event::UINavNext, "UINavNext"},
+  {Event::UIOK, "UIOK"},
+  {Event::UICancel, "UICancel"},
+  {Event::UIPrevDir, "UIPrevDir"},
+  {Event::UITabPrev, "UITabPrev"},
+  {Event::UITabNext, "UITabNext"},
+  {Event::HandleMouseControl, "HandleMouseControl"},
+  {Event::ToggleGrabMouse, "ToggleGrabMouse"},
+  {Event::MouseAxisXMove, "MouseAxisXMove"},
+  {Event::MouseAxisYMove, "MouseAxisYMove"},
+  {Event::MouseAxisXValue, "MouseAxisXValue"},
+  {Event::MouseAxisYValue, "MouseAxisYValue"},
+  {Event::MouseButtonLeftValue, "MouseButtonLeftValue"},
+  {Event::MouseButtonRightValue, "MouseButtonRightValue"},
+  {Event::Quit, "Quit"},
+  {Event::ReloadConsole, "ReloadConsole"},
+  {Event::Fry, "Fry"},
+  {Event::TogglePauseMode, "TogglePauseMode"},
+  {Event::StartPauseMode, "StartPauseMode"},
+  {Event::OptionsMenuMode, "OptionsMenuMode"},
+  {Event::CmdMenuMode, "CmdMenuMode"},
+  {Event::DebuggerMode, "DebuggerMode"},
+  {Event::ExitMode, "ExitMode"},
+  {Event::TakeSnapshot, "TakeSnapshot"},
+  {Event::ToggleContSnapshots, "ToggleContSnapshots"},
+  {Event::ToggleContSnapshotsFrame, "ToggleContSnapshotsFrame"},
+  {Event::ToggleTurbo, "ToggleTurbo"},
+  {Event::NextState, "NextState"},
+  {Event::PreviousState, "PreviousState"},
+  {Event::LoadState, "LoadState"},
+  {Event::SaveState, "SaveState"},
+  {Event::SaveAllStates, "SaveAllStates"},
+  {Event::LoadAllStates, "LoadAllStates"},
+  {Event::ToggleAutoSlot, "ToggleAutoSlot"},
+  {Event::ToggleTimeMachine, "ToggleTimeMachine"},
+  {Event::TimeMachineMode, "TimeMachineMode"},
+  {Event::Rewind1Menu, "Rewind1Menu"},
+  {Event::Rewind10Menu, "Rewind10Menu"},
+  {Event::RewindAllMenu, "RewindAllMenu"},
+  {Event::Unwind1Menu, "Unwind1Menu"},
+  {Event::Unwind10Menu, "Unwind10Menu"},
+  {Event::UnwindAllMenu, "UnwindAllMenu"},
+  {Event::RewindPause, "RewindPause"},
+  {Event::UnwindPause, "UnwindPause"},
+  {Event::FormatDecrease, "FormatDecrease"},
+  {Event::FormatIncrease, "FormatIncrease"},
+  {Event::PaletteDecrease, "PaletteDecrease"},
+  {Event::PaletteIncrease, "PaletteIncrease"},
+  {Event::ToggleColorLoss, "ToggleColorLoss"},
+  {Event::PreviousPaletteAttribute, "PreviousPaletteAttribute"},
+  {Event::NextPaletteAttribute, "NextPaletteAttribute"},
+  {Event::PaletteAttributeDecrease, "PaletteAttributeDecrease"},
+  {Event::PaletteAttributeIncrease, "PaletteAttributeIncrease"},
+  {Event::ToggleFullScreen, "ToggleFullScreen"},
+  {Event::VidmodeDecrease, "VidmodeDecrease"},
+  {Event::VidmodeIncrease, "VidmodeIncrease"},
+  {Event::VCenterDecrease, "VCenterDecrease"},
+  {Event::VCenterIncrease, "VCenterIncrease"},
+  {Event::VSizeAdjustDecrease, "VSizeAdjustDecrease"},
+  {Event::VSizeAdjustIncrease, "VSizeAdjustIncrease"},
+  {Event::OverscanDecrease, "OverscanDecrease"},
+  {Event::OverscanIncrease, "OverscanIncrease"},
+  {Event::VidmodeStd, "VidmodeStd"},
+  {Event::VidmodeRGB, "VidmodeRGB"},
+  {Event::VidmodeSVideo, "VidmodeSVideo"},
+  {Event::VidModeComposite, "VidModeComposite"},
+  {Event::VidModeBad, "VidModeBad"},
+  {Event::VidModeCustom, "VidModeCustom"},
+  {Event::PreviousVideoMode, "PreviousVideoMode"},
+  {Event::NextVideoMode, "NextVideoMode"},
+  {Event::PreviousAttribute, "PreviousAttribute"},
+  {Event::NextAttribute, "NextAttribute"},
+  {Event::DecreaseAttribute, "DecreaseAttribute"},
+  {Event::IncreaseAttribute, "IncreaseAttribute"},
+  {Event::ScanlinesDecrease, "ScanlinesDecrease"},
+  {Event::ScanlinesIncrease, "ScanlinesIncrease"},
+  {Event::PhosphorDecrease, "PhosphorDecrease"},
+  {Event::PhosphorIncrease, "PhosphorIncrease"},
+  {Event::TogglePhosphor, "TogglePhosphor"},
+  {Event::ToggleInter, "ToggleInter"},
+  {Event::ToggleJitter, "ToggleJitter"},
+  {Event::VolumeDecrease, "VolumeDecrease"},
+  {Event::VolumeIncrease, "VolumeIncrease"},
+  {Event::SoundToggle, "SoundToggle"},
+  {Event::ToggleP0Collision, "ToggleP0Collision"},
+  {Event::ToggleP0Bit, "ToggleP0Bit"},
+  {Event::ToggleP1Collision, "ToggleP1Collision"},
+  {Event::ToggleP1Bit, "ToggleP1Bit"},
+  {Event::ToggleM0Collision, "ToggleM0Collision"},
+  {Event::ToggleM0Bit, "ToggleM0Bit"},
+  {Event::ToggleM1Collision, "ToggleM1Collision"},
+  {Event::ToggleM1Bit, "ToggleM1Bit"},
+  {Event::ToggleBLCollision, "ToggleBLCollision"},
+  {Event::ToggleBLBit, "ToggleBLBit"},
+  {Event::TogglePFCollision, "TogglePFCollision"},
+  {Event::TogglePFBit, "TogglePFBit"},
+  {Event::ToggleCollisions, "ToggleCollisions"},
+  {Event::ToggleBits, "ToggleBits"},
+  {Event::ToggleFixedColors, "ToggleFixedColors"},
+  {Event::ToggleFrameStats, "ToggleFrameStats"},
+  {Event::ToggleSAPortOrder, "ToggleSAPortOrder"},
+  {Event::ExitGame, "ExitGame"},
+  {Event::SettingDecrease, "SettingDecrease"},
+  {Event::SettingIncrease, "SettingIncrease"},
+  {Event::PreviousSetting, "PreviousSetting"},
+  {Event::NextSetting, "NextSetting"},
+  {Event::ToggleAdaptRefresh, "ToggleAdaptRefresh"},
+  {Event::PreviousMultiCartRom, "PreviousMultiCartRom"},
+  {Event::PreviousSettingGroup, "PreviousSettingGroup"},
+  {Event::NextSettingGroup, "NextSettingGroup"},
+  {Event::TogglePlayBackMode, "TogglePlayBackMode"},
+  {Event::DecreaseAutoFire, "DecreaseAutoFire"},
+  {Event::IncreaseAutoFire, "IncreaseAutoFire"},
+  {Event::DecreaseSpeed, "DecreaseSpeed"},
+  {Event::IncreaseSpeed, "IncreaseSpeed"},
+  {Event::JoystickTwoUp, "JoystickTwoUp"},
+  {Event::JoystickTwoDown, "JoystickTwoDown"},
+  {Event::JoystickTwoLeft, "JoystickTwoLeft"},
+  {Event::JoystickTwoRight, "JoystickTwoRight"},
+  {Event::JoystickTwoFire, "JoystickTwoFire"},
+  {Event::JoystickThreeUp, "JoystickThreeUp"},
+  {Event::JoystickThreeDown, "JoystickThreeDown"},
+  {Event::JoystickThreeLeft, "JoystickThreeLeft"},
+  {Event::JoystickThreeRight, "JoystickThreeRight"},
+  {Event::JoystickThreeFire, "JoystickThreeFire"},
+  {Event::ToggleCorrectAspectRatio, "ToggleCorrectAspectRatio"},
+  {Event::MoveLeftChar, "MoveLeftChar"},
+  {Event::MoveRightChar, "MoveRightChar"},
+  {Event::MoveLeftWord, "MoveLeftWord"},
+  {Event::MoveRightWord, "MoveRightWord"},
+  {Event::MoveHome, "MoveHome"},
+  {Event::MoveEnd, "MoveEnd"},
+  {Event::SelectLeftChar, "SelectLeftChar"},
+  {Event::SelectRightChar, "SelectRightChar"},
+  {Event::SelectLeftWord, "SelectLeftWord"},
+  {Event::SelectRightWord, "SelectRightWord"},
+  {Event::SelectHome, "SelectHome"},
+  {Event::SelectEnd, "SelectEnd"},
+  {Event::SelectAll, "SelectAll"},
+  {Event::Delete, "Delete"},
+  {Event::DeleteLeftWord, "DeleteLeftWord"},
+  {Event::DeleteRightWord, "DeleteRightWord"},
+  {Event::DeleteHome, "DeleteHome"},
+  {Event::DeleteEnd, "DeleteEnd"},
+  {Event::Backspace, "Backspace"},
+  {Event::Cut, "Cut"},
+  {Event::Copy, "Copy"},
+  {Event::Paste, "Paste"},
+  {Event::Undo, "Undo"},
+  {Event::Redo, "Redo"},
+  {Event::AbortEdit, "AbortEdit"},
+  {Event::EndEdit, "EndEdit"},
+  {Event::LastType, "LastType"}
+})
+
+NLOHMANN_JSON_SERIALIZE_ENUM(StellaKey, {
+  {StellaKey::KBDK_UNKNOWN, "unknown"},
+  {StellaKey::KBDK_A, "a"},
+  {StellaKey::KBDK_B, "b"},
+  {StellaKey::KBDK_C, "c"},
+  {StellaKey::KBDK_D, "d"},
+  {StellaKey::KBDK_E, "e"},
+  {StellaKey::KBDK_F, "f"},
+  {StellaKey::KBDK_G, "g"},
+  {StellaKey::KBDK_H, "h"},
+  {StellaKey::KBDK_I, "i"},
+  {StellaKey::KBDK_J, "j"},
+  {StellaKey::KBDK_K, "k"},
+  {StellaKey::KBDK_L, "l"},
+  {StellaKey::KBDK_M, "m"},
+  {StellaKey::KBDK_N, "n"},
+  {StellaKey::KBDK_O, "o"},
+  {StellaKey::KBDK_P, "p"},
+  {StellaKey::KBDK_Q, "q"},
+  {StellaKey::KBDK_R, "r"},
+  {StellaKey::KBDK_S, "s"},
+  {StellaKey::KBDK_T, "t"},
+  {StellaKey::KBDK_U, "u"},
+  {StellaKey::KBDK_V, "v"},
+  {StellaKey::KBDK_W, "w"},
+  {StellaKey::KBDK_X, "x"},
+  {StellaKey::KBDK_Y, "y"},
+  {StellaKey::KBDK_Z, "z"},
+  {StellaKey::KBDK_1, "1"},
+  {StellaKey::KBDK_2, "2"},
+  {StellaKey::KBDK_3, "3"},
+  {StellaKey::KBDK_4, "4"},
+  {StellaKey::KBDK_5, "5"},
+  {StellaKey::KBDK_6, "6"},
+  {StellaKey::KBDK_7, "7"},
+  {StellaKey::KBDK_8, "8"},
+  {StellaKey::KBDK_9, "9"},
+  {StellaKey::KBDK_0, "0"},
+  {StellaKey::KBDK_RETURN, "return"},
+  {StellaKey::KBDK_ESCAPE, "escape"},
+  {StellaKey::KBDK_BACKSPACE, "backspace"},
+  {StellaKey::KBDK_TAB, "tab"},
+  {StellaKey::KBDK_SPACE, "space"},
+  {StellaKey::KBDK_MINUS, "minus"},
+  {StellaKey::KBDK_EQUALS, "equals"},
+  {StellaKey::KBDK_LEFTBRACKET, "leftbracket"},
+  {StellaKey::KBDK_RIGHTBRACKET, "rightbracket"},
+  {StellaKey::KBDK_BACKSLASH, "backslash"},
+  {StellaKey::KBDK_NONUSHASH, "nonushash"},
+  {StellaKey::KBDK_SEMICOLON, "semicolon"},
+  {StellaKey::KBDK_APOSTROPHE, "apostrophe"},
+  {StellaKey::KBDK_GRAVE, "grave"},
+  {StellaKey::KBDK_COMMA, "comma"},
+  {StellaKey::KBDK_PERIOD, "period"},
+  {StellaKey::KBDK_SLASH, "slash"},
+  {StellaKey::KBDK_CAPSLOCK, "capslock"},
+  {StellaKey::KBDK_F1, "f1"},
+  {StellaKey::KBDK_F2, "f2"},
+  {StellaKey::KBDK_F3, "f3"},
+  {StellaKey::KBDK_F4, "f4"},
+  {StellaKey::KBDK_F5, "f5"},
+  {StellaKey::KBDK_F6, "f6"},
+  {StellaKey::KBDK_F7, "f7"},
+  {StellaKey::KBDK_F8, "f8"},
+  {StellaKey::KBDK_F9, "f9"},
+  {StellaKey::KBDK_F10, "f10"},
+  {StellaKey::KBDK_F11, "f11"},
+  {StellaKey::KBDK_F12, "f12"},
+  {StellaKey::KBDK_PRINTSCREEN, "printscreen"},
+  {StellaKey::KBDK_SCROLLLOCK, "scrolllock"},
+  {StellaKey::KBDK_PAUSE, "pause"},
+  {StellaKey::KBDK_INSERT, "insert"},
+  {StellaKey::KBDK_HOME, "home"},
+  {StellaKey::KBDK_PAGEUP, "pageup"},
+  {StellaKey::KBDK_DELETE, "delete"},
+  {StellaKey::KBDK_END, "end"},
+  {StellaKey::KBDK_PAGEDOWN, "pagedown"},
+  {StellaKey::KBDK_RIGHT, "right"},
+  {StellaKey::KBDK_LEFT, "left"},
+  {StellaKey::KBDK_DOWN, "down"},
+  {StellaKey::KBDK_UP, "up"},
+  {StellaKey::KBDK_NUMLOCKCLEAR, "numlockclear"},
+  {StellaKey::KBDK_KP_DIVIDE, "kp_divide"},
+  {StellaKey::KBDK_KP_MULTIPLY, "kp_multiply"},
+  {StellaKey::KBDK_KP_MINUS, "kp_minus"},
+  {StellaKey::KBDK_KP_PLUS, "kp_plus"},
+  {StellaKey::KBDK_KP_ENTER, "kp_enter"},
+  {StellaKey::KBDK_KP_1, "kp_1"},
+  {StellaKey::KBDK_KP_2, "kp_2"},
+  {StellaKey::KBDK_KP_3, "kp_3"},
+  {StellaKey::KBDK_KP_4, "kp_4"},
+  {StellaKey::KBDK_KP_5, "kp_5"},
+  {StellaKey::KBDK_KP_6, "kp_6"},
+  {StellaKey::KBDK_KP_7, "kp_7"},
+  {StellaKey::KBDK_KP_8, "kp_8"},
+  {StellaKey::KBDK_KP_9, "kp_9"},
+  {StellaKey::KBDK_KP_0, "kp_0"},
+  {StellaKey::KBDK_KP_PERIOD, "kp_period"},
+  {StellaKey::KBDK_NONUSBACKSLASH, "nonusbackslash"},
+  {StellaKey::KBDK_APPLICATION, "application"},
+  {StellaKey::KBDK_POWER, "power"},
+  {StellaKey::KBDK_KP_EQUALS, "kp_equals"},
+  {StellaKey::KBDK_F13, "f13"},
+  {StellaKey::KBDK_F14, "f14"},
+  {StellaKey::KBDK_F15, "f15"},
+  {StellaKey::KBDK_F16, "f16"},
+  {StellaKey::KBDK_F17, "f17"},
+  {StellaKey::KBDK_F18, "f18"},
+  {StellaKey::KBDK_F19, "f19"},
+  {StellaKey::KBDK_F20, "f20"},
+  {StellaKey::KBDK_F21, "f21"},
+  {StellaKey::KBDK_F22, "f22"},
+  {StellaKey::KBDK_F23, "f23"},
+  {StellaKey::KBDK_F24, "f24"},
+  {StellaKey::KBDK_EXECUTE, "execute"},
+  {StellaKey::KBDK_HELP, "help"},
+  {StellaKey::KBDK_MENU, "menu"},
+  {StellaKey::KBDK_SELECT, "select"},
+  {StellaKey::KBDK_STOP, "stop"},
+  {StellaKey::KBDK_AGAIN, "again"},
+  {StellaKey::KBDK_UNDO, "undo"},
+  {StellaKey::KBDK_CUT, "cut"},
+  {StellaKey::KBDK_COPY, "copy"},
+  {StellaKey::KBDK_PASTE, "paste"},
+  {StellaKey::KBDK_FIND, "find"},
+  {StellaKey::KBDK_MUTE, "mute"},
+  {StellaKey::KBDK_VOLUMEUP, "volumeup"},
+  {StellaKey::KBDK_VOLUMEDOWN, "volumedown"},
+  {StellaKey::KBDK_KP_COMMA, "kp_comma"},
+  {StellaKey::KBDK_KP_EQUALSAS400, "kp_equalsas400"},
+  {StellaKey::KBDK_INTERNATIONAL1, "international1"},
+  {StellaKey::KBDK_INTERNATIONAL2, "international2"},
+  {StellaKey::KBDK_INTERNATIONAL3, "international3"},
+  {StellaKey::KBDK_INTERNATIONAL4, "international4"},
+  {StellaKey::KBDK_INTERNATIONAL5, "international5"},
+  {StellaKey::KBDK_INTERNATIONAL6, "international6"},
+  {StellaKey::KBDK_INTERNATIONAL7, "international7"},
+  {StellaKey::KBDK_INTERNATIONAL8, "international8"},
+  {StellaKey::KBDK_INTERNATIONAL9, "international9"},
+  {StellaKey::KBDK_LANG1, "lang1"},
+  {StellaKey::KBDK_LANG2, "lang2"},
+  {StellaKey::KBDK_LANG3, "lang3"},
+  {StellaKey::KBDK_LANG4, "lang4"},
+  {StellaKey::KBDK_LANG5, "lang5"},
+  {StellaKey::KBDK_LANG6, "lang6"},
+  {StellaKey::KBDK_LANG7, "lang7"},
+  {StellaKey::KBDK_LANG8, "lang8"},
+  {StellaKey::KBDK_LANG9, "lang9"},
+  {StellaKey::KBDK_ALTERASE, "alterase"},
+  {StellaKey::KBDK_SYSREQ, "sysreq"},
+  {StellaKey::KBDK_CANCEL, "cancel"},
+  {StellaKey::KBDK_CLEAR, "clear"},
+  {StellaKey::KBDK_PRIOR, "prior"},
+  {StellaKey::KBDK_RETURN2, "return2"},
+  {StellaKey::KBDK_SEPARATOR, "separator"},
+  {StellaKey::KBDK_OUT, "out"},
+  {StellaKey::KBDK_OPER, "oper"},
+  {StellaKey::KBDK_CLEARAGAIN, "clearagain"},
+  {StellaKey::KBDK_CRSEL, "crsel"},
+  {StellaKey::KBDK_EXSEL, "exsel"},
+  {StellaKey::KBDK_KP_00, "kp_00"},
+  {StellaKey::KBDK_KP_000, "kp_000"},
+  {StellaKey::KBDK_THOUSANDSSEPARATOR, "thousandsseparator"},
+  {StellaKey::KBDK_DECIMALSEPARATOR, "decimalseparator"},
+  {StellaKey::KBDK_CURRENCYUNIT, "currencyunit"},
+  {StellaKey::KBDK_CURRENCYSUBUNIT, "currencysubunit"},
+  {StellaKey::KBDK_KP_LEFTPAREN, "kp_leftparen"},
+  {StellaKey::KBDK_KP_RIGHTPAREN, "kp_rightparen"},
+  {StellaKey::KBDK_KP_LEFTBRACE, "kp_leftbrace"},
+  {StellaKey::KBDK_KP_RIGHTBRACE, "kp_rightbrace"},
+  {StellaKey::KBDK_KP_TAB, "kp_tab"},
+  {StellaKey::KBDK_KP_BACKSPACE, "kp_backspace"},
+  {StellaKey::KBDK_KP_A, "kp_a"},
+  {StellaKey::KBDK_KP_B, "kp_b"},
+  {StellaKey::KBDK_KP_C, "kp_c"},
+  {StellaKey::KBDK_KP_D, "kp_d"},
+  {StellaKey::KBDK_KP_E, "kp_e"},
+  {StellaKey::KBDK_KP_F, "kp_f"},
+  {StellaKey::KBDK_KP_XOR, "kp_xor"},
+  {StellaKey::KBDK_KP_POWER, "kp_power"},
+  {StellaKey::KBDK_KP_PERCENT, "kp_percent"},
+  {StellaKey::KBDK_KP_LESS, "kp_less"},
+  {StellaKey::KBDK_KP_GREATER, "kp_greater"},
+  {StellaKey::KBDK_KP_AMPERSAND, "kp_ampersand"},
+  {StellaKey::KBDK_KP_DBLAMPERSAND, "kp_dblampersand"},
+  {StellaKey::KBDK_KP_VERTICALBAR, "kp_verticalbar"},
+  {StellaKey::KBDK_KP_DBLVERTICALBAR, "kp_dblverticalbar"},
+  {StellaKey::KBDK_KP_COLON, "kp_colon"},
+  {StellaKey::KBDK_KP_HASH, "kp_hash"},
+  {StellaKey::KBDK_KP_SPACE, "kp_space"},
+  {StellaKey::KBDK_KP_AT, "kp_at"},
+  {StellaKey::KBDK_KP_EXCLAM, "kp_exclam"},
+  {StellaKey::KBDK_KP_MEMSTORE, "kp_memstore"},
+  {StellaKey::KBDK_KP_MEMRECALL, "kp_memrecall"},
+  {StellaKey::KBDK_KP_MEMCLEAR, "kp_memclear"},
+  {StellaKey::KBDK_KP_MEMADD, "kp_memadd"},
+  {StellaKey::KBDK_KP_MEMSUBTRACT, "kp_memsubtract"},
+  {StellaKey::KBDK_KP_MEMMULTIPLY, "kp_memmultiply"},
+  {StellaKey::KBDK_KP_MEMDIVIDE, "kp_memdivide"},
+  {StellaKey::KBDK_KP_PLUSMINUS, "kp_plusminus"},
+  {StellaKey::KBDK_KP_CLEAR, "kp_clear"},
+  {StellaKey::KBDK_KP_CLEARENTRY, "kp_clearentry"},
+  {StellaKey::KBDK_KP_BINARY, "kp_binary"},
+  {StellaKey::KBDK_KP_OCTAL, "kp_octal"},
+  {StellaKey::KBDK_KP_DECIMAL, "kp_decimal"},
+  {StellaKey::KBDK_KP_HEXADECIMAL, "kp_hexadecimal"},
+  {StellaKey::KBDK_LCTRL, "lctrl"},
+  {StellaKey::KBDK_LSHIFT, "lshift"},
+  {StellaKey::KBDK_LALT, "lalt"},
+  {StellaKey::KBDK_LGUI, "lgui"},
+  {StellaKey::KBDK_RCTRL, "rctrl"},
+  {StellaKey::KBDK_RSHIFT, "rshift"},
+  {StellaKey::KBDK_RALT, "ralt"},
+  {StellaKey::KBDK_RGUI, "rgui"},
+  {StellaKey::KBDK_MODE, "mode"},
+  {StellaKey::KBDK_AUDIONEXT, "audionext"},
+  {StellaKey::KBDK_AUDIOPREV, "audioprev"},
+  {StellaKey::KBDK_AUDIOSTOP, "audiostop"},
+  {StellaKey::KBDK_AUDIOPLAY, "audioplay"},
+  {StellaKey::KBDK_AUDIOMUTE, "audiomute"},
+  {StellaKey::KBDK_MEDIASELECT, "mediaselect"},
+  {StellaKey::KBDK_WWW, "www"},
+  {StellaKey::KBDK_MAIL, "mail"},
+  {StellaKey::KBDK_CALCULATOR, "calculator"},
+  {StellaKey::KBDK_COMPUTER, "computer"},
+  {StellaKey::KBDK_AC_SEARCH, "ac_search"},
+  {StellaKey::KBDK_AC_HOME, "ac_home"},
+  {StellaKey::KBDK_AC_BACK, "ac_back"},
+  {StellaKey::KBDK_AC_FORWARD, "ac_forward"},
+  {StellaKey::KBDK_AC_STOP, "ac_stop"},
+  {StellaKey::KBDK_AC_REFRESH, "ac_refresh"},
+  {StellaKey::KBDK_AC_BOOKMARKS, "ac_bookmarks"},
+  {StellaKey::KBDK_BRIGHTNESSDOWN, "brightnessdown"},
+  {StellaKey::KBDK_BRIGHTNESSUP, "brightnessup"},
+  {StellaKey::KBDK_DISPLAYSWITCH, "displayswitch"},
+  {StellaKey::KBDK_KBDILLUMTOGGLE, "kbdillumtoggle"},
+  {StellaKey::KBDK_KBDILLUMDOWN, "kbdillumdown"},
+  {StellaKey::KBDK_KBDILLUMUP, "kbdillumup"},
+  {StellaKey::KBDK_EJECT, "eject"},
+  {StellaKey::KBDK_SLEEP, "sleep"},
+  {StellaKey::KBDK_APP1, "app1"},
+  {StellaKey::KBDK_APP2, "app2"},
+  {StellaKey::KBDK_LAST, "last"}
+})
+
+NLOHMANN_JSON_SERIALIZE_ENUM(StellaMod, {
+  {StellaMod::KBDM_NONE, "none"},
+  {StellaMod::KBDM_LSHIFT, "lshift"},
+  {StellaMod::KBDM_RSHIFT, "rshift"},
+  {StellaMod::KBDM_LCTRL, "lctrl"},
+  {StellaMod::KBDM_RCTRL, "rctrl"},
+  {StellaMod::KBDM_LALT, "lalt"},
+  {StellaMod::KBDM_RALT, "ralt"},
+  {StellaMod::KBDM_LGUI, "lgui"},
+  {StellaMod::KBDM_RGUI, "rgui"},
+  {StellaMod::KBDM_NUM, "num"},
+  {StellaMod::KBDM_CAPS, "caps"},
+  {StellaMod::KBDM_MODE, "mode"},
+  {StellaMod::KBDM_RESERVED, "reserved"},
+  {StellaMod::KBDM_CTRL, "ctrl"},
+  {StellaMod::KBDM_SHIFT, "shift"},
+  {StellaMod::KBDM_ALT, "alt"},
+  {StellaMod::KBDM_GUI, "gui"}
+})
+
+#endif // JSON_DEFINITIONS_HXX
diff --git a/src/common/module.mk b/src/common/module.mk
index 1aae6cd0a..7fa2cf6f9 100644
--- a/src/common/module.mk
+++ b/src/common/module.mk
@@ -1,10 +1,13 @@
 MODULE := src/common
 
 MODULE_OBJS := \
+	src/common/AudioQueue.o \
+	src/common/AudioSettings.o \
 	src/common/Base.o \
 	src/common/EventHandlerSDL2.o \
+	src/common/FBBackendSDL2.o \
 	src/common/FBSurfaceSDL2.o \
-	src/common/FrameBufferSDL2.o \
+	src/common/FpsMeter.o \
 	src/common/FSNodeZIP.o \
 	src/common/JoyMap.o \
 	src/common/KeyMap.o \
@@ -19,14 +22,12 @@ MODULE_OBJS := \
 	src/common/PNGLibrary.o \
 	src/common/RewindManager.o \
 	src/common/SoundSDL2.o \
-	src/common/StateManager.o \
-	src/common/TimerManager.o \
-	src/common/ZipHandler.o \
-	src/common/AudioQueue.o \
-	src/common/AudioSettings.o \
-	src/common/FpsMeter.o \
-	src/common/ThreadDebugging.o \
 	src/common/StaggeredLogger.o \
+	src/common/StateManager.o \
+	src/common/ThreadDebugging.o \
+	src/common/TimerManager.o \
+	src/common/VideoModeHandler.o \
+	src/common/ZipHandler.o \
 	src/common/repository/KeyValueRepositoryConfigfile.o \
 	src/common/sdl_blitter/BilinearBlitter.o \
 	src/common/sdl_blitter/QisBlitter.o \
diff --git a/src/common/sdl_blitter/BilinearBlitter.cxx b/src/common/sdl_blitter/BilinearBlitter.cxx
index 295d8e8e2..d8f25d133 100644
--- a/src/common/sdl_blitter/BilinearBlitter.cxx
+++ b/src/common/sdl_blitter/BilinearBlitter.cxx
@@ -15,12 +15,12 @@
 // this file, and for a DISCLAIMER OF ALL WARRANTIES.
 //============================================================================
 
-#include "FrameBufferSDL2.hxx"
+#include "FBBackendSDL2.hxx"
 #include "ThreadDebugging.hxx"
 #include "BilinearBlitter.hxx"
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-BilinearBlitter::BilinearBlitter(FrameBufferSDL2& fb, bool interpolate)
+BilinearBlitter::BilinearBlitter(FBBackendSDL2& fb, bool interpolate)
   : myFB(fb),
     myInterpolate(interpolate)
 {
diff --git a/src/common/sdl_blitter/BilinearBlitter.hxx b/src/common/sdl_blitter/BilinearBlitter.hxx
index 8588e390e..684b966c8 100644
--- a/src/common/sdl_blitter/BilinearBlitter.hxx
+++ b/src/common/sdl_blitter/BilinearBlitter.hxx
@@ -18,7 +18,7 @@
 #ifndef BILINEAR_BLITTER_HXX
 #define BILINEAR_BLITTER_HXX
 
-class FrameBufferSDL2;
+class FBBackendSDL2;
 
 #include "Blitter.hxx"
 #include "SDL_lib.hxx"
@@ -27,7 +27,7 @@ class BilinearBlitter : public Blitter {
 
   public:
 
-    BilinearBlitter(FrameBufferSDL2& fb, bool interpolate);
+    BilinearBlitter(FBBackendSDL2& fb, bool interpolate);
 
     ~BilinearBlitter() override;
 
@@ -41,7 +41,7 @@ class BilinearBlitter : public Blitter {
     virtual void blit(SDL_Surface& surface) override;
 
   private:
-    FrameBufferSDL2& myFB;
+    FBBackendSDL2& myFB;
 
     SDL_Texture* myTexture{nullptr};
     SDL_Texture* mySecondaryTexture{nullptr};
diff --git a/src/common/sdl_blitter/BlitterFactory.cxx b/src/common/sdl_blitter/BlitterFactory.cxx
index df567a874..3c969b71b 100644
--- a/src/common/sdl_blitter/BlitterFactory.cxx
+++ b/src/common/sdl_blitter/BlitterFactory.cxx
@@ -21,7 +21,7 @@
 #include "BilinearBlitter.hxx"
 #include "QisBlitter.hxx"
 
-unique_ptr<Blitter> BlitterFactory::createBlitter(FrameBufferSDL2& fb, ScalingAlgorithm scaling)
+unique_ptr<Blitter> BlitterFactory::createBlitter(FBBackendSDL2& fb, ScalingAlgorithm scaling)
 {
   if (!fb.isInitialized()) {
     throw runtime_error("BlitterFactory requires an initialized framebuffer!");
diff --git a/src/common/sdl_blitter/BlitterFactory.hxx b/src/common/sdl_blitter/BlitterFactory.hxx
index 8c1a0cfbf..96f3c9706 100644
--- a/src/common/sdl_blitter/BlitterFactory.hxx
+++ b/src/common/sdl_blitter/BlitterFactory.hxx
@@ -21,8 +21,8 @@
 #include <string>
 
 #include "Blitter.hxx"
+#include "FBBackendSDL2.hxx"
 #include "bspf.hxx"
-#include "FrameBufferSDL2.hxx"
 
 class BlitterFactory {
   public:
@@ -35,7 +35,7 @@ class BlitterFactory {
 
   public:
 
-    static unique_ptr<Blitter> createBlitter(FrameBufferSDL2& fb, ScalingAlgorithm scaling);
+    static unique_ptr<Blitter> createBlitter(FBBackendSDL2& fb, ScalingAlgorithm scaling);
 };
 
 #endif // BLITTER_FACTORY_HXX
diff --git a/src/common/sdl_blitter/QisBlitter.cxx b/src/common/sdl_blitter/QisBlitter.cxx
index c68c4bff9..c0b7f7dbd 100644
--- a/src/common/sdl_blitter/QisBlitter.cxx
+++ b/src/common/sdl_blitter/QisBlitter.cxx
@@ -15,12 +15,12 @@
 // this file, and for a DISCLAIMER OF ALL WARRANTIES.
 //============================================================================
 
-#include "FrameBufferSDL2.hxx"
+#include "FBBackendSDL2.hxx"
 #include "ThreadDebugging.hxx"
 #include "QisBlitter.hxx"
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-QisBlitter::QisBlitter(FrameBufferSDL2& fb)
+QisBlitter::QisBlitter(FBBackendSDL2& fb)
   : myFB(fb)
 {
 }
@@ -32,7 +32,7 @@ QisBlitter::~QisBlitter()
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-bool QisBlitter::isSupported(FrameBufferSDL2 &fb)
+bool QisBlitter::isSupported(FBBackendSDL2& fb)
 {
   if (!fb.isInitialized()) throw runtime_error("framebuffer not initialized");
 
diff --git a/src/common/sdl_blitter/QisBlitter.hxx b/src/common/sdl_blitter/QisBlitter.hxx
index 9aa68e4c0..7fc7c3393 100644
--- a/src/common/sdl_blitter/QisBlitter.hxx
+++ b/src/common/sdl_blitter/QisBlitter.hxx
@@ -18,7 +18,7 @@
 #ifndef QIS_BLITTER_HXX
 #define QIS_BLITTER_HXX
 
-class FrameBufferSDL2;
+class FBBackendSDL2;
 
 #include "Blitter.hxx"
 #include "SDL_lib.hxx"
@@ -27,9 +27,9 @@ class QisBlitter : public Blitter {
 
   public:
 
-    explicit QisBlitter(FrameBufferSDL2& fb);
+    explicit QisBlitter(FBBackendSDL2& fb);
 
-    static bool isSupported(FrameBufferSDL2 &fb);
+    static bool isSupported(FBBackendSDL2& fb);
 
     ~QisBlitter() override;
 
@@ -44,7 +44,7 @@ class QisBlitter : public Blitter {
 
   private:
 
-    FrameBufferSDL2& myFB;
+    FBBackendSDL2& myFB;
 
     SDL_Texture* mySrcTexture{nullptr};
     SDL_Texture* mySecondarySrcTexture{nullptr};
diff --git a/src/debugger/CartDebug.cxx b/src/debugger/CartDebug.cxx
index d62b16b66..ab988e000 100644
--- a/src/debugger/CartDebug.cxx
+++ b/src/debugger/CartDebug.cxx
@@ -605,7 +605,8 @@ bool CartDebug::removeLabel(const string& label)
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-bool CartDebug::getLabel(ostream& buf, uInt16 addr, bool isRead, int places) const
+bool CartDebug::getLabel(ostream& buf, uInt16 addr, bool isRead,
+                         int places, bool isRam) const
 {
   switch(addressType(addr))
   {
@@ -662,21 +663,24 @@ bool CartDebug::getLabel(ostream& buf, uInt16 addr, bool isRead, int places) con
     {
       // RAM can use user-defined labels; otherwise we default to
       // standard mnemonics
-      auto iter = myUserLabels.find(addr);
-      if(iter != myUserLabels.end())
-      {
-        buf << iter->second;
-      }
-      else
-      {
-        uInt16 a = addr & 0xFF, offset = addr & 0xFF00;
-        if((iter = myUserLabels.find(a)) != myUserLabels.end())
+      AddrToLabel::const_iterator iter;
+      uInt16 a = addr & 0xFF, offset = addr & 0xFF00;
+      bool found = false;
+
+      // Search for nearest label
+      for(uInt16 i = a; i >= 0x80; --i)
+        if((iter = myUserLabels.find(i)) != myUserLabels.end())
+        {
           buf << iter->second;
-        else
-          buf << ourZPMnemonic[a - 0x80];
-        if(offset > 0)
-          buf << "|$" << Base::HEX2 << offset;
-      }
+          if(a != i)
+            buf << "+$" << Base::HEX1 << (a - i);
+          found = true;
+          break;
+        }
+      if(!found)
+        buf << ourZPMnemonic[a - 0x80];
+      if(offset > 0)
+        buf << "|$" << Base::HEX2 << offset;
 
       return true;
     }
@@ -684,11 +688,28 @@ bool CartDebug::getLabel(ostream& buf, uInt16 addr, bool isRead, int places) con
     case AddrType::ROM:
     {
       // These addresses can never be in the system labels list
-      const auto& iter = myUserLabels.find(addr);
-      if(iter != myUserLabels.end())
+      if(isRam) // cartridge RAM
       {
-        buf << iter->second;
-        return true;
+        AddrToLabel::const_iterator iter;
+
+        // Search for nearest label
+        for(uInt16 i = addr; i >= (addr & 0xf000); --i)
+          if((iter = myUserLabels.find(i)) != myUserLabels.end())
+          {
+            buf << iter->second;
+            if(addr != i)
+              buf << "+$" << Base::HEX1 << (addr - i);
+            return true;
+          }
+      }
+      else
+      {
+        const auto& iter = myUserLabels.find(addr);
+        if(iter != myUserLabels.end())
+        {
+          buf << iter->second;
+          return true;
+        }
       }
       break;
     }
@@ -713,10 +734,10 @@ bool CartDebug::getLabel(ostream& buf, uInt16 addr, bool isRead, int places) con
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-string CartDebug::getLabel(uInt16 addr, bool isRead, int places) const
+string CartDebug::getLabel(uInt16 addr, bool isRead, int places, bool isRam) const
 {
   ostringstream buf;
-  getLabel(buf, addr, isRead, places);
+  getLabel(buf, addr, isRead, places, isRam);
   return buf.str();
 }
 
diff --git a/src/debugger/CartDebug.hxx b/src/debugger/CartDebug.hxx
index 9d71de51b..25dd59e63 100644
--- a/src/debugger/CartDebug.hxx
+++ b/src/debugger/CartDebug.hxx
@@ -211,8 +211,10 @@ class CartDebug : public DebuggerSystem
       If places is not -1 and a label hasn't been defined, return a
       formatted hexidecimal address
     */
-    bool getLabel(ostream& buf, uInt16 addr, bool isRead, int places = -1) const;
-    string getLabel(uInt16 addr, bool isRead, int places = -1) const;
+    bool getLabel(ostream& buf, uInt16 addr, bool isRead,
+                  int places = -1, bool isRam = false) const;
+    string getLabel(uInt16 addr, bool isRead,
+                    int places = -1, bool isRam = false) const;
     int getAddress(const string& label) const;
 
     /**
diff --git a/src/debugger/Debugger.cxx b/src/debugger/Debugger.cxx
index 315a45c3b..abfc63ac1 100644
--- a/src/debugger/Debugger.cxx
+++ b/src/debugger/Debugger.cxx
@@ -90,21 +90,18 @@ Debugger::~Debugger()
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void Debugger::initialize()
 {
-  const Common::Size& s = myOSystem.settings().getSize("dbg.res");
+  mySize = myOSystem.settings().getSize("dbg.res");
   const Common::Size& d = myOSystem.frameBuffer().desktopSize();
-  myWidth = s.w;  myHeight = s.h;
 
   // The debugger dialog is resizable, within certain bounds
   // We check those bounds now
-  myWidth  = std::max(myWidth,  uInt32(DebuggerDialog::kSmallFontMinW));
-  myHeight = std::max(myHeight, uInt32(DebuggerDialog::kSmallFontMinH));
-  myWidth  = std::min(myWidth,  uInt32(d.w));
-  myHeight = std::min(myHeight, uInt32(d.h));
+  mySize.clamp(uInt32(DebuggerDialog::kSmallFontMinW), d.w,
+               uInt32(DebuggerDialog::kSmallFontMinH), d.h);
 
-  myOSystem.settings().setValue("dbg.res", Common::Size(myWidth, myHeight));
+  myOSystem.settings().setValue("dbg.res", mySize);
 
   delete myDialog;  myDialog = nullptr;
-  myDialog = new DebuggerDialog(myOSystem, *this, 0, 0, myWidth, myHeight);
+  myDialog = new DebuggerDialog(myOSystem, *this, 0, 0, mySize.w, mySize.h);
 
   myCartDebug->setDebugWidget(&(myDialog->cartDebug()));
 
@@ -115,12 +112,14 @@ void Debugger::initialize()
 FBInitStatus Debugger::initializeVideo()
 {
   string title = string("Stella ") + STELLA_VERSION + ": Debugger mode";
-  return myOSystem.frameBuffer().createDisplay(title, FrameBuffer::BufferType::Debugger,
-                                               myWidth, myHeight);
+  return myOSystem.frameBuffer().createDisplay(
+      title, BufferType::Debugger, mySize
+  );
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-bool Debugger::start(const string& message, int address, bool read)
+bool Debugger::start(const string& message, int address, bool read,
+                     const string& toolTip)
 {
   if(myOSystem.eventHandler().enterDebugMode())
   {
@@ -131,6 +130,7 @@ bool Debugger::start(const string& message, int address, bool read)
     if(address > -1)
       buf << cartDebug().getLabel(address, read, 4);
     myDialog->message().setText(buf.str());
+    myDialog->message().setToolTip(toolTip);
     return true;
   }
   return false;
@@ -877,23 +877,28 @@ std::array<Debugger::BuiltinFunction, 18> Debugger::ourBuiltinFunctions = { {
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 // Names are defined here, but processed in YaccParser
-std::array<Debugger::PseudoRegister, 12> Debugger::ourPseudoRegisters = { {
+std::array<Debugger::PseudoRegister, 16> Debugger::ourPseudoRegisters = { {
 // Debugger::PseudoRegister Debugger::ourPseudoRegisters[NUM_PSEUDO_REGS] = {
-  { "_bank",      "Currently selected bank" },
-  { "_cclocks",   "Color clocks on current scanline" },
-  { "_cycleshi",  "Higher 32 bits of number of cycles since emulation started" },
-  { "_cycleslo",  "Lower 32 bits of number of cycles since emulation started" },
-  { "_fcount",    "Number of frames since emulation started" },
-  { "_fcycles",   "Number of cycles since frame started" },
-  { "_icycles",   "Number of cycles of last instruction" },
-  { "_scan",      "Current scanline count" },
-  { "_scanend",   "Scanline count at end of last frame" },
-  { "_scycles",   "Number of cycles in current scanline" },
-  { "_vblank",    "Whether vertical blank is enabled (1 or 0)" },
-  { "_vsync",     "Whether vertical sync is enabled (1 or 0)" }
+  { "_bank",          "Currently selected bank" },
+  { "_cclocks",       "Color clocks on current scanline" },
+  { "_cycleshi",      "Higher 32 bits of number of cycles since emulation started" },
+  { "_cycleslo",      "Lower 32 bits of number of cycles since emulation started" },
+  { "_fcount",        "Number of frames since emulation started" },
+  { "_fcycles",       "Number of cycles since frame started" },
+  { "_ftimreadcycles","Number of cycles used by timer reads since frame started" },
+  { "_fwsynccycles",  "Number of cycles skipped by WSYNC since frame started" },
+  { "_icycles",       "Number of cycles of last instruction" },
+  { "_scan",          "Current scanline count" },
+  { "_scanend",       "Scanline count at end of last frame" },
+  { "_scycles",       "Number of cycles in current scanline" },
+  { "_timwrapread",   "Timer read wrapped on this cycle" },
+  { "_timwrapwrite",  "Timer write wrapped on this cycle" },
+  { "_vblank",        "Whether vertical blank is enabled (1 or 0)" },
+  { "_vsync",         "Whether vertical sync is enabled (1 or 0)" }
   // CPU address access functions:
   /*{ "_lastread", "last CPU read address" },
   { "_lastwrite", "last CPU write address" },
   { "__lastbaseread", "last CPU read base address" },
   { "__lastbasewrite", "last CPU write base address" }*/
 } };
+//
diff --git a/src/debugger/Debugger.hxx b/src/debugger/Debugger.hxx
index 6435a6d1a..6a53238bb 100644
--- a/src/debugger/Debugger.hxx
+++ b/src/debugger/Debugger.hxx
@@ -44,6 +44,7 @@ class RewindManager;
 #include <map>
 
 #include "Base.hxx"
+#include "Rect.hxx"
 #include "DialogContainer.hxx"
 #include "DebuggerDialog.hxx"
 #include "FrameBufferConstants.hxx"
@@ -96,7 +97,8 @@ class Debugger : public DialogContainer
       @param message  Message to display when entering debugger
       @param address  An address associated with the message
     */
-    bool start(const string& message = "", int address = -1, bool read = true);
+    bool start(const string& message = "", int address = -1, bool read = true,
+               const string& toolTip = "");
     bool startWithFatalError(const string& message = "");
 
     /**
@@ -352,8 +354,8 @@ class Debugger : public DialogContainer
     FunctionDefMap myFunctionDefs;
 
     // Dimensions of the entire debugger window
-    uInt32 myWidth{DebuggerDialog::kSmallFontMinW};
-    uInt32 myHeight{DebuggerDialog::kSmallFontMinH};
+    Common::Size mySize{DebuggerDialog::kSmallFontMinW,
+                        DebuggerDialog::kSmallFontMinH};
 
     // Various builtin functions and operations
     struct BuiltinFunction {
@@ -363,7 +365,7 @@ class Debugger : public DialogContainer
       string name, help;
     };
     static std::array<BuiltinFunction, 18> ourBuiltinFunctions;
-    static std::array<PseudoRegister, 12> ourPseudoRegisters;
+    static std::array<PseudoRegister, 16> ourPseudoRegisters;
 
   private:
     // rewind/unwind n states
diff --git a/src/debugger/DebuggerExpressions.hxx b/src/debugger/DebuggerExpressions.hxx
index 6c422fc5a..060411c09 100644
--- a/src/debugger/DebuggerExpressions.hxx
+++ b/src/debugger/DebuggerExpressions.hxx
@@ -23,6 +23,7 @@
 #include "bspf.hxx"
 #include "CartDebug.hxx"
 #include "CpuDebug.hxx"
+#include "RiotDebug.hxx"
 #include "TIADebug.hxx"
 #include "Debugger.hxx"
 #include "Expression.hxx"
@@ -310,6 +311,18 @@ class ShiftRightExpression : public Expression
       { return myLHS->evaluate() >> myRHS->evaluate(); }
 };
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+class RiotMethodExpression : public Expression
+{
+  public:
+    RiotMethodExpression(RiotMethod method) : Expression(), myMethod(std::mem_fn(method)) { }
+    Int32 evaluate() const override
+      { return myMethod(Debugger::debugger().riotDebug()); }
+
+  private:
+    std::function<int(const RiotDebug&)> myMethod;
+};
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 class TiaMethodExpression : public Expression
 {
diff --git a/src/debugger/DebuggerParser.cxx b/src/debugger/DebuggerParser.cxx
index 97c302392..014188673 100644
--- a/src/debugger/DebuggerParser.cxx
+++ b/src/debugger/DebuggerParser.cxx
@@ -1748,9 +1748,13 @@ void DebuggerParser::executeRunTo()
   // Create a progress dialog box to show the progress searching through the
   // disassembly, since this may be a time-consuming operation
   ostringstream buf;
-  buf << "RunTo searching through " << max_iterations << " disassembled instructions";
-  ProgressDialog progress(debugger.baseDialog(), debugger.lfont(), buf.str());
+  ProgressDialog progress(debugger.baseDialog(), debugger.lfont());
+
+  buf << "RunTo searching through " << max_iterations << " disassembled instructions"
+    << progress.ELLIPSIS;
+  progress.setMessage(buf.str());
   progress.setRange(0, max_iterations, 5);
+  progress.open();
 
   bool done = false;
   do {
@@ -1764,8 +1768,8 @@ void DebuggerParser::executeRunTo()
       done = (BSPF::findIgnoreCase(next, argStrings[0]) != string::npos);
     }
     // Update the progress bar
-    progress.setProgress(count);
-  } while(!done && ++count < max_iterations);
+    progress.incProgress();
+  } while(!done && ++count < max_iterations && !progress.isCancelled());
 
   progress.close();
 
@@ -1790,13 +1794,15 @@ void DebuggerParser::executeRunToPc()
 
   uInt32 count = 0;
   bool done = false;
-  constexpr uInt32 max_iterations = 1000000;
   // Create a progress dialog box to show the progress searching through the
   // disassembly, since this may be a time-consuming operation
   ostringstream buf;
-  buf << "RunTo PC searching through " << max_iterations << " instructions";
-  ProgressDialog progress(debugger.baseDialog(), debugger.lfont(), buf.str());
-  progress.setRange(0, max_iterations, 5);
+  ProgressDialog progress(debugger.baseDialog(), debugger.lfont());
+
+  buf << "        RunTo PC running" << progress.ELLIPSIS << "        ";
+  progress.setMessage(buf.str());
+  progress.setRange(0, 100000, 5);
+  progress.open();
 
   do {
     debugger.step(false);
@@ -1804,8 +1810,9 @@ void DebuggerParser::executeRunToPc()
     // Update romlist to point to current PC
     int pcline = cartdbg.addressToLine(debugger.cpuDebug().pc());
     done = (pcline >= 0) && (list[pcline].address == args[0]);
-    progress.setProgress(count);
-  } while(!done && ++count < max_iterations/*list.size()*/);
+    progress.incProgress();
+    ++count;
+  } while(!done && !progress.isCancelled());
   progress.close();
 
   if(done)
@@ -1960,20 +1967,24 @@ void DebuggerParser::executeStepwhile()
   Expression* expr = YaccParser::getResult();
   int ncycles = 0;
   uInt32 count = 0;
-  constexpr uInt32 max_iterations = 1000000;
 
   // Create a progress dialog box to show the progress searching through the
   // disassembly, since this may be a time-consuming operation
   ostringstream buf;
-  buf << "stepwhile running through " << max_iterations << " disassembled instructions";
-  ProgressDialog progress(debugger.baseDialog(), debugger.lfont(), buf.str());
-  progress.setRange(0, max_iterations, 5);
+  ProgressDialog progress(debugger.baseDialog(), debugger.lfont());
+
+  buf << "stepwhile running through disassembled instructions"
+    << progress.ELLIPSIS;
+  progress.setMessage(buf.str());
+  progress.setRange(0, 100000, 5);
+  progress.open();
 
   do {
     ncycles += debugger.step(false);
 
-    progress.setProgress(count);
-  } while (expr->evaluate() && ++count < max_iterations);
+    progress.incProgress();
+    ++count;
+  } while (expr->evaluate() && !progress.isCancelled());
 
   progress.close();
   commandResult << "executed " << ncycles << " cycles";
diff --git a/src/debugger/RiotDebug.cxx b/src/debugger/RiotDebug.cxx
index 0a71c6d92..34a21b8cf 100644
--- a/src/debugger/RiotDebug.cxx
+++ b/src/debugger/RiotDebug.cxx
@@ -68,6 +68,8 @@ const DebuggerState& RiotDebug::getState()
   myState.INTIMCLKS = intimClocks();
   myState.TIMDIV    = timDivider();
 
+  myState.timReadCycles = timReadCycles();
+
   return myState;
 }
 
@@ -75,10 +77,11 @@ const DebuggerState& RiotDebug::getState()
 void RiotDebug::saveOldState()
 {
   // Port A & B registers
-  myOldState.SWCHA_R = swcha();
+  // read from myState where other widgets can update pins directly
+  myOldState.SWCHA_R = myState.SWCHA_R; // swcha();
   myOldState.SWCHA_W = mySystem.m6532().myOutA;
   myOldState.SWACNT  = swacnt();
-  myOldState.SWCHB_R = swchb();
+  myOldState.SWCHB_R = myState.SWCHB_R; // swchb();
   myOldState.SWCHB_W = mySystem.m6532().myOutB;
   myOldState.SWBCNT  = swbcnt();
   Debugger::set_bits(myOldState.SWCHA_R, myOldState.swchaReadBits);
@@ -93,8 +96,9 @@ void RiotDebug::saveOldState()
   myOldState.INPT1 = inpt(1);
   myOldState.INPT2 = inpt(2);
   myOldState.INPT3 = inpt(3);
-  myOldState.INPT4 = inpt(4);
-  myOldState.INPT5 = inpt(5);
+  // read from myState where other widgets can update pins directly
+  myOldState.INPT4 = myState.INPT4; // inpt(4);
+  myOldState.INPT5 = myState.INPT5; // inpt(5);
 
   myOldState.INPTLatch = vblank(6);
   myOldState.INPTDump = vblank(7);
@@ -109,6 +113,8 @@ void RiotDebug::saveOldState()
   myOldState.TIMCLKS   = timClocks();
   myOldState.INTIMCLKS = intimClocks();
   myOldState.TIMDIV    = timDivider();
+
+  myOldState.timReadCycles = timReadCycles();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -233,6 +239,24 @@ Int32 RiotDebug::timDivider() const
   return mySystem.m6532().myDivider;
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+int RiotDebug::timWrappedOnRead() const
+{
+  return mySystem.m6532().myTimWrappedOnRead;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+int RiotDebug::timWrappedOnWrite() const
+{
+  return mySystem.m6532().myTimWrappedOnWrite;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+int RiotDebug::timReadCycles() const
+{
+  return mySystem.m6532().myTimReadCycles;
+}
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 bool RiotDebug::diffP0(int newVal)
 {
diff --git a/src/debugger/RiotDebug.hxx b/src/debugger/RiotDebug.hxx
index b86968684..999b3da3e 100644
--- a/src/debugger/RiotDebug.hxx
+++ b/src/debugger/RiotDebug.hxx
@@ -22,6 +22,10 @@ class M6532;
 class Debugger;
 class RiotDebug;
 
+// Function type for RiotDebug instance methods
+class RiotDebug;
+using RiotMethod = int (RiotDebug::*)() const;
+
 #include "DebuggerSystem.hxx"
 
 class RiotState : public DebuggerState
@@ -37,6 +41,7 @@ class RiotState : public DebuggerState
 
     uInt8 TIM1T{0}, TIM8T{0}, TIM64T{0}, T1024T{0}, INTIM{0}, TIMINT{0};
     Int32 TIMCLKS{0}, INTIMCLKS{0}, TIMDIV{0};
+    uInt16 timReadCycles;
 
     // These are actually from the TIA, but are I/O related
     uInt8 INPT0{0}, INPT1{0}, INPT2{0}, INPT3{0}, INPT4{0}, INPT5{0};
@@ -75,6 +80,11 @@ class RiotDebug : public DebuggerSystem
     Int32 timClocks() const;
     Int32 intimClocks() const;
     Int32 timDivider() const;
+    /* Debugger pseudo-registers for timer accesses */
+    int timWrappedOnRead() const;
+    int timWrappedOnWrite() const;
+
+    int timReadCycles() const;
 
     /* Console switches */
     bool diffP0(int newVal = -1);
diff --git a/src/debugger/TIADebug.cxx b/src/debugger/TIADebug.cxx
index abde49c69..01b870d68 100644
--- a/src/debugger/TIADebug.cxx
+++ b/src/debugger/TIADebug.cxx
@@ -149,6 +149,7 @@ const DebuggerState& TIADebug::getState()
   myState.info.push_back(scanlines());
   myState.info.push_back(scanlinesLastFrame());
   myState.info.push_back(clocksThisLine());
+  myState.info.push_back(frameWsyncCycles());
 
   return myState;
 }
@@ -258,6 +259,7 @@ void TIADebug::saveOldState()
   myOldState.info.push_back(scanlines());
   myOldState.info.push_back(scanlinesLastFrame());
   myOldState.info.push_back(clocksThisLine());
+  myOldState.info.push_back(frameWsyncCycles());
 }
 
 /* the set methods now use mySystem.poke(). This will save us the
@@ -909,6 +911,12 @@ int TIADebug::frameCycles() const
   return myTIA.frameCycles();
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+int TIADebug::frameWsyncCycles() const
+{
+  return myTIA.frameWSyncCycles();
+}
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 int TIADebug::cyclesLo() const
 {
diff --git a/src/debugger/TIADebug.hxx b/src/debugger/TIADebug.hxx
index cf6171d17..0a2e21663 100644
--- a/src/debugger/TIADebug.hxx
+++ b/src/debugger/TIADebug.hxx
@@ -169,6 +169,7 @@ class TIADebug : public DebuggerSystem
     int scanlinesLastFrame() const;
     int frameCount() const;
     int frameCycles() const;
+    int frameWsyncCycles() const;
     int cyclesLo() const;
     int cyclesHi() const;
     int clocksThisLine() const;
diff --git a/src/debugger/gui/AtariVoxWidget.cxx b/src/debugger/gui/AtariVoxWidget.cxx
index 0a38d2ec5..3d3dfe762 100644
--- a/src/debugger/gui/AtariVoxWidget.cxx
+++ b/src/debugger/gui/AtariVoxWidget.cxx
@@ -20,10 +20,11 @@
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 AtariVoxWidget::AtariVoxWidget(GuiObject* boss, const GUI::Font& font,
-                               int x, int y, Controller& controller)
+                               int x, int y, Controller& controller,
+                               bool embedded)
   : FlashWidget(boss, font, x, y, controller)
 {
-  init(boss, font, x, y);
+  init(boss, font, x, y, embedded);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/debugger/gui/AtariVoxWidget.hxx b/src/debugger/gui/AtariVoxWidget.hxx
index cf168173d..ea0345762 100644
--- a/src/debugger/gui/AtariVoxWidget.hxx
+++ b/src/debugger/gui/AtariVoxWidget.hxx
@@ -26,7 +26,7 @@ class AtariVoxWidget : public FlashWidget
 {
   public:
     AtariVoxWidget(GuiObject* boss, const GUI::Font& font, int x, int y,
-                   Controller& controller);
+                   Controller& controller, bool embedded = false);
     ~AtariVoxWidget() override = default;
 
   private:
diff --git a/src/debugger/gui/BoosterWidget.cxx b/src/debugger/gui/BoosterWidget.cxx
index 1820919bb..b1056c069 100644
--- a/src/debugger/gui/BoosterWidget.cxx
+++ b/src/debugger/gui/BoosterWidget.cxx
@@ -73,6 +73,14 @@ BoosterWidget::BoosterWidget(GuiObject* boss, const GUI::Font& font,
                                          CheckboxWidget::kCheckActionCmd);
   myPins[kJTrigger]->setID(kJTrigger);
   myPins[kJTrigger]->setTarget(this);
+
+  addFocusWidget(myPins[kJUp]);
+  addFocusWidget(myPins[kJLeft]);
+  addFocusWidget(myPins[kJRight]);
+  addFocusWidget(myPins[kJDown]);
+  addFocusWidget(myPins[kJFire]);
+  addFocusWidget(myPins[kJBooster]);
+  addFocusWidget(myPins[kJTrigger]);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/debugger/gui/Cart3EWidget.cxx b/src/debugger/gui/Cart3EWidget.cxx
index 910f03368..9e0822b51 100644
--- a/src/debugger/gui/Cart3EWidget.cxx
+++ b/src/debugger/gui/Cart3EWidget.cxx
@@ -117,7 +117,7 @@ void Cartridge3EWidget::loadConfig()
     myBankWidgets[1]->setSelectedIndex(bank - myCart.romBankCount(), oldBank != bank);
   }
 
-  CartDebugWidget::loadConfig();
+  CartDebugWidget::loadConfig();  // Intentionally calling grand-parent method
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/debugger/gui/CartCDFInfoWidget.cxx b/src/debugger/gui/CartCDFInfoWidget.cxx
index b56c61ca1..a1db55cdf 100644
--- a/src/debugger/gui/CartCDFInfoWidget.cxx
+++ b/src/debugger/gui/CartCDFInfoWidget.cxx
@@ -23,16 +23,16 @@ CartridgeCDFInfoWidget::CartridgeCDFInfoWidget(
     int x, int y, int w, int h, CartridgeCDF& cart)
   : CartDebugWidget(boss, lfont, nfont, x, y, w, h)
 {
-  uInt16 size = 8 * 4096;
-
   ostringstream info;
-  info << describeCDFVersion(cart.myCDFSubtype) << " cartridge\n"
-  << "32K ROM, seven 4K banks are accessible to 2600\n"
-  << "8K CDF RAM\n"
-  << "CDF registers accessible @ $FFF0 - $FFF3\n"
-  << "Banks accessible at hotspots $FFF5 to $FFFB\n"
-  << "Startup bank = " << cart.startBank() << "\n";
 
+  info << describeCDFVersion(cart.myCDFSubtype) << " cartridge\n"
+    << (cart.romSize() / 1024) << "K ROM\n"
+    << (cart.ramSize() / 1024) << "K RAM\n"
+    << "Seven 4K banks are available to 2600\n"
+    << "Functions accessible @ $FFF0 - $FFF3\n"
+    << (cart.isCDFJplus() ? "Banks accessible @ $FFF4 to $FFFA\n" : "Banks accessible @ $FFF5 to $FFFB\n")
+    << "Startup bank = " << cart.startBank() << "\n";
+ 
 #if 0
   // Eventually, we should query this from the debugger/disassembler
   for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF5; i < 7; ++i, offset += 0x1000)
@@ -44,7 +44,7 @@ CartridgeCDFInfoWidget::CartridgeCDFInfoWidget(
   }
 #endif
 
-  addBaseInformation(size, "AtariAge", info.str());
+  addBaseInformation(cart.romSize(), "AtariAge", info.str());
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -61,6 +61,9 @@ string CartridgeCDFInfoWidget::describeCDFVersion(CartridgeCDF::CDFSubtype subty
     case CartridgeCDF::CDFSubtype::CDFJ:
       return "CDFJ";
 
+    case CartridgeCDF::CDFSubtype::CDFJplus:
+      return "CDFJ+";
+
     default:
       throw runtime_error("unreachable");
   }
diff --git a/src/debugger/gui/CartCDFWidget.cxx b/src/debugger/gui/CartCDFWidget.cxx
index 8c4fdf2fc..8b43d0fc8 100644
--- a/src/debugger/gui/CartCDFWidget.cxx
+++ b/src/debugger/gui/CartCDFWidget.cxx
@@ -34,13 +34,23 @@ CartridgeCDFWidget::CartridgeCDFWidget(
   int xpos = HBORDER, ypos = VBORDER;
 
   VariantList items;
-  VarList::push_back(items, "0 ($FFF5)");
-  VarList::push_back(items, "1 ($FFF6)");
-  VarList::push_back(items, "2 ($FFF7)");
-  VarList::push_back(items, "3 ($FFF8)");
-  VarList::push_back(items, "4 ($FFF9)");
-  VarList::push_back(items, "5 ($FFFA)");
-  VarList::push_back(items, "6 ($FFFB)");
+  if (isCDFJplus()) {
+    VarList::push_back(items, "0 ($FFF4)");
+    VarList::push_back(items, "1 ($FFF5)");
+    VarList::push_back(items, "2 ($FFF6)");
+    VarList::push_back(items, "3 ($FFF7)");
+    VarList::push_back(items, "4 ($FFF8)");
+    VarList::push_back(items, "5 ($FFF9)");
+    VarList::push_back(items, "6 ($FFFA)");
+  } else {
+    VarList::push_back(items, "0 ($FFF5)");
+    VarList::push_back(items, "1 ($FFF6)");
+    VarList::push_back(items, "2 ($FFF7)");
+    VarList::push_back(items, "3 ($FFF8)");
+    VarList::push_back(items, "4 ($FFF9)");
+    VarList::push_back(items, "5 ($FFFA)");
+    VarList::push_back(items, "6 ($FFFB)");
+  }
   myBank = new PopUpWidget(boss, _font, xpos, ypos, _font.getStringWidth("0 ($FFFx)"),
                            myLineHeight, items,
                            "Set bank ", 0, kBankChanged);
@@ -73,7 +83,7 @@ CartridgeCDFWidget::CartridgeCDFWidget(
   myCommandStreamPointer->setTarget(this);
   myCommandStreamPointer->setEditable(false);
 
-  if (isCDFJ())
+  if (isCDFJ() || isCDFJplus())
     myJumpStreamPointers = new DataGridWidget(boss, _nfont, DS_X  + myDatastreamPointers->getWidth() * 2 / 4,
                                               ypos+myLineHeight + 9*myLineHeight, 2, 1, 6, 32,
                                               Common::Base::Fmt::_16_3_2);
@@ -102,7 +112,7 @@ CartridgeCDFWidget::CartridgeCDFWidget(
   new StaticTextWidget(_boss, _font, DS_X - _font.getStringWidth("xx "),
                        ypos+myLineHeight + 9*myLineHeight + 2,
                        lwidth, myFontHeight,
-                       isCDFJ() ? "Jump Data (21|22)" : "Jump Data (21)");
+                       (isCDFJ() || isCDFJplus()) ? "Jump Data (21|22)" : "Jump Data (21)");
 
   // Datastream Increments
   xpos = DS_X + myDatastreamPointers->getWidth() + 16;
@@ -121,7 +131,7 @@ CartridgeCDFWidget::CartridgeCDFWidget(
   myCommandStreamIncrement->setEditable(false);
 
   myJumpStreamIncrements = new DataGridWidget(boss, _nfont, xpos,
-                                              ypos+myLineHeight + 9*myLineHeight, isCDFJ() ? 2 : 1, 1, 5, 32,
+                                              ypos+myLineHeight + 9*myLineHeight, (isCDFJ() || isCDFJplus()) ? 2 : 1, 1, 5, 32,
                                               Common::Base::Fmt::_16_2_2);
   myJumpStreamIncrements->setTarget(this);
   myJumpStreamIncrements->setEditable(false);
@@ -205,7 +215,7 @@ void CartridgeCDFWidget::saveOldState()
   myOldState.internalram.clear();
   myOldState.samplepointer.clear();
 
-  for(uInt32 i = 0; i < static_cast<uInt32>(isCDFJ() ? 35 : 34); ++i)
+  for(uInt32 i = 0; i < static_cast<uInt32>((isCDFJ() || isCDFJplus()) ? 35 : 34); ++i)
   {
     // Pointers are stored as:
     // PPPFF---
@@ -281,7 +291,7 @@ void CartridgeCDFWidget::loadConfig()
   myCommandStreamPointer->setList(alist, vlist, changed);
 
   alist.clear();  vlist.clear();  changed.clear();
-  for(int i = 0; i < (isCDFJ() ? 2 : 1); ++i)
+  for(int i = 0; i < ((isCDFJ() || isCDFJplus()) ? 2 : 1); ++i)
   {
     Int32 pointervalue = myCart.getDatastreamPointer(0x21 + i) >> 12;
     alist.push_back(0);  vlist.push_back(pointervalue);
@@ -305,7 +315,7 @@ void CartridgeCDFWidget::loadConfig()
   myCommandStreamIncrement->setList(alist, vlist, changed);
 
   alist.clear();  vlist.clear();  changed.clear();
-  for(int i = 0; i < (isCDFJ() ? 2 : 1); ++i)
+  for(int i = 0; i < ((isCDFJ() || isCDFJplus()) ? 2 : 1); ++i)
   {
     Int32 pointervalue = myCart.getDatastreamIncrement(0x21 + i) >> 12;
     alist.push_back(0);  vlist.push_back(pointervalue);
@@ -387,11 +397,12 @@ string CartridgeCDFWidget::bankState()
 {
   ostringstream& buf = buffer();
 
-  static constexpr std::array<const char*, 7> spot = {
-    "$FFF5", "$FFF6", "$FFF7", "$FFF8", "$FFF9", "$FFFA", "$FFFB"
+  static constexpr std::array<const char*, 8> spot = {
+    "$FFF4", "$FFF5", "$FFF6", "$FFF7", "$FFF8", "$FFF9", "$FFFA", "$FFFB"
   };
+
   buf << "Bank = " << std::dec << myCart.getBank()
-  << ", hotspot = " << spot[myCart.getBank()];
+  << ", hotspot = " << spot[myCart.getBank() + (isCDFJplus() ? 0 : 1)];
 
   return buf.str();
 }
@@ -399,7 +410,7 @@ string CartridgeCDFWidget::bankState()
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 uInt32 CartridgeCDFWidget::internalRamSize()
 {
-  return 8*1024;
+  return myCart.ramSize();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -412,13 +423,21 @@ uInt32 CartridgeCDFWidget::internalRamRPort(int start)
 string CartridgeCDFWidget::internalRamDescription()
 {
   ostringstream desc;
-  desc << "$0000 - $07FF - CDF driver\n"
-  << "                not accessible to 6507\n"
-  << "$0800 - $17FF - 4K Data Stream storage\n"
-  << "                indirectly accessible to 6507\n"
-  << "                via CDF's Data Stream registers\n"
-  << "$1800 - $1FFF - 2K C variable storage and stack\n"
-  << "                not accessible to 6507";
+  if (isCDFJplus()) {
+    desc << "$0000 - $07FF - CDFJ+ driver\n"
+    << "                not accessible to 6507\n"
+    << "$0800 - $7FFF - 30K Data Stream storage\n"
+    << "                indirectly accessible to 6507\n"
+    << "                via fast fecthers\n";
+  } else {
+    desc << "$0000 - $07FF - CDF/CDFJ driver\n"
+    << "                not accessible to 6507\n"
+    << "$0800 - $17FF - 4K Data Stream storage\n"
+    << "                indirectly accessible to 6507\n"
+    << "                via fast fetchers\n"
+    << "$1800 - $1FFF - 2K C variable storage and stack\n"
+    << "                not accessible to 6507";
+  }
 
   return desc.str();
 }
@@ -467,6 +486,9 @@ string CartridgeCDFWidget::describeCDFVersion(CartridgeCDF::CDFSubtype subtype)
     case CartridgeCDF::CDFSubtype::CDFJ:
       return "CDFJ";
 
+    case CartridgeCDF::CDFSubtype::CDFJplus:
+      return "CDFJ+";
+
     default:
       throw runtime_error("unreachable");
   }
@@ -477,3 +499,9 @@ bool CartridgeCDFWidget::isCDFJ() const
 {
   return myCart.myCDFSubtype == CartridgeCDF::CDFSubtype::CDFJ;
 }
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool CartridgeCDFWidget::isCDFJplus() const
+{
+  return myCart.isCDFJplus();
+}
diff --git a/src/debugger/gui/CartCDFWidget.hxx b/src/debugger/gui/CartCDFWidget.hxx
index fdf5622a9..431553db6 100644
--- a/src/debugger/gui/CartCDFWidget.hxx
+++ b/src/debugger/gui/CartCDFWidget.hxx
@@ -75,6 +75,7 @@ class CartridgeCDFWidget : public CartDebugWidget
 
   private:
     bool isCDFJ() const;
+    bool isCDFJplus() const;
 
     static string describeCDFVersion(CartridgeCDF::CDFSubtype subtype);
 
diff --git a/src/debugger/gui/CartDebugWidget.cxx b/src/debugger/gui/CartDebugWidget.cxx
index b04000328..778a70c50 100644
--- a/src/debugger/gui/CartDebugWidget.cxx
+++ b/src/debugger/gui/CartDebugWidget.cxx
@@ -69,11 +69,16 @@ int CartDebugWidget::addBaseInformation(size_t bytes, const string& manufacturer
   const StringList& sl = bs.stringList();
   uInt32 lines = uInt32(sl.size());
   if(lines < 3) lines = 3;
-  if(lines > maxlines) lines = maxlines;
+  bool useScrollbar = false;
+  if(lines > maxlines)
+  {
+    lines = maxlines;
+    useScrollbar = true;
+  }
 
   new StaticTextWidget(_boss, _font, x, y + 1, "Description ");
   myDesc = new StringListWidget(_boss, _nfont, x+lwidth, y - 1,
-                                fwidth, lines * myLineHeight, false);
+                                fwidth, lines * myLineHeight, false, useScrollbar);
   myDesc->setEditable(false);
   myDesc->setEnabled(false);
   myDesc->setList(sl);
diff --git a/src/debugger/gui/CartEnhancedWidget.cxx b/src/debugger/gui/CartEnhancedWidget.cxx
index 97beb1f6b..80da02ffd 100644
--- a/src/debugger/gui/CartEnhancedWidget.cxx
+++ b/src/debugger/gui/CartEnhancedWidget.cxx
@@ -392,5 +392,5 @@ uInt8 CartridgeEnhancedWidget::internalRamGetValue(int addr)
 string CartridgeEnhancedWidget::internalRamLabel(int addr)
 {
   CartDebug& dbg = instance().debugger().cartDebug();
-  return dbg.getLabel(addr + ADDR_BASE + myCart.myReadOffset, false);
+  return dbg.getLabel(addr + ADDR_BASE + myCart.myReadOffset, false, -1, true);
 }
diff --git a/src/debugger/gui/CartMNetworkWidget.cxx b/src/debugger/gui/CartMNetworkWidget.cxx
index e9cc68869..e56a1ecb7 100644
--- a/src/debugger/gui/CartMNetworkWidget.cxx
+++ b/src/debugger/gui/CartMNetworkWidget.cxx
@@ -26,14 +26,13 @@ CartridgeMNetworkWidget::CartridgeMNetworkWidget(
     int x, int y, int w, int h,
     CartridgeMNetwork& cart)
   : CartDebugWidget(boss, lfont, nfont, x, y, w, h),
-    myCart(cart),
-    myLower2K(nullptr),
-    myUpper256B(nullptr)
+    myCart(cart)
 {
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void CartridgeMNetworkWidget::initialize(GuiObject* boss, CartridgeMNetwork& cart, ostringstream& info)
+void CartridgeMNetworkWidget::initialize(GuiObject* boss,
+    CartridgeMNetwork& cart, ostringstream& info)
 {
   uInt32 size = cart.romBankCount() * cart.BANK_SIZE;
 
diff --git a/src/debugger/gui/CartRamWidget.cxx b/src/debugger/gui/CartRamWidget.cxx
index 76c8e972a..0ab421df3 100644
--- a/src/debugger/gui/CartRamWidget.cxx
+++ b/src/debugger/gui/CartRamWidget.cxx
@@ -65,12 +65,18 @@ CartRamWidget::CartRamWidget(
   StringParser bs(desc, (fwidth - ScrollBarWidget::scrollBarWidth(_font)) / myFontWidth);
   const StringList& sl = bs.stringList();
   uInt32 lines = uInt32(sl.size());
+  bool useScrollbar = false;
+
   if(lines < 2) lines = 2;
-  if(lines > maxlines) lines = maxlines;
+  if(lines > maxlines)
+  {
+    lines = maxlines;
+    useScrollbar = true;
+  }
 
   new StaticTextWidget(_boss, _font, xpos, ypos + 1, "Description ");
   myDesc = new StringListWidget(boss, nfont, xpos+lwidth, ypos - 1,
-                                fwidth, lines * myLineHeight, false);
+                                fwidth, lines * myLineHeight, false, useScrollbar);
   myDesc->setEditable(false);
   myDesc->setEnabled(false);
   myDesc->setList(sl);
diff --git a/src/debugger/gui/CartRamWidget.hxx b/src/debugger/gui/CartRamWidget.hxx
index bc0f4f810..d24a5d134 100644
--- a/src/debugger/gui/CartRamWidget.hxx
+++ b/src/debugger/gui/CartRamWidget.hxx
@@ -67,11 +67,11 @@ class CartRamWidget : public Widget, public CommandSender
                           int x, int y, int w, int h,
                           CartDebugWidget& cartDebug);
         ~InternalRamWidget() override = default;
+        string getLabel(int addr) const override;
 
       private:
         uInt8 getValue(int addr) const override;
         void setValue(int addr, uInt8 value) override;
-        string getLabel(int addr) const override;
 
         void fillList(uInt32 start, uInt32 size, IntArray& alist,
                       IntArray& vlist, BoolArray& changed) const override;
diff --git a/src/debugger/gui/CartUAWidget.cxx b/src/debugger/gui/CartUAWidget.cxx
index f6ae16bc7..02728b52d 100644
--- a/src/debugger/gui/CartUAWidget.cxx
+++ b/src/debugger/gui/CartUAWidget.cxx
@@ -47,7 +47,7 @@ string CartridgeUAWidget::hotspotStr(int bank, int, bool prefix)
   uInt16 hotspot = myCart.hotspot() + (bank ^ (mySwappedHotspots ? 1 : 0)) * myHotspotDelta;
 
   info << "(" << (prefix ? "hotspot " : "");
-  info << "$" << Common::Base::HEX1 << hotspot << ", $" << (hotspot | 0x80);
+  info << "$" << Common::Base::HEX1 << hotspot << ", $" << (hotspot | 0x80) << ", $" << (hotspot | 0xf80);
   info << ")";
 
   return info.str();
diff --git a/src/debugger/gui/CpuWidget.cxx b/src/debugger/gui/CpuWidget.cxx
index babdb8e08..1069e8001 100644
--- a/src/debugger/gui/CpuWidget.cxx
+++ b/src/debugger/gui/CpuWidget.cxx
@@ -39,11 +39,12 @@ CpuWidget::CpuWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n
   const int fontWidth  = lfont.getMaxCharWidth(),
             fontHeight = lfont.getFontHeight(),
             lineHeight = lfont.getLineHeight();
+  const int VGAP = 2;
   int xpos, ypos, lwidth;
 
   // Create a 1x1 grid with label for the PC register
   xpos = x;  ypos = y;  lwidth = 4 * fontWidth;
-  new StaticTextWidget(boss, lfont, xpos, ypos+1, lwidth-2, fontHeight,
+  new StaticTextWidget(boss, lfont, xpos, ypos + 2, lwidth-2, fontHeight,
                        "PC ", TextAlign::Left);
   myPCGrid =
     new DataGridWidget(boss, nfont, xpos + lwidth, ypos, 1, 1, 4, 16, Common::Base::Fmt::_16);
@@ -58,7 +59,7 @@ CpuWidget::CpuWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n
   myPCLabel->setEditable(false, true);
 
   // Create a 1x4 grid with labels for the other CPU registers
-  xpos = x + lwidth;  ypos += myPCGrid->getHeight() + 1;
+  xpos = x + lwidth;  ypos = myPCGrid->getBottom() + VGAP;
   myCpuGrid =
     new DataGridWidget(boss, nfont, xpos, ypos, 1, 4, 2, 8, Common::Base::Fmt::_16);
   myCpuGrid->setTarget(this);
@@ -66,14 +67,14 @@ CpuWidget::CpuWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n
   addFocusWidget(myCpuGrid);
 
   // Create a 1x4 grid with decimal and binary values for the other CPU registers
-  xpos = x + lwidth + myPCGrid->getWidth() + 10;
+  xpos = myPCGrid->getRight() + 10;
   myCpuGridDecValue =
     new DataGridWidget(boss, nfont, xpos, ypos, 1, 4, 3, 8, Common::Base::Fmt::_10);
   myCpuGridDecValue->setTarget(this);
   myCpuGridDecValue->setID(kCpuRegDecID);
   addFocusWidget(myCpuGridDecValue);
 
-  xpos += myCpuGridDecValue->getWidth() + 5;
+  xpos = myCpuGridDecValue->getRight() + fontWidth * 2;
   myCpuGridBinValue =
     new DataGridWidget(boss, nfont, xpos, ypos, 1, 4, 8, 8, Common::Base::Fmt::_2);
   myCpuGridBinValue->setTarget(this);
@@ -84,34 +85,40 @@ CpuWidget::CpuWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n
   _w = lwidth + myPCGrid->getWidth() + myPCLabel->getWidth() + 20;
 
   // Create labels showing the source of data for SP/A/X/Y registers
+  const std::array<string, 4> labels = { "SP", "A", "X", "Y" };
   xpos += myCpuGridBinValue->getWidth() + 20;
   int src_y = ypos, src_w = (max_w - xpos + x) - 10;
   for(int i = 0; i < 4; ++i)
   {
-    myCpuDataSrc[i] = new EditTextWidget(boss, nfont, xpos, src_y, src_w,
-                                 fontHeight+1, "");
+    myCpuDataSrc[i] = new EditTextWidget(boss, nfont, xpos, src_y, src_w, fontHeight + 1);
+    myCpuDataSrc[i]->setToolTip("Source label of last read for " + labels[i] + ".");
     myCpuDataSrc[i]->setEditable(false, true);
-    src_y += fontHeight+2;
+    src_y += fontHeight + 2;
   }
 
-  // Last write destination address
-  new StaticTextWidget(boss, lfont, xpos - fontWidth * 4.5, src_y + 4, "Dest");
-  myCpuDataDest = new EditTextWidget(boss, nfont, xpos, src_y + 2, src_w, fontHeight+1);
-  myCpuDataDest->setEditable(false, true);
-
   // Add labels for other CPU registers
   xpos = x;
-  const std::array<string, 4> labels = { "SP ", "A ", "X ", "Y " };
   for(int row = 0; row < 4; ++row)
   {
-    new StaticTextWidget(boss, lfont, xpos, ypos + row*lineHeight + 1,
+    new StaticTextWidget(boss, lfont, xpos, ypos + row*lineHeight + 2,
                          lwidth-2, fontHeight,
                          labels[row], TextAlign::Left);
   }
 
+  // Add prefixes for decimal and binary values
+  for(int row = 0; row < 4; ++row)
+  {
+    new StaticTextWidget(boss, lfont, myCpuGridDecValue->getLeft() - fontWidth,
+                         ypos + row * lineHeight + 2,
+                         fontWidth, fontHeight, "#");
+    new StaticTextWidget(boss, lfont, myCpuGridBinValue->getLeft() - fontWidth,
+                         ypos + row * lineHeight + 2,
+                         fontWidth, fontHeight, "%");
+  }
+
   // Create a bitfield widget for changing the processor status
-  xpos = x;  ypos += 4*lineHeight + 2;
-  new StaticTextWidget(boss, lfont, xpos, ypos+1, lwidth-2, fontHeight,
+  xpos = x;  ypos = myCpuGrid->getBottom() + VGAP;
+  new StaticTextWidget(boss, lfont, xpos, ypos + 2, lwidth-2, fontHeight,
                        "PS ", TextAlign::Left);
   myPSRegister = new ToggleBitWidget(boss, nfont, xpos+lwidth, ypos, 8, 1);
   myPSRegister->setTarget(this);
@@ -129,6 +136,13 @@ CpuWidget::CpuWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n
   }
   myPSRegister->setList(off, on);
 
+  // Last write destination address
+  xpos = myCpuDataSrc[0]->getLeft();
+  new StaticTextWidget(boss, lfont, xpos - fontWidth * 4.5, ypos + 2, "Dest");
+  myCpuDataDest = new EditTextWidget(boss, nfont, xpos, ypos, src_w, fontHeight + 1);
+  myCpuDataDest->setToolTip("Destination label of last write.");
+  myCpuDataDest->setEditable(false, true);
+
   _h = ypos + myPSRegister->getHeight() - y;
 }
 
diff --git a/src/debugger/gui/DataGridOpsWidget.cxx b/src/debugger/gui/DataGridOpsWidget.cxx
index 102d7a94d..2a62ec60c 100644
--- a/src/debugger/gui/DataGridOpsWidget.cxx
+++ b/src/debugger/gui/DataGridOpsWidget.cxx
@@ -33,31 +33,38 @@ DataGridOpsWidget::DataGridOpsWidget(GuiObject* boss, const GUI::Font& font,
   xpos = x;  ypos = y;
   _zeroButton = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight,
                                  "0", kDGZeroCmd);
-
+  _zeroButton->setToolTip("Zero currently selected value");
+  
   ypos += bheight + space;
   _invButton = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight,
                                 "Inv", kDGInvertCmd);
+  _invButton->setToolTip("Invert currently selected value");
 
   ypos += bheight + space;
   _incButton = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight,
                                 "++", kDGIncCmd);
+  _incButton->setToolTip("Increase currently selected value.");
 
   ypos += bheight + space;
   _shiftLeftButton = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight,
                                       "<<", kDGShiftLCmd);
+  _shiftLeftButton->setToolTip("Shift currently selected value left");
 
   // Move to next column, skip a row
   xpos = x + bwidth + space;  ypos = y + bheight + space;
   _negButton = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight,
                                 "Neg", kDGNegateCmd);
+  _negButton->setToolTip("Negate currently selected value");
 
   ypos += bheight + space;
   _decButton = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight,
                                 "--", kDGDecCmd);
+  _decButton->setToolTip("Decrease currently selected value");
 
   ypos += bheight + space;
   _shiftRightButton = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight,
                                        ">>", kDGShiftRCmd);
+  _shiftRightButton->setToolTip("Shift currently selected value right");
 
   // Calculate real dimensions
   _w = 2 * (bwidth+space);
diff --git a/src/debugger/gui/DataGridRamWidget.cxx b/src/debugger/gui/DataGridRamWidget.cxx
new file mode 100644
index 000000000..7445f1d90
--- /dev/null
+++ b/src/debugger/gui/DataGridRamWidget.cxx
@@ -0,0 +1,54 @@
+//============================================================================
+//
+//   SSSS    tt          lll  lll
+//  SS  SS   tt           ll   ll
+//  SS     tttttt  eeee   ll   ll   aaaa
+//   SSSS    tt   ee  ee  ll   ll      aa
+//      SS   tt   eeeeee  ll   ll   aaaaa  --  "An Atari 2600 VCS Emulator"
+//  SS  SS   tt   ee      ll   ll  aa  aa
+//   SSSS     ttt  eeeee llll llll  aaaaa
+//
+// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
+// and the Stella Team
+//
+// See the file "License.txt" for information on usage and redistribution of
+// this file, and for a DISCLAIMER OF ALL WARRANTIES.
+//============================================================================
+
+#include "RamWidget.hxx"
+#include "DataGridRamWidget.hxx"
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+DataGridRamWidget::DataGridRamWidget(GuiObject* boss, const RamWidget& ram,
+                                     const GUI::Font& font,
+                                     int x, int y, int cols, int rows,
+                                     int colchars, int bits,
+                                     Common::Base::Fmt base,
+                                     bool useScrollbar)
+  : DataGridWidget(boss, font, x, y, cols, rows, colchars,
+                   bits, base, useScrollbar),
+    _ram(ram)
+{
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+string DataGridRamWidget::getToolTip(const Common::Point& pos) const
+{
+  const int idx = getToolTipIndex(pos);
+
+  if(idx < 0)
+    return EmptyString;
+
+  const Int32 addr = _addrList[idx];
+  const string label = _ram.getLabel(addr);
+  const string tip = DataGridWidget::getToolTip(pos);
+
+  if(label.empty())
+    return tip;
+
+  ostringstream buf;
+
+  buf << label << '\n' << tip;
+
+  return buf.str();
+}
diff --git a/src/debugger/gui/DataGridRamWidget.hxx b/src/debugger/gui/DataGridRamWidget.hxx
new file mode 100644
index 000000000..451c23403
--- /dev/null
+++ b/src/debugger/gui/DataGridRamWidget.hxx
@@ -0,0 +1,51 @@
+//============================================================================
+//
+//   SSSS    tt          lll  lll
+//  SS  SS   tt           ll   ll
+//  SS     tttttt  eeee   ll   ll   aaaa
+//   SSSS    tt   ee  ee  ll   ll      aa
+//      SS   tt   eeeeee  ll   ll   aaaaa  --  "An Atari 2600 VCS Emulator"
+//  SS  SS   tt   ee      ll   ll  aa  aa
+//   SSSS     ttt  eeeee llll llll  aaaaa
+//
+// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
+// and the Stella Team
+//
+// See the file "License.txt" for information on usage and redistribution of
+// this file, and for a DISCLAIMER OF ALL WARRANTIES.
+//============================================================================
+
+#ifndef DATA_GRID_RAM_WIDGET_HXX
+#define DATA_GRID_RAM_WIDGET_HXX
+
+class RamWidget;
+
+#include "DataGridWidget.hxx"
+#include "Base.hxx"
+
+class DataGridRamWidget : public DataGridWidget
+{
+  public:
+    DataGridRamWidget(GuiObject* boss, const RamWidget& ram,
+                      const GUI::Font& font,
+                      int x, int y, int cols, int rows,
+                      int colchars, int bits,
+                      Common::Base::Fmt format = Common::Base::Fmt::_DEFAULT,
+                      bool useScrollbar = false);
+    ~DataGridRamWidget() override = default;
+
+    string getToolTip(const Common::Point& pos) const override;
+
+  private:
+    const RamWidget& _ram;
+
+  private:
+    // Following constructors and assignment operators not supported
+    DataGridRamWidget() = delete;
+    DataGridRamWidget(const DataGridRamWidget&) = delete;
+    DataGridRamWidget(DataGridRamWidget&&) = delete;
+    DataGridRamWidget& operator=(const DataGridRamWidget&) = delete;
+    DataGridRamWidget& operator=(DataGridRamWidget&&) = delete;
+};
+
+#endif
diff --git a/src/debugger/gui/DataGridWidget.cxx b/src/debugger/gui/DataGridWidget.cxx
index 719eebef2..9fa82bcdc 100644
--- a/src/debugger/gui/DataGridWidget.cxx
+++ b/src/debugger/gui/DataGridWidget.cxx
@@ -17,6 +17,7 @@
 
 #include "Widget.hxx"
 #include "Dialog.hxx"
+#include "ToolTip.hxx"
 #include "Font.hxx"
 #include "OSystem.hxx"
 #include "Debugger.hxx"
@@ -45,10 +46,7 @@ DataGridWidget::DataGridWidget(GuiObject* boss, const GUI::Font& font,
     _base(base)
 {
   _flags = Widget::FLAG_ENABLED | Widget::FLAG_RETAIN_FOCUS | Widget::FLAG_WANTS_RAWDATA;
-
-  // The item is selected, thus _bgcolor is used to draw the caret and
-  // _textcolorhi to erase it
-  _caretInverse = true;
+  _editMode = false;
 
   // Make sure all lists contain some default values
   _hiliteList.clear();
@@ -109,15 +107,21 @@ DataGridWidget::DataGridWidget(GuiObject* boss, const GUI::Font& font,
 void DataGridWidget::setList(const IntArray& alist, const IntArray& vlist,
                              const BoolArray& changed)
 {
-/*
-cerr << "alist.size() = "     << alist.size()
-     << ", vlist.size() = "   << vlist.size()
-     << ", changed.size() = " << changed.size()
-     << ", _rows*_cols = "    << _rows * _cols << endl << endl;
-*/
+  /*
+  cerr << "alist.size() = "     << alist.size()
+       << ", vlist.size() = "   << vlist.size()
+       << ", changed.size() = " << changed.size()
+       << ", _rows*_cols = "    << _rows * _cols << endl << endl;
+  */
   int size = int(vlist.size());  // assume the alist is the same size
   assert(size == _rows * _cols);
 
+  bool dirty = _editMode
+    || !std::equal(_valueList.begin(), _valueList.end(),
+                   vlist.begin(), vlist.end())
+    || !std::equal(_changedList.begin(), _changedList.end(),
+                   changed.begin(), changed.end());
+
   _addrList.clear();
   _valueList.clear();
   _valueStringList.clear();
@@ -132,19 +136,22 @@ cerr << "alist.size() = "     << alist.size()
   for(int i = 0; i < size; ++i)
     _valueStringList.push_back(Common::Base::toString(_valueList[i], _base));
 
-/*
-cerr << "_addrList.size() = "     << _addrList.size()
-     << ", _valueList.size() = "   << _valueList.size()
-     << ", _changedList.size() = " << _changedList.size()
-     << ", _valueStringList.size() = " << _valueStringList.size()
-     << ", _rows*_cols = "    << _rows * _cols << endl << endl;
-*/
+  /*
+  cerr << "_addrList.size() = "     << _addrList.size()
+       << ", _valueList.size() = "   << _valueList.size()
+       << ", _changedList.size() = " << _changedList.size()
+       << ", _valueStringList.size() = " << _valueStringList.size()
+       << ", _rows*_cols = "    << _rows * _cols << endl << endl;
+  */
   enableEditMode(false);
 
-  // Send item selected signal for starting with cell 0
-  sendCommand(DataGridWidget::kSelectionChangedCmd, _selectedItem, _id);
+  if(dirty)
+  {
+    // Send item selected signal for starting with cell 0
+    sendCommand(DataGridWidget::kSelectionChangedCmd, _selectedItem, _id);
 
-  setDirty();
+    setDirty();
+  }
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -243,26 +250,13 @@ void DataGridWidget::setRange(int lower, int upper)
   _upperBound = std::min(1 << _bits, upper);
 }
 
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void DataGridWidget::handleMouseEntered()
-{
-  setFlags(Widget::FLAG_HILITED);
-  setDirty();
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void DataGridWidget::handleMouseLeft()
-{
-  clearFlags(Widget::FLAG_HILITED);
-  setDirty();
-}
-
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void DataGridWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount)
 {
   if (!isEnabled())
     return;
 
+  resetSelection();
   // First check whether the selection changed
   int newSelectedItem;
   newSelectedItem = findItem(x, y);
@@ -310,6 +304,7 @@ void DataGridWidget::handleMouseWheel(int x, int y, int direction)
     else if(direction < 0)
       incrementCell();
   }
+  dialog().tooltip().hide();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -507,6 +502,7 @@ bool DataGridWidget::handleKeyDown(StellaKey key, StellaMod mod)
       sendCommand(DataGridWidget::kSelectionChangedCmd, _selectedItem, _id);
 
     setDirty();
+    dialog().tooltip().hide();
   }
 
   _currentKeyDown = key;
@@ -586,14 +582,56 @@ void DataGridWidget::handleCommand(CommandSender* sender, int cmd,
   }
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+int DataGridWidget::getToolTipIndex(const Common::Point& pos) const
+{
+  const int col = (pos.x - getAbsX()) / _colWidth;
+  const int row = (pos.y - getAbsY()) / _rowHeight;
+
+  if(row >= 0 && row < _rows && col >= 0 && col < _cols)
+    return row * _cols + col;
+  else
+    return -1;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+string DataGridWidget::getToolTip(const Common::Point& pos) const
+{
+  const int idx = getToolTipIndex(pos);
+
+  if(idx < 0)
+    return EmptyString;
+
+  const Int32 val = _valueList[idx];
+  ostringstream buf;
+
+  buf << _toolTipText
+    << "$" << Common::Base::toString(val, Common::Base::Fmt::_16)
+    << " = #" << val;
+  if(val < 0x100)
+  {
+    if(val >= 0x80)
+      buf << '/' << -(0x100 - val);
+    buf << " = %" << Common::Base::toString(val, Common::Base::Fmt::_2);
+  }
+
+  return buf.str();
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool DataGridWidget::changedToolTip(const Common::Point& oldPos,
+                                    const Common::Point& newPos) const
+{
+  return getToolTipIndex(oldPos) != getToolTipIndex(newPos);
+}
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void DataGridWidget::drawWidget(bool hilite)
 {
   FBSurface& s = _boss->dialog().surface();
-  bool onTop = _boss->dialog().isOnTop();
   int row, col;
 
-  s.fillRect(_x, _y, _w, _h, hilite && isEnabled() && isEditable() ? _bgcolorhi : onTop ? _bgcolor : kBGColorHi);
+  s.fillRect(_x, _y, _w, _h, hilite && isEnabled() && isEditable() ? _bgcolorhi : _bgcolor);
   // Draw the internal grid and labels
   int linewidth = _cols * _colWidth;
   s.frameRect(_x, _y, _w, _h, hilite && isEnabled() && isEditable() ? kWidColorHi : kColor);
@@ -612,7 +650,7 @@ void DataGridWidget::drawWidget(bool hilite)
       int x = _x + 4 + (col * _colWidth);
       int y = _y + 2 + (row * _rowHeight);
       int pos = row*_cols + col;
-      ColorId textColor = onTop ? kTextColor : kColor;
+      ColorId textColor = kTextColor;
 
       // Draw the selected item inverted, on a highlighted background.
       if (_currentRow == row && _currentCol == col &&
@@ -632,13 +670,12 @@ void DataGridWidget::drawWidget(bool hilite)
       {
         if(_changedList[pos])
         {
-          s.fillRect(x - 3, y - 1, _colWidth-1, _rowHeight-1,
-                     onTop ? kDbgChangedColor : _bgcolorlo);
+          s.fillRect(x - 3, y - 1, _colWidth-1, _rowHeight-1, kDbgChangedColor);
 
           if(_hiliteList[pos])
             textColor = kDbgColorHi;
           else
-            textColor = onTop ? kDbgChangedTextColor : textColor;
+            textColor = kDbgChangedTextColor;
         }
         else if(_hiliteList[pos])
           textColor = kDbgColorHi;
@@ -650,7 +687,7 @@ void DataGridWidget::drawWidget(bool hilite)
 
   // Only draw the caret while editing, and if it's in the current viewport
   if(_editMode)
-    drawCaret();
+    drawCaretSelection();
 
   // Draw the scrollbar
   if(_scrollBar)
@@ -680,11 +717,22 @@ int DataGridWidget::getWidth() const
   return _w + (_scrollBar ? ScrollBarWidget::scrollBarWidth(_font) : 0);
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void DataGridWidget::setCrossed(bool enable)
+{
+  if(_crossGrid != enable)
+  {
+    _crossGrid = enable;
+    setDirty();
+  }
+}
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void DataGridWidget::startEditMode()
 {
   if (isEditable() && !_editMode && _selectedItem >= 0)
   {
+    dialog().tooltip().hide();
     enableEditMode(true);
     setText("", true);  // Erase current entry when starting editing
   }
diff --git a/src/debugger/gui/DataGridWidget.hxx b/src/debugger/gui/DataGridWidget.hxx
index f7d9988c5..ed1b6be02 100644
--- a/src/debugger/gui/DataGridWidget.hxx
+++ b/src/debugger/gui/DataGridWidget.hxx
@@ -69,6 +69,7 @@ class DataGridWidget : public EditableWidget
 
     int getSelectedAddr() const   { return _addrList[_selectedItem]; }
     int getSelectedValue() const  { return _valueList[_selectedItem]; }
+    bool getSelectedChanged() const { return _changedList[_selectedItem]; }
 
     void setRange(int lower, int upper);
 
@@ -81,7 +82,10 @@ class DataGridWidget : public EditableWidget
 
     void setOpsWidget(DataGridOpsWidget* w) { _opsWidget = w; }
 
-    void setCrossed(bool enable) { _crossGrid = enable; }
+    void setCrossed(bool enable);
+
+    string getToolTip(const Common::Point& pos) const override;
+    bool changedToolTip(const Common::Point& oldPos, const Common::Point& newPos) const override;
 
   protected:
     void drawWidget(bool hilite) override;
@@ -97,11 +101,12 @@ class DataGridWidget : public EditableWidget
     void receivedFocusWidget() override;
     void lostFocusWidget() override;
 
+    bool hasToolTip() const override { return true; }
+    int getToolTipIndex(const Common::Point& pos) const;
+
     void handleMouseDown(int x, int y, MouseButton b, int clickCount) override;
     void handleMouseUp(int x, int y, MouseButton b, int clickCount) override;
     void handleMouseWheel(int x, int y, int direction) override;
-    void handleMouseEntered() override;
-    void handleMouseLeft() override;
     bool handleText(char text) override;
     bool handleKeyDown(StellaKey key, StellaMod mod) override;
     bool handleKeyUp(StellaKey key, StellaMod mod) override;
@@ -127,7 +132,6 @@ class DataGridWidget : public EditableWidget
     BoolArray   _changedList;
     BoolArray   _hiliteList;
 
-    bool      _editMode{false};
     int       _selectedItem{0};
     StellaKey _currentKeyDown{KBDK_UNKNOWN};
     string    _backupString;
@@ -147,6 +151,7 @@ class DataGridWidget : public EditableWidget
 
     void enableEditMode(bool state) { _editMode = state; }
 
+
   private:
     // Following constructors and assignment operators not supported
     DataGridWidget() = delete;
diff --git a/src/debugger/gui/DebuggerDialog.cxx b/src/debugger/gui/DebuggerDialog.cxx
index 17716b634..e344ab12a 100644
--- a/src/debugger/gui/DebuggerDialog.cxx
+++ b/src/debugger/gui/DebuggerDialog.cxx
@@ -18,6 +18,7 @@
 #include "Cart.hxx"
 #include "Widget.hxx"
 #include "Dialog.hxx"
+#include "ToolTip.hxx"
 #include "Settings.hxx"
 #include "StellaKeys.hxx"
 #include "EventHandler.hxx"
@@ -94,6 +95,7 @@ void DebuggerDialog::loadConfig()
   myRomTab->loadConfig();
 
   myMessageBox->setText("");
+  myMessageBox->setToolTip("");
 }
 
 void DebuggerDialog::saveConfig()
@@ -308,84 +310,72 @@ void DebuggerDialog::handleCommand(CommandSender* sender, int cmd,
 void DebuggerDialog::doStep()
 {
   instance().debugger().parser().run("step");
-  setDirty();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void DebuggerDialog::doTrace()
 {
   instance().debugger().parser().run("trace");
-  setDirty();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void DebuggerDialog::doAdvance()
 {
   instance().debugger().parser().run("frame #1");
-  setDirty();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void DebuggerDialog::doScanlineAdvance()
 {
   instance().debugger().parser().run("scanline #1");
-  setDirty();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void DebuggerDialog::doRewind()
 {
   instance().debugger().parser().run("rewind");
-  setDirty();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void DebuggerDialog::doUnwind()
 {
   instance().debugger().parser().run("unwind");
-  setDirty();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void DebuggerDialog::doRewind10()
 {
   instance().debugger().parser().run("rewind #10");
-  setDirty();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void DebuggerDialog::doUnwind10()
 {
   instance().debugger().parser().run("unwind #10");
-  setDirty();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void DebuggerDialog::doRewindAll()
 {
   instance().debugger().parser().run("rewind #1000");
-  setDirty();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void DebuggerDialog::doUnwindAll()
 {
   instance().debugger().parser().run("unwind #1000");
-  setDirty();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void DebuggerDialog::doExitDebugger()
 {
   instance().debugger().parser().run("run");
-  setDirty();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void DebuggerDialog::doExitRom()
 {
   instance().debugger().parser().run("exitrom");
-  setDirty();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -444,6 +434,7 @@ void DebuggerDialog::createFont()
         break;
     }
   }
+  tooltip().setFont(*myNFont);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -624,20 +615,21 @@ void DebuggerDialog::addStatusArea()
 {
   const int lineHeight = myLFont->getLineHeight();
   const Common::Rect& r = getStatusBounds();
+  const int HBORDER = 10;
+  const int VGAP = lineHeight / 3;
   int xpos, ypos;
 
-  xpos = r.x();  ypos = r.y();
-  myTiaInfo = new TiaInfoWidget(this, *myLFont, *myNFont, xpos, ypos, r.w());
+  xpos = r.x() + HBORDER;  ypos = r.y();
+  myTiaInfo = new TiaInfoWidget(this, *myLFont, *myNFont, xpos, ypos, r.w() - HBORDER);
 
-  ypos += myTiaInfo->getHeight() + 8;
-  myTiaZoom = new TiaZoomWidget(this, *myNFont, xpos + 10, ypos,
-                                r.w() - 10, r.h() - lineHeight - ypos - 3);
+  ypos = myTiaInfo->getBottom() + VGAP;
+  myTiaZoom = new TiaZoomWidget(this, *myNFont, xpos, ypos,
+                                r.w() - HBORDER, r.h() - ypos - VGAP - lineHeight + 3);
   addToFocusList(myTiaZoom->getFocusList());
 
-  xpos += 10;  ypos += myTiaZoom->getHeight() + 6;
-  myMessageBox = new EditTextWidget(this, *myLFont,
-                                    xpos, ypos, myTiaZoom->getWidth(),
-                                    myLFont->getLineHeight(), "");
+  ypos = myTiaZoom->getBottom() + VGAP;
+  myMessageBox = new EditTextWidget(this, *myLFont, xpos, ypos,
+                                    myTiaZoom->getWidth(), lineHeight);
   myMessageBox->setEditable(false, false);
   myMessageBox->clearFlags(Widget::FLAG_RETAIN_FOCUS);
   myMessageBox->setTextColor(kTextColorEm);
@@ -735,7 +727,7 @@ void DebuggerDialog::addRomArea()
   DataGridOpsWidget* ops = new DataGridOpsWidget(this, *myLFont, xpos, ypos);
 
   int max_w = xpos - r.x() - 10;
-  xpos = r.x() + 10;  ypos = 10;
+  xpos = r.x() + 10;  ypos = 5;
   myCpu = new CpuWidget(this, *myLFont, *myNFont, xpos, ypos, max_w);
   addToFocusList(myCpu->getFocusList());
 
diff --git a/src/debugger/gui/DebuggerDialog.hxx b/src/debugger/gui/DebuggerDialog.hxx
index 76fb869bb..01e35c2f4 100644
--- a/src/debugger/gui/DebuggerDialog.hxx
+++ b/src/debugger/gui/DebuggerDialog.hxx
@@ -89,7 +89,7 @@ class DebuggerDialog : public Dialog
     void showBrowser(BrowserType type);
 
   private:
-    void center() override { positionAt(0); }
+    void setPosition() override { positionAt(0); }
     void loadConfig() override;
     void handleKeyDown(StellaKey key, StellaMod mod, bool repeated) override;
     void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
diff --git a/src/debugger/gui/DelayQueueWidget.cxx b/src/debugger/gui/DelayQueueWidget.cxx
index 6dbd613be..d0ad50351 100644
--- a/src/debugger/gui/DelayQueueWidget.cxx
+++ b/src/debugger/gui/DelayQueueWidget.cxx
@@ -50,7 +50,11 @@ void DelayQueueWidget::loadConfig() {
   using Common::Base;
   for (auto&& line : myLines) {
     if (!delayQueueIterator->isValid()) {
-      line = "";
+      if(line != "")
+      {
+        setDirty();
+        line = "";
+      }
       continue;
     }
 
@@ -81,7 +85,11 @@ void DelayQueueWidget::loadConfig() {
         break;
     }
 
-    line = ss.str();
+    if(line != ss.str())
+    {
+      setDirty();
+      line = ss.str();
+    }
     delayQueueIterator->next();
   }
 }
@@ -90,7 +98,6 @@ void DelayQueueWidget::loadConfig() {
 void DelayQueueWidget::drawWidget(bool hilite)
 {
   FBSurface& surface = _boss->dialog().surface();
-  bool onTop = _boss->dialog().isOnTop();
 
   int y = _y,
       x = _x,
@@ -102,14 +109,14 @@ void DelayQueueWidget::drawWidget(bool hilite)
   y += 1;
   x += 1;
   w -= 1;
-  surface.fillRect(x, y, w - 1, _h - 2, onTop ? kDlgColor : _bgcolorlo);
+  surface.fillRect(x, y, w - 1, _h - 2, kDlgColor);
 
   y += 2;
   x += 2;
   w -= 3;
 
   for (const auto& line : myLines) {
-    surface.drawString(_font, line, x, y, w, onTop ? _textcolor : kColor);
+    surface.drawString(_font, line, x, y, w, _textcolor);
     y += lineHeight;
   }
 }
diff --git a/src/debugger/gui/DrivingWidget.cxx b/src/debugger/gui/DrivingWidget.cxx
index 29419268c..5f0b74d95 100644
--- a/src/debugger/gui/DrivingWidget.cxx
+++ b/src/debugger/gui/DrivingWidget.cxx
@@ -20,39 +20,61 @@
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 DrivingWidget::DrivingWidget(GuiObject* boss, const GUI::Font& font,
-                             int x, int y, Controller& controller)
+                             int x, int y, Controller& controller, bool embedded)
   : ControllerWidget(boss, font, x, y, controller)
 {
   const string& label = getHeader();
 
-  const int fontHeight = font.getFontHeight(),
-            bwidth = font.getStringWidth("Gray code +") + 10,
-            bheight = font.getLineHeight() + 4;
-  int xpos = x, ypos = y, lwidth = font.getStringWidth("Right (Driving)");
-  StaticTextWidget* t;
+  const int lineHeight = font.getLineHeight(),
+            bHeight = font.getLineHeight() * 1.25;
+  int xpos = x, ypos = y;
 
-  t = new StaticTextWidget(boss, font, xpos, ypos+2, lwidth,
-                           fontHeight, label, TextAlign::Left);
+  if(embedded)
+  {
+    const int bWidth = font.getStringWidth("GC+ ");
 
-  ypos += t->getHeight() + 20;
-  myGrayUp = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight,
-                              "Gray code +", kGrayUpCmd);
-  myGrayUp->setTarget(this);
+    ypos += _lineHeight * 0.334;
+    myGrayUp = new ButtonWidget(boss, font, xpos, ypos, bWidth, bHeight,
+                                "GC+", kGrayUpCmd);
 
-  ypos += myGrayUp->getHeight() + 5;
-  myGrayDown = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight,
-                                "Gray code -", kGrayDownCmd);
-  myGrayDown->setTarget(this);
+    ypos += myGrayUp->getHeight() + bHeight * 0.3;
+    myGrayDown = new ButtonWidget(boss, font, xpos, ypos, bWidth, bHeight,
+                                  "GC-", kGrayDownCmd);
+    xpos += myGrayDown->getWidth() + _fontWidth * 0.75;
+  }
+  else
+  {
+    const int lwidth = font.getStringWidth("Right (Driving)"),
+      bWidth = font.getStringWidth("Gray code +") + _fontWidth * 1.25;
 
-  xpos += myGrayDown->getWidth() + 10;  ypos -= 10;
+    StaticTextWidget* t = new StaticTextWidget(boss, font, xpos, ypos + 2, lwidth,
+                                               lineHeight, label, TextAlign::Left);
+
+    ypos = t->getBottom() + _lineHeight * 1.334;
+    myGrayUp = new ButtonWidget(boss, font, xpos, ypos, bWidth, bHeight,
+                                "Gray code +", kGrayUpCmd);
+
+    ypos += myGrayUp->getHeight() + bHeight * 0.3;
+    myGrayDown = new ButtonWidget(boss, font, xpos, ypos, bWidth, bHeight,
+                                  "Gray code -", kGrayDownCmd);
+    xpos += myGrayDown->getWidth() + _fontWidth;
+  }
+  ypos -= bHeight * 0.6;
   myGrayValue = new DataGridWidget(boss, font, xpos, ypos,
                                    1, 1, 2, 8, Common::Base::Fmt::_16);
+
+  xpos = x + myGrayDown->getWidth() * 0.25; ypos = myGrayDown->getBottom() + _lineHeight;
+  myFire = new CheckboxWidget(boss, font, xpos, ypos, "Fire", kFireCmd);
+
+  myGrayUp->setTarget(this);
+  myGrayDown->setTarget(this);
   myGrayValue->setTarget(this);
   myGrayValue->setEditable(false);
-
-  xpos = x + 30;  ypos += myGrayDown->getHeight() + 20;
-  myFire = new CheckboxWidget(boss, font, xpos, ypos, "Fire", kFireCmd);
   myFire->setTarget(this);
+
+  addFocusWidget(myGrayUp);
+  addFocusWidget(myGrayDown);
+  addFocusWidget(myFire);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/debugger/gui/DrivingWidget.hxx b/src/debugger/gui/DrivingWidget.hxx
index 0ab6c1d15..e8d648f8f 100644
--- a/src/debugger/gui/DrivingWidget.hxx
+++ b/src/debugger/gui/DrivingWidget.hxx
@@ -29,7 +29,7 @@ class DrivingWidget : public ControllerWidget
 {
   public:
     DrivingWidget(GuiObject* boss, const GUI::Font& font, int x, int y,
-                  Controller& controller);
+                  Controller& controller, bool embedded = false);
     ~DrivingWidget() override = default;
 
   private:
diff --git a/src/debugger/gui/FlashWidget.cxx b/src/debugger/gui/FlashWidget.cxx
index 3c2614659..1b7f06445 100644
--- a/src/debugger/gui/FlashWidget.cxx
+++ b/src/debugger/gui/FlashWidget.cxx
@@ -28,31 +28,42 @@ FlashWidget::FlashWidget(GuiObject* boss, const GUI::Font& font,
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void FlashWidget::init(GuiObject* boss, const GUI::Font& font, int x, int y)
+void FlashWidget::init(GuiObject* boss, const GUI::Font& font,
+                       int x, int y, bool embedded)
 {
-  const int lineHeight = font.getLineHeight();
   int xpos = x, ypos = y;
 
-  new StaticTextWidget(boss, font, xpos, ypos + 2, getHeader());
+  myEmbedded = embedded;
+  if(!embedded)
+  {
+    new StaticTextWidget(boss, font, xpos, ypos + 2, getHeader());
 
-  ypos += lineHeight + 6;
+    ypos += _lineHeight * 1.4;
+    new StaticTextWidget(boss, font, xpos, ypos, "Pages/Ranges used:");
+  }
+  else
+  {
+    ypos += _lineHeight * 0.4 - (2 + _lineHeight);
+    new StaticTextWidget(boss, font, xpos, ypos, "Pages:");
+  }
 
-  new StaticTextWidget(boss, font, xpos, ypos, "Pages/Ranges used:");
-
-  ypos += lineHeight + 2;
+  ypos += _lineHeight + 2;
   xpos += 8;
-
   for(uInt32 page = 0; page < MAX_PAGES; ++page)
   {
     myPage[page] = new StaticTextWidget(boss, font, xpos, ypos,
-        page ? "                  " : "none              ");
-    ypos += lineHeight;
+        embedded ? page ? "    " : "none"
+                 : page ? "                  " : "none              ");
+    ypos += _lineHeight;
   }
 
   xpos -= 8; ypos += 2;
   myEEPROMEraseCurrent = new ButtonWidget(boss, font, xpos, ypos,
-                                          "Erase used pages", kEEPROMEraseCurrent);
+                                          embedded ? "Erase" : "Erase used pages", 
+                                          kEEPROMEraseCurrent);
   myEEPROMEraseCurrent->setTarget(this);
+
+  addFocusWidget(myEEPROMEraseCurrent);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -86,12 +97,14 @@ void FlashWidget::loadConfig()
         label.str("");
         label << Common::Base::HEX3 << startPage;
 
-        if(int(page) - 1 != startPage)
-          label << "-" << Common::Base::HEX3 << page - 1;
-        else
-          label << "    ";
-        label << ": " << Common::Base::HEX4 << from << "-" << Common::Base::HEX4 << to;
-
+        if(!myEmbedded)
+        {
+          if(int(page) - 1 != startPage)
+            label << "-" << Common::Base::HEX3 << page - 1;
+          else
+            label << "    ";
+          label << ": " << Common::Base::HEX4 << from << "-" << Common::Base::HEX4 << to;
+        }
         myPage[useCount]->setLabel(label.str());
 
         startPage = -1;
diff --git a/src/debugger/gui/FlashWidget.hxx b/src/debugger/gui/FlashWidget.hxx
index cb085be9d..5db1cae2f 100644
--- a/src/debugger/gui/FlashWidget.hxx
+++ b/src/debugger/gui/FlashWidget.hxx
@@ -31,12 +31,14 @@ class FlashWidget : public ControllerWidget
     ~FlashWidget() override = default;
 
   protected:
-    void init(GuiObject* boss, const GUI::Font& font, int x, int y);
+    void init(GuiObject* boss, const GUI::Font& font, int x, int y, bool embedded);
 
   private:
-    ButtonWidget* myEEPROMEraseCurrent{nullptr};
     enum { kEEPROMEraseCurrent = 'eeEC' };
 
+    bool myEmbedded{false};
+    ButtonWidget* myEEPROMEraseCurrent{nullptr};
+
     static constexpr uInt32 MAX_PAGES = 5;
     std::array<StaticTextWidget*, MAX_PAGES> myPage{nullptr};
 
diff --git a/src/debugger/gui/GenesisWidget.cxx b/src/debugger/gui/GenesisWidget.cxx
index 70833879a..fcf05ce2f 100644
--- a/src/debugger/gui/GenesisWidget.cxx
+++ b/src/debugger/gui/GenesisWidget.cxx
@@ -67,6 +67,13 @@ GenesisWidget::GenesisWidget(GuiObject* boss, const GUI::Font& font,
                                       CheckboxWidget::kCheckActionCmd);
   myPins[kJCbtn]->setID(kJCbtn);
   myPins[kJCbtn]->setTarget(this);
+
+  addFocusWidget(myPins[kJUp]);
+  addFocusWidget(myPins[kJLeft]);
+  addFocusWidget(myPins[kJRight]);
+  addFocusWidget(myPins[kJDown]);
+  addFocusWidget(myPins[kJBbtn]);
+  addFocusWidget(myPins[kJCbtn]);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/debugger/gui/JoystickWidget.cxx b/src/debugger/gui/JoystickWidget.cxx
index dc3b2c85d..2581f41ae 100644
--- a/src/debugger/gui/JoystickWidget.cxx
+++ b/src/debugger/gui/JoystickWidget.cxx
@@ -19,17 +19,23 @@
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 JoystickWidget::JoystickWidget(GuiObject* boss, const GUI::Font& font,
-                               int x, int y, Controller& controller)
+                               int x, int y, Controller& controller,
+                               bool embedded)
   : ControllerWidget(boss, font, x, y, controller)
 {
-  const string& label = getHeader();
   const int fontHeight = font.getFontHeight();
-  int xpos = x, ypos = y, lwidth = font.getStringWidth("Right (Joystick)");
-  StaticTextWidget* t;
+  int xpos = x, ypos = y;
 
-  t = new StaticTextWidget(boss, font, xpos, ypos+2, lwidth,
-                           fontHeight, label, TextAlign::Left);
-  xpos += t->getWidth()/2 - 5;  ypos += t->getHeight() + 20;
+  if(!embedded)
+  {
+    const string& label = getHeader();
+    const int lwidth = font.getStringWidth("Right (Joystick)");
+    StaticTextWidget* t;
+
+    t = new StaticTextWidget(boss, font, xpos, ypos + 2, lwidth,
+                             _lineHeight, label, TextAlign::Left);
+    xpos += t->getWidth() / 2 - 5;  ypos = t->getBottom() + fontHeight;
+  }
   myPins[kJUp] = new CheckboxWidget(boss, font, xpos, ypos, "",
                                     CheckboxWidget::kCheckActionCmd);
   myPins[kJUp]->setID(kJUp);
@@ -55,11 +61,17 @@ JoystickWidget::JoystickWidget(GuiObject* boss, const GUI::Font& font,
   myPins[kJRight]->setTarget(this);
 
   xpos -= (myPins[kJUp]->getWidth() + 5) * 2;
-  ypos = 30 + (myPins[kJUp]->getHeight() + 10) * 3;
+  ypos = myPins[kJDown]->getBottom() + fontHeight * 0.75;
   myPins[kJFire] = new CheckboxWidget(boss, font, xpos, ypos, "Fire",
                                       CheckboxWidget::kCheckActionCmd);
   myPins[kJFire]->setID(kJFire);
   myPins[kJFire]->setTarget(this);
+
+  addFocusWidget(myPins[kJUp]);
+  addFocusWidget(myPins[kJLeft]);
+  addFocusWidget(myPins[kJRight]);
+  addFocusWidget(myPins[kJDown]);
+  addFocusWidget(myPins[kJFire]);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/debugger/gui/JoystickWidget.hxx b/src/debugger/gui/JoystickWidget.hxx
index 1c1143b7f..1804dd2a6 100644
--- a/src/debugger/gui/JoystickWidget.hxx
+++ b/src/debugger/gui/JoystickWidget.hxx
@@ -25,7 +25,7 @@ class JoystickWidget : public ControllerWidget
 {
   public:
     JoystickWidget(GuiObject* boss, const GUI::Font& font, int x, int y,
-                   Controller& controller);
+                   Controller& controller, bool embedded = false);
     ~JoystickWidget() override = default;
 
   private:
diff --git a/src/debugger/gui/KeyboardWidget.cxx b/src/debugger/gui/KeyboardWidget.cxx
index 296217d1e..1496b172c 100644
--- a/src/debugger/gui/KeyboardWidget.cxx
+++ b/src/debugger/gui/KeyboardWidget.cxx
@@ -47,6 +47,7 @@ KeyboardWidget::KeyboardWidget(GuiObject* boss, const GUI::Font& font,
       xpos = x + 30;
       ypos += myBox[i]->getHeight() + 5;
     }
+    addFocusWidget(myBox[i]);
   }
   myEvent = leftport ? ourLeftEvents.data() : ourRightEvents.data();
 }
diff --git a/src/debugger/gui/NullControlWidget.hxx b/src/debugger/gui/NullControlWidget.hxx
index 79364ca6e..d5cef42c9 100644
--- a/src/debugger/gui/NullControlWidget.hxx
+++ b/src/debugger/gui/NullControlWidget.hxx
@@ -26,22 +26,38 @@ class NullControlWidget : public ControllerWidget
 {
   public:
     NullControlWidget(GuiObject* boss, const GUI::Font& font, int x, int y,
-                      Controller& controller)
+                      Controller& controller, bool embedded = false)
       : ControllerWidget(boss, font, x, y, controller)
     {
-      ostringstream buf;
-      buf << getHeader();
       const int fontHeight = font.getFontHeight(),
-                lineHeight = font.getLineHeight(),
-                lwidth = std::max(font.getStringWidth(buf.str()),
-                font.getStringWidth("Controller input"));
-      new StaticTextWidget(boss, font, x, y+2, lwidth,
-                           fontHeight, buf.str(), TextAlign::Left);
-      new StaticTextWidget(boss, font, x, y+2+2*lineHeight, lwidth,
-                           fontHeight, "Controller input", TextAlign::Center);
-      new StaticTextWidget(boss, font, x, y+2+3*lineHeight, lwidth,
-                           fontHeight, "not available",
-                           TextAlign::Center);
+        lineHeight = font.getLineHeight();
+
+      if(embedded)
+      {
+        const int lwidth = font.getStringWidth("avail.");
+
+        y += fontHeight;
+        new StaticTextWidget(boss, font, x, y, lwidth, fontHeight,
+                             "not", TextAlign::Center);
+        y += lineHeight;
+        new StaticTextWidget(boss, font, x, y, lwidth, fontHeight,
+                             "avail.", TextAlign::Center);
+      }
+      else
+      {
+        ostringstream buf;
+        buf << getHeader();
+        const int lwidth = std::max(font.getStringWidth(buf.str()),
+                                    font.getStringWidth("Controller input"));
+
+        new StaticTextWidget(boss, font, x, y + 2, lwidth, fontHeight, buf.str());
+        y += 2 + lineHeight * 2;
+        new StaticTextWidget(boss, font, x, y, lwidth,
+                             fontHeight, "Controller input", TextAlign::Center);
+        new StaticTextWidget(boss, font, x, y+lineHeight, lwidth,
+                             fontHeight, "not available",
+                             TextAlign::Center);
+      }
     }
 
     ~NullControlWidget() override = default;
diff --git a/src/debugger/gui/PaddleWidget.cxx b/src/debugger/gui/PaddleWidget.cxx
index 87d9fe6ec..d3e31d656 100644
--- a/src/debugger/gui/PaddleWidget.cxx
+++ b/src/debugger/gui/PaddleWidget.cxx
@@ -19,49 +19,90 @@
 #include "PaddleWidget.hxx"
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-PaddleWidget::PaddleWidget(GuiObject* boss, const GUI::Font& font,
-                           int x, int y, Controller& controller)
+PaddleWidget::PaddleWidget(GuiObject* boss, const GUI::Font& font, int x, int y,
+                           Controller& controller, bool embedded, bool second)
   : ControllerWidget(boss, font, x, y, controller)
 {
   bool leftport = isLeftPort();
   const string& label = getHeader();
+  const int fontHeight = font.getFontHeight();
 
-  const int fontHeight = font.getFontHeight(),
-            lineHeight = font.getLineHeight();
-  int xpos = x, ypos = y, lwidth = font.getStringWidth("Right (Paddles)");
+  int xpos = x, ypos = y,
+    lwidth = font.getStringWidth("Right (Paddles)");
 
-  new StaticTextWidget(boss, font, xpos, ypos+2, lwidth,
-                       fontHeight, label);
+  if(!embedded)
+  {
+    new StaticTextWidget(boss, font, xpos, ypos + 2, lwidth,
+                         _lineHeight, label);
+    ypos += _lineHeight + fontHeight + 2;
 
-  ypos += lineHeight + 20;
-  const string& p0string = leftport ? "P0 pot " : "P2 pot ";
-  const string& p1string = leftport ? "P1 pot " : "P3 pot ";
-  myP0Resistance =
-    new SliderWidget(boss, font, xpos, ypos,
-                     p0string, 0, kP0Changed);
+    const string& p0string = leftport ? "P1 pot " : "P3 pot ";
+    const string& p1string = leftport ? "P2 pot " : "P4 pot ";
+    myP0Resistance =
+      new SliderWidget(boss, font, xpos, ypos,
+                       p0string, 0, kP0Changed);
+
+    xpos += 20;  ypos += myP0Resistance->getHeight() * 1.33;
+    myP0Fire = new CheckboxWidget(boss, font, xpos, ypos,
+                                  "Fire", kP0Fire);
+
+    xpos = x;  ypos += _lineHeight * 2.25;
+    myP1Resistance =
+      new SliderWidget(boss, font, xpos, ypos,
+                       p1string, 0, kP1Changed);
+
+    xpos += 20;  ypos += myP1Resistance->getHeight() * 1.33;
+    myP1Fire = new CheckboxWidget(boss, font, xpos, ypos,
+                                  "Fire", kP1Fire);
+  }
+  else
+  {
+    const string& p0string = leftport ? second ? "P1b" : "P1a"
+                                      : second ? "P3b" : "P3a";
+    const string& p1string = leftport ? second ? "P2b" : "P2a"
+                                      : second ? "P4b" : "P4a";
+
+    new StaticTextWidget(boss, font, xpos, ypos + 2, p0string);
+
+    //ypos += lineHeight;
+    myP0Resistance = new SliderWidget(boss, font, xpos, ypos);
+    myP0Resistance->setEnabled(false);
+    myP0Resistance->setFlags(Widget::FLAG_INVISIBLE);
+
+    ypos += _lineHeight * 1.33;
+    myP0Fire = new CheckboxWidget(boss, font, xpos, ypos,
+                                  "Fire", kP0Fire);
+
+    xpos = x;  ypos += _lineHeight * 2.25;
+    new StaticTextWidget(boss, font, xpos, ypos + 2, p1string);
+
+    //ypos += lineHeight;
+    myP1Resistance = new SliderWidget(boss, font, xpos, ypos);
+    myP1Resistance->setEnabled(false);
+    myP1Resistance->setFlags(Widget::FLAG_INVISIBLE);
+
+    ypos += _lineHeight * 1.33;
+    myP1Fire = new CheckboxWidget(boss, font, xpos, ypos,
+                                  "Fire", kP1Fire);
+  }
   myP0Resistance->setMinValue(0);
   myP0Resistance->setMaxValue(uInt32(Paddles::MAX_RESISTANCE));
   myP0Resistance->setStepValue(uInt32(Paddles::MAX_RESISTANCE/100));
   myP0Resistance->setTarget(this);
 
-  xpos += 20;  ypos += myP0Resistance->getHeight() + 4;
-  myP0Fire = new CheckboxWidget(boss, font, xpos, ypos,
-                      "Fire", kP0Fire);
   myP0Fire->setTarget(this);
 
-  xpos = x;  ypos += 2*lineHeight;
-  myP1Resistance =
-    new SliderWidget(boss, font, xpos, ypos,
-                     p1string, 0, kP1Changed);
   myP1Resistance->setMinValue(0);
   myP1Resistance->setMaxValue(uInt32(Paddles::MAX_RESISTANCE));
   myP1Resistance->setStepValue(uInt32(Paddles::MAX_RESISTANCE/100));
   myP1Resistance->setTarget(this);
 
-  xpos += 20;  ypos += myP1Resistance->getHeight() + 4;
-  myP1Fire = new CheckboxWidget(boss, font, xpos, ypos,
-                      "Fire", kP1Fire);
   myP1Fire->setTarget(this);
+
+  addFocusWidget(myP0Resistance);
+  addFocusWidget(myP0Fire);
+  addFocusWidget(myP1Resistance);
+  addFocusWidget(myP1Fire);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/debugger/gui/PaddleWidget.hxx b/src/debugger/gui/PaddleWidget.hxx
index 8773b5a1d..e3034c80c 100644
--- a/src/debugger/gui/PaddleWidget.hxx
+++ b/src/debugger/gui/PaddleWidget.hxx
@@ -26,7 +26,8 @@ class PaddleWidget : public ControllerWidget
 {
   public:
     PaddleWidget(GuiObject* boss, const GUI::Font& font, int x, int y,
-                 Controller& controller);
+                 Controller& controller,
+                 bool embedded = false, bool second = false);
     ~PaddleWidget() override = default;
 
   private:
diff --git a/src/debugger/gui/PointingDeviceWidget.cxx b/src/debugger/gui/PointingDeviceWidget.cxx
index 43bbc4ed5..56127c83c 100644
--- a/src/debugger/gui/PointingDeviceWidget.cxx
+++ b/src/debugger/gui/PointingDeviceWidget.cxx
@@ -68,6 +68,12 @@ PointingDeviceWidget::PointingDeviceWidget(GuiObject* boss, const GUI::Font& fon
 
   myFire = new CheckboxWidget(boss, font, xLeft, ypos, "Fire", kTBFire);
   myFire->setTarget(this);
+
+  addFocusWidget(myGrayUp);
+  addFocusWidget(myGrayLeft);
+  addFocusWidget(myGrayRight);
+  addFocusWidget(myGrayDown);
+  addFocusWidget(myFire);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/debugger/gui/PromptWidget.cxx b/src/debugger/gui/PromptWidget.cxx
index 7a1cd56f2..116080bf7 100644
--- a/src/debugger/gui/PromptWidget.cxx
+++ b/src/debugger/gui/PromptWidget.cxx
@@ -24,12 +24,17 @@
 #include "Debugger.hxx"
 #include "DebuggerDialog.hxx"
 #include "DebuggerParser.hxx"
+#include "EventHandler.hxx"
 
 #include "PromptWidget.hxx"
 #include "CartDebug.hxx"
 
 #define PROMPT  "> "
 
+// Uncomment the following to give full-line cut/copy/paste
+// Note that this will be removed eventually, when we implement proper cut/copy/paste
+#define PSEUDO_CUT_COPY_PASTE
+
 // TODO: Github issue #361
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 PromptWidget::PromptWidget(GuiObject* boss, const GUI::Font& font,
@@ -76,9 +81,7 @@ void PromptWidget::drawWidget(bool hilite)
 {
 //cerr << "PromptWidget::drawWidget\n";
   ColorId fgcolor, bgcolor;
-
   FBSurface& s = _boss->dialog().surface();
-  bool onTop = _boss->dialog().isOnTop();
 
   // Draw text
   int start = _scrollLine - _linesPerPage + 1;
@@ -99,7 +102,7 @@ void PromptWidget::drawWidget(bool hilite)
       else
         fgcolor = ColorId(c >> 8);
 
-      s.drawChar(_font, c & 0x7f, x, y, onTop ? fgcolor : kColor);
+      s.drawChar(_font, c & 0x7f, x, y, fgcolor);
       x += _kConsoleCharWidth;
     }
     y += _kConsoleLineHeight;
@@ -332,7 +335,10 @@ bool PromptWidget::handleKeyDown(StellaKey key, StellaMod mod)
 
     case KBDK_DELETE:
     case KBDK_KP_PERIOD: // actually the num delete
-      killChar(+1);
+      if(StellaModTest::isShift(mod))
+        textCut();
+      else
+        killChar(+1);
       dirty = true;
       break;
 
@@ -439,6 +445,21 @@ bool PromptWidget::handleKeyDown(StellaKey key, StellaMod mod)
       dirty = true;
       break;
 
+    case KBDK_INSERT:
+      if(StellaModTest::isShift(mod))
+      {
+        textPaste();
+        dirty = true;
+      }
+      else if(StellaModTest::isControl(mod))
+      {
+        textCopy();
+        dirty = true;
+      }
+      else
+        handled = false;
+      break;
+
     default:
       if (StellaModTest::isControl(mod))
       {
@@ -568,7 +589,7 @@ void PromptWidget::specialKeys(StellaKey key)
       killLine(-1);
       break;
     case KBDK_W:
-      killLastWord();
+      killWord();
       break;
     case KBDK_A:
       textSelectAll();
@@ -643,7 +664,7 @@ void PromptWidget::killLine(int direction)
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void PromptWidget::killLastWord()
+void PromptWidget::killWord()
 {
   int cnt = 0;
   bool space = true;
@@ -673,19 +694,61 @@ void PromptWidget::textSelectAll()
 {
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+string PromptWidget::getLine()
+{
+#if defined(PSEUDO_CUT_COPY_PASTE)
+  assert(_promptEndPos >= _promptStartPos);
+  int len = _promptEndPos - _promptStartPos;
+  string text;
+
+  // Copy current line to text
+  for(int i = 0; i < len; i++)
+    text += buffer(_promptStartPos + i) & 0x7f;
+
+  return text;
+#endif
+}
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void PromptWidget::textCut()
 {
+#if defined(PSEUDO_CUT_COPY_PASTE)
+  string text = getLine();
+
+  instance().eventHandler().copyText(text);
+
+  // Remove the current line
+  _currentPos = _promptStartPos;
+  killLine(1);  // to end of line
+  _promptEndPos = _currentPos;
+#endif
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void PromptWidget::textCopy()
 {
+#if defined(PSEUDO_CUT_COPY_PASTE)
+  string text = getLine();
+
+  instance().eventHandler().copyText(text);
+#endif
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void PromptWidget::textPaste()
 {
+#if defined(PSEUDO_CUT_COPY_PASTE)
+  string text;
+
+  // Remove the current line
+  _currentPos = _promptStartPos;
+  killLine(1);  // to end of line
+
+  instance().eventHandler().pasteText(text);
+  print(text);
+  _promptEndPos = _currentPos;
+#endif
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -873,8 +936,6 @@ void PromptWidget::drawCaret()
 {
 //cerr << "PromptWidget::drawCaret()\n";
   FBSurface& s = _boss->dialog().surface();
-  bool onTop = _boss->dialog().isOnTop();
-
   int line = _currentPos / _lineWidth;
 
   // Don't draw the cursor if it's not in the current view
@@ -886,7 +947,7 @@ void PromptWidget::drawCaret()
   int y = _y + displayLine * _kConsoleLineHeight;
 
   char c = buffer(_currentPos); //FIXME: int to char??
-  s.fillRect(x, y, _kConsoleCharWidth, _kConsoleLineHeight, onTop ? kTextColor : kColor);
+  s.fillRect(x, y, _kConsoleCharWidth, _kConsoleLineHeight, kTextColor);
   s.drawChar(_font, c, x, y + 2, kBGColor);
 }
 
diff --git a/src/debugger/gui/PromptWidget.hxx b/src/debugger/gui/PromptWidget.hxx
index 0570f025f..c1719fa1a 100644
--- a/src/debugger/gui/PromptWidget.hxx
+++ b/src/debugger/gui/PromptWidget.hxx
@@ -68,10 +68,11 @@ class PromptWidget : public Widget, public CommandSender
     void nextLine();
     void killChar(int direction);
     void killLine(int direction);
-    void killLastWord();
+    void killWord();
 
     // Clipboard
     void textSelectAll();
+    string getLine();
     void textCut();
     void textCopy();
     void textPaste();
diff --git a/src/debugger/gui/QuadTariWidget.cxx b/src/debugger/gui/QuadTariWidget.cxx
new file mode 100644
index 000000000..3ab7c0e78
--- /dev/null
+++ b/src/debugger/gui/QuadTariWidget.cxx
@@ -0,0 +1,93 @@
+//============================================================================
+//
+//   SSSS    tt          lll  lll
+//  SS  SS   tt           ll   ll
+//  SS     tttttt  eeee   ll   ll   aaaa
+//   SSSS    tt   ee  ee  ll   ll      aa
+//      SS   tt   eeeeee  ll   ll   aaaaa  --  "An Atari 2600 VCS Emulator"
+//  SS  SS   tt   ee      ll   ll  aa  aa
+//   SSSS     ttt  eeeee llll llll  aaaaa
+//
+// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
+// and the Stella Team
+//
+// See the file "License.txt" for information on usage and redistribution of
+// this file, and for a DISCLAIMER OF ALL WARRANTIES.
+//============================================================================
+
+#include "OSystem.hxx"
+#include "Console.hxx"
+#include "TIA.hxx"
+#include "QuadTari.hxx"
+#include "AtariVoxWidget.hxx"
+#include "DrivingWidget.hxx"
+#include "JoystickWidget.hxx"
+#include "NullControlWidget.hxx"
+#include "PaddleWidget.hxx"
+#include "SaveKeyWidget.hxx"
+
+#include "QuadTariWidget.hxx"
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+QuadTariWidget::QuadTariWidget(GuiObject* boss, const GUI::Font& font,
+                               int x, int y, Controller& controller)
+  : ControllerWidget(boss, font, x, y, controller)
+{
+  string label = (isLeftPort() ? "Left" : "Right") + string(" (QuadTari)");
+  StaticTextWidget* t = new StaticTextWidget(boss, font, x, y + 2, label);
+  QuadTari& qt = static_cast<QuadTari&>(controller);
+
+  y = t->getBottom() + _lineHeight;
+  addController(boss, x, y, *qt.myFirstController, false);
+  addController(boss, x, y, *qt.mySecondController, true);
+
+  myPointer = new StaticTextWidget(boss, font,
+                                   t->getLeft() + _fontWidth * 7, y, "  ");
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void QuadTariWidget::addController(GuiObject* boss, int x, int y,
+                                   Controller& controller, bool second)
+{
+  ControllerWidget* widget;
+
+  x += second ? _fontWidth * 10 : 0;
+  switch(controller.type())
+  {
+    case Controller::Type::Joystick:
+      x += _fontWidth * 2;
+      widget = new JoystickWidget(boss, _font, x, y, controller, true);
+      break;
+
+    case Controller::Type::Driving:
+      widget = new DrivingWidget(boss, _font, x, y, controller, true);
+      break;
+
+    case Controller::Type::Paddles:
+      widget = new PaddleWidget(boss, _font, x, y, controller, true, second);
+      break;
+
+    case Controller::Type::AtariVox:
+      widget = new AtariVoxWidget(boss, _font, x, y, controller, true);
+      break;
+
+    case Controller::Type::SaveKey:
+      widget = new SaveKeyWidget(boss, _font, x, y, controller, true);
+      break;
+
+    default:
+      widget = new NullControlWidget(boss, _font, x, y, controller, true);
+      break;
+  }
+  WidgetArray focusList = widget->getFocusList();
+  if(!focusList.empty())
+    addToFocusList(focusList);
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void QuadTariWidget::loadConfig()
+{
+  bool first = !(instance().console().tia().registerValue(VBLANK) & 0x80);
+
+  myPointer->setLabel(first ? "<-" : "->");
+}
diff --git a/src/debugger/gui/QuadTariWidget.hxx b/src/debugger/gui/QuadTariWidget.hxx
new file mode 100644
index 000000000..2af39743b
--- /dev/null
+++ b/src/debugger/gui/QuadTariWidget.hxx
@@ -0,0 +1,53 @@
+//============================================================================
+//
+//   SSSS    tt          lll  lll
+//  SS  SS   tt           ll   ll
+//  SS     tttttt  eeee   ll   ll   aaaa
+//   SSSS    tt   ee  ee  ll   ll      aa
+//      SS   tt   eeeeee  ll   ll   aaaaa  --  "An Atari 2600 VCS Emulator"
+//  SS  SS   tt   ee      ll   ll  aa  aa
+//   SSSS     ttt  eeeee llll llll  aaaaa
+//
+// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
+// and the Stella Team
+//
+// See the file "License.txt" for information on usage and redistribution of
+// this file, and for a DISCLAIMER OF ALL WARRANTIES.
+//============================================================================
+
+#ifndef QUADTARI_WIDGET_HXX
+#define QUADTARI_WIDGET_HXX
+
+#include "Control.hxx"
+#include "ControllerWidget.hxx"
+
+class QuadTariWidget: public ControllerWidget
+{
+  public:
+    QuadTariWidget(GuiObject* boss, const GUI::Font& font, int x, int y,
+                   Controller& controller);
+    ~QuadTariWidget() override = default;
+
+  protected:
+    virtual string getHeader()
+    {
+      return (isLeftPort() ? "Left (" : "Right (") + string("QuadTari)");
+    }
+
+  private:
+    StaticTextWidget* myPointer{nullptr};
+
+    void loadConfig() override;
+
+    void addController(GuiObject* boss, int x, int y,
+                       Controller& controller, bool second);
+
+    // Following constructors and assignment operators not supported
+    QuadTariWidget() = delete;
+    QuadTariWidget(const QuadTariWidget&) = delete;
+    QuadTariWidget(QuadTariWidget&&) = delete;
+    QuadTariWidget& operator=(const QuadTariWidget&) = delete;
+    QuadTariWidget& operator=(QuadTariWidget&&) = delete;
+};
+
+#endif
diff --git a/src/debugger/gui/RamWidget.cxx b/src/debugger/gui/RamWidget.cxx
index f7559cd5b..4e097d9be 100644
--- a/src/debugger/gui/RamWidget.cxx
+++ b/src/debugger/gui/RamWidget.cxx
@@ -15,7 +15,7 @@
 // this file, and for a DISCLAIMER OF ALL WARRANTIES.
 //============================================================================
 
-#include "DataGridWidget.hxx"
+#include "DataGridRamWidget.hxx"
 #include "EditTextWidget.hxx"
 #include "GuiObject.hxx"
 #include "InputTextDialog.hxx"
@@ -37,24 +37,27 @@ RamWidget::RamWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n
     myFontWidth(lfont.getMaxCharWidth()),
     myFontHeight(lfont.getFontHeight()),
     myLineHeight(lfont.getLineHeight()),
-    myButtonHeight(myLineHeight + 4),
+    myButtonHeight(myLineHeight * 1.25),
     myRamSize(ramsize),
     myNumRows(numrows),
     myPageSize(pagesize)
 {
   const int bwidth  = lfont.getStringWidth("Compare " + ELLIPSIS),
             bheight = myLineHeight + 2;
-  const int VGAP = 4;
+  //const int VGAP = 4;
+  const int VGAP = myFontHeight / 4;
+  StaticTextWidget* s;
   WidgetArray wid;
 
   int ypos = y + myLineHeight;
 
   // Add RAM grid (with scrollbar)
   int xpos = x + _font.getStringWidth("xxxx");
-  myRamGrid = new DataGridWidget(_boss, _nfont, xpos, ypos,
-                                 16, myNumRows, 2, 8, Common::Base::Fmt::_16, true);
+  bool useScrollbar = ramsize / numrows > 16;
+  myRamGrid = new DataGridRamWidget(_boss, *this, _nfont, xpos, ypos,
+                                    16, myNumRows, 2, 8, Common::Base::Fmt::_16, useScrollbar);
   myRamGrid->setTarget(this);
-  myRamGrid->setID(kRamHexID);
+  myRamGrid->setID(kRamGridID);
   addFocusWidget(myRamGrid);
 
   // Create actions buttons to the left of the RAM grid
@@ -75,18 +78,21 @@ RamWidget::RamWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n
   by += bheight + VGAP * 6;
   mySearchButton = new ButtonWidget(boss, lfont, bx, by, bwidth, bheight,
                                     "Search" + ELLIPSIS, kSearchCmd);
+  mySearchButton->setToolTip("Search and highlight found values.");
   wid.push_back(mySearchButton);
   mySearchButton->setTarget(this);
 
   by += bheight + VGAP;
   myCompareButton = new ButtonWidget(boss, lfont, bx, by, bwidth, bheight,
                                      "Compare" + ELLIPSIS, kCmpCmd);
+  myCompareButton->setToolTip("Compare highlighted values.");
   wid.push_back(myCompareButton);
   myCompareButton->setTarget(this);
 
   by += bheight + VGAP;
   myRestartButton = new ButtonWidget(boss, lfont, bx, by, bwidth, bheight,
                                      "Reset", kRestartCmd);
+  myRestartButton->setToolTip("Reset search/compare mode.");
   wid.push_back(myRestartButton);
   myRestartButton->setTarget(this);
 
@@ -119,35 +125,43 @@ RamWidget::RamWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n
 
   // For smaller grids, make sure RAM cell detail fields are below the RESET button
   row = myNumRows < 8 ? 9 : myNumRows + 1;
-  ypos += row * myLineHeight;
+  ypos += (row - 1) * myLineHeight + VGAP * 2;
 
   // We need to define these widgets from right to left since the leftmost
   // one resizes as much as possible
 
   // Add Binary display of selected RAM cell
-  xpos = x + w - 11*myFontWidth - 22;
-  new StaticTextWidget(boss, lfont, xpos, ypos, "Bin");
-  myBinValue = new DataGridWidget(boss, nfont, xpos + 3*myFontWidth + 5, ypos-2,
+  xpos = x + w - 9.6 * myFontWidth - 9;
+  s = new StaticTextWidget(boss, lfont, xpos, ypos, "%");
+  myBinValue = new DataGridWidget(boss, nfont, s->getRight() + myFontWidth * 0.1, ypos-2,
                                   1, 1, 8, 8, Common::Base::Fmt::_2);
   myBinValue->setTarget(this);
   myBinValue->setID(kRamBinID);
 
   // Add Decimal display of selected RAM cell
-  xpos -= 7*myFontWidth + 5 + 20;
-  new StaticTextWidget(boss, lfont, xpos, ypos, "Dec");
-  myDecValue = new DataGridWidget(boss, nfont, xpos + 3*myFontWidth + 5, ypos-2,
+  xpos -= 6.5 * myFontWidth;
+  s = new StaticTextWidget(boss, lfont, xpos, ypos, "#");
+  myDecValue = new DataGridWidget(boss, nfont, s->getRight(), ypos-2,
                                   1, 1, 3, 8, Common::Base::Fmt::_10);
   myDecValue->setTarget(this);
   myDecValue->setID(kRamDecID);
 
+  // Add Hex display of selected RAM cell
+  xpos -= 4.5 * myFontWidth;
+  myHexValue = new DataGridWidget(boss, nfont, xpos, ypos - 2,
+                                  1, 1, 2, 8, Common::Base::Fmt::_16);
+  myHexValue->setTarget(this);
+  myHexValue->setID(kRamHexID);
+
+  addFocusWidget(myHexValue);
   addFocusWidget(myDecValue);
   addFocusWidget(myBinValue);
 
   // Add Label of selected RAM cell
-  int xpos_r = xpos - 20;
+  int xpos_r = xpos - myFontWidth * 1.5;
   xpos = x;
-  new StaticTextWidget(boss, lfont, xpos, ypos, "Label");
-  xpos += 5*myFontWidth + 5;
+  s = new StaticTextWidget(boss, lfont, xpos, ypos, "Label");
+  xpos = s->getRight() + myFontWidth / 2;
   myLabel = new EditTextWidget(boss, nfont, xpos, ypos-2, xpos_r-xpos,
                                myLineHeight);
   myLabel->setEditable(false, true);
@@ -184,11 +198,16 @@ void RamWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
     {
       switch(id)
       {
-        case kRamHexID:
+        case kRamGridID:
           addr  = myRamGrid->getSelectedAddr();
           value = myRamGrid->getSelectedValue();
           break;
 
+        case kRamHexID:
+          addr  = myRamGrid->getSelectedAddr();
+          value = myHexValue->getSelectedValue();
+          break;
+
         case kRamDecID:
           addr  = myRamGrid->getSelectedAddr();
           value = myDecValue->getSelectedValue();
@@ -210,6 +229,7 @@ void RamWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
       myUndoValue = oldval;
 
       myRamGrid->setValueInternal(addr - myCurrentRamBank*myPageSize, value, true);
+      myHexValue->setValueInternal(0, value, true);
       myDecValue->setValueInternal(0, value, true);
       myBinValue->setValueInternal(0, value, true);
 
@@ -222,10 +242,12 @@ void RamWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
     {
       addr  = myRamGrid->getSelectedAddr();
       value = myRamGrid->getSelectedValue();
+      bool changed = myRamGrid->getSelectedChanged();
 
       myLabel->setText(getLabel(addr));
-      myDecValue->setValueInternal(0, value, false);
-      myBinValue->setValueInternal(0, value, false);
+      myHexValue->setValueInternal(0, value, changed);
+      myDecValue->setValueInternal(0, value, changed);
+      myBinValue->setValueInternal(0, value, changed);
       break;
     }
 
@@ -288,6 +310,7 @@ void RamWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
 void RamWidget::setOpsWidget(DataGridOpsWidget* w)
 {
   myRamGrid->setOpsWidget(w);
+  myHexValue->setOpsWidget(w);
   myBinValue->setOpsWidget(w);
   myDecValue->setOpsWidget(w);
 }
@@ -296,6 +319,13 @@ void RamWidget::setOpsWidget(DataGridOpsWidget* w)
 void RamWidget::loadConfig()
 {
   fillGrid(true);
+
+  int value = myRamGrid->getSelectedValue();
+  bool changed = myRamGrid->getSelectedChanged();
+
+  myHexValue->setValueInternal(0, value, changed);
+  myDecValue->setValueInternal(0, value, changed);
+  myBinValue->setValueInternal(0, value, changed);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -321,10 +351,10 @@ void RamWidget::fillGrid(bool updateOld)
 
   // Update RAM labels
   uInt32 rport = readPort(start), page = rport & 0xf0;
-  char buf[5];  // NOLINT : convert to stringstream
-  std::snprintf(buf, 5, "%04X", rport);
-  buf[2] = buf[3] = 'x';
-  myRamStart->setLabel(buf);
+  string label = Common::Base::toString(rport, Common::Base::Fmt::_16_4);
+
+  label[2] = label[3] = 'x';
+  myRamStart->setLabel(label);
   for(uInt32 row = 0; row < myNumRows; ++row, page += 0x10)
     myRamLabels[row]->setLabel(Common::Base::toString(page>>4, Common::Base::Fmt::_16_1));
 }
@@ -339,6 +369,9 @@ void RamWidget::showInputBox(int cmd)
   myInputBox->show(x, y, dialog().surface().dstRect());
   myInputBox->setText("");
   myInputBox->setMessage("");
+  myInputBox->setToolTip(cmd == kSValEntered
+                         ? "Enter search value (leave blank for all)."
+                         : "Enter relative or absolute value\nto compare with searched values.");
   myInputBox->setFocus(0);
   myInputBox->setEmitSignal(cmd);
   myInputBox->setTitle(cmd == kSValEntered ? "Search" : "Compare");
diff --git a/src/debugger/gui/RamWidget.hxx b/src/debugger/gui/RamWidget.hxx
index 3562187fb..069086fef 100644
--- a/src/debugger/gui/RamWidget.hxx
+++ b/src/debugger/gui/RamWidget.hxx
@@ -22,6 +22,7 @@ class GuiObject;
 class ButtonWidget;
 class DataGridWidget;
 class DataGridOpsWidget;
+class DataGridRamWidget;
 class EditTextWidget;
 class StaticTextWidget;
 class InputTextDialog;
@@ -41,11 +42,12 @@ class RamWidget : public Widget, public CommandSender
     void setOpsWidget(DataGridOpsWidget* w);
     void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
 
+    virtual string getLabel(int addr) const = 0;
+
   private:
     // To be implemented by derived classes
     virtual uInt8 getValue(int addr) const = 0;
     virtual void setValue(int addr, uInt8 value) = 0;
-    virtual string getLabel(int addr) const = 0;
 
     virtual void fillList(uInt32 start, uInt32 size,
                           IntArray& alist, IntArray& vlist,
@@ -79,8 +81,10 @@ class RamWidget : public Widget, public CommandSender
       kRestartCmd  = 'RWrs',
       kSValEntered = 'RWsv',
       kCValEntered = 'RWcv',
+      kRamGridID,
       kRamHexID,
       kRamDecID,
+      kRamSignID,
       kRamBinID
     };
 
@@ -95,7 +99,8 @@ class RamWidget : public Widget, public CommandSender
     StaticTextWidget* myRamStart{nullptr};
     std::array<StaticTextWidget*, 16> myRamLabels{nullptr};
 
-    DataGridWidget* myRamGrid{nullptr};
+    DataGridRamWidget* myRamGrid{nullptr};
+    DataGridWidget* myHexValue{nullptr};
     DataGridWidget* myDecValue{nullptr};
     DataGridWidget* myBinValue{nullptr};
     EditTextWidget* myLabel{nullptr};
diff --git a/src/debugger/gui/RiotRamWidget.hxx b/src/debugger/gui/RiotRamWidget.hxx
index 53d006bb0..3e30fc3e0 100644
--- a/src/debugger/gui/RiotRamWidget.hxx
+++ b/src/debugger/gui/RiotRamWidget.hxx
@@ -36,10 +36,11 @@ class RiotRamWidget : public RamWidget
                   int x, int y, int w);
     ~RiotRamWidget() override = default;
 
+    string getLabel(int addr) const override;
+
   private:
     uInt8 getValue(int addr) const override;
     void setValue(int addr, uInt8 value) override;
-    string getLabel(int addr) const override;
 
     void fillList(uInt32 start, uInt32 size, IntArray& alist,
                   IntArray& vlist, BoolArray& changed) const override;
diff --git a/src/debugger/gui/RiotWidget.cxx b/src/debugger/gui/RiotWidget.cxx
index 43514e072..053ff1325 100644
--- a/src/debugger/gui/RiotWidget.cxx
+++ b/src/debugger/gui/RiotWidget.cxx
@@ -39,6 +39,7 @@
 #include "AmigaMouseWidget.hxx"
 #include "AtariMouseWidget.hxx"
 #include "TrakBallWidget.hxx"
+#include "QuadTariWidget.hxx"
 
 #include "RiotWidget.hxx"
 
@@ -65,11 +66,13 @@ RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& lfont,
     on.push_back("1");
   }
 
+  StringList labels;
+
 #define CREATE_IO_REGS(desc, bits, bitsID, editable)                     \
   t = new StaticTextWidget(boss, lfont, xpos, ypos+2, lwidth, fontHeight,\
-                           desc, TextAlign::Left);                        \
+                           desc);                                        \
   xpos += t->getWidth() + 5;                                             \
-  bits = new ToggleBitWidget(boss, nfont, xpos, ypos, 8, 1);             \
+  bits = new ToggleBitWidget(boss, nfont, xpos, ypos, 8, 1, 1, labels);  \
   bits->setTarget(this);                                                 \
   bits->setID(bitsID);                                                   \
   if(editable) addFocusWidget(bits); else bits->setEditable(false);      \
@@ -77,6 +80,7 @@ RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& lfont,
   bits->setList(off, on);
 
   // SWCHA bits in 'poke' mode
+  labels.clear();
   CREATE_IO_REGS("SWCHA(W)", mySWCHAWriteBits, kSWCHABitsID, true)
   col = xpos + 20;  // remember this for adding widgets to the second column
 
@@ -86,10 +90,20 @@ RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& lfont,
 
   // SWCHA bits in 'peek' mode
   xpos = 10;  ypos += lineHeight + 5;
+  labels.clear();
+  labels.push_back("P0 right");
+  labels.push_back("P0 left");
+  labels.push_back("P0 down");
+  labels.push_back("P0 up");
+  labels.push_back("P1 right");
+  labels.push_back("P1 left");
+  labels.push_back("P1 down");
+  labels.push_back("P1 up");
   CREATE_IO_REGS("SWCHA(R)", mySWCHAReadBits, kSWCHARBitsID, true)
 
   // SWCHB bits in 'poke' mode
   xpos = 10;  ypos += 2 * lineHeight;
+  labels.clear();
   CREATE_IO_REGS("SWCHB(W)", mySWCHBWriteBits, kSWCHBBitsID, true)
 
   // SWBCNT bits
@@ -98,7 +112,16 @@ RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& lfont,
 
   // SWCHB bits in 'peek' mode
   xpos = 10;  ypos += lineHeight + 5;
-  CREATE_IO_REGS("SWCHB(R)", mySWCHBReadBits, 0, false)
+  labels.clear();
+  labels.push_back("P1 difficulty");
+  labels.push_back("P0 difficulty");
+  labels.push_back("");
+  labels.push_back("");
+  labels.push_back("Color/B+W");
+  labels.push_back("");
+  labels.push_back("Select");
+  labels.push_back("Reset");
+  CREATE_IO_REGS("SWCHB(R)", mySWCHBReadBits, kSWCHBRBitsID, true)
 
   // Timer registers (R/W)
   static constexpr std::array<const char*, 4> writeNames = {
@@ -118,21 +141,21 @@ RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& lfont,
 
   // Timer registers (RO)
   static constexpr std::array<const char*, 5> readNames = {
-    "INTIM", "TIMINT", "Total Clks", "INTIM Clks", "Divider"
+    "INTIM", "TIMINT", "Total Clks", "INTIM Clks", "Divider  #"
   };
   xpos = 10;  ypos += myTimWrite->getHeight() + lineHeight / 2;
   for(int row = 0; row < 5; ++row)
   {
-    t = new StaticTextWidget(boss, lfont, xpos, ypos + row*lineHeight + 2,
-                             10*fontWidth, fontHeight, readNames[row], TextAlign::Left);
+    t = new StaticTextWidget(boss, lfont, xpos, ypos + row * lineHeight + 2,
+                             readNames[row]);
   }
   xpos += t->getWidth() + 5;
-  myTimRead = new DataGridWidget(boss, nfont, xpos, ypos, 1, 4, 8, 32, Common::Base::Fmt::_16);
+  myTimRead = new DataGridWidget(boss, nfont, xpos, ypos, 1, 4, 4, 30, Common::Base::Fmt::_16);
   myTimRead->setTarget(this);
   myTimRead->setEditable(false);
 
   ypos += myTimRead->getHeight() - 1;
-  myTimDivider = new DataGridWidget(boss, nfont, xpos, ypos, 1, 1, 4, 32, Common::Base::Fmt::_10_4);
+  myTimDivider = new DataGridWidget(boss, nfont, xpos, ypos, 1, 1, 4, 12, Common::Base::Fmt::_10_4);
   myTimDivider->setTarget(this);
   myTimDivider->setEditable(false);
 
@@ -140,9 +163,11 @@ RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& lfont,
   xpos = col;  ypos = 10;
   myLeftControl = addControlWidget(boss, lfont, xpos, ypos,
       instance().console().leftController());
+  addToFocusList(myLeftControl->getFocusList());
   xpos += myLeftControl->getWidth() + 15;
   myRightControl = addControlWidget(boss, lfont, xpos, ypos,
       instance().console().rightController());
+  addToFocusList(myRightControl->getFocusList());
 
   // TIA INPTx registers (R), left port
   static constexpr std::array<const char*, 3> contLeftReadNames = {
@@ -417,6 +442,17 @@ void RiotWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
           rport.setPin(Controller::DigitalPin::Four,  value & 0b00001000);
           break;
         }
+        case kSWCHBRBitsID:
+        {
+          value = Debugger::get_bits(mySWCHBReadBits->getState());
+
+          riot.reset( value & 0b00000001);
+          riot.select(value & 0b00000010);
+          riot.tvType(value & 0b00001000);
+          riot.diffP0(value & 0b01000000);
+          riot.diffP1(value & 0b10000000);
+          break;
+        }
         default:
           break;
       }
@@ -480,12 +516,15 @@ ControllerWidget* RiotWidget::addControlWidget(GuiObject* boss, const GUI::Font&
       return new KeyboardWidget(boss, font, x, y, controller);
 //    case Controller::Type::KidVid:      // TODO - implement this
 //    case Controller::Type::MindLink:    // TODO - implement this
+//    case Controller::Type::Lightgun:    // TODO - implement this
     case Controller::Type::Paddles:
       return new PaddleWidget(boss, font, x, y, controller);
     case Controller::Type::SaveKey:
       return new SaveKeyWidget(boss, font, x, y, controller);
     case Controller::Type::TrakBall:
       return new TrakBallWidget(boss, font, x, y, controller);
+    case Controller::Type::QuadTari:
+      return new QuadTariWidget(boss, font, x, y, controller);
     default:
       return new NullControlWidget(boss, font, x, y, controller);
   }
diff --git a/src/debugger/gui/RiotWidget.hxx b/src/debugger/gui/RiotWidget.hxx
index fdfd699ef..dfbe16ce2 100644
--- a/src/debugger/gui/RiotWidget.hxx
+++ b/src/debugger/gui/RiotWidget.hxx
@@ -76,7 +76,7 @@ class RiotWidget : public Widget, public CommandSender
       kTim1TID, kTim8TID, kTim64TID, kTim1024TID, kTimWriteID,
       kSWCHABitsID, kSWACNTBitsID, kSWCHBBitsID, kSWBCNTBitsID,
       kP0DiffChanged, kP1DiffChanged, kTVTypeChanged, kSelectID, kResetID,
-      kSWCHARBitsID, kPauseID
+      kSWCHARBitsID, kSWCHBRBitsID, kPauseID
     };
 
   private:
diff --git a/src/debugger/gui/RomListSettings.cxx b/src/debugger/gui/RomListSettings.cxx
index 9c3baf3d2..93b555631 100644
--- a/src/debugger/gui/RomListSettings.cxx
+++ b/src/debugger/gui/RomListSettings.cxx
@@ -100,7 +100,7 @@ void RomListSettings::show(uInt32 x, uInt32 y, const Common::Rect& bossRect, int
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void RomListSettings::center()
+void RomListSettings::setPosition()
 {
   // First set position according to original coordinates
   surface().setDstPos(_xorig, _yorig);
diff --git a/src/debugger/gui/RomListSettings.hxx b/src/debugger/gui/RomListSettings.hxx
index 0845dd8ab..a589b0334 100644
--- a/src/debugger/gui/RomListSettings.hxx
+++ b/src/debugger/gui/RomListSettings.hxx
@@ -38,8 +38,8 @@ class RomListSettings : public Dialog, public CommandSender
         ('data' will be the currently selected line number in RomListWidget) */
     void show(uInt32 x, uInt32 y, const Common::Rect& bossRect, int data = -1);
 
-    /** This dialog uses its own positioning, so we override Dialog::center() */
-    void center() override;
+    /** This dialog uses its own positioning, so we override Dialog::setPosition() */
+    void setPosition() override;
 
   private:
     uInt32 _xorig{0}, _yorig{0};
diff --git a/src/debugger/gui/RomListWidget.cxx b/src/debugger/gui/RomListWidget.cxx
index 6e450e334..9f8b9d589 100644
--- a/src/debugger/gui/RomListWidget.cxx
+++ b/src/debugger/gui/RomListWidget.cxx
@@ -20,6 +20,8 @@
 #include "Debugger.hxx"
 #include "DiStella.hxx"
 #include "Widget.hxx"
+#include "Dialog.hxx"
+#include "ToolTip.hxx"
 #include "StellaKeys.hxx"
 #include "FBSurface.hxx"
 #include "Font.hxx"
@@ -39,8 +41,11 @@ RomListWidget::RomListWidget(GuiObject* boss, const GUI::Font& lfont,
   _textcolor = kTextColor;
   _textcolorhi = kTextColor;
 
+  _editMode = false;
+  _dyText = -1; // fixes the vertical position of selected text
+
   _cols = w / _fontWidth;
-  _rows = h / _fontHeight;
+  _rows = h / _lineHeight;
 
   // Set real dimensions
   _w = w - ScrollBarWidget::scrollBarWidth(_font);
@@ -67,8 +72,8 @@ RomListWidget::RomListWidget(GuiObject* boss, const GUI::Font& lfont,
 
   // rowheight is determined by largest item on a line,
   // possibly meaning that number of rows will change
-  _fontHeight = std::max(_fontHeight, CheckboxWidget::boxSize(_font));
-  _rows = h / _fontHeight;
+  _lineHeight = std::max(_lineHeight, CheckboxWidget::boxSize(_font));
+  _rows = h / _lineHeight;
 
   // Create a CheckboxWidget for each row in the list
   for(int i = 0; i < _rows; ++i)
@@ -79,7 +84,7 @@ RomListWidget::RomListWidget(GuiObject* boss, const GUI::Font& lfont,
     t->setID(i);
     t->setFill(CheckboxWidget::FillType::Circle);
     t->setTextColor(kTextColorEm);
-    ypos += _fontHeight;
+    ypos += _lineHeight;
 
     myCheckList.push_back(t);
   }
@@ -175,7 +180,7 @@ void RomListWidget::setHighlighted(int item)
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 int RomListWidget::findItem(int x, int y) const
 {
-  return (y - 1) / _fontHeight + _currentPos;
+  return (y - 1) / _lineHeight + _currentPos;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -235,12 +240,14 @@ void RomListWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount)
   if (!isEnabled())
     return;
 
+  resetSelection();
   // Grab right mouse button for context menu, left for selection/edit mode
   if(b == MouseButton::RIGHT)
   {
     // Set selected and add menu at current x,y mouse location
     _selectedItem = findItem(x, y);
     scrollToSelected();
+    dialog().tooltip().hide();
     myMenu->show(x + getAbsX(), y + getAbsY(),
                  dialog().surface().dstRect(), _selectedItem);
   }
@@ -281,20 +288,6 @@ void RomListWidget::handleMouseWheel(int x, int y, int direction)
   myScrollBar->handleMouseWheel(x, y, direction);
 }
 
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void RomListWidget::handleMouseEntered()
-{
-  setFlags(Widget::FLAG_HILITED);
-  setDirty();
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void RomListWidget::handleMouseLeft()
-{
-  clearFlags(Widget::FLAG_HILITED);
-  setDirty();
-}
-
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 bool RomListWidget::handleText(char text)
 {
@@ -453,14 +446,86 @@ void RomListWidget::lostFocusWidget()
   abortEditMode();
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Common::Point RomListWidget::getToolTipIndex(const Common::Point& pos) const
+{
+  const Common::Rect& r = getEditRect();
+  const int col = (pos.x - r.x() - getAbsX()) / _font.getMaxCharWidth();
+  const int row = (pos.y - getAbsY()) / _lineHeight;
+
+  if(col < 0 || col >= 8
+     || row < 0 || row + _currentPos >= int(myDisasm->list.size()))
+    return Common::Point(-1, -1);
+  else
+    return Common::Point(col, row + _currentPos);
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+string RomListWidget::getToolTip(const Common::Point& pos) const
+{
+  const Common::Point& idx = getToolTipIndex(pos);
+
+  if(idx.y < 0)
+    return EmptyString;
+
+  const string bytes = myDisasm->list[idx.y].bytes;
+
+  if(static_cast<Int32>(bytes.length()) < idx.x + 1)
+    return EmptyString;
+
+  Int32 val;
+  if(bytes.length() == 8 && bytes[2] != ' ')
+  {
+    // Binary value
+    val = static_cast<Int32>(stol(bytes, nullptr, 2));
+  }
+  else
+  {
+    // 1..3 hex values
+    if(idx.x == 2)
+      // Skip gap after first byte
+      return EmptyString;
+
+    string valStr;
+
+    if(idx.x < 2 || bytes.length() < 8)
+      // 1 or 2 hex bytes, get one hex byte
+      valStr = bytes.substr((idx.x / 3) * 3, 2);
+    else
+      // 3 hex bytes, get two rightmost hex bytes
+      valStr = bytes.substr(6, 2) + bytes.substr(3, 2);
+
+    val = static_cast<Int32>(stol(valStr, nullptr, 16));
+  }
+  ostringstream buf;
+
+  buf << _toolTipText
+    << "$" << Common::Base::toString(val, Common::Base::Fmt::_16)
+    << " = #" << val;
+  if(val < 0x100)
+  {
+    if(val >= 0x80)
+      buf << '/' << -(0x100 - val);
+    buf << " = %" << Common::Base::toString(val, Common::Base::Fmt::_2);
+  }
+
+  return buf.str();
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool RomListWidget::changedToolTip(const Common::Point& oldPos,
+                                   const Common::Point& newPos) const
+{
+  return getToolTipIndex(oldPos) != getToolTipIndex(newPos);
+}
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void RomListWidget::drawWidget(bool hilite)
 {
   FBSurface& s = _boss->dialog().surface();
-  bool onTop = _boss->dialog().isOnTop();
   const CartDebug::DisassemblyList& dlist = myDisasm->list;
   int i, pos, xpos, ypos, len = int(dlist.size());
-  ColorId textColor = onTop ? kTextColor : kColor;
+  ColorId textColor = kTextColor;
 
   const Common::Rect& r = getEditRect();
   const Common::Rect& l = getLineRect();
@@ -479,75 +544,76 @@ void RomListWidget::drawWidget(bool hilite)
     codeDisasmW = actualWidth;
 
   xpos = _x + CheckboxWidget::boxSize(_font) + 10;  ypos = _y + 2;
-  for (i = 0, pos = _currentPos; i < _rows && pos < len; i++, pos++, ypos += _fontHeight)
+  for(i = 0, pos = _currentPos; i < _rows && pos < len; i++, pos++, ypos += _lineHeight)
   {
     ColorId bytesColor = textColor;
 
-    // Draw checkboxes for correct lines (takes scrolling into account)
+    // Mark checkboxes dirty for correct lines (takes scrolling into account)
     myCheckList[i]->setState(instance().debugger().
                              checkBreakPoint(dlist[pos].address,
                              instance().debugger().cartDebug().getBank(dlist[pos].address)));
-
     myCheckList[i]->setDirty();
+    // All checkboxes have to be redrawn because RomListWidget clears its whole area
+    // Also draw immediately, because chain order is not deterministic
     myCheckList[i]->draw();
 
     // Draw highlighted item in a frame
-    if (_highlightedItem == pos)
-      s.frameRect(_x + l.x() - 3, ypos - 1, _w - l.x(), _fontHeight, onTop ? kWidColorHi : kBGColorLo);
+    if(_highlightedItem == pos)
+      s.frameRect(_x + l.x() - 3, ypos - 1, _w - l.x(), _lineHeight, kWidColorHi);
 
     // Draw the selected item inverted, on a highlighted background.
     if(_selectedItem == pos && _hasFocus)
     {
       if(!_editMode)
       {
-        s.fillRect(_x + r.x() - 3, ypos - 1, r.w(), _fontHeight, kTextColorHi);
+        s.fillRect(_x + r.x() - 3, ypos - 1, r.w(), _lineHeight, kTextColorHi);
         bytesColor = kTextColorInv;
       }
       else
-        s.frameRect(_x + r.x() - 3, ypos - 1, r.w(), _fontHeight, kWidColorHi);
+        s.frameRect(_x + r.x() - 3, ypos - 1, r.w(), _lineHeight, kWidColorHi);
     }
 
     // Draw labels
     s.drawString(_font, dlist[pos].label, xpos, ypos, _labelWidth,
-                 dlist[pos].hllabel ? textColor : kColor);
+                  dlist[pos].hllabel ? textColor : kColor);
 
     // Bytes are only editable if they represent code, graphics, or accessible data
     // Otherwise, the disassembly should get all remaining space
-    if(dlist[pos].type & (Device::CODE|Device::GFX|Device::PGFX|
-       Device::COL|Device::PCOL|Device::BCOL|Device::DATA))
+    if(dlist[pos].type & (Device::CODE | Device::GFX | Device::PGFX |
+       Device::COL | Device::PCOL | Device::BCOL | Device::DATA))
     {
       if(dlist[pos].type == Device::CODE)
       {
         // Draw mnemonic
         s.drawString(_font, dlist[pos].disasm.substr(0, 7), xpos + _labelWidth, ypos,
-                     7 * _fontWidth, textColor);
+                      7 * _fontWidth, textColor);
         // Draw operand
-        if (dlist[pos].disasm.length() > 8)
+        if(dlist[pos].disasm.length() > 8)
           s.drawString(_font, dlist[pos].disasm.substr(8), xpos + _labelWidth + 7 * _fontWidth, ypos,
-                       codeDisasmW - 7 * _fontWidth, textColor);
+                        codeDisasmW - 7 * _fontWidth, textColor);
         // Draw cycle count
         s.drawString(_font, dlist[pos].ccount, xpos + _labelWidth + codeDisasmW, ypos,
-                     cycleCountW, textColor);
+                      cycleCountW, textColor);
       }
       else
       {
         // Draw disassembly only
         s.drawString(_font, dlist[pos].disasm, xpos + _labelWidth, ypos,
-                     noCodeDisasmW - 4, kTextColor);
+                      noCodeDisasmW - 4, kTextColor);
       }
 
       // Draw separator
-      s.vLine(_x + r.x() - 7, ypos, ypos + _fontHeight - 1, kColor);
+      s.vLine(_x + r.x() - 7, ypos, ypos + _lineHeight - 1, kColor);
 
       // Draw bytes
       {
-        if (_selectedItem == pos && _editMode)
+        if(_selectedItem == pos && _editMode)
         {
           adjustOffset();
           s.drawString(_font, editString(), _x + r.x(), ypos, r.w(), textColor,
-                       TextAlign::Left, -_editScrollOffset, false);
+                        TextAlign::Left, -_editScrollOffset, false);
 
-          drawCaret();
+          drawCaretSelection();
         }
         else
         {
@@ -559,7 +625,7 @@ void RomListWidget::drawWidget(bool hilite)
     {
       // Draw disassembly, giving it all remaining horizontal space
       s.drawString(_font, dlist[pos].disasm, xpos + _labelWidth, ypos,
-                   noTypeDisasmW, textColor);
+                    noTypeDisasmW, textColor);
     }
   }
 }
@@ -567,20 +633,20 @@ void RomListWidget::drawWidget(bool hilite)
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Common::Rect RomListWidget::getLineRect() const
 {
-  const int yoffset = std::max(0, (_selectedItem - _currentPos) * _fontHeight),
+  const int yoffset = std::max(0, (_selectedItem - _currentPos) * _lineHeight),
             xoffset = CheckboxWidget::boxSize(_font) + 10;
 
   return Common::Rect(2 + xoffset, 1 + yoffset,
-                      _w - (xoffset - 15), _fontHeight + yoffset);
+                      _w - (xoffset - 15), _lineHeight + yoffset);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Common::Rect RomListWidget::getEditRect() const
 {
-  const int yoffset = std::max(0, (_selectedItem - _currentPos) * _fontHeight);
+  const int yoffset = std::max(0, (_selectedItem - _currentPos) * _lineHeight);
 
-  return Common::Rect(2 + _w - _bytesWidth, 1 + yoffset,
-                      _w, _fontHeight + yoffset);
+  return Common::Rect(2 + _w - _bytesWidth, 1 + yoffset + 1,
+                      _w, _lineHeight + yoffset + 1);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -593,6 +659,7 @@ void RomListWidget::startEditMode()
       return;
 
     _editMode = true;
+    dialog().tooltip().hide();
     switch(myDisasm->list[_selectedItem].type)
     {
       case Device::GFX:
diff --git a/src/debugger/gui/RomListWidget.hxx b/src/debugger/gui/RomListWidget.hxx
index 40abb0adf..9baa9350a 100644
--- a/src/debugger/gui/RomListWidget.hxx
+++ b/src/debugger/gui/RomListWidget.hxx
@@ -56,12 +56,13 @@ class RomListWidget : public EditableWidget
     void setSelected(int item);
     void setHighlighted(int item);
 
+    string getToolTip(const Common::Point& pos) const override;
+    bool changedToolTip(const Common::Point& oldPos, const Common::Point& newPos) const override;
+
   protected:
     void handleMouseDown(int x, int y, MouseButton b, int clickCount) override;
     void handleMouseUp(int x, int y, MouseButton b, int clickCount) override;
     void handleMouseWheel(int x, int y, int direction) override;
-    void handleMouseEntered() override;
-    void handleMouseLeft() override;
     bool handleText(char text) override;
     bool handleKeyDown(StellaKey key, StellaMod mod) override;
     bool handleKeyUp(StellaKey key, StellaMod mod) override;
@@ -79,11 +80,15 @@ class RomListWidget : public EditableWidget
     void endEditMode() override;
     void abortEditMode() override;
     void lostFocusWidget() override;
+
+    bool hasToolTip() const override { return true; }
+
     void scrollToSelected()    { scrollToCurrent(_selectedItem);    }
     void scrollToHighlighted() { scrollToCurrent(_highlightedItem); }
 
   private:
     void scrollToCurrent(int item);
+    Common::Point getToolTipIndex(const Common::Point& pos) const;
 
   private:
     unique_ptr<RomListSettings> myMenu;
@@ -96,7 +101,6 @@ class RomListWidget : public EditableWidget
     int  _currentPos{0}; // position of first line in visible window
     int  _selectedItem{-1};
     int  _highlightedItem{-1};
-    bool _editMode{false};
     StellaKey _currentKeyDown{KBDK_UNKNOWN};
     Common::Base::Fmt _base{Common::Base::Fmt::_DEFAULT};  // base used during editing
 
diff --git a/src/debugger/gui/RomWidget.cxx b/src/debugger/gui/RomWidget.cxx
index 9b387d69f..0454ef16d 100644
--- a/src/debugger/gui/RomWidget.cxx
+++ b/src/debugger/gui/RomWidget.cxx
@@ -90,10 +90,6 @@ void RomWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
     case RomListWidget::kBPointChangedCmd:
       // 'data' is the line in the disassemblylist to be accessed
       toggleBreak(data);
-      // Refresh the romlist, since the breakpoint may not have
-      // actually changed
-      myRomList->setDirty();
-      myRomList->draw();
       break;
 
     case RomListWidget::kRomChangedCmd:
@@ -199,7 +195,7 @@ void RomWidget::runtoPC(int disasm_line)
     ostringstream command;
     command << "runtopc #" << address;
     string msg = instance().debugger().run(command.str());
-    instance().frameBuffer().showMessage(msg);
+    instance().frameBuffer().showTextMessage(msg);
   }
 }
 
diff --git a/src/debugger/gui/SaveKeyWidget.cxx b/src/debugger/gui/SaveKeyWidget.cxx
index eb6602ad3..92c58329e 100644
--- a/src/debugger/gui/SaveKeyWidget.cxx
+++ b/src/debugger/gui/SaveKeyWidget.cxx
@@ -20,10 +20,10 @@
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 SaveKeyWidget::SaveKeyWidget(GuiObject* boss, const GUI::Font& font,
-                             int x, int y, Controller& controller)
+                             int x, int y, Controller& controller, bool embedded)
   : FlashWidget(boss, font, x, y, controller)
 {
-  init(boss, font, x, y);
+  init(boss, font, x, y, embedded);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/debugger/gui/SaveKeyWidget.hxx b/src/debugger/gui/SaveKeyWidget.hxx
index 3a646f2d4..e3e6b5213 100644
--- a/src/debugger/gui/SaveKeyWidget.hxx
+++ b/src/debugger/gui/SaveKeyWidget.hxx
@@ -26,7 +26,7 @@ class SaveKeyWidget : public FlashWidget
 {
   public:
     SaveKeyWidget(GuiObject* boss, const GUI::Font& font, int x, int y,
-                  Controller& controller);
+                  Controller& controller, bool embedded = false);
     ~SaveKeyWidget() override = default;
 
   private:
diff --git a/src/debugger/gui/TiaInfoWidget.cxx b/src/debugger/gui/TiaInfoWidget.cxx
index 21681d2c0..fe2ce6d9b 100644
--- a/src/debugger/gui/TiaInfoWidget.cxx
+++ b/src/debugger/gui/TiaInfoWidget.cxx
@@ -19,6 +19,7 @@
 #include "Font.hxx"
 #include "OSystem.hxx"
 #include "Debugger.hxx"
+#include "RiotDebug.hxx"
 #include "TIADebug.hxx"
 #include "TIA.hxx"
 #include "Widget.hxx"
@@ -34,87 +35,110 @@ TiaInfoWidget::TiaInfoWidget(GuiObject* boss, const GUI::Font& lfont,
   : Widget(boss, lfont, x, y, 16, 16),
     CommandSender(boss)
 {
-  bool longstr = 11 + 32 * lfont.getMaxCharWidth() + 9
+  const int VGAP = lfont.getLineHeight() / 4;
+  const int VBORDER = 5 + 1;
+  const int COLUMN_GAP = _fontWidth * 1.25;
+  bool longstr = lfont.getStringWidth("Frame Cycls12345") + _fontWidth * 0.5
+    + COLUMN_GAP + lfont.getStringWidth("Scanline262262")
     + EditTextWidget::calcWidth(lfont) * 3 <= max_w;
-  const int VGAP = 5;
-
-  x += 11;
   const int lineHeight = lfont.getLineHeight();
-  int xpos = x, ypos = y + 10;
-  int lwidth = lfont.getStringWidth(longstr ? "Frame Cycle " : "F. Cycle ");
+  int xpos = x, ypos = y + VBORDER;
+  int lwidth = lfont.getStringWidth(longstr ? "Frame Cycls" : "F. Cycls");
+  int lwidth8 = lwidth - lfont.getMaxCharWidth() * 3;
+  int lwidthR = lfont.getStringWidth(longstr ? "Frame Cnt." : "Frame   ");
   int fwidth = EditTextWidget::calcWidth(lfont, 5);
-  int twidth = EditTextWidget::calcWidth(lfont, 8);
+  const int twidth = EditTextWidget::calcWidth(lfont, 8);
+  const int LGAP = (max_w - lwidth - EditTextWidget::calcWidth(lfont, 5)
+    - lwidthR - EditTextWidget::calcWidth(lfont, 5)) / 4;
 
-  // Add frame info
-  // 1st column
-  new StaticTextWidget(boss, lfont, xpos, ypos, lwidth, lineHeight,
-                       longstr ? "Frame Count " : "Frame ",
-                       TextAlign::Left);
-  xpos += lwidth;
-  myFrameCount = new EditTextWidget(boss, nfont, xpos, ypos-1, fwidth, lineHeight, "");
-  myFrameCount->setEditable(false, true);
+  lwidth += LGAP;
+  lwidth8 += LGAP;
+  lwidthR += LGAP;
 
-  xpos = x;  ypos += lineHeight + VGAP;
-  new StaticTextWidget(boss, lfont, xpos, ypos, lwidth, lineHeight,
-                       longstr ? "Frame Cycle " : "F. Cycle ",
-                       TextAlign::Left);
-  xpos += lwidth;
-  myFrameCycles = new EditTextWidget(boss, nfont, xpos, ypos-1, fwidth, lineHeight, "");
+  // Left column
+  // Left: Frame Cycle
+  xpos = x;
+  new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Frame Cycls" : "F. Cycls");
+  myFrameCycles = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight);
+  myFrameCycles->setToolTip("CPU cycles executed this frame.");
   myFrameCycles->setEditable(false, true);
 
-  xpos = x;  ypos += lineHeight + VGAP;
-  new StaticTextWidget(boss, lfont, xpos, ypos, lwidth, lineHeight,
-                       "Total ", TextAlign::Left);
-  xpos += lfont.getStringWidth("Total ");
-  myTotalCycles = new EditTextWidget(boss, nfont, xpos, ypos - 1, twidth, lineHeight, "");
+  // Left: WSync Cycles
+  ypos += lineHeight + VGAP;
+  new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "WSync Cycls" : "WSync C.");
+  myWSyncCylces = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight);
+  myWSyncCylces->setToolTip("CPU cycles used for WSYNC this frame.");
+  myWSyncCylces->setEditable(false, true);
+
+  // Left: Timer Cycles
+  ypos += lineHeight + VGAP;
+  new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Timer Cycls" : "Timer C.");
+  myTimerCylces = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight);
+  myTimerCylces->setToolTip("CPU cycles roughly used for INTIM reads this frame.");
+  myTimerCylces->setEditable(false, true);
+
+  // Left: Total Cycles
+  ypos += lineHeight + VGAP;
+  new StaticTextWidget(boss, lfont, xpos, ypos + 1, "Total");
+  myTotalCycles = new EditTextWidget(boss, nfont, xpos + lwidth8, ypos - 1, twidth, lineHeight);
   myTotalCycles->setEditable(false, true);
 
-  xpos = x;  ypos += lineHeight + VGAP;
-  new StaticTextWidget(boss, lfont, xpos, ypos, lwidth, lineHeight,
-                       "Delta ", TextAlign::Left);
-  xpos = x + lfont.getStringWidth("Delta ");
-  myDeltaCycles = new EditTextWidget(boss, nfont, xpos, ypos - 1, twidth, lineHeight, "");
+  // Left: Delta Cycles
+  ypos += lineHeight + VGAP;
+  new StaticTextWidget(boss, lfont, xpos, ypos + 1, "Delta");
+  myDeltaCycles = new EditTextWidget(boss, nfont, xpos + lwidth8, ypos - 1, twidth, lineHeight);
+  myDeltaCycles->setToolTip("CPU cycles executed since last debug break.");
   myDeltaCycles->setEditable(false, true);
 
-  // 2nd column
-  xpos = x + lwidth + myFrameCycles->getWidth() + 9;  ypos = y + 10;
-  lwidth = lfont.getStringWidth(longstr ? "Color Clock " : "Pixel Pos ");
+  // Right column
+  xpos = x + max_w - lwidthR - EditTextWidget::calcWidth(lfont, 5); ypos = y + VBORDER;
+  //xpos = myDeltaCycles->getRight() + LGAP * 2; ypos = y + VBORDER;
+
+  // Right: Frame Count
+  new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Frame Cnt." : "Frame");
+  myFrameCount = new EditTextWidget(boss, nfont, xpos + lwidthR, ypos - 1, fwidth, lineHeight);
+  myFrameCount->setToolTip("Total number of frames executed this session.");
+  myFrameCount->setEditable(false, true);
+
+  lwidth = lfont.getStringWidth(longstr ? "Color Clock " : "Pixel Pos ") + LGAP;
   fwidth = EditTextWidget::calcWidth(lfont, 3);
 
-  new StaticTextWidget(boss, lfont, xpos, ypos, longstr ? "Scanline" : "Scn Ln");
-  myScanlineCountLast = new EditTextWidget(boss, nfont, xpos+lwidth, ypos-1, fwidth,
-                                       lineHeight, "");
+  // Right: Scanline
+  ypos += lineHeight + VGAP;
+  new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Scanline" : "Scn Ln");
+  myScanlineCountLast = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight);
+  myScanlineCountLast->setToolTip("Number of scanlines of last frame.");
   myScanlineCountLast->setEditable(false, true);
   myScanlineCount = new EditTextWidget(boss, nfont,
-        xpos+lwidth - myScanlineCountLast->getWidth() - 2, ypos-1, fwidth,
-        lineHeight, "");
+                                       xpos + lwidth - myScanlineCountLast->getWidth() - 2, ypos - 1,
+                                       fwidth, lineHeight);
+  myScanlineCount->setToolTip("Current scanline of this frame.");
   myScanlineCount->setEditable(false, true);
 
+  // Right: Scan Cycle
   ypos += lineHeight + VGAP;
-  new StaticTextWidget(boss, lfont, xpos, ypos, lwidth, lineHeight,
-                       longstr ? "Scan Cycle " : "Scn Cycle", TextAlign::Left);
-  myScanlineCycles = new EditTextWidget(boss, nfont, xpos+lwidth, ypos-1, fwidth,
-                                        lineHeight, "");
+  new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Scan Cycle" : "Scn Cycle");
+  myScanlineCycles = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight);
+  myScanlineCycles->setToolTip("CPU cycles in current scanline.");
   myScanlineCycles->setEditable(false, true);
 
+  // Right: Pixel Pos
   ypos += lineHeight + VGAP;
-  new StaticTextWidget(boss, lfont, xpos, ypos, lwidth, lineHeight,
-                       "Pixel Pos ", TextAlign::Left);
-  myPixelPosition = new EditTextWidget(boss, nfont, xpos+lwidth, ypos-1, fwidth,
-                                       lineHeight, "");
+  new StaticTextWidget(boss, lfont, xpos, ypos + 1, "Pixel Pos");
+  myPixelPosition = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight);
+  myPixelPosition->setToolTip("Pixel position in current scanline.");
   myPixelPosition->setEditable(false, true);
 
+  // Right: Color Clock
   ypos += lineHeight + VGAP;
-  new StaticTextWidget(boss, lfont, xpos, ypos, lwidth, lineHeight,
-                       longstr ? "Color Clock " : "Color Clk ", TextAlign::Left);
-
-  myColorClocks = new EditTextWidget(boss, nfont, xpos+lwidth, ypos-1, fwidth,
-                                     lineHeight, "");
+  new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Color Clock" : "Color Clk");
+  myColorClocks = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight);
+  myColorClocks->setToolTip("Color clocks in current scanline.");
   myColorClocks->setEditable(false, true);
 
   // Calculate actual dimensions
-  _w = myColorClocks->getAbsX() + myColorClocks->getWidth() - x;
-  _h = ypos + lineHeight;
+  _w = myColorClocks->getRight() - x;
+  _h = myColorClocks->getBottom();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -134,6 +158,8 @@ void TiaInfoWidget::loadConfig()
   Debugger& dbg = instance().debugger();
   TIADebug& tia = dbg.tiaDebug();
   const TiaState& oldTia = static_cast<const TiaState&>(tia.getOldState());
+  RiotDebug& riot = dbg.riotDebug();
+  const RiotState& oldRiot = static_cast<const RiotState&>(riot.getOldState());
 
   myFrameCount->setText(Common::Base::toString(tia.frameCount(), Common::Base::Fmt::_10_5),
                         tia.frameCount() != oldTia.info[0]);
@@ -143,7 +169,10 @@ void TiaInfoWidget::loadConfig()
   uInt64 total = tia.cyclesLo() + (uInt64(tia.cyclesHi()) << 32);
   uInt64 totalOld = oldTia.info[2] + (uInt64(oldTia.info[3]) << 32);
   myTotalCycles->setText(Common::Base::toString(uInt32(total) / 1000000, Common::Base::Fmt::_10_6) + "e6",
-                         total != totalOld);
+                         total / 1000000 != totalOld / 1000000);
+  myTotalCycles->setToolTip("Total CPU cycles (E notation) executed for this session ("
+                            + std::to_string(total) + ").");
+
   uInt64 delta = total - totalOld;
   myDeltaCycles->setText(Common::Base::toString(uInt32(delta), Common::Base::Fmt::_10_8)); // no coloring
 
@@ -159,4 +188,10 @@ void TiaInfoWidget::loadConfig()
                            clk != oldTia.info[6]);
   myColorClocks->setText(Common::Base::toString(clk, Common::Base::Fmt::_10),
                          clk != oldTia.info[6]);
+
+  myWSyncCylces->setText(Common::Base::toString(tia.frameWsyncCycles(), Common::Base::Fmt::_10_5),
+                         tia.frameWsyncCycles() != oldTia.info[7]);
+
+  myTimerCylces->setText(Common::Base::toString(riot.timReadCycles(), Common::Base::Fmt::_10_5),
+                         riot.timReadCycles() != oldRiot.timReadCycles);
 }
diff --git a/src/debugger/gui/TiaInfoWidget.hxx b/src/debugger/gui/TiaInfoWidget.hxx
index 2f7796162..3b21a222b 100644
--- a/src/debugger/gui/TiaInfoWidget.hxx
+++ b/src/debugger/gui/TiaInfoWidget.hxx
@@ -38,12 +38,14 @@ class TiaInfoWidget : public Widget, public CommandSender
   private:
     EditTextWidget* myFrameCount{nullptr};
     EditTextWidget* myFrameCycles{nullptr};
-    EditTextWidget* myTotalCycles{ nullptr };
+    EditTextWidget* myTotalCycles{nullptr};
+    EditTextWidget* myDeltaCycles{nullptr};
+    EditTextWidget* myWSyncCylces{nullptr};
+    EditTextWidget* myTimerCylces{nullptr};
 
     EditTextWidget* myScanlineCount{nullptr};
     EditTextWidget* myScanlineCountLast{nullptr};
     EditTextWidget* myScanlineCycles{nullptr};
-    EditTextWidget* myDeltaCycles{ nullptr };
     EditTextWidget* myPixelPosition{nullptr};
     EditTextWidget* myColorClocks{nullptr};
 
diff --git a/src/debugger/gui/TiaOutputWidget.cxx b/src/debugger/gui/TiaOutputWidget.cxx
index 01d6d094b..d101fa674 100644
--- a/src/debugger/gui/TiaOutputWidget.cxx
+++ b/src/debugger/gui/TiaOutputWidget.cxx
@@ -22,6 +22,7 @@
 #include "FBSurface.hxx"
 #include "Widget.hxx"
 #include "GuiObject.hxx"
+#include "Dialog.hxx"
 #include "ContextMenu.hxx"
 #include "TiaZoomWidget.hxx"
 #include "Debugger.hxx"
@@ -55,6 +56,7 @@ TiaOutputWidget::TiaOutputWidget(GuiObject* boss, const GUI::Font& font,
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void TiaOutputWidget::loadConfig()
 {
+  setEnabled(true);
   setDirty();
 }
 
@@ -92,10 +94,10 @@ void TiaOutputWidget::saveSnapshot(int execDepth, const string& execPrefix)
     message = e.what();
   }
   if (execDepth == 0) {
-    instance().frameBuffer().showMessage(message);
+    instance().frameBuffer().showTextMessage(message);
   }
 #else
-  instance().frameBuffer().showMessage("PNG image saving not supported");
+  instance().frameBuffer().showTextMessage("PNG image saving not supported");
 #endif
 }
 
@@ -108,7 +110,7 @@ void TiaOutputWidget::handleMouseDown(int x, int y, MouseButton b, int clickCoun
   else if(b == MouseButton::RIGHT)
   {
     myClickX = x;
-    myClickY = y;
+    myClickY = y - 1;
 
     // Add menu at current x,y mouse location
     myMenu->show(x + getAbsX(), y + getAbsY(), dialog().surface().dstRect());
@@ -135,7 +137,7 @@ void TiaOutputWidget::handleCommand(CommandSender* sender, int cmd, int data, in
       {
         command << "scanline #" << lines;
         string message = instance().debugger().parser().run(command.str());
-        instance().frameBuffer().showMessage(message);
+        instance().frameBuffer().showTextMessage(message);
       }
     }
     else if(rmb == "bp")
@@ -144,7 +146,7 @@ void TiaOutputWidget::handleCommand(CommandSender* sender, int cmd, int data, in
       int scanline = myClickY + startLine;
       command << "breakif _scan==#" << scanline;
       string message = instance().debugger().parser().run(command.str());
-      instance().frameBuffer().showMessage(message);
+      instance().frameBuffer().showTextMessage(message);
     }
     else if(rmb == "zoom")
     {
@@ -158,6 +160,52 @@ void TiaOutputWidget::handleCommand(CommandSender* sender, int cmd, int data, in
   }
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Common::Point TiaOutputWidget::getToolTipIndex(const Common::Point& pos) const
+{
+  const Int32 width = instance().console().tia().width();
+  const Int32 height = instance().console().tia().height();
+  const int col = (pos.x - 1 - getAbsX()) >> 1;
+  const int row = pos.y - 1 - getAbsY();
+
+  if(col < 0 || col >= width || row < 0 || row >= height)
+    return Common::Point(-1, -1);
+  else
+    return Common::Point(col, row);
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+string TiaOutputWidget::getToolTip(const Common::Point& pos) const
+{
+  const Common::Point& idx = getToolTipIndex(pos);
+
+  if(idx.x < 0)
+    return EmptyString;
+
+  const uInt32 startLine = instance().console().tia().startLine();
+  const uInt32 height = instance().console().tia().height();
+  // limit to 274 lines (PAL default without scaling)
+  const uInt32 yStart = height <= FrameManager::Metrics::baseHeightPAL
+    ? 0 : (height - FrameManager::Metrics::baseHeightPAL) >> 1;
+  const Int32 i = idx.x + (yStart + idx.y) * instance().console().tia().width();
+  uInt8* tiaOutputBuffer = instance().console().tia().outputBuffer();
+  ostringstream buf;
+
+  buf << _toolTipText
+    << "X: #" << idx.x
+    << "\nY: #" << idx.y + startLine
+    << "\nC: $" << Common::Base::toString(tiaOutputBuffer[i], Common::Base::Fmt::_16);
+
+  return buf.str();
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool TiaOutputWidget::changedToolTip(const Common::Point& oldPos,
+                                     const Common::Point& newPos) const
+{
+  return getToolTipIndex(oldPos) != getToolTipIndex(newPos);
+}
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void TiaOutputWidget::drawWidget(bool hilite)
 {
diff --git a/src/debugger/gui/TiaOutputWidget.hxx b/src/debugger/gui/TiaOutputWidget.hxx
index c7bfd26f6..cc465266a 100644
--- a/src/debugger/gui/TiaOutputWidget.hxx
+++ b/src/debugger/gui/TiaOutputWidget.hxx
@@ -47,6 +47,13 @@ class TiaOutputWidget : public Widget, public CommandSender
     bool handleKeyDown(StellaKey key, StellaMod mod) override;
     bool handleKeyUp(StellaKey key, StellaMod mod) override;
 */
+    string getToolTip(const Common::Point& pos) const override;
+    bool changedToolTip(const Common::Point& oldPos, const Common::Point& newPos) const override;
+
+  protected:
+    bool hasToolTip() const override { return true; }
+    Common::Point getToolTipIndex(const Common::Point& pos) const;
+
   private:
     unique_ptr<ContextMenu> myMenu;
     TiaZoomWidget* myZoom{nullptr};
diff --git a/src/debugger/gui/TiaWidget.cxx b/src/debugger/gui/TiaWidget.cxx
index 5f6ba56ab..f6bc43e6e 100644
--- a/src/debugger/gui/TiaWidget.cxx
+++ b/src/debugger/gui/TiaWidget.cxx
@@ -563,7 +563,7 @@ TiaWidget::TiaWidget(GuiObject* boss, const GUI::Font& lfont,
   new StaticTextWidget(boss, lfont, xpos, ypos+2, 2*fontWidth, fontHeight,
                        "PF", TextAlign::Left);
   xpos += 2*fontWidth + 5;
-  myPF[0] = new TogglePixelWidget(boss, nfont, xpos, ypos+1, 4, 1);
+  myPF[0] = new TogglePixelWidget(boss, nfont, xpos, ypos+1, 4, 1, 4);
   myPF[0]->setTarget(this);
   myPF[0]->setID(kPF0ID);
   addFocusWidget(myPF[0]);
@@ -1043,8 +1043,8 @@ void TiaWidget::loadConfig()
     myGRP0Old->setColor(kBGColorLo);
     myGRP0Old->setCrossed(true);
   }
-  myGRP0->setIntState(state.gr[TiaState::P0], false);
-  myGRP0Old->setIntState(state.gr[TiaState::P0+2], false);
+  myGRP0->setIntState(state.gr[TiaState::P0], state.ref[TiaState::P0]);
+  myGRP0Old->setIntState(state.gr[TiaState::P0+2], state.ref[TiaState::P0]);
 
   // posP0
   myPosP0->setList(0, state.pos[TiaState::P0],
@@ -1079,8 +1079,8 @@ void TiaWidget::loadConfig()
     myGRP1Old->setColor(kBGColorLo);
     myGRP1Old->setCrossed(true);
   }
-  myGRP1->setIntState(state.gr[TiaState::P1], false);
-  myGRP1Old->setIntState(state.gr[TiaState::P1+2], false);
+  myGRP1->setIntState(state.gr[TiaState::P1], state.ref[TiaState::P1]);
+  myGRP1Old->setIntState(state.gr[TiaState::P1+2], state.ref[TiaState::P1]);
 
   // posP1
   myPosP1->setList(0, state.pos[TiaState::P1],
diff --git a/src/debugger/gui/TiaZoomWidget.cxx b/src/debugger/gui/TiaZoomWidget.cxx
index e4553f361..af8e468dd 100644
--- a/src/debugger/gui/TiaZoomWidget.cxx
+++ b/src/debugger/gui/TiaZoomWidget.cxx
@@ -26,6 +26,8 @@
 #include "FBSurface.hxx"
 #include "Widget.hxx"
 #include "GuiObject.hxx"
+#include "Dialog.hxx"
+#include "ToolTip.hxx"
 #include "ContextMenu.hxx"
 #include "FrameManager.hxx"
 #include "TiaZoomWidget.hxx"
@@ -115,7 +117,7 @@ void TiaZoomWidget::recalc()
 void TiaZoomWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount)
 {
   myClickX = x;
-  myClickY = y;
+  myClickY = y - 1;
 
   // Button 1 is for 'drag'/movement of the image
   // Button 2 is for context menu
@@ -141,9 +143,11 @@ void TiaZoomWidget::handleMouseUp(int x, int y, MouseButton b, int clickCount)
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void TiaZoomWidget::handleMouseWheel(int x, int y, int direction)
 {
+  dialog().tooltip().hide();
+
   // zoom towards mouse position
   myClickX = x;
-  myClickY = y;
+  myClickY = y - 1;
 
   if(direction > 0)
   {
@@ -162,6 +166,7 @@ void TiaZoomWidget::handleMouseMoved(int x, int y)
 {
   if(myMouseMoving)
   {
+    y--;
     int diffx = x + myOffXLo - myClickX;
     int diffy = y + myOffYLo - myClickY;
 
@@ -178,19 +183,11 @@ void TiaZoomWidget::handleMouseMoved(int x, int y)
   }
 }
 
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void TiaZoomWidget::handleMouseEntered()
-{
-  setFlags(Widget::FLAG_HILITED);
-  setDirty();
-}
-
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void TiaZoomWidget::handleMouseLeft()
 {
-  clearFlags(Widget::FLAG_HILITED);
-  setDirty();
   myMouseMoving = false;
+  Widget::handleMouseLeft();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -262,7 +259,7 @@ void TiaZoomWidget::handleCommand(CommandSender* sender, int cmd, int data, int
       {
         command << "scanline #" << lines;
         string message = instance().debugger().parser().run(command.str());
-        instance().frameBuffer().showMessage(message);
+        instance().frameBuffer().showTextMessage(message);
       }
     }
     else if(rmb == "bp")
@@ -271,7 +268,7 @@ void TiaZoomWidget::handleCommand(CommandSender* sender, int cmd, int data, int
       int scanline = myClickY / myZoomLevel + myOffY + startLine;
       command << "breakif _scan==#" << scanline;
       string message = instance().debugger().parser().run(command.str());
-      instance().frameBuffer().showMessage(message);
+      instance().frameBuffer().showTextMessage(message);
     }
     else
     {
@@ -282,6 +279,48 @@ void TiaZoomWidget::handleCommand(CommandSender* sender, int cmd, int data, int
   }
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Common::Point TiaZoomWidget::getToolTipIndex(const Common::Point& pos) const
+{
+  const Int32 width = instance().console().tia().width() * 2;
+  const Int32 height = instance().console().tia().height();
+  const int col = (pos.x - 1 - getAbsX()) / (myZoomLevel << 1) + (myOffX >> 1);
+  const int row = (pos.y - 1 - getAbsY()) / myZoomLevel + myOffY;
+
+  if(col < 0 || col >= width || row < 0 || row >= height)
+    return Common::Point(-1, -1);
+  else
+    return Common::Point(col, row);
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+string TiaZoomWidget::getToolTip(const Common::Point& pos) const
+{
+  const Common::Point& idx = getToolTipIndex(pos);
+
+  if(idx.x < 0)
+    return EmptyString;
+
+  const Int32 i = idx.x + idx.y * instance().console().tia().width();
+  const uInt32 startLine = instance().console().tia().startLine();
+  uInt8* tiaOutputBuffer = instance().console().tia().outputBuffer();
+  ostringstream buf;
+
+  buf << _toolTipText
+    << "X: #" << idx.x
+    << "\nY: #" << idx.y + startLine
+    << "\nC: $" << Common::Base::toString(tiaOutputBuffer[i], Common::Base::Fmt::_16);
+
+  return buf.str();
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool TiaZoomWidget::changedToolTip(const Common::Point& oldPos,
+                                     const Common::Point& newPos) const
+{
+  return getToolTipIndex(oldPos) != getToolTipIndex(newPos);
+}
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void TiaZoomWidget::drawWidget(bool hilite)
 {
diff --git a/src/debugger/gui/TiaZoomWidget.hxx b/src/debugger/gui/TiaZoomWidget.hxx
index d4d3a9835..1cc53068f 100644
--- a/src/debugger/gui/TiaZoomWidget.hxx
+++ b/src/debugger/gui/TiaZoomWidget.hxx
@@ -27,15 +27,21 @@ class ContextMenu;
 class TiaZoomWidget : public Widget, public CommandSender
 {
   public:
+    using Widget::setPos;
+
     TiaZoomWidget(GuiObject *boss, const GUI::Font& font,
                   int x, int y, int w, int h);
     ~TiaZoomWidget() override = default;
 
     void loadConfig() override;
-    void setPos(int x, int y);
+    void setPos(int x, int y) override;
+
+    string getToolTip(const Common::Point& pos) const override;
+    bool changedToolTip(const Common::Point& oldPos, const Common::Point& newPos) const override;
 
   protected:
-    void handleMouseEntered() override;
+    bool hasToolTip() const override { return true; }
+    Common::Point getToolTipIndex(const Common::Point& pos) const;
 
   private:
     void zoom(int level);
diff --git a/src/debugger/gui/ToggleBitWidget.cxx b/src/debugger/gui/ToggleBitWidget.cxx
index 479f31225..629e58c57 100644
--- a/src/debugger/gui/ToggleBitWidget.cxx
+++ b/src/debugger/gui/ToggleBitWidget.cxx
@@ -25,8 +25,10 @@
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 ToggleBitWidget::ToggleBitWidget(GuiObject* boss, const GUI::Font& font,
-                                 int x, int y, int cols, int rows, int colchars)
-  : ToggleWidget(boss, font, x, y, cols, rows, 1)
+                                 int x, int y, int cols, int rows, int colchars,
+                                 const StringList& labels)
+  : ToggleWidget(boss, font, x, y, cols, rows),
+    _labelList(labels)
 {
   _rowHeight = font.getLineHeight();
   _colWidth  = colchars * font.getMaxCharWidth() + 8;
@@ -47,6 +49,13 @@ ToggleBitWidget::ToggleBitWidget(GuiObject* boss, const GUI::Font& font,
   _h = _rowHeight * rows + 1;
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ToggleBitWidget::ToggleBitWidget(GuiObject* boss, const GUI::Font& font,
+                                 int x, int y, int cols, int rows, int colchars)
+  : ToggleBitWidget(boss, font, x, y, cols, rows, colchars, StringList())
+{
+}
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void ToggleBitWidget::setList(const StringList& off, const StringList& on)
 {
@@ -61,12 +70,35 @@ void ToggleBitWidget::setList(const StringList& off, const StringList& on)
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void ToggleBitWidget::setState(const BoolArray& state, const BoolArray& changed)
 {
+  if(!std::equal(_changedList.begin(), _changedList.end(),
+     changed.begin(), changed.end()))
+    setDirty();
+
   _stateList.clear();
   _stateList = state;
   _changedList.clear();
   _changedList = changed;
+}
 
-  setDirty();
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+string ToggleBitWidget::getToolTip(const Common::Point& pos) const
+{
+  const Common::Point& idx = getToolTipIndex(pos);
+
+  if(idx.y < 0)
+    return EmptyString;
+
+  const string tip = ToggleWidget::getToolTip(pos);
+
+  if(idx.x < static_cast<int>(_labelList.size()))
+  {
+    const string label = _labelList[idx.x];
+
+    if(!label.empty())
+      return tip + "\n" + label;
+  }
+  return tip;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -74,7 +106,6 @@ void ToggleBitWidget::drawWidget(bool hilite)
 {
 //cerr << "ToggleBitWidget::drawWidget\n";
   FBSurface& s = dialog().surface();
-  bool onTop = _boss->dialog().isOnTop();
   int row, col;
   string buffer;
 
@@ -116,18 +147,16 @@ void ToggleBitWidget::drawWidget(bool hilite)
         // Highlight changes
         if(_changedList[pos])
         {
-          s.fillRect(x - 3, y - 1, _colWidth-1, _rowHeight-1,
-                     onTop ? kDbgChangedColor : _bgcolorlo);
-          s.drawString(_font, buffer, x, y, _colWidth, onTop ? kDbgChangedTextColor : kColor);
+          s.fillRect(x - 3, y - 1, _colWidth-1, _rowHeight-1, kDbgChangedColor);
+          s.drawString(_font, buffer, x, y, _colWidth, kDbgChangedTextColor);
         }
         else
-          s.drawString(_font, buffer, x, y, _colWidth,
-                       onTop ? textColor : kColor);
+          s.drawString(_font, buffer, x, y, _colWidth, textColor);
       }
       else
       {
-        s.fillRect(x - 3, y - 1, _colWidth-1, _rowHeight-1, onTop ? kBGColorHi : kDlgColor);
-        s.drawString(_font, buffer, x, y, _colWidth, onTop ? kTextColor : kColor);
+        s.fillRect(x - 3, y - 1, _colWidth-1, _rowHeight-1, kBGColorHi);
+        s.drawString(_font, buffer, x, y, _colWidth, kTextColor);
       }
     }
   }
diff --git a/src/debugger/gui/ToggleBitWidget.hxx b/src/debugger/gui/ToggleBitWidget.hxx
index 6d5505030..707aea1cc 100644
--- a/src/debugger/gui/ToggleBitWidget.hxx
+++ b/src/debugger/gui/ToggleBitWidget.hxx
@@ -26,17 +26,23 @@ class ToggleBitWidget : public ToggleWidget
   public:
     ToggleBitWidget(GuiObject* boss, const GUI::Font& font,
                     int x, int y, int cols, int rows, int colchars = 1);
+    ToggleBitWidget(GuiObject* boss, const GUI::Font& font,
+                    int x, int y, int cols, int rows, int colchars,
+                    const StringList& labels);
     ~ToggleBitWidget() override = default;
 
     void setList(const StringList& off, const StringList& on);
     void setState(const BoolArray& state, const BoolArray& changed);
 
+    string getToolTip(const Common::Point& pos) const override;
+
   protected:
     void drawWidget(bool hilite) override;
 
   protected:
     StringList _offList;
     StringList _onList;
+    StringList _labelList;
 
   private:
     // Following constructors and assignment operators not supported
diff --git a/src/debugger/gui/TogglePixelWidget.cxx b/src/debugger/gui/TogglePixelWidget.cxx
index fdc1609bc..c26600130 100644
--- a/src/debugger/gui/TogglePixelWidget.cxx
+++ b/src/debugger/gui/TogglePixelWidget.cxx
@@ -24,8 +24,9 @@
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 TogglePixelWidget::TogglePixelWidget(GuiObject* boss, const GUI::Font& font,
-                                     int x, int y, int cols, int rows)
-  : ToggleWidget(boss, font, x, y, cols, rows, 1)
+                                     int x, int y, int cols, int rows,
+                                     int shiftBits)
+  : ToggleWidget(boss, font, x, y, cols, rows, shiftBits)
 {
   _rowHeight = _colWidth = font.getLineHeight();
 
@@ -50,15 +51,18 @@ void TogglePixelWidget::setState(const BoolArray& state)
     for(int col = 0; col < _cols; col++)
     {
       int pos = row * _cols + col;
+      bool changed = _stateList[pos] != state[pos];
 
-       _changedList[pos] = _stateList[pos] != state[pos];
+      if(_changedList[pos] != changed)
+      {
+        _changedList[pos] = changed;
+        setDirty();
+      }
     }
   }
 
   _stateList.clear();
   _stateList = state;
-
-  setDirty();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -112,12 +116,21 @@ int TogglePixelWidget::getIntState()
   return value;
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void TogglePixelWidget::setCrossed(bool enable)
+{
+  if(_crossBits != enable)
+  {
+    _crossBits = enable;
+    setDirty();
+  }
+}
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void TogglePixelWidget::drawWidget(bool hilite)
 {
 //cerr << "TogglePixelWidget::drawWidget\n";
   FBSurface& s = dialog().surface();
-  bool onTop = _boss->dialog().isOnTop();
   int row, col;
 
   s.frameRect(_x, _y, _w, _h, hilite && isEnabled() && isEditable() ? kWidColorHi : kColor);
@@ -145,7 +158,7 @@ void TogglePixelWidget::drawWidget(bool hilite)
 
       // Either draw the pixel in given color, or erase (show background)
       s.fillRect(x - 3, y - 1, _colWidth-1, _rowHeight-1,
-                 _stateList[pos] ? onTop ? _pixelColor : kColor : onTop ? _backgroundColor : kBGColorLo);
+                 _stateList[pos] ? _pixelColor : _backgroundColor);
       if (_changedList[pos])
         s.frameRect(x - 3, y - 1, _colWidth - 1, _rowHeight - 1, kDbgChangedColor);
     }
diff --git a/src/debugger/gui/TogglePixelWidget.hxx b/src/debugger/gui/TogglePixelWidget.hxx
index 6177cac45..503404c6f 100644
--- a/src/debugger/gui/TogglePixelWidget.hxx
+++ b/src/debugger/gui/TogglePixelWidget.hxx
@@ -25,7 +25,8 @@ class TogglePixelWidget : public ToggleWidget
 {
   public:
     TogglePixelWidget(GuiObject* boss, const GUI::Font& font,
-                      int x, int y, int cols, int rows);
+                      int x, int y, int cols = 1, int rows = 1,
+                      int shiftBits = 0);
     ~TogglePixelWidget() override = default;
 
     void setColor(ColorId color) { _pixelColor = color; }
@@ -35,14 +36,13 @@ class TogglePixelWidget : public ToggleWidget
 
     void setState(const BoolArray& state);
 
-    void setIntState(int value, bool swap);
+    void setIntState(int value, bool swap = false);
     int  getIntState();
 
-    void setCrossed(bool enable) { _crossBits = enable; }
+    void setCrossed(bool enable);
 
   private:
     ColorId _pixelColor{kNone}, _backgroundColor{kDlgColor};
-    bool _swapBits{false};
     bool _crossBits{false};
 
   private:
diff --git a/src/debugger/gui/ToggleWidget.cxx b/src/debugger/gui/ToggleWidget.cxx
index 02ba10146..adb33e118 100644
--- a/src/debugger/gui/ToggleWidget.cxx
+++ b/src/debugger/gui/ToggleWidget.cxx
@@ -16,44 +16,26 @@
 //============================================================================
 
 #include "OSystem.hxx"
+#include "Base.hxx"
 #include "StellaKeys.hxx"
 #include "Widget.hxx"
+#include "Dialog.hxx"
+#include "ToolTip.hxx"
 #include "ToggleWidget.hxx"
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 ToggleWidget::ToggleWidget(GuiObject* boss, const GUI::Font& font,
-                           int x, int y, int cols, int rows,
-                           int clicksToChange)
+                           int x, int y, int cols, int rows, int shiftBits)
   : Widget(boss, font, x, y, 16, 16),
     CommandSender(boss),
     _rows(rows),
     _cols(cols),
-    _currentRow(0),
-    _currentCol(0),
-    _rowHeight(0),
-    _colWidth(0),
-    _selectedItem(0),
-    _clicksToChange(clicksToChange),
-    _editable(true)
+    _shiftBits(shiftBits)
 {
   _flags = Widget::FLAG_ENABLED | Widget::FLAG_CLEARBG | Widget::FLAG_RETAIN_FOCUS |
            Widget::FLAG_WANTS_RAWDATA;
 }
 
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void ToggleWidget::handleMouseEntered()
-{
-  setFlags(Widget::FLAG_HILITED);
-  setDirty();
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void ToggleWidget::handleMouseLeft()
-{
-  clearFlags(Widget::FLAG_HILITED);
-  setDirty();
-}
-
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void ToggleWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount)
 {
@@ -71,6 +53,7 @@ void ToggleWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount)
     _selectedItem = newSelectedItem;
     _currentRow = _selectedItem / _cols;
     _currentCol = _selectedItem - (_currentRow * _cols);
+    dialog().tooltip().hide();
     setDirty();
   }
 }
@@ -83,7 +66,7 @@ void ToggleWidget::handleMouseUp(int x, int y, MouseButton b, int clickCount)
 
   // If this was a double click and the mouse is still over the selected item,
   // send the double click command
-  if (clickCount == _clicksToChange && (_selectedItem == findItem(x, y)))
+  if (clickCount == 1 && (_selectedItem == findItem(x, y)))
   {
     _stateList[_selectedItem] = !_stateList[_selectedItem];
     _changedList[_selectedItem] = !_changedList[_selectedItem];
@@ -202,6 +185,7 @@ bool ToggleWidget::handleKeyDown(StellaKey key, StellaMod mod)
       _stateList[_selectedItem] = !_stateList[_selectedItem];
       _changedList[_selectedItem] = !_changedList[_selectedItem];
       sendCommand(ToggleWidget::kItemDataChangedCmd, _selectedItem, _id);
+      dialog().tooltip().hide();
     }
 
     setDirty();
@@ -223,3 +207,56 @@ void ToggleWidget::handleCommand(CommandSender* sender, int cmd,
     }
   }
 }
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Common::Point ToggleWidget::getToolTipIndex(const Common::Point& pos) const
+{
+  const int col = (pos.x - getAbsX()) / _colWidth;
+  const int row = (pos.y - getAbsY()) / _rowHeight;
+
+  if(row >= 0 && row < _rows && col >= 0 && col < _cols)
+    return Common::Point(col, row);
+  else
+    return Common::Point(-1, -1);
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+string ToggleWidget::getToolTip(const Common::Point& pos) const
+{
+  const int idx = getToolTipIndex(pos).y * _cols;
+
+  if(idx < 0)
+    return EmptyString;
+
+  Int32 val = 0;
+  ostringstream buf;
+
+  if(_swapBits)
+    for(int col = _cols - 1; col >= 0; --col)
+    {
+      val <<= 1;
+      val += _stateList[idx + col];
+    }
+  else
+    for(int col = 0; col < _cols; ++col)
+    {
+      val <<= 1;
+      val += _stateList[idx + col];
+    }
+  val <<= _shiftBits;
+
+  buf << _toolTipText
+    << "$" << Common::Base::toString(val, Common::Base::Fmt::_16)
+    << " = #" << val;
+  if(val < 0x100)
+    buf << " = %" << Common::Base::toString(val, Common::Base::Fmt::_2);
+
+  return buf.str();
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool ToggleWidget::changedToolTip(const Common::Point& oldPos,
+                                  const Common::Point& newPos) const
+{
+  return getToolTipIndex(oldPos) != getToolTipIndex(newPos);
+}
diff --git a/src/debugger/gui/ToggleWidget.hxx b/src/debugger/gui/ToggleWidget.hxx
index 67777a13a..ee70f6233 100644
--- a/src/debugger/gui/ToggleWidget.hxx
+++ b/src/debugger/gui/ToggleWidget.hxx
@@ -33,8 +33,8 @@ class ToggleWidget : public Widget, public CommandSender
 
   public:
     ToggleWidget(GuiObject* boss, const GUI::Font& font,
-                 int x, int y, int cols, int rows,
-                 int clicksToChange = 2);
+                 int x, int y, int cols = 1, int rows = 1,
+                 int shiftBits = 0);
     ~ToggleWidget() override = default;
 
     const BoolArray& getState()    { return _stateList; }
@@ -46,18 +46,24 @@ class ToggleWidget : public Widget, public CommandSender
     void setEditable(bool editable) { _editable = editable; }
     bool isEditable() const { return _editable; }
 
-  protected:
+    string getToolTip(const Common::Point& pos) const override;
+    bool changedToolTip(const Common::Point& oldPos, const Common::Point& newPos) const override;
 
   protected:
-    int  _rows;
-    int  _cols;
-    int  _currentRow;
-    int  _currentCol;
-    int  _rowHeight;   // explicitly set in child classes
-    int  _colWidth;    // explicitly set in child classes
-    int  _selectedItem;
-    int  _clicksToChange;  // number of clicks to register a change
-    bool _editable;
+    bool hasToolTip() const override { return true; }
+    Common::Point getToolTipIndex(const Common::Point& pos) const;
+
+  protected:
+    int  _rows{0};
+    int  _cols{0};
+    int  _currentRow{0};
+    int  _currentCol{0};
+    int  _rowHeight{0};   // explicitly set in child classes
+    int  _colWidth{0};    // explicitly set in child classes
+    int  _selectedItem{0};
+    bool _editable{true};
+    bool _swapBits{false};
+    int  _shiftBits{0}; // shift bits for tooltip display
 
     BoolArray  _stateList;
     BoolArray  _changedList;
@@ -68,8 +74,6 @@ class ToggleWidget : public Widget, public CommandSender
 
     void handleMouseDown(int x, int y, MouseButton b, int clickCount) override;
     void handleMouseUp(int x, int y, MouseButton b, int clickCount) override;
-    void handleMouseEntered() override;
-    void handleMouseLeft() override;
     bool handleKeyDown(StellaKey key, StellaMod mod) override;
     void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
 
diff --git a/src/debugger/gui/module.mk b/src/debugger/gui/module.mk
index d992ae85a..0a985e71b 100644
--- a/src/debugger/gui/module.mk
+++ b/src/debugger/gui/module.mk
@@ -1,89 +1,91 @@
 MODULE := src/debugger/gui
 
 MODULE_OBJS := \
-	src/debugger/gui/AmigaMouseWidget.o \
-	src/debugger/gui/AtariMouseWidget.o \
-	src/debugger/gui/AtariVoxWidget.o \
-	src/debugger/gui/AudioWidget.o \
-	src/debugger/gui/BoosterWidget.o \
-	src/debugger/gui/Cart0840Widget.o \
-	src/debugger/gui/Cart2KWidget.o \
-	src/debugger/gui/Cart3EPlusWidget.o \
-	src/debugger/gui/Cart3EWidget.o \
-	src/debugger/gui/Cart3FWidget.o \
-	src/debugger/gui/Cart4A50Widget.o \
-	src/debugger/gui/Cart4KSCWidget.o \
-	src/debugger/gui/Cart4KWidget.o \
-	src/debugger/gui/CartARWidget.o \
-	src/debugger/gui/CartBFSCWidget.o \
-	src/debugger/gui/CartBFWidget.o \
-	src/debugger/gui/CartBUSWidget.o \
-	src/debugger/gui/CartCDFWidget.o \
-	src/debugger/gui/CartCDFInfoWidget.o \
-	src/debugger/gui/CartCMWidget.o \
-	src/debugger/gui/CartCTYWidget.o \
-	src/debugger/gui/CartCVWidget.o \
-	src/debugger/gui/CartDFSCWidget.o \
-	src/debugger/gui/CartDFWidget.o \
-	src/debugger/gui/CartDPCPlusWidget.o \
-	src/debugger/gui/CartDPCWidget.o \
-	src/debugger/gui/CartE0Widget.o \
-	src/debugger/gui/CartEnhancedWidget.o \
-	src/debugger/gui/CartMNetworkWidget.o \
-	src/debugger/gui/CartE7Widget.o \
-	src/debugger/gui/CartE78KWidget.o \
-	src/debugger/gui/CartEFSCWidget.o \
-	src/debugger/gui/CartEFWidget.o \
-	src/debugger/gui/CartF0Widget.o \
-	src/debugger/gui/CartF4SCWidget.o \
-	src/debugger/gui/CartF4Widget.o \
-	src/debugger/gui/CartF6SCWidget.o \
-	src/debugger/gui/CartF6Widget.o \
-	src/debugger/gui/CartF8SCWidget.o \
-	src/debugger/gui/CartF8Widget.o \
-	src/debugger/gui/CartFA2Widget.o \
-	src/debugger/gui/CartFAWidget.o \
-	src/debugger/gui/CartFCWidget.o \
-	src/debugger/gui/CartFEWidget.o \
-	src/debugger/gui/CartMDMWidget.o \
-	src/debugger/gui/CartRamWidget.o \
-	src/debugger/gui/CartSBWidget.o \
-	src/debugger/gui/CartTVBoyWidget.o \
-	src/debugger/gui/CartUAWidget.o \
-	src/debugger/gui/CartWDWidget.o \
-	src/debugger/gui/CartX07Widget.o \
-	src/debugger/gui/CartDebugWidget.o \
-	src/debugger/gui/CpuWidget.o \
-	src/debugger/gui/DataGridOpsWidget.o \
-	src/debugger/gui/DataGridWidget.o \
-	src/debugger/gui/DebuggerDialog.o \
-	src/debugger/gui/DelayQueueWidget.o \
-	src/debugger/gui/DrivingWidget.o \
-	src/debugger/gui/FlashWidget.o \
-	src/debugger/gui/GenesisWidget.o \
-	src/debugger/gui/JoystickWidget.o \
-	src/debugger/gui/KeyboardWidget.o \
-	src/debugger/gui/PaddleWidget.o \
-	src/debugger/gui/PointingDeviceWidget.o \
-	src/debugger/gui/PromptWidget.o \
-	src/debugger/gui/RamWidget.o \
-	src/debugger/gui/RiotRamWidget.o \
-	src/debugger/gui/RiotWidget.o \
-	src/debugger/gui/RomListSettings.o \
-	src/debugger/gui/RomListWidget.o \
-	src/debugger/gui/RomWidget.o \
-	src/debugger/gui/SaveKeyWidget.o \
-	src/debugger/gui/TiaInfoWidget.o \
-	src/debugger/gui/TiaOutputWidget.o \
-	src/debugger/gui/TiaWidget.o \
-	src/debugger/gui/TiaZoomWidget.o \
-	src/debugger/gui/ToggleBitWidget.o \
-	src/debugger/gui/TogglePixelWidget.o \
-	src/debugger/gui/ToggleWidget.o \
-	src/debugger/gui/TrakBallWidget.o
+        src/debugger/gui/AmigaMouseWidget.o \
+        src/debugger/gui/AtariMouseWidget.o \
+        src/debugger/gui/AtariVoxWidget.o \
+        src/debugger/gui/AudioWidget.o \
+        src/debugger/gui/BoosterWidget.o \
+        src/debugger/gui/Cart0840Widget.o \
+        src/debugger/gui/Cart2KWidget.o \
+        src/debugger/gui/Cart3EPlusWidget.o \
+        src/debugger/gui/Cart3EWidget.o \
+        src/debugger/gui/Cart3FWidget.o \
+        src/debugger/gui/Cart4A50Widget.o \
+        src/debugger/gui/Cart4KSCWidget.o \
+        src/debugger/gui/Cart4KWidget.o \
+        src/debugger/gui/CartARWidget.o \
+        src/debugger/gui/CartBFSCWidget.o \
+        src/debugger/gui/CartBFWidget.o \
+        src/debugger/gui/CartBUSWidget.o \
+        src/debugger/gui/CartCDFWidget.o \
+        src/debugger/gui/CartCDFInfoWidget.o \
+        src/debugger/gui/CartCMWidget.o \
+        src/debugger/gui/CartCTYWidget.o \
+        src/debugger/gui/CartCVWidget.o \
+        src/debugger/gui/CartDFSCWidget.o \
+        src/debugger/gui/CartDFWidget.o \
+        src/debugger/gui/CartDPCPlusWidget.o \
+        src/debugger/gui/CartDPCWidget.o \
+        src/debugger/gui/CartE0Widget.o \
+        src/debugger/gui/CartEnhancedWidget.o \
+        src/debugger/gui/CartMNetworkWidget.o \
+        src/debugger/gui/CartE7Widget.o \
+        src/debugger/gui/CartE78KWidget.o \
+        src/debugger/gui/CartEFSCWidget.o \
+        src/debugger/gui/CartEFWidget.o \
+        src/debugger/gui/CartF0Widget.o \
+        src/debugger/gui/CartF4SCWidget.o \
+        src/debugger/gui/CartF4Widget.o \
+        src/debugger/gui/CartF6SCWidget.o \
+        src/debugger/gui/CartF6Widget.o \
+        src/debugger/gui/CartF8SCWidget.o \
+        src/debugger/gui/CartF8Widget.o \
+        src/debugger/gui/CartFA2Widget.o \
+        src/debugger/gui/CartFAWidget.o \
+        src/debugger/gui/CartFCWidget.o \
+        src/debugger/gui/CartFEWidget.o \
+        src/debugger/gui/CartMDMWidget.o \
+        src/debugger/gui/CartRamWidget.o \
+        src/debugger/gui/CartSBWidget.o \
+        src/debugger/gui/CartTVBoyWidget.o \
+        src/debugger/gui/CartUAWidget.o \
+        src/debugger/gui/CartWDWidget.o \
+        src/debugger/gui/CartX07Widget.o \
+        src/debugger/gui/CartDebugWidget.o \
+        src/debugger/gui/CpuWidget.o \
+        src/debugger/gui/DataGridOpsWidget.o \
+	src/debugger/gui/DataGridRamWidget.o \
+        src/debugger/gui/DataGridWidget.o \
+        src/debugger/gui/DebuggerDialog.o \
+        src/debugger/gui/DelayQueueWidget.o \
+        src/debugger/gui/DrivingWidget.o \
+        src/debugger/gui/FlashWidget.o \
+        src/debugger/gui/GenesisWidget.o \
+        src/debugger/gui/JoystickWidget.o \
+        src/debugger/gui/KeyboardWidget.o \
+        src/debugger/gui/PaddleWidget.o \
+        src/debugger/gui/PointingDeviceWidget.o \
+        src/debugger/gui/PromptWidget.o \
+        src/debugger/gui/QuadTariWidget.o \
+        src/debugger/gui/RamWidget.o \
+        src/debugger/gui/RiotRamWidget.o \
+        src/debugger/gui/RiotWidget.o \
+        src/debugger/gui/RomListSettings.o \
+        src/debugger/gui/RomListWidget.o \
+        src/debugger/gui/RomWidget.o \
+        src/debugger/gui/SaveKeyWidget.o \
+        src/debugger/gui/TiaInfoWidget.o \
+        src/debugger/gui/TiaOutputWidget.o \
+        src/debugger/gui/TiaWidget.o \
+        src/debugger/gui/TiaZoomWidget.o \
+        src/debugger/gui/ToggleBitWidget.o \
+        src/debugger/gui/TogglePixelWidget.o \
+        src/debugger/gui/ToggleWidget.o \
+        src/debugger/gui/TrakBallWidget.o
 
 MODULE_DIRS += \
-	src/debugger/gui
+        src/debugger/gui
 
 # Include common rules
 include $(srcdir)/common.rules
diff --git a/src/emucore/Cart3EPlus.cxx b/src/emucore/Cart3EPlus.cxx
index 2233b0d71..41f3ef21b 100644
--- a/src/emucore/Cart3EPlus.cxx
+++ b/src/emucore/Cart3EPlus.cxx
@@ -59,28 +59,3 @@ bool Cartridge3EPlus::checkSwitchBank(uInt16 address, uInt8 value)
   }
   return false;
 }
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-uInt8 Cartridge3EPlus::peek(uInt16 address)
-{
-  uInt16 peekAddress = address;
-  address &= ROM_MASK;
-
-  if(address < 0x0040)  // TIA peek
-    return mySystem->tia().peek(address);
-
-  return CartridgeEnhanced::peek(peekAddress);
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-bool Cartridge3EPlus::poke(uInt16 address, uInt8 value)
-{
-  if(CartridgeEnhanced::poke(address, value))
-    return true;
-
-  if(address < 0x0040)  // TIA poke
-    // Handle TIA space that we claimed above
-    return mySystem->tia().poke(address, value);
-
-  return false;
-}
diff --git a/src/emucore/Cart3EPlus.hxx b/src/emucore/Cart3EPlus.hxx
index bdb8f85f5..d09a445ce 100644
--- a/src/emucore/Cart3EPlus.hxx
+++ b/src/emucore/Cart3EPlus.hxx
@@ -124,23 +124,6 @@ class Cartridge3EPlus: public Cartridge3E
     }
   #endif
 
-  public:
-    /**
-      Get the byte at the specified address
-
-      @return The byte at the specified address
-    */
-    uInt8 peek(uInt16 address) override;
-
-    /**
-      Change the byte at the specified address to the given value
-
-      @param address  The address where the value should be stored
-      @param value    The value to be stored at the address
-      @return         True if the poke changed the device address space, else false
-    */
-    bool poke(uInt16 address, uInt8 value) override;
-
   private:
     bool checkSwitchBank(uInt16 address, uInt8 value) override;
 
diff --git a/src/emucore/CartBUS.cxx b/src/emucore/CartBUS.cxx
index 46d220bbf..edd56d72c 100644
--- a/src/emucore/CartBUS.cxx
+++ b/src/emucore/CartBUS.cxx
@@ -68,8 +68,12 @@ CartridgeBUS::CartridgeBUS(const ByteBuffer& image, size_t size,
     reinterpret_cast<uInt16*>(myImage.get()),
     reinterpret_cast<uInt16*>(myRAM.data()),
     static_cast<uInt32>(32_KB),
-    devSettings ? settings.getBool("dev.thumb.trapfatal") : false, Thumbulator::ConfigureFor::BUS, this
-  );
+    0x00000800,
+    0x00000808,
+    0x40001FDC,
+    devSettings ? settings.getBool("dev.thumb.trapfatal") : false, 
+    Thumbulator::ConfigureFor::BUS, 
+    this);
 
   setInitialState();
 }
diff --git a/src/emucore/CartBUS.hxx b/src/emucore/CartBUS.hxx
index 054324353..86947ed19 100644
--- a/src/emucore/CartBUS.hxx
+++ b/src/emucore/CartBUS.hxx
@@ -181,6 +181,13 @@ class CartridgeBUS : public Cartridge
     bool poke(uInt16 address, uInt8 value) override;
 
   private:
+    /**
+      Checks if startup bank randomization is enabled.  For this scheme,
+      randomization is not supported, since the ARM code is always in a
+      pre-defined bank, and we *must* start from there.
+    */
+    bool randomStartBank() const override { return false; }
+
     /**
       Sets the initial state of the DPC pointers and RAM
     */
diff --git a/src/emucore/CartCDF.cxx b/src/emucore/CartCDF.cxx
index e09480464..ae06bdc05 100644
--- a/src/emucore/CartCDF.cxx
+++ b/src/emucore/CartCDF.cxx
@@ -29,14 +29,17 @@
 #include "TIA.hxx"
 #include "exception/FatalEmulationError.hxx"
 
-#define DSRAM         0x0800
-
 #define COMMSTREAM        0x20
 #define JUMPSTREAM_BASE   0x21
 
 #define FAST_FETCH_ON ((myMode & 0x0F) == 0)
 #define DIGITAL_AUDIO_ON ((myMode & 0xF0) == 0)
 
+#define getUInt32(_array, _address) ((_array)[(_address) + 0]        +  \
+                                    ((_array)[(_address) + 1] << 8)  +  \
+                                    ((_array)[(_address) + 2] << 16) +  \
+                                    ((_array)[(_address) + 3] << 24))
+
 namespace {
   Thumbulator::ConfigureFor thumulatorConfiguration(CartridgeCDF::CDFSubtype subtype)
   {
@@ -50,6 +53,9 @@ namespace {
       case CartridgeCDF::CDFSubtype::CDFJ:
         return Thumbulator::ConfigureFor::CDFJ;
 
+      case CartridgeCDF::CDFSubtype::CDFJplus:
+        return Thumbulator::ConfigureFor::CDFJplus;
+
       default:
         throw runtime_error("unreachable");
     }
@@ -60,34 +66,50 @@ namespace {
 CartridgeCDF::CartridgeCDF(const ByteBuffer& image, size_t size,
                            const string& md5, const Settings& settings)
   : Cartridge(settings, md5),
-    myImage(make_unique<uInt8[]>(32_KB))
+    myImage(make_unique<uInt8[]>(512_KB))
 {
   // Copy the ROM image into my buffer
-  std::fill_n(myImage.get(), 32_KB, 0);
-  std::copy_n(image.get(), std::min(32_KB, size), myImage.get());
+  std::fill_n(myImage.get(), 512_KB, 0);
+  std::copy_n(image.get(), std::min(512_KB, size), myImage.get());
 
-  // even though the ROM is 32K, only 28K is accessible to the 6507
-  createRomAccessArrays(28_KB);
+  // Detect cart version
+  setupVersion();
 
-  // Pointer to the program ROM (28K @ 0 byte offset)
-  // which starts after the 2K CDF Driver and 2K C Code
-  myProgramImage = myImage.get() + 4_KB;
+  // The lowest 2K is not accessible to the debugger
+  createRomAccessArrays(isCDFJplus() ? 510_KB : 28_KB);
+
+  // Pointer to the program ROM
+  // which starts after the 2K driver (and 2K C Code for CDF)
+  myProgramImage = myImage.get() + (isCDFJplus() ? 2_KB : 4_KB);
 
   // Pointer to CDF driver in RAM
   myDriverImage = myRAM.data();
 
-  // Pointer to the display RAM
-  myDisplayImage = myRAM.data() + DSRAM;
+  // Pointer to the display RAM (starts after 2K driver)
+  myDisplayImage = myRAM.data() + 2_KB;
 
-  setupVersion();
+  // C addresses
+  uInt32 cBase, cStart, cStack;
+  if (isCDFJplus()) {
+    cBase = getUInt32(myImage.get(), 0x17F8) & 0xFFFFFFFE;    // C Base Address
+    cStart = cBase;                                           // C Start Address
+    cStack = getUInt32(myImage.get(), 0x17F4);                // C Stack
+  } else {
+    cBase = 0x800;          // C Base Address
+    cStart = 0x808;         // C Start Address (skip ARM header)
+    cStack = 0x40001FDC;    // C Stack
+  }
 
   // Create Thumbulator ARM emulator
   bool devSettings = settings.getBool("dev.settings");
   myThumbEmulator = make_unique<Thumbulator>(
     reinterpret_cast<uInt16*>(myImage.get()),
     reinterpret_cast<uInt16*>(myRAM.data()),
-    static_cast<uInt32>(32_KB),
-    devSettings ? settings.getBool("dev.thumb.trapfatal") : false, thumulatorConfiguration(myCDFSubtype), this);
+    static_cast<uInt32>(512_KB),
+    cBase, cStart, cStack,
+    devSettings ? settings.getBool("dev.thumb.trapfatal") : false, 
+    thumulatorConfiguration(myCDFSubtype), 
+    this);
 
   setInitialState();
 }
@@ -97,8 +119,8 @@ void CartridgeCDF::reset()
 {
   initializeRAM(myRAM.data()+2_KB, myRAM.size()-2_KB);
 
-  // CDF always starts in bank 6
-  initializeStartBank(6);
+  // CDF always starts in bank 6, CDFJ+ in bank 0
+  initializeStartBank(isCDFJplus() ? 0 : 6);
 
   myAudioCycles = myARMCycles = 0;
   myFractionalClocks = 0.0;
@@ -123,7 +145,6 @@ void CartridgeCDF::setInitialState()
 
   myBankOffset = myLDAimmediateOperandAddress = myJMPoperandAddress = 0;
   myFastJumpActive = myFastJumpStream = 0;
-
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -195,7 +216,6 @@ inline void CartridgeCDF::callFunction(uInt8 value)
 uInt8 CartridgeCDF::peek(uInt16 address)
 {
   address &= 0x0FFF;
-
   uInt8 peekvalue = myProgramImage[myBankOffset + address];
 
   // In debugger/bank-locked mode, we ignore all hotspots and in general
@@ -214,8 +234,14 @@ uInt8 CartridgeCDF::peek(uInt16 address)
     ++myJMPoperandAddress;
 
     pointer = getDatastreamPointer(myFastJumpStream);
-    value = myDisplayImage[ pointer >> 20 ];
-    pointer += 0x100000;  // always increment by 1
+    if (isCDFJplus()) {
+      value = myDisplayImage[ pointer >> 16 ];
+      pointer += 0x00010000;  // always increment by 1
+    } else {
+      value = myDisplayImage[ pointer >> 20 ];
+      pointer += 0x00100000;  // always increment by 1
+    }
+
     setDatastreamPointer(myFastJumpStream, pointer);
 
     return value;
@@ -251,18 +277,19 @@ uInt8 CartridgeCDF::peek(uInt16 address)
       if DIGITAL_AUDIO_ON
       {
         // retrieve packed sample (max size is 2K, or 4K of unpacked data)
-        uInt32 sampleaddress = getSample() + (myMusicCounters[0] >> 21);
+        
+        uInt32 sampleaddress = getSample() + (myMusicCounters[0] >> (isCDFJplus() ? 13 : 21));
 
         // get sample value from ROM or RAM
-        if (sampleaddress < 0x8000)
+        if (sampleaddress < 0x00080000)
           peekvalue = myImage[sampleaddress];
-        else if (sampleaddress >= 0x40000000 && sampleaddress < 0x40002000) // check for RAM
+        else if (sampleaddress >= 0x40000000 && sampleaddress < 0x40008000) // check for RAM
           peekvalue = myRAM[sampleaddress - 0x40000000];
         else
           peekvalue = 0;
 
         // make sure current volume value is in the lower nybble
-        if ((myMusicCounters[0] & (1<<20)) == 0)
+        if ((myMusicCounters[0] & (1<<(isCDFJplus() ? 12 : 20))) == 0)
           peekvalue >>= 4;
         peekvalue &= 0x0f;
       }
@@ -284,39 +311,36 @@ uInt8 CartridgeCDF::peek(uInt16 address)
   // Switch banks if necessary
   switch(address)
   {
-    case 0xFF5:
-      // Set the current bank to the first 4k bank
-      bank(0);
+    case 0x0FF4:
+      bank(isCDFJplus() ? 0 : 6);
+      break;
+
+    case 0x0FF5:
+      bank(isCDFJplus() ? 1 : 0);
       break;
 
     case 0x0FF6:
-      // Set the current bank to the second 4k bank
-      bank(1);
+      bank(isCDFJplus() ? 2 : 1);
       break;
 
     case 0x0FF7:
-      // Set the current bank to the third 4k bank
-      bank(2);
+      bank(isCDFJplus() ? 3 : 2);
       break;
 
     case 0x0FF8:
-      // Set the current bank to the fourth 4k bank
-      bank(3);
+      bank(isCDFJplus() ? 4 : 3);
       break;
 
     case 0x0FF9:
-      // Set the current bank to the fifth 4k bank
-      bank(4);
+      bank(isCDFJplus() ? 5 : 4);
       break;
 
     case 0x0FFA:
-      // Set the current bank to the sixth 4k bank
-      bank(5);
+      bank(isCDFJplus() ? 6 : 5);
       break;
 
     case 0x0FFB:
-      // Set the current bank to the last 4k bank
-      bank(6);
+      bank(isCDFJplus() ? 0 : 6);
       break;
 
     default:
@@ -335,65 +359,71 @@ bool CartridgeCDF::poke(uInt16 address, uInt8 value)
   uInt32 pointer;
 
   address &= 0x0FFF;
-
   switch(address)
   {
-    case 0xFF0:   // DSWRITE
+    case 0x0FF0:   // DSWRITE
       pointer = getDatastreamPointer(COMMSTREAM);
-      myDisplayImage[ pointer >> 20 ] = value;
-      pointer += 0x100000;  // always increment by 1 when writing
+      if (isCDFJplus()) {
+        myDisplayImage[ pointer >> 16 ] = value;
+        pointer += 0x00010000;  // always increment by 1 when writing  
+      } else {
+        myDisplayImage[ pointer >> 20 ] = value;
+        pointer += 0x00100000;  // always increment by 1 when writing
+      }
       setDatastreamPointer(COMMSTREAM, pointer);
       break;
 
-    case 0xFF1:   // DSPTR
+    case 0x0FF1:   // DSPTR
       pointer = getDatastreamPointer(COMMSTREAM);
-      pointer <<=8;
-      pointer &= 0xf0000000;
-      pointer |= (value << 20);
+      pointer <<= 8;
+      if (isCDFJplus()) {
+        pointer &= 0xff000000;
+        pointer |= (value << 16);
+      } else {
+        pointer &= 0xf0000000;
+        pointer |= (value << 20);
+      }
       setDatastreamPointer(COMMSTREAM, pointer);
       break;
 
-    case 0xFF2:   // SETMODE
+    case 0x0FF2:   // SETMODE
       myMode = value;
       break;
 
-    case 0xFF3:   // CALLFN
+    case 0x0FF3:   // CALLFN
       callFunction(value);
       break;
 
-    case 0xFF5:
-      // Set the current bank to the first 4k bank
-      bank(0);
+   case 0x00FF4:
+      bank(isCDFJplus() ? 0 : 6);
+      break;
+
+    case 0x0FF5:
+      bank(isCDFJplus() ? 1 : 0);
       break;
 
     case 0x0FF6:
-      // Set the current bank to the second 4k bank
-      bank(1);
+      bank(isCDFJplus() ? 2 : 1);
       break;
 
     case 0x0FF7:
-      // Set the current bank to the third 4k bank
-      bank(2);
+      bank(isCDFJplus() ? 3 : 2);
       break;
 
     case 0x0FF8:
-      // Set the current bank to the fourth 4k bank
-      bank(3);
+      bank(isCDFJplus() ? 4 : 3);
       break;
 
     case 0x0FF9:
-      // Set the current bank to the fifth 4k bank
-      bank(4);
+      bank(isCDFJplus() ? 5 : 4);
       break;
 
     case 0x0FFA:
-      // Set the current bank to the sixth 4k bank
-      bank(5);
+      bank(isCDFJplus() ? 6 : 5);
       break;
 
     case 0x0FFB:
-      // Set the current bank to the last 4k bank
-      bank(6);
+      bank(isCDFJplus() ? 0 : 6);
       break;
 
     default:
@@ -419,7 +449,7 @@ bool CartridgeCDF::bank(uInt16 bank, uInt16)
   {
     access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)];
     access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)];
-    access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + 28_KB];
+    access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + 28_KB];  // TODO: Change for CDFJ+???
     mySystem->setPageAccess(addr, access);
   }
   return myBankChanged = true;
@@ -455,7 +485,7 @@ bool CartridgeCDF::patch(uInt16 address, uInt8 value)
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 const ByteBuffer& CartridgeCDF::getImage(size_t& size) const
 {
-  size = 32_KB;
+  size = 512_KB;
   return myImage;
 }
 
@@ -617,11 +647,13 @@ uInt32 CartridgeCDF::getWaveform(uInt8 index) const
                  (myRAM[address + 2] << 16) +
                  (myRAM[address + 3] << 24);   // high byte
 
-  result -= (0x40000000 + DSRAM);
-
-  if (result >= 4096)
-    result &= 4095;
+  result -= (0x40000000 + uInt32(2_KB));
 
+  if (!isCDFJplus()) {
+    if (result >= 4096) {
+      result &= 4095;
+    }
+  }
   return result;
 }
 
@@ -659,8 +691,16 @@ uInt8 CartridgeCDF::readFromDatastream(uInt8 index)
 
   uInt32 pointer = getDatastreamPointer(index);
   uInt16 increment = getDatastreamIncrement(index);
-  uInt8 value = myDisplayImage[ pointer >> 20 ];
-  pointer += (increment << 12);
+
+  uInt8 value;
+  if (isCDFJplus()) {
+    value = myDisplayImage[ pointer >> 16 ];
+    pointer += (increment << 8);
+  } else {
+    value = myDisplayImage[ pointer >> 20 ];
+    pointer += (increment << 12);   
+  }
+
   setDatastreamPointer(index, pointer);
   return value;
 }
@@ -668,8 +708,21 @@ uInt8 CartridgeCDF::readFromDatastream(uInt8 index)
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void CartridgeCDF::setupVersion()
 {
-  uInt8 subversion = 0;
+  // CDFJ+ detection
+  if (getUInt32(myImage.get(), 0x174) == 0x53554c50 &&    // Plus
+      getUInt32(myImage.get(), 0x178) == 0x4a464443 &&    // CDFJ
+      getUInt32(myImage.get(), 0x17C) == 0x00000001) {    // V1
 
+    myCDFSubtype = CDFSubtype::CDFJplus;
+    myAmplitudeStream = 0x23;
+    myFastjumpStreamIndexMask = 0xfe;
+    myDatastreamBase = 0x0098;
+    myDatastreamIncrementBase = 0x0124;
+    myWaveformBase = 0x01b0;
+    return;
+  }
+
+  uInt8 subversion = 0;
   for(uInt32 i = 0; i < 2048; i += 4)
   {
     // CDF signature occurs 3 times in a row, i+3 (+7 or +11) is version
@@ -683,6 +736,7 @@ void CartridgeCDF::setupVersion()
   }
 
   switch (subversion) {
+
     case 0x4a:
       myCDFSubtype = CDFSubtype::CDFJ;
 
@@ -727,11 +781,29 @@ string CartridgeCDF::name() const
       return "CartridgeCDF1";
     case CDFSubtype::CDFJ:
       return "CartridgeCDFJ";
+    case CDFSubtype::CDFJplus:
+      return "CartridgeCDFJ+";
     default:
       return "Cart unknown";
   }
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool CartridgeCDF::isCDFJplus() const
+{
+  return (myCDFSubtype == CDFSubtype::CDFJplus);
+}
+
+uInt32 CartridgeCDF::ramSize() const
+{
+  return uInt32(isCDFJplus() ? 32_KB : 8_KB);
+}
+
+uInt32 CartridgeCDF::romSize() const
+{
+  return uInt32(isCDFJplus() ? 512_KB : 32_KB);
+}
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 #ifdef DEBUGGER_SUPPORT
   CartDebugWidget* CartridgeCDF::debugWidget(GuiObject* boss, const GUI::Font& lfont,
diff --git a/src/emucore/CartCDF.hxx b/src/emucore/CartCDF.hxx
index cf172b8d2..e02b8a83d 100644
--- a/src/emucore/CartCDF.hxx
+++ b/src/emucore/CartCDF.hxx
@@ -25,17 +25,32 @@ class Thumbulator;
 #include "Cart.hxx"
 
 /**
-  Cartridge class used for CDF.
+  Cartridge class used for CDF/CDFJ/CDFJ+.
 
-  There are seven 4K program banks, a 4K Display Data RAM,
-  1K C Variable and Stack, and the CDF chip.
-  CDF chip access is mapped to $1000 - $103F (both read and write).
-  Program banks are accessible by read/write to $1FF5 - $1FFB.
+  CDFJ bankswitching for Atari games using ARM/C code.
+  There are two variants supported:
+  1) CDF/CDFJ - initial scheme with 32K ROM and 8K RAM
+  2) CDFJ+ - support for larger ROM sizes (64/128/256/512K) and RAM sizes (16/32K)
 
-  FIXME: THIS NEEDS TO BE UPDATED
+  Features:
+  32 fast fetchers
+  2 fast jump queues
+  1 parameter queue
+  3 channel digital audio/1 channel sampled sound
+  7 banks (4K) of atari code
+  4K display data (16K and 32K available with CDFJ+)
 
-  @authors: Darrell Spice Jr, Chris Walton, Fred Quimby,
-            Stephen Anthony, Bradford W. Mott
+  Note that for CDFJ+, the same driver is used for all RAM/RAM combinations.
+  It is left to the programmer to ensure that only the available RAM/ROM on the target device is used.
+
+  Bankswitching Note:
+  CDF/CDFJ uses $FFF5 through $FFFB (initial bank 6)
+  CDFJ+ uses $FFF4 through $FFFA (initial bank 0)
+
+  The letters CDFJ stand for Chris, Darrell, Fred, and John.
+
+  @authors: Darrell Spice Jr, Chris Walton, Fred Quimby, John Champeau
+            Thomas Jentzsch, Stephen Anthony, Bradford W. Mott
 */
 class CartridgeCDF : public Cartridge
 {
@@ -48,7 +63,8 @@ class CartridgeCDF : public Cartridge
     enum class CDFSubtype {
       CDF0,
       CDF1,
-      CDFJ
+      CDFJ,
+      CDFJplus
     };
 
   public:
@@ -154,6 +170,21 @@ class CartridgeCDF : public Cartridge
     */
     uInt32 thumbCallback(uInt8 function, uInt32 value1, uInt32 value2) override;
 
+    /**
+      Set if we are using CDFJ+ bankswitching
+     */
+    bool isCDFJplus() const;
+
+    /**
+      Size of SRAM (RAM) area in cart
+     */
+    uInt32 ramSize() const;
+
+    /**
+      Size of Flash memory (ROM) area in cart
+     */
+    uInt32 romSize() const;
+
 #ifdef DEBUGGER_SUPPORT
     /**
       Get debugger widget responsible for accessing the inner workings
@@ -184,9 +215,9 @@ class CartridgeCDF : public Cartridge
 
   private:
     /**
-      Checks if startup bank randomization is enabled.
-
-      @return  Whether the startup bank(s) should be randomized
+      Checks if startup bank randomization is enabled.  For this scheme,
+      randomization is not supported, since the ARM code is always in a
+      pre-defined bank, and we *must* start from there.
     */
     bool randomStartBank() const override { return false; }
 
@@ -220,23 +251,26 @@ class CartridgeCDF : public Cartridge
     void setupVersion();
 
   private:
-    // The 32K ROM image of the cartridge
+    // The ROM image of the cartridge
     ByteBuffer myImage;
 
-    // Pointer to the 28K program ROM image of the cartridge
+    // Pointer to the program ROM image of the cartridge
     uInt8* myProgramImage{nullptr};
 
-    // Pointer to the 4K display ROM image of the cartridge
+    // Pointer to the display ROM image of the cartridge
     uInt8* myDisplayImage{nullptr};
 
-    // Pointer to the 2K CDF driver image in RAM
+    // Pointer to the driver image in RAM
     uInt8* myDriverImage{nullptr};
 
-    // The CDF 8k RAM image, used as:
-    //   $0000 - 2K CDF driver
+    // The CDFJ 8K RAM image, used as:
+    //   $0000 - 2K Driver
     //   $0800 - 4K Display Data
     //   $1800 - 2K C Variable & Stack
-    std::array<uInt8, 8_KB> myRAM;
+    // For CDFJ+, used as:
+    //   $0000 - 2K Driver
+    //   $0800 - Display Data, C Variables & Stack
+    std::array<uInt8, 32_KB> myRAM;
 
     // Pointer to the Thumb ARM emulator object
     unique_ptr<Thumbulator> myThumbEmulator;
diff --git a/src/emucore/CartDPCPlus.cxx b/src/emucore/CartDPCPlus.cxx
index 71500ee94..17494b8cb 100644
--- a/src/emucore/CartDPCPlus.cxx
+++ b/src/emucore/CartDPCPlus.cxx
@@ -54,6 +54,9 @@ CartridgeDPCPlus::CartridgeDPCPlus(const ByteBuffer& image, size_t size,
       (reinterpret_cast<uInt16*>(myImage.get()),
        reinterpret_cast<uInt16*>(myDPCRAM.data()),
        static_cast<uInt32>(32_KB),
+      0x00000C00,
+      0x00000C08,
+      0x40001FDC,
        devSettings ? settings.getBool("dev.thumb.trapfatal") : false,
        Thumbulator::ConfigureFor::DPCplus,
        this);
diff --git a/src/emucore/CartDPCPlus.hxx b/src/emucore/CartDPCPlus.hxx
index 5c83da263..3cef0a47a 100644
--- a/src/emucore/CartDPCPlus.hxx
+++ b/src/emucore/CartDPCPlus.hxx
@@ -175,6 +175,13 @@ class CartridgeDPCPlus : public Cartridge
     bool poke(uInt16 address, uInt8 value) override;
 
   private:
+    /**
+      Checks if startup bank randomization is enabled.  For this scheme,
+      randomization is not supported, since the ARM code is always in a
+      pre-defined bank, and we *must* start from there.
+    */
+    bool randomStartBank() const override { return false; }
+
     /**
       Sets the initial state of the DPC pointers and RAM
     */
diff --git a/src/emucore/CartDetector.cxx b/src/emucore/CartDetector.cxx
index 0ecc6e82e..6874c2576 100644
--- a/src/emucore/CartDetector.cxx
+++ b/src/emucore/CartDetector.cxx
@@ -169,6 +169,8 @@ Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t si
       type = Bankswitch::Type::_3E;
     else if(isProbably3F(image, size))
       type = Bankswitch::Type::_3F;
+    else if (isProbablyCDF(image, size))
+      type = Bankswitch::Type::_CDF;
     else if(isProbably4A50(image, size))
       type = Bankswitch::Type::_4A50;
     else if(isProbablyEF(image, size, type))
@@ -188,6 +190,8 @@ Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t si
       ; // type has been set directly in the function
     else if(isProbably3F(image, size))
       type = Bankswitch::Type::_3F;
+    else if (isProbablyCDF(image, size))
+      type = Bankswitch::Type::_CDF;
     else if(isProbably4A50(image, size))
       type = Bankswitch::Type::_4A50;
     else /*if(isProbablySB(image, size))*/
@@ -203,6 +207,8 @@ Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t si
       ; // type has been set directly in the function
     else if(isProbably3F(image, size))
       type = Bankswitch::Type::_3F;
+    else if (isProbablyCDF(image, size))
+      type = Bankswitch::Type::_CDF;
     else /*if(isProbablySB(image, size))*/
       type = Bankswitch::Type::_SB;
   }
@@ -216,6 +222,8 @@ Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t si
       type = Bankswitch::Type::_3E;
     else if(isProbably3F(image, size))
       type = Bankswitch::Type::_3F;
+    else if (isProbablyCDF(image, size))
+      type = Bankswitch::Type::_CDF;
   }
   else  // what else can we do?
   {
@@ -444,7 +452,9 @@ bool CartDetector::isProbablyCDF(const ByteBuffer& image, size_t size)
   // Note: all Harmony/Melody custom drivers also contain the value
   // 0x10adab1e (LOADABLE) if needed for future improvement
   uInt8 cdf[] = { 'C', 'D', 'F' };
-  return searchForBytes(image, size, cdf, 3, 3);
+  uInt8 cdfjplus[] = { 'P', 'L', 'U', 'S', 'C', 'D', 'F', 'J' };
+  return (searchForBytes(image, size, cdf, 3, 3) || 
+          searchForBytes(image, size, cdfjplus, 8, 1));
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -708,15 +718,18 @@ bool CartDetector::isProbablyUA(const ByteBuffer& image, size_t size)
   // using 'STA $240' or 'LDA $240'
   // Similar Brazilian (Digivison) cart bankswitching switches to bank 1 by accessing address 0x2C0
   // using 'BIT $2C0', 'STA $2C0' or 'LDA $2C0'
-  uInt8 signature[6][3] = {
+  // Other Brazilian (Atari Mania) ROM's bankswitching switches to bank 1 by accessing address 0xFC0
+  // using 'BIT $FA0', 'BIT $FC0' or 'STA $FA0'
+  uInt8 signature[7][3] = {
     { 0x8D, 0x40, 0x02 },  // STA $240 (Funky Fish, Pleiades)
     { 0xAD, 0x40, 0x02 },  // LDA $240 (???)
     { 0xBD, 0x1F, 0x02 },  // LDA $21F,X (Gingerbread Man)
     { 0x2C, 0xC0, 0x02 },  // BIT $2C0 (Time Pilot)
     { 0x8D, 0xC0, 0x02 },  // STA $2C0 (Fathom, Vanguard)
-    { 0xAD, 0xC0, 0x02 }   // LDA $2C0 (Mickey)
+    { 0xAD, 0xC0, 0x02 },  // LDA $2C0 (Mickey)
+    { 0x2C, 0xC0, 0x0F }   // BIT $FC0 (H.E.R.O., Kung-Fu Master)
   };
-  for(uInt32 i = 0; i < 6; ++i)
+  for(uInt32 i = 0; i < 7; ++i)
     if(searchForBytes(image, size, signature[i], 3))
       return true;
 
diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx
index 633104cf3..487a22741 100644
--- a/src/emucore/CartEnhanced.cxx
+++ b/src/emucore/CartEnhanced.cxx
@@ -60,7 +60,7 @@ CartridgeEnhanced::CartridgeEnhanced(const ByteBuffer& image, size_t size,
 void CartridgeEnhanced::install(System& system)
 {
   // limit banked RAM size to the size of one RAM bank
-  const uInt32 ramSize = myRamBankCount > 0 ? 1 << (myBankShift - 1) : uInt32(myRamSize);
+  const uInt16 ramSize = myRamBankCount > 0 ? 1 << (myBankShift - 1) : uInt16(myRamSize);
 
   // calculate bank switching and RAM sizes and masks
   myBankSize = 1 << myBankShift;                    // e.g. = 2 ^ 12 = 4K = 0x1000
@@ -91,14 +91,12 @@ void CartridgeEnhanced::install(System& system)
     System::PageAccess access(this, System::PageAccessType::READ);
 
     // Set the page accessing method for the RAM writing pages
-    // Map access to this class, since we need to inspect all accesses to
-    // check if RWP happens
+    // Note: Writes are mapped to poke() (NOT using direcPokeBase) to check for read from write port (RWP)
     access.type = System::PageAccessType::WRITE;
     for(uInt16 addr = ROM_OFFSET + myWriteOffset; addr < ROM_OFFSET + myWriteOffset + myRamSize; addr += System::PAGE_SIZE)
     {
       const uInt16 offset = addr & myRamMask;
 
-      access.directPokeBase = &myRAM[offset];
       access.romAccessBase = &myRomAccessBase[myWriteOffset + offset];
       access.romPeekCounter = &myRomAccessCounter[myWriteOffset + offset];
       access.romPokeCounter = &myRomAccessCounter[myWriteOffset + offset + myAccessSize];
@@ -107,7 +105,6 @@ void CartridgeEnhanced::install(System& system)
 
     // Set the page accessing method for the RAM reading pages
     access.type = System::PageAccessType::READ;
-    access.directPokeBase = nullptr;
     for(uInt16 addr = ROM_OFFSET + myReadOffset; addr < ROM_OFFSET + myReadOffset + myRamSize; addr += System::PAGE_SIZE)
     {
       const uInt16 offset = addr & myRamMask;
@@ -263,6 +260,7 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment)
     myCurrentSegOffset[segment] = uInt32(mySize) + (ramBank << myBankShift);
 
     // Set the page accessing method for the RAM writing pages
+    // Note: Writes are mapped to poke() (NOT using direcPokeBase) to check for read from write port (RWP)
     uInt16 fromAddr = (ROM_OFFSET + segmentOffset + myWriteOffset) & ~System::PAGE_MASK;
     uInt16 toAddr   = (ROM_OFFSET + segmentOffset + myWriteOffset + (myBankSize >> 1)) & ~System::PAGE_MASK;
     System::PageAccess access(this, System::PageAccessType::WRITE);
@@ -271,7 +269,6 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment)
     {
       const uInt32 offset = bankOffset + (addr & myRamMask);
 
-      access.directPokeBase = &myRAM[offset - mySize];
       access.romAccessBase = &myRomAccessBase[offset];
       access.romPeekCounter = &myRomAccessCounter[offset];
       access.romPokeCounter = &myRomAccessCounter[offset + myAccessSize];
@@ -282,7 +279,6 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment)
     fromAddr = (ROM_OFFSET + segmentOffset + myReadOffset) & ~System::PAGE_MASK;
     toAddr   = (ROM_OFFSET + segmentOffset + myReadOffset + (myBankSize >> 1)) & ~System::PAGE_MASK;
     access.type = System::PageAccessType::READ;
-    access.directPokeBase = nullptr;
 
     for(uInt16 addr = fromAddr; addr < toAddr; addr += System::PAGE_SIZE)
     {
@@ -298,18 +294,6 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment)
   return myBankChanged = true;
 }
 
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-inline uInt16 CartridgeEnhanced::romAddressSegmentOffset(uInt16 address) const
-{
-  return myCurrentSegOffset[((address & ROM_MASK) >> myBankShift) % myBankSegs];
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-inline uInt16 CartridgeEnhanced::ramAddressSegmentOffset(uInt16 address) const
-{
-  return uInt16(myCurrentSegOffset[((address & ROM_MASK) >> myBankShift) % myBankSegs] - mySize) >> 1;
-}
-
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 uInt16 CartridgeEnhanced::getBank(uInt16 address) const
 {
diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx
index 98fb8e910..fb5b35509 100644
--- a/src/emucore/CartEnhanced.hxx
+++ b/src/emucore/CartEnhanced.hxx
@@ -275,7 +275,9 @@ class CartridgeEnhanced : public Cartridge
       @param address  The address to get the offset for
       @return  The calculated offset
     */
-    uInt16 romAddressSegmentOffset(uInt16 address) const;
+    uInt32 romAddressSegmentOffset(uInt16 address) const {
+      return myCurrentSegOffset[((address & ROM_MASK) >> myBankShift) % myBankSegs];
+    }
 
     /**
       Get the RAM offset of the segment of the given address
@@ -283,7 +285,10 @@ class CartridgeEnhanced : public Cartridge
       @param address  The address to get the offset for
       @return  The calculated offset
     */
-    uInt16 ramAddressSegmentOffset(uInt16 address) const;
+    uInt16 ramAddressSegmentOffset(uInt16 address) const {
+      return static_cast<uInt16>((myCurrentSegOffset[
+        ((address & ROM_MASK) >> myBankShift) % myBankSegs] - mySize) >> 1);
+    }
 
   private:
     // Following constructors and assignment operators not supported
diff --git a/src/emucore/CartUA.cxx b/src/emucore/CartUA.cxx
index e73f166db..83afca20e 100644
--- a/src/emucore/CartUA.cxx
+++ b/src/emucore/CartUA.cxx
@@ -39,11 +39,21 @@ void CartridgeUA::install(System& system)
 
   // Set the page accessing methods for the hot spots
   System::PageAccess access(this, System::PageAccessType::READ);
-  mySystem->setPageAccess(0x0220, access);
-  mySystem->setPageAccess(0x0240, access);
-  mySystem->setPageAccess(0x0220 | 0x80, access);
-  mySystem->setPageAccess(0x0240 | 0x80, access);
+  // Map all potential addresses
+  // - A11, A10 and A8 are not connected to RIOT
+  // - A9 is the fixed part of the hotspot address
+  // - A7 is used by Brazilian carts
+  // - A5 and A4 determine bank
+  for(uInt16 a11 = 0; a11 <= 1; ++a11)
+    for(uInt16 a10 = 0; a10 <= 1; ++a10)
+      for(uInt16 a8 = 0; a8 <= 1; ++a8)
+        for(uInt16 a7 = 0; a7 <= 1; ++a7)
+        {
+          uInt16 addr = (a11 << 11) + (a10 << 10) + (a8 << 8) + (a7 << 7);
 
+          mySystem->setPageAccess(0x0220 | addr, access);
+          mySystem->setPageAccess(0x0240 | addr, access);
+        }
   // Install pages for the startup bank
   bank(startBank());
 }
diff --git a/src/emucore/CartUA.hxx b/src/emucore/CartUA.hxx
index 95d4d022d..f5b25803f 100644
--- a/src/emucore/CartUA.hxx
+++ b/src/emucore/CartUA.hxx
@@ -28,7 +28,9 @@
 /**
   Cartridge class used for UA Limited's 8K bankswitched games.  There
   are two 4K banks, which are switched by accessing $0220 (bank 0) and
-  $0240 (bank 1).
+  $0240 (bank 1).  Similar addresses are used by Brazilian carts, e.g.
+  $02A0, $02C0 and $0FA0, $0FC0.  The code accepts further potential
+  hotspot addresses.
 
   @author  Bradford W. Mott, Thomas Jentzsch
 */
diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx
index 9cb5c5087..bb292859e 100644
--- a/src/emucore/Console.cxx
+++ b/src/emucore/Console.cxx
@@ -35,6 +35,11 @@
 #include "Genesis.hxx"
 #include "MindLink.hxx"
 #include "CompuMate.hxx"
+#include "AmigaMouse.hxx"
+#include "AtariMouse.hxx"
+#include "TrakBall.hxx"
+#include "Lightgun.hxx"
+#include "QuadTari.hxx"
 #include "M6502.hxx"
 #include "M6532.hxx"
 #include "TIA.hxx"
@@ -46,10 +51,6 @@
 #include "Sound.hxx"
 #include "Switches.hxx"
 #include "System.hxx"
-#include "AmigaMouse.hxx"
-#include "AtariMouse.hxx"
-#include "TrakBall.hxx"
-#include "Lightgun.hxx"
 #include "FrameBuffer.hxx"
 #include "TIASurface.hxx"
 #include "OSystem.hxx"
@@ -249,7 +250,6 @@ Console::~Console()
   myOSystem.sound().close();
 }
 
-
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void Console::setConsoleTiming()
 {
@@ -476,7 +476,7 @@ void Console::setFormat(uInt32 format, bool force)
   initializeAudio(); // ensure that audio synthesis is set up to match emulation rate
   myOSystem.resetFps(); // Reset FPS measurement
 
-  myOSystem.frameBuffer().showMessage(message);
+  myOSystem.frameBuffer().showTextMessage(message);
 
   // Let the other devices know about the console change
   mySystem->consoleChanged(myConsoleTiming);
@@ -493,10 +493,10 @@ void Console::toggleColorLoss(bool toggle)
 
     string message = string("PAL color-loss ") +
                      (colorloss ? "enabled" : "disabled");
-    myOSystem.frameBuffer().showMessage(message);
+    myOSystem.frameBuffer().showTextMessage(message);
   }
   else
-    myOSystem.frameBuffer().showMessage(
+    myOSystem.frameBuffer().showTextMessage(
       "PAL color-loss not available in non PAL modes");
 }
 
@@ -521,7 +521,7 @@ void Console::toggleInter(bool toggle)
   ostringstream ss;
 
   ss << "Interpolation " << (enabled ? "enabled" : "disabled");
-  myOSystem.frameBuffer().showMessage(ss.str());
+  myOSystem.frameBuffer().showTextMessage(ss.str());
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -539,7 +539,7 @@ void Console::toggleTurbo()
 
   ostringstream ss;
   ss << "Turbo mode " << (!enabled ? "enabled" : "disabled");
-  myOSystem.frameBuffer().showMessage(ss.str());
+  myOSystem.frameBuffer().showTextMessage(ss.str());
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -564,7 +564,7 @@ void Console::changeSpeed(int direction)
   ostringstream val;
 
   val << formatSpeed(speed) << "%";
-  myOSystem.frameBuffer().showMessage("Emulation speed", val.str(), speed, MIN_SPEED, MAX_SPEED);
+  myOSystem.frameBuffer().showGaugeMessage("Emulation speed", val.str(), speed, MIN_SPEED, MAX_SPEED);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -574,13 +574,13 @@ void Console::togglePhosphor()
   {
     myProperties.set(PropType::Display_Phosphor, "NO");
     myOSystem.frameBuffer().tiaSurface().enablePhosphor(false);
-    myOSystem.frameBuffer().showMessage("Phosphor effect disabled");
+    myOSystem.frameBuffer().showTextMessage("Phosphor effect disabled");
   }
   else
   {
     myProperties.set(PropType::Display_Phosphor, "YES");
     myOSystem.frameBuffer().tiaSurface().enablePhosphor(true);
-    myOSystem.frameBuffer().showMessage("Phosphor effect enabled");
+    myOSystem.frameBuffer().showTextMessage("Phosphor effect enabled");
   }
 }
 
@@ -605,7 +605,7 @@ void Console::changePhosphor(int direction)
     val.str("");
     val << "Off";
   }
-  myOSystem.frameBuffer().showMessage("Phosphor blend", val.str(), blend);
+  myOSystem.frameBuffer().showGaugeMessage("Phosphor blend", val.str(), blend);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -621,11 +621,15 @@ FBInitStatus Console::initializeVideo(bool full)
 
   if(full)
   {
+    auto size = myOSystem.settings().getBool("tia.correct_aspect") ?
+      Common::Size(TIAConstants::viewableWidth, TIAConstants::viewableHeight) :
+      Common::Size(2 * myTIA->width(), myTIA->height());
+
     bool devSettings = myOSystem.settings().getBool("dev.settings");
     const string& title = string("Stella ") + STELLA_VERSION +
                    ": \"" + myProperties.get(PropType::Cart_Name) + "\"";
-    fbstatus = myOSystem.frameBuffer().createDisplay(title, FrameBuffer::BufferType::Emulator,
-        TIAConstants::viewableWidth, TIAConstants::viewableHeight, false);
+    fbstatus = myOSystem.frameBuffer().createDisplay(title,
+        BufferType::Emulator, size, false);
     if(fbstatus != FBInitStatus::Success)
       return fbstatus;
 
@@ -695,7 +699,7 @@ void Console::changeVerticalCenter(int direction)
   if (vcenter != myTIA->vcenter()) myTIA->setVcenter(vcenter);
 
   val << (vcenter ? vcenter > 0 ? "+" : "" : " ") << vcenter << "px";
-  myOSystem.frameBuffer().showMessage("V-Center", val.str(), vcenter,
+  myOSystem.frameBuffer().showGaugeMessage("V-Center", val.str(), vcenter,
                                       myTIA->minVcenter(), myTIA->maxVcenter());
 }
 
@@ -723,8 +727,26 @@ void Console::changeVSizeAdjust(int direction)
 
   ostringstream val;
 
-  val << (newAdjustVSize ? newAdjustVSize > 0 ? "+" : "" : " ") << newAdjustVSize << "%";
-  myOSystem.frameBuffer().showMessage("V-Size", val.str(), newAdjustVSize, -5, 5);
+  val << (newAdjustVSize ? newAdjustVSize > 0 ? "+" : "" : " ")
+      << newAdjustVSize << "%";
+  myOSystem.frameBuffer().showGaugeMessage("V-Size", val.str(), newAdjustVSize, -5, 5);
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void Console::toggleCorrectAspectRatio(bool toggle)
+{
+  bool enabled = myOSystem.settings().getBool("tia.correct_aspect");
+
+  if(toggle)
+  {
+    enabled = !enabled;
+    myOSystem.settings().setValue("tia.correct_aspect", enabled);
+    initializeVideo();
+  }
+  const string& message = string("Correct aspect ratio ") +
+      (enabled ? "enabled" : "disabled");
+
+  myOSystem.frameBuffer().showTextMessage(message);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -734,8 +756,7 @@ void Console::setTIAProperties()
     static_cast<Int32>(BSPF::stringToInt(myProperties.get(PropType::Display_VCenter))), TIAConstants::minVcenter, TIAConstants::maxVcenter
   );
 
-  if(myDisplayFormat == "NTSC" || myDisplayFormat == "PAL60" ||
-     myDisplayFormat == "SECAM60")
+  if(gameRefreshRate() == 60)
   {
     // Assume we've got ~262 scanlines (NTSC-like format)
     myTIA->setLayout(FrameLayout::ntsc);
@@ -784,17 +805,22 @@ void Console::setControllers(const string& romMd5)
 
     myLeftControl  = std::move(myCMHandler->leftController());
     myRightControl = std::move(myCMHandler->rightController());
-    myOSystem.eventHandler().defineKeyControllerMappings(Controller::Type::CompuMate, Controller::Jack::Left);
-    myOSystem.eventHandler().defineJoyControllerMappings(Controller::Type::CompuMate, Controller::Jack::Left);
+    myOSystem.eventHandler().defineKeyControllerMappings(
+        Controller::Type::CompuMate, Controller::Jack::Left);
+    myOSystem.eventHandler().defineJoyControllerMappings(
+        Controller::Type::CompuMate, Controller::Jack::Left);
   }
   else
   {
     // Setup the controllers based on properties
-    Controller::Type leftType = Controller::getType(myProperties.get(PropType::Controller_Left));
-    Controller::Type rightType = Controller::getType(myProperties.get(PropType::Controller_Right));
+    Controller::Type leftType =
+        Controller::getType(myProperties.get(PropType::Controller_Left));
+    Controller::Type rightType =
+        Controller::getType(myProperties.get(PropType::Controller_Right));
     size_t size = 0;
     const ByteBuffer& image = myCart->getImage(size);
-    const bool swappedPorts = myProperties.get(PropType::Console_SwapPorts) == "YES";
+    const bool swappedPorts =
+        myProperties.get(PropType::Console_SwapPorts) == "YES";
 
     // Try to detect controllers
     if(image != nullptr && size != 0)
@@ -806,7 +832,8 @@ void Console::setControllers(const string& romMd5)
           !swappedPorts ? Controller::Jack::Right : Controller::Jack::Left, myOSystem.settings());
     }
 
-    unique_ptr<Controller> leftC = getControllerPort(leftType, Controller::Jack::Left, romMd5),
+    unique_ptr<Controller>
+      leftC = getControllerPort(leftType, Controller::Jack::Left, romMd5),
       rightC = getControllerPort(rightType, Controller::Jack::Right, romMd5);
 
     // Swap the ports if necessary
@@ -893,7 +920,7 @@ unique_ptr<Controller> Console::getControllerPort(const Controller::Type type,
       Controller::onMessageCallback callback = [&os = myOSystem](const string& msg) {
         bool devSettings = os.settings().getBool("dev.settings");
         if(os.settings().getBool(devSettings ? "dev.eepromaccess" : "plr.eepromaccess"))
-          os.frameBuffer().showMessage(msg);
+          os.frameBuffer().showTextMessage(msg);
       };
       controller = make_unique<AtariVox>(port, myEvent, *mySystem,
           myOSystem.settings().getString("avoxport"), nvramfile, callback);
@@ -906,7 +933,7 @@ unique_ptr<Controller> Console::getControllerPort(const Controller::Type type,
       Controller::onMessageCallback callback = [&os = myOSystem](const string& msg) {
         bool devSettings = os.settings().getBool("dev.settings");
         if(os.settings().getBool(devSettings ? "dev.eepromaccess" : "plr.eepromaccess"))
-          os.frameBuffer().showMessage(msg);
+          os.frameBuffer().showTextMessage(msg);
       };
       controller = make_unique<SaveKey>(port, myEvent, *mySystem, nvramfile, callback);
       break;
@@ -927,6 +954,10 @@ unique_ptr<Controller> Console::getControllerPort(const Controller::Type type,
       controller = make_unique<Lightgun>(port, myEvent, *mySystem, romMd5, myOSystem.frameBuffer());
       break;
 
+    case Controller::Type::QuadTari:
+      controller = make_unique<QuadTari>(port, myOSystem, *mySystem, myProperties);
+      break;
+
     default:
       // What else can we do?
       // always create because it may have been changed by user dialog
@@ -956,24 +987,32 @@ void Console::changeAutoFireRate(int direction)
   else
     val << "Off";
 
-  myOSystem.frameBuffer().showMessage("Autofire rate", val.str(), rate, 0, isNTSC ? 30 : 25);
+  myOSystem.frameBuffer().showGaugeMessage("Autofire rate", val.str(), rate, 0, isNTSC ? 30 : 25);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-float Console::getFramerate() const
+float Console::currentFrameRate() const
 {
   return
     (myConsoleTiming == ConsoleTiming::ntsc ? 262.F * 60.F : 312.F * 50.F) /
      myTIA->frameBufferScanlinesLastFrame();
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+int Console::gameRefreshRate() const
+{
+  return
+    myDisplayFormat == "NTSC" || myDisplayFormat == "PAL60" ||
+    myDisplayFormat == "SECAM60" ? 60 : 50;
+}
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void Console::toggleTIABit(TIABit bit, const string& bitname, bool show, bool toggle) const
 {
   bool result = myTIA->toggleBit(bit, toggle ? 2 : 3);
   const string message = bitname + (result ? " enabled" : " disabled");
 
-  myOSystem.frameBuffer().showMessage(message);
+  myOSystem.frameBuffer().showTextMessage(message);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -982,7 +1021,7 @@ void Console::toggleBits(bool toggle) const
   bool enabled = myTIA->toggleBits(toggle);
   const string message = string("TIA bits ") + (enabled ? "enabled" : "disabled");
 
-  myOSystem.frameBuffer().showMessage(message);
+  myOSystem.frameBuffer().showTextMessage(message);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -991,7 +1030,7 @@ void Console::toggleTIACollision(TIABit bit, const string& bitname, bool show, b
   bool result = myTIA->toggleCollision(bit, toggle ? 2 : 3);
   const string message = bitname + (result ? " collision enabled" : " collision disabled");
 
-  myOSystem.frameBuffer().showMessage(message);
+  myOSystem.frameBuffer().showTextMessage(message);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -1000,7 +1039,7 @@ void Console::toggleCollisions(bool toggle) const
   bool enabled = myTIA->toggleCollisions(toggle);
   const string message = string("TIA collisions ") + (enabled ? "enabled" : "disabled");
 
-  myOSystem.frameBuffer().showMessage(message);
+  myOSystem.frameBuffer().showTextMessage(message);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -1009,7 +1048,7 @@ void Console::toggleFixedColors(bool toggle) const
   bool enabled = toggle ? myTIA->toggleFixedColors() : myTIA->usingFixedColors();
   const string message = string("Fixed debug colors ") + (enabled ? "enabled" : "disabled");
 
-  myOSystem.frameBuffer().showMessage(message);
+  myOSystem.frameBuffer().showTextMessage(message);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -1018,7 +1057,7 @@ void Console::toggleJitter(bool toggle) const
   bool enabled = myTIA->toggleJitter(toggle ? 2 : 3);
   const string message = string("TV scanline jitter ") + (enabled ? "enabled" : "disabled");
 
-  myOSystem.frameBuffer().showMessage(message);
+  myOSystem.frameBuffer().showTextMessage(message);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/emucore/Console.hxx b/src/emucore/Console.hxx
index 78f14ba20..aa9a75f38 100644
--- a/src/emucore/Console.hxx
+++ b/src/emucore/Console.hxx
@@ -185,6 +185,11 @@ class Console : public Serializable, public ConsoleIO
      */
     EmulationTiming& emulationTiming() { return myEmulationTiming; }
 
+    /**
+      Retrieve the current game's refresh rate, or 0 if no game.
+    */
+    int refreshRate() const;
+
   public:
     /**
       Toggle between NTSC/PAL/SECAM (and variants) display format.
@@ -277,9 +282,21 @@ class Console : public Serializable, public ConsoleIO
     void changeVSizeAdjust(int direction = +1);
 
     /**
-      Returns the current framerate.
+      Toggle the aspect ratio correction.
     */
-    float getFramerate() const;
+    void toggleCorrectAspectRatio(bool toggle = true);
+
+    /**
+      Returns the current framerate.  Note that this is the actual,
+      dynamic frame rate while a game is running.
+    */
+    float currentFrameRate() const;
+
+    /**
+      Retrieve the current game's refresh rate.  Note that this is a
+      static, basic frame rate based on the current TV format.
+    */
+    int gameRefreshRate() const;
 
     /**
       Toggles the TIA bit specified in the method name.
diff --git a/src/emucore/Control.cxx b/src/emucore/Control.cxx
index 813063c04..fb57b6278 100644
--- a/src/emucore/Control.cxx
+++ b/src/emucore/Control.cxx
@@ -110,7 +110,7 @@ string Controller::getName(const Type type)
     "AmigaMouse", "AtariMouse", "AtariVox", "BoosterGrip", "CompuMate",
     "Driving", "Sega Genesis", "Joystick", "Keyboard", "KidVid", "MindLink",
     "Paddles", "Paddles_IAxis", "Paddles_IAxDr", "SaveKey", "TrakBall",
-    "Lightgun"
+    "Lightgun", "QuadTari"
   };
 
   return NAMES[int(type)];
@@ -125,7 +125,7 @@ string Controller::getPropName(const Type type)
     "AMIGAMOUSE", "ATARIMOUSE", "ATARIVOX", "BOOSTERGRIP", "COMPUMATE",
     "DRIVING", "GENESIS", "JOYSTICK", "KEYBOARD", "KIDVID", "MINDLINK",
     "PADDLES", "PADDLES_IAXIS", "PADDLES_IAXDR", "SAVEKEY", "TRAKBALL",
-    "LIGHTGUN"
+    "LIGHTGUN", "QUADTARI"
   };
 
   return PROP_NAMES[int(type)];
diff --git a/src/emucore/Control.hxx b/src/emucore/Control.hxx
index 629a2afee..48eb303f5 100644
--- a/src/emucore/Control.hxx
+++ b/src/emucore/Control.hxx
@@ -94,7 +94,7 @@ class Controller : public Serializable
       AmigaMouse, AtariMouse, AtariVox, BoosterGrip, CompuMate,
       Driving, Genesis, Joystick, Keyboard, KidVid, MindLink,
       Paddles, PaddlesIAxis, PaddlesIAxDr, SaveKey, TrakBall,
-      Lightgun,
+      Lightgun, QuadTari,
       LastType
     };
 
@@ -178,12 +178,12 @@ class Controller : public Serializable
       Update the entire digital and analog pin state according to the
       events currently set.
     */
-    virtual void update() = 0;
+    virtual void update() { }
 
     /**
       Returns the name of this controller.
     */
-    virtual string name() const = 0;
+    virtual string name() const { return ""; }
 
     /**
       Answers whether the controller is intrinsically an analog controller.
diff --git a/src/emucore/ControllerDetector.cxx b/src/emucore/ControllerDetector.cxx
index 622f59ca1..d8799c365 100644
--- a/src/emucore/ControllerDetector.cxx
+++ b/src/emucore/ControllerDetector.cxx
@@ -62,12 +62,14 @@ Controller::Type ControllerDetector::autodetectPort(
 
   if(isProbablySaveKey(image, size, port))
     type = Controller::Type::SaveKey;
+  else if(isProbablyQuadTari(image, size, port))
+    type = Controller::Type::QuadTari;
   else if(usesJoystickButton(image, size, port))
   {
     if(isProbablyTrakBall(image, size))
       type = Controller::Type::TrakBall;
     else if(isProbablyAtariMouse(image, size))
-      type = Controller::Type::AmigaMouse;
+      type = Controller::Type::AtariMouse;
     else if(isProbablyAmigaMouse(image, size))
       type = Controller::Type::AmigaMouse;
     else if(usesKeyboard(image, size, port))
@@ -690,6 +692,29 @@ bool ControllerDetector::isProbablyLightGun(const ByteBuffer& image, size_t size
       if (searchForBytes(image, size, signature[i], SIG_SIZE))
         return true;
   }
-
+  return false;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool ControllerDetector::isProbablyQuadTari(const ByteBuffer& image, size_t size,
+                                            Controller::Jack port)
+{
+  uInt8 signatureBoth[] = { 0x1B, 0x1F, 0x0B, 0x0E, 0x1E, 0x0B, 0x1C, 0x13 }; // "QUADTARI"
+
+  if(searchForBytes(image, size, signatureBoth, 8))
+    return true;
+
+  if(port == Controller::Jack::Left)
+  {
+    uInt8 signature[] = { 'Q', 'U', 'A', 'D', 'L' };
+
+    return searchForBytes(image, size, signature, 5);
+  }
+  else if(port == Controller::Jack::Right)
+  {
+    uInt8 signature[] = { 'Q', 'U', 'A', 'D', 'R' };
+
+    return searchForBytes(image, size, signature, 5);
+  }
   return false;
 }
diff --git a/src/emucore/ControllerDetector.hxx b/src/emucore/ControllerDetector.hxx
index be24ae09d..1e21b447f 100644
--- a/src/emucore/ControllerDetector.hxx
+++ b/src/emucore/ControllerDetector.hxx
@@ -121,6 +121,9 @@ class ControllerDetector
     static bool isProbablyLightGun(const ByteBuffer& image, size_t size,
                                    Controller::Jack port);
 
+    // Returns true if a QuadTari code pattern is found.
+    static bool isProbablyQuadTari(const ByteBuffer& image, size_t size,
+                                   Controller::Jack port);
 
   private:
     // Following constructors and assignment operators not supported
diff --git a/src/emucore/DefProps.hxx b/src/emucore/DefProps.hxx
index 65f2d67ca..36e71288c 100644
--- a/src/emucore/DefProps.hxx
+++ b/src/emucore/DefProps.hxx
@@ -27,3525 +27,3525 @@
 
 static constexpr uInt32 DEF_PROPS_SIZE = 3518;
 
-static const BSPF::array2D<const char*, DEF_PROPS_SIZE, 23> DefProps = {{
-  { "000509d1ed2b8d30a9d94be1b3b5febb", "Greg Zumwalt", "", "Jungle Jane (2003) (Greg Zumwalt) (Hack)", "Hack of Pitfall!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0060a89b4c956b9c703a59b181cb3018", "CommaVid, Irwin Gaines - Ariola", "CM-008 - 712 008-720", "Cakewalk (1983) (CommaVid) (PAL)", "AKA Alarm in der Backstube", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "007d18dedc1f0565f09c42aa61a6f585", "CCE", "C-843", "Worm War I (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "008543ae43497af015e9428a5e3e874e", "Retroactive", "", "Qb (V2.09) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "00b7b4cbec81570642283e7fc1ef17af", "SEGA - Beck-Tech, Steve Beck, Phat Ho", "006-01", "Congo Bongo (1983) (SEGA)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "00ce0bdd43aed84a983bef38fe7f5ee3", "20th Century Fox, Bill Aspromonte", "11012", "Bank Heist (1983) (20th Century Fox)", "AKA Bonnie and Clyde, Cops 'n' Robbers, Holdup, Rooring 20's", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "00ce76ad69cdc2fa36ada01ae092d5a6", "Bit Corporation", "PGP214", "Cosmic Avenger (4 Game in One) (1983) (BitCorp) (PAL)", "AKA StarMaster", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "00dc28b881989c39a6cf87a892bd3c6b", "CCE", "", "Krull (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "00e19ebf9d0817ccfb057e262be1e5af", "Atari, Ed Logg, Carol Shaw", "CX2639, CX2639P", "Othello (1981) (Atari) (PAL) [no grid markers]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "00e55b27fe2e96354cd21b8b698d1e31", "", "", "Phoenix (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "00eaee22034aff602f899b684c107d77", "Rainbow Vision - Suntek - Sunteck Corp", "SS-001", "Time Race (1983) (Rainbow Vision) (PAL)", "AKA Space Jockey", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "00f7985c20b8bdf3c557fac4d3f26775", "Aaron Curtis", "", "AStar (NTSC)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "012020625a3227815e47b37fd025e480", "Rob Kudla", "", "Better Space Invaders (1999) (Rob Kudla) (Hack) [a]", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "01293bd90a4579abb7aed2f7d440681f", "Century", "", "Snoopy (1983) (Century) (PAL)", "AKA Snoopy and the Red Baron", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "01297d9b450455dd716db9658efb2fae", "TechnoVision - Video Technology", "TVS1002", "Save Our Ship (1983) (TechnoVision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "012b8e6ef3b5fd5aabc94075c527709d", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix (1983) (Arcadia)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 56", "", "", "", "" },
-  { "0164f26f6b38a34208cd4a2d0212afc3", "Coleco, Ed English", "2656", "Mr. Do! (1983) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "0173675d40a8d975763ee493377ca87d", "CBS Electronics, Ed English", "4L1751", "Roc 'n Rope (1984) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "01abcc1d2d3cba87a3aa0eb97a9d7b9c", "Jone Yuan Telephonic Enterprise Co", "", "Topy (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "01b09872dcd9556427761f0ed64aa42a", "Galaga Games", "", "River Raid (1984) (Galaga Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "01cb3e8dfab7203a9c62ba3b94b4e59f", "Atari, Mimi Nyden, Scott Smith, Robert Vieira", "CX26127", "Gremlins (1984) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "01e5c81258860dd82f77339d58bc5f5c", "CCE", "", "Corrida da Matematica (CCE)", "AKA Math Gran Prix", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "01e60a109a6a67c70d3c0528381d0187", "ITT Family Games, Perry Rhodan-Serie", "554-33 383", "Fire Birds (1983) (ITT Family Games) (PAL)", "AKA Sky Alien", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "01f584bf67b0e464014a8c8b5ea470e3", "Arcadia Corporation, Dennis Caswell", "5 AR-4200", "Labyrinth (Escape from the Mindmaster Beta) (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "02066b17f29082412c6754c1a2d6302e", "", "", "Demo Image Series #3 - Baboon (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "024365007a87f213cbe8ef5f2e8e1333", "Atari, Frank Hausman, Mimi Nyden, Steve Woita", "CX2686", "Quadrun (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "025668e36a788e8af8ac4f1be7e72043", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX2659", "Raiders of the Lost Ark (06-14-82) (Atari) (Prototype)", "Console ports are swapped", "Prototype", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" },
-  { "026180bf641ff17d8577c33facf0edea", "Activision, Steve Cartwright", "AX-022", "Seaquest (1983) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0277c449fae63f6f1c8f94dedfcf0058", "", "", "Laser Demo (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "027a59a575b78860aed780b2ae7d001d", "CCE", "", "Pressure Cooker (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "028024fb8e5e5f18ea586652f9799c96", "Coleco - Woodside Design Associates, Steve 'Jessica Stevens' Kitchen", "2468", "Carnival (1982) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "02811151906e477d47c135db5b1699c6", "", "", "FlickerSort Demo (Updated) (20-04-2002) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "02a5fc90a0d183f870e8eebac1f16591", "HES", "771-422", "2 Pak Special - Star Warrior, Frogger (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "02ab2c47bc21e7feafa015f90d7df776", "Atari", "MA017600", "Diagnostic Test Cartridge 2.6 (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "02ced7ea2b7cb509748db6bfa227ebec", "Parker Brothers, Ed English, David Lamkins", "931502", "Frogger (1982) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "02cee0b140d2f1a1efcfb1d482a5c392", "Atari, Ed Logg, Carol Shaw - Sears", "CX2639 - 49-75162", "Othello (1981) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "02dcba28c614fec7ca25955327128abb", "Andrew Wallace", "", "Laseresal 2002 (PAL) (PD) [a]", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "02e3f4ba156fb578bef7d7a0bf3400c1", "", "", "Booster (Junkosoft) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "033e21521e0bf4e54e8816873943406d", "20th Century Fox Video Games - Sirius Software, Dan Thompson", "11020", "Earth Dies Screaming, The (1983) (20th Century Fox)", "The Day the Earth Stood Still", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "034c1434280b0f2c9f229777d790d1e1", "Telegames", "5665 A016", "Baseball (1988) (Telegames) (PAL)", "AKA Super Challenge Baseball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0375f589f7da06d2d2be532e0d4d4b94", "", "", "Push (V0.04) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0383dc02cb82302da3d155fd108bfe3a", "AtariAge, Chris Spry", "CX26200", "Princess Rescue (2013) (Sprybug) (PAL60)", "Compatible with Genesis controller", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "YES", "" },
-  { "038e1e79c3d4410defde4bfe0b99cc32", "Atari, Tod Frye, Gary Shannon", "", "Aquaventure (08-12-1983) (Atari) (Prototype)", "AKA Sea Sentinel", "Unbelievably Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "039cf18b459d33b8a8fca31d06c4c244", "", "", "Demo Image Series #0 (12-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "03b1051c9374678363c899914412cfc5", "", "", "Incoming (30-10-2002) (Ben Larson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "03c3f7ba4585e349dd12bfa7b34b7729", "SEGA, Jeff Lorenz", "004-01", "Star Trek - Strategic Operations Simulator (1983) (SEGA)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "03fbcee0bc80e31f27254aea3d920510", "Bit Corporation", "R320", "Trick Shot (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "03ff9e8a7af437f16447fe88cea3226c", "Bomb - Onbase", "CA285", "Wall-Defender (1983) (Bomb)", "AKA Wall Break", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "04014d563b094e79ac8974366f616308", "Atari, Andrew Fuchs, Courtney Granner, Jeffrey Gusman, Mark R. Hahn", "CX2690", "Pengo (1984) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "041b5e56bbc650db574bd8db3fae2696", "Thomas Jentzsch", "", "Thrust (V1.0) (2000) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "043f165f384fbea3ea89393597951512", "Spectravision - Spectravideo", "SA-202", "Planet Patrol (1982) (Spectravision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0443cfa9872cdb49069186413275fa21", "M Network - INTV, Patricia Lewis Du Long, Ron Surratt", "MT4518", "BurgerTime (1983) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "045035f995272eb2deb8820111745a07", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (1983) (Arcadia)", "AKA Jungle Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "047ac3b9faea64522b7a23c4465a7aa8", "", "", "Defender (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "04856e3006a4f5f7b4638da71dad3d88", "Atari, Douglas Neubauer", "CX26176", "Radar Lock (1989) (Atari) (PAL)", "AKA Dog Fight", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "049626cbfb1a5f7a5dc885a0c4bb758e", "", "", "MegaMania (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "04b488d4eef622d022a0021375e7e339", "Home Vision - Gem International Corp. - VDI", "VCS83107", "Tennis (1983) (Home Vision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "04cf9e6898007024622ed6a0b295961f", "Bit Corporation", "R320", "Tennis (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "04dfb4acac1d0909e4c360fd2ac04480", "Thomas Jentzsch", "", "Jammed (2001) (XYPE) (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "04e737c9d53cd84bfd5ee679954e4706", "Jone Yuan Telephonic Enterprise Co", "", "Checkers (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "04fccc7735155a6c1373d453b110c640", "HES - Imagineering, David Lubar", "535", "My Golf (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0519f395d5f7d76be813b834aa51c0be", "Atari, Ian Shepard", "CX2604", "Space War (1978) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0546f4e6b946f38956799dd00caab3b1", "Thomas Jentzsch", "", "My Golf (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "056f5d886a4e7e6fdd83650554997d0d", "Parker Brothers, Ed Temple", "931504", "Amidar (1982) (Parker Bros) (PAL)", "", "Uncommon", "", "", "", "A", "A", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "056ff67dd9715fafa91fb8b0ddcc4a46", "", "", "Frisco (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "05824fcbe615dbca836d061a140a50e0", "Jeffry Johnston", "", "Radial Pong - Version 9 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "05aedf04803c43eb5e09dfd098d3fd01", "", "", "Keystone Kapers (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "05aff8f626ef870432ae3b3d9d5aa301", "Activision, Bob Whitehead", "AG-019", "Sky Jinks (1982) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "05b45ba09c05befa75ac70476829eda0", "Parker Brothers, Rex Bradford", "931507", "Star Wars - Jedi Arena (1983) (Parker Bros) (PAL)", "Uses the Paddle Controllers (swapped)", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 50", "", "", "", "" },
-  { "05c60458ec69e7fe8b1be973852d84f1", "", "", "Test (1996) (J.V. Matthews) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "05c765a63e61882abd1c2d627b652225", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Amiga Mouse Hack v1.1 (NTSC) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "05ccf96247af12eef59698f1a060a54f", "Otto Versand", "600273", "King Arthur (1983) (Otto Versand) (PAL)", "AKA Dragonfire (Double-Game Package)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "05d61b925d3d2474bab83f0a79bb5df1", "Eckhard Stolberg", "", "Cosmic Ark Stars (1997) (Eckhard Stolberg)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "05eb4347f0ec8f4783983ca35ffd8d1b", "", "", "Qb (2.06) (Retroactive) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "05ebd183ea854c0a1b56c218246fbbae", "Atari, Dan Hitchens", "CX2656", "SwordQuest - EarthWorld (1982) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "05f11fb2e45c4e47424d3cb25414d278", "", "", "Boring (NTSC) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "060c865c782debb047e6fd101c8923fc", "Atari", "CX26163P", "Freeway Rabbit (32 in 1) (1988) (Atari) (PAL) (4K)", "AKA Freeway", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0614ed51acd027d531e7c85c4f435292", "", "", "Narnia (Glenn Saunders) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0619e1c3286bbfbace040b8c3ec5add2", "Omegamatrix", "", "Millipede (Atari Trak-Ball) v6.5 (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "PAL60", "", "", "" },
-  { "0651216c4a4a9c9ac5ada3013a317c72", "Jone Yuan Telephonic Enterprise Co", "", "Fishing Derby (Jone Yuan) (4K) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "06742cf522f23797157f215a1dc8a1a9", "", "", "Healthbars (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0685bd0bcb975ceef7041749a5454a48", "Piero Cavina", "", "11 Sprite Demo (Piero Cavina) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "069c17beb1e8e0557adb8539fdcf6cba", "", "", "Phantom II & Pirate (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "06b0194ce992584c365278e0d7323279", "Activision", "", "Unknown Activision Game #2 (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "06b6c5031b8353f3a424a5b86b8fe409", "Activision, Mike Lorenzen - Ariola", "EAX-023 - 711 023-720", "Oink! (1983) (Activision) (PAL)", "AKA Das Schweinchen und der Wolf", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "06cfd57f0559f38b9293adae9128ff88", "Telegames", "4317 A009", "Adventures on GX-12 (1988) (Telegames) (PAL)", "AKA Adventures of Tron", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "06d2f7674cea977607f74c464ce600a2", "CBS Electronics, Alex Nevelson", "4L 2737 0000", "Omega Race (1983) (CBS Electronics) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "BOOSTERGRIP", "", "", "", "", "", "", "", "", "" },
-  { "06db908011065e5ebb37f4e253c2a0b0", "", "", "Gopher (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "06e5dc181a8eda1c31cc7c581c68b6ef", "", "", "Tac-Scan (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "071f84d10b343c7c05ce3e32af631687", "Rainbow Vision - Suntek", "SS-019", "Curtiss (1983) (Rainbow Vision) (PAL)", "AKA Atlantis", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "072a6ea2181ca0df88ac0dedc67b239d", "", "", "Multiple Missiles Demo (19-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "073cb76b006af034fd150be3f5e0e7e6", "", "", "Mobile 48 Sprite Kernel (Bug Fixed) (10-01-2003) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "073d7aff37b7601431e4f742c36c0dc1", "", "", "Bermuda (Unknown) (PAL)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "074ec425ec20579e64a7ded592155d48", "Atari - Sculptured Software, Steve Aguirre", "CX26162", "Fatal Run (Ultimate Driving) (1991) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "075069ad80cde15eca69e3c98bd66714", "CCE", "C-803", "Bobby Is Going Home (1983) (CCE)", "AKA Bobby Vai Para Casa", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0751f342ee4cf28f2c9a6e8467c901be", "Atari, Mimi Nyden, Joseph Tung", "CX26152", "Super Baseball (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "07973be3ecfd55235bf59aa56bdef28c", "Suntek", "SS-036", "Criminal Pursuit (1983) (Suntek) (PAL)", "AKA A Mysterious Thief", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "079fe9103515d15bc108577e234a484d", "", "", "Multi-Color Demo 0 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "07a3af1e18b63765b6807876366f5e8a", "Joe Grand", "", "SCSIcide Pre-release 2 (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "07c76f2d88552d20ad2c0ed7aef406c6", "Cody Pittman", "", "Blob (Cody Pittman) (Hack)", "Hack of Halloween", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "07f42847a79e4f5ae55cc03304b18c25", "Zellers", "", "Sea Hawk (Zellers)", "AKA Seahawk", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "07f84db31e97ef8d08dc9fa8a5250755", "Supergame", "", "Enduro (1984) (Supergame)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "07f91e33e76f53bb9d2731fd5d8a35a5", "Atari", "CX2632", "Space Invaders (1978) (Atari) [t1]", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0805366f1b165a64b6d4df20d2c39d25", "Atari, Dan Hitchens", "CX2650", "Berzerk (1982) (Atari) (PAL)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "08188785e2b8300983529946dbeff4d2", "Atari, Carla Meninsky, Ed Riddle - Sears", "CX2611 - 99821, 49-75149", "Indy 500 (1977) (Atari) (4K)", "Uses the Driving Controllers", "", "", "", "", "", "", "", "", "DRIVING", "DRIVING", "", "", "", "45", "", "", "", "" },
-  { "081e2c114c9c20b61acf25fc95c71bf4", "Parker Brothers, Ed English, David Lamkins", "PB5300", "Frogger (1982) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "082fdc8bd47fef01482ce5883c4ffdb8", "Charles Morgan", "", "Tanks DX (Charles Morgan) (Hack)", "Hack of Tanks But No Tanks", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0832fb2ee654bf9382bc57d2b16d2ffc", "Apollo - Games by Apollo, Ed Salvo", "AP-1001", "Skeet Shoot (1981) (Apollo) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "083e7cae41a874b2f9b61736c37d2ffe", "Imagic, Rob Fulop, Bob Smith", "720106-2A, IA3600P, EIX-009-04I", "Riddle of the Sphinx (1982) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "085322bae40d904f53bdcc56df0593fc", "Parker Brothers, Dave Engman, Dawn Stockbridge", "PB5340", "Tutankham (1983) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0856f202b18cd46e44fd1dc3b42e9bfb", "", "", "Frame Counter 1 (2001) (Jake Patterson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0866e22f6f56f92ea1a14c8d8d01d29c", "Androbot - Western Technologies, Michael Case, Lenny Carlson", "", "AndroMan on the Moon (1984) (Western Tech) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0891252ee4e307689febccf3cfd8a8ab", "Thomas Jentzsch", "", "Centipede - Atari Trak-Ball Hack v1.4 (PAL60) (Half-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0894aa7be77521f9df562be8d9555fe6", "CBS Electronics, Dan Kitchen, Garry Kitchen", "4L1700, 4L1701, 4L1702, 4L1802, 4L2274", "Donkey Kong (1982) (CBS Electronics) (PAL) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "08989fa4ff537f5dbd611aff4019521a", "Atari, Gary Palmer", "CX26163P", "Fun with Numbers (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "08bd4c1dcc843f6a0b563d9fd80b3b11", "Quelle", "343.273 9", "Phantompanzer II (1983) (Quelle) (PAL)", "AKA Thunderground", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "08bf437d012db07b05ff57a0c745c49e", "Arcadia Corporation, Steve Hales, Stephen H. Landrum", "4 AR-4102", "Meteoroids (1982) (Arcadia) (Prototype)", "Suicide Mission Beta", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "08d1b6d75206edb999252caf542a2c7f", "Larry Petit", "", "Super Home Run (2003) (Larry Petit) (Hack)", "Hack of Home Run", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "08d60a58a691c7f690162850302dc0e1", "", "", "Poker Squares (V0.27) (PAL) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "08e5960bb52d9a3e2c9954677b5e4472", "Atari - CCW, Christopher H. Omarzu, Preston Stuart, Bruce Williams", "CX26101", "Oscar's Trash Race (10-20-1982) (Atari) (Prototype)", "Uses the Keypad Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "08ea2fdaa22e5802c839ee7dfb0483dc", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Trak-Ball Hack v1.2 (PAL60) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "08f4dc6f118f7c98e2406c180c08e78e", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix - Tug of War (2 of 3) (1983) (Arcadia) (PAL)", "Uses Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "02", "", "", "", "" },
-  { "08f853e8e01e711919e734d85349220d", "Atari, Jerome Domurat, Michael Sierchio", "CX2667", "RealSports Soccer (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0906c6e0e4bda9c10cfa4c5fc64d2f4b", "Retroactive", "", "Qb (V0.12) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "090f0a7ef8a3f885048d213faa59b2f8", "Carrere Video - Western Technologies, John Hall - Teldec - Prism", "USC1012", "M.A.D. (1983) (Carrere Video) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "09274c3fc1c43bf1e362fda436651fd8", "Thomas Jentzsch", "", "Acid Drop (TJ)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "09388bf390cd9a86dc0849697b96c7dc", "Absolute Entertainment, Alex DeMeo", "AG-045-04, AK-045-04", "Pete Rose Baseball (1988) (Absolute)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0945081a6bd00345ff3d58eb7a07330a", "", "", "Stampede (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0956285e24a18efa10c68a33846ca84d", "Dismac", "", "Viagem Espacial (Dismac)", "AKA Star Voyager", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0963aa9f7f6cf5a36ff700001583624e", "Franklin Cruz", "", "Space Invaders 2 (Hack) [o1]", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "096649575e451508006b17e0353259a5", "Justin J. Scott", "", "Yar Vs. Yar (2002) (Justin J. Scott) (Hack)", "Hack of Yars' Revenge", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "097074f24cde141fe6a0f26a10333265", "", "", "Marble Craze (V0.90) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "097936b07e0e0117b9026ae6835eb168", "Imagic, Dennis Koble", "720100-2B, IA3000P", "Trick Shot (1982) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "09abfe9a312ce7c9f661582fdf12eab6", "Atari, Douglas Neubauer", "CX26154", "Super Football (1988) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "09e1ecf9bd2a3030d5670dba7a65e78d", "Atari, James Andreasen", "CX2654", "Haunted House (1982) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "09e9ba0762fd0c3cf3c2e072cff79cac", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (1984) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "09f89bbfa2ab00f1964d200e12d7ced0", "Atari", "MA017600", "Diagnostic Test Cartridge 2.6 (1982) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0a1b98937911d621b004b1617446d124", "", "", "Hangman Pac-Man Biglist1 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0a981c03204ac2b278ba392674682560", "Atari, Bob Whitehead - Sears", "CX2651 - 99805, 49-75602", "Blackjack (1977) (Atari)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "" },
-  { "0aa208060d7c140f20571e3341f5a3f8", "U.S. Games Corporation - Western Technologies,  Jeff Corsiglia, Paul Allen Newell, Tom Sloper", "VC1009", "Towering Inferno (1982) (U.S. Games)", "Uses the Joystick Controllers (swapped)", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "YES", "" },
-  { "0abf64ca504a116adca80f77f85e00fb", "", "", "Cube Conquest (Billy Eno) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0ac0d491763153fac75f5337ce32a9d6", "", "", "SPAM Image Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0acaf71e60b89f6b6eab63db6ab84510", "", "", "This Planet Sucks (Greg Troutman) [a2]", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0aceb7c3bd13fe048b77a1928ed4267d", "Imagic, Bob Smith", "720102-2B, IA3201P, EIX-011-04I", "Star Voyager (1982) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0ad9a358e361256b94f3fb4f2fa5a3b1", "Atari, Carol Shaw, Nick 'Sandy Maiwald' Turner - Sears", "CX2608 - 49-75165", "Super Breakout (1982 - 1981) (Atari) [a]", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 45", "", "", "", "" },
-  { "0adb21206de92e8aec5ef295805ebb90", "", "", "Solaris (Genesis)", "Genesis controller (C switches to map mode)", "Hack of Solaris", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0ae3497e731ca0bf6a77b23441d9d9f9", "", "", "Analog Clock (V0.0) (20-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0af51ceb4aecc7a8fc89781ac44a1973", "Barry Laws Jr.", "", "Face Invaders Deluxe (Barry Laws Jr.) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0afe6ae18966795b89314c3797dd2b1e", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692, CX2692P", "Moon Patrol (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0b01909ba84512fdaf224d3c3fd0cf8d", "", "", "Revenge of the Apes (Hack)", "Hack of Planet of the Apes", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0b1056f1091cfdc5eb0e2301f47ac6c3", "Tigervision - Software Electronics Corp., Karl T. Olinger - Teldec", "7-001 - 3.60001 VE", "King Kong (1982) (Tigervision) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0b17ed42984000da8b727ca46143f87a", "Atari - CCW, Christopher H. Omarzu", "CX26104", "Big Bird's Egg Catch (05-17-1983) (Atari) (Prototype)", "Uses the Keypad Controller", "Prototype", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "" },
-  { "0b24658714f8dff110a693a2052cc207", "CCE", "C-815", "Seaquest (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0b33252b680b65001e91a411e56e72e9", "CCE", "C-832", "Atlantis (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0b4e793c9425175498f5a65a3e960086", "CCE", "", "Kung Fu Master (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0b55399cf640a2a00ba72dd155a0c140", "Imagic, Wilfredo Aguilar, Michael Becker, Rob Fulop", "720111-1A, 03205", "Fathom (1983) (Imagic)", "AKA Scuba", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "0b577e63b0c64f9779f315dca8967587", "Videospielkassette - Ariola", "PGP236", "Raketen-Angriff (Ariola) (PAL)", "AKA Missile Control", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0b8d3002d8f744a753ba434a4d39249a", "Sears Tele-Games, Robert Zdybel", "CX2619 - 49-75159", "Stellar Track (1981) (Sears)", "AKA Stella Trak", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "0bf19e40d5cd8aa5afb33b16569313e6", "Atari, Jerome Domurat, Andrew Fuchs, Dave Staugas, Robert Vieira", "CX26118", "Millipede (01-04-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0bf1e354304f46c0caf8fc0f6f5e9525", "Arcadia Corporation, Stephen Harland Landrum", "AR-4105", "Official Frogger (1983) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0bfabf1e98bdb180643f35f2165995d0", "Atari, Bob Whitehead - Sears", "CX2623 - 6-99819, 49-75108, 49-75125", "Home Run (1978) (Atari)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" },
-  { "0c0392db94a20e4d006d885abbe60d8e", "", "", "Dodge Demo 3 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0c336f83b0e6e3bc86c77f368448e77b", "Bit Corporation", "R320", "Circus Atari (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0c35806ff0019a270a7acae68de89d28", "Froggo", "FG1003", "Task Force (1987) (Froggo)", "AKA Gangster Alley", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0c48e820301251fbb6bcdc89bd3555d9", "Atari, Bill Aspromonte, Andrew Fuchs", "CX26120", "Stargate (1984) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0c54811cf3b1f1573c9164d5f19eca65", "Activision, David Crane - Ariola", "EAG-001, PAG-001, EAG-001-04B, EAG-001-04I - 711 001-715", "Dragster (1980) (Activision) (PAL)", "AKA Dragster Rennen, Drag Strip", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0c72cc3a6658c1abd4b735ef55fa72e4", "Dion Olsthoorn", "v1.3", "Amoeba Jump (2018) (Dionoid) (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0c7926d660f903a2d6910c254660c32c", "Atari, Larry Kaplan", "CX2602, CX2602P", "Air-Sea Battle (1977) (Atari) (PAL)", "AKA Anti-Aircraft", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0c7bd935d9a7f2522155e48315f44fa0", "Carrere Video - Western Technologies, Jeff Corsiglia, Paul Allen Newell, Tom Sloper - Teldec - Prism", "USC1009", "Infernal Tower (1983) (Carrere Video) (PAL)", "AKA Towering Inferno", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "YES", "" },
-  { "0c80751f6f7a3b370cc9e9f39ad533a7", "Atari, Carla Meninsky", "CX2610", "Warlords (1981) (Atari) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
-  { "0cb7af80fd0ddef84844481d85e5d29b", "", "", "Mr. Pac-Man (El Destructo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0cc8224ff1edfe458e8629e9e5fe3f5b", "Thomas Jentzsch", "", "Trick 12 (2001) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0cdd9cc692e8b04ba8eb31fc31d72e5e", "Thomas Jentzsch", "", "Wing War (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0cebb0bb45a856b23f56d21ce7d1bc34", "20th Century Fox Video Games, Bill Aspromonte", "11131", "Crash Dive (1983) (20th Century Fox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0cec9e46a25d338bf595a29aa2606516", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Mouse Hack v1.1 (PAL60) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0cfdd2f3b243cac21f38a0f09f54bead", "", "", "Overhead Adventure Demo 4 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0d07d2c1be1a5eaaea235a533bcda781", "", "", "Scrolling Playfield 1 (Junkosoft) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0d08558f34a47e4eaa39d01c8efb81f0", "Thomas Jentzsch", "", "Missile Control - Atari Mouse Hack v1.15 (NTSC) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0d09cff0d28033c02c3290edfc3a5cea", "Atari, Jerome Domurat, Steve Woita", "CX2699", "Taz (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0d1b3abf681a2fc9a6aa31a9b0e8b445", "Atari", "CX26163P", "Laser Blast (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0d27c7f5db349b592f70f68daf5e8f3b", "", "", "Space Instigators (21-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0d35618b6d76ddd46d2626e9e3e40db5", "", "", "X-Doom V.26 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0d5af65ad3f19558e6f8e29bf2a9d0f8", "Atari - Sculptured Software, Adam Clayton", "CX26151, CX26151P", "Dark Chambers (1989) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "0d6b974fe58a1bdd453600401c407856", "Atari", "", "128-in-1 Junior Console (Chip 3 or 4) (1991) (Atari) (PAL)", "Actually contains only 16 games, not 32", "", "", "", "16IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0d786a41695e5fc8cffd05a6dbb3f659", "", "", "Scrolling Playfield With Score (10-02-2003) (Aaron Bergstrom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0d7e630a14856f4d52c9666040961d4d", "", "", "Wavy Line Test (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0d90a0ee73d55539b7def24c88caa651", "Activision, Bob Whitehead", "AG-005, CAG-005, AG-005-04", "Skiing (1980) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0db4f4150fecf77e4ce72ca4d04c052f", "Atari, Carol Shaw - Sears", "CX2618 - 49-75123", "3-D Tic-Tac-Toe (1980) (Atari)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0dd4c69b5f9a7ae96a7a08329496779a", "Tigervision - Software Electronics Corp., Karl T. Olinger - Teldec", "7-001 - 3.60001 VE", "King Kong (1982) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0de53160a8b54c3aa5aed8d68c970b62", "Quelle", "806.174 9", "Fuchs & Schweinchen Schlau (1983) (Quelle) (PAL)", "AKA Oink!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0dfbdadf8f1bc718e7e1bb3ccd5fef3d", "", "", "Mr. Pac-Man (New start tune) (El Destructo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0e0808227ef41f6825c06f25082c2e56", "", "", "Candi (Hack) [a]", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0e08cd2c5bcf11c6a7e5a009a7715b6a", "", "", "Boing! (PD) [a1]", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0e224ea74310da4e7e2103400eb1b4bf", "Atari, Peter C. Niday, Gary Shannon, Howard Scott Warshaw", "", "Mind Maze (10-10-1984) (Atari) (Prototype)", "Uses the MindLink controller", "Prototype", "", "", "", "", "", "", "", "", "MINDLINK", "", "", "", "", "", "", "", "" },
-  { "0e23d0ed4c33b2011ab4cc93a7619683", "Thomas Jentzsch", "", "Centipede - Amiga Mouse Hack v1.4 (PAL60) (Half-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0e4b2b6e014a93ef8be896823da0d4ec", "", "", "Skiing (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0e713d4e272ea7322c5b27d645f56dd0", "Home Vision - Gem International Corp. - VDI", "VCS83105", "Panda Chase (1983) (Home Vision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0e7e73421606873b544e858c59dc283e", "Digivision", "", "Super Soccer (Digivision)", "AKA RealSports Soccer", "", "", "", "F8", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "0e86470791b26292abe1c64545c47985", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix - Down on the Line (3 of 3) (1983) (Arcadia) (PAL)", "Uses Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "01 70", "", "", "", "" },
-  { "0ec93f519bb769e0d9f80e61f6cc8023", "Atari - GCC, John Allred, Mike Feinstein", "CX2688", "Jungle Hunt (02-25-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0ecdb07bf9b36ef18f3780ef48e6c709", "Bit Corporation", "PG209", "Mr. Postman (1983) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0eebfb60d437796d536039701ec43845", "Fabrizio Zavagli", "", "Cakewalk (Fabrizio Zavagli)", "NTSC Conversion", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0eecb5f58f55de9db4eedb3a0f6b74a8", "Xonox - Beck-Tech", "6210, 06002, 06004, 99002", "Ghost Manor (1983) (Xonox) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0ef64cdbecccb7049752a3de0b7ade14", "Atari, Joe Decuir, Larry Caplan, Steve Mayer, Larry Wagner", "CX26163P", "Combat (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0efc91e45f61023cda9d086a7d3c402f", "B.J. Best (aka bjbest60)", "", "Space Cactus Canyon (2017)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "0effef4a341f8eebab65621c60c48787", "Thomas Jentzsch", "", "Reactor - Atari Trak-Ball Hack v1.3 (PAL) (Full-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0f14c03050b35d6b1d8850b07578722d", "Jeffry Johnston", "", "Radial Pong - Version 10 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0f24ca5668b4ab5dfaf217933c505926", "", "", "Fantastic Voyage (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0f2e09c71cc216f79d22a804152ba24b", "Bob Colbert", "", "Scroller Demo (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "0f341d1f4e144e3163d9a5fc5a662b79", "", "", "RUN Platform Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "0f39fc03d579d0d93a6b729a3746843e", "Atari, Sam Comstock, Richard Dobbis, Nick 'Sandy Maiwald' Turner", "CX26111", "Snoopy and the Red Baron (05-27-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0f604cd4c9d2795cf5746e8af7948064", "Champ Games", "CG-02-N", "Conquest Of Mars (2010) (NTSC)", "Rev 2 release", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0f643c34e40e3f1daafd9c524d3ffe64", "Atari, Robert C. Polaro, Alan J. Murphy - Sears", "CX2609 - 49-75186", "Defender (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0f6676b05621f80c670966e2995b227a", "", "", "Globe Trotter Demo 1 (24-03-2003) (Weston)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0f738dc44437557624eb277ed7ad91c9", "", "", "Grand Prix (Unknown) (PAL)", "AKA Grand Prix", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0f8043715d66a4bbed394ef801d99862", "Quelle", "684.733 9", "Robin Hood (1983) (Quelle) (PAL)", "AKA Save Our Ship", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0f95264089c99fc2a839a19872552004", "Activision, David Crane", "AG-009, AG-009-04", "Freeway (1981) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0fba7d8c3520bdb681f75494e498ec36", "", "", "Gunfight 2600 - Final Run (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0fbf618be43d4396856d4244126fe7dc", "Quelle", "805.784 6", "Labyrinth (1983) (Quelle) (PAL)", "AKA Maze Craze", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0fc161704c46e16f7483f92b06c1558d", "CCE", "C-853", "Spider Fighter (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0fcff6fe3b0769ad5d0cf82814d2a6d9", "Suntek", "SS-027", "Zoo Fun (1983) (Suntek) (PAL)", "AKA Panda Chase", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0fd72a13b3b6103fc825a692c71963b4", "Imagic, Rob Fulop", "720104-2A, IA3204P, EIX-008-04I", "Cosmic Ark (1982) (Imagic) (PAL) [selectable starfield]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "0fee596b974c9d3e70b367a3671599b6", "Bit Corporation", "R320", "Name This Game (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "101ab60f4000a5d13792ef0abad5f74b", "Atari, Jerome Domurat, Peter C. Niday, Robert Vieira", "CX26109", "Sorcerer's Apprentice (1983) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "102672bbd7e25cd79f4384dd7214c32b", "Atari, Alan Miller - Sears", "CX2642 - 6-99814", "Hunt & Score - Memory Match (1978) (Atari)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "103e9d616328969f5d7b4e0a381b25d5", "", "", "Playfield Illustration and Logo Demo (2001) (Jake Patterson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "103f1756d9dc0dd2b16b53ad0f0f1859", "Home Vision, Gem International Corp.", "", "Go Go Home Monster (1983) (Home Vision) (PAL)", "AKA Go Go Home", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "104468e44898b8e9fa4a1500fde8d4cb", "AtariAge, Chris Spry", "CX26200", "Princess Rescue (2013) (Sprybug)", "Compatible with Genesis controller", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "YES", "" },
-  { "106326c262dfd3e8eaeabd961d2a0519", "", "", "PAL-NTSC Detector (15-11-2002) (CT)[a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "106855474c69d08c8ffa308d47337269", "Atari - Sculptured Software, Adam Clayton", "CX26151", "Dark Chambers (1989) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "107cc025334211e6d29da0b6be46aec7", "Atari, Bob Smith - Sears", "CX2648 - 49-75161", "Video Pinball (1981) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1086ff69f82b68d6776634f336fb4857", "Activision, David Crane", "AG-009", "Bloody Human Freeway (1981) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "10958cd0a1a81d599005f1797ab0e51d", "", "", "Centipede 2k (2000) (PD) (Hack)", "Hack of Centipede", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "10a3cd14e5dcfdde6ff216a14ce7b7dd", "Atari", "CX262, CX2627P", "Human Cannonball (1979) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "10af8728f975aa35a99d0965de8f714c", "Dinatronic", "", "Seaquest (Dinatronic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "10c47acca2ecd212b900ad3cf6942dbb", "Atari - Axlon, Tod Frye - Heuristica, Agustin Ortiz", "CX26169", "Shooting Arcade (03-07-1989) (Atari) (Prototype) [a4]", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "10c8cfd8c37522f11d47540ff024e5f9", "Canal 3 - Intellivision", "C 3016", "Demon Attack (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "10eae73a07b3da044b72473d8d366267", "Funvision - Fund. Int'l Co.", "", "Karate (1982) (Funvision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "10f0ecaf962aef1fc28abed870b01b65", "Atari, Paul Donaldson", "", "Bionic Breakthrough (06-22-1984) (Atari) (Prototype)", "Uses the Mindlink Controller", "Prototype", "", "", "", "", "", "", "", "MINDLINK", "", "", "", "", "", "", "", "", "" },
-  { "10f62443f1ae087dc588a77f9e8f43e9", "Atari, Carla Meninsky", "CX2637, CX2637P", "Dodge 'Em (1980) (Atari) (PAL) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "110ac8ecaf1b69f41bc94c59dfcb8b2d", "", "", "Demon Attack (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "111029770226b319524134193886a10e", "Hozer Video Games", "", "Gunfight 2600 - One Limit Reached! (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "11330eaa5dd2629052fac37cfe1a0b7d", "128-in-1 Junior Console", "", "Human Cannonball (128-in-1 Junior Console) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "113cd09c9771ac278544b7e90efe7df2", "Atari, Ed Logg, Carol Shaw - Sears", "CX2639 - 49-75162", "Othello (1981) (Atari) [no grid markers]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "114c599454d32f74c728a6e1f71012ba", "Activision, Bob Whitehead - Ariola", "EAX-015, EAX-015-04I - 711 015-725", "Chopper Command (1982) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "11bcf5c752088b5aaf86d6c7a6a11e8d", "Atari, Jerome Domurat, Andrew Fuchs, Dave Staugas, Robert Vieira", "CX26118", "Millipede (1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "11e7e0d9437ec98fa085284cf16d0eb4", "", "", "Bowling (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "11f9532557e4c9569f4b242164006161", "Chris Walton, Justin Hairgrove, Tony Morse", "", "Hunchy II (2005) (PAL)", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1201c18cf00d2c236f42e4d7d8c86aa1", "", "", "Nick Bensema Demo (Nick Bensema)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "12080205f669b8e7783b976f8cf3d8bb", "Omegamatrix", "", "Star Wars Arcade (Amiga Mouse) v4 (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "12123b534bdee79ed7563b9ad74f1cbd", "Absolute Entertainment, Alex DeMeo", "AG-041-04", "Title Match Pro Wrestling (1987) (Absolute)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1228c01cd3c4b9c477540c5adb306d2a", "Atari, Alan Miller", "CX26163P", "Basketball (32 in 1) (1988) (Atari) (PAL)", "Console ports are swapped", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" },
-  { "1266b3fd632c981f3ef9bdbf9f86ce9a", "Activision, Bob Whitehead", "EAZ-034-04, EAZ-034-04I", "Private Eye (1984) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1267e3c6ca951ff1df6f222c8f813d97", "", "", "Dragonfire (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "126f7f64b7b00e25dcf5e3710b4cf8b8", "Atari - GCC", "CX2676", "Centipede (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1278f74ca1dfaa9122df3eca3c5bcaad", "Rainbow Vision - Suntek", "SS-013", "Bi! Bi! (Rainbow Vision) (PAL)", "AKA Skindiver", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1287535256bf5dff404839ac9e25c3e7", "PacManPlus", "Rev 2", "Alien Pac-Man (PacManPlus) (Hack)", "Hack of Alien", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "12937db3d4a80da5c4452b752891252d", "Digitel", "", "Megamania (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "12bca8305d5ab8ea51fe1cfd95d7ab0e", "Epyx, Steven A. Baker, Tod Frye, Peter Engelbrite", "80561-00250", "Summer Games (1987) (Epyx) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "12d7e0d6b187889f8d150bf7034d1db2", "", "", "Poker Squares (V0.0e) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "130c5742cd6cbe4877704d733d5b08ca", "Home Vision - Gem International Corp. - VDI", "VCS83109", "World End (1983) (Home Vision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1323c45d660f5a5b6d5ea45c6c4cbe4a", "Canal 3 - Intellivision", "", "Enduro (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "133456269a03e3fdae6cddd65754c50d", "Tigervision - Software Electronics Corporation - Teldec", "7-006 - 3.60008 VG", "Springer (1983) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "133a4234512e8c4e9e8c5651469d4a09", "Atari, Andrew Fuchs, Jeffrey Gusman, Dave Jolly, Suki Lee", "CX26117", "Obelix (1984) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "133b56de011d562cbab665968bde352b", "Activision, John Van Ryzin", "AG-038-04", "Cosmic Commuter (1984) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1343de49c2a50d99176255f99f0d0234", "Gray Games & AtariAge", "", "E.T. Book Cart (PAL)", "Charles F. Gray & Michael Rideout", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "55" },
-  { "13448eb5ba575e8d7b8d5b280ea6788f", "Digivision", "", "Crackpots (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1345e972dbe08ea3e70850902e20e1a5", "Greg Troutman", "", "Dark Mage (rough beta) (Greg Troutman) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "1351c67b42770c1bd758c3e42f553fea", "Digivision", "", "Keystone Kapers (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "135708b9a7dd20576c1b66ab2a41860d", "", "", "Hangman Man Biglist1 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "13584411da0a8d431991035423fdc0dc", "Jone Yuan Telephonic Enterprise Co", "", "Skiing (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1367e41858be525710eb04d0dab53505", "Kyle Pittman", "", "Zelda (2003) (Kyle Pittman) (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "136f75c4dd02c29283752b7e5799f978", "Atari, Dan Hitchens - Sears", "CX2650 - 49-75168", "Berzerk (1982) (Atari)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "13895ef15610af0d0f89d588f376b3fe", "Tigervision, Rorke Weigandt", "7-005", "Marauder (1982) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "13a37cf8170a3a34ce311b89bde82032", "Atari - GCC, Mark Ackerman, Tom Calderwood, Glenn Parker", "CX2684, CX2684P", "Galaxian (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "13a991bc9c2ff03753aeb322d3e3e2e5", "Funvision - Fund. International Co.", "", "Galactic (Funvision) (PAL)", "AKA Condor Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "13aa1f9ac4249947e4af61319d9a08f2", "Atari - GCC", "CX2680, CX2680P", "RealSports Tennis (1983) (Atari) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "13abc32f803165c458bb086fa57195fb", "Christian Samuel", "", "E.T. The Extra-Testical (Christian Samuel) (Hack)", "Hack of E.T. The Extra-Terrestrial", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "13ccc692f111d52fec75d83df16192e2", "Canal 3 - Intellivision", "", "Fishing Derby (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "13d8326bf5648db4dafce45d25e62ddd", "", "", "Atari Logo Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "13dfb095e519a555a5b60b7d9d7169f9", "", "", "Red Line Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "140909d204abd6841c64cdad4d7765b4", "", "", "Moving Blue Ladder Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "14163eb2a3ddd35576bd8527eae3b45e", "", "", "Multi-Color Demo 6 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1423f560062c4f3c669d55891a2bcbe7", "CCE", "C-859", "MASH (1983) (CCE) [a]", "AKA M.A.S.H", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1428029e762797069ad795ce7c6a1a93", "", "", "Thunderground (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "143918368f4f4dfff90999188c0197c9", "", "", "Unknown Title (bin00016 (200110)) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1442d1b35a6478fba22ae7dd1fcb5634", "Thomas Jentzsch", "", "Thrust (V0.2) (2000) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "148471144ccebd7f6aa9aa9215896533", "Parker Brothers - JWDA, Todd Marshall", "PB5550", "Q-bert's Qubes (1984) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "149b543c917c180a1b02d33c12415206", "CCE", "C-857", "Superman (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "14a56b493a8d9d10e94a3e100362e3a2", "Hozer Video Games", "", "Gunfight 2600 - Early Play-kernel (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "14b1e30982962c72f426e2e763eb4274", "Atari, Carol Shaw - Ralph Lauren", "", "Polo (1978) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "14c2548712099c220964d7f044c59fd9", "First Star Software, Alex Leavens, Shirley Ann Russell", "", "Boing! (1983) (First Star Software)", "AKA Bubbles, Soap Suds, The Emphysema Game", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "14d365bbfaac3d20c6119591f57acca4", "", "", "Video Life (Unknown) (4K) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "14dbb3686dd31964332dc2ef0c55cad0", "", "", "Demo Image Series #15 - Three Marios (PAL) (Non-Interleave) (06-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "151c33a71b99e6bcffb34b43c6f0ec23", "Parker Brothers, Laura Nikolich", "", "Care Bears (1983) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "151fa3218d8d7600114eb5bcd79c85cb", "Atari - CCW, Christopher H. Omarzu", "CX26104", "Big Bird's Egg Catch (05-02-1983) (Atari) (Prototype)", "Uses the Keypad Controller", "Prototype", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "" },
-  { "152c253478b009c275e18cd731b48561", "", "", "Quest (11-10-2002) (Chris Larkin)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "153f40e335e5cb90f5ce02e54934ab62", "Absolute Entertainment, Alex DeMeo", "EAZ-041-04I", "Title Match Pro Wrestling (1987) (Absolute) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1542662f665d2ffaa77b4b897dd2e2af", "", "", "Starfield (V1.0) (2002) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "155fa7f479dcba3b10b1494e236d6010", "Skyworks", "", "Tomcat (2002) (Skyworks) (PAL)", "AKA The F-14 Flight Simulator", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "157356f80c709ab675961d8b8b207e20", "", "", "Multi-Sprite Game V2.5 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "157bddb7192754a45372be196797f284", "Atari, Warren Robinett - Sears", "CX2613, 49-75154", "Adventure (1980) (Atari)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "159e5cd6ccb968015f49aed5adbc91eb", "Justin J. Scott", "", "Yar's Defeat (2002) (Justin J. Scott) (Hack)", "Hack of Yars' Revenge", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "15a0d59304dece2c7d0580f3ea3527f0", "Atari, Jerome Domurat, Peter C. Niday", "CX26115", "Dumbo's Flying Circus (04-04-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "15b498199ed0ed28057bf0dbdce9b8d8", "Thomas Jentzsch", "", "Jammed (V0.2) (Demo) (2001) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "15b9f5e2439bfaa08874b5184261c777", "Bit Corporation", "R320", "Space Invaders (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "15bcd74f2f1f2a63e1aa93e90d2c0555", "", "", "Incoming (22-08-2002) (Ben Larson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "15bf2ef7583bfcbbba630847a1dc5539", "Erik Eid", "", "Euchre (Jul 15) (2002) (Eric Eid) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "15c11ab6e4502b2010b18366133fc322", "Atari - Axlon, Tod Frye - Heuristica, Augustin Ortiz", "CX26169", "Shooting Arcade (09-19-1989) (Atari) (Prototype)", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "15dd21c2608e0d7d9f54c0d3f08cca1f", "Data Age, J. Ray Dettling", "112-008", "Frankenstein's Monster (1983) (Data Age)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "15fe28d0c8893be9223e8cb2d032e557", "", "", "Towering Inferno (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "1619bc27632f9148d8480cd813aa74c3", "Thomas Jentzsch", "", "Steeple Chase (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "161ded4a85d3c78e44fffd40426f537f", "Thomas Jentzsch", "", "JtzBall (Alpha) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "16229d61d7b0c89b01853660a8da22bb", "", "", "spin4a50", "", "", "", "", "4A50", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "163e7e757e2dc44469123ff0e5daec5e", "", "", "Many Blue Bars and Text Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "169d4c7bd3a4d09e184a3b993823d048", "", "", "Superman (Unknown) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "16cb43492987d2f32b423817cdaaf7c4", "Atari, Larry Kaplan - Sears", "CX2602 - 99802, 6-99802, 49-75102", "Air-Sea Battle (1977) (Atari)", "AKA Target Fun (Anti-Aircraft)", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "16cc6d1b4ddce51c767a1ba8e5ff196c", "", "", "Big - Move This Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "16d69f71bf5846639be5ff16483f0498", "Bit Corporation", "R320", "Golf (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "16e04823887c547dc24bc70dff693df4", "Atari", "CX26163P", "Tennis (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "16ee443c990215f61f7dd1e55a0d2256", "Spectravideo, David Lubar", "SA-218, SA-218C", "Bumper Bash (1983) (Spectravideo) (PAL)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "PADDLES", "", "", "", "", "", "", "", "", "" },
-  { "16f494f20af5dc803bc35939ef924020", "Mark De Smet", "", "Video Simon (Mark De Smet)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "170e7589a48739cfb9cc782cbb0fe25a", "M Network - INTV - APh Technological Consulting, Hal Finney", "MT5666", "Astroblast (1982) (M Network) [fixed]", "Can also use left joystick", "Uncommon", "", "", "", "", "", "", "", "PADDLES", "", "YES", "", "", "AUTO 55", "", "", "", "" },
-  { "171cd6b55267573e6a9c2921fb720794", "Kurt Howe", "", "Adventure 34 (Kurt Howe) (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "171ebf135b13ba907f462c10d88a2c25", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Amiga Mouse Hack v1.1 (PAL60) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1733772165d7b886a94e2b4ed0f74ccd", "", "", "Boring Journey Escape (Hack)", "Hack of Journey - Escape", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1738b2e3f25ab3eef3cecb95e1d0d957", "", "", "Hangman Monkey Biglist1 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "17512d0c38f448712f49f36f9d185c4e", "Retroactive", "", "Qb (Release Candidate #1) (Retroactive)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "17515a4d0b7ea5029ffff7dfa8456671", "Piero Cavina", "", "Multi-Sprite Demo V1.1 (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "176d3fba7d687f2b23158098e103c34a", "Zach Matley", "", "Combat AI (16-02-2003) (Zach Matley)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "177504abd4260c4265e1338955e9fa47", "HCC Software", "", "Pitfall! (Steroids Hack)", "Hack of Pitfall! (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1782929e1c214b70fb6884f77c207a55", "Activision, David Crane", "AX-018, AX-018-04", "Pitfall! (1982) (Activision) (Prototype)", "Pitfall Harry's Jungle Adventure (Jungle Runner)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "17ba72433dd41383065d4aa6dedb3d91", "", "", "SCSIcide (09-06-2001) (Joe Grand)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "17badbb3f54d1fc01ee68726882f26a6", "M Network - INTV - APh Technological Consulting, Hal Finney, Bruce Pedersen", "MT5659", "Space Attack (1982) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "17bbe288c3855c235950fea91c9504e9", "Dismac", "", "Pega Ladrao (Dismac)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "17c0a63f9a680e7a61beba81692d9297", "U.S. Games Corporation - Western Technologies, Jeff Corsiglia, David Johnson, Tom Sloper", "VC2004", "Picnic (1983) (U.S. Games)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" },
-  { "17d000a2882f9fdaa8b4a391ad367f00", "Atari - GCC", "CX2676", "Centipede (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "17ee158d15e4a34f57a837bc1ce2b0ce", "Atari - GCC, Mike Feinstein, Kevin Osborn", "CX2691, CX2691P", "Joust (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "17ee23e5da931be82f733917adcb6386", "Salu, Dennis M. Kiss", "460758", "Acid Drop (1992) (Salu) (PAL)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1802cc46b879b229272501998c5de04f", "Atari - CCW, Christopher H. Omarzu", "CX26104", "Big Bird's Egg Catch (1983) (Atari)", "Uses Kids/Keypad Controllers", "Rare", "", "", "", "", "", "", "", "KEYBOARD", "KEYBOARD", "", "", "", "", "", "", "", "" },
-  { "183020a80848e06a1238a1ab74079d52", "Thomas Jentzsch", "", "Missile Command (Amiga Mouse) (2002) (TJ) (PAL)", "Uses Amiga Mouse Controller", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "1862fca4f98e66f363308b859b5863af", "Atari", "", "128-in-1 Junior Console (Chip 1 of 4) (1991) (Atari) (PAL)", "Actually contains only 16 games, not 32", "", "", "", "16IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "18a970bea7ac4d29707c8d5cd559d03a", "", "", "Bridge (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "18b28b386abdadb3a700ac8fb68e639a", "Manuel Polik", "", "Gunfight 2600 (MP) (PAL)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "18b476a34ce5e6db2c032029873ac39b", "Bit Corporation", "R320", "Atlantis (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "18be8981b8201638f3ed8ae92bb4c215", "Thomas Jentzsch", "", "Missile Control - Amiga Mouse Hack v1.15 (PAL60) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "18bebbbd41c234f82b1717b1905e6027", "", "", "Space Instigators (Public Release) (02-01-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "18d26111cef66dff0c8af8cf0e117843", "", "", "Tunnel Demo (Cycling Colours 2) (29-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "18dc28bc22402f21e1c9b81344b3b8c5", "Atari - GCC, Mark Ackerman, Glenn Parker", "CX2684, CX2684P", "Galaxian (1983) (Atari) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "18ed63e3ce5bc3dd2d8bd188b807f1a2", "", "", "Stell-A-Sketch (Bob Colbert) (PD) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "18f299edb5ba709a64c80c8c9cec24f2", "Home Vision - Gem International Corp. - VDI", "VCS83111", "Asteroid Fire (1983) (Home Vision) (PAL)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "19098c46da0640f2b5763167dea6c716", "Andrew Wallace", "", "Laseresal 2002 (NTSC) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "191449e40b0c56411c70772706f79224", "", "", "Multi-Color Demo 2 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "19162393786098d50587827588198a86", "Jone Yuan Telephonic Enterprise Co", "", "Flag Capture (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "191ac4eec767358ee3ec3756c120423a", "", "", "Checkers (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "192aa2e8c795c9e10a7913e5d41feb81", "Atari - GCC, Jaques Hugon, Seth Lipkin", "CX26125", "Los Angeles 1984 Games (1984) (Atari) (Prototype) (PAL)", "AKA Track and Field (Uses Track & Field Controller)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "193f060553ba0a2a2676f91d9ec0c555", "Atari, Carol Shaw", "CX2636, CX2636P", "Video Checkers (1980) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1942bdb7abc75e412068330a9082b0ff", "Atari, Omegamatrix", "", "Super Breakout Menu (2020) (PAL) (Hack)", "Hack of Super Breakout", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 55", "", "", "", "" },
-  { "1986f864e32e3e8d198b5becf3022257", "Thomas Jentzsch", "", "Reactor - Atari Trak-Ball Hack v1.3 (PAL) (Half-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "199985cae1c0123ab1aef921daace8be", "", "", "Euchre (Release Candidate 2) (PAL) (01-10-2002) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "199eb0b8dce1408f3f7d46411b715ca9", "Parker Brothers, David Lamkins, Laura Nikolich", "PB5900", "Spider-Man (1982) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "19a9d3f9fa1b1358fb53009444247aaf", "", "", "Blackjack (Unknown) (PAL) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "" },
-  { "19abaf2144b6a7b281c4112cff154904", "Atari, Brad Stewart", "CX2649, CX2649P", "Asteroids (1981) (Atari) (PAL) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "19b3b807507653516985ba95da92499d", "Joe Gaucher", "", "VCS Draw Demo (Joe Gaucher)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "19d6956ff17a959c48fcd8f4706a848d", "PlayAround - J.H.M.", "202", "Burning Desire (1982) (PlayAround)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "19d9b5f8428947eae6f8e97c7f33bf44", "", "", "Fortress (Dual Version) (20-04-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "19e739c2764a5ab9ed08f9095aa2af0b", "Atari, Andrew Fuchs, Jeffrey Gusman, Dave Jolly, Suki Lee", "CX26117", "Obelix (1984) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "19e761e53e5ec8e9f2fceea62715ca06", "Panda", "104", "Scuba Diver (1983) (Panda)", "AKA Skindiver", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1a23540d91f87584a04f184304a00648", "", "", "Race Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1a613ce60fc834d4970e1e674b9196b3", "Home Vision - Gem International Corp. - VDI", "VCS83135", "Tanks War (1983) (Home Vision) (PAL)", "AKA Phantom Tank", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1a624e236526c4c8f31175e9c89b2a22", "Rainbow Vision - Suntek", "SS-007", "Space Raid (1983) (Rainbow Vision) (PAL) [a]", "AKA MegaMania", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1a8204a2bcd793f539168773d9ad6230", "Atari, Rob Fulop - Sears", "CX2638 - 49-75166", "Missile Command (1981) (Atari) [no initials]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1aa7344b563c597eecfbfcf8e7093c27", "David Marli", "", "Slot Invaders (David Marli) (Hack)", "Hack of Slot Machine", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1b0f3d7af668eeea38ddd6182d8f48fb", "Jone Yuan Telephonic Enterprise Co", "", "Cosmic Swarm (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "1b1daaa9aa5cded3d633bfcbeb06479c", "", "", "Ship Demo (V 1502) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1b22a3d79ddd79335b69c94dd9b3e44e", "Tron", "", "Moon Patrol (Tron)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1b4b06c2a14ed3ee73b7d0fd61b6aaf5", "Arcadia Corporation, Stephen H. Landrum", "AR-4400", "Excalibur (Dragonstomper Beta) (1982) (Arcadia) (Prototype) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1b5a8da0622bffcee4c5b42aed4e0ef0", "Akor", "", "TV Boy II (1992) (Akor)", "Includes 127 games", "", "", "", "", "", "", "", "", "JOYSTICK", "JOYSTICK", "", "", "", "", "", "", "", "" },
-  { "1b8c3c0bfb815b2a1010bba95998b66e", "Telegames", "", "Frogs and Flies (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1b8d35d93697450ea26ebf7ff17bd4d1", "Quelle - Otto Versand", "176.764 9 - 781644", "Marineflieger (1983) (Quelle) (PAL)", "AKA Seahawk", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1bb91bae919ddbd655fa25c54ea6f532", "Suntek", "SS-026", "Treasure Island (1983) (Suntek) (PAL)", "AKA Treasure Discovery", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1bc2427ac9b032a52fe527c7b26ce22c", "Intellivision Productions - M Network - APh Technological Consulting, Bruce Pedersen, Larry Zwick", "MT5860", "Sea Battle (1983) (M Network)", "High Seas", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1bef389e3dd2d4ca4f2f60d42c932509", "Dimax - Sinmax", "SM8001", "Space Robot (1983) (Dimax - Sinmax) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "1bf503c724001b09be79c515ecfcbd03", "", "", "Bumper Bash (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1bfae770e089fa81412d04eb299f4c3f", "Thomas Jentzsch", "", "Marble Craze - Atari Mouse Hack v1.0 (NTSC) (TJ)", "Uses Atari Mouse Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1c3f3133a3e5b023c77ecba94fd65995", "CCE", "C-830", "Planet Patrol (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1c5796d277d9e4df3f6648f7012884c4", "Rainbow Vision - Suntek", "SS-012", "Hey! Stop! (1983) (Rainbow Vision) (PAL)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1c666ba5aac19b81671357e76062989b", "Nukey Shay, Omegamatrix", "", "Double Dragon (Genesis) (PAL60) V2", "Genesis controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1c6eb740d3c485766cade566abab8208", "Atari, Michael Kosaka, Peter C. Niday, Robert Vieira", "CX26110", "Crystal Castles (1984) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1c85c0fc480bbd69dc301591b6ecb422", "CCE", "", "Super Box (CCE)", "AKA RealSports Boxing", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1c8c42d1aee5010b30e7f1992d69216e", "PlayAround - J.H.M.", "205", "Gigolo (1982) (PlayAround)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "1cad3b56cc0e6e858554e46d08952861", "Jone Yuan Telephonic Enterprise Co", "", "Chopper Command (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1cafa9f3f9a2fce4af6e4b85a2bbd254", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX2659", "Raiders of the Lost Ark (1982) (Atari) (PAL)", "Console ports are swapped", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" },
-  { "1cca2197d95c5a41f2add49a13738055", "Atari, Larry Kaplan - Sears", "CX2664 - 6-99818", "Brain Games (1978) (Atari)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "KEYBOARD", "KEYBOARD", "", "", "", "", "", "", "", "" },
-  { "1cf59fc7b11cdbcefe931e41641772f6", "SEGA", "005-01", "Buck Rogers - Planet of Zoom (1983) (SEGA)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "1d1d2603ec139867c1d1f5ddf83093f1", "Atari, Larry Kaplan - Sears", "CX2602 - 99802, 6-99802, 49-75102", "Air-Sea Battle (1977) (Atari) (4K)", "AKA Target Fun (Anti-Aircraft)", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1d284d6a3f850bafb25635a12b316f3d", "CCE", "", "H.E.R.O. (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1d2a28eb8c95da0d6d6b18294211839f", "", "", "Fishing Derby (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1d4e0a034ad1275bc4d75165ae236105", "20th Century Fox Video Games, Mark Klein", "11034", "Pick Up (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1d5eac85e67b8cff1377c8dba1136929", "", "", "Chronocolor Donkey Kong Sideways (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1d6ed6fe9dfbde32708e8353548cbb80", "Jone Yuan Telephonic Enterprise Co", "", "Super Challenge Baseball (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1d72cc6ee466a4af1b27587b900ed430", "Atari, Omegamatrix", "", "Space Invaders Menu (2020) (Hack)", "Hack of Space Invaders", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1da2da7974d2ca73a823523f82f517b3", "Spectravision - Spectravideo - Sirius Software, David Lubar", "SA-206", "Challenge of.... Nexar, The (1982) (Spectravision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1db3bc4601f22cf43be7ce015d74f59a", "", "", "Ship Demo (V 10) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1e060a8025512ad2127e3da11e212ccc", "Arcadia Corporation, Scott Nelson", "13", "Sweat! - The Decathlon Game (3 of 3) (1983) (Arcadia) (Prototype)", "Uses the Paddle Controllers (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1e0ef01e330e5b91387f75f700ccaf8f", "Quelle - Otto Versand", "686.561 2 - 781627", "Mein Weg (1983) (Quelle) (PAL)", "AKA Challenge", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "1e1290ea102e12d7ac52820961457e2b", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (12-15-1983) (Parker Bros) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "1e272d09c0e55f5ef14fcb76a735f6d7", "Atari, David Crane", "CX26163P", "Slot Machine (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1e31b3a48865ba98d4d1aa5205115983", "Atari - Roklan, Bob Curtiss", "", "Firefox (1983) (Atari) (Prototype)", "AKA Combat II, Fighter Command", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1e587ca91518a47753a28217cd4fd586", "Telesys, Jim Rupp, Jack Woodman", "1001", "Coco Nuts (1982) (Telesys)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1e750000af77cc76232f4d040f4ab060", "Jone Yuan Telephonic Enterprise Co", "", "Raft Rider (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1e85f8bccb4b866d4daa9fcf89306474", "Atari, Lou Harp", "CX26122", "Sinistar (02-13-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1e89f722494608d6ea15a00d99f81337", "", "", "River Raid (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "NTSC50", "", "", "" },
-  { "1ea1abcd2d3d3d628f59a99a9d41b13b", "Jone Yuan Telephonic Enterprise Co", "", "Stampede (Jone Yuan) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1ea980574416bfd504f62575ba524005", "Atari - GCC, Mark Ackerman, Glenn Parker", "CX2675", "Ms. Pac-Man (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1ec57bbd27bdbd08b60c391c4895c1cf", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX26119", "Saboteur (09-02-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1ec5bef77b91e59313cba205f15b06d7", "", "", "Overhead Adventure Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1ede4f365ce1386d58f121b15a775e24", "Parker Brothers, Dave Hampton, Tom Sloper", "931517", "Q-bert (1983) (Parker Bros) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1ee2cfc7d0333b96bd11f7f3ec8ce8bc", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (4 of 4) (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1ee9c1ba95cef2cf987d63f176c54ac3", "Atari - GCC, Mark Ackerman, Glenn Parker", "CX2675, CX2675P", "Ms. Pac-Man (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1ef04e7e508296a8d9eb61cc7dae2e5d", "SOLID Corp. (D. Scott Williamson)", "CX2655-069", "Star Castle 2600 (SolidCorp) [069]", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "1f21666b8f78b65051b7a609f1d48608", "K-Tel Vision", "", "Vulture Attack (1982) (K-Tel Vision)", "AKA Condor Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1f2ae0c70a04c980c838c2cdc412cf45", "Atari - GCC", "CX2698", "Rubik's Cube (1984) (Atari)", "AKA Atari Video Cube", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1f349dd41c3f93c4214e5e308dccb056", "", "", "Virtual Pet Demo 2 (CRACKERS) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1f40eefc7447336ae6cd8ffa5eb325be", "Atari, Chris Crawford", "", "Wizard (1980) (Atari) (Prototype) (4K) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1f562b89d081e36d58e6fc943512ec05", "", "", "Hangman Man Biglist2 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1f5a2927a0b2faf87540b01d9d7d7fd1", "Pet Boat", "", "Tennis (Pet Boat) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1f60e48ad98b659a05ce0c1a8e999ad9", "", "", "Mondo Pong V2 (Piero Cavina) (PD)", "Uses the Paddle Controllers", "New Release", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "01", "", "", "", "" },
-  { "1f773a94d919b2a3c647172bbb97f6b4", "Atari, Jerome Domurat, Peter C. Niday", "CX26115", "Dumbo's Flying Circus (07-11-1983) (Atari) (Prototype) (PAL)", "AKA Dumbo Flies Home", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1fa58679d4a39052bd9db059e8cda4ad", "Imagic, Dan Oliver", "720118-1A, 03208", "Laser Gates (1983) (Imagic)", "AKA Innerspace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1fa7a42c2c7d6b7a0c6a05d38c7508f4", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (09-04-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "1fa86282403fa35d103ab88a9d603c31", "SpiceWare - Darrell Spice Jr.", "", "Stay Frosty (SpiceWare) (PAL60)", "Part of Stella's Stocking 2007 Xmas compilation", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "1fab68fd67fe5a86b2c0a9227a59bb95", "20th Century Fox Video Games - Videa, Lee Actor", "", "Lasercade (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "200309c8fba0f248c13751ed4fc69bab", "Jeffry Johnston", "", "Radial Pong - Version 1 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2008c76deba5953201ef75a09b2ff7dc", "", "", "Fortress (21-04-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "200a9d2a7cb4441ce4f002df6aa47e38", "", "", "Doomzerk (PD) (Hack)", "Hack of Berzerk", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2016726db38ad6a68b4c48ba6fe51557", "Piero Cavina, Erik Mooney", "", "INV 2 (Piero Cavina, Erik Mooney)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "203049f4d8290bb4521cc4402415e737", "Tigervision, Robert H. O'Neil - Teldec", "7-007 - 3.60005 VG", "Polaris (1983) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "203abb713c00b0884206dcc656caa48f", "Imagic, Bob Smith", "720114-1A, 03207, IZ-001-04", "Moonsweeper (1983) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "203b1efc6101d4b9d83bb6cc1c71f67f", "Quelle", "685.996 1", "Teller-Jonglieren! (1983) (Quelle) (PAL)", "AKA Dancing Plate", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "205070b6a0d454961dd9196a8e81d877", "", "", "Hangman Monkey Biglist2 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2058cf3fefad4d2bc03ed817cedddcd4", "Thomas Jentzsch", "", "Reactor - Amiga Mouse Hack v1.3 (PAL60) (Full-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2091af29b4e7b86914d79d9aaa4cbd20", "CBS Electronics - Woodside Design Associates, Harley H. Puthuff Jr.", "4L1802", "Donkey Kong Junior (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "20ae62fb69c6cc6e8098cca8cd080487", "Zirok", "", "Tennis (Zirok)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "20d4457ba22517253fcb62967af11b37", "Atari, Eric Manghise, Mimi Nyden, Joseph Tung", "CX2640", "RealSports Baseball (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "20dca534b997bf607d658e77fbb3c0ee", "Mythicon, Bill Bryner, Bruce de Graaf", "MA1002", "Fire Fly (1983) (Mythicon)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "20edcc3aa6c189259fa7e2f044a99c49", "Spectravision - Spectravideo", "SA-201", "Gangster Alley (1982) (Spectravision) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "211774f4c5739042618be8ff67351177", "Atari - GCC, Mark Ackerman, Tom Calderwood, Glenn Parker", "CX2684", "Galaxian (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "211f76dff0b7dad3f6fcac9d938ee61a", "JSK", "", "Custer's Viagra (JSK) (Hack) [a]", "Hack of Custer's Revenge", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "211fbbdbbca1102dc5b43dc8157c09b3", "Apollo", "AP-2009", "Final Approach (1982) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2124cf92978c46684b6c39ccc2e33713", "", "", "Sea Monster (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "21299c8c3ac1d54f8289d88702a738fd", "K-Tel Vision", "", "Spider Maze (1982) (K-Tel Vision)", "AKA Spider Kong", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "212d0b200ed8b45d8795ad899734d7d7", "Atari, Richard Maurer, Christopher H. Omarzu - Coca Cola", "", "Pepsi Invaders (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "213e5e82ecb42af237cfed8612c128ac", "Sancho - Tang's Electronic Co.", "TEC006", "Forest (1983) (Sancho) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "2162266b906c939b35c84ff9a0f50ad1", "Atari, Larry Kaplan", "CX2664, CX2664P", "Brain Games (1978) (Atari) (PAL) (4K)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "KEYBOARD", "KEYBOARD", "", "", "", "", "", "", "", "" },
-  { "2179dfd7edee76efafe698c1bc763735", "", "", "Yellow Submarine (Cody Pittman) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "217b1452881264ac75126bf77b8d0db8", "Thomas Jentzsch", "", "Centipede - Atari Trak-Ball Hack v1.4 (NTSC) (Full-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "218b76f5a4142dc2ea9051a768583d70", "Atari - GCC, Mark Ackerman, Glenn Parker", "CX2684, CX2684P", "Galaxian (1983) (Atari) (PAL) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "218c0fe53dfaaa37f3c823f66eafd3fc", "Atari, Alan Miller", "CX2624, CX2624P", "Basketball (1978) (Atari) (PAL)", "Console ports are swapped", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" },
-  { "21a96301bb0df27fde2e7eefa49e0397", "Data Age", "DA1003", "Sssnake (1982) (Data Age)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "21b09c40295c2d7074a83ae040f22edf", "", "", "Marble Craze (V0.90) (Easy Version) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "21d2c435bcccde7792d82844b3cf60f4", "Atari - GCC, Doug Macrae", "CX2677, CX2677P", "Dig Dug (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "21d7334e406c2407e69dbddd7cec3583", "Activision, Bob Whitehead", "AG-011", "Stampede (1981) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2228c67d25e507603d4873d3934f0757", "", "", "Fu Kung! (V0.10) (28-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "22319be7a640af5314ec3c482cceb676", "", "", "Joustpong (05-07-2002) (Kirk Israel) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2240655247d6de1c585564004a853ab7", "", "", "Fu Kung! (V0.17) (07-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "225522777dc7155627808bde0c1d0ef0", "", "", "This Planet Sucks Demo 1 (Greg Troutman) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "22675cacd9b71dea21800cbf8597f000", "Atari, David Crane", "CX2605, CX2605P", "Outlaw (1978) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "227532d82505c3c185a878273c285d5f", "", "", "Hangman Man Original Words (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "22abbdcb094d014388d529352abe9b4b", "Apollo", "AP-2012", "Squoosh (1983) (Apollo) (Prototype) [a]", "AKA Vat's Incredible!, The Grape Escape", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "22b22c4ce240303012e8a9596ae8d189", "", "", "Skeleton+ (03-05-2003) (Eric Ball) (PAL)", "", "", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "22f6b40fc82110d68e50a1208ae0bb97", "", "", "Purple Bar Demo (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2319922df4d0c820b3e5f15faa870cc3", "Atari - GCC, Mike Feinstein", "CX2681, CX2681P", "Battlezone (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2327456f86d7e0deda94758c518d05b3", "Digitel", "", "Mr. Postman (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2351d26d0bfdee3095bec9c05cbcf7b0", "", "", "Warring Worms (19-01-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2353725ec98e0f0073462109e886efd7", "Champ Games", "CG-03-P", "Scramble (PAL60)", "Compatible with Genesis controller", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "YES", "" },
-  { "235436ab0832370e73677c9c6f0c8b06", "", "", "Beast Invaders (Double Shot) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2365e1534d67f94d8670394ab99150ce", "Thomas Jentzsch", "", "Missile Command (Atari Mouse) (2002) (TJ)", "Uses Atari ST Mouse Controller", "Homebrew", "", "", "", "", "", "", "", "ATARIMOUSE", "ATARIMOUSE", "", "", "", "", "", "", "YES", "" },
-  { "23d445ea19a18fb78d5035878d9fb649", "CBS Electronics - JWDA, Sylvia Day, Todd Marshall, Henry Will IV", "4L1818, 4L1819, 4L1820, 4L1821", "Mouse Trap (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "23e4ca038aba11982e1694559f3be10f", "", "", "Big Dig (V3) (20-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "23fad5a125bcd4463701c8ad8a0043a9", "CCE", "C-840", "Stone Age (1983) (CCE)", "Uses the Joystick Controllers (swapped)", "", "", "", "", "A", "A", "", "YES", "", "", "", "", "", "", "", "", "YES", "" },
-  { "240bfbac5163af4df5ae713985386f92", "Activision, Steve Cartwright", "AX-022", "Seaquest (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2432f33fd278dea5fe6ae94073627fcc", "CBS Electronics, Tom DiDomenico", "4L2477, 4L2482, 4L2485, 4L4171", "Blueprint (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "2434102f30eeb47792cf0825e368229b", "Sparrow - Enter-Tech, Paul Walters, Rick Harris, George Hefner, Barbara Ultis", "", "Arkyology (1983) (Sparrow) (Prototype)", "ROM must be started in bank 0", "Prototype", "", "0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "24385ba7f5109fbe76aadc0a375de573", "CCE", "", "Xevious (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "2447e17a4e18e6b609de498fe4ab52ba", "CCE", "", "Super Futebol (CCE)", "AKA RealSports Soccer", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "244c6de27faff527886fc7699a41c3be", "", "", "Matt Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2450dfa1df70d12b60683185775efed8", "Jeffry Johnston", "", "Radial Pong - Version 7 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "24544ee5d76f579992d9522e9b238955", "Carrere Video - Western Technologies, Jeff Corsiglia, David Johnson, Tom Sloper - Teldec - Prism", "USC2004", "Picnic (1983) (Carrere Video) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" },
-  { "245f07c8603077a0caf5f83ee6cf8b43", "Home Vision - Thomas Jentzsch", "", "Parachute (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "24759be31e8fe55d2829fd86bdf3181f", "Hozer Video Games", "", "Gunfight 2600 - Worst Nightmare... (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "247fa1a29ad90e64069ee13d96fea6d6", "CCE", "C-867", "Radar (1983) (CCE)", "AKA Exocet", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "248668b364514de590382a7eda2c9834", "CBS Electronics, Richard K. Balaska Jr., Bob Curtiss, Alex Leavens, Alex Nevelson", "", "Kick-Man (01-08-82) (CBS Electronics) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2496d404bfc561a40a80bea6a69695c3", "CCE", "C-1007", "Jungle Hunt (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "24ad538291eb5f5cac4b9998f3b851c3", "", "", "Gunfight 2600 - This time it's your decission! (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "24aff972d58990f9b88a6d787c796f1e", "CBS Electronics", "4L1767, 4L1768, 4L1769, 4L1770", "Smurf (1982) (CBS Electronics) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "24b5f4bbdb853eca38ea0cae2dfe73a1", "", "", "Home Run (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" },
-  { "24b9adac1b4f85b0bac9bf9b9e180906", "Angelino", "", "Space 2002 (Angelino) (Hack)", "Hack of Space Jockey", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "24d018c4a6de7e5bd19a36f2b879b335", "Activision, Larry Miller", "AX-021", "Spider Fighter (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "24d9a55d8f0633e886a1b33ee1e0e797", "Thomas Jentzsch", "", "Dragon Defender (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "24df052902aa9de21c2b2525eb84a255", "Imagic, Dennis Koble", "720000-100, 720100-1B, IA3000, IA3000C", "Trick Shot (1982) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "24fbf8250a71611e40ef18552e61b009", "", "", "Movable Grid Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2516f4f4b811ede4ecf6fbeb5d54a299", "Quelle", "701.134 9", "Schiessbude (1983) (Quelle) (PAL)", "AKA Carnival", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2517827950fee41a3b9de60275c8aa6a", "Atari", "CX26163P", "Fishing (32 in 1) (1988) (Atari) (PAL)", "AKA Fishing Derby", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "25265d0e7f88b3026003809f25ee025e", "Atari - GCC, Ava-Robin Cohen", "CX26123", "Jr. Pac-Man (1984) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "25472dfdeef6a42581a231d631d6b04d", "", "", "Gunfight 2600 - Design thoughts (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "25710bde8fa181b0c5cf0846b983bec1", "", "", "Demo Image Series #15 - Three Marios (NTSC) (06-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "257bc3b72a6b5db3fd0d47619125b387", "CBS Electronics", "4L 2737 0000", "Omega Race (1983) (CBS Electronics) [a]", "Set right difficulty to 'A' for BoosterGrip in both ports", "", "", "", "", "", "", "", "", "BOOSTERGRIP", "BOOSTERGRIP", "", "", "", "", "", "", "", "" },
-  { "25a21c47afe925a3ca0806876a2b4f3f", "Quelle", "685.640 5", "Der kleine Baer (1983) (Quelle) (PAL)", "AKA Frostbite", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "25b52bf8dd215bcbd59c9abdb55c44f8", "Atari - GCC, Betty Ryan Tylko, Doug Macrae", "CX2694, CX2694P", "Pole Position (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "25b6dc012cdba63704ea9535c6987beb", "Avalon Hill, Jean Baer, Bill Hood", "5004002", "Shuttle Orbiter (1983) (Avalon Hill)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "25bb080457351be724aac8a02021aa92", "CBS Electronics", "4L1784, 4L1786, 4L1787, 4L2277", "Zaxxon (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "25d4be3309b89583c6b39d9f93bf654f", "Activision, Bob Whitehead", "AX-015, AX-015-04", "Chopper Command (1982) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "25e73efb9a6edf119114718bd2f646ba", "Atari, Suki Lee", "CX26113", "Miss Piggy's Wedding (1983) (Atari) (Prototype) (4K) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "25f2e760cd7f56b88aac88d63757d41b", "Activision, Bob Whitehead - Ariola", "EAG-002, EAG-002-04I, PAG-002 - 711 002-715", "Boxing (1980) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "25f879ff678130fea615ac418e7943f1", "Activision, Garry Kitchen", "EAX-025", "Keystone Kapers (1983) (Activision) (SECAM)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "25f9cf703575c5d63048c222f5463758", "", "", "Multi-Sprite Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "260c787e8925bf3649c8aeae5b97dcc0", "Thomas Jentzsch", "", "Hell Driver (Thomas Jentzsch)", "NTSC Conversion, joystick ports swapped", "Homebrew", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" },
-  { "262ccb882ff617d9b4b51f24aee02cbe", "Atari, Douglas Neubauer", "CX26154, CX26154P", "Super Football (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "265a85f66544eaf95fda06c3d9e48abf", "", "", "Tunnel Demo (Cycling Colours) (29-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "265c74a956500bd31efd24adc6d5ccf6", "Activision, Larry Miller", "AX-026, AX-026-04", "Enduro (1983) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2683d29a282dd059535ac3bb250f540d", "", "", "Space Treat (12-01-2003) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "268f46038e29301568fa9e443e16e960", "Atarius Maximum", "", "Pitfall Unlimited (Atarius Maximus) (Hack)", "Hack of Pitfall", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "26bc2bdf447a17376aea7ef187ff6e44", "", "", "Amanda Invaders (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "26f4f8b098609164effef7809e0121e1", "", "", "Oystron (V2.7) (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "270229c6d5578446e6a588492e4e5910", "", "", "Space Invaders 2 (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2712e91f6f1dc55e90e2b14b27c042ac", "Omegamatrix", "", "SpaceMaster X-7 (Amiga Mouse) (PAL60) (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "271bfd5dc2673d382019f1fb6cab9332", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (Preview) (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "273ce50db5a0d6da7ea827a54f44dee9", "", "", "Island Flyer Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "274d17ccd825ef9c728d68394b4569d2", "Playaround - J.H.M.", "202", "Bachelorette Party (1982) (Playaround)", "AKA Bachelor Party, Uses the paddle controllers", "Extremely Rare", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "AUTO 65", "", "", "YES", "" },
-  { "277c7281ac945b8331e2e6fcad560c11", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (2 of 3) (1983) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "277cca62014fceebb46c549bac25a2e3", "Activision, Bob Whitehead", "AG-002, CAG-002, AG-002-04", "Boxing (1980) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "277fa4b9a6bb7a8dcea2c5f38a4c25f0", "Atari, Alan J. Murphy, Robert Zdybel", "CX2668", "RealSports Football (1982) (Atari) (Prototype)", "AKA Football II", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "278155fc9956e9b6ef2359eb238f7c7f", "", "", "Donkey Kong Junior (Unknown) (Hack)", "Hack of Donkey Kong Junior", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2783006ee6519f15cbc96adae031c9a9", "Telegames", "", "Night Stalker (1989) (Telegames) (PAL) [a]", "AKA Dark Cavern", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "278531cc31915747018d22145823d2c9", "", "", "Defender MegaDrive (PAL) (Genesis)", "Genesis controller (C is smartbomb)", "Hack of Defender", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "278f14887d601b5e5b620f1870bc09f6", "Thomas Jentzsch", "", "SWOOPS! (v0.96) (TJ)", "Uses the Joystick (L) and Paddle (R) Controllers", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "27a5d2d0c74c8e4b2c05b94c9f098eea", "Atari, Omegamatrix", "", "Video Olympics Menu (2020) (PAL60) (Hack)", "Hack of Video Olympics", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "AUTO 60", "", "", "", "" },
-  { "27baecd618e7e53dc11f2a9c559f529d", "Omegamatrix", "", "Star Wars Arcade (Atari Trak-Ball) v4 (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "27c4c2af4b46394bb98638af8e0f6e9d", "Atari, Jerome Domurat, Peter C. Niday, Robert Vieira", "CX26109", "Sorcerer's Apprentice (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "27c6a2ca16ad7d814626ceea62fa8fb4", "Parker Brothers, Mark Lesser", "PB5590", "Frogger II (1984) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "27f9e2e1b92af9dc17c6155605c38e49", "CCE", "", "Nightmare (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2808dc745ff4321dc5c8122abef6711f", "Retroactive", "", "Qb (2.11) (Retroactive) (Stella)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "28148a52b1955ce12c7a74d3a3e620a4", "CCE", "", "Freeway (CCE) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "281ff9bd0470643853de5cbd6d9e17f5", "Eckhard Stolberg", "", "Cubis (EM) (1997) (Eckhard Stolberg)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2823364702595feea24a3fbee138a243", "Bit Corporation", "PG206", "Bobby Is Going Home (1983) (BitCorp) (PAL)", "AKA Bobby geht Heim", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2825f4d068feba6973e61c84649489fe", "", "", "Boom Bang (Unknown) (PAL)", "AKA Crackpots", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "282a77841cb3d33af5b56151acba770e", "Otto Versand", "311388", "Black Hole (1983) (Otto Versand) (PAL)", "AKA Cosmic Ark (Double-Game Package)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "283cb03ee031c842beabdad1aa4e7dbc", "Bit Corporation", "R320", "Demon Attack (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "283dee88f295834c4c077d788f151125", "Retroactive", "", "Qb (2.11) (Retroactive) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "284ca61b2407bdba3938048b0a559015", "Atari, Tod Frye", "CX2695", "Xevious (05-25-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "2854e5dfb84173fafc5bf485c3e69d5a", "Canal 3 - Intellivision", "C 3004", "Moon Patrol (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2880c6b59bd54b153174676e465167c7", "Tron", "", "Donkey Kong Jr. (Tron)", "AKA Donkey Kong Junior", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "28a2bea8f84936cb2e063f857414cda0", "Thiago Paiva", "", "Mega Mania Raid (1999) (Thiago Paiva) (Hack)", "Hack of Megamania", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "28a4cd87fb9de4ee91693a38611cb53c", "", "", "Skeleton (V1.1) (NTSC) (24-10-2002) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "28d5df3ed036ed63d33a31d0d8b85c47", "Bit Corporation", "PG204", "Open, Sesame! (1983) (BitCorp) (PAL)", "AKA Sesam, Offne Dich", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "2903896d88a341511586d69fcfc20f7d", "Activision, David Crane", "AX-014, AX-014-04", "Grand Prix (1982) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "291bcdb05f2b37cdf9452d2bf08e0321", "Atari", "CX26163P", "32 in 1 Game Cartridge (1988) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "32IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "291cc37604bc899e8e065c30153fc4b9", "Activision, Carol Shaw", "AX-020, AX-020-04", "River Raid (1982) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "291dd47588b9158beebe4accc3a093a6", "Atari", "", "32 in 1 Console ROM (02-10-1989) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "32IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "292a0bb975b2587f9ac784c960e1b453", "", "", "Qb (05-02-2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "292f2446a0325b7b423e88a2ebfeb5a0", "", "", "Cube Conquest (Non Interlaced) (Billy Eno) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "29396db58406084e416032c372734a3e", "", "", "Gunfight 2600 - Fixed Beta Release! (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2942680c47beb9bf713a910706ffabfe", "", "", "Blue Line Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "294762000e853b4319f9991c1ced5dfc", "", "", "T.F. Space Invaders (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "295f3679bdf91ca5e37da3f787b29997", "", "", "Exorcise (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "29630a20d356fb58685b150bfa8f00c3", "M Network, Kevin Miller", "MT5687", "International Soccer (1982) (Mattel) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "297236cb9156be35679f83c4e38ee169", "Exus Corporation", "", "Video Reflex (1983) (Exus) [no roman numbers]", "AKA Foot Craz (no roman numbers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "297c405afd01f3ac48cdb67b00d273fe", "Atari - GCC, Ava-Robin Cohen", "CX26123, CX26123P", "Jr. Pac-Man (1986) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2982e655dffc89d218a0a3072cfc6811", "", "", "Mini Golf 812631 (Hack)", "Hack of Miniature Golf", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "298387b0637173d2002770a649b4fbca", "", "", "S.I.PLIX 2 (Hack) [a]", "Hack of Kaboom!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
-  { "29843f43b81f3736bf35c00b1bb88fb2", "Gray Games & AtariAge", "", "E.T. Book Cart (NTSC)", "Charles F. Gray & Michael Rideout", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "55" },
-  { "29949f893ef6cb9e8ecb368b9e99eee4", "Erik Eid", "", "Euchre (Alpha) (NTSC) (31-08-2002) (Erik Eid)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "29dfa26b7988af9984d617708e4fc6e2", "", "", "Boulderdash Demo (05-04-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2a0ba55e56e7a596146fa729acf0e109", "Activision, Bob Whitehead", "AG-019", "Sky Jinks (1982) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2a10053fd08664c7cfbbb104386ed77f", "", "", "Alpha Demo - The Beta Demo (2000) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2a1b454a5c3832b0240111e7fd73de8a", "Tigervision, Bill Hogue", "7-011", "Miner 2049er Volume II (1983) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "2a2f46b3f4000495239cbdad70f17c59", "CommaVid, John Bronstein - Ariola", "CM-003 - 712 003-720", "Cosmic Swarm (1982) (CommaVid) (PAL)", "AKA Angriff der Termiten", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "2a33e21447bf9e13dcfed85077ff6b40", "", "", "Backwards Cannonball v2 (Hack)", "Hack of Human Cannonball", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2a360bc85bf22de438651cf92ffda1de", "Bit Corporation", "PGP213", "Spy Vs. Spy (4 Game in One) (1983) (BitCorp) (PAL)", "AKA Chopper Command", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2a9f9001540c55a302befd8e9d54b47b", "Atari, Dan Hitchens", "CX2697, CX2697P", "Mario Bros. (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2aa5e56d36c2e58b6f2856109f2099a9", "Atari, Larry Kaplan - Sears", "CX2628 - 6-99842, 49-75117", "Bowling (1979) (Atari) (4K) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2aba6a1b01a5859e96d6a66d2286772f", "Activision, Steve Cartwright", "AX-027", "Plaque Attack (1983) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2abc3d46b3f2140160759e2e10bc86d9", "", "", "Gunfight 2600 - Beta Release! (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2ac3a08cfbf1942ba169c3e9e6c47e09", "Activision, Dan Kitchen", "EAK-046-04B", "Fighter Pilot (1988) (Activision) (PAL)", "AKA Tomcat - The F-14 Fighter Simulator", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2ae700c9dba843a68dfdca40d7d86bd6", "TechnoVision - Thomas Jentzsch", "", "Pharaoh's Curse (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "2aeedcc6eb1602efb77161b0cef832ab", "SOLID Corp. (D. Scott Williamson)", "CX2655-025", "Star Castle 2600 (SolidCorp) [025]", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "2b1589c7e1f394ae6a1c046944f06688", "Carrere Video - JWDA, Todd Marshall, Robin McDaniel, Wes Trager, Henry Will IV - Teldec - Prism", "USC2003", "Eggomania (1983) (Carrere Video) (PAL)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 60", "", "", "", "" },
-  { "2b27eb194e13f3b38d23c879cc1e3abf", "Quelle", "402.272 9", "Super-Ferrari (1983) (Quelle) (PAL)", "AKA Enduro", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2b42da79a682ed6e2d735facbf70107e", "", "", "DKjr Improved (Hack)", "Hack of Donkey Kong Jr.", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2b430c00dc79e495762ac59b2f9b4fcd", "Activision, David Crane", "AX-018, AX-018-04", "Pitfall! (1982) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2b71a59a53be5883399917bf582b7772", "Greg Troutman", "", "Dark Mage (final beta) (Greg Troutman) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "2ba02f509a4991aa176ba8d9e540df3d", "Atari, Mark R. Hahn", "CX2678", "Dukes of Hazzard (1983) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2bb0a1f1dee5226de648eb5f1c97f067", "Robby", "", "Enduro (Robby)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2bb9f4686f7e08c5fcc69ec1a1c66fe7", "Atari - GCC, John Allred, Mike Feinstein", "CX2688", "Jungle Hunt (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2bc26619e31710a9884c110d8430c1da", "Atari, Bob Whitehead", "CX2652, CX2652P", "Casino (1979) (Atari) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "" },
-  { "2bc6c53b19e0097a242f22375a6a60ff", "", "", "Droid Demo 2 (David Conrad Schweinsberg) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2bee7f226d506c217163bad4ab1768c0", "Xonox - K-Tel Software - Beck-Tech, Steve Beck", "6210, 06002, 06004, 99002", "Ghost Manor (1983) (Xonox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2bf34b6ad7d2317a2d0808b3fb93571b", "", "", "Easy Playfield Graphics (1997) (Chris Cracknell)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2c0dc885d5ede94aa664bf3081add34e", "", "", "Earth Dies Screaming, The (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2c29182edf0965a7f56fe0897d2f84ba", "Atari - Axlon, Steve DeFrisco", "CX26192", "Klax (08-18-1990) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2c2aea31b01c6126c1a43e10cacbfd58", "Paul Slocum", "", "Synthcart (2002) (Paul Slocum)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "2c3b2843295c9d6b16996971180a3fe9", "HES - Activision", "", "Sports Action Pak - Enduro, Ice Hockey, Fishing Derby, Dragster (1988) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2c3b9c171e214e9e46bbaa12bdf8977e", "Bit Corporation", "R320", "Othello (32 in 1) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2c45c3eb819a797237820a1816c532eb", "Atari", "CX26163P", "Boxing (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2c8835aed7f52a0da9ade5226ee5aa75", "Arcadia Corporation, Stephen H. Landrum", "AR-4101", "Communist Mutants from Space (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2c8c11295d8613f875b7bcf5253ab9bb", "Fabrizio Zavagli", "", "Kool Aid Man (PAL Conversion) (16-11-2002) (Fabrizio Zavagli) (PAL60)", "PAL60 Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2c9fadd510509cc7f28f1ccba931855f", "", "", "Hangman Invader Biglist1 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2ca6445204ffb7686ddee3e33ba64d5b", "Alex Herbert", "", "AtariVox Test ROM", "Uses the AtariVox controller", "", "", "", "", "", "", "", "", "", "ATARIVOX", "", "", "", "", "", "", "", "" },
-  { "2cb42cf62b2f25f59f909b5447821b14", "Atari, Christopher H. Omarzu - Children's Computer Workshop", "CX26104", "Big Bird's Egg Catch (1983) (Atari) (PAL) [a]", "Uses Kids/Keypad Controllers", "", "", "", "", "", "", "", "", "KEYBOARD", "KEYBOARD", "", "", "", "", "", "", "", "" },
-  { "2cc3049b7feb8e92f1870f1972629757", "Video Soft", "", "Atom Smasher (1984) (Video Soft) (Prototype) [stack pointer fix]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2cccc079c15e9af94246f867ffc7e9bf", "PlayAround - J.H.M.", "203", "Jungle Fever (1982) (PlayAround)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "2cefa695df2ed020899a7df7bb1e3a95", "Manuel Polik, Fabrizio Zavagli", "", "A-Team (2002) (Manuel Polik) (Hack)", "Hack of A-Team", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2cf20f82abcae2decff88db99331e071", "Activision, Mike Lorenzen", "AX-023", "Oink! (1983) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2cfb188c1091cc7ec2a7e60064d2a758", "", "", "Space Invaders Hack Demo (2003) (SnailSoft)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2d15b092e8350912ec4b2e5e750fa1c6", "Wizard Video Games, Bob Davis, Robert H. O'Neil", "", "Texas Chainsaw Massacre, The (1982) (Wizard Video Games) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2d16a8b59a225ea551667be45f554652", "Quelle", "802.744 3", "Der Geheimkurier (1983) (Quelle) (PAL)", "AKA Mr. Postman", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2d1cf85fbc732856bf76470cd4060f4a", "", "", "Daredevil (V1) (Stunt_Cycle_Rules!) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2d2c5f0761e609e3c5228766f446f7f8", "Atari - Axlon, Steve DeFrisco", "CX26170, CX26170P", "Secret Quest (1989) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2d33a44e82f88d05f6c50577218c0cae", "AtariAge - Michael Haas", "RC2", "Flappy (2014) (AtariAge)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2d38a96f92952b301eefdf25a5e6976b", "Omegamatrix", "", "Star Wars Arcade (Atari Mouse) (Y_Inverted) v4 (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2d405da70af82b20a6b3ecc3d1d2c4ec", "Genus", "", "Pitfall (Genus)", "AKA Pitfall!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2d6388a8389f1d59108fd169c3356d79", "Thomas Jentzsch", "", "Reactor - Atari Mouse Hack v1.3 (NTSC) (Half-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2d63b452f897818c52b3fceeb080a4d0", "HES - Absolute Entertainment", "", "Pete Rose Baseball (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2d6741cda3000230f6bbdd5e31941c01", "CBS Electronics - VSS", "80110", "Targ (1983) (CBS Electronics) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2d69a5f23784f1c2230143292a073b53", "", "", "Qb (Fixed background animation) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "2d6da0eb85eabc93270e5bb8a466ca51", "", "", "Sprite Demo 7 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2d76c5d1aad506442b9e9fb67765e051", "Apollo - Games by Apollo, Larry Minor, Ernie Runyon, Ed Salvo", "AP-2004", "Lost Luggage (1982) (Apollo) [no opening scene]", "AKA Airport Mayhem", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2d9e5d8d083b6367eda880e80dfdfaeb", "QDI, Mike Montana, Rich Montana - Selchow & Righter", "87", "Glib (1983) (QDI)", "AKA Video Word Game", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2d9e65959808a6098c16c82a59c9d9dc", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (1 of 3) (1982) (Starpath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2dbc92688f9ba92a7e086d62be9df79d", "", "", "How to Draw a Playfield (1997) (Jim Crawford) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2dbdca3058035d2b40c734dcf06a86d9", "Thomas Jentzsch", "", "Asteroids DC+ (Thomas Jentzsch) (Hack)", "Uses the Joystick (left) or Driving (right) Controller", "Hack", "", "", "", "", "", "", "", "", "DRIVING", "", "", "", "58", "", "", "YES", "" },
-  { "2dcf9ce486393cd36ca0928cd53b96cb", "Atari - GCC, Mike Feinstein, John Allred", "CX2688, CX2688P", "Jungle Hunt (1983) (Atari) (PAL) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2de41a11c6767e54a5ee9ebaffec72af", "Gray Games & AtariAge", "", "E.T. Book Cart (PAL60)", "Charles F. Gray & Michael Rideout", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "55" },
-  { "2dfec1615c49501fefc02165c81955e6", "", "", "Song (05-11-2002) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "2e0aed5bb619edcefa3fafb4fbe7c551", "", "", "Qb (2.06) (Retroactive) (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "2e2acef8513edcca991e7e5149412e11", "Parker Brothers, Larry Gelberg, Gary Goltz", "PB5065", "Star Wars - Ewok Adventure (1983) (Parker Bros) (Prototype) (16K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2e3728f3086dc3e71047ffd6b2d9f015", "Atari, David Crane", "CX26163P", "Outlaw (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2e5b184da8a27c4d362b5a81f0b4a68f", "Atari", "", "Rabbit Transit (08-29-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2e663eaa0d6b723b645e643750b942fd", "Atari, Tom Rudadahl - Sears", "CX2634 - 49-75121", "Golf (1980) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2e7e9c6dcfcceaffc6fa73f0d08a402a", "CCE", "C-818", "Star Voyager (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2e82a1628ef6c735c0ab8fa92927e9b0", "Atari, Jerome Domurat, Peter C. Niday, Robert Vieira", "CX26109", "Sorcerer's Apprentice (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2e842c2ee22e9dad9df16eed091315c4", "HES", "701-157", "2 Pak Special - Moto-cross, Boom Bang (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2eaf8fa9e9fdf1fcfc896926a4bdbf85", "Arcadia Corporation, Stephen H. Landrum", "AR-4400", "Excalibur Version 39 (Dragonstomper Beta) (1982) (Arcadia) (Prototype)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2ec6b045cfd7bc52d9cdfd1b1447d1e5", "Activision, David Crane - Ariola", "EAG-009, PAG-009 - 711 009-720", "Freeway (1981) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2eda6a49a49fcb2b674ea9e160b6a617", "Kyle Pittman", "", "Rambo in Afghanistan (Kyle Pittman) (Hack)", "Hack of Riddle of the Sphinx", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2ef36341d1bf42e02c7ea2f71e024982", "", "", "Space Invaders (Explosion Hack)", "Hack of Space Invaders (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2f0546c4d238551c7d64d884b618100c", "SEGA, Jeff Lorenz", "", "Ixion (1984) (SEGA) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2f0a8bb4e18839f9b1dcaa2f5d02fd1d", "CCE", "", "Super Futebol (CCE) [a]", "AKA RealSports Football", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "2f11ba54609777e2c6a5da9b302c98e8", "Atari - GCC", "CX2676", "Centipede (1982) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2f16663b01591539624d0ef52934a17d", "M Network", "", "Rocky and Bullwinkle", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2f2f9061398a74c80420b99ddecf6448", "Rentacom - Brazil", "", "Bobby Is Going Home (Rentacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2f66ebf037321ed0442ac4b89ce22633", "Baroque Gaming (Brian Eno)", "", "Warring Worms (Beta 2) (2002) (Baroque Gaming)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2f7772879a1ed04f660aa9d77a86a4bd", "", "", "Yars' Revenge (Genesis)", "Genesis controller (C is zorlon cannon)", "Hack of Yars' Revenge", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "2f77f015fc880b05f28e84156f989a0c", "", "", "Plane Demo (Gonzalo) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2f7949f71076db42480d3f5036b4a332", "", "", "Name This Game (208 in 1) (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "2facd460a6828e0e476d3ac4b8c5f4f7", "Sancho - Tang's Electronic Co.", "", "Words-Attack (1983) (Sancho) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "3025bdc30b5aec9fb40668787f67d24c", "", "", "Demo Image Series #14 - Two Marios (4K Interleaved Chronocolour Vertical Movement) (05-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "303242c239474f2d7763b843de58c1c3", "CCE", "", "Laser Blast (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "304512528a5530a9361e8a231ed9a6de", "Thomas Jentzsch", "", "River Raid Plus (Thomas Jentzsch) (Hack)", "Hack of River Raid", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "30512e0e83903fc05541d2f6a6a62654", "Atari, Jim Huether - Sears", "CX2644 - 6-99824", "Flag Capture (1978) (Atari)", "AKA Capture the Flag", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "30516cfbaa1bc3b5335ee53ad811f17a", "Wizard Video Games - MicroGraphic Image, Robert Barber, Tim Martin", "007", "Halloween (1983) (Wizard Video Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3051b6071cb26377cd428af155e1bfc4", "Atari, David Crane - Sears", "CX2607 - 6-99828, 49-75115", "Canyon Bomber (1979) (Atari) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "YES", "", "", "10", "", "", "", "" },
-  { "30685b9b6ebd9ba71536dd7632a1e3b6", "Dactari - Milmar", "", "Tennis (Dactari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3091af0ef1a61e801f4867783c21d45c", "CCE", "C-862", "Crackpots (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "30997031b668e37168d4d0e299ccc46f", "", "", "John K Harvey's Equalizer (PAL) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "30c92c685224dc7a72b9bbe5eb62d004", "", "", "Hangman Monkey Original Words (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "30e012e8d50330c8972f126b8e913bc4", "", "", "Indy 500 (Hack) [a2]", "Hack of Indy 500", "Hack", "", "", "", "", "", "", "", "DRIVING", "DRIVING", "", "", "", "", "", "", "", "" },
-  { "30e0ab8be713208ae9a978b34e9e8e8c", "Atari, Mike Lorenzen", "CX2630, CX2630P", "Circus Atari (1980) (Atari) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 55", "", "", "", "" },
-  { "30f0b49661cfcfd4ec63395fab837dc3", "SEGA, Jeff Lorenz - Teldec", "004-01", "Star Trek - Strategic Operations Simulator (1983) (SEGA) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "3105967f7222cc36a5ac6e5f6e89a0b4", "SEGA, Jeff Lorenz", "011-01, 011-02", "Spy Hunter (1984) (SEGA)", "Uses Joystick Coupler (Dual Control Module)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "310ba30e25ea8957e58180b663503c0c", "Ed Federmeyer", "", "Sound X6 (1994) (Ed Federmeyer)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "31235a27b065c2863048fa84db330dc6", "Thomas Jentzsch", "", "Missile Control - Amiga Mouse Hack v1.15 (PAL) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "313243fc41e49ef6bd3aa9ebc0d372dd", "", "", "Fast Food (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "31512cdfadfd82bfb6f196e3b0fd83cd", "Tigervision", "7-004", "River Patrol (1984) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3177cc5c04c1a4080a927dfa4099482b", "Atari - Imagineering, Alex DeMeo", "CX26135", "RealSports Boxing (1987) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "317a4cdbab090dcc996833d07cb40165", "Goliath - Hot Shot", "83-312", "Missile War (1983) (Goliath) (PAL)", "AKA Astrowar", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "318046ae3711c05fd16e479b298e5fcc", "Retroactive", "", "Qb (V2.08) (Stella) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "318a9d6dda791268df92d72679914ac3", "Activision, Steve Cartwright", "AX-017, AX-017-04", "MegaMania (1982) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "319a142aab6260842ab616382848c204", "", "", "Marble Craze (05-02-2002) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "31bb9b8ceed46cb3e506777a9e65f3ce", "Bit Corporation", "", "4 Game in One Light Green (1983) (BitCorp) (PAL)", "Phantom UFO, Ice Hockey, Cosmic Avenger, Spy Vs. Spy", "", "", "", "4IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "31c5fd55a39db5ff30a0da065f86c140", "Dactari - Milmar", "", "Enduro (Dactari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "31d08cb465965f80d3541a57ec82c625", "Atari, Alan Miller - Sears", "CX2641 - 99807, 49-75105", "Surround (1977) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "31df1c50c4351e144c9a378adb8c10ba", "Quelle", "687.463 0", "Die Ratte und die Karotten (1983) (Quelle) (PAL)", "AKA Gopher", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "31e518debba46df6226b535fa8bd2543", "Atari, Douglas 'Solaris' Neubauer, Mimi Nyden", "CX26134", "Last Starfighter (1984) (Atari) (Prototype)", "Solaris Beta", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "31f4692ee2ca07a7ce1f7a6a1dab4ac9", "Atari, Alan Miller", "CX2642", "Game of Concentration (1980) (Atari) (4K)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "31fcbce1cfa6ec9f5b6de318e1f57647", "Atari, Jerome Domurat, Peter C. Niday", "CX26115", "Dumbo's Flying Circus (1983) (Atari) (Prototype) (PAL)", "AKA Dumbo Flies Home", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "32199271dc980eb31a2cc96e10a9e244", "", "", "Radial Pong - Version 12 (Jeffry Johnston) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "321c3451129357af42a375d12afd4450", "Atari - Imagineering, Dan Kitchen", "CX26177", "Ikari Warriors (1991) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "32244e55ce6ec6bfbd763f33384bdc2e", "Activision, Steve Cartwright", "AX-027", "Plaque Attack (1983) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3225676f5c0c577aeccfaa7e6bedd765", "CCE", "C-1002", "Pole Position (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "322b29e84455aa41e7cc9af463bffa89", "Atari - Bobco, Robert C. Polaro", "CX2663", "Road Runner (06-25-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "324cb4a749bcac4f3db9da842b85d2f7", "Dennis Debro", "", "Climber 5 (01-05-2003) (Dennis Debro)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "327468d6c19697e65ab702f06502c7ed", "Charles Morgan", "", "Aster-Hawk (2002) (Charles Morgan) (Hack)", "Hack of Asteroids", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "3276c777cbe97cdd2b4a63ffc16b7151", "Atari - GCC, Mike Feinstein, Kevin Osborn", "CX2691", "Joust (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "3278158e5c1f7eb5c5d28ccfd7285250", "Dactari - Milmar", "", "Megamania (Dactari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "327fe8cf94f3a45c35a840a453df1235", "", "", "Spice Girls Rule Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "328949872e454181223a80389d03c122", "", "", "Home Run (Unknown) (PAL)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" },
-  { "32ae78abbb5e677e2aabae5cc86cec29", "Atari, Christopher H. Omarzu, Courtney Granner", "CX26112", "Good Luck, Charlie Brown (04-18-1984) (Atari) (Prototype)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "32d1260ea682e1bb10850fa94c04ec5f", "Atari, Alan Miller", "CX26163P", "Basketball (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "32dcd1b535f564ee38143a70a8146efe", "Xonox - K-Tel Software - Product Guild, Anthony R. Henderson", "99007, 6240", "Tomarc the Barbarian (1983) (Xonox)", "AKA Thundarr the Barbarian", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "32e65d1e4dfcbcd9b57fee72cafe074c", "", "", "Eckhard Stolberg's Scrolling Text Demo 3 (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "32ecb5a652eb73d287e883eea751d99c", "Dactar - Milmar", "", "Bowling (Dactar - Milmar)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "32f4e47a71601ab06cfb59e1c6a0b846", "Ed Federmeyer", "", "Sound X (1994) (Ed Federmeyer)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3316ee2f887e9cb9b54dd23c5b98c3e2", "", "", "Texas Golf (miniature Gold Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "331938989f0f33ca39c10af4c09ff640", "Zach Matley", "", "Combat - Tank AI (19-04-2003) (Zach Matley)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "332f01fd18e99c6584f61aa45ee7791e", "", "", "X'Mission (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "3347a6dd59049b15a38394aa2dafa585", "Parker Brothers - JWDA, Henry Will IV", "PB5760", "Montezuma's Revenge (1984) (Parker Bros)", "Featuring Panama Joe", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "335793736cbf6fc99c9359ed2a32a49d", "", "", "Analog Clock (V0.0) (20-01-2003) (AD) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "335a7c5cfa6fee0f35f5824d1fa09aed", "SEGA - Beck-Tech, Steve Beck, Phat Ho - Teldec", "006-01 - 3.60105 VG", "Congo Bongo (1983) (SEGA) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3367eeba3269aa04720abe6169767502", "", "", "Space Treat (30-12-2002) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "336ea20d38f98926919d4b4651d1a03f", "Omegamatrix", "", "Omega Race (Genesis) V2", "Genesis controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3391f7c4c656793f92299f4187e139f7", "Commavid, Ben Burch", "CM-010", "Rush Hour (1983) (Commavid) (Prototype) [a4]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "33cac5e767a534c95d292b04f439dc37", "Jone Yuan Telephonic Enterprise Co", "", "Tapeworm (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "33d68c3cd74e5bc4cf0df3716c5848bc", "CBS Electronics, Tom DiDomenico", "4L 2486 5000", "Blueprint (1983) (CBS Electronics)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "33ed6dfac4b9ea2f81f778ceddbb4a75", "Activision", "", "River Raid (1982) (SpkSoft) [t1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "340f546d59e72fb358c49ac2ca8482bb", "Sancho - Tang's Electronic Co.", "TEC003", "Skindiver (1983) (Sancho) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "34340c8eecd1e557314789cc6477e650", "Joe Grand", "", "SCSIcide Pre-release 4 (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "345488d3b014b684a181108f0ef823cb", "CBS Electronics, Tom DiDomenico", "4L 2486 5000", "Blueprint (1983) (CBS Electronics) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "345758747b893e4c9bdde8877de47788", "CBS Electronics, Joseph Biel", "4L1802, 4L1803, 4L1804, 4L2278", "Venture (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "345769d085113d57937198262af52298", "Rainbow Vision - Suntek", "SS-007", "Space Raid (1983) (Rainbow Vision) (PAL)", "AKA MegaMania", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "346555779a2d51b48833463b5433472f", "Thomas Jentzsch", "", "Thrust (V0.1) (2000) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "348615ffa30fab3cec1441b5a76e9460", "Activision, Alan Miller - Ariola", "EAX-016, PAX-016 - 711 016-725", "StarMaster (1982) (Activision) (PAL) [fixed]", "Use Color/BW switch to change between galactic chart and front views", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "34b269387fa1aa5a396636f5ecdd63dd", "", "", "Marble Craze (mc7_23) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "34c808ad6577dbfa46169b73171585a3", "Apollo", "AP-2012", "Squoosh (1983) (Apollo) (Prototype)", "AKA Vat's Incredible!, The Grape Escape", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "34ca2fcbc8ba4a0b544acd94991cfb50", "Atari, Robert C. Polaro", "", "Dukes of Hazzard (1980) (Atari) (Prototype) (4K)", "AKA Stunt Cycle", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "34e37eaffc0d34e05e40ed883f848b40", "Retroactive", "", "Qb (2.15) (Retroactive) (Stella)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "34f4b1d809aa705ace6e46b13253fd3b", "Aaron Bergstrom", "", "Nothern Alliance (Aaron Bergstrom) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "34fd4fcb40ff5babce67f8b806d5969c", "", "", "Boxing (Dactari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "350e0f7b562ec5e457b3f5af013648db", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX26119", "Saboteur (06-09-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "35156407e54f67eb1f625450d5c093e1", "", "", "Mouse Trap (Genesis)", "Genesis controller (C changes to dog)", "Hack of Mouse Trap", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "35163b56f4a692a232ae96ad3e23310f", "Retroactive", "", "Qb (2.12) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "3545eb3b8b1e7dc19f87d231ab0b1d4c", "CBS Electronics - Roklan, Joe Hellesen, Joe Wagner", "M8774, M8794", "Wizard of Wor (1982) (CBS Electronics) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3556e125681aea864e17b09f3f3b2a75", "", "", "Incoming (2 Player Demo) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3576037c9281656655fa114a835be553", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (1 of 4) (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3577e19714921912685bb0e32ddf943c", "TechnoVision - Video Technology", "TVS1003", "Pharaoh's Curse (1983) (TechnoVision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "35ae903dff7389755ad4a07f2fb7400c", "", "", "Colored Wall Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "35b10a248a7e67493ec43aeb9743538c", "Dor-x", "", "Defender (Dor-x) (Hack)", "Hack of Defender", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "35b43b54e83403bb3d71f519739a9549", "Parker Brothers, Dave Engman, Isabel Garret", "", "McDonald's (06-06-1983) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "35be55426c1fec32dfb503b4f0651572", "Men-A-Vision", "", "Air Raid (Men-A-Vision) (PAL)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "35fa32256982774a4f134c3347882dff", "Retroactive", "", "Qb (V0.05) (Macintosh) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "360ba640f6810ec902b01a09cc8ab556", "Atari, Jerome Domurat, Steve Woita", "CX2699", "Taz (06-15-1983) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "360c0dcb11506e73bd0b77207c81bc62", "Digitel", "", "Enduro (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3619786f6a32efc1e4a262d5aca8a070", "Atari, John Dunn - Sears", "CX2631 - 49-75152", "Superman (1979) (Atari) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3624e5568368929fabb55d7f9df1022e", "Activision - Imagineering, Donald Hahn, Dan Kitchen", "EAK-050-04", "Double Dragon (1989) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "36306070f0c90a72461551a7a4f3a209", "U.S. Games Corporation - JWDA, Roger Booth, Sylvia Day, Ron Dubren, Todd Marshall, Robin McDaniel, Wes Trager, Henry Will IV", "VC1007", "Name This Game (1983) (U.S. Games)", "AKA Octopussy", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "36547bc6faa5132b87504e18d088e1d7", "", "", "Cosmic Swarm (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "367411b78119299234772c08df10e134", "Atari", "CX26163P", "Skiing (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3685060707df27d4091ba0ea2dc4b059", "", "", "PezZerk - PezMan in Ghost Manor (Hack)", "Hack of Berzerk", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "368d88a6c071caba60b4f778615aae94", "Atari, Matthew L. Hubbard", "CX26159", "Double Dunk (1989) (Atari)", "AKA Super Basketball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "36a701c60a9f9768d057bc2a83526a80", "", "", "Cube Conquest (Interlaced) (Billy Eno) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "36b20c427975760cb9cf4a47e41369e4", "Coleco - Woodside Design Associates - Imaginative Systems Software, Garry Kitchen", "2451", "Donkey Kong (1982) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "36c29ceee2c151b23a1ad7aa04bd529d", "Atari - GCC, Ava-Robin Cohen", "CX26123", "Jr. Pac-Man (1986) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "36c31bb5daeb103f488c66de67ac5075", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix - Bop a Buggy (1 of 3) (1983) (Arcadia)", "Uses Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 56", "", "", "", "" },
-  { "36c993dc328933e4dd6374a8ffe224f4", "Gameworld, J. Ray Dettling", "133-007", "Bermuda Triangle (1983) (Gameworld) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "36e47ed74968c365121eab60f48c6517", "Quelle", "343.373 7", "Master Builder (1983) (Quelle) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "36edef446ab4c2395666efc672b92ed0", "Atari - Axlon, John Vifian", "CX26168", "Off the Wall (1989) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "36f9a953ebdd9a8be97ccf27a2041903", "", "", "Chinese Character Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "37252757a79dc5b174e3c03d6ea0bdcb", "", "", "Sky Diver (Unknown) (PAL) (4K) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "372bddf113d088bc572f94e98d8249f5", "Bomb - Onbase", "CA285", "Wall-Defender (1983) (Bomb) (PAL)", "AKA Wall Break", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "373b8a081acd98a895db0cb02df35673", "", "", "Demo Image Series #5 - Boofly (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3750f2375252b6a20e4628692e94e8b1", "Dismac", "", "Ases do Ar (Dismac)", "AKA Sky Jinks", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "37527966823ee9243d34c7da8302774f", "", "", "Word Zapper (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "376944889dcfa96c73d3079f308e3d32", "Retroactive", "", "Qb (0.11) (Retroactive) (Stella)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "3783f12821b88b08814da8adb1a9f220", "", "", "Mission Survive (PAL) (Genesis)", "Genesis controller (C is vertical fire)", "Hack of Mission Survive)", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "378a62af6e9c12a760795ff4fc939656", "Atari - Axlon, Steve DeFrisco", "CX26171", "MotoRodeo (1991) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "378c118b3bda502c73e76190ca089eef", "Atari, Alan Miller", "CX2662P", "Hangman (1978) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "37ab3affc7987995784b59fcd3fcbd31", "", "", "Sprite Test (29-11-2002) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "37b98344c8e0746c486caf5aaeec892a", "K-Tel Vision", "6", "Spider Maze (1982) (K-Tel Vision) (PAL)", "AKA Spider Kong", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "37e828675d556775ae8285c0caf7d11c", "AtariAge - Fred Quimby", "", "Gingerbread Man (Fred Quimby) (Genesis)", "Genesis controller (C throws cookie)", "New Release", "", "", "", "", "", "", "", "GENESIS", "", "", "", "", "", "", "", "", "" },
-  { "37f42ab50018497114f6b0f4f01aa9a1", "", "", "Droid Demo 2-M (David Conrad Schweinsberg) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "37fd7fa52d358f66984948999f1213c5", "Rainbow Vision - Suntek", "SS-004", "Pyramid War (1983) (Rainbow Vision) (PAL) [a2]", "AKA Chopper Command", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "384db97670817103dd8c0bbdef132445", "Atari - Sears", "CX2626 - 6-99829, 49-75116", "Miniature Golf (1979) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "384f5fbf57b5e92ed708935ebf8a8610", "20th Century Fox Video Games, John W.S. Marvin", "11009", "Crypts of Chaos (1983) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3856b9425cc0185ed770376a62af0282", "Kyle Pittman", "", "Yellow Submarine (Kyle Pittman) (Hack)", "Hack of Bermuda Triangle", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "386ff28ac5e254ba1b1bac6916bcc93a", "Arcadia Corporation, Scott Nelson", "AR-4300", "Fireball (1982) (Arcadia)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" },
-  { "3882224adbd0ca7c748b2a1c9b87263e", "Atari, Tod Frye", "CX2657", "SwordQuest - FireWorld (1982) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3889351c6c2100b9f3aef817a7e17a7a", "CCE", "", "Dolphin (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3897744dd3c756ea4b1542e5e181e02a", "Atari, Jerome Domurat, Peter C. Niday", "CX26115", "Dumbo's Flying Circus (05-05-1983) (Atari) (Prototype)", "AKA Dumbo Flies Home", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "38bd172da8b2a3a176e517c213fcd5a6", "Atari", "MA017600", "Diagnostic Test Cartridge 2.6 (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "38c362dcd5cad5a62e73ae52631bd9d8", "Jake Patterson", "", "Baubles (14-11-2001) (Jake Patterson) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "38cf93eacfb2fa9a2c5e39059ff35a74", "Greg Zumwalt", "", "WacMan (2003) (Greg Zumwalt) (Hack)", "Hack of Ms. Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "38de7b68379770b9bd3f7bf000136eb0", "Imagic, Mark Klein", "EIZ-003-04I", "Subterranea (1983) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "391764720140c432aec454a468f77a40", "Video Game Program", "", "Miss Pack Man (Video Game Program) (PAL)", "AKA Ms. Pac-Man", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "392d34c0498075dd58df0ce7cd491ea2", "Atari, Frank Hausman, Mimi Nyden, Steve Woita", "CX2686", "Quadrun (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "392f00fd1a074a3c15bc96b0a57d52a1", "Atari, Rob Fulop - Sears", "CX2633 - 49-75119", "Night Driver (1980) (Atari)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "YES", "" },
-  { "393948436d1f4cc3192410bb918f9724", "Activision, Carol Shaw", "AX-020, AX-020-04", "River Raid (1982) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "393e41ca8bdd35b52bf6256a968a9b89", "U.S. Games Corporation - Western Technologies, John Hall", "VC1012", "M.A.D. (1983) (U.S. Games)", "AKA Missile Intercept, Mutually Assured Destruction", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3947eb7305b0c904256cdbc5c5956c0f", "Jone Yuan Telephonic Enterprise Co", "", "Lilly Adventure (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "396f7bc90ab4fa4975f8c74abe4e81f0", "Atari, Larry Kaplan - Sears", "CX2612 - 99804, 49-75103", "Street Racer (1977) (Atari)", "Uses the Paddle Controllers (swapped)", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "AUTO 60", "", "", "", "" },
-  { "3974e2d1f614fbd3a092533ecae2e84d", "Alessandro Ciceri", "", "MagiCard+ (alex_79) WIP_20150118", "MagiCard hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "39790a2e9030751d7db414e13f1b6960", "", "", "Robotfindskitten2600 (26-04-2003) (Jeremy Penner) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "39a6a5a2e1f6297cceaa48bb03af02e9", "", "", "Pitfall 2 Plus (Hack)", "Hack of Pitfall 2", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "39b94d41bd3b01c12b4054c1a8733783", "SOLID Corp. (D. Scott Williamson)", "CX2655-016", "Star Castle 2600 (SolidCorp) [016]", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "39c78d682516d79130b379fa9deb8d1c", "Apollo - Games by Apollo, Ed Salvo", "AP-1001", "Skeet Shoot (1981) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "39d36366ae7e6dfd53393fb9ebab02a0", "CCE", "C-811", "River Raid (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "39da69ff9833f8c143f03b6e0e7a996b", "Charles Morgan", "", "Ventrra Invaders 2002 (Charles Morgan) (Hack)", "Hack of Megamania", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "39fe316952134b1277b6a81af8e05776", "Robby", "18", "River Raid (Robby)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3a10562937a766cbbb77203d029b00e1", "Carrere Video - JWDA, Garry Kitchen, Paul Willson - Teldec - Prism", "USC1002", "Sneak 'n Peek (1983) (Carrere Video) (PAL)", "AKA Der Unsichtbare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3a2e2d0c6892aa14544083dfb7762782", "Atari, Rob Fulop - Sears", "CX2638 - 49-75166", "Missile Command (1981) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "3a35d7f1dc2a33565c8dca52baa86bc4", "", "", "Rubik's Cube Demo 2 (23-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3a51a6860848e36e6d06ffe01b71fb13", "Retroactive", "", "Qb (2.07) (Retroactive) (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "3a521b7e29123b2d38e34e3ff8dc255c", "Thomas Jentzsch", "", "Centipede - Atari Mouse Hack v1.4 (NTSC) (Full-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3a526e6a1f9fe918af0f2ce997dfea73", "CBS Electronics, Dan Kitchen, Garry Kitchen", "4L1700, 4L1701, 4L1702, 4L1802, 4L2274", "Donkey Kong (1982) (CBS Electronics) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3a53963f053b22599db6ac9686f7722f", "", "", "Word Zapper (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3a771876e4b61d42e3a3892ad885d889", "Atari, Bill Aspromonte, Andrew Fuchs", "CX26120", "Defender II (1987) (Atari)", "AKA Stargate", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3aad0ef62885736a5b8c6ccac0dbe00c", "Dynacom", "", "Atlantis (1983) (Dynacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3ab5d138e26d88c8190e7cc629a89493", "", "", "Phased Color Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "3ac6c50a8e62d4ce71595134cbd8035e", "Absolute Entertainment, Dan Kitchen", "AK-046-04", "Tomcat (1988) (Absolute)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3ad3dc799211ccd424d7c6d454401436", "Probe 2000 - NAP", "", "Power Lords (1983) (Probe) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3ad58b53a1e972396890bd86c735e78d", "Arcadia Corporation, Stephen H. Landrum", "AR-4400", "Excalibur Version 36 (Dragonstomper Beta) (1982) (Arcadia) (Prototype)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3b040ed7d1ef8acb4efdeebebdaa2052", "Tigervision", "7-008", "Miner 2049er (1983) (Tigervision) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3b097a7ed5bd2a84dc3d3ed361e9c31c", "", "", "Interleaved ChronoColour Demo (PAL) (05-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3b10106836565e5db28c7823c0898fbb", "Xonox - Beck-Tech", "6210, 06002, 06004, 99002", "Ghost Manor (1983) (Xonox) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3b2c32fcd331664d037952bcaa62df94", "Xonox", "6230, 6250", "Super Kung-Fu (1983) (Xonox) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3b5751a8d20f7de41eb069f76fecd5d7", "", "", "Eckhard Stolberg's Scrolling Text Demo 4 (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3b64a00ce147c3c29f7f8f8e531d08d8", "", "", "This Planet Sucks (16K) (Greg Troutman)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3b69f8929373598e1752f43f8da61aa4", "Apollo - Games by Apollo - RCA Video Jeux", "AP-2006", "Infiltrate (1921) (Apollo) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "3b6dba1a24bb2893bd3bd0593f92016b", "CBS Electronics / Thomas Jentzsch", "", "Omega Race JS (TJ)", "Hack of Omega Race (CBS Electronics)", "New Release (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3b76242691730b2dd22ec0ceab351bc6", "M Network - INTV, Connie Goldman, Joe King, Patricia Lewis Du Long, Gerald Moore, Mike Sanders, Jossef Wagner", "MT4319", "Masters of the Universe (1983) (M Network)", "", "", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "3b80b8f52a0939e16b5059f93a3fc19a", "V007", "", "Virtual Pet (V007) (after Demo 2) (CRACKERS) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3b86a27132fb74d9b35d4783605a1bcb", "Atari, Chris Crawford", "", "Wizard (1980) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3b8aacf5f5638492b926b5124de19f18", "Atari, Tod Frye - Sears", "CX2646 - 49-75185", "Pac-Man (1981) (Atari) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3b91c347d8e6427edbe942a7a405290d", "Parker Brothers", "PB5350", "Sky Skipper (1983) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3b9480bb6fb1e358c9c0a64e86945aee", "", "", "Title Match Pro Wrestling (2002) (Skyworks)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3b966bf3c2ca34ac6ca1de4cf6383582", "", "", "Double-Height 6-Digit Score Display (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3bb9793c60c92911895cf44530846136", "Jone Yuan Telephonic Enterprise Co", "", "Dragster (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3c21a89bc38d8cd0b010a2916bcff5c2", "", "", "Colony 7 - CX-22 Hack v0.4 (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "50" },
-  { "3c3a2bb776dec245c7d6678b5a56ac10", "", "", "Unknown Title (bin00003) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3c4223316c835ceaad619651e25df0f9", "", "", "Defender (Genesis)", "Genesis controller (C is smartbomb)", "Hack of Defender", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3c4a6f613ca8ba27ce9e43c6c92a3128", "", "", "Qb (V0.04) (Non-Lax Version) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "3c57748c8286cf9e821ecd064f21aaa9", "Atari, Jerome Domurat, Andrew Fuchs, Dave Staugas, Robert Vieira", "CX26118", "Millipede (1984) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3c72ddaf41158fdd66e4f1cb90d4fd29", "Dismac", "", "Comando Suicida (Dismac)", "AKA Chopper Command", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3c7a7b3a0a7e6319b2fa0f923ef6c9af", "Atari - Roklan, Joe Gaucher", "", "Racer (1982) (Atari) (Prototype)", "ROM must be started in bank 0", "Prototype", "", "0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3c7a96978f52b2b15426cdd50f2c4048", "", "", "Overhead Adventure Demo 3 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3c82e808fe0e6a006dc0c4e714d36209", "Activision, David Crane", "AG-004", "Fishing Derby (1980) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3c853d864a1d5534ed0d4b325347f131", "Telesys, Don 'Donyo' Ruffcorn", "1002", "Cosmic Creeps (1982) (Telesys)", "AKA Space Maze, Spaze Maze", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "3c8e57a246742fa5d59e517134c0b4e6", "Parker Brothers, Rex Bradford, Sam Kjellman", "PB5050", "Star Wars - The Empire Strikes Back (1982) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3ca51b5c08f5a0ecfb17d0c1ec6d0942", "Atari, James Andreasen - Sears", "CX2654 - 49-75141", "Haunted House (09-28-81) (Atari) (Prototype)", "AKA Mystery Mansion, Graves' Manor, Nightmare Manor", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3caa902ac0ce4509308990645876426a", "Atari - GCC, Dave Payne", "CX2669, CX2669P", "Vanguard (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3cbdf71bb9fd261fbc433717f547d738", "CCE", "C-803", "Bobby Is Going Home (1983) (CCE) (PAL)", "AKA Bobby Vai Para Casa", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3cdd91e1c28d28e856c0063d602da166", "", "", "Stell-A-Sketch (03-11-1997) (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "3d1e83afdb4265fa2fb84819c9cfd39c", "Coleco - JWDA, Todd Marshall, Robin McDaniel, Henry Will IV", "2465", "Smurf - Rescue in Gargamel's Castle (1983) (Coleco)", "AKA Smurf, Smurf Action", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3d2367b2b09c28f1659c082bb46a7334", "Imagic, Dennis Koble", "720103-2A, IA3203P, EIX-010-04I", "Atlantis (1982) (Imagic) (PAL)", "AKA Lost City of Atlantis", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3d2652cbea462a886a41791dd7c8d073", "", "", "Ritorno dei frattelli di Mario (Mario Bros Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3d48b8b586a09bdbf49f1a016bf4d29a", "Video Game Cartridge - Ariola", "TP-606", "Hole Hunter (Video Game Cartridge)", "AKA Topy", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3d6fc7a19be76d808aa233415cb583fc", "CCE", "C-833", "Target Practice (1983) (CCE)", "AKA Carnival", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3d7749fb9c2f91a276dfe494495234c5", "Jone Yuan Telephonic Enterprise Co", "", "Checkers (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3d7aad37c55692814211c8b590a0334c", "Atari, Dan Oliver", "", "Telepathy (1983) (Atari) (Prototype)", "Uses both left joystick and right Mindlink controllers (press Fire on respective controller to begin)", "Prototype", "", "", "", "", "", "", "", "", "MINDLINK", "", "", "", "78", "", "", "", "" },
-  { "3d8a2d6493123a53ade45e3e2c5cafa0", "Atari, Jim Huether - Sears", "CX2629 - 6-99843, 49-75118", "Sky Diver (1979) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3d934bb980e2e63e1ead3e7756928ccd", "Activision, Steve Cartwright - Ariola", "EAX-017, EAX-017-04I - 711 017-720", "MegaMania (1982) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3d9c2fccf8b11630762ff00811c19277", "", "", "Challenge of.... Nexar, The (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3da7cc7049d73d34920bb73817bd05a9", "Activision, Mike Lorenzen", "AX-023", "Oink! (1983) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3dfb7c1803f937fadc652a3e95ff7dc6", "Dimax - Sinmax", "SM8001", "Space Robot (Dimax - Sinmax)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "3e03086da53ecc29d855d8edf10962cb", "CBS Electronics - Roklan, Joe Gaucher, Alex Leavens", "4L1751, 4L1752, 4L1753, 4L2275", "Gorf (1982) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "3e1682ddaec486d8b6b90b527aaa0fc4", "Thomas Jentzsch", "", "Robot City (V0.12) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3e22c7eaf6459b67388602e4bebbb3a8", "CommaVid, John Bronstein - Ariola", "CM-003 - 712 003-720", "Cosmic Swarm (1982) (CommaVid) (PAL) (4K)", "AKA Angriff der Termiten", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3e33ac10dcf2dff014bc1decf8a9aea4", "Spectravideo - Video Games Industries Corporation, Michael Schwartz - Ralston Purina", "", "Chase the Chuckwagon (1983) (Spectravideo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "3e49da621193d2611a4ea152d5d5ca3a", "", "", "Atari Logo Demo 3 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3e4b1137433cc1e617b5508619e13063", "", "", "Asteroids (Genesis)", "Genesis controller (C is hyperspace)", "Hack of Asteroids", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "3e5ca1afaa27c5da3c54c9942fec528b", "", "", "2600 Digital Clock (Demo 2) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3e6dab92009d6034618cb6b7844c5216", "", "", "Ed Invaders (Hack)", "Hack of Pepsi Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3e7d10d0a911afc4b492d06c99863e65", "VGS", "", "Super Tenis (VGS)", "AKA RealSports Tennis", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3e88cca5b860d0bd8947479e74c44284", "Atari, Lou Harp", "CX26122", "Sinistar (01-23-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3e899eba0ca8cd2972da1ae5479b4f0d", "Coleco, Joseph Biel", "2457", "Venture (1982) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "3e90cf23106f2e08b2781e41299de556", "Activision, David Crane", "AX-018, AX-018-04", "Pitfall! (1982) (Activision)", "Pitfall Harry's Jungle Adventure (Jungle Runner)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3eae062a9b722bda1255d474a87eca5c", "Atari, David Crane", "CX2605, CX2605P", "Outlaw (1978) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3eb1e34a4f0eec36f12e7336badcecf2", "Jake Patterson", "", "Baubles (V0.001) (2001) (Jake Patterson) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3eb21313ea5d5764c5ed9160a5a55a83", "Activision, Alan Miller", "AX-012, CAX-012, AX-012-04", "Ice Hockey (1981) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3ec12372ca3e870b11ca70edc7ec26a4", "CommaVid, John Bronstein", "CM-002", "Video Life (1981) (CommaVid) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "3eccf9f363f5c5de0c8b174a535dc83b", "", "", "Plaque Attack (Unknown) (PAL)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3ef9573536730dcd6d9c20b6822dbdc4", "Atari, Larry Wagner, Bob Whitehead", "CX2645, CX2645P", "Video Chess (1979) (Atari) (PAL)", "AKA Computer Chess", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3f01bd6d059396f495a4cde7de0ab180", "", "", "Qb (Special Edition) (NTSC) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "3f039981255691d3859d04ef813a1264", "Xonox, John Perkins", "6230, 7210, 06004, 99004", "Artillery Duel (1983) (Xonox) [a]", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3f251c50aa7237e61a38ab42315ebed4", "Thomas Jentzsch", "", "Ikari Warriors (1990) (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3f3ad2765c874ca13c015ca6a44a40a1", "CCE", "C-862", "Crackpots (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3f540a30fdee0b20aed7288e4a5ea528", "Atari - GCC", "CX2670", "Atari Video Cube (1983) (Atari)", "AKA Atari Cube, Video Cube", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3f58f972276d1e4e0e09582521ed7a5b", "Telegames", "6082 A145", "Kung Fu Superkicks (1988) (Telegames)", "AKA Chuck Norris Superkicks", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3f5a43602f960ede330cd2f43a25139e", "Activision, Alan Miller", "AG-003", "Checkers (1980) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3f6938aa6ce66e6f42e582c1eb19b18c", "Jone Yuan Telephonic Enterprise Co", "", "Laser Blast (Jone Yuan) (4K) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3f6dbf448f25e2bd06dea44248eb122d", "", "5687 A279", "Soccer (1988) (Telegames)", "AKA International Soccer", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3f75a5da3e40d486b21dfc1c8517adc0", "Atari, Jim Huether", "CX26163P", "Sky Diver (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3f9431cc8c5e2f220b2ac14bbc8231f4", "", "", "Colors Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3f96eb711928a6fac667c04ecd41f59f", "Bit Corporation", "PGP218", "Rodeo Champ (4 Game in One Dark Green) (1983) (BitCorp) (PAL)", "AKA Stampede", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3f9cb1aba8ec20e2c243ae642f9942bf", "", "", "New Questions (1998) (John K. Harvey) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3fd1f9d66a418c9f787fc5799174ddb7", "Aaron Curtis", "", "AStar (PAL)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3fd53bfeee39064c945a769f17815a7f", "CCE", "", "Sea Hawk (CCE)", "AKA Seahawk", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3fe43915e5655cf69485364e9f464097", "CCE", "C-863", "Fisher Price (1983) (CCE)", "AKA Skindiver", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "3ff5165378213dab531ffa4f1a41ae45", "Otto Versand", "311377", "Pygmy (1983) (Otto Versand) (PAL)", "AKA Lock 'n' Chase (Double-Game Package)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4026ad38ba5ce486e88383dc27d7a46f", "Nukey Shay, Omegamatrix", "", "Double Dragon (Genesis) V2", "Genesis controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "402b1ca3c230a60fb279d4a2a10fa677", "", "", "3-D Tic-Tac-Toe (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "402d876ec4a73f9e3133f8f7f7992a1e", "Alex Herbert", "", "Man Goes Down (2006) (A. Herbert) (Prototype)", "Uses AtariVox controller", "Homebrew", "", "", "", "", "", "", "", "", "ATARIVOX", "", "", "", "", "", "", "", "" },
-  { "405f8591b6941cff56c9b392c2d5e4e5", "Telegames", "", "Star Strike (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4066309eb3fa3e7a725585b9814bc375", "", "", "Multi Ball Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4066d7d88ec4a2c656127a67fa52dcf1", "", "", "Overhead Adventure Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "407a0c6cc0ff777f67b669440d68a242", "Erik Eid", "", "Euchre (Alpha) (PAL) (31-08-2002) (Erik Eid)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4093382187f8387e6d011883e8ea519b", "", "", "Go Go Home (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "40aa851e8d0f1c555176a5e209a5fabb", "", "", "Euchre (More for less) (NTSC) (22-08-2002) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "40b1832177c63ebf81e6c5b61aaffd3a", "Atari, Peter C. Niday", "", "Rubik's Cube 3-D (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "40b59249e05135bca33861e383735e9e", "Atari", "CX26163P", "Skiing (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "40d8ed6a5106245aa79f05642a961485", "Xonox - K-Tel Software - Beck-Tech, Steve Beck", "6210, 06002, 06004, 99002", "Ghost Manor (1983) (Xonox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "40d9f5709877ecf3dd1184f9791dd35e", "Dactari - Milmar", "", "Skiing (Dactari - Milmar)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "40e12c008037a323a1290c8fa4d2fe7f", "", "", "Skeleton (NTSC) (06-09-2002) (Eric Ball)", "", "", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "40eb4e263581b3dfec6dd8920b68e00f", "Sears Tele-Games, Marilyn Churchill, Matthew L. Hubbard", "CX2647 - 49-75142", "Seawolf 3 (03-23-1981) (Sears) (Prototype) (PAL)", "Submarine Commander Beta", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "413c925c5fdcea62842a63a4c671a5f2", "Activision, Larry Kaplan", "AX-006", "Bridge (1980) (Activision) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4153dd2beed648e9dc082140ebe8e836", "Thomas Jentzsch", "", "Coke Zero (v1.0) (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "415c11fcac66bbd2ace2096687774b5a", "", "", "Fu Kung! (V0.00) (07-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4181087389a79c7f59611fb51c263137", "Atari, Suki Lee", "CX26113", "Miss Piggy's Wedding (06-24-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "41810dd94bd0de1110bedc5092bef5b0", "Funvision - Fund. International Co.", "", "Dragon Treasure (Funvision)", "AKA Dragonfire", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "41818738ab1745e879024a17784d71f5", "CCE", "C-832", "Atlantis (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4189adfc1b30c121248876e3a1a3ac7e", "Eric Ball", "", "Skeleton (Complete) (06-09-2002) (Eric Ball)", "", "New Release", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4191b671bcd8237fc8e297b4947f2990", "Exus Corporation", "", "Video Jogger (1983) (Exus)", "AKA Foot Craz", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "41b554c6970b18670acc7b6baef8ed2e", "Thomas Jentzsch", "", "Reactor - Amiga Mouse Hack v1.3 (PAL) (Half-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "41c4e3d45a06df9d21b7aae6ae7e9912", "CCE", "C-826", "Grand Prix (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "41f252a66c6301f1e8ab3612c19bc5d4", "Atari - GCC, Mike Feinstein, Brad Rice", "CX2681", "Battlezone (1983) (Atari)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4209e9dcdf05614e290167a1c033cfd2", "CommaVid, John Bronstein", "CM-002", "Video Life (1984) (CommaVid) [higher sounds]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "42249ec8043a9a0203dde0b5bb46d8c4", "CCE", "", "Resgate Espacial (CCE)", "AKA Moonsweeper", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "4233eb824c2b4811abef9b6d00355ae9", "Retroactive", "", "Qb (V0.10) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "4251b4557ea6953e88afb22a3a868724", "Thomas Jentzsch", "", "Robot City (V1.1) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "425ee444a41d218598893d6b6e03431a", "Thomas Jentzsch", "", "Invaders Demo (2001) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4279485e922b34f127a88904b31ce9fa", "", "", "Enduro (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "428b2d36f5d716765460701f7016ac91", "Andrew Wallace", "", "Brooni (2001) (Andrew Wallace) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "42ae81ae8ac51e5c238639f9f77d91ae", "", "", "Multi-Sprite Demo 2 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "42b2c3b4545f1499a083cfbc4a3b7640", "U.S. Games Corporation - JWDA, Todd Marshall, Robin McDaniel, Wes Trager, Henry Will IV", "VC2003", "Eggomania (1982) (U.S. Games)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 60", "", "", "", "" },
-  { "42b3ab3cf661929bdc77b621a8c37574", "Robby", "", "Volleyball (Robby)", "AKA RealSports Volleyball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "42b5e3a35b032f033809afb0ea28802d", "Atari, Mimi Nyden, Scott Smith, Robert Vieira", "CX26127", "Gremlins (03-12-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "42cdd6a9e42a3639e190722b8ea3fc51", "Activision, Alan Miller", "AG-007, CAG-007", "Tennis (1981) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "42dcc02777b0bcfacd85aeb61d33558a", "", "", "Human Cannonball (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "42e0ec5ab8f5deba53e4169ff2a5efbe", "", "", "Atari Logo Demo 5 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4311a4115fb7bc68477c96cf44cebacf", "", "", "Challenge (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4326edb70ff20d0ee5ba58fa5cb09d60", "Atari - GCC, Kevin Osborn", "CX2689", "Kangaroo (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "435fd469f088468c4d66be6b5204d887", "Atari - GCC", "CX2680, CX2680P", "RealSports Tennis (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "438968a26b7cfe14a499f5bbbbf844db", "", "", "Raft Rider (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "43adf60ebdd6b5a0fae21594ecf17154", "Jone Yuan Telephonic Enterprise Co", "", "Stampede (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "43c6cfffeddab6b3787357fed9d44529", "20th Century Fox Video Games, Frank Cohen, Douglas 'Dallas North' Neubauer", "11111", "M.A.S.H (1983) (20th Century Fox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "43f33c6dfdeaf5138ce6e6968ad7c5ce", "Jeffry Johnston", "", "Radial Pong - Version 11 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "43f8459d39fb4eddf9186d62722ff795", "", "", "Skeleton+ (17-04-2003) (Eric Ball) (PAL)", "", "", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "442602713cb45b9321ee93c6ea28a5d0", "", "", "Demon Attack (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4427f06085bb4c22ff047027f7acecc2", "Parker Brothers, Rex Bradford", "PB5000", "Star Wars - Jedi Arena (1983) (Parker Bros) (Prototype)", "Uses the Paddle Controllers (swapped)", "Prototype", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 50", "", "", "", "" },
-  { "442b7863683e5f084716fda050474feb", "Eckhard Stolberg", "", "Frame Timed Sound Effects-EM (Eckhard Stolberg)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4431428a7500c96fc0e2798a5dbd36d6", "", "", "Kangaroo (Genesis)", "Genesis controller (B is punch, C is jump)", "Hack of Kangaroo", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4474b3ad3bf6aabe719a2d7f1d1fb4cc", "Activision - Imagineering, Dan Kitchen, Garry Kitchen", "EAX-039-04B, EAX-039-04I", "Kung-Fu Master (1987) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4476c39736090dabac09f6caf835fc49", "", "", "Text Screen (25-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "448c2a175afc8df174d6ff4cce12c794", "Activision, David Crane", "AB-035-04", "Pitfall II (1983) (Activision) [a2]", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "44e9c4a047c348dbeb7ace60f45484b4", "", "", "Moon Patrol Arcade (Genesis)", "Genesis controller (C is jump)", "Hack of Moon Patrol", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "44f71e70b89dcc7cf39dfd622cfb9a27", "Tigervision, Robert H. O'Neil", "7-007", "Polaris (1983) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "45027dde2be5bdd0cab522b80632717d", "Epyx, Steven A. Baker, Tod Frye, Peter Engelbrite", "80561-00250", "Summer Games (1987) (Epyx)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "45040679d72b101189c298a864a5b5ba", "20th Century Fox Video Games - Sirius Software, David Lubar", "11022", "SpaceMaster X-7 (1983) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4543b7691914dfd69c3755a5287a95e1", "CommaVid, Irwin Gaines", "CM-005", "Mines of Minos (1982) (CommaVid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "456453a54ca65191781aef316343ae00", "", "", "Full Screen Bitmap (3-D Green) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4565c1a7abce773e53c75b35414adefd", "Arcadia Corporation", "", "Supercharger BIOS (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "457b03cd48ff6d895795ef043c6b0f1e", "AtariAge, Chris Spry", "CX26201", "Zippy the Porcupine (2014) (Sprybug)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "457e7d4fcd56ebc47f5925dbea3ee427", "Carrere Video - JWDA, Garry Kitchen - Teldec - Prism", "USC1001", "Space Jockey (1983) (Carrere Video) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "457f4ad2cda5f4803f122508bfbde3f5", "", "", "Canyon Bomber (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "458883f1d952cd772cf0057abca57497", "", "", "Fishing Derby (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "45a095645696a217e416e4bd2baea723", "Digivision", "", "Snoopy (Digivision)", "AKA Snoopy and the Red Baron", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "45a4f55bb9a5083d470ad479afd8bca2", "CommaVid, Joseph Biel", "", "Frog Demo (1983) (CommaVid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "45beef9da1a7e45f37f3f445f769a0b3", "Atari, Suki Lee", "CX2658", "Math Gran Prix (1982) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "45c4413dd703b9cfea49a13709d560eb", "Jone Yuan Telephonic Enterprise Co", "", "Challenge of.... Nexar, The (Jone Yuan) (Hack)", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "45cb0f41774b78def53331e4c3bf3362", "Carrere Video - JWDA, Roger Booth, Sylvia Day, Todd Marshall, Robin McDaniel, Wes Trager, Henry Will IV - Teldec - Prism", "USC1007", "Octopus (1983) (Carrere Video) (PAL)", "AKA Name This Game", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4605a00f5b44a9cbd5803a7a55de150e", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (07-03-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "461029ab23800833e9645be3e472d470", "", "", "Combat TC (v0.1)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "46258bd92b1f66f4cb47864d7654f542", "Zellers", "", "Turmoil (Zellers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "463dd4770506e6c0ef993a40c52c47be", "Arcadia Corporation, Steve Hales, Stephen H. Landrum", "4 AR-4102", "Suicide Mission (Preview) (1982) (Arcadia)", "AKA Meteoroids", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "463e66ad98806a49106cffa49c08e2ed", "", "", "Interlace Game Demo (01-09-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "467340a18158649aa5e02a4372dcfccd", "Activision, John Van Ryzin - Ariola", "EAZ-036-04, EAZ-036-04B, EAZ-036-04I - 711 036-720", "H.E.R.O. (1984) (Activision) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4689081b7363721858756fe781cc7713", "", "", "Oystron (V2.6) (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "468f2dec984f3d4114ea84f05edf82b6", "Tigervision - Teldec", "7-011 - 3.60015 VG", "Miner 2049er Volume II (1983) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "4690fdb70c86604bb35da26696818667", "", "", "Euchre (Release Candidate) (NTSC) (28-09-2002) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "469473ff6fed8cc8d65f3c334f963aab", "Atari, Bruce Poehlman, Gary Stark", "", "Dune (07-10-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "46c021a3e9e2fd00919ca3dd1a6b76d8", "Atari, Jim Huether - Sears", "CX2629 - 6-99843, 49-75118", "Sky Diver (1979) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "46c43fdcbce8fde3a91ebeafc05b7cbd", "", "", "Invaders Demo (PAL) (2001) (Eckhard Stolberg)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "46dc526773808c8b9bb2111f24e5704c", "Omegamatrix", "", "SpaceMaster X-7 (Atari Mouse) (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "46e9428848c9ea71a4d8f91ff81ac9cc", "Telegames", "", "Astroblast (1988) (Telegames) (PAL)", "Can also use left joystick", "", "", "", "", "", "", "", "", "PADDLES", "", "YES", "", "", "AUTO 55", "", "", "", "" },
-  { "4702d8d9b48a332724af198aeac9e469", "Atari, Jerome Domurat, Steve Woita", "CX2699", "Taz (1983) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "470878b9917ea0348d64b5750af149aa", "Atari, Suki Lee - Sears", "CX2658 - 49-75128", "Math Gran Prix (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "471f7bdc933e8db0e44aa3dde2dd92af", "Omegamatrix", "", "Millipede (Atari Mouse) v6.5 (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "47464694e9cce07fdbfd096605bf39d4", "Activision, Dan Kitchen", "EAK-050-04", "Double Dragon (1989) (Activision) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "47585c047802dd9af888b998fb921f32", "Omegamatrix", "", "Star Wars Arcade (Atari Trak-Ball) v4 (PAL60) (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4767356fa0ed3ebe21437b4473d4ee28", "Atari, Dan Hitchens, Mimi Nyden", "CX2685", "Gravitar (04-12-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "47711c44723da5d67047990157dcb5dd", "CCE", "", "Ice Hockey (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "47911752bf113a2496dbb66c70c9e70c", "Atari - CCW, Christopher H. Omarzu, Preston Stuart, Bruce Williams", "CX26101", "Oscar's Trash Race (1984) (Atari) (PAL)", "Uses the Keypad Controllers", "", "", "", "", "", "", "", "", "KEYBOARD", "KEYBOARD", "", "", "", "", "", "", "", "" },
-  { "4799a40b6e889370b7ee55c17ba65141", "Konami", "RC 100-X 02", "Pooyan (1983) (Konami)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "47aad247cce2534fd70c412cb483c7e0", "Rainbow Vision - Suntek", "SS-010", "Mafia (1983) (Rainbow Vision) (PAL)", "AKA Gangster Alley", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "47abfb993ff14f502f88cf988092e055", "Zellers", "", "Inca Gold (Zellers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "47aef18509051bab493589cb2619170b", "", "", "Stell-A-Sketch (Bob Colbert) (PD)", "Uses Driving, Joystick, or Amiga/Atari ST Mouse Controllers", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "47b82d47e491ac7fdb5053a88fccc832", "Atari Freak 1, Franklin Cruz", "", "Asteroid 2 (Atari Freak 1) (Hack)", "Hack of Asteroids", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "47cd61f83457a0890de381e478f5cf5f", "Imagic, Wilfredo Aguilar, Michael Becker, Rob Fulop", "720111-2A, 13205", "Fathom (1983) (Imagic) (PAL)", "AKA Scuba", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "481d20ec22e7a63e818d5ef9679d548b", "Atari", "CX26163P", "Freeway Rabbit (32 in 1) (1988) (Atari) (PAL)", "AKA Freeway", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "481f9a742052801cc5f3defb41cb638e", "Jeffry Johnston", "", "Radial Pong - Version 4 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "48287a9323a0ae6ab15e671ac2a87598", "Zellers", "", "Laser Volley (Zellers)", "AKA Innerspace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4834b7b28ea862227ac7e40053fb52a5", "Nukey Shay", "", "Montezuma's Revenge (Genesis) (F6_Conversion)", "Genesis controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "48411c9ef7e2cef1d6b2bee0e6055c27", "Telesys, Don Ruffcorn, Jack Woodman", "1003", "Fast Food (1982) (Telesys) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "484b0076816a104875e00467d431c2d2", "Atari", "CX26150", "Q-bert (1987) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4857f8bb88bb63c640d3ea5aac7f5d6d", "Atari, James Andreasen - Sears", "CX2654 - 49-75141", "Haunted House (08-12-81) (Atari) (Prototype)", "AKA Mystery Mansion, Graves' Manor, Nightmare Manor", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4868a81e1b6031ed66ecd60547e6ec85", "Eric Mooney", "", "Invaders by Erik Mooney (V2.1) (1-3-98) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "487193a7b7fe57a1bbc2f431f628bd5f", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Trak-Ball Hack v1.1 (NTSC) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4884b1297500bd1243659e43c7e7579e", "Atari - Axlon, Tod Frye", "CX26178", "Save Mary! (10-24-1991) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4892b85c248131d6a42c66a4163a40d0", "Canal 3 - Intellivision", "", "Tac-Scan (Canal 3)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "YES", "", "", "YES", "", "", "AUTO 60", "", "", "", "" },
-  { "48bcf2c5a8c80f18b24c55db96845472", "Activision, John Van Ryzin - Ariola", "EAZ-036-04, EAZ-036-04B, EAZ-036-04I - 711 036-720", "H.E.R.O. (1984) (Activision) (PAL) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "48e5c4ae4f2d3b62b35a87bca18dc9f5", "Quelle", "476.774 5", "Bobby geht nach Hause (1983) (Quelle) (PAL)", "AKA Bobby Is Going Home", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "48f18d69799a5f5451a5f0d17876acef", "ZiMAG - Emag - Vidco", "GN-070", "Mysterious Thief, A (1983) (ZiMAG) (Prototype) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "4901c05068512828367fde3fb22199fe", "Imagic, Rob Fulop", "720101-2B, IA3200P, EIX-006-04I", "Demon Attack (1982) (Imagic) (PAL)", "AKA Death from Above", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4904a2550759b9b4570e886374f9d092", "Parker Brothers, Charlie Heath", "931506", "Reactor (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "490e3cc59d82f85fae817cdf767ea7a0", "", "", "Berzerk (Unknown) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "490eed07d4691b27f473953fbea6541a", "Activision, Steve Cartwright, David Crane", "AB-035-04", "Pitfall II (1983) (Activision) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "49366f41aa7a54baf263426e99ce4312", "", "", "POP-MDM-Test (PAL) (63 games)", "", "", "", "", "MDM", "", "", "", "", "JOYSTICK", "JOYSTICK", "", "", "", "", "", "", "", "" },
-  { "493daaf9fb1ba450eba6b8ed53ffb37d", "", "", "3-D Corridor Demo (27-03-2003) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "493de059b32f84ab29cde6213964aeee", "Atari, Bill Aspromonte, Andrew Fuchs", "CX26120", "Stargate (1984) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "493e90602a4434b117c91c95e73828d1", "Telegames", "", "Lock 'n' Chase (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4947c9de2e28b2f5f3b0c40ce7e56d93", "", "", "3-D Corridor Demo 2 (29-03-2003) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "494cda91cc640551b4898c82be058dd9", "Andreas Dietrich", "", "Donkey Kong VCS (2017) (1.0) (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "49571b26f46620a85f93448359324c28", "", "", "Save Our Ship (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "497c811026367c08fd838c9c59e5041d", "Omegamatrix", "", "SpaceMaster X-7 (Atari Trak-Ball) (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "497f3d2970c43e5224be99f75e97cbbb", "CommaVid, John Bronstein", "CM-002", "Video Life (1984) (CommaVid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "4981cefe5493ea512284e7f9f27d1e54", "Home Vision - Gem International Corp. - VDI", "VCS83136", "Cosmic War (1983) (Home Vision) (PAL)", "AKA Space Tunnel", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4999b45be0ab5a85bac1b7c0e551542b", "CCE", "", "Double Dragon (CCE) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "499b612f6544ae71d4915aa63e403e10", "Atari, Carol Shaw", "CX26163P", "Checkers (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "49f2cef5269fd06218be9f9474c74f8d", "Rentacom", "", "Time Pilot (Rentacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4a196713a21ef07a3f74cf51784c6b12", "Jone Yuan Telephonic Enterprise Co", "", "Frogs and Flies (Jone Yuan) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4a2fe6f0f6317f006fd6d4b34515448b", "", "", "Warring Worms (Midwest Classic Edition) (08-06-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4a45c6d75b1ba131f94a9c13194d8e46", "", "", "How to Draw a Playfield II (Joystick Hack) (1997) (Eric Bacher) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4a5fddf89801336637ac8e57a7c9a881", "Amiga", "1125", "Power Play Arcade Video Game Album IV (1984) (Amiga) (Prototype)", "Atlantis, Cosmic Ark, Dragonfire", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4a6be79310f86f0bebc7dfcba4d74161", "", "", "Demolition Herby (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "4a7eee19c2dfb6aeb4d9d0a01d37e127", "Hozer Video Games", "", "Crazy Valet (Hozer Video Games)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4a8c743396b8ad69d97e6fd3dd3e3132", "Arcadia Corporation", "", "Supercharger BIOS (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4a9009620038f7f30aaeb2a00ae58fde", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (3 of 3) (1983) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4ab2ebd95a8f861ea451abebdad914a5", "Nukey Shay, Thomas Jentzsch", "PAL conversion (F6)", "Montezuma's Revenge (PAL) (Genesis)", "Genesis controller (B jumps left, C jumps right)", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4ab4af3adcdae8cdacc3d06084fc8d6a", "Nick Bensema", "", "Sucky Zepplin (Nick Bensema) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4abb4c87a4c5f5d0c14ead2bb36251be", "Atari - Imagineering, Alex DeMeo", "CX26135, CX26135P", "RealSports Boxing (1987) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4ac9f40ddfcf194bd8732a75b3f2f214", "Atari - CCW, Stephan R. Keith, Laura Scholl, Preston Stuart", "CX26106", "Grover's Music Maker (12-29-1982) (Atari) (Prototype)", "Uses Keypad Controller", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4ae8c76cd6f24a2e181ae874d4d2aa3d", "", "", "Flash Gordon (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4af4103759d603c82b1c9c5acd2d8faf", "Imagic, Bob Smith", "720114-2A, 13207, EIZ-001-04I", "Moonsweeper (1983) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "4afa7f377eae1cafb4265c68f73f2718", "Ed Fries", "", "Halo 2600 (2010) (Ed Fries)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4afe528a082f0d008e7319ebd481248d", "", "", "Multi-Color Demo 1 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4b143d7dcf6c96796c37090cba045f4f", "Atari, Jim Huether - Sears", "CX2644 - 6-99824", "Flag Capture (1978) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4b205ef73a5779acc5759bde3f6d33ed", "", "", "Berzerk (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4b27f5397c442d25f0c418ccdacf1926", "Atari, Warren Robinett", "CX2613, 49-75154", "Adventure (1980) (Atari) (PAL)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4b379b885e2694f992c6cc932f18327f", "Omegamatrix", "", "SpaceMaster X-7 (Atari Mouse) (PAL60) (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4b71197153d651480830638cb6a03249", "Atari, Larry Kaplan", "CX26163P", "Bowling (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4b753a97aee91e4b3e4e02f5e9758c72", "Glenn Saunders, Roger Williams", "", "Asymmetric Reflected Playfield (Glenn Saunders)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4b94fd272785d7ec6c95fb7279d0f522", "Atari - CCW, Christopher H. Omarzu, Preston Stuart, Bruce Williams", "CX26101", "Oscar's Trash Race (12-03-1982) (Atari) (Prototype)", "Uses the Keypad Controllers", "Prototype", "", "", "", "", "", "", "", "KEYBOARD", "KEYBOARD", "", "", "", "", "", "", "", "" },
-  { "4b9581c3100a1ef05eac1535d25385aa", "", "", "IQ 180 (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4baada22435320d185c95b7dd2bcdb24", "Atari, Jerome Domurat, Dave Staugas", "CX2682", "Krull (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4bcc7f6ba501a26ee785b7efbfb0fdc8", "Atari, Andrew Fuchs, Courtney Granner, Jeffrey Gusman, Mark R. Hahn", "CX2690", "Pengo (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4bdae9246d6ee258c26665512c1c8de3", "Atari", "CX26163P", "Human Cannonball (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4bdf54a454470ba015a217a8f5e61320", "Omegamatrix", "", "Millipede (Amiga Mouse) v6.5 (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "PAL60", "", "", "" },
-  { "4c030667d07d1438f0e5c458a90978d8", "Retroactive", "", "Qb (V2.03) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "4c0fb2544ae0f8b5f7ae8bce7bd7f134", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix (Preview) (1983) (Arcadia)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4c205f166157154df2f1ef60d87e552f", "", "", "Single-Scanline Positioning Demo 2 (2001) (Roger Williams)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4c39a2c97917d3d71739b3e21f60bba5", "", "", "Whale (Sub Scan Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4c462b2b6fb0a19a1437eb2c3dc20783", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (1 of 3) (1983) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4c4ce802cbfd160f7b3ec0f13f2a29df", "", "", "Beta Demo (V1.1) (26-09-2002) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4c606235f4ec5d2a4b89139093a69437", "Andrew Davies", "", "Andrew Davies early notBoulderDash demo (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "4c6afb8a44adf8e28f49164c84144bfe", "CCE", "C-806", "Mission 3,000 A.D. (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4c8832ed387bbafc055320c05205bc08", "Atari, Joe Decuir, Steve Mayer, Larry Wagner - Sears", "CX2601 - 99801, 6-99801, 49-75124", "Combat (1977) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4c8970f6c294a0a54c9c45e5e8445f93", "Xonox - K-Tel Software - Product Guild, Anthony R. Henderson", "99006, 6220", "Sir Lancelot (1983) (Xonox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4c9307de724c36fd487af6c99ca078f2", "Imagic, Brad Stewart", "720106-1A, IA3409", "Sky Patrol (1982) (Imagic) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4ca0959f846d2beada18ecf29efe137e", "Atari, Jim Huether, Alan J. Murphy, Robert C. Polaro", "CX2666, CX2666P", "RealSports Volleyball (1982) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4ca73eb959299471788f0b685c3ba0b5", "Activision, Steve Cartwright", "AX-031", "Frostbite (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4ca90ba45eced6f5ad560ea8938641b2", "", "", "Hangman Man Wordlist (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4cabc895ea546022c2ecaa5129036634", "Funvision - Fund. International Co.", "", "Ocean City (Funvision)", "AKA Atlantis", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4cd796b5911ed3f1062e805a3df33d98", "Tigervision - Software Electronics Corporation - Teldec", "7-006", "Springer (1983) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4d06f72cc3d8934579c11ff8f375c260", "Bit Corporation", "R320", "Bowling (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4d0a28443f7df5f883cf669894164cfa", "", "", "Beast Invaders (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4d2cef8f19cafeec72d142e34a1bbc03", "HES", "771-422", "2 Pak Special - Star Warrior, Frogger (1990) (HES) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4d38e1105c3a5f0b3119a805f261fcb5", "Bit Corporation", "PGP212", "Phantom UFO (4 Game in One Light Green) (1983) (BitCorp) (PAL)", "AKA Spider Fighter", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4d502d6fb5b992ee0591569144128f99", "Atari - Axlon, Tod Frye", "CX26178", "Save Mary! (11-21-1989) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4d5f6db55f7f44fd0253258e810bde21", "Fabrizio Zavagli", "", "Betterblast (Fabrizio Zavagli) (Hack)", "Hack of Astroblast", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4d7517ae69f95cfbc053be01312b7dba", "Atari, Alan Miller - Sears", "CX2641 - 99807, 49-75105", "Surround (1977) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4d77f291dca1518d7d8e47838695f54b", "Data Age", "DA1004", "Airlock (1982) (Data Age)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4d8396deeabb40b5e8578276eb5a8b6d", "Otto Versand", "781698", "Volleyball (1983) (Otto Versand) (PAL)", "AKA RealSports Volleyball (Double-Game Package)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4dbd7e8b30e715efc8d71d215aec7fe7", "Bit Corporation", "R320", "Air Raiders (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4dbf47c7f5ac767a3b07843a530d29a5", "Ric Pryor", "", "Breaking News (2002) (Ric Pryor) (Hack)", "Hack of Bump 'n' Jump", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4dcc7e7c2ec0738e26c817b9383091af", "", "", "Unknown Title (bin00026 (200110)) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4dd6c7ab9ef77f2b4950d8fc7cd42ee1", "Retroactive", "", "Qb (V2.04) (Stella) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "4df6124093ccb4f0b6c26a719f4b7706", "Atari, Brad Stewart - Sears", "CX2622 - 6-99813, 49-75107", "Breakout (1978) (Atari) [a]", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 60", "", "", "", "" },
-  { "4df9d7352a56a458abb7961bf10aba4e", "", "", "Racing Car (Unknown)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" },
-  { "4e01d9072c500331e65bb87c24020d3f", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX26119", "Saboteur (06-15-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4e02880beeb8dbd4da724a3f33f0971f", "Imagic, Michael Greene", "EIZ-002-04I", "Wing War (1983) (Imagic) (PAL)", "AKA Flap!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4e15ddfd48bca4f0bf999240c47b49f5", "Avalon Hill, Jean Baer, Jim Jacob", "5001002", "Death Trap (1983) (Avalon Hill)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "4e2c884d04b57b43f23a5a2f4e9d9750", "", "", "Baby Center Animation (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "4e37992a37ea36489283f7eb90913bbc", "Kris", "", "Hangman Ghost Halloween (Kris) (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4e4895c3381aa4220f8c2795d6338237", "", "", "Backwards Cannonball v1 (Hack)", "Hack of Human Cannonball", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4e66c8e7c670532569c70d205f615dad", "Atari - GCC", "CX2680, CX2680P", "RealSports Tennis (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4e86866d9cde738d1630e2e35d7288ce", "Supergame", "", "River Raid III (Supergame)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4e99ebd65a967cabf350db54405d577c", "Coleco", "2663", "Time Pilot (1983) (Coleco) [b1]", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4eb4fd544805babafc375dcdb8c2a597", "Inspirational Video Concepts, Steve Shustack", "321430", "Red Sea Crossing (1983) (Inspirational Video Concepts)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4edb251f5f287c22efc64b3a2d095504", "Atari", "", "Atari VCS Point-of-Purchase ROM (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4f0071946e80ca68edfdccbac86dcce0", "", "", "Virtual Pet Demo 1 (CRACKERS) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4f2d47792a06da224ba996c489a87939", "HES - Activision", "223", "Super Action Pak - Pitfall, Barnstorming, Grand Prix, Laser Blast (1988) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4f32b24869d8c1310fecf039c6424db6", "U.S. Games Corporation - JWDA, Todd Marshall", "", "3-D Zapper (12-15-82) (U.S. Games) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "4f618c2429138e0280969193ed6c107e", "Activision, Alan Miller", "AZ-028, AG-028-04", "Robot Tank (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4f634893d54e9cabe106e0ec0b7bdcdf", "Retroactive", "", "Qb (2.14) (Retroactive) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "4f64d6d0694d9b7a1ed7b0cb0b83e759", "20th Century Fox Video Games, John Russell", "11016", "Revenge of the Beefsteak Tomatoes (1983) (20th Century Fox)", "AKA Revenge of the Cherry Tomatoes", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4f6702c3ba6e0ee2e2868d054b00c064", "Activision - Woodside Design Associates, Steve 'Jessica Stevens' Kitchen - Ariola", "EAZ-033 - 711 033-725", "Space Shuttle (1983) (Activision) (PAL)", "A Journey Into Space, Eine Reise ins All", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4f781f0476493c50dc578336f1132a67", "", "", "Indy 500 (Unknown) (PAL) (4K)", "Uses Driving Controllers", "", "", "", "", "", "", "", "", "DRIVING", "DRIVING", "", "", "", "45", "", "", "", "" },
-  { "4f7b07ec2bef5ccffe06403a142f80db", "Apollo - Games by Apollo, Ed Salvo, Byron Parks", "AP-2003", "Racquetball (1982) (Apollo) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "4f82d8d78099dd71e8e169646e799d05", "", "", "Miniature Golf (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4f89b897444e7c3b36aed469b8836839", "Atari", "CX26190", "BMX Air Master (1989) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4fae08027365d31c558e400b687adf21", "", "", "Qb (V2.17) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "4faeb04b1b7fb0fa25db05753182a898", "", "", "2600 Digital Clock (V x.xx) (PD) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4fbe0f10a6327a76f83f83958c3cbeff", "CCE", "C-816", "Keystone Kappers (1983) (CCE)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "4fc1b85b8074b4b9436d097900e34f29", "John K. Harvey", "", "John K. Harvey's Equalizer (John K. Harvey)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "50200f697aeef38a3ce31c4f49739551", "Mystique - American Multiple Industries, Joel H. Martin", "", "Custer's Revenge (1982) (Mystique) (PAL60)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "502044b1ac111b394e6fbb0d821fca41", "", "", "Hangman Invader 4letter (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "502168660bfd9c1d2649d415dc89c69d", "Activision, Bob Whitehead - Ariola", "EAG-019, EAG-019-04I - 711 019-715", "Sky Jinks (1982) (Activision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "504688d49a41bf03d8a955512609f3f2", "Thomas Jentzsch", "", "SWOOPS! (v0.94) (TJ)", "Uses the Joystick (L) and Paddle (R) Controllers", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "50568c80ac61cab789d9923c9b05b68e", "Ebivision", "", "Merlin's Walls - Standard Edition (1999) (Ebivision)", "Image rotated 90 degrees CW", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5069fecbe4706371f17737b0357cfa68", "Apollo - Games by Apollo, Steve Stringfellow", "AP-2005", "Shark Attack (1982) (Apollo) (PAL)", "AKA Lochjaw", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5079bfbc7b8f5770f84215ed2e3bdd1b", "Omegamatrix (2012)", "", "Genesis Button Tester", "", "Homebrew", "", "", "", "", "", "", "", "GENESIS", "GENESIS", "", "", "", "", "", "", "", "" },
-  { "50a410a5ded0fc9aa6576be45a04f215", "Activision, Bob Whitehead - Ariola", "EAG-019, EAG-019-04I - 711 019-715", "Sky Jinks (1982) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "50c7edc9f9dc0369abcdab3b4efeb5e9", "U.S. Games Corporation - JWDA, Todd Marshall", "", "3-D Zapper (U.S. Games) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "50ef88f9a5e0e1e6b86e175362a27fdb", "", "", "Multi-Sprite Game V2.4 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "512e874a240731d7378586a05f28aec6", "Tigervision, Rorke Weigandt - Teldec", "7-005", "Marauder (1982) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5131ab3797fe8c127e3e135b18b4d2c8", "Activision, David Crane", "AG-004", "Fishing Derby (1980) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "514f911ecff2be5eeff2f39c49a9725c", "Parker Brothers", "931510", "Sky Skipper (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "515046e3061b7b18aa3a551c3ae12673", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692", "Moon Patrol (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "516ffd008057a1d78d007c851e6eff37", "Parker Brothers, Dawn Stockbridge", "PB5910", "Strawberry Shortcake - Musical Match-Ups (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "517592e6e0c71731019c0cebc2ce044f", "Parker Brothers - JWDA, Todd Marshall", "PB5550", "Q-bert's Qubes (1984) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "517923e655755086a3b72c0b17b430e6", "Tron", "", "Super Tennis (Tron)", "AKA RealSports Tennis", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5188fee071d3c5ef0d66fb45c123e4a5", "Gameworld", "133-001", "Encounter at L-5 (1983) (Gameworld) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 50", "", "", "", "" },
-  { "519f007c0e14fb90208dbb5199dfb604", "Amiga - Video Soft", "", "Depth Charge (1983) (Amiga) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "51c1ddc9d6d597f71fb7efb56012abec", "Bit Corporation", "R320", "Lock 'n' Chase (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "51de328e79d919d7234cf19c1cd77fbc", "Atari, Mark R. Hahn", "CX2678", "Dukes of Hazzard (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "51e390424f20e468d2b480030ce95d7b", "Video Game Program", "", "Fire Bird (Video Game Program) (PAL)", "AKA Phoenix", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "51f15b39d9f502c2361b6ba6a73464d4", "", "", "Amanda Invaders (PD) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "51f211c8fc879391fee26edfa7d3f11c", "Activision, Bob Whitehead", "AX-015, AX-015-04", "Chopper Command (1982) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "521f4dd1eb84a09b2b19959a41839aad", "Bit Corporation", "PG206", "Bobby Is Going Home (1983) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "522b27a8afeb951b5a5a667f8d1a46a1", "Omegamatrix", "", "Millipede (Amiga Mouse) v6.5 (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "522c9cf684ecd72db2f85053e6f6f720", "Rainbow Vision - Suntek", "SS-008", "Year 1999, The (1983) (Rainbow Vision) (PAL)", "AKA Condor Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "52385334ac9e9b713e13ffa4cc5cb940", "CCE", "C-804", "Open, Sesame! (1983) (CCE)", "AKA Abre-te, Sesamo!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "523f5cbb992f121e2d100f0f9965e33f", "Joe Grand", "", "SCSIcide (1.30) (CGE 2001 Release) (Joe Grand)", "Uses the Paddle Controllers", "New Release", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "AUTO 65", "", "", "", "" },
-  { "524693b337f7ecc9e8b9126e04a232af", "", "", "Euchre (19-08-2001) (Eric Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5256f68d1491986aae5cfdff539bfeb5", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692", "Moon Patrol (07-26-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "525ea747d746f3e80e3027720e1fa7ac", "Activision, Garry Kitchen - Ariola", "EAZ-032 - 771 032-712", "Pressure Cooker (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "525f2dfc8b21b0186cff2568e0509bfc", "Activision, David Crane", "AG-930-04, AZ-030", "Decathlon (1983) (Activision) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "52615ae358a68de6e76467e95eb404c7", "", "", "DJdsl-wopd (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "528400fad9a77fd5ad7fc5fdc2b7d69d", "Starpath Corporation, Stephen H. Landrum, Jon Leupp", "11 AR-4201", "Sword of Saros (1983) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "52a0003efb3b1c49fcde4dbc2c685d8f", "Atari, Alan Miller - Sears", "CX2641 - 99807, 49-75105", "Surround (1977) (Atari) (4K) [a]", "", "", "", "", "2K", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "52b448757081fd9fabf859f4e2f91f6b", "", "", "Worm War I (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "52bae1726d2d7a531c9ca81e25377fc3", "", "", "Space Instigators (V1.8 Fixed) (20-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "52e1954dc01454c03a336b30c390fb8d", "Retroactive", "", "Qb (2.14) (Retroactive) (Stella)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "52e9db3fe8b5d336843acac234aaea79", "", "", "Fu Kung! (V0.11) (28-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5305f69fbf772fac4760cdcf87f1ab1f", "Jone Yuan Telephonic Enterprise Co", "", "Ski Run (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5324cf5b6dc17af4c64bf8696c39c2c1", "Imagic, Dennis Koble", "IA3203, IX-010-04", "Atlantis (1982) (Imagic) (8K)", "AKA Lost City of Atlantis", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "533661e9bccd8a9f80ce3765f282c92f", "Omegamatrix", "", "Star Wars Arcade (Atari Trak-Ball) (Y Inverted) v4 (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5336f86f6b982cc925532f2e80aa1e17", "Parker Brothers - JWDA, Todd Marshall, Robin McDaniel, Ray Miller", "PB5060", "Star Wars - Death Star Battle (1983) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "534e23210dd1993c828d944c6ac4d9fb", "M Network, Stephen Tatsumi, Jane Terjung - Kool Aid", "MT4648", "Kool-Aid Man (1983) (M Network)", "AKA Kool Aid Pitcher Man", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5355f80cacf0e63a49cbf4ade4e27034", "Christian Samuel", "", "Cute Dead Things House (Christian Samuel) (Hack)", "Hack of Haunted House", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5360693f1eb90856176bd1c0a7b17432", "", "", "Oystron (V2.85) (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "536bf56baa70acb17113884ac41f2820", "Atari, Omegamatrix", "", "Video Olympics Menu (2020) (PAL) (Hack)", "Hack of Video Olympics", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "AUTO 60", "", "", "", "" },
-  { "537ed1e0d80e6c9f752b33ea7acbe079", "", "", "A-VCS-tec Challenge (beta 5) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5385cf2a04de1d36ab55c73174b84db0", "Paul Slocum", "", "Combat Rock (PD) (Hack)", "Hack of Combat", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "539d26b6e9df0da8e7465f0f5ad863b7", "Atari, Carol Shaw - Sears", "CX2636 - 49-75156", "Video Checkers (1980) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "539f3c42c4e15f450ed93cb96ce93af5", "Dion Olsthoorn", "v1.3", "Amoeba Jump (2018) (Dionoid)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "53b66f11f67c3b53b2995e0e02017bd7", "CCE", "C-1005", "Super Tennis (1983) (CCE)", "AKA RealSports Tennis", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "53bd1c7c972ae634c912331a9276c6e3", "Atari, Nick 'Sandy Maiwald' Turner", "CX2665", "Frog Pond (1982) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "53d181cde2e0219b5754caad246fcb66", "", "", "Missile Demo (1998) (Ruffin Bailey) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "53e03df47e76329b701641f8bdc206f5", "Thomas Jentzsch", "", "Centipede - Atari Trak-Ball Hack v1.4 (PAL) (Half-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "53f147b9746fdc997c62f3dd67888ee5", "Activision, Bob Whitehead", "AG-011", "Stampede (1981) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "540075f657d4b244a1f74da1b9e4bf92", "Bit Corporation", "PGP230", "Festival (4 Game in One Dark Green) (1983) (BitCorp) (PAL)", "AKA Carnival", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5409d20c1aea0b89c56993aec5dc5740", "", "", "Carnival Shooter (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "541cac55ebcf7891d9d51c415922303f", "SpiceWare - Darrell Spice Jr.", "SW-05", "Stay Frosty 2", "AtariAge Holiday Greetings 2014", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "YES", "" },
-  { "5428cdfada281c569c74c7308c7f2c26", "Activision, Larry Kaplan, David Crane", "AG-010, AG-010-04", "Kaboom! (1981) (Activision)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
-  { "542c6dd5f7280179b51917a4cba4faff", "ZiMAG - Emag - Vidco", "GN-080", "Spinning Fireball (1983) (ZiMAG) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5438e84b90e50a5362f01cc843b358d4", "Arcadia Corporation, Scott Nelson", "3 AR-4300", "Fireball (1982) (Arcadia) (Prototype)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "543b4b8ff1d616fa250c648be428a75c", "Warren Robinett", "", "Adventure (1978) (Warren Robinett) (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "545048ccb045f9efc6cf2b125cd0dfa8", "Arcadia Corporation, Stephen Harland Landrum, Jon Leupp", "AR-4201", "Sword of Saros (1983) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "54785fa29e28aae6038929ba29d33d38", "", "", "Poker Squares (V0.19) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "54836a8f23913e9a77c7f2665baf36ac", "Bit Corporation", "PG204", "Open, Sesame! (1982) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5494b9ee403d9757f0fd1f749e80214a", "Larry Petit", "", "Xenophobe Arcade (2003) (Larry Petit) (Hack)", "Hack of Xenophobe", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "54a1c1255ed45eb8f71414dadb1cf669", "Spectravideo", "SA-212", "Mangia' (1983) (Spectravideo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "54bafc299423f5a50b8bc3a797914706", "SOLID Corp. (D. Scott Williamson)", "CX2655*", "Star Castle 2600 (SolidCorp) (PAL)", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "54da3b0b3f43f5b37911c135b9432b49", "", "", "Halloween III Revision (Hack)", "Hack of Kaboom!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
-  { "54f7efa6428f14b9f610ad0ca757e26c", "Apollo - Games by Apollo, Steve Stringfellow", "AP-2005", "Shark Attack (1982) (Apollo)", "AKA Lochjaw", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "551a64a945d7d6ece81e9c1047acedbc", "Matthias Jaap", "", "Coffee Cup Soccer (Matthias Jaap) (Hack)", "Hack of Pele's Soccer", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5524718a19107a04ec3265c93136a7b5", "Thomas Jentzsch", "", "RealSports Basketball (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "553dbf9358cfd2195e2fa0e08b01fb6a", "Atari - GCC, Mike Feinstein, Kevin Osborn", "CX2691", "Joust (07-05-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "554fd5775ca6d544818c96825032cf0d", "Atari - Roklan, Bob Curtiss", "", "Firefox (06-01-83) (Atari) (Prototype)", "AKA Combat II, Fighter Command", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "557e893616648c37a27aab5a47acbf10", "Atari - Axlon, Tod Frye - Heuristica, Augustin Ortiz", "CX26169", "Shooting Arcade (01-16-1990) (Atari) (Prototype) (PAL)", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "559317712f989f097ea464517f1a8318", "Panda", "100", "Space Canyon (1983) (Panda)", "AKA Space Cavern", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "55949cb7884f9db0f8dfcf8707c7e5cb", "Atari, Ed Logg, Carol Shaw - Sears", "CX2639 - 49-75162", "Othello (1981) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "55ace3c775f42eb46f08bb1dca9114e7", "", "", "Shadow Keep (04-03-2003) (Andrew Towers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "55ef6ab2321ca0c3d369e63d59c059c8", "", "", "Pitfall! (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "55ef7b65066428367844342ed59f956c", "Atari - Roklan, Joe Gaucher, Alex Leavens", "CX2683", "Crazy Climber (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "56210a3b9ea6d5dd8f417a357ed8ca92", "Probe 2000 - NAP, Roger Booth, Todd Marshall, Robin McDaniel, Jim Wickstead", "3152VC", "Pursuit of the Pink Panther (Probe) (Prototype) [bad dump]", "AKA Adventures of the Pink Panther", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "56300ed31fef018bd96768ccc982f7b4", "HES - Activision", "559", "Rad Action Pak - Kung-Fu Master, Freeway, Frostbite (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5641c0ff707630d2dd829b26a9f2e98f", "Joystik", "", "Motocross (Joystik)", "AKA Motocross Racer", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5643ee916f7dc760148fca4db3aa7d10", "", "", "Moon Patrol (Genesis)", "Genesis controller (C is jump)", "Hack of Moon Patrol", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5678ebaa09ca3b699516dba4671643ed", "Coleco, Sylvia Day, Henry Will IV", "2459", "Mouse Trap (1982) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "568371fbae6f5e5b936af80031cd8888", "", "", "Robotfindskitten2600 (26-04-2003) (Jeremy Penner)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "56f72247eb9ebfd33bfd0cca23ab7ef4", "Omegamatrix", "", "Star Wars Arcade (Amiga Mouse) v4 (PAL60) (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "571c6d9bc71cb97617422851f787f8fe", "Activision, David Crane - Ariola", "EAG-004, PAG-004 - 711 004-715", "Fishing Derby (1980) (Activision) (PAL)", "AKA Schneller als der Hai", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "572d0a4633d6a9407d3ba83083536e0f", "Funvision - Fund. International Co.", "", "Busy Police (Funvision)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "575c0fb61e66a31d982c95c9dea6865c", "", "", "Blackjack (Unknown) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "" },
-  { "57939b326df86b74ca6404f64f89fce9", "Atari, Sam Comstock, Richard Dobbis, Nick 'Sandy Maiwald' Turner", "CX26111", "Snoopy and the Red Baron (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "579baa6a4aa44f035d245908ea7a044d", "Jess Ragan", "", "Galaxian Enhanced Graphics (Jess Ragan) (Hack)", "Hack of Galaxian", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "57a66b6db7efc5df17b0b0f2f2c2f078", "Retroactive", "", "Qb (V2.08) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "57c5b351d4de021785cf8ed8191a195c", "Atari - CCW, Gary Stark", "CX26102", "Cookie Monster Munch (1983) (Atari)", "Uses Kids/Keypad Controllers", "", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "" },
-  { "5835a78a88f97acea38c964980b7dbc6", "", "", "Cosmic Creeps (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "5846b1d34c296bf7afc2fa05bbc16e98", "Atari - Sears", "CX2643 - 6-99815", "Codebreaker (1978) (Atari)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "58513bae774360b96866a07ca0e8fd8e", "Mystique - American Multiple Industries, Joel H. Martin", "1001", "Custer's Revenge (1982) (Mystique)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "585600522b1f22f617652c962e358a5d", "", "", "Multi-Sprite Game V2.2 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "585f73010e205ae5b04ee5c1a67e632d", "", "", "Daredevil (V3) (Stunt_Cycle_Rules!) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5864cab0bc21a60be3853b6bcd50c59f", "", "", "Commando Raid (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "58746219d8094edff869f0f5c2aeaad5", "Jone Yuan Telephonic Enterprise Co", "", "Bowling (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5894c9c0c1e7e29f3ab86c6d3f673361", "Activision - Woodside Design Associates, Steve 'Jessica Stevens' Kitchen", "AZ-033, AZ-033-04", "Space Shuttle (1983) (Activision)", "A Journey Into Space", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "589c73bbcd77db798cb92a992b4c06c3", "Xonox - K-Tel Software - Action Graphics, Michael Schwartz, David Thiel", "6230, 7210, 06004, 99004", "Artillery Duel (1983) (Xonox) (PAL60)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "58a82e1da64a692fd727c25faef2ecc9", "CCE", "C-824", "Jaw Breaker (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "58c396323ea3e85671e34c98eb54e2a4", "Brian Watson", "", "Color Tweaker (B. Watson)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "58d331c23297ed98663d11b869636f16", "", "", "Fu Kung! (V0.09) (26-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "58e313e2b5613b2439b5f12bb41e3eef", "", "", "Cube Conquest (Demo Interlace) (Billy Eno) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "590ac71fa5f71d3eb29c41023b09ade9", "Atari - GCC, Mark Ackerman, Tom Calderwood, Glenn Parker", "CX2684", "Galaxian (01-05-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "59135f13985b84c4f13cc9e55eec869a", "", "", "Multi-Sprite Game V2.0 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "594437a35603c3e857b5af75b9718b61", "HES - Activision", "", "Robot Tank (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "594dbc80b93fa5804e0f1368c037331d", "Telesys, Alex Leavens", "", "Bouncin' Baby Bunnies (1983) (Telesys) (Prototype)", "AKA Baby Boom Boom, Bouncing Baby Monkeys", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5961d259115e99c30b64fe7058256bcf", "Universal Gamex Corporation, Miguel Castillo, H.K. Poon", "GX-001", "X-Man (1983) (Universal)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "59734e1cc41822373845a09c51e6ba21", "Activision, John Van Ryzin", "AG-038-04", "Cosmic Commuter (1984) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "598a4e6e12f8238b7e7555f5a7777b46", "Tigervision", "7-008", "Miner 2049er (1983) (Tigervision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "599cbf919d47a05af975ad447df29497", "Jake Patterson", "", "Baubles (V0.002) (2001) (Jake Patterson) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "59b70658f9dd0e2075770b07be1a35cf", "Thomas Jentzsch", "", "Surfer's Paradise (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "59d33e00c07665395209c1e55da0b139", "", "", "Imagic Selector ROM (1982) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "59e53894b3899ee164c91cfa7842da66", "Data Age", "", "Survival Run (1983) (Data Age) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "59e96de9628e8373d1c685f5e57dcf10", "PlayAround - J.H.M.", "204", "Beat 'Em & Eat 'Em (1982) (PlayAround)", "Uses the Paddle Controllers", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" },
-  { "59f596285d174233c84597dee6f34f1f", "CCE", "C-811", "River Raid (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5a0ff99ba10bd26d542e1d6f59f56850", "Champ Games", "CG-04-P", "Super Cobra Arcade (PAL60)", "Compatible with Genesis controller", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "YES", "" },
-  { "5a17e30e6e911e74ccd7b716d02b16c6", "Activision, Dan Kitchen", "AX-029", "Crackpots (1983) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5a272012a62becabcd52920348c7c60b", "Star Game", "", "Pitfall (Star Game)", "AKA Pitfall!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5a2f2dcd775207536d9299e768bcd2df", "Otto Versand", "781698", "Flippern (Double-Game Package) (1983) (Otto Versand) (PAL)", "AKA Video Pinball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5a4205aeedd3b0588f973f38bbd9dfd4", "Thomas Jentzsch", "", "Centipede - Amiga Mouse Hack v1.4 (PAL) (Full-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5a5390f91437af9951a5f8455b61cd43", "Retroactive", "", "Qb (0.11) (Retroactive) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "5a6febb9554483d8c71c86a84a0aa74e", "CCE", "C-1003", "Donkey Kong Jr (1983) (CCE)", "AKA Donkey Kong Junior", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5a734779d797ccef25dc8acfa47244c7", "", "", "Oh No! (Version 2) (18-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5a80b857eb8b908ab477ec4ef902edc8", "Activision, Bob Whitehead", "AG-002, CAG-002, AG-002-04", "Boxing (1980) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5a81ad4e184050851e63c8e16e3dac77", "Jone Yuan Telephonic Enterprise Co", "Hack", "Sky Diver (Jone Yuan) (Hack)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5a8afe5422abbfb0a342fb15afd7415f", "Atari - Bobco, Robert C. Polaro", "CX26155", "Sprint Master (1988) (Atari)", "AKA Sprint 88, Sprint 2000", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5a93265095146458df2baf2162014889", "Activision, Steve Cartwright - Ariola", "EAX-031, EAX-031-04B - 711 031-717", "Frostbite (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5a9685c4d51a6c1d6a9544946d9e8dc3", "AtariAge", "", "Grandma's Revenge (AtariAge)", "Can use Driving Controller in right port", "", "", "", "", "", "", "", "", "", "DRIVING", "", "", "", "", "", "", "", "" },
-  { "5a9d188245aff829efde816fcade0b16", "CCE", "C-808", "Phantom Tank (1983) (CCE) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5acf9865a72c0ce944979f76ff9610f0", "", "", "Dodge Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5ae73916fa1da8d38ceff674fa25a78a", "CCE", "", "Barnstorming (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5aea9974b975a6a844e6df10d2b861c4", "Atari, Dan Hitchens. Mimi Nyden", "CX2656", "SwordQuest - EarthWorld (1982) (Atari)", "AKA Adventure I, SwordQuest I - EarthWorld", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5af9cd346266a1f2515e1fbc86f5186a", "SEGA", "002-01", "Sub-Scan (1983) (SEGA)", "AKA Subterfuge", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5b124850de9eea66781a50b2e9837000", "PlayAround - J.H.M.", "205", "Bachelor Party (1982) (PlayAround)", "Uses the paddle controllers", "Extremely Rare", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "AUTO 65", "", "", "YES", "" },
-  { "5b574faa56836da0866ba32ae32547f2", "", "", "Tomb Raider 2600 [REV 03] (Montezuma's Revenge Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5b5d04887922b430de0b7b2a21f9cd25", "", "", "Omega Race (Genesis)", "Genesis controller (B is thrust, C is fire)", "Hack of Omega Race", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5b6f5bcbbde42fc77d0bdb3146693565", "", "", "Seaquest (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5b7ea6aa6b35dc947c65ce665fde624b", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (2 of 3) (1982) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5b85e987e2b1618769d97ba9182333d0", "Atari - GCC, Mike Feinstein, Brad Rice", "CX2681", "Battlezone (05-12-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5b92a93b23523ff16e2789b820e2a4c5", "Activision - Imagineering, Dan Kitchen, Garry Kitchen", "AG-039-04", "Kung-Fu Master (1987) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5b98e0536c3f60547dd708ae22adb04b", "Ben Hudman", "", "Donkey Kong Gingerbread Man (Ben Hudman) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5b9c2e0012fbfd29efd3306359bbfc4a", "HES", "", "2 Pak Special - Hoppy, Alien Force (1992) (HES) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5babe0cad3ec99d76b0aa1d36a695d2f", "Coleco - Individeo, Ed Temple", "2654", "Looping (1983) (Coleco) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5bba254e18257e578c245ed96f6b003b", "", "", "Music Effects Demo (21-01-2003) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "5bbab3f3e4b47e3e23f9820765dbb45c", "", "", "Pitfall! (says 1985) [h1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5bbb75b49b2bccef9c91ff84bb249c80", "Thomas Jentzsch", "", "Missile Control - Atari Trak-Ball Hack v1.15 (NTSC) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5bc9998b7e9a970e31d2cb60e8696cc4", "Jack Kortkamp", "", "Borgwars Asteroids (2003) (Jack Kortkamp) (Hack)", "Hack of Asteroids", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "5bcc83677d68f7ef74c1b4a0697ba2a8", "Activision, Alan Miller", "AX-012, CAX-012, AX-012-04", "Ice Hockey (1981) (Activision) (16K)", "", "", "", "", "4K", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5bd79139a0c03b63f6f2cf00a7d385d2", "Marc de Smet", "", "An Exercise In Minimalism (V1) (1999) (Marc de Smet) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5be03a1fe7b2c114725150be04b38704", "Atari, Alan Miller", "CX2642", "Hunt & Score (1978) (Atari) (PAL)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5c0227ad63300670a647fcebf595ea37", "Josh", "", "Battle for Naboo (Josh) (Hack)", "Hack of Atlantis", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5c0520c00163915a4336e481ca4e7ef4", "Rainbow Vision - Suntek", "SS-004", "Pyramid War (1983) (Rainbow Vision) (PAL) [a1]", "AKA Chopper Command", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5c19f6da638c4c7c1f98d09e63df43e4", "Canal 3 - Intellivision", "", "Cosmic Ark (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5c1b1aa78b7609d43c5144c3b3b60adf", "", "", "Demo Image Series #8 - Two Marios (Different Interlacing) (27-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5c3a6d27c026f59a96b7af91e8b1bf26", "PlayAround - J.H.M.", "", "PlayAround Demo (PlayAround) (1982)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5c618a50dfa23daac97ba459b9ff5206", "Steve Engelhardt", "", "Berzerk Renegade (2002) (Steve Engelhardt) (Hack)", "Hack of Room of Doom", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "5c73693a89b06e5a09f1721a13176f95", "", "", "Wavy Line Test 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5c86e938e0845b9d61f458539e9a552b", "Atari, Alan Miller", "CX26163P", "Surround (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5cbd7c31443fb9c308e9f0b54d94a395", "Spectravideo, Mark Turmell", "SA-217", "Gas Hog (1983) (Spectravideo) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5ce98f22ade915108860424d8dde0d35", "", "", "Hangman Man Biglist3 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5ced13931c21ef4fc77d3fe801a1cbfa", "CCE", "C-828", "Missile Command (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5d0e8a25cbd23e76f843c75a86b7e15b", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (09-07-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5d132d121aabc5235dd039dfc46aa024", "", "", "Basketball (208 in 1) (Unknown) (PAL) (Hack)", "Console ports are swapped", "Hack", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" },
-  { "5d25df9dc2cde746ceac48e834cf84a7", "Activision - Woodside Design Associates, Steve 'Jessica Stevens' Kitchen", "EAZ-033", "Space Shuttle (1983) (Activision) (SECAM)", "A Journey Into Space", "", "", "", "FE", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5d2cc33ca798783dee435eb29debf6d6", "Activision - Imagineering, Mike Reidel", "AK-043-04", "Commando (1988) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5d7293f1892b66c014e8d222e06f6165", "Atari - Axlon, Tod Frye - Heuristica, Agustin Ortiz", "CX26169", "Shooting Arcade (03-07-1989) (Atari) (Prototype) [a1]", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5d799bfa9e1e7b6224877162accada0d", "Spectravision - Spectravideo - Sirius Software, David Lubar", "SA-206", "Challenge of.... Nexar, The (1982) (Spectravision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5d8f1ab95362acdf3426d572a6301bf2", "Thomas Jentzsch", "", "SWOOPS! (v0.96) (TJ) (PAL)", "Uses the Joystick (L) and Paddle (R) Controllers", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5d8fb14860c2f198472b233874f6b0c9", "", "", "Boing! (PD) [a2]", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5d9592756425192ec621d2613d0e683d", "CCE", "C-839", "Misterious Thief, A (1983) (CCE) [a]", "AKA A Mysterious Thief", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5da8fd0b5ed33a360bff37f8b5d0cd58", "Tron", "", "Pole Position (Tron)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5dae540347cf0a559962d62604ecf750", "Canal 3 - Intellivision", "", "Freeway (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5db9e5bf663cad6bf159bc395f6ead53", "Goliath - Hot Shot", "83-212", "Time Race (1983) (Goliath) (PAL)", "AKA Space Jockey", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5dccf215fdb9bbf5d4a6d0139e5e8bcb", "Froggo", "FG1009", "Sea Hunt (1987) (Froggo)", "AKA Skindiver", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5de8803a59c36725888346fdc6e7429d", "Atari, John Dunn - Sears", "CX2631 - 49-75152", "Superman (1979) (Atari) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5df32450b9fbcaf43f9d83bd66bd5a81", "Eric Ball", "", "Atari Logo Playfield Demo (2001) (Eric Ball) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5df559a36347d8572f9a6e8075a31322", "Digivision", "", "Enduro (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5e0c37f534ab5ccc4661768e2ddf0162", "Telegames - VSS, Ed Salvo", "5667 A106", "Glacier Patrol (1988) (Telegames)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5e1b4629426f4992cf3b2905a696e1a7", "Activision - Bobco, Robert C. Polaro", "AK-049-04", "Rampage! (1989) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5e1b7a6078af428ef056fe85a37a95ca", "Activision, David Crane", "AX-014, AX-014-04", "Grand Prix (1982) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5e1cd11a6d41fc15cf4792257400a31e", "Philip R. Frey", "", "Return of Mario Bros (Philip R. Frey) (Hack)", "Hack of Mario Bros.", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5e201d6bfc520424a28f129ee5e56835", "Universal Gamex Corporation, Miguel Castillo, H.K. Poon", "GX-001", "X-Man (1983) (Universal) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5e2495d43b981010304af55efed1e798", "Jone Yuan Telephonic Enterprise Co", "", "Math Gran Prix (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5e43c0391f7412ae64fae6f3742d6ee9", "Thomas Jentzsch, Paul Slocum", "", "Thrust+ Platinum (v1.27)", "", "New Release, supports BoosterGrip", "", "", "", "", "", "", "", "BOOSTERGRIP", "DRIVING", "", "", "", "", "", "", "", "" },
-  { "5e99aa93d0acc741dcda8752c4e813ce", "", "", "2600 Digital Clock (V b2) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5ec73ac7d2ac95ac9530c6d33e713d14", "Arcadia Corporation, Scott Nelson", "13", "Sweat! - The Decathlon Game (2 of 3) (1983) (Arcadia) (Prototype)", "Uses the Paddle Controllers (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5eeb81292992e057b290a5cd196f155d", "Wizard Video Games - VSS, Ed Salvo", "008", "Texas Chainsaw Massacre, The (1983) (Wizard Video)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5ef303b9f0aa8cf20720c560e5f9baa1", "Atari, Jim Huether", "CX2629, CX2629P", "Sky Diver (1979) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5f1b7d5fa73aa071ba0a3c2819511505", "CCE", "", "Cosmic Commuter (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5f2b4c155949f01c06507fb32369d42a", "Apollo, Ed Salvo", "AP-1001", "Skeet Shoot (1981) (Apollo) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5f316973ffd107f7ab9117e93f50e4bd", "", "", "Commando Raid (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5f39353f7c6925779b0169a87ff86f1e", "Atari - GCC, John Allred, Douglas B. Macrae, Betty Ryan Tylko", "CX2694", "Pole Position (1983) (Atari) [a]", "AKA RealSports Driving", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5f46d1ff6d7cdeb4b09c39d04dfd50a1", "Atari, Gary Palmer", "CX2661P", "Fun with Numbers (1980) (Atari) (PAL)", "AKA Basic Math", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5f4ebf8a1e5f5f7b9ff3e3c6affff3e6", "Bit Corporation", "R320", "Donkey Kong (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5f560837396387455c9dcb05cdd4b053", "Canal 3 - Intellivision", "", "Eggomania (Canal 3)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 60", "", "", "", "" },
-  { "5f681403b1051a0822344f467b05a94d", "Atari, Howard Scott Warshaw - Sears", "CX2655 - 49-75167", "Yars' Revenge (1982) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "5f708ca39627697e859d1c53f8d8d7d2", "Atari, Warren Robinett - Sears", "CX2606 - 6-99825, 49-75112", "Slot Racers (1978) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5f73e7175474c1c22fb8030c3158e9b3", "Atari, Nick 'Sandy Maiwald' Turner", "CX2665", "Frog Pond (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5f786b67e05fb9985b77d4beb35e06ee", "Atari, Bill Aspromonte, Andrew Fuchs", "CX26120", "Defender II (1987) (Atari) (PAL)", "AKA Stargate", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5f7ae9a7f8d79a3b37e8fc841f65643a", "Atari, Jerome Domurat, Peter C. Niday, Robert Vieira", "CX26109", "Sorcerer's Apprentice (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5f7de62a408b9de3a1168898298fd31d", "", "", "Super Cobra (Genesis)", "Genesis controller (B is bomb, C is laser)", "Hack of Super Cobra", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5f950a2d1eb331a1276819520705df94", "20th Century Fox Video Games - Micro Computer Technologies, Jim Collas", "", "Heart Like a Wheel (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "5f9b62350b31be8bd270d9a241cbd50e", "Telegames", "5658 A088", "Football (1988) (Telegames) (PAL)", "AKA Super Challenge Football", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5faffe1c4c57430978dec5ced32b9f4a", "Dactari - Milmar", "", "Volleyball (Dactari - Milmar)", "AKA RealSports Volleyball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "5fb71cc60e293fe10a5023f11c734e55", "", "", "This Planet Sucks (Fix) (27-12-2002) (Greg Troutman)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "600d48eef5c0ec27db554b7328b3251c", "", "", "Bars and Text Demo 3 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6015a9cef783e97e98a2aa2cf070ae06", "Thomas Jentzsch", "", "Battlezone TC (Thomas Jentzsch) (Hack)", "Uses two simultaneous Joystick Controllers, Hack of Battlezone", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "60358edf0c2cc76b1e549e031e50e130", "Manuel Polik", "", "Cyber Goth Galaxian (Manuel Polik) (Hack)", "Hack of Galaxian", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "603c7a0d12c935df5810f400f3971b67", "Bit Corporation", "PG209", "Mr. Postman (1983) (BitCorp) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6041f400b45511aa3a69fab4b8fc8f41", "Apollo, Ban Tran", "AP-2010", "Wabbit (1982) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "604e09724555807c28108049efe34a13", "", "", "Sokoban (01-01-2003) (Adam Wozniak)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6058e40ce79d7434c7f7477b29abd4a5", "", "", "Rubik's Cube Demo (23-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "605dcb73d22f4efdb90ef9da2f290f7c", "Atari, Larry Kaplan", "CX26163P", "Air-Sea Battle (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "605fd59bfef88901c8c4794193a4cbad", "Data Age", "", "Secret Agent (1983) (Data Age) (Prototype)", "Uses the Paddle Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "01 45", "", "", "", "" },
-  { "606c2c1753051e03c1f1ac096c9d2832", "Jone Yuan Telephonic Enterprise Co", "", "Crackpots (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6076b187a5d8ea7a2a05111c19b5d5cd", "", "", "Fu Kung! (V0.14) (01-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "60a61da9b2f43dd7e13a5093ec41a53d", "VentureVision, Dan Oliver", "VV2001", "Rescue Terra I (1982) (VentureVision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "60bbd425cb7214ddb9f9a31948e91ecb", "Activision, Bob Whitehead", "AG-005, CAG-005, AG-005-04", "Skiing (1980) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "60cd61a2dfccb0e2736434f9792c1672", "Amiga - Video Soft, Frank Ellis, Jerry Lawson", "2110", "3-D Havoc (1983) (Amiga) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "60d304582d33e2957b73eb300a7495bb", "", "", "Jam Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "60e0ea3cbe0913d39803477945e9e5ec", "Atari, Joe Decuir - Sears", "CX2621 - 99806, 6-99806, 49-75104", "Video Olympics (1977) (Atari)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXDR", "PADDLES_IAXDR", "YES", "", "", "AUTO 60", "", "", "", "" },
-  { "613abf596c304ef6dbd8f3351920c37a", "", "", "Boring Pac-Man (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6141c095d0aee4e734bebfaac939030a", "Rainbow Vision - Suntek", "SS-017", "Mariana (1983) (Rainbow Vision) (PAL)", "AKA Seaquest", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "61426cee013306e7f7367534ab124747", "", "", "One Blue Bar Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "615a3bf251a38eb6638cdc7ffbde5480", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX2674", "E.T. - The Extra-Terrestrial (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "61621a556ad3228f0234f5feb3ab135c", "", "", "Fu Kung! (V0.05 Cuttle Card Compattle Revision) (14-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "61631c2f96221527e7da9802b4704f93", "Activision - Imagineering, Mike Reidel", "AK-043-04", "Commando (1988) (Activision) [different logo]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "61719a8bdafbd8dab3ca9ce7b171b9e2", "", "", "Enduro (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "61728c6cfb052e62a9ed088c5bf407ba", "", "", "Sprite Demo 4 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "619de46281eb2e0adbb98255732483b4", "", "", "Time Warp (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "61baadddc2c8f6e5faa57d4d0f285462", "", "", "208-in-1 MDM-Test (PAL) (127 games)", "", "", "", "", "MDM", "", "", "", "", "JOYSTICK", "JOYSTICK", "", "", "", "", "", "", "", "" },
-  { "61dbe94f110f30ca4ec524ae5ce2d026", "CCE", "C-820", "Space Invaders (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "61e0f5e1cc207e98704d0758c68df317", "Star Game", "007", "Tennis (Star Game)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "61ef8c2fc43be9a04fe13fdb79ff2bd9", "", "", "Gas Gauge Demo - Revisited (2001) (Joe Grand) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6205855cc848d1f6c4551391b9bfa279", "", "", "Euchre (Release Candidate 2) (NTSC) (01-10-2002) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6238ac888871fec301d1b9fc4fc613c9", "Thomas Jentzsch", "", "Marble Craze - Atari Mouse Hack v1.0 (PAL) (TJ)", "Uses Atari Mouse Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "624e0a77f9ec67d628211aaf24d8aea6", "Panda", "108", "Sea Hawk (1983) (Panda)", "AKA Seahawk", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "626d67918f4b5e3f961e4b2af2f41f1d", "Atari", "50008", "Diagnostic Test Cartridge 2.0 (1980) (Atari) (Prototype)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6272f348a9a7f2d500a4006aa93e0d08", "Atari, Jerome Domurat, Michael Sierchio", "CX2667, CX2667P", "RealSports Soccer (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "62899430338e0538ee93397867d85957", "Gameworld", "133-004", "Airlock (1983) (Gameworld) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "62921652f6634eb1a0940ed5489c7e18", "", "", "SCSIcide (V1.09) (2001) (Joe Grand)", "", "", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "AUTO 65", "", "", "", "" },
-  { "62992392ea651a16aa724a92e4596ed6", "Eric Mooney", "", "Invaders by Erik Mooney (Beta) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "62d1f50219edf9a429a9f004c19f31b3", "JWDA, Todd Marshall", "", "Euro Gen (02-01-83) (JWDA) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "62ee2b8f59e9cd6285bbdb674a952e8b", "Probe 2000 - NAP, Roger Booth, Todd Marshall, Robin McDaniel, Jim Wickstead", "3152VC", "Pursuit of the Pink Panther (Probe) (Prototype)", "AKA Adventures of the Pink Panther", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "62f74a2736841191135514422b20382d", "", "", "Pharaoh's Curse (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "PAL60", "", "YES", "" },
-  { "62ffd175cac3f781ef6e4870136a2520", "", "", "2600 Digital Clock (V x.xx) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "63166867f75869a3592b7a94ea62d147", "", "", "Indy 500 (Hack) [a1]", "Hack of Indy 500", "Hack", "", "", "", "", "", "", "", "DRIVING", "DRIVING", "", "", "", "", "", "", "", "" },
-  { "6333ef5b5cbb77acd47f558c8b7a95d3", "Greg Troutman", "", "Dark Mage (Greg Troutman) (PD) (8K)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "6337927ad909aa739d6d0044699a916d", "Jeffry Johnston", "", "Radial Pong - Version 2 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6339d28c9a7f92054e70029eb0375837", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (1984) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "6342afe9c9ad1b6120b8f6fb040d0926", "", "", "Move a Blue Blob Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6354f9c7588a27109c66905b0405825b", "Thomas Jentzsch", "", "Amidar DS (2003) (TJ) (Hack)", "Hack of Amidar", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6358f7f8bf0483402a080efccf250d61", "CommaVid, John Bronstein", "CM-003", "Cosmic Swarm (1982) (CommaVid) (Prototype)", "AKA Termite", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "635cc7a0db33773959d739d04eff96c2", "", "", "Minesweeper (V.90) (Soren Gust) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6362396c8344eec3e86731a700b13abf", "Panda", "109", "Exocet (1983) (Panda)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "637efac676ff063f2fbb0abff77c4fa5", "", "", "Noize Maker Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "63811ed69bdbc35c69d8aa7806c3d6e9", "Atari", "CX26163P", "Homerun (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "638cc82ea96f67674595ba9ae05da6c6", "Rainbow Vision - Suntek", "SS-011", "Super Ferrari (1983) (Rainbow Vision) (PAL)", "AKA Enduro", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "63a6eda1da30446569ac76211d0f861c", "Activision, David Crane", "AG-001", "Dragster (1980) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "63a7445b1d3046d3cdcdbd488dca38d9", "Rob Kudla", "", "Better Space Invaders (1999) (Rob Kudla) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "63c5fef3208bb1424d26cf1ab984b40c", "", "", "Analog Clock (V0.1) (20-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "63c7395d412a3cd095ccdd9b5711f387", "Eric Ball", "ELB005", "Skeleton+ (PAL)", "Stereo sound", "Homebrew", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "63d6247f35902ba32aa49e7660b0ecaa", "", "", "Space War (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "63e42d576800086488679490a833e097", "Telesys, Jim Rupp", "1004", "Ram It (1983) (Telesys) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "63e783994df824caf289b69a084cbf3e", "David Marli", "", "Fat Albert (David Marli) (Hack)", "Hack of Fast Food", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "63e9e612bbee31045f8d184a4e53f8ec", "ATARITALIA", "", "Moby Blues (2002) (ATARITALIA) (Hack)", "Hack of Mario Bros", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "640a08e9ca019172d612df22a9190afb", "Atari - GCC, Mike Feinstein, Kevin Osborn", "CX2691, CX2691P", "Joust (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "64198bb6470c78ac24fcf13fe76ab28c", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (1982) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "643e6451eb6b8ab793eb60ba9c02e000", "Salu - Avantgarde Software, Michael Buetepage", "460741", "Ghostbusters II (1992) (Salu) (PAL) [different tune]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "645bf7f9146f0e4811ff9c7898f5cd93", "Xonox - K-Tel Software - VSS, Robert Weatherby", "6230, 6250", "Super Kung-Fu (1983) (Xonox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6468d744be9984f2a39ca9285443a2b2", "Atari, Ed Logg, Carol Shaw", "CX26163P", "Reversi (32 in 1) (1988) (Atari) (PAL)", "AKA Othello", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "647162cceb550fd49820e2206d9ee7e8", "", "", "Skeleton (NTSC) (2002) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "64b8e19c767191ccdc97acc6904c397b", "Jeffry Johnston", "", "Radial Pong - Version 6 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "64ca518905311d2d9aeb56273f6caa04", "CCE", "", "Cubo Magico (CCE)", "AKA Cubicolor", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "64d43859258dc8ca54949e9ff4174202", "Thomas Jentzsch", "", "Lilly Adventure (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "64fab9d15df937915b1c392fc119b83b", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX26119", "Saboteur (05-20-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "650df778c6ce22d3fd1a7c33c565bcc3", "Atari - GCC, Betty Ryan Tylko, Douglas B. Macrae", "CX2694", "Pole Position (1983) (Atari)", "Genesis controller (B is high gear, C is low gear, left difficulty switch swaps gear buttons)", "Hack of Pole Position", "", "", "", "", "", "", "", "GENESIS", "", "", "", "", "", "", "", "", "" },
-  { "651d2b6743a3a18b426bce2c881af212", "CCE", "C-812", "Pac Man (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6522717cfd75d1dba252cbde76992090", "Home Vision - Gem International Corp. - VDI", "VCS83102", "War 2000 (1983) (Home Vision) (PAL)", "AKA Astrowar", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6538e454b0498ad2befe1ef0f87815c0", "Joe Grand", "", "SCSIcide (v1.2) (2001) (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "AUTO 65", "", "", "", "" },
-  { "65490d61922f3e3883ee1d583ce10855", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692, CX2692P", "Moon Patrol (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "65562f686b267b21b81c4dddc129d724", "", "", "Euchre (28-07-2001) (Eric Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "655c84e5b951258c9d20f0bf2b9d496d", "", "", "2600_2003 Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "656dc247db2871766dffd978c71da80c", "Sears Tele-Games, Jim Huether", "CX2614 - 49-75126", "Steeplechase (1981) (Sears)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "AUTO 60", "", "", "", "" },
-  { "6588d192d9a8afce27b44271a2072325", "Bit Corporation", "R320", "Basketball (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "65917ae29a8c9785bb1f2acb0d6aafd0", "", "", "Junkosoft One Year Demo (1999) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6596b3737ae4b976e4aadb68d836c5c7", "Digivision", "", "Defender (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "659a20019de4a23c748ec2292ea5f221", "Retroactive", "", "Qb (V2.05) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "65a6f1255fe22468a8bf84ff28a4d289", "Akor", "", "Super TV Boy (1995) (Akor)", "Includes 127 games", "", "", "", "", "", "", "", "", "JOYSTICK", "JOYSTICK", "", "", "", "", "", "", "", "" },
-  { "65b106eba3e45f3dab72ea907f39f8b4", "Christian Software Development - HomeComputer Software, Dan Schafer, Glenn Stohel, Jon Tedesco - Sparrow", "GCG 1001T", "Music Machine, The (1983) (Sparrow)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" },
-  { "65ba1a4c643d1ab44481bdddeb403827", "Quelle", "876.013 4", "Katastrophen-Einsatz (1983) (Quelle) (PAL)", "AKA M.A.S.H.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "65bd29e8ab1b847309775b0de6b2e4fe", "Coleco, Ed English", "2667", "Roc 'n Rope (1984) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "65c6406f5af934590097c8c032ebb482", "", "", "Three Hugger (Pave Demo) (20-12-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6604f72a966ca6b2df6a94ee4a68eb82", "", "", "MegaMania (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "662eca7e3d89175ba0802e8e3425dedb", "", "", "Hangman Pac-Man Biglist3 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "66362890eb78d6ea65301592cce65f5b", "", "", "Euchre (13-07-2001) (Eric Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "663ef22eb399504d5204c543b8a86bcd", "CBS Electronics - Roklan, Joe Hellesen, Joe Wagner", "4L1720, 4L1721, 4L1722, 4L2276", "Wizard of Wor (1982) (CBS Electronics) (PAL)", "Uses the Joystick Controllers (swapped)", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "YES", "" },
-  { "664d9bfda6f32511f6b4aa0159fd87f5", "Atari - Roklan, Joe Gaucher", "", "Racer (1982) (Atari) (Prototype) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6651e2791d38edc02c5a5fd7b47a1627", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (04-05-1984) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "665b8f8ead0eef220ed53886fbd61ec9", "Telesys, Don Ruffcorn, Jack Woodman", "1003", "Fast Food (1982) (Telesys)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "66706459e62514d0c39c3797cbf73ff1", "Video Gems", "VG-05", "Treasure Below (1983) (Video Gems) (PAL)", "", "", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6672de8f82c4f7b8f7f1ef8b6b4f614d", "Videospielkassette - Ariola", "PGP237", "Angeln I (Ariola) (PAL)", "AKA Fishing Derby", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "667a70b028f581d87648693b873bc962", "Parker Brothers - Roklan, Joe Gaucher", "PB5370", "Popeye (1983) (Parker Bros) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "668dc528b7ea9345140f4fcfbecf7066", "Gakken", "001", "Pooyan (1983) (Gakken) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6697f177847c70505824422e76aad586", "", "", "Tennis (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "669840b0411bfbab5c05b786947d55d4", "Atari, Andrew Fuchs, Jeffrey Gusman, Dave Jolly, Suki Lee", "CX26117", "Obelix (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "66b89ba44e7ae0b51f9ef000ebba1eb7", "Atari - CCW, Stephan R. Keith, Laura Scholl, Preston Stuart", "CX26106", "Grover's Music Maker (01-18-1983) (Atari) (Prototype)", "Uses Keypad Controller", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "66b92ede655b73b402ecd1f4d8cd9c50", "Activision, John Van Ryzin - Ariola", "EAZ-036-04, EAZ-036-04B, EAZ-036-04I - 711 036-720", "H.E.R.O. (1984) (Activision) (PAL) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "66bc1bef269ea59033928bac2d1d81e6", "Arcadia Corporation, Scott Nelson", "AR-4300", "Fireball (Preview) (1982) (Arcadia)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" },
-  { "66c2380c71709efa7b166621e5bb4558", "Parker Brothers, Dave Engman, Dawn Stockbridge", "931509", "Tutankham (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "66c4e0298d4120df333bc2f3e163657e", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (2 of 3) (1982) (Starpath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "66f49b3248791b9803fa3e2f4165d072", "Bit Corporation", "R320", "Football (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "66fcf7643d554f5e15d4d06bab59fe70", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (09-13-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6706a00f9635508cfeda20639156e66e", "Atari, Jerome Domurat, Michael Sierchio", "CX2667", "RealSports Soccer (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "672012d40336b403edea4a98ce70c76d", "", "", "Spider Kong (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "675ae9c23fa1aae376cea86cad96f9a5", "", "", "Poker Squares (V0.25) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "67631ea5cfe44066a1e76ddcb6bcb512", "", "", "Termool (Unknown) (PAL)", "AKA Turmoil", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "67684a1d18c85ffa5d82dab48fd1cb51", "Tigervision, Warren Schwader - Teldec", "7-003", "Threshold (1982) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "678c1d71a1616d9d022f03d8545b64bb", "", "", "Demo Image Series #11 - Donald And Mario (28-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "67931b0d37dc99af250dd06f1c095e8d", "CommaVid, Irwin Gaines", "CM-004", "Room of Doom (1982) (CommaVid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "679d30c7886b283cbe1db4e7dbe5f2a6", "Colin Hughes", "", "Puzzle (Colin Hughes) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "679e910b27406c6a2072f9569ae35fc8", "Data Age", "DA1002", "Warplock (1982) (Data Age)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 40", "", "", "YES", "" },
-  { "67bd3d4dc5ac6a42a99950b4245bdc81", "Retroactive", "", "Qb (2.11) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "67c05ae94bf8b83a666c3ae2c4bc14de", "Atari", "CX26163P", "NFL Football (32 in 1) (1988) (Atari) (PAL) (4K)", "AKA Football", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "67cdde4176e0447fc45a71e0a1cdd288", "Telegames - VSS, Ed Salvo", "5665 A016", "Glacier Patrol (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "67ce6cdf788d324935fd317d064ed842", "Retroactive", "", "Qb (V2.09) (Stella) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "67cf913d1df0bf2d7ae668060d0b6694", "", "", "Hangman Monkey 4letter (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "67f90d74fd0b72fdc6d9b92436780ea9", "Omegamatrix", "", "SpaceMaster X-7 (Atari Trak-Ball) (PAL60) (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6803fa7c2c094b428b859a58dc1dd06a", "Retroactive", "", "Qb (0.11) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "6805734a0b7bcc8925d9305b071bf147", "Bit Corporation", "PGP229", "Kung Fu (4 Game in One Dark Green) (1983) (BitCorp) (PAL)", "AKA Karate", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "681206a6bde73e71c19743607e96c4bb", "", "", "Casino (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6833c26f385e866f3a0fa0dff311216e", "Thomas Jentzsch", "", "Centipede - Atari Mouse Hack v1.4 (PAL60) (Full-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "683bb0d0f0c5df58557fba9dffc32c40", "Arcadia Corporation, Scott Nelson", "AR-4300", "Fireball (1982) (Arcadia) [a]", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" },
-  { "683dc64ef7316c13ba04ee4398e2b93a", "Ed Federmeyer", "", "Edtris (1995) (Ed Federmeyer)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "68449e4aaba677abcd7cde4264e02168", "", "", "Horizonal Color Bars Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6847ce70819b74febcfd03e99610243b", "", "", "Ruby Runner 4A50", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "68489e60268a5e6e052bad9c62681635", "Bit Corporation", "PG201", "Sea Monster (1982) (BitCorp) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "68597264c8e57ada93be3a5be4565096", "Data Age", "DA1005", "Bugs (1982) (Data Age)", "Uses the Paddle Controllers", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 50", "", "", "", "" },
-  { "685e9668dc270b6deeb9cfbfd4d633c3", "CommaVid, Irwin Gaines - Ariola", "CM-004 - 712 004-720", "Room of Doom (1982) (CommaVid) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "68760b82fc5dcf3fedf84376a4944bf9", "CCE", "C-860", "Laser Gate (1983) (CCE)", "AKA Innerspace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "687c23224e26f81c56e431c24faea36d", "", "", "Qb (Simple Background Animation) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "68878250e106eb6c7754bc2519d780a0", "CCE", "C-809", "Squirrel (1983) (CCE)", "AKA Snail Against Squirrel", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "68ac69b8e1ba83af8792f693f5ae7783", "Digivision", "", "Fathon (Digivision)", "AKA Fathom", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "68c80e7e1d30df98a0cf67ecbf39cc67", "Hozer Video Games", "", "Gunfight 2600 - One Step Forward & Two Steps Back (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "68c938a2a2b45c37db50509f1037fe6e", "Omegamatrix", "", "Star Wars Arcade (Atari Mouse) v4 (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "68cd2adc6b1fc9a1f263ab4561112f30", "Thomas Jentzsch", "", "Boulderdash Demo (09-12-2002) (TJ)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "68feb6d6ff63e80df1302d8547979aec", "", "", "Starfield Demo 2 (20-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "690a6049db78b9400c13521646708e9c", "King Tripod Enterprise Co.", "SS - 007", "Space Raid (King Tripod) (PAL)", "AKA Challenge of.... Nexar, The", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6913c90002636c1487538d4004f7cac2", "Atari - CCW", "CX26131", "Monster Cise (1984) (Atari) (Prototype)", "Uses the Keypad Controllers (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "691d67910b08b63de8631901d1887c1f", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (1983) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "692202772d8b38ccf85a90c8003a1324", "", "", "Zi - The Flie Buster (2002) (Fernando Mora) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "693137592a7f5ccc9baae2d1041b7a85", "", "", "Qb (V2.02) (Stella) (2001) (Retroactive) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "6936aa6763835f62ac13d1aaa79b9f91", "Thomas Jentzsch", "", "Centipede - Atari Trak-Ball Hack v1.4 (NTSC) (Half-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6979f30204149be3e227558cffe21c1d", "Atari", "CX26163P", "Miniaturer Golf (32 in 1) (1988) (Atari) (PAL) (4K)", "AKA Miniature Golf", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6982854657a2cc87d712f718e402bf85", "Zellers", "", "Earth Attack (Zellers)", "AKA Defender", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "69877da5caded48315e3e45882a303d5", "Atari - Roklan, Joe Gaucher, Alex Leavens", "CX2683", "Crazy Climber (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "698f569eab5a9906eec3bc7c6b3e0980", "SpkLeader", "", "Demons! (2003) (SpkLeader) (Hack)", "Hack of Phoenix", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "69974dd5d6420b90898cde50aec5ef39", "Activision, David Crane", "AG-009, AG-009-04", "Freeway (1981) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "69df0411d4d176e558017f961f5c5849", "CCE", "C-831", "Cosmic Ark (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "69e79b1352b9ee1754bbe63b4a7062c3", "Barry Laws Jr.", "", "Pink Floyd - The Wall (2003) (Barry Laws Jr.) (Hack)", "Hack of Berzerk", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "69ebf910ab9b63e5b8345f016095003b", "", "", "Maze Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "69edfb4e1810a523311b3e250fc1e275", "Thomas Jentzsch", "", "Missile Command Atari Trak-Ball Hack v1.3 (PAL) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "69fac82cd2312dd9ce5d90e22e2f070a", "Spectravision - Spectravideo - Quelle", "SA-202 - 412.851 8", "Planet Patrol (1982) (Spectravision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6a03c28d505bab710bf20b954e14d521", "", "", "Pressure Gauge 2 Beta (Hozer Video Games)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6a07836c382195dd5305ce61d992aaa6", "Apollo, Larry Martin", "AP-2008", "Guardian (1982) (Apollo) (Prototype)", "Uses the Paddle Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" },
-  { "6a091b8ffeacd0939850da2094b51564", "", "", "Vertically Scrolling Playfield (02-02-2003) (Aaron Bergstrom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6a222c26bcece3a510ddda21398f72c6", "Bit Corporation", "PG203", "Phantom Tank (1982) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6a2c68f7a77736ba02c0f21a6ba0985b", "Atari, Larry Wagner, Bob Whitehead", "", "Computer Chess (07-07-1978) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6a3b0c33cf74b1e213a629e3c142b73c", "Cody Pittman", "", "Cory The Interviewer (Cody Pittman) (Hack)", "Hack of Ghostbusters", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6a76d5f0ed721639474aa9bbde69ebf0", "", "", "Play Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "6a82b8ecc663f371b19076d99f46c598", "Activision, Larry Miller - Ariola", "EAX-026, EAX-026-04B, EAX-026-04I - 711 026-725", "Enduro (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6a882fb1413912d2ce5cf5fa62cf3875", "Video Game Cartridge - Ariola", "TP-605", "Dragon Defender (Ariola) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "6a8c6940d3be6fd01274363c4d4b298e", "", "", "Spy Hunter (Genesis)", "Genesis controller (C is oil/smoke)", "Hack of Spy Hunter", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6a9b30ca46b0dba9e719f4cbd340e01c", "", "", "Frostbite (Unknown) (PAL) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6a9e0c72fab92df70084eccd9061fdbd", "CCE", "C-835", "Beany Bopper (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6aa66e9c3eea76a0c40ef05513497c40", "", "", "Hangman Ghost Biglist2 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6ac3fd31a51730358708c7fdc62487f8", "Matthias Jaap", "", "PC Invaders (Matthias Jaap) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6aca52e11b597ab84b33d5252e1cd9d1", "Bit Corporation", "R320", "Tac-Scan (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 60", "", "", "", "" },
-  { "6ae4dc6d7351dacd1012749ca82f9a56", "Atari - GCC, Jaques Hugon, Seth Lipkin", "CX26125, CX26127", "Track and Field (1984) (Atari)", "Uses the Track & Field Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6b01a519b413f8cfa2f399f4d2841b42", "", "", "Aphex Invaders (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6b1fc959e28bd71aed7b89014574bdc2", "Bit Corporation", "PG203", "Phantom Tank (1982) (BitCorp) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6b4eb5b3df80995b8d9117cb7e9aeb3c", "Gameworld, J. Ray Dettling", "133-006", "Journey Escape (1983) (Gameworld) (PAL)", "AKA Rock 'n' Roll Escape", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "6b683be69f92958abe0e2a9945157ad5", "U.S. Games Corporation - Western Technologies, Jeff Corsiglia, Paul Allen Newell, Steven B. Sidley, Tom Sloper", "VC2007", "Entombed (1983) (U.S. Games)", "Released as Name That Game for a contest (winning name was Entombed)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "6b6ca32228ae352b4267e4bd2cddf10c", "", "", "Pac-Man 4 (Pac-Man Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6b71f20c857574b732e7a8e840bd3cb2", "", "", "Frostbite (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6b72b691ea86f61438ed0d84c4d711de", "", "", "Fishing Derby (Unknown) (PAL) (4K) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6b75f8fa4fd011a6698c58315f83d2ac", "Thomas Jentzsch", "", "Sprintmaster DC (TJ)", "Uses the Driving Controllers, Hack of Sprintmaster (Atari)", "New Release (Hack)", "", "", "", "", "", "", "", "DRIVING", "DRIVING", "", "", "", "45", "", "", "", "" },
-  { "6b7a56b6ac2ca4bf9254474bf6ed7d80", "", "", "Horizonal Color Bars Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6b7e1c11448c4d3f28160d2de884ebc8", "Zirok", "", "Fast Food (Zirok)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6b8fb021bb2e1f1e9bd7ee57f2a8e709", "Paul Slocum", "", "3-D Corridor (29-03-2003) (Paul Slocum) (PD) [a]", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6bb09bc915a7411fe160d0b2e4d66047", "Atari", "CX26163P", "UFO (32 in 1) (1988) (Atari) (PAL)", "AKA Space Jockey", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6bb22efa892b89b69b9bf5ea547e62b8", "Dynacom", "", "Megamania (1982) (Dynacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6bde3f6ac31aceef447ce57d4d2c2ec0", "Piero Cavina", "", "Mondo Pong V1 (Piero Cavina) (PD)", "Uses the Paddle Controllers", "New Release", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "01", "", "", "", "" },
-  { "6c128bc950fcbdbcaf0d99935da70156", "Digitel", "", "Volleyball (1983) (Digitel)", "AKA RealSports Volleyball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6c1553ca90b413bf762dfc65f2b881c7", "Quelle", "343.073 3", "Winterjagd (1983) (Quelle) (PAL)", "AKA Ski Hunt", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6c1f3f2e359dbf55df462ccbcdd2f6bf", "Activision, Garry Kitchen - Ariola", "EAX-025, EAX-025-04I - 711 025-725", "Keystone Kapers (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6c25f58fd184632ca76020f589bb3767", "Dynacom", "", "Beat 'Em & Eat 'Em (1983) (Dynacom)", "Uses the Paddle Controller (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" },
-  { "6c449db9bbbd90972ad1932d6af87330", "", "", "20 Sprites at Once Demo 3 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6c658b52d03e01828b9d2d4718a998ac", "", "", "Hangman Invader Biglist2 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6c76fe09aa8b39ee52035e0da6d0808b", "Atari, Brad Stewart", "CX2622, CX2622P", "Breakout (1978) (Atari) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 60", "", "", "", "" },
-  { "6c85098518d3f94f7622c42fd1d819ac", "Suntek", "SS-028", "Firebug (1983) (Suntek) (PAL)", "AKA Spinning Fireball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6c91ac51421cb9fc72c9833c4f440d65", "ITT Family Games", "554-33 375", "Cosmic Town (1983) (ITT Family Games) (PAL)", "AKA Base Attack (Perry Rhodan-Serie)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6c9a32ad83bcfde3774536e52be1cce7", "", "", "Space Treat (NTSC) (13-08-2002) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6cab04277e7cd552a3e40b3c0e6e1e3d", "Telegames - VSS", "7062 A305", "Universal Chaos (1988) (Telegames) (Prototype)", "AKA Targ", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6cbe945e16d9f827d0d295546ac11b22", "", "", "Gunfight 2600 - AI (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6ccd8ca17a0e4429b446cdcb66327bf1", "", "", "RPG Engine (12-05-2003) (Paul Slocum) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "6cd1dc960e3e8d5c5e0fbe67ab49087a", "", "", "Vertical Playfield Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6cd506509e8fd5627f55603780e862a8", "Greg Troutman", "", "Dark Mage (SuperCharger) (Greg Troutman) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "6ce2110ac5dd89ab398d9452891752ab", "Funvision - Fund. International Co.", "", "Persian Gulf War (Funvision)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6cea35ded079863a846159c3a1101cc7", "", "", "Atlantis (208 in 1) (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6ceb7d6a54e9a5e62d26874d1cc88dbc", "Video Soft", "", "Atom Smasher (1984) (Video Soft) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6cf054cd23a02e09298d2c6f787eb21d", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (1984) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "6d218dafbf5a691045cdc1f67ceb6a8f", "Robin Harbron", "", "6 Digit Score Display (1998) (Robin Harbron) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6d475019ea30d0b29f695e9dcfd8f730", "Eric Mooney", "", "Invaders by Erik Mooney (Alpha 2) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6d74ebaba914a5cfc868de9dd1a5c434", "", "", "Fortress (Smooth Version) (20-04-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6d842c96d5a01967be9680080dd5be54", "Activision, Steve Cartwright, David Crane", "AB-035-04", "Pitfall II (1984) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6d8a04ee15951480cb7c466e5951eee0", "Zirok", "", "Kanguru (1983) (Zirok)", "AKA Kangaroo", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6d9afd70e9369c2a6bff96c4964413b7", "", "", "Time Warp (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6dda84fb8e442ecf34241ac0d1d91d69", "Atari - GCC, Douglas B. Macrae", "CX2677", "Dig Dug (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6de924c2297c8733524952448d54a33c", "CCE", "C-1006", "Moon Patrol (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6dfad2dd2c7c16ac0fa257b6ce0be2f0", "Parker Brothers, Larry Gelberg", "PB5065", "Star Wars - Ewok Adventure (1983) (Parker Bros) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6e179eee3d4631a7434d40cf7aeea6e8", "Wizard Video Games - MicroGraphic Image, Robert Barber, Tim Martin", "007", "Halloween (1983) (Wizard Video Games) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6e19428387686a77d8c8d2f731cb09e0", "", "", "Purple Cross Demo (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6e372f076fb9586aff416144f5cfe1cb", "Atari, Tod Frye - Sears", "CX2646 - 49-75185", "Pac-Man (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6e59dd52f88c00d5060eac56c1a0b0d3", "Atari, Bob Smith", "CX2648", "Video Pinball (1981) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6e5d5ba193d2540aec2e847aafb2a5fb", "Retroactive", "", "Qb (2.14) (Retroactive) (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "6e7ed74082f39ad4166c823765a59909", "", "", "Poker Squares (V0.14) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6e7efb0ed13ec28a00d19572de9c9f03", "Apollo - Games by Apollo", "AP-2006", "Infiltrate (1982) (Apollo) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6eb10fd23c7161751d18b9e8484c0004", "Coleco - JWDA, Todd Marshall, Robin McDaniel, Henry Will IV", "2465", "Smurf - Rescue in Gargamel's Castle (1983) (Coleco) (Prototype)", "AKA Smurf, Smurf Action", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6ed5012793f5ddf4353a48c11ea9b8d3", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix - Down on the Line (3 of 3) (1983) (Arcadia)", "Uses Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "01 70", "", "", "", "" },
-  { "6ed6bda5c42b2eb7a21c54e5b3ace3e3", "Canal 3 - Intellivision", "", "Ice Hockey (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6efe876168e2d45d4719b6a61355e5fe", "Bit Corporation", "PG207", "Mission 3,000 A.D. (1983) (BitCorp) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "6f084daf265599f65422ef4173b69bc7", "", "", "Music Kit (V2.0) - Song Player (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "6f2aaffaaf53d23a28bf6677b86ac0e3", "U.S. Games Corporation - Vidtec - JWDA, Garry Kitchen", "VC1001", "Space Jockey (1982) (U.S. Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6f3e3306da2aa6e74a5e046ff43bf028", "", "", "Defender Arcade (Genesis)", "Genesis controller (C is smartbomb)", "Hack of Defender 2", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6f744f14aac04f7e1ea0d3f4bafcb3e4", "Atari - Roklan, Joe Gaucher, Alex Leavens", "CX2683", "Crazy Climber (1983) (Atari) (Prototype) [a3]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6f74ed915ffe73b524ef0f63819e2a1d", "Eckhard Stolberg", "", "An Exercise In Minimalism (V2) (1999) (Eckhard Stolberg)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6fa0ac6943e33637d8e77df14962fbfc", "Imagic, Rob Fulop", "", "Cubicolor (1982) (Imagic) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6fac680fc9a72e0e54255567c72afe34", "", "", "Superman (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6fbd05b0ad65b2a261fa154b34328a7f", "", "", "Boardgame Demo (20-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6fc0176ccf53d7bce249aeb56d59d414", "Rainbow Vision - Suntek", "SS-004", "Pyramid War (1983) (Rainbow Vision) (PAL)", "AKA Chopper Command", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6fc27a9233fc69d28d3f190b4ff80f03", "", "", "UFO #6 (Charles Morgan) (Hack)", "Hack of Pepsi Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6fc394dbf21cf541a60e3b3631b817f1", "Imagic, Bob Smith", "720020-2A, IA3611P", "Dragonfire (1982) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "6fd7c7057eeab273b29c7aafc7429a96", "Activision, David Crane", "AX-018, AX-018-04", "Pitfall! (1982) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6fe67f525c39200a798985e419431805", "Atari - GCC, Kevin Osborn", "CX2689, CX2689P", "Kangaroo (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "6ff4156d10b357f61f09820d03c0f852", "Atari, Larry Kaplan - Sears", "CX2612 - 99804, 49-75103", "Street Racer (1977) (Atari) (4K)", "Uses the Paddle Controllers (swapped)", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 60", "", "", "", "" },
-  { "6ffc95108e5add6f9b8abcaf330be835", "Charles Morgan", "", "TP Bug (Charles Morgan) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "700a786471c8a91ec09e2f8e47f14a04", "Activision", "", "Hard-Head (1983) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "703d32062436e4c20c48313dff30e257", "", "", "Moving Maze Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "703f0f7af350b0fa29dfe5fbf45d0d75", "Bit Corporation", "P460", "4 Game in One Dark Green (1983) (BitCorp) (PAL)", "Rodeo Champ, Bobby is Going Home, Open Sesame, Festival", "", "", "", "4IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "705fe719179e65b0af328644f3a04900", "Atari, David Crane - Sears", "CX2653 - 6-99823, 49-75111", "Slot Machine (1979) (Atari) (4K) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "706e3cc4931f984447213b92d1417aff", "", "", "Joustpong (06-07-2002) (Kirk Israel) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "707ecd80030e85751ef311ced66220bc", "", "", "Double-Height 6-Digit Score Display (Background Color Change) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7096a198531d3f16a99d518ac0d7519a", "Telesys, Jim Rupp", "1004", "Ram It (1983) (Telesys)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "709910c2e83361bc4bf8cd0c20c34fbf", "Rainbow Vision - Suntek", "SS-006", "Netmaker (1983) (Rainbow Vision) (PAL)", "AKA Amidar", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "70a43fbdb1c039283ee5048d99842469", "Thomas Jentzsch", "", "Reactor - Atari Mouse Hack v1.3 (PAL) (Half-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "70a8480cfaf08776e5420365732159d2", "Rob Kudla", "", "Horizontally Scrolling Playfield Thing (Rob Kudla) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "70ce036e59be92821c4c7fd735ec6f68", "Activision, Steve Cartwright - Ariola", "EAX-031, EAX-031-04B - 711 031-717", "Frostbite (1983) (Activision) (PAL) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "70d14c66c319683b4c19abbe0e3db57c", "", "", "Oystron (V2.82) (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "710497df2caab69cdcc45e919c69e13f", "Arcadia Corporation, Dennis Caswell", "5 AR-4200", "Labyrinth (Escape from the Mindmaster Beta) (1982) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "713fde2af865b6ec464dfd72e2ebb83e", "", "", "Challenge (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "71464c54da46adae9447926fdbfc1abe", "M Network - INTV - APh Technological Consulting, Bruce Pedersen", "MT5663", "Lock 'n' Chase (1982) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "714e13c08508ee9a7785ceac908ae831", "Home Vision - Gem International Corp. - VDI", "VCS83123", "Parachute (1983) (Home Vision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "715dbf2e39ba8a52c5fe5cdd927b37e0", "Amiga - Video Soft", "3135", "S.A.C. Alert (1983) (Amiga) (Prototype)", "Uses Joyboard", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "715dd9e0240638d441a3add49316c018", "Atari", "", "128-in-1 Junior Console (Chip 2 of 4) (1991) (Atari) (PAL)", "Actually contains only 16 games, not 32", "", "", "", "16IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7187118674ff3c0bb932e049d9dbb379", "Zirok", "", "Keystone Keypers (1983) (Zirok)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "718ae62c70af4e5fd8e932fee216948a", "Data Age, J. Ray Dettling", "112-006", "Journey Escape (1983) (Data Age)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "718ee85ea7ec27d5bea60d11f6d40030", "Thomas Jentzsch", "", "Ghostbusters II (1992) (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "7197b6cbde6ecd10376155e6b848e80d", "Piero Cavina", "", "Multi-Sprite Game V2.1 (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "71b193f46c88fb234329855452dfac5b", "Digitel", "", "Atlantis (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "71d005b60cf6e608d04efb99a37362c3", "Atari, Larry Kaplan", "CX2643", "Codebreaker (1978) (Atari) (PAL) (4K) [a]", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "71f09f128e76eb14e244be8f44848759", "Funvision - Fund. International Co.", "", "Time Race (Funvision) (PAL)", "AKA Time Warp", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "71f8bacfbdca019113f3f0801849057e", "Atari, Dan Hitchens", "CX26126", "Elevator Action (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "72097e9dc366900ba2da73a47e3e80f5", "", "", "Euchre (15-06-2001) (Eric Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "721a5567f76856f6b50a6707aa8f8316", "Activision, David Crane, Dan Kitchen", "EAG-108-04, EAZ-108-04B", "Ghostbusters (1985) (Activision) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "72305c997f2cec414fe6f8c946172f83", "Arcadia Corporation, Dennis Caswell", "AR-4000, AR-4100", "Phaser Patrol (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "724613effaf7743cbcd695fab469c2a8", "", "", "Super-Ferrari (Unknown)", "AKA Enduro", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "728152f5ae6fdd0d3a9b88709bee6c7a", "Spectravideo, Mark Turmell", "SA-217", "Gas Hog (1983) (Spectravideo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "72876fd7c7435f41d571f1101fc456ea", "Quelle", "688.383 9", "Die Ente und der Wolf (1983) (Quelle) (PAL)", "AKA Pooyan", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "72a46e0c21f825518b7261c267ab886e", "Xonox - K-Tel Software - Computer Magic", "99005, 6220, 6250", "Robin Hood (1983) (Xonox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "72a5b5052272ac785fa076709d16cef4", "", "", "KC Munckin (29-01-2003) (J. Parlee)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "72a63bcb5eb31bd0fd5e98ed05125ec1", "Thomas Jentzsch", "", "Missile Control - Atari Trak-Ball Hack v1.15 (PAL60) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "72bda70c75dfa2365b3f8894bace9e6a", "Thomas Jentzsch", "", "Atlantis (TJ) (Hack)", "Hack of Atlantis", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "72d0acb5de0db662de0360a6fc59334d", "", "", "Cosmic Ark (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "72db1194b1cc7d45b242f25eb1c148d3", "", "", "Pac-Man (1981) (Atari) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "72fd08deed1d6195942e0c6f392e9848", "HES", "0701-406", "2 Pak Special - Wall Defender, Planet Patrol (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "72ffbef6504b75e69ee1045af9075f66", "Atari, Richard Maurer - Sears", "CX2632 - 49-75153", "Space Invaders (1980) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "73158ea51d77bf521e1369311d26c27b", "Zellers", "", "Challenge (Zellers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "73521c6b9fed6a243d9b7b161a0fb793", "Atari, Tom Reuterdahl", "CX26163P", "Miniaturer Golf (32 in 1) (1988) (Atari) (PAL)", "AKA Miniature Golf", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "736388d73198552d77d423962000006f", "Dactari", "", "Tennis (Dactari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "73a710e621d44e97039d640071908aef", "", "", "Barber Pole Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "73aa02458b413091ac940c0489301710", "Rainbow Vision - Suntek", "SS-016", "Boom Bang (1983) (Rainbow Vision) (PAL)", "AKA Crackpots", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "73b4e8f8b04515d91937510e680214bc", "", "", "Rubik's Cube Demo 3 (24-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "73c545db2afd5783d37c46004e4024c2", "CBS Electronics - JWDA, Todd Marshall, Robin McDaniel, Henry Will IV", "4L1767, 4L1768, 4L1769, 4L1770", "Smurf - Schtroumpfs (1983) (CBS Electronics) (PAL)", "Pitufo", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "73c839aff6a055643044d2ce16b3aaf7", "Activision, Alan Miller - Ariola", "EAX-016, PAX-016 - 711 016-725", "StarMaster (1982) (Activision) (PAL)", "Use Color/BW switch to change between galactic chart and front views", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "73cb1f1666f3fd30b52b4f3d760c928f", "", "", "Mines of Minos (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "73e66e82ac22b305eb4d9578e866236e", "Jone Yuan Telephonic Enterprise Co", "", "Unknown Datatech Game (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "73efa9f3cbe197f26e0fb87132829232", "CCE", "C-858", "Tennis (1983) (CCE) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "74023e0f2e739fc5a9ba7caaeeee8b6b", "Jone Yuan Telephonic Enterprise Co", "", "Fishing Derby (Jone Yuan) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "740a7fa80f52cc7287ba37677afb6b21", "", "", "Double Dragon (PAL) (Genesis)", "Genesis controller (C is jumpkick)", "Hack of Double Dragon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "740b47df422372fbef700b42cea4e0bf", "", "", "Dizzy Wiz (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "740f39e71104e90416c29a73560b9c6b", "Atari", "TE016643", "Diagnostic Test Cartridge 2.6P (1982) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7412f6788087d7e912c33ba03b36dd1b", "AtariAge, Omegamatrix", "", "Venture Reloaded (2019) (AtariAge) (Hack)", "Transformative hack of Venture", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "742de93b8d849220f266b627fbabba82", "", "", "SCSIcide (25-02-2001) (Chris Wilkson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7450ae4e10ba8380c55b259d7c2b13e8", "", "", "Register Twiddler Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7454786af7126ccc7a0c31fcf5af40f1", "", "", "Phantom Tank (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7465b06b6e25a4a6c6d77d02242af6d6", "Atari", "CX26193", "8 in 1 (01-16-92) (Atari) (Prototype)", "Game 2 is Centipede, but doesn't work", "Prototype", "", "", "8IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7481f0771bff13885b2ff2570cf90d7b", "Arcadia Corporation, Brian McGhie", "AR-4104", "Rabbit Transit (1983) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "749fec9918160921576f850b2375b516", "Spectravision - Spectravideo", "SA-205", "China Syndrome (1982) (Spectravision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "74d072e8a34560c36cacbc57b2462360", "Sancho - Tang's Electronic Co.", "TEC002", "Seahawk (1982) (Sancho) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "74ebaca101cc428cf219f15dda84b6f8", "Activision, Alan Miller", "AG-007, CAG-007", "Tennis (1981) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "74f623833429d35341b7a84bc09793c0", "Zellers", "", "Radar (Zellers)", "AKA Exocet", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "75028162bfc4cc8e74b04e320f9e6a3f", "Atari, Greg Easter, Mimi Nyden", "CX26107", "Snow White (02-09-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7511c34518a9a124ea773f5b0b5c9a48", "", "", "Donkey Kong (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "75169c08b56e4e6c36681e599c4d8cc5", "M Network - INTV - APh Technological Consulting, Hal Finney", "MT5666", "Astroblast (1982) (M Network)", "Can also use left joystick", "Uncommon", "", "", "", "", "", "", "", "PADDLES", "", "YES", "", "", "AUTO 55", "", "", "", "" },
-  { "752da1c0acd7d132ccfb0b1067f53cf6", "Thomas Jentzsch", "", "Reactor - Atari Mouse Hack v1.3 (PAL) (Full-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "753375d183c713cfa0aa7298d1f3067b", "Arcadia Corporation, Steve Hales, Stephen Harland Landrum", "AR-4102", "Suicide Mission (1982) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "7550b821ee56fb5833dca2be88622d5a", "", "", "Multiple Moving Objects Demo (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "75511bb694662301c9e71df645f4b5a7", "Activision, Bob Whitehead - Ariola", "EAG-011, PAG-011 - 711 011-715", "Stampede (1981) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "755fed16b48e81de05130708a905d00d", "SnailSoft", "", "Comitoid beta 3 (SnailSoft)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "756ca07a65a4fbbedeb5f0ddfc04d0be", "Atari, Jim Huether", "CX2629, CX2629P", "Sky Diver (1979) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7574480ae2ab0d282c887e9015fdb54c", "Atari, Jerome Domurat, Steve Woita", "CX2699", "Taz (1984) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7576dd46c2f8d8ab159d97e3a3f2052f", "Goliath - Hot Shot", "83-112", "Time Machine (1983) (Goliath) (PAL)", "AKA Asteroid Fire", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "757f529026696e13838364dea382a4ed", "Activision, David Crane - Ariola", "EAX-014, PAX-014, EAX-014-04B, EAX-014-04I - 711 014-720", "Grand Prix (1982) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "75893a9dc5de4b91cc426959b82a1da0", "Champ Games", "CG-02-P", "Conquest Of Mars (2010) (PAL60)", "Rev 2 release", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "75a303fd46ad12457ed8e853016815a0", "ZiMAG - Emag - Vidco", "715-111 - GN-060", "Immies & Aggies (1983) (ZiMAG) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "75b22fdf632d76e246433db1ebccd3c4", "", "", "Skeleton+ (05-05-2003) (Eric Ball) (PAL)", "", "", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "75b557be7f08db84ec5b242207b9f241", "", "", "Space Treat (30-12-2002) (Fabrizio Zavagli) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "75e276ba12dc4504659481c31345703a", "Arcadia Corporation, Kevin Norman", "AR-4103", "Killer Satellites (1983) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "75e8d8b9e9c5c67c2226dbfd77dcfa7d", "", "", "2600 Digital Clock (V b1) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "75ea128ba96ac6db8edf54b071027c4e", "Atari, David Crane", "CX26163P", "Slot Machine (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "75ea60884c05ba496473c23a58edf12f", "Atari, Howard Scott Warshaw - Sears", "CX2655 - 49-75167", "Yars' Revenge (1982) (Atari) (PAL) [a]", "ROM must be started in bank 0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "75ee371ccfc4f43e7d9b8f24e1266b55", "Atari, Greg Easter, Mimi Nyden", "CX26107", "Snow White (11-09-1982) (Atari) (Prototype)", "ROM must be started in bank 0", "Prototype", "", "0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7608abdfd9b26f4a0ecec18b232bea54", "Atari, Bob Whitehead", "CX26163P", "NFL Football (32 in 1) (1988) (Atari) (PAL)", "AKA Football", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7623a639a6fffdb246775fe2eabc8d01", "Activision, Bob Whitehead", "AG-005, CAG-005, AG-005-04", "Skiing (1980) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7628d3cadeee0fd2e41e68b3b8fbe229", "Atari", "CX26163P", "Fishing Derby (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7648e72a5b5899076688df18a1ddcf72", "CBS Electronics, Richard K. Balaska Jr., Andy Frank, Stuart Ross", "4L 2520 5000", "Tunnel Runner (1983) (CBS Electronics) (Prototype)", "Black Box", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "764ce6801f28a9ad36f11de3e57c053b", "Atari, Jim Huether, Alan J. Murphy, Robert C. Polaro", "CX2666", "RealSports Volleyball (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "76809eb1ee0db8a318308a5cdda0f4e2", "Atari, Jerome Domurat, Steve Woita", "CX2699", "Taz (1983) (Atari) (Prototype) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "769ddc995dbb9edb8167efcea9f34a7c", "", "", "H.E.R.O. (Genesis)", "Genesis controller (B is laser, C is dynamite)", "Hack of H.E.R.0.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "76a9bf05a6de8418a3ebc7fc254b71b4", "VideoSoft, Jerry Lawson, Dan McElroy", "VS1008", "Color Bar Generator (1984) (VideoSoft)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "76c685d1a60c0107aa54a772113a2972", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (3 of 3) (1983) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "76c88341017eae660efc6e49c4b6ab40", "", "", "Indiana Pitfall (Hack)", "Hack of Pitfall!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "76ee917d817ef9a654bc4783e0273ac4", "Otto Versand", "311377", "Fox & Goat (Double-Game Package) (1983) (Otto Versand) (PAL)", "AKA Nuts", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "76f53abbbf39a0063f24036d6ee0968a", "M Network, David Akers, Joe 'Ferreira' King, Patricia Lewis Du Long, Jeff Ratcliff - INTV", "MT7045", "Bump 'n' Jump (1983) (M Network)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "76f66ce3b83d7a104a899b4b3354a2f2", "UA Limited", "", "Cat Trax (1983) (UA Limited) (1)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "77057d9d14b99e465ea9e29783af0ae3", "Activision, David Crane", "AG-001", "Dragster (1980) (Activision)", "AKA Drag Strip", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7732e4e4cc2644f163d6650ddcc9d9df", "HES", "771-333", "2 Pak Special - Challenge, Surfing (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7761418d46af069b8cd80c29fe6cd814", "Dion Olsthoorn", "RetroN 77 edition", "Amoeba Jump (R77) (DionoiD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7778ac65d775a079f537e97cbdad541c", "", "", "Spider Fighter (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "777aece98d7373998ffb8bc0b5eff1a2", "", "", "2600 Collison Demo 2 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "77887e4192a6b0a781530e6cf9be7199", "Atari", "CX2604", "Space War (1978) (Atari) [b1]", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "77be57d872e3f5b7ecf8d19d97f73281", "", "", "Basketball (208 in 1) (Unknown) (PAL)", "Console ports are swapped", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" },
-  { "77cd9a9dd810ce8042bdb9d40e256dfe", "Kyle Pittman", "", "Evil Dead (2003) (Kyle Pittman) (Hack)", "Hack of Haunted House", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "77d0a577636e1c9212aeccde9d0baa4b", "Atari, Joe Decuir", "CX2621, CX2621P", "Video Olympics (1977) (Atari) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXDR", "PADDLES_IAXDR", "YES", "", "", "AUTO 60", "", "", "", "" },
-  { "78297db7f416af3052dd793b53ff014e", "", "", "Poker Squares (V0.17) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7836794b79e8060c2b8326a2db74eef0", "", "", "RIOT RAM Test (26-11-2002) (Dennis Debro)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "784176346e9422733d55c427230e5bad", "Activision, Alex DeMeo", "", "Title Match Pro Wrestling (1989) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "784abfdb31d5341e5bd404d8d2a71c3b", "Alessandro Ciceri", "", "MagiCard (TV format conversion) (alex_79) (PAL)", "MagiCard PAL conversion hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7860716fa5dbc0fffab93fb9a4cb4132", "", "", "Hangman Monkey Wordlist (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7867ee819b53d69cfcfe740f7ddca574", "Arcadia Corporation, Dennis Caswell", "1 AR-4000, AR-4100", "Phaser Patrol (1982) (Arcadia) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "787ebc2609a31eb5c57c4a18837d1aee", "Prescott", "", "Vault Assault (19xx) (Prescott)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "78821ef76ebc3934850d1bc1b9e4f4b0", "HES - Activision", "542", "Hot Action Pak - Ghostbusters, Tennis, Plaque Attack (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "78963290052fd17c6c7998305ab3a6a0", "", "", "Push (V0.08) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "78b84cfb1c57b0488d674d2374e656e6", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (1 of 3) (1982) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "78c2de58e42cd1faac2ea7df783eaeb3", "", "", "Fu Kung! (V0.07) (25-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "79004f84bdeee78d142e445057883169", "CCE", "C-830", "Planet Patrol (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "791bc8aceb6b0f4d9990d6062b30adfa", "Activision, David Crane - Ariola", "EAX-018, EAX-018-04B, EAX-018-04I - 711 018-725", "Pitfall! (1982) (Activision) (PAL)", "Abenteuer im Urwald (Jungle Runner)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "791c88eca9836af8c34bf32b07cb58a7", "SpiceWare - Darrell Spice Jr.", "SW-05", "Stay Frosty 2 (PAL60)", "AtariAge Holiday Greetings 2014", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "YES", "" },
-  { "7926083ad423ed685de3b3a04a914315", "Barry Laws Jr.", "", "Face Invaders 2 (Barry Laws Jr.) (Hack)", "Hack of Astroblast", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "792b1d93eb1d8045260c840b0688ec8f", "Kroko", "", "3E Bankswitch Test (TIA @ $00)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7972e5101fa548b952d852db24ad6060", "Atari - Sears", "CX2627 - 6-99841", "Human Cannonball (1979) (Atari)", "AKA Cannon Man", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "798b8921276eec9e332dfcb47a2dbb17", "Atari - CCW, Gary Stark", "CX26102", "Cookie Monster Munch (1983) (Atari) (PAL) [a]", "Uses Kids/Keypad Controllers", "", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "" },
-  { "798cc114f1623c14085868cd3494fe8e", "", "", "Pins Revenge (Atari Freak 1)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7991e1797e5e9f311fd957e62d889dff", "Joe Grand", "", "SCSIcide (v1.1) (2001) (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "AUTO 65", "", "", "", "" },
-  { "7996b8d07462a19259baa4c811c2b4b4", "", "", "Math Gran Prix (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "79ab4123a83dc11d468fb2108ea09e2e", "Activision - Cheshire Engineering, David Rolfe, Larry Zwick", "AZ-037-04", "Beamrider (1984) (Activision)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "79b649fb812c50b4347d12e7ddbb8400", "", "", "Red Pong Number 2 Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "79c27f90591e3fdc7d2ed020ecbedeb3", "CCE", "C-815", "Seaquest (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "79d4af56036ec28f298cad964a2e2494", "", "", "Hangman Pac-Man Wordlist (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "79d6f61da3c64688ac8e075667f8a39f", "", "", "Tie-Fighters (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "79e5338dbfa6b64008bb0d72a3179d3c", "M Network - INTV, David Akers, Patricia Lewis Du Long", "MT4313", "Star Strike (1983) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "79fcdee6d71f23f6cf3d01258236c3b9", "Atari - GCC, Mike Feinstein, John Mracek", "CX2673, CX2673P", "Phoenix (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7a09299f473105ae1ef3ad6f9f2cd807", "Atari, Steve Wright", "CX2616P", "Pele's Soccer (1981) (Atari) (PAL)", "AKA Pele's Championship Soccer", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7a2af383014f5d810ad26d322823549d", "", "", "FlickerSort Demo (20-04-2002) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7a5463545dfb2dcfdafa6074b2f2c15e", "20th Century Fox Video Games - Sirius Software, Mark Turmell", "11007", "Turmoil (1982) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7a63d7ea3f2851bcf04f0bb4ba1a3929", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (3 of 4) (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7a64a8b727c8215d945e37d565ca95a5", "Atari, Warren Robinett", "CX2606", "Slot Racers (1978) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7a64b5a6e90619c6aacf244cdd7502f8", "Baroque Gaming (Brian Eno)", "", "Warring Worms (Beta 1) (2002) (Baroque Gaming)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7a7f6ab9215a3a6b5940b8737f116359", "Arcadia Corporation, Kevin Norman", "AR-4103", "Killer Satellites (1983) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7a93d0c029eaa72236523eedc3f19645", "", "", "20 Sprites at Once Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7ab0917107b6ec768a5ebaadf28c497a", "", "", "Santa's Helper (Hack)", "Hack of Kaboom!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
-  { "7ab210f448de518fa61a5924120ba872", "", "", "Fortress (20-04-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7ab2f190d4e59e8742e76a6e870b567e", "Apollo, Larry Martin", "AP-2008", "Guardian (1982) (Apollo)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 65", "", "", "", "" },
-  { "7ac4f4fb425db38288fa07fb8ff4b21d", "Goliath", "83-213", "Space Eagle (1983) (Goliath) (PAL)", "AKA Exocet", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7ad257833190bc60277c1ca475057051", "Atari, Alan J. Murphy, Robert Zdybel", "CX2668", "RealSports Football (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "7ad782952e5147b88b65a25cadcdf9e0", "Imagic, Dave Johnson", "720119-1A, 03211", "Kwibble (1983) (Imagic) (Prototype)", "AKA Quick Step! Beta", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7adbcf78399b19596671edbffc3d34aa", "Atari, Mimi Nyden, Joseph Tung", "CX26152", "Super Baseball (1988) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7af40c1485ce9f29b1a7b069a2eb04a7", "Amiga - Video Soft", "3120", "Mogul Maniac (1983) (Amiga)", "Uses the Amiga Joyboard", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7b24bfe1b61864e758ada1fe9adaa098", "Atari, Chris Crawford", "", "Wizard (1980) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7b33407b2b198af74906b936ce1eecbb", "King Atari", "", "Ghostbuster 2 (King Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "7b3cf0256e1fa0fdc538caf3d5d86337", "CommaVid, Joseph Biel", "CM-009", "Stronghold (1983) (CommaVid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7b43c32e3d4ff5932f39afcb4c551627", "Syncro, Daniel Wolf", "", "Kamikaze Saucers (1983) (Syncro) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7b4be337ac4d73eda75c848355f6f480", "Omegamatrix", "", "Star Wars Arcade (Atari Trak-Ball) (Y Inverted) (PAL60) v4 (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7b5207e68ee85b16998bea861987c690", "Atari, Carol Shaw", "CX26163P", "3-D Tic-Tac-Toe (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7b57318c489ff178f7ff500da1ec9e8c", "Thomas Jentzsch", "", "Reactor - Amiga Mouse Hack v1.3 (PAL) (Full-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7b6f3348dbf71ada88db0fdaf7feefe0", "", "", "3-D Corridor (Pink Spiral) (31-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7b79beb378d1b4471def90ceccf413de", "", "", "Pitfall Cupcake (Hack)", "Hack of Pitfall", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7b7b4ac05232490c28f9b680c72998f9", "Zellers", "", "Freeway (Zellers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7b8a481e0c5aa78150b5555dff01f64e", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692", "Moon Patrol (05-12-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7b938c7ddf18e8362949b62c7eaa660a", "Atari, Bob Whitehead - Sears", "CX2603 - 99803, 49-75601", "Star Ship (1977) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7ba07d4ea18bf3b3245c374d8720ad30", "Starpath Corporation, Stephen H. Landrum", "AR-4101", "Communist Mutants from Space (Preview) (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7bb286cb659d146af3966d699b51f509", "Atari - Axlon, Tod Frye", "CX26178", "Save Mary! (04-03-1989) (Atari) (Prototype)", "AKA Saving Mary", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7bc4fd254ec8c0a25a13f02fd3f762ff", "Retroactive", "", "Qb (V1.00) (Stella) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "7c00e7a205d3fda98eb20da7c9c50a55", "Apollo - Games by Apollo, Larry Minor, Ernie Runyon, Ed Salvo", "AP-2004", "Lost Luggage (1982) (Apollo)", "AKA Airport Mayhem", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7c4a499d343fca0cef2d59dd16af621a", "", "", "Poker Card Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7c757bb151269b2a626c907a22f5dae7", "TNT Games - Sculptured Software, Adam Clayton", "26192", "BMX Air Master (1989) (TNT Games) (PAL)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7c7a4a2d505c2d0c75337c44711d8d54", "Atari, Warren Robinett", "", "Elf Adventure (04-22-83) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7c9b3b8b25acf2fe3b8da834f69629c6", "", "", "I Robot (1984) (Atari) (Prototype) [!]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7ca7a471d70305c673fedd08174a81e8", "Tim Snider", "", "Venture II (2001) (Tim Snider)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "7cc77f6745e1f2b20df4a4327d350545", "Atari, Richard Maurer", "CX2632, CX2632P", "Space Invaders (1980) (Atari) (PAL) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7ccf350354ee15cd9b85564a2014b08c", "", "", "Big Dig (13-04-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7cd379da92c93679f3b6d2548617746a", "", "", "Demo Image Series #5 - Clown (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7cd900e9eccbb240fe9c37fa28f917b5", "Jone Yuan Telephonic Enterprise Co", "", "Bi! Bi! (Jone Yuan) (PAL)", "AKA Skindiver", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7ced6709f091e79a2ab9575d3516a4ac", "Activision, Steve Cartwright - Ariola", "EAX-027 - 711 027-722", "Plaque Attack (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7cedffa0db65d610568b90aeca705ac6", "Atari, Rob Fulop - Sears", "CX2638 - 49-75166", "Missile Command (1981) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7cf3a9267cdb95aba91abc5838d61cc5", "Thomas Jentzsch", "", "Centipede - Atari Mouse Hack v1.4 (PAL60) (Half-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7d0b49ea4fe3a5f1e119a6d14843db17", "Gameworld, J. Ray Dettling", "133-008", "Frankenstein's Monster (1983) (Gameworld) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7d1034bcb38c9b746ea2c0ae37d9dff2", "Atari, Brad Stewart", "", "Morse Code Tutor (1979) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7d3cdde63b16fa637c4484e716839c94", "CCE", "", "Road Runner (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7d483b702c44ee65cd2df22cbcc8b7ed", "Atari, Warren Robinett", "", "Elf Adventure (05-25-83) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7d5c3b7b908752b98e30690e2a3322c2", "Dactari - Milmar", "", "Freeway (Dactari - Milmar)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7d726fa494f706784bafeb1b50d87f23", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (07-27-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7d8287e8423a56d4f8cef10435d97179", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Trak-Ball Hack v1.2 (NTSC) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7d903411807704e725cf3fafbeb97255", "Imagic, Rob Fulop", "720104-1A, 720104-1B, IA3204", "Cosmic Ark (Reaction) (1982) (Imagic) [selectable starfield]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7d93071b3e3616093a6b5a98b0315751", "", "", "Gunfight 2600 - Music & Bugfixes 2 (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7d940d749e55b96b7b746519fa06f2de", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix (Preview) (1983) (Arcadia) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7d9c96b215d1941e87b6fb412eb9204f", "", "", "Othello (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7da9de8d62fcdd3a2c545b2e720c2a61", "CommaVid, John Bronstein", "CM-001", "MagiCard (1981) (CommaVid) (4K)", "Uses the Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7dbc8fa2e488e3f6b87fbe0f76c5b89f", "Ed Federmeyer", "", "Sound X (1996) (Ed Federmeyer)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7dc03a1f56d0e6a8aae3e3e50d654a08", "", "", "Hozer Video Demo (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7dcbfd2acc013e817f011309c7504daa", "Arcadia Corporation, Dennis Caswell", "AR-4000, AR-4100", "Phaser Patrol (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "7dd9c5284422f729066ab22a284c8283", "CCE", "C-833", "Target Practice (1983) (CCE) [a]", "AKA Carnival", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7ded20e88b17c8149b4de0d55c795d37", "Thomas Jentzsch, Paul Slocum", "", "Thrust+ Platinum (v1.26)", "", "New Release, supports BoosterGrip", "", "", "", "", "", "", "", "BOOSTERGRIP", "DRIVING", "", "", "", "", "", "", "", "" },
-  { "7dfd100bda9abb0f3744361bc7112681", "Telesys, Don Ruffcorn", "1006", "Demolition Herby (1983) (Telesys) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "7e2fe40a788e56765fe56a3576019968", "Activision - Imagineering, Donald Hahn, Dan Kitchen", "AK-050-04", "Double Dragon (1989) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7e464186ba384069582d9f0c141f7491", "PlayAround - J.H.M.", "206", "General Re-Treat (1982) (PlayAround) (PAL)", "AKA Custer's Revenge", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7e4783a59972ae2cd8384f231757ea0b", "Atari - Imagineering, Dan Kichen", "CX26139P", "Crossbow (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7e51a58de2c0db7d33715f518893b0db", "CBS Electronics, E.F. Dreyer, Ed Salvo", "4L 2738 0000", "Mountain King (1983) (CBS Electronics) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "7e52a95074a66640fcfde124fffd491a", "Atari - GCC, Mike Feinstein, John Mracek", "CX2673", "Phoenix (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7e7c4c59d55494e66eef5e04ec1c6157", "Baroque Gaming (Brian Eno)", "", "Warring Worms (2002) (Baroque Gaming)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7e8aa18bc9502eb57daaf5e7c1e94da7", "CBS Electronics - Roklan, Joe Hellesen, Joe Wagner", "M8774, M8794", "Wizard of Wor (1982) (CBS Electronics)", "Uses the Joystick Controllers (swapped)", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "YES", "" },
-  { "7e9da5cb84d5bc869854938fe3e85ffa", "Atari, Ian Shepard - Sears", "CX2604 - 6-99812, 49-75106", "Space War (1978) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7e9f088e15b2af9ff3411991393e6b1f", "Atari - Roklan, Joe Gaucher", "CX2679", "RealSports Basketball (12-28-1982) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7eab0284a0cd1043461d446a08d08cec", "Jone Yuan Telephonic Enterprise Co", "", "Basic Math (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7ead257e8b5a44cac538f5f54c7a0023", "Xonox, Anthony R. Henderson", "99006, 6220", "Sir Lancelot (1983) (Xonox) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7eaf009a892f03d90682dc1e67e85f07", "Fabrizio Zavagli", "", "Bounce! (18-03-2003) (Fabrizio Zavagli)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "7eafc9827e8d5b1336905939e097aae7", "Atari, Mark R. Hahn", "", "Elk Attack (1987) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7eba20c2291a982214cc7cbe8d0b47cd", "Imagic, Dave Johnson", "720119-1A, 03211", "Quick Step! (1983) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7ed61a18cebdeca0a93be1f5461731e5", "Dactari", "", "Skiing (Dactari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7ed7130a6e4020161836414332b11983", "", "", "Fu Kung! (V0.05 Cuttle Card Compatible) (13-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7edc8fcb319b3fb61cac87614afd4ffa", "Activision, Alan Miller", "AG-003", "Checkers (1980) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7ef3ca08abde439c6ccca84693839c57", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix (1983) (Arcadia) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" },
-  { "7ef74879d7cb9fa0ef161b91ad55b3bb", "CCE", "", "Vanguard (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7f0209cfcc3d181715463f4d6451cecf", "Atari - GCC, John Allred, Douglas B. Macrae, Betty Ryan Tylko", "CX2694", "Pole Position (05-15-1983) (Atari) (Prototype)", "AKA RealSports Driving", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7f07cd2e89dda5a3a90d3ab064bfd1f6", "Videospielkassette - Ariola", "PGP234", "Boxen (Ariola) (PAL)", "AKA Boxing", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7f430c33044e0354815392b53a9a772d", "HES", "773-891", "2 Pak Special - Cavern Blaster, City War (1992) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7f525b07bc98080cc8950f7284e52ede", "Atari", "", "128-in-1 Junior Console (Chip 4 of 4) (1991) (Atari) (PAL)", "Actually contains only 16 games, not 32", "", "", "", "16IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7f54fa6aa824001af415503c313262f2", "HES", "", "Boom Bang (HES) (PAL)", "AKA Crackpots", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7f6533386644c7d6358f871666c86e79", "CommaVid, Irwin Gaines", "CM-008", "Cakewalk (1983) (CommaVid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7f790939f7eaa8c47a246c4283981f84", "", "", "This Planet Sucks Demo 3 (Greg Troutman) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "7f819454734ddf93f83fefcffcd3e212", "Jone Yuan Telephonic Enterprise Co", "", "Outlaw (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7f9fbe3e00a21ea06e6ae5e0e5db2143", "", "", "Skate Boardin' (2002) (Skyworks)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7fcd1766de75c614a3ccc31b25dd5b7a", "PlayAround - J.H.M.", "203", "Knight on the Town (1982) (PlayAround)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "7fcd5fb59e88fc7b8473c641f44226c3", "CCE", "C-807", "Space Tunnel (1983) (CCE)", "AKA O Tunel Espacial", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7ff53f6922708119e7bf478d7d618c86", "Suntek", "SS-032", "Walker (1983) (Suntek) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "7ffc2d80fd49a124808315306d19868e", "Ishido", "", "Domino (Ishido) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "801ba40f3290fc413e8c816c467c765c", "Hozer Video Games", "", "Gunfight 2600 - Westward Ho! (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "803393ed29a9e9346569dd1bf209907b", "Atari - GCC, Mark Ackerman, Tom Calderwood, Glenn Parker", "CX2684", "Galaxian (02-04-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "804ed85eadf1ce3e93721547cbea7592", "CCE", "", "Fishing Derby (CCE) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8055b9c2622136fd91edfea6df642daf", "Activision", "", "Unknown Activision Game #1 (1983) (Activision) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "805f9a32ef97ac25f999a25014dc5c23", "SnailSoft", "", "Balthazar (SnailSoft)", "AKA Babylon 5", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "8068e07b484dfd661158b3771d6621ca", "Epyx, Steven A. Baker, Peter Engelbrite", "80561-00286", "California Games (1987) (Epyx) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "807841df228ee8aab0a06ee639ce5a8a", "Coleco - Project Guild - GMA, Michael Green, Anthony R. Henderson, Gary Littleton", "2455", "Turbo (1982) (Coleco) (Prototype)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "807a8ff6216b00d52aba2dfea5d8d860", "John Payson", "", "Strat-O-Gems Deluxe (2005) (J. Payson)", "Uses the AtariVox controller", "Homebrew", "", "", "", "", "", "", "", "", "ATARIVOX", "", "", "", "", "", "", "", "" },
-  { "808c3b1e60ee0e7c65205fa4bd772221", "CCE", "", "Defender (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "80cd42881e670e4b74a9ccd10d0d7b2e", "20th Century Fox Video Games - Sirius, Ed Hodapp", "11004", "Deadly Duck (1982) (20th Century Fox) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "80cec82239913cb8c4016eb13749de44", "David Marli", "", "Invaders from Space by David Marli (Space Invaders Hack)", "Hack of Space Invaders (Atari)", "New Release (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "80dcbe1b55f12be731a224a53ee4ad5f", "Bit Corporation", "R320", "Amidar (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "80e1410ec98089e0733cc09e584dba4b", "Dynamics", "DY-293005", "Jumping Jack (1983) (Dynamics) (PAL)", "AKA Bobby Is Going Home", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "80e52315919bd8a8b82a407ccd9bb13f", "", "", "Euchre (Jul 28) (2002) (Eric Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "80e5400470ac788143e6db9bc8dd88cf", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (06-XX-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "80f7bf7418a462e8687ecefeaf6eb9c2", "Thomas Jentzsch", "", "Reactor - Atari Trak-Ball Hack v1.3 (NTSC) (Half-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8101efafcf0af32fedda4579c941e6f4", "", "", "Okie Dokie (4K) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "81073d0377a2badef8d5e74fc44fc323", "Thomas Jentzsch", "", "Sadoom (TJ) (PAL60) (Hack)", "Hack of Kaboom!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
-  { "8108162bc88b5a14adc3e031cf4175ad", "Suntek", "SS-030", "Skydiver (1983) (Suntek) (PAL)", "AKA Parachute", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8108ad2679bd055afec0a35a1dca46a4", "", "", "Maze Craze (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "NTSC", "", "", "" },
-  { "810d8952af5a6036fca8d0c4e1b23db6", "Tiger Vision - Eram", "", "Keystone (Tiger Vision)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "81254ebce88fa46c4ff5a2f4d2bad538", "Atari, David Crane - Sears", "CX2653 - 6-99823, 49-75111", "Slot Machine (1979) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "81341f00b61ab37d19d1529f483d496d", "", "", "Fu Kung! (V0.04) (10-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "813985a940aa739cc28df19e0edd4722", "Imagic, Bob Smith", "720000-201, 720102-1B, IA3201", "Star Voyager (1982) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "81414174f1816d5c1e583af427ac89fc", "Thomas Jentzsch", "", "Treasure Below (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "814210c0e121f7dbc25661b93c06311c", "", "", "Joustpong (16-09-2002) (Kirk Israel) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "81591a221419024060b890665beb0fb8", "Atari, Carla Meninsky, Ed Riddle", "CX2611, CX2611P", "Indy 500 (1977) (Atari) (PAL)", "Uses the Driving Controllers", "", "", "", "", "", "", "", "", "DRIVING", "DRIVING", "", "", "", "45", "", "", "", "" },
-  { "8190b403d67bf9792fe22fa5d22f3556", "", "", "Sky Diver (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "819aeeb9a2e11deb54e6de334f843894", "Atari, Gary Palmer", "CX2661", "Fun with Numbers (1980) (Atari)", "AKA Basic Math", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "81a010abdba1a640f7adf7f84e13d307", "Telegames - VSS", "7062 A305", "Universal Chaos (1988) (Telegames)", "AKA Targ", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "81b3bf17cf01039d311b4cd738ae608e", "CBS Electronics - Roklan, Joe Gaucher, Alex Leavens", "M8776, M8793", "Gorf (1982) (CBS Electronics)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "81f4f0285f651399a12ff2e2f35bab77", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "822a950f27ff0122870558a89a49cad3", "", "", "Space Jockey (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "82337e5fe0f418ca9484ca851dfc226a", "Thomas Jentzsch", "", "Robot City (V1.0) (Alpha) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "826481f6fc53ea47c9f272f7050eedf7", "Imagic, Dennis Koble", "720103-1A, IA3203", "Atlantis II (1982) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "827a22b9dffee24e93ed0df09ff8414a", "CBS Electronics, Stuart Ross", "", "Wings (10-10-1983) (CBS Electronics) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "8290daea8391f96d7c8e1482e184d19c", "Eckhard Stolberg", "", "Frame Timed Sound Effects (Eckhard Stolberg)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "82bf0dff20cee6a1ed4bb834b00074e6", "Suntek", "SS-035", "Panda (1983) (Quest) (Suntek) (PAL)", "AKA Panda Chase", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "82c25d1c35e6ac6f893d1d7c2fc2f9c8", "Atari, Larry Kaplan", "CX2628, CX2628P", "Bowling (1979) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "82de957d155fc041fc6afb8315a28550", "Coleco, Joseph Biel", "2457", "Venture (1982) (Coleco) (Prototype)", "2K", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "82e7aab602c378cffdd8186a099e807e", "", "", "Space Robot (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "82efe7984783e23a7c55266a5125c68e", "CCE", "C-837", "Pizza Chef (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "834a2273e97aec3181ee127917b4b269", "Quelle", "043.151 0, 874.382 5", "Die hungrigen Froesche (1983) (Quelle) (PAL)", "AKA Frogs and Flies", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "835759ff95c2cdc2324d7c1e7c5fa237", "20th Century Fox Video Games, Frank Cohen, Douglas 'Dallas North' Neubauer", "11011", "M.A.S.H (1983) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8372eec01a08c60dbed063c5524cdfb1", "", "", "Cross Force (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8388d6fe59c38c0b3a6ab2c58420036a", "Atari, Frank Hausman, Mimi Nyden, Steve Woita", "CX2686", "Quadrun (12-06-1982) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "83b8c01c72306d60dd9b753332ebd276", "", "", "Bank Heist (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "83bdc819980db99bf89a7f2ed6a2de59", "Atari, Carla Meninsky - Sears", "CX2637 - 49-75158", "Dodge 'Em (1980) (Atari) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "83d15fb9843d9f84aa3710538403f434", "", "", "Gunfight 2600 - Release Candidate (2001) (MP) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "83e1b9f22f29259679e1018bc04cc018", "Bit Corporation", "R320", "Fast Eddie (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "83f05ececae8be59ba1e51135f4bdcbf", "", "", "Demo Image Series #13 - Mario (4K Interleaved Chronocolour) (05-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "83f50fa0fbae545e4b88bb53b788c341", "Atari, Larry Kaplan - Sears", "CX2643 - 6-99815", "Codebreaker (1978) (Atari) (4K)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "83fafd7bd12e3335166c6314b3bde528", "Epyx, Steven A. Baker, Tod Frye, Peter Engelbrite", "80561-00251", "Winter Games (1987) (Epyx)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "840a5a2eaea24d95d289f514fd12f9bb", "", "", "GBImprov (Hack)", "Hack of Ghostbusters", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "841057f83ce3731e6bbfda1707cbca58", "Champ Games", "CG-04-N", "Super Cobra Arcade (NTSC)", "Compatible with Genesis controller", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "YES", "" },
-  { "841b7bc1cad05f5408302308777d49dc", "Activision", "", "Unknown Activision Game (10-22-1982) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "84290e333ff7567c2380f179430083b8", "Imagic, Dave Johnson", "13211, EIX-004-04I", "Quick Step! (1983) (Imagic) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "843435eb360ed72085f7ab9374f9749a", "Joe Grand", "", "SCSIcide (1.31) (Joe Grand)", "Uses the Paddle Controllers", "New Release", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "AUTO 65", "", "", "", "" },
-  { "84535afb9a69712ec0af4947329e08b8", "CCE", "C-868", "Bingo (1983) (CCE) (PAL)", "AKA Dice Puzzle", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "8454ed9787c9d8211748ccddb673e920", "Froggo", "FG1002", "Spiderdroid (1987) (Froggo)", "AKA Amidar", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8490e1014c2baa0d3a3a08854e5d68b3", "Xonox, Anthony R. Henderson", "99006, 6220", "Sir Lancelot (1983) (Xonox) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "84db818cd4111542a15c2a795369a256", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (1983) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "850ffd5849c911946b24544ea1e60496", "", "", "Invasion (07-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "851cc1f3c64eaedd10361ea26345acea", "Activision, David Crane", "AG-009, AG-009-04", "Freeway (1981) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "85227160f37aaa29f5e3a6c7a3219f54", "Activision, David Crane", "AG-004", "Fishing Derby (1980) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8530caaaf40acbdcd118c282b5f8a37a", "", "", "This Planet Sucks Demo 2 (Greg Troutman) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8538c5e3ee83267774480649f83fa8d6", "", "", "Escape Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "853c11c4d07050c22ef3e0721533e0c5", "", "", "Oink! (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "85470dcb7989e5e856f36b962d815537", "Atari - Sculptured Software, Inc., Steve Aguirre", "CX26162", "Fatal Run (1989) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "85478bb289dfa5c63726b9153992a920", "", "", "Candi (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "854b68b93e7123a3be42b5a2a41f75d7", "Atari, Carol Shaw", "CX2618, CX2618P", "3-D Tic-Tac-Toe (1980) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "85502d69fe46b7f54ef2598225678b47", "Jone Yuan Telephonic Enterprise Co", "", "Super-Ferrari (Jone Yuan)", "AKA Enduro", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "85564dd0665aa0a1359037aef1a48d58", "ITT Family Games", "554-33 367", "Laser Base (1983) (ITT Family Games) (PAL) [a]", "AKA The End of the World (Perry Rhodan-Serie)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "8556b42aa05f94bc29ff39c39b11bff4", "Atari, Craig Nelson - Sears", "CX2617 - 49-75183", "Backgammon (1979) (Atari)", "Uses the Paddle Controllers", "Extremely Rare", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "AUTO 80", "", "", "", "" },
-  { "855a42078b14714bcfd490d2cf57e68d", "Atari, Suki Lee", "CX26113", "Miss Piggy's Wedding (1983) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8597f66dd37d9c855663804669d69d7a", "Tigervision, Warren Schwader", "7-003", "Threshold (1982) (Tigervision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "85a4133f6dcf4180e36e70ad0fca0921", "CCE", "C-827", "Chopper Command (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "85b1bca93e69f13905107cc802a02470", "Atari, Craig Nelson", "CX2617, CX2617P", "Backgammon (1979) (Atari) (PAL)", "Uses the Paddle Controllers", "Extremely Rare", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "AUTO 80", "", "", "", "" },
-  { "85bbefb90e16bf386b304c1e9a1f6084", "Champ Games", "CG-02-P", "Conquest Of Mars (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "85e48d68c8d802e3ba9d494a47d6e016", "", "", "Ship Demo (V 15) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "85e564dae5687e431955056fbda10978", "Milton Bradley Company - Renaissance Technology, Ty Roberts", "4362", "Survival Run (1983) (Milton Bradley)", "AKA Cosmic Commander", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "86128001e69ab049937f265911ce7e8a", "Apollo - Games by Apollo, Steve Stringfellow", "AP-2005", "Lochjaw (1982) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8619da7f6796cedff59e5aa20712fb4e", "Thomas Jentzsch", "", "Sadistroids (v1.2) (2003) (Thomas Jentzsch)", "Supports Driving Controller in right port", "", "", "", "", "", "", "", "", "", "DRIVING", "", "", "", "", "", "", "YES", "30" },
-  { "862cf669cbced78f9ed31a5d375b2ebe", "", "", "Gunfight 2600 - Flicker acceptance (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8644352b806985efde499ae6fc7b0fec", "CCE", "C-801", "Mr. Postman (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8654d7f0fb351960016e06646f639b02", "Home Vision, R.J.P.G. - Gem International Corp. - VDI", "VCS83106", "Ski Hunt (1983) (Home Vision) (PAL)", "AKA Skiiing Hunt", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "866e5150c995c4ae5172e5207ba948c7", "Canal 3 - Intellivision", "", "Stampede (Canal 3) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "869abe0426e6e9fcb6d75a3c2d6e05d1", "", "", "Stampede (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "86b4aa76bbeb70e1a4f9211a9880ba8e", "", "", "Incoming (1 Player Version) (05-11-2002) (Ben Larson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8712cceec5644aacc2c21203d9ebe2ec", "Retroactive", "", "Qb (V0.10) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "8726c17ee7b559cb7bf2330d20972ad0", "", "", "Cave Demo (21-04-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "873fb75a7788ba0f4ae715229a05545e", "", "", "Euchre (Improved Colors) (PAL) (26-09-2002) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8747ba79cd39fa83a529bb26010db21b", "Atari, Richard Maurer", "CX2632, CX2632P", "Space Invaders (1980) (Atari) (PAL) [different speed and colors]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8749a0d088df25218c149dc325abc7ca", "Commavid, Ben Burch", "CM-010", "Rush Hour (1983) (Commavid) (Prototype) [a5]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "874c76726f68c166fcfac48ce78eef95", "", "", "Red Pong Number 2 Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "8764462d7d19a33b0717af22b99fc88f", "CCE", "", "Sky Jinks (CCE) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "87662815bc4f3c3c86071dc994e3f30e", "Intellivision Productions - M Network, Patricia Lewis Du Long, Stephen Tatsumi", "", "Swordfight (1983) (Intellivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "876a953daae0e946620cf05ed41989f4", "Retroactive", "", "Qb (V2.08) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "877a5397f3f205bf6750398c98f33de1", "Erik Eid", "", "Euchre (Beta) (PAL) (12-09-2002) (Erik Eid)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8786c1e56ef221d946c64f6b65b697e9", "20th Century Fox Video Games, David Lubar", "11015", "AKA Space Adventure", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8786f229b974c393222874f73a9f3206", "Activision, Larry Miller - Ariola", "EAX-021, EAX-021-04I - 711 021-720", "Spider Fighter (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8786f4609a66fbea2cd9aa48ca7aa11c", "Goliath", "5", "Open Sesame (1983) (Goliath) (PAL)", "AKA Open, Sesame!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "87b460df21b7bbcfc57b1c082c6794b0", "Dennis Debro", "", "Climber 5 (20-03-2003) (Dennis Debro)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "87b6a17132fc32f576bc49ea18729506", "Atari, Andrew Fuchs, Courtney Granner, Jeffrey Gusman, Mark R. Hahn", "CX2690", "Pengo (1984) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "87bea777a34278d29b3b6029833c5422", "Thomas Jentzsch", "", "Polaris (1983) (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "87e79cd41ce136fd4f72cc6e2c161bee", "Atari - GCC, Mark Ackerman, Glenn Parker", "CX2675", "Ms. Pac-Man (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "87f020daa98d0132e98e43db7d8fea7e", "20th Century Fox Video Games - Sirius, David Lubar", "11001", "Worm War I (1982) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "883258dcd68cefc6cd4d40b1185116dc", "Activision, David Crane - Ariola", "EAZ-030, EAZ-030-04B, EAZ-030-04I - 711 030-725", "Decathlon (1983) (Activision) (PAL)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8874b68751fd2ba6d3306a263ae57a7d", "Eric Mooney", "", "Invaders by Erik Mooney (Alpha 1) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8885d0ce11c5b40c3a8a8d9ed28cefef", "Atari, Carol Shaw, Nick 'Sandy Maiwald' Turner - Sears", "CX2608 - 49-75165", "Super Breakout (1982 - 1981) (Atari)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 45", "", "", "", "" },
-  { "888debb162d7d1ae71025b4ab794257f", "", "", "Interleaved ChronoColour - Nude Art (17-04-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "88a6c9c88cb329ee5fa7d168bd6c7c63", "CCE", "C-1007", "Jungle Hunt (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "88d300a38bdd7cab9edad271c18cd02b", "Funvision - Fund. Int'l Co.", "", "Pac Kong (Funvision) (PAL)", "AKA Inca Gold", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "88d7b6b3967de0db24cdae1c7f7181bd", "Atari - GCC, Dave Payne", "CX2669", "Vanguard (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "88d8a1accab58cf1abb043613cf185e9", "Ultravison", "", "Sabotage (Ultravison)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "88dce4037471424bb38ab6841aaa8cab", "", "", "Double-Height 6-Digit Score Display (Two Background Color Change) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "88ed87c011f699dd27321dbe404db6c8", "Activision, Dan Kitchen", "AX-029", "Crackpots (1983) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "88f74ec75ef696e7294b7b6ac5ca465f", "Activision, Bob Whitehead", "AG-002, CAG-002, AG-002-04", "Boxing (1980) (Activision) (16K)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8905d54f48b8024fc718ed643e9033f7", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (05-24-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "890c13590e0d8d5d6149737d930e4d95", "Atari, David Crane - Sears", "CX2605 - 6-99822, 49-75109", "Outlaw (1978) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8917f7c1ac5eb05b82331cf01c495af2", "Bit Corporation", "PG202", "Space Tunnel (1982) (BitCorp) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8933976f2029c0d8492ebd8f4eb21492", "", "", "Synthcart Plus (09-02-2003) (Paul Slocum)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8953bc11352d794431d3303e31d3b892", "Tigervision, Robert H. O'Neil", "7-007", "Polaris (02-17-1983) (Tigervision) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "896ec58f26e930e02f5e4f046602c3a1", "", "", "Synthcart (Beta) (2002) (Paul Slocum)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "898143773824663efe88d0a3a0bb1ba4", "Activision - Woodside Design Associates, Steve 'Jessica Stevens' Kitchen", "AZ-033, AZ-033-04", "Space Shuttle (1983) (Activision) [FE]", "A Journey Into Space", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "898748d5eaac3164b0391a64ae1e0e32", "", "", "Hangman Man 4letter (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "898b5467551d32af48a604802407b6e8", "Bit Corporation", "PG208", "Snail Against Squirrel (1983) (BitCorp) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "89a65b83203980d5d4d60f52a584a5b8", "", "", "Marble Craze (PAL) (02-02-2003) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "89a68746eff7f266bbf08de2483abe55", "Atari, Jerome Domurat, Steve Woita", "CX2696", "Asterix (1984) (Atari)", "AKA Taz", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "89afff4a10807093c105740c73e9b544", "", "", "Pooyan (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "89eaba47a59cbfd26e74aad32f553cd7", "Apollo - Games by Apollo, Ed Salvo, Byron Parks", "AP-2001", "Spacechase (1982) (Apollo) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8a159ee58b2f0a54805162984b0f07e5", "Atari - Sculptured Software, Inc., Steve Aguirre", "CX26162", "Fatal Run (1989) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8a183b6357987db5170c5cf9f4a113e5", "Atari - Roklan, Joe Gaucher", "CX2679", "RealSports Basketball (01-11-1983) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8a42e2c7266439d8997a55d0124c912c", "", "", "Hangman Invader Wordlist (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8a49cf1785e3dea2012d331a3ad476e1", "", "", "Boulderdash (10 Blocks Wide) (02-04-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8a6c84f481acf42abcb78ba5064ad755", "128-in-1 Junior Console", "", "Street Racer (128-in-1 Junior Console) (PAL) (4K)", "Uses the Paddle Controllers (swapped)", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 75", "", "", "", "" },
-  { "8a8e401369e2b63a13e18a4d685387c6", "Activision, David Crane - Ariola", "EAG-008, PAG-008, EAG-008-04I - 711 008-720", "Laser Blast (1981) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8a9d874a38608964f33ec0c35cab618d", "Chris Cracknell", "", "Rescue Bira Bira (Chris Cracknell)", "Hack of Jungle Fever", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "8a9d953ac3db52a313a90d6a9b139c76", "", "", "Hangman Invader Biglist3 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8aad33da907bed78b76b87fceaa838c1", "Atari, Larry Kaplan", "CX26163P", "Air-Sea Battle (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8ac18076d01a6b63acf6e2cab4968940", "Atari, Dan Hitchens, Mimi Nyden", "CX2685", "Gravitar (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8af58a9b90b25907da0251ec0facf3b8", "Jone Yuan Telephonic Enterprise Co", "", "Cosmic Swarm (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "8b04e9d132b8e30d447acaa6bd049c32", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (1982) (Starpath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8b40a9ca1cfcd14822e2547eaa9df5c1", "Parker Brothers - Western Technologies, Dave Hampton, Tom Sloper", "931517", "Q-bert (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8b504b417c8626167a7e02f44229f0e7", "Retroactive", "", "Qb (V1.00) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "8b556c3d9ca8e5e6e665bd759b93ffae", "", "", "Synthcart (2002) (Paul Slocum) (PAL) [!]", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "8b5b1e3a434ebbdc2c2a49dc68f46360", "CBS Electronics - Woodside Design Associates - Imaginative Systems Software, Garry Kitchen", "4L1700, 4L1701, 4L1702, 4L1802, 4L2274", "Donkey Kong (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8b7ca29a55432f886cee3d452fb00481", "Starpath Corporation, Stephen H. Landrum, Jon Leupp", "11 AR-4201", "Sword of Saros (1983) (Starpath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8b8152d6081f31365406cb716bd95567", "Atari", "CX2626, CX2626P", "Miniature Golf (1979) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8b8789c6669a4cee86c579a65332f852", "Digivision", "", "Plaque Attack (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8bbfd951c89cc09c148bfabdefa08bec", "UA Limited", "", "Pleiades (1983) (UA Limited) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "8bc0d2052b4f259e7a50a7c771b45241", "Xonox - K-Tel Software, Anthony R. Henderson", "99007, 6240", "Tomarc the Barbarian (1983) (Xonox) [a]", "AKA Thundarr the Barbarian", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8bd8f65377023bdb7c5fcf46ddda5d31", "Activision, Bob Whitehead", "AG-019", "Sky Jinks (1982) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8bebac614571135933116045204f0f00", "Thomas Jentzsch", "", "Missile Command (Trakball) (2002) (TJ) (PAL)", "Uses the Trakball Controller", "Homebrew", "", "", "", "", "", "", "", "TRAKBALL", "TRAKBALL", "", "", "", "", "", "", "YES", "" },
-  { "8c103a79b007a2fd5af602334937b4e1", "Thomas Jentzsch", "", "Laser Base (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8c136e97c0a4af66da4a249561ed17db", "", "", "Poker Squares (V0.27) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8c146c61817edd376bc1354c7f1ddc63", "Omegamatrix", "", "Star Wars Arcade (Amiga Mouse) (Y Inverted) (PAL60) v4 (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8c1cc284edba691139d6626d062c606f", "Atari, Omegamatrix", "", "Super Breakout Menu (2020) (PAL60) (Hack)", "Hack of Super Breakout", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" },
-  { "8c2fa33048f055f38358d51eefe417db", "Home Vision - Gem International Corp. - VDI", "VCS83137", "Teddy Apple (1983) (Home Vision) (PAL)", "AKA Open, Sesame!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "8c36ed2352801031516695d1eeefe617", "Epyx, Steven A. Baker, Tod Frye, Peter Engelbrite", "80561-00251", "Winter Games (1987) (Epyx) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8c7e5e2329f4f4e06cbcc994a30fd352", "Data Age", "DA1004", "Airlock (1982) (Data Age) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8c8a26ed57870daba8e13162d497bad1", "HES", "", "2 Pak Special - Dolphin, Oink (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8c8b15b3259e60757987ed13cdd74d41", "Supergame", "71", "River Raid (1984) (Supergame)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8c941fa32c7718a10061d8c328909577", "Digivision", "", "River Raid (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8ccaa442d26b09139685f5b22bf189c4", "Retroactive", "", "Qb (V1.01) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "8ccf63141a029603572d1056e772990e", "Thomas Jentzsch", "", "Centipede - Amiga Mouse Hack v1.4 (NTSC) (Full-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8cd26dcf249456fe4aeb8db42d49df74", "Atari - Imagineering, Dan Kichen", "CX26139", "Crossbow (1988) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8ce9126066f2ddd5173e9f1f9ce1494e", "Thomas Jentzsch", "", "Missile Command (Trakball) (2002) (TJ)", "Uses the Trakball Controller", "Homebrew", "", "", "", "", "", "", "", "TRAKBALL", "TRAKBALL", "", "", "", "", "", "", "YES", "" },
-  { "8cf0d333bbe85b9549b1e6b1e2390b8d", "Atari, Brad Stewart", "CX2649, CX2649P", "Asteroids (1981) (Atari) (PAL)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "8d00a38f4c8f8800f1c237215ac243fc", "", "", "3-D Corridor (Green) (30-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8d1e2a6d2885966e6d86717180938f87", "Thomas Jentzsch", "", "Missile Command (Amiga Mouse) (2002) (TJ)", "Uses Amiga Mouse Controller", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "8d8b7d7b983f75debbdaac651e814768", "", "", "Demo Image Series #15 - Three Marios (PAL) (06-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8d9a06101ebb0f147936356e645309b8", "", "", "Grid Pattern Demo 2 (20-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8da51e0c4b6b46f7619425119c7d018e", "Atari - Imagineering, David Lubar", "CX26183", "Sentinel (1991) (Atari)", "Uses the Light Gun Controller (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8db152458abaef3cfa7a4e420ddbda59", "", "", "Keystone Kapers (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8df4be9ddc54ac363b13dc57ceaf161a", "Scott Stilphen", "", "Asteroids SS (Scott Stilphen) (Hack)", "Hack of Asteroids", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "8e0ab801b1705a740b476b7f588c6d16", "Activision, David Crane", "AG-009, AG-009-04", "Freeway (1981) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8e42674972d6805068fc653e014370fd", "", "", "Skeleton (PAL) (15-10-2002) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8e48ea6ea53709b98e6f4bd8aa018908", "CBS Electronics, Stuart Ross", "", "Wings (06-03-1983) (CBS Electronics) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "8e4cd60d93fcde8065c1a2b972a26377", "Imagic, Dan Oliver", "720118-2A, 13208, EIX-007-04I", "Laser Gates (1983) (Imagic) (PAL)", "AKA Innerspace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8e4fa8c6ad8d8dce0db8c991c166cdaa", "Atari, Bill Aspromonte, John Russell, Michael Sierchio, Robert Zdybel", "CX26114", "Pigs in Space (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8e512ad4506800458f99dec084fc2c64", "Bob Montgomery, Nathan Strum", "", "Reindeer Rescue (2005)", "2005 AtariAge Holiday Cart", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8e7241bfc8380aac3c0ef1b6881cdded", "Atari, Howard Scott Warshaw - Sears", "CX2655 - 49-75167", "Yars' Revenge (09-01-81) (Atari) (Prototype)", "Time Freeze", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "8e737a88a566cc94bd50174c2d019593", "Quelle", "343.173 1", "Feuerwehr im Einsatz (1983) (Quelle) (PAL)", "AKA Fire Fighter", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8e822b39a71c84ac875f0107fb61d6f0", "", "", "Hangman Ghost Original Words (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8e879aa58db41edb67cbf318b77766c4", "Thomas Jentzsch", "", "Cosmic Commuter (Thomas Jentzsch) (PAL60)", "NTSC Conversion", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8e887d1ba5f3a71ae8a0ea16a4af9fc9", "", "", "Skeleton (V1.1) (PAL) (24-10-2002) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8ed5a746c59571feb255eaa7d6d0cf98", "", "", "Carnival (208 in 1) (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8ed73106e2f42f91447fb90b6f0ea4a4", "Spectravision - Spectravideo", "SA-204", "Tapeworm (1982) (Spectravision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "8ee3f64dc0f349adc893fe93df5245d8", "", "", "Euchre (20-07-2001) (Eric Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8ef96ace4a1d6dfb65926c1e868b0188", "Thomas Jentzsch", "", "Reactor - Amiga Mouse Hack v1.3 (PAL60) (Half-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8f33bce5ba1053dcf4cea9c1c69981e4", "", "", "Jawbreaker (Unknown) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8f53a3b925f0fd961d9b8c4d46ee6755", "", "", "Astrowar (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8f5ac5139419c5d49bacc296e342a247", "Atari - CCW, Michael Callahan, Preston Stuart", "CX26103", "Alpha Beam with Ernie (12-22-1982) (Atari) (Prototype)", "Uses Keypad Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8f60551db6d1535ef0030f155018c738", "", "", "Space War (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8f613ea7c32a587d6741790e32872ddd", "", "", "Troll Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8f88309afad108936ca70f8b2b084718", "Spectravision - Spectravideo - Quelle", "SA-203 - 413.223 9", "Cross Force (1982) (Spectravision) (PAL)", "AKA Kreuzfeuer (Cross Fire)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8f90590dba143d783df5a6cff2000e4d", "", "", "Gopher (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8f98519a91dbbf4864f135a10050d9ed", "Silvio Mogno", "", "Rainbow Invaders (non-playable demo) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8fa47e5242776e841df7e708b12eb998", "", "", "Sea Hawk (Genesis)", "Genesis controller (C drops bomb)", "Hack of Sea Hawk", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8fbabaa87941cdf3a377c15e95bdb0f3", "", "", "Meteor Smasher (SnailSoft)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8fe00172e7fff4c1878dabcf11bb8dce", "Quelle", "689.302 8", "Hili Ball (1983) (Quelle) (PAL)", "AKA Racquetball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "8febdd9142960d084ab6eeb1d3e88969", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX2674", "E.T. - The Extra-Terrestrial (1982) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "8fffc8f15bb2e6d24e211884a5479aa5", "Retroactive", "", "Qb (V1.00) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "9007c3cbb55ce05ad7d1c34d4906750a", "Activision, David Crane", "AX-018, AX-018-04", "Pitfall! (03-18-1983) (Activision) (Prototype)", "Pitfall Harry's Jungle Adventure (Jungle Runner)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9048ccb7e0802cd8fa5bfc2609f292d8", "Tigervision, Robert H. O'Neil", "7-007", "Polaris (1983) (Tigervision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9057694dce8449521e6164d263702185", "Activision, Bob Whitehead", "AG-011", "Stampede (1981) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "90578a63441de4520be5324e8f015352", "Bit Corporation", "PGP204", "Open Sesame (4 Game in One) (1983) (BitCorp) (PAL)", "AKA Open, Sesame!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "9072c142728a3a3d994956d03bfacba2", "Fabrizio Zavagli", "", "Crash Dive (Fabrizio Zavagli) (PAL60)", "NTSC Conversion", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "90a3c3255f2a54225cdcb50831f8793a", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Trak-Ball Hack v1.1 (PAL) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "90b1799dddb8bf748ee286d22e609480", "", "", "Ship Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "90b647bfb6b18af35fcf613573ad2eec", "AtariAge (Chris Walton)", "", "Juno First (2009)", "AtariVox supported", "Homebrew", "", "", "", "", "", "", "", "", "ATARIVOX", "", "", "", "", "", "", "YES", "" },
-  { "90ccf4f30a5ad8c801090b388ddd5613", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (1982) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "90d77e966793754ab4312c47b42900b1", "Imagic, Brad Stewart", "720105-2A, IA3400P, EIX-005-04I", "Fire Fighter (1982) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "90f502cbf4438a95f69f848cef36eb64", "Digitel", "", "River Raid II (1985) (Digitel)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "910dd9bf98cc5bc080943e5128b15bf5", "", "", "Gunfight 2600 - Improved AI (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "911d385ee0805ff5b8f96c5a63da7de5", "Thomas Jentzsch", "", "Jammed (V0.1) (Demo) (2001) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "913d5d959b5021f879033c89797bab5e", "", "", "Robot Player Graphic (1996) (J.V. Matthews) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "914a8feaf6d0a1bbed9eb61d33817679", "Atari", "CX26163P", "Freeway Chicken (32 in 1) (1988) (Atari) (PAL)", "AKA Freeway", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "91925abce3a29e33b6a8b81482f4f5af", "Activision, Garry Kitchen - Ariola", "EAX-025, EAX-025-04I - 711 025-725", "Keystone Kapers (1983) (Activision) (PAL) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9193b6fff6897d43274741d4f9855b6d", "", "", "M.A.S.H (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "91a3749ff7b7e72b7fa09e05396a0e7b", "", "", "Gunfight 2600 - Final Run Part 2 (2002) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "91b007f33f9b790be64f57220ec52e80", "Jone Yuan Telephonic Enterprise", "", "Laser Blast (Jone Yuan) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "91c2098e88a6b13f977af8c003e0bca5", "Atari - GCC", "CX2676", "Centipede (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "91d1c82ceaf8af2add3973a3c34bc0cb", "", "", "Starfield Demo 1 (20-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "91f0a708eeb93c133e9672ad2c8e0429", "", "", "Oystron (V2.9) (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "91fdb6541f70c40b16aabf8308123be8", "", "", "Interlacing Game (19-08-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9222b25a0875022b412e8da37e7f6887", "Panda", "106", "Dice Puzzle (1983) (Panda)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "9245a84e9851565d565cb6c9fac5802b", "Bomb - Onbase", "CA282", "Great Escape (1983) (Bomb)", "AKA Asteroid Fire", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "927d422d6335018da469a9a07cd80390", "Activision, Carol Shaw - Ariola", "EAX-020, EAX-020-04B, EAX-020-04I - 711 020-720", "River Raid (1982) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9281eccd7f6ef4b3ebdcfd2204c9763a", "Retroactive", "", "Qb (2.15) (Retroactive) (PAL)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "9295570a141cdec18074c55dc7229d08", "Telegames", "7045 A015", "Bump 'n' Jump (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "929e8a84ed50601d9af8c49b0425c7ea", "Bit Corporation", "PG205", "Dancing Plate (1982) (BitCorp) (PAL)", "AKA Dishaster, Dancing Plates, Tanzende Teller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "92a1a605b7ad56d863a56373a866761b", "U.S. Games Corporation - Western Technologies, Dave Hampton", "VC2006", "Raft Rider (1983) (U.S. Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "92d1b6cb8a1b615266c4088a58464779", "Bit Corporation", "R320", "Fishing Derby (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "92d1f6ac179ebe5963868d6bc1bdda8d", "HES", "498", "Smash Hit Pak - Frogger, Boxing, Seaquest, Skiing, Stampede (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "92e72f7cc569584c44c9530d645ae04e", "Canal 3 - Intellivision", "", "Spider Fighter (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "931b91a8ea2d39fe4dca1a23832b591a", "Activision, David Crane", "AG-008", "Laser Blast (1981) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9333172e3c4992ecf548d3ac1f2553eb", "Konami", "RC 101-X 02", "Strategy X (1983) (Konami)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "93420cc4cb1af1f2175c63e52ec18332", "Tim Snider", "", "Blair Witch Project (Tim Snider) (Hack)", "Hack of Haunted House", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9364ad51c321e0f15c96a8c0aff47ceb", "Atari, Rob Fulop", "CX2638", "Missile Command (1981) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "936ef1d6f8a57b9ff575dc195ee36b80", "", "", "Pac Kong (Unknown)", "AKA Inca Gold", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "936f555b4b1a2cd061b659ff63f4f5f2", "HES, David Lubar", "535", "My Golf (1990) (HES) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "937736d899337036de818391a87271e0", "Atari, Peter C. Niday", "CX26108", "Donald Duck's Speedboat (04-12-1983) (Atari) (Prototype)", "AKA Donald Duck's Regatta", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "939ce554f5c0e74cc6e4e62810ec2111", "ZiMAG - Emag - Vidco", "711-111 - GN-020", "Dishaster (1983) (ZiMAG)", "AKA Dancing Plate", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "93acd5020ae8eb5673601e2edecbc158", "Chris Cracknell", "", "Video Time Machine (Chris Cracknell)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "93b9229fc0ea4fb959d604f83f8f603c", "Thomas Jentzsch", "", "Amidar DS (Fast Enemies) (2003) (TJ) (Hack)", "Hack of Amidar", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "93c4b910f7649b3e998bb6d8527c6f4a", "Sparrow - Enter-Tech, Paul Walters, Rick Harris, George Hefner, Barbara Ultis", "", "Arkyology (1983) (Sparrow) (Prototype) [fixed]", "Fix for un-initialized 'X' register", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "93c52141d3c4e1b5574d072f1afde6cd", "Imagic, Mark Klein", "720112-1A, 03213", "Subterranea (1983) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "93c8d9d24f9c5f1f570694848d087df7", "Digivision", "", "Galaxian (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "93c9f9239a4e5c956663dd7affa70da2", "Quelle", "626.610 0", "Billard (1983) (Quelle) (PAL)", "AKA Trick Shot", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "93db185c3b3dc382f3aecd6a2fea7fd9", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Trak-Ball Hack v1.1 (PAL60) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "93dc15d15e77a7b23162467f95a5f22d", "CCE", "", "Sky Jinks (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "93e276172b521c4491097f8b1393eea7", "Atari", "", "Diagnostic Test Cartridge 4.2 (06-01-1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "93eb1795c8b1065b1b3d62bb9ec0ccdc", "JSK", "", "Custer's Viagra (JSK) (Hack)", "Hack of Custer's Revenge", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "94102febc53b4a78342d11b645342ed4", "", "", "Joustpong (14-07-2002) (Kirk Israel) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9433770890f087bfcf3e50122694d8c0", "Omegamatrix", "", "Star Wars Arcade (Amiga Mouse) (Y Inverted) v4 (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9436b7ad131b5a1f7753ce4309ba3dee", "Kyle Pittman", "", "War of The Worlds (Kyle Pittman) (Hack)", "Hack of Defender", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "943798452ceba9357e2c56303cadb4f7", "Thomas Jentzsch, Paul Slocum", "", "Thrust+ Platinum (v1.28)", "", "New Release, supports BoosterGrip and Genesis (switched by Color/B+W)", "", "", "", "", "", "", "", "JOYSTICK", "DRIVING", "", "", "", "", "", "", "", "" },
-  { "9446940866c9417f210f8552cf6c3078", "Thomas Jentzsch", "", "Marble Craze - Amiga Mouse Hack v1.0 (PAL60) (TJ)", "Uses Amiga Mouse Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "94507dee401b0a072a481c00d7699ffe", "Thomas Jentzsch", "", "Missile Control - Atari Trak-Ball Hack v1.15 (PAL) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9469d18238345d87768e8965f9f4a6b2", "CCE", "", "Ms. Pac-Man (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "947317a89af38a49c4864d6bdd6a91fb", "CBS Electronics, Bob Curtiss", "4L 2487 5000", "Solar Fox (1983) (CBS Electronics)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "94b92a882f6dbaa6993a46e2dcc58402", "Activision, Larry Miller", "AX-026, AX-026-04", "Enduro (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "94d90f63678e086f6b6d5e1bc6c4c8c2", "Digivision", "", "Seaquest (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "94e3fbc19107a169909e274187247a9d", "", "2402-044-01", "2-in-1 Freeway and Tennis (Unknown)", "", "", "", "", "2IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "94e4c9b924286038527f49cdc20fda69", "Retroactive", "", "Qb (V2.12) (Stella) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "94e7cc6342d11e508e7e8b2ddf53c255", "", "", "Missile Command (208 in 1) (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "94ff6b7489ed401dcaaf952fece10f67", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692", "Moon Patrol (07-31-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "951e8cec7a1a1d6c01fd649e7ff7743a", "Atari - Sculptured Software, Adam Clayton", "CX26151, CX26151P", "Dark Chambers (1988) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9526e3db3bdfbc27989a9cbfd0ee34bf", "", "", "Atari Logo Demo 6 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "95351b46fa9c45471d852d28b9b4e00b", "Atari, Tom Rudadahl", "CX26163P", "Golf (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "955c408265ad6994f61f9b66657bbae9", "", "", "Quadrun (Video Conversion) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "956496f81775de0b69a116a0d1ad41cc", "CCE", "", "Alien (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "956b99511c0f47b3a11d18e8b7ac8d47", "", "", "Bones (Arcade Golf Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "95956108289a917f80667eccd3ce98a9", "Atari, Ed Logg, Carol Shaw", "CX2639, CX2639P", "Othello (1981) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "95a69cf8c08ef1522b050529464f0bca", "", "", "Grid Pattern Demo 1 (20-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "95a89d1bf767d7cc9d0d5093d579ba61", "PlayAround - J.H.M.", "204", "Lady in Wading (1982) (PlayAround)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "95e1d834c57cdd525dd0bd6048a57f7b", "Atari, Bill Aspromonte, John Russell, Michael Sierchio, Robert Zdybel", "CX26114", "Pigs in Space (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "95e542a7467c94b1e4ab24a3ebe907f1", "Suntek", "SS-021", "Dragon Defender (1983) (Suntek) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "95fd6097dc27c20666f039cfe34f7c69", "", "", "Oh No! (Version 1) (17-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "961112b74a920a5242e233480326c356", "Activision, Alan Miller", "AG-007, CAG-007", "Tennis (1981) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "962ffd3eaf865230a7a312b80e6c5cfd", "Imagic, Wilfredo 'Willy' Aguilar, Michael Becker, Rob Fulop", "13205", "Fathom (1983) (Imagic) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "96662271ae50b6859017bffbdda75525", "Andrew Davie & Thomas Jentzsch", "", "Boulder Dash - Demo (2011)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "96670d0bf3610da2afcabd8e21d8eabf", "", "", "Boring Pitfall (Hack)", "Hack of Pitfall!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "966b11d3c147d894dd9e4ebb971ea309", "", "", "Marble Craze Song (Paul Slocum) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "966c955e4aaca7082d9ffb9a68e3f3ed", "Thomas Jentzsch", "", "Centipede - Atari Mouse Hack v1.4 (PAL) (Full-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9671b658286e276cc4a3d02aa25931d2", "", "", "Hangman Ghost Wordlist (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "968efc79d500dce52a906870a97358ab", "TNT Games - Sculptured Software, Adam Clayton", "26192", "BMX Air Master (1989) (TNT Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "969b968383d9f0e9d8ffd1056bcaef49", "Atari, Larry Kaplan", "CX2628, CX2628P", "Bowling (1979) (Atari) (PAL)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "96bcb3d97ce4ff7586326d183ac338a2", "", "", "Revenge of the Apes (Hack) [h2]", "Hack of Planet of the Apes", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "96e798995af6ed9d8601166d4350f276", "20th Century Fox Video Games - Videa, David Ross", "11029", "Meltdown (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "96eccc2277043508a6c481ea432d7dd9", "Thomas Jentzsch", "", "Missile Command (Atari Mouse) (2002) (TJ) (PAL)", "Uses Atari ST Mouse Controller", "Homebrew", "", "", "", "", "", "", "", "ATARIMOUSE", "ATARIMOUSE", "", "", "", "", "", "", "YES", "" },
-  { "96f806fc62005205d851e758d050dfca", "", "", "Push (V0.05) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "97184b263722748757cfdc41107ca5c0", "Parker Brothers", "PB5820", "Mr. Do!'s Castle (1984) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "9718b85ac5a55cbc7348963c63ffa35a", "Robby", "", "Demon Attack (Robby)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "972486110933623039a3581db308fda6", "", "", "Xeno Plus (Hack)", "Hack of Xenophobe", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "97327d6962f8c64e6f926f79cd01c6b9", "", "", "Jawbreaker (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "977294ae6526c31c7f9a166ee00964ad", "Atari - GCC, Douglas B. Macrae", "CX2677, CX2677P", "Dig Dug (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9784290f422e7aeeab4d542318bd9a1f", "AtariAge, Chris Walton", "1.0 (Release)", "Chetiry (2011) (AtariAge) (60k)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "50" },
-  { "97842fe847e8eb71263d6f92f7e122bd", "Imagic, Wilfredo Aguilar, Michael Becker, Dennis Koble", "720113-1A, 03206", "Solar Storm (1983) (Imagic)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 45", "", "", "", "" },
-  { "97933c9f20873446e4c1f8a4da21575f", "", "", "Racquetball (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "97a9bb5c3679d67f5c2cd17f30b85d95", "Atari", "", "Colors (1980) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "97cd63c483fe3c68b7ce939ab8f7a318", "Thomas Jentzsch", "", "Robot City (V0.21) (15-09-2002) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "97d0151beb84acbe82aa6db18cd91b98", "Steve Engelhardt", "", "Lunar Attack (2002) (Steve Engelhardt) (Hack)", "Hack of Z-Tack", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "97d079315c09796ff6d95a06e4b70171", "Activision, Garry Kitchen", "AZ-032", "Pressure Cooker (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "97e47512f89e79818d988d078dc90410", "Thomas Jentzsch", "", "Missile Control - Amiga Mouse Hack v1.15 (NTSC) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "97f4da9f1031486f4e588f1e53572e53", "SpiceWare - Darrell Spice Jr.", "", "Draconian", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "9813b9e4b8a6fd919c86a40c6bda8c93", "Atari", "CX26177", "Ikari Warriors (1989) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9831efc7f4cb8ffb4df0082bab2f07a3", "Activision, Steve Cartwright - Ariola", "EAX-031, EAX-031-04B - 711 031-717", "Frostbite (1983) (Activision) (PAL) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9848b5ef7a0c02fe808b920a2ac566d2", "Skyworks Technology Inc.", "", "Baseball (2002) (Skyworks)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9853089672116117258097dbbdb939b7", "Hozer Video Games", "", "Gunfight 2600 - Cowboy Hair (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "98555b95cb38e0e0b22b482b2b60a5b6", "", "", "Spinning Fireball (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "98ba601a60172cb46c5bf9a962fd5b1f", "", "", "Gorilla Kong (Hack)", "Hack of Donkey Kong", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "98ccd15345b1aee6caf51e05955f0261", "Retroactive", "", "Qb (V2.03) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "98e5e4d5c4dd9a986d30fd62bd2f75ae", "", "", "Air-Sea Battle (Unknown) (Hack) (4K)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "98e6e34af45a0664597972c3bb31180f", "", "", "Space Instigators (V1.7) (17-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "98e7caaab8ec237558378d2776c66616", "Bradford W. Mott", "", "HMOVE Test (Bradford W. Mott) (1998) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "98ea10c47c13f1b3306c7b13db304865", "", "", "Jam Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "98ec0fa4199b9c01f7b8fa3732e43372", "Activision, David Crane", "AX-018, AX-018-04", "Pitfall! (1982) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "98ef1593624b409b9fb83a1c272a0aa7", "CCE", "C-831", "Cosmic Ark (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "98f63949e656ff309cefa672146dc1b8", "Atari - Axlon, John Vifian", "CX26168", "Off the Wall (1989) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "98fa3ad778a668a79449350de4b3b95b", "Thomas Jentzsch", "", "Thrust (V1.1) (2000) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9905f9f4706223dadee84f6867ede8e3", "HES", "", "Challenge (HES) (PAL)", "Surfer's Paradise if right difficulty = 'A'", "", "", "0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9912d06eea42200a198dd3e2be18c601", "Imagic, Michael Greene", "IA3312", "No Escape! (1982) (Imagic) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "991d57bbcd529ad62925098e0aec1241", "", "", "Gunfight 2600 - The Final Kernel (MP) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9945a22f60bbaf6d04a8d73b3cf3db75", "Activision, Dan Kitchen", "EAX-039-04B, EAX-039-04I", "Kung-Fu Master (1987) (Activision) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9947f1ebabb56fd075a96c6d37351efa", "CBS Electronics", "4L 2737 0000", "Omega Race (1983) (CBS Electronics)", "Set right difficulty to 'A' for BoosterGrip in both ports", "", "", "", "", "", "A", "", "", "BOOSTERGRIP", "BOOSTERGRIP", "", "", "", "", "", "", "", "" },
-  { "9962034ea7b3d4a905d0991804670087", "", "", "Grid Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9989f974c3cf9c641db6c8a70a2a2267", "Eckhard Stolberg", "", "Colours Selector (Eckhard Stolberg)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "99a24d7bb31d49b720b422550b32c35f", "", "", "Hangman Ghost Biglist1 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "99ac89241365b692255ba95d745edd91", "Atari, Frank Hausman, Mimi Nyden, Steve Woita", "CX2686", "Quadrun (18-03-1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "99f7c6c26046bbe95f1c604b25da8360", "SnailSoft", "", "Comitoid beta 2 (SnailSoft)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9a01115206f32eb0b539c7e5a47ccafa", "Atari, Jerome Domurat, Steve Woita", "CX2699", "Taz (07-15-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9a165c39af3f050fdee6583fdfcdc9be", "Zirok", "", "Mario Bros. (Zirok)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9a21fba9ee9794e0fadd7c7eb6be4e12", "Atari - Imagineering, Dan Kitchen", "CX26177", "Ikari Warriors (1991) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9a25b3cfe2bbb847b66a97282200cca2", "Atari, Brad Stewart - Sears", "CX2622 - 6-99813, 49-75107", "Breakout (1978) (Atari) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 60", "", "", "", "" },
-  { "9a4274409216ff09ecde799f2a56ac73", "CCE", "C-801", "Mr. Postman (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9ab72d3fd2cc1a0c9adb504502579037", "Epyx, Steven A. Baker, Peter Engelbrite", "80561-00286", "California Games (1987) (Epyx)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9ad362179c2eea4ea115c7640b4b003e", "", "", "Barnstorming (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "NTSC50", "", "", "" },
-  { "9ad36e699ef6f45d9eb6c4cf90475c9f", "Imagic, Dennis Koble", "720103-1A, 720103-1B, IA3203, IX-010-04", "Atlantis (1982) (Imagic)", "AKA Lost City of Atlantis", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9aeb5206c5bf974892a9cc59f1478db3", "Activision, Steve Cartwright", "AX-013", "Barnstorming (1982) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9af615951e9719df2244bc77fc50cb95", "Dactari - Milmar", "", "Defender (Dactari - Milmar)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9afdfe1cff7f37f1c971fe3f0c900606", "Funvision - Fund. International Co.", "", "Plug Attack (Funvision)", "AKA Plaque Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9b150a42fc788960fbb4cbe250259ee2", "Kroko", "", "3E Bankswitch Test (TIA @ $40)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9b21d8fc78cc4308990d99a4d906ec52", "CCE", "C-838", "Immies & Aggies (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9b246683f44c963a50e41d6b485bee77", "", "", "Boring (PAL) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9bb136b62521c67ac893213e01dd338f", "Xonox - Beck-Tech", "6210, 7210, 06003. 99001", "Spike's Peak (1983) (Xonox) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9bd4e0d5f28ba6da417c26649171f8e4", "", "", "Hangman Pac-Man Original Words (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9be58a14e055b0e7581fc4d6c2f6b31d", "", "", "Adventure (Color Scrolling) (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9c27ef3bd01c611cdb80182a59463a82", "Arcadia Corporation, Kevin Norman", "AR-4103", "Killer Satellites (1983) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9c40bf810f761ffc9c1b69c4647a8b84", "", "", "2 in 1 - Frostbite, River Raid (Unknown)", "", "", "", "", "2IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9c6d65bd3b477aace0376f705b354d68", "", "", "RPG Kernal (18-04-2003) (Paul Slocum) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "9c6faa4ff7f2ae549bbcb14f582b70e4", "U.S. Games Corporation, Garry Kitchen, Paul Willson - Vidtec", "VC1002", "Sneak 'n Peek (1982) (U.S. Games)", "AKA Hide 'n Seek", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9c6fd6ed3599978ab7b6f900484b9be6", "Andrew Wallace", "", "Laseresal 2002 (PAL60) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9c729017dd2f9ccbadcb511187f80e6b", "", "", "J-Pac (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9c7fa3cfcaaafb4e6daf1e2517d43d88", "", "", "PIEROXM Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9ca2deb61318eba4fb784d4bf7441d8b", "", "", "Purple Bar Demo 2 (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9cbb07f1993a027bc2f87d5205457ec9", "", "", "Eckhard Stolberg's Scrolling Text Demo 1 (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9d0befa555f003069a21d2f6847ad962", "Atari - GCC, Dave Payne", "CX2669", "Vanguard (1982) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9d1556ae5890398be7e3d57449774b40", "Activision, David Crane", "AG-001", "Dragster (1980) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9d2938eb2b17bb73e9a79bbc06053506", "Imagic, Michael Greene", "EIZ-002-04I", "Wing War (1983) (Imagic) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9d2f05d0fe8b2dfcf770b02eda066fc1", "", "", "Push (V0.06) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9d33d31fb1de58c5460d8a67b57b36da", "", "", "Star Voyager (Genesis)", "Genesis controller (C is secondary lasers)", "Hack of Star Voyager", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9d37a1be4a6e898026414b8fee2fc826", "M Network - INTV - APh Technological Consulting, David Rolfe", "MT5665", "Super Challenge Baseball (1982) (M Network)", "AKA Big League Baseball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9d4bc7c6fe9a7c8c4aa24a237c340adb", "Dennis Debro", "", "Climber 5 (16-04-2003) (Dennis Debro)", "For Philly Classic 4", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9d522a3759aa855668e75962c84546f7", "Atari, Tom Rudadahl", "CX2634, CX2634P", "Golf (1980) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9d7f04618bb4043f531d087e3aaa7ac8", "Parker Brothers, Larry Gelberg, Gary Goltz", "PB5065", "Star Wars - Ewok Adventure (1983) (Parker Bros) (Prototype) (PAL) (16K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9de0d45731f90a0a922ab09228510393", "20th Century Fox Video Games - Sirius, Mark Turmell", "11003", "Fast Eddie (1982) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9dec0be14d899e1aac4337acef5ab94a", "CommaVid, John Bronstein", "CM-003", "Cosmic Swarm (1982) (CommaVid) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "9e01f7f95cb8596765e03b9a36e8e33c", "Atari - CCW, Michael Callahan, Preston Stuart", "CX26103", "Alpha Beam with Ernie (1983) (Atari)", "Uses Keypad Controllers", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9e135f5dce61e3435314f5cddb33752f", "Fabrizio Zavagli", "", "Space Treat Deluxe (2003)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9e192601829f5f5c2d3b51f8ae25dbe5", "PlayAround - J.H.M.", "201", "Cathouse Blues (1982) (PlayAround)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "9e2c7299c69b602443d327c7dad51cbf", "Charles Morgan", "", "Xaxyrax Road (Charles Morgan) (Hack)", "Hack of Freeway", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9e437229136f1c5e6ef4c5f36178ed18", "Funvision - Fund. International Co.", "", "Grand Prize (Funvision)", "AKA Enduro", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9e5007131695621d06902ab3c960622a", "Sega", "", "Tac Scan (1983) (Sega) [h1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 60", "", "", "YES", "" },
-  { "9e792a59f8795664cbaaff1ba152d731", "", "", "Bullet Demo (20-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9e904e2eaa471c050c491289b8b80f60", "", "", "How to Draw a Playfield II (1997) (Erik Mooney) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9ea8ed9dec03082973244a080941e58a", "Eric Mooney, Piero Cavina", "", "INV+", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9ec1b259a1bcffa63042a3c2b3b90f0a", "Activision, David Crane", "AG-008", "Laser Blast (1981) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9eca521db1959156a115dee85a405194", "", "", "Fu Kung! (V0.08) (2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9ed0f2aa226c34d4f55f661442e8f22a", "", "", "Nuts (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9eeb40f04a27efb1c68ba1d25e606607", "Kyle Pittman", "", "Rambo II (2003) (Kyle Pittman) (Hack)", "Hack of Double Dragon", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9efa877a98dd5a075e058214da428abb", "Hozer Video Games", "", "SCSIcide (1.32) (Hozer Video Games)", "Uses the Paddle Controllers", "New Release", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "AUTO 65", "", "", "", "" },
-  { "9efb4e1a15a6cdd286e4bcd7cd94b7b8", "20th Century Fox Video Games, John W.S. Marvin", "", "Planet of the Apes (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9f2d58dce1b81c6ba201ed103507c025", "", "", "Fu Kung! (V0.02) (2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9f48eeb47836cf145a15771775f0767a", "Atari, Warren Robinett", "CX2620", "Basic Programming (1979) (Atari)", "Uses Keypad Controllers", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "9f5096a6f1a5049df87798eb59707583", "20th Century Fox Video Games, Mark Klein", "11036", "Entity, The (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9f52271759f8a2004d207b2247ae0bb3", "Parker Brothers", "PB5820", "Mr. Do!'s Castle (03-12-84) (Parker Bros) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "9f59eddf9ba91a7d93bce7ee4b7693bc", "Thomas Jentzsch", "", "Montezuma's Revenge (Thomas Jentzsch) (PAL60)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9f8fad4badcd7be61bbd2bcaeef3c58f", "Parker Brothers, Charlie Heath", "PB5330", "Reactor (1983) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "9f901509f0474bf9760e6ebd80e629cd", "Atari, Bob Whitehead - Sears", "CX2623 - 6-99819, 49-75108, 49-75125", "Home Run (1978) (Atari) (4K)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" },
-  { "9f93734c68f6479eb022cab40814142e", "", "", "Push (V0.07) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9f982421b9b4320ede00fe4aa2e812f4", "Atari, Omegamatrix", "", "Super Breakout Menu (2020) (Hack)", "Hack of Super Breakout", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" },
-  { "9f9ee0f60c119c831e80694b6678ca1a", "Jeffry Johnston", "", "Radial Pong - Version 8 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9fa0c664b157a0c27d10319dbbca812c", "Chris Walton, Justin Hairgrove, Tony Morse", "", "Hunchy II (2005)", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "9fc2d1627dcdd8925f4c042e38eb0bc9", "Atari - GCC, John Allred, Mike Feinstein", "CX2688, CX2688P", "Jungle Hunt (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "E68E28752D3C54EDD3CCDA42C27E320C", "Xonox - K-Tel Software, Anthony R. Henderson", "99007, 6240", "Tomarc the Barbarian (1983) (Xonox)", "Genesis controller (B is jump and throw, C switches between players)", "Hack of Tomarc the Barbarian", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a0028f057d496f22b549fd8deecc6f78", "Joe Grand", "", "SCSIcide Pre-release 6 (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a00ec89d22fcc0c1a85bb542ddcb1178", "CCE", "C-1012", "Phoenix (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a00ee0aed5c8979add4c170f5322c706", "Barry Laws Jr.", "", "Egghead (Barry Laws Jr.) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a0185c06297b2818f786d11a3f9e42c3", "", "", "International Soccer (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a025a8f83a42a4d6d46c4887e799bfac", "Hozer Video Games", "", "Gunfight 2600 - Descissions had to be made (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a0297c4788f9e91d43e522f4c561b4ad", "Atari - CCW, Gary Stark", "CX26102", "Cookie Monster Munch (1983) (Atari) (PAL)", "Uses Kids/Keypad Controllers", "", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "" },
-  { "a0563dd6d8215c38c488fbbd61435626", "", "", "Ship Demo (V 1501) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a0675883f9b09a3595ddd66a6f5d3498", "Telegames - VSS", "6057 A227", "Quest for Quintana Roo (1988) (Telegames)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a075ad332942740c386f4c3814925ece", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (2 of 4) (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a0d502dc8b90b1d7daa5f6effb10d349", "", "", "Demo Image Series #5 - Sam (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a0e2d310e3e98646268200c8f0f08f46", "Atari, Ed Logg, Carol Shaw", "CX2639, CX2639P", "Othello (1981) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a100eff2d7ae61ca2b8e65baf7e2aae8", "David Marli", "", "Muncher (David Marli) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a11099b6ec24e4b00b8795744fb12005", "Activision - Bobco, Robert C. Polaro", "EAK-049-04B", "Rampage! (1989) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a1403fef01641dcd3980cac9f24d63f9", "Dactari - Milmar", "", "Atlantis (Dactari - Milmar)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a14d8a388083c60283e00592b18d4c6c", "", "", "Tunnel Demo (28-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a15b5831a1fab52e4c416068c85ec011", "Hozer Video Games", "", "Gunfight 2600 - The Good, The Bad, The Ugly (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a174cece06b3abc0aec3516913cdf9cc", "Sears Tele-Games, Jim Huether", "CX2614 - 49-75126", "Steeplechase (1980) (Sears) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "" },
-  { "a1770ef47146ab7b12e2c4beccd68806", "Digitel", "", "Kaystone Kapers (1983) (Digitel)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a184846d8904396830951217b47d13d9", "Activision, Dan Kitchen", "AX-029", "Crackpots (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a189f280521f4e5224d345efb4e75506", "Atari - Thomas Jentzsch", "", "Obelix (1983) (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a1bcbe0bfe6570da2661fc4de2f74e8a", "Imagic - Advanced Program Technology, Rob Fulop", "", "Actionauts (Microbots) (1984-2008) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a1ca372388b6465a693e4626cc98b865", "Quelle", "176.543 7", "Der Vielfrass (1983) (Quelle) (PAL)", "AKA Fast Food", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a1ead9c181d67859aa93c44e40f1709c", "American Videogame - Dunhill Electronics, Darrell Wagner, Todd Clark Holm, John Simonds", "", "Tax Avoiders (1986) (American Videogame)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a1f9159121142d42e63e6fb807d337aa", "Quelle - Otto Versand", "700.223 1 - 781627", "Der moderne Ritter (1983) (Quelle) (PAL)", "AKA Fast Eddie", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a204cd4fb1944c86e800120706512a64", "Coleco, Rob Harris", "2511", "Smurfs Save the Day (1983) (Coleco)", "Uses the Kid Vid Controller", "", "", "", "", "", "", "", "", "", "KIDVID", "", "", "", "", "", "", "", "" },
-  { "a20b7abbcdf90fbc29ac0fafa195bd12", "Quelle - Otto Versand", "719.383 2 - 649635, 781393, 781784, 986404", "Motocross (1983) (Quelle) (PAL)", "AKA Motorcross", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a20d931a8fddcd6f6116ed21ff5c4832", "Apollo - Games by Apollo, Ed Salvo, Byron Parks", "AP-2003", "Racquetball (1982) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "a2170318a8ef4b50a1b1d38567c220d6", "Amiga - Video Soft", "3125", "Surf's Up (1983) (Amiga) (Prototype) [a1]", "Uses the Joyboard controller", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a2276822c772f72073a8a40a72a1ca52", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Mouse Hack v1.1 (NTSC) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a2424c1a0c783d7585d701b1c71b5fdc", "", "", "Video Pinball (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a25bb76e9e773117e567fd4300b1bb23", "", "", "Interleaved ChronoColour Demo (NTSC) (05-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a28d872fc50fa6b64eb35981d0f4bb8d", "Atari, Larry Kaplan - Sears", "CX2628 - 6-99842, 49-75117", "Bowling (1979) (Atari) (4K)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a29df35557f31dfea2e2ae4609c6ebb7", "Atari", "", "Circus Atari (1980) (Atari) (Joystick)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a29fc854838e08c247553a7d883dd65b", "Activision, Steve Cartwright", "AX-013", "Barnstorming (1982) (Activision) (16K)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a2a384d3a16d5be50afd12906f146827", "Bit Corporation", "R320", "Flash Gordon (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a2aae759e4e76f85c8afec3b86529317", "", "", "Boom Bang (Unknown)", "AKA Crackpots", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a2d7cc2e5419a9e4ab91fdb26339b726", "Omegamatrix", "", "Star Wars Arcade (Atari Mouse) (Y Inverted) (PAL60) v4 (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a2de0fc85548871279ed2a3c1325c13e", "George Veeder", "", "Cat and Mouse (George Veeder) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a2eb84cfeed55acd7fece7fefdc83fbb", "", "", "Kool Aid Man (Fixed) (15-11-2002) (CT)", "HMOVE handling fixed in this version", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a2f296ea2d6d4b59979bac5dfbf4edf0", "", "", "Warring Worms (28-01-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a2f9e3b6aaa23b6dc06099cdd5b51b31", "Nukey Shay", "", "Montezuma's Revenge (Genesis) (PAL60) (F6_Conversion)", "Genesis controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a302b922a8dbec47743f28b7f91d4cd8", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (Preview) (1982) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a30ece6dc4787e474fbc4090512838dc", "Zellers", "", "Circus (Zellers)", "AKA Circus Atari", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a310494ad5ba2b5b221a30d7180a0336", "", "", "Demo Image Series #6 - Mario (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a336beac1f0a835614200ecd9c41fd70", "Atari, Christopher H. Omarzu, Robert Vieira", "CX26121", "Zoo Keeper Sounds (1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a34560841e0878c7b14cc65f79f6967d", "Multivision, Michael Case", "", "Harem (1982) (Multivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a3486c0b8110d9d4b1db5d8a280723c6", "Atari, Alan J. Murphy, Robert C. Polaro", "CX26100", "Bugs Bunny (08-04-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a35d47898b2b16ec641d1dfa8a45c2b7", "Activision, Steve Cartwright", "AX-017, AX-017-04", "MegaMania (1982) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a3873d7c544af459f40d58dfcfb78887", "", "", "Tennis (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a3b9d2be822eab07e7f4b10593fb5eaa", "", "", "GREGXM Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a3c1c70024d7aabb41381adbfb6d3b25", "Telesys, Alex Leavens", "1005", "Stargunner (1983) (Telesys)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a3d7c299fbcd7b637898ee0fdcfc47fc", "Arcadia Corporation, Scott Nelson", "AR-4300", "Fireball (Preview) (1982) (Arcadia) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" },
-  { "a3f2a0fcf74bbc5fa763b0ee979b05b1", "Quelle", "873.790 0", "Eishockey-Fieber (1983) (Quelle) (PAL)", "AKA Ice Hockey", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a3f8aebb38182749cb8da85cfbc63d7c", "", "", "Tennis (208 in 1) (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a3fee8ce15525ea00d45a06f04c215d1", "Aaron Curtis", "", "AStar (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a406d2f6d84e61d842f4cb13b2b1cfa7", "Tigervision, John Harris - Teldec", "7-002", "Jawbreaker (1982) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a412c8577b2d57b09185ae51739ac54f", "Arcadia Corporation, Dennis Caswell", "AR-4000", "Phaser Patrol (1982) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "a41450333f8dd0e96e5e9f0af3770ae9", "", "", "Basic Math (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a422194290c64ef9d444da9d6a207807", "M Network - APh Technological Consulting, Hal Finney", "MT5667", "Dark Cavern (1982) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a428068d3e51498907d97cec40000515", "Bit Corporation", "R320", "Sky Alien (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a47878a760f5fa3aa99f95c3fdc70a0b", "", "", "Demo Image Series #5 - Baboon (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a4790224bd5afabd53cbe93e46a7f241", "Activision, Bob Whitehead", "AG-019", "Sky Jinks (1982) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a47e26096de6f6487bf5dd2d1cced294", "Atari", "CX2643", "Codebreaker (1978) (Atari) (PAL)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a484638990de7b12c62947c79dafa4c6", "Thomas Jentzsch", "", "Marble Craze - Atari Mouse Hack v1.0 (PAL60) (TJ)", "Uses Atari Mouse Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a499d720e7ee35c62424de882a3351b6", "SEGA - Beck-Tech, Steve Beck, Phat Ho", "009-01", "Up 'n Down (1984) (SEGA)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a4aa7630e4c0ad7ebb9837d2d81de801", "", "", "Atari 2600 Invaders (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a4ab331e8768eafdc20ce8b0411ff77a", "", "", "Demo Image Series #1 - Sam (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a4b9423877a0b86ca35b52ca3c994ac5", "CCE", "C-805", "Sea Monster (1983) (CCE)", "O Monstro Marinho", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a4b99aa5ed85cfdb7d101923147de035", "Jim Goebel", "", "Pac-Law (Jim Goebel) (Hack)", "Hack of Outlaw", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a4c08c4994eb9d24fb78be1793e82e26", "Activision, Alan Miller", "AX-012, CAX-012, AX-012-04", "Ice Hockey (1981) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a4d026a5c200ef98518ebb77719fe8dc", "Kyle Pittman", "", "SpongeBob SquarePants (2003) (Kyle Pittman) (Hack)", "Hack of Revenge of the Beefsteak Tomatoes", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a4e885726af9d97b12bb5a36792eab63", "Xonox - K-Tel Software - Beck-Tech, Steve Beck", "6210, 7210, 06003. 99001", "Spike's Peak (1983) (Xonox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a4ecb54f877cd94515527b11e698608c", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX26119", "Saboteur (12-20-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a4f1cea2c8479284e2a2292f8d51b5fa", "", "", "Gunfight 2600 - The Final Kernel Part 2 (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a4ff39d513b993159911efe01ac12eba", "Atari - GCC, John Allred, Douglas B. Macrae, Betty Ryan Tylko", "CX2694", "Pole Position (1983) (Atari)", "AKA RealSports Driving", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a511f7ee13e4b35512f9217a677b4028", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX2674", "E.T. - The Extra-Terrestrial (1982) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a5262fe6d01d6a1253692682a47f79dd", "", "", "JKH Text Scrolling Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a537879d8e82e1061d3ad800479d3b84", "Andrew Wallace", "", "Brooni (2001) (Andrew Wallace) (PD) (PAL)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a539b9fd1ba57e46442b3e9351e6383b", "", "", "River Raid (208 in 1) (Unknown) (PAL) (Hack) [a]", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a56b642a3d3ab9bbeee63cd44eb73216", "Carrere Video - JWDA, Sylvia Day, Todd Marshall, Robin McDaniel, Henry Will IV - Teldec - Prism", "USC2001", "Gopher (1983) (Carrere Video) (PAL)", "AKA Vossicht Whlmaus!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a5855d73d304d83ef07dde03e379619f", "Atari, David Crane", "", "Boggle (08-07-1978) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "a58b11148c18d85e4c2aef4ff46ade67", "", "", "Video Chess (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a591b5e8587aae0d984a0f6fe2cc7d1c", "", "", "Globe Trotter Demo (24-03-2003) (Weston)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a5b7f420ca6cc1384da0fed523920d8e", "", "", "Adventure (New Graphics) (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a5c96b046d5f8b7c96daaa12f925bef8", "Activision, Alan Miller - Ariola", "EAG-007, EAG-007-04I, PAG-007 - 711 007-720", "Tennis (1981) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a5e9ed3033fb2836e80aa7a420376788", "Atari, Carla Meninsky", "CX2637, CX2637P", "Dodge 'Em (1980) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a60598ad7ee9c5ccad42d5b0df1570a1", "Atari, Alan Miller", "CX26163P", "Surround (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a6127f470306eed359d85eb4a9cf3c96", "Atari, Michael Kosaka, Peter C. Niday, Robert Vieira", "CX26110", "Crystal Castles (1984) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a6239810564638de7e4c54e66b3014e4", "Personal Games Company, Robert Anthony Tokar", "", "Birthday Mania (1984) (Personal Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a62e3e19280ff958407e05ca0a2d5ec7", "", "", "Hangman Ghost Biglist3 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a6737c81542a99ee71cb5f5ff14703d9", "", "", "Scrolling Playfield 3 (Junkosoft) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a69f5b1761a8a11c98e706ec7204937f", "", "", "Pharaoh's Curse (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "a6ed8d72ed691fd3aad5b6974fa17978", "Bit Corporation", "R320", "Bank Heist (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a74689a08746a667a299b0507e1e6dd9", "Starpath Corporation, Stephen H. Landrum", "9 AR-4105", "Official Frogger, The (1983) (Starpath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a7523db9a33e9417637be0e71fa4377c", "Videospielkassette - Ariola", "PGP238", "Gangster (Ariola) (PAL)", "AKA Outlaw", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a7673809068062106db8e9d10b56a5b3", "Atari, Jerome Domurat, Andrew Fuchs, Dave Staugas, Robert Vieira", "CX26118, CX26118P", "Millipede (1984) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a779b9fa02c62d00d7c31ed51268f18a", "Arcadia Corporation, Brian McGhie", "AR-4104", "Rabbit Transit (1983) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a7a58e9291aefa1064e933071f60d4ef", "Arcadia Corporation, Dennis Caswell", "1 AR-4000, AR-4100", "Phaser Patrol (1982) (Arcadia) (Prototype) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "a7b584937911d60c120677fe0d47f36f", "M Network - INTV - APh Technological Consulting, Hal Finney", "MT5661", "Armor Ambush (1982) (M Network)", "AKA Tank Battle", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a7b96a8150600b3e800a4689c3ec60a2", "Atari, Mike Lorenzen - Sears", "CX2630 - 49-75122", "Circus Atari (1980) (Atari)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 55", "", "", "", "" },
-  { "a7bf8353f77caca407ef85c2698fdff2", "Atari, Suki Lee - Sears", "CX2658 - 49-75128", "Math Gran Prix (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a7cf2b9afdbb3a161bf418dbcf0321dc", "Barry Laws Jr.", "", "Attack Of The Mutant Space Urchins (2002) (Barry Laws Jr.) (Hack)", "Hack of Alien", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "a7d2e9408bb7cd70139ecced407ff238", "Atari - Roklan, Joe Gaucher, Alex Leavens", "CX2683", "Crazy Climber (1983) (Atari) (Prototype) [a1]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a7ed7dc5cbc901388afa59030fb11d26", "Atari, Warren Robinett", "CX2606, CX2606P", "Slot Racers (1978) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a7ef44ccb5b9000caf02df3e6da71a92", "Atari, Ian Shepard - Sears", "CX2604 - 6-99812, 49-75106", "Space War (1978) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a8101cb667e50a46165c6fb48c608b6b", "", "", "Kung Fu Sprite Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "a81697b0c8bbc338ae4d0046ede0646b", "CCE", "", "Gravitar (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a81b29177f258494b499fbac69789cef", "Greg Thompson", "", "Console Wars (Greg Thompson) (Hack)", "Hack of Space Jockey", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a83b070b485cf1fb4d5a48da153fdf1a", "Apollo", "AP-2011", "Pompeii (1983) (Apollo) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a8435ec570141de5d833c4abec499e55", "", "", "Happy Birthday Demo (2001) (Dennis Debro) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a8633050a686270fcf6c0cc4dcbad630", "Zirok", "", "Phoenix (Zirok)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a867b76098786c4091dba2fcee5084c3", "", "", "Dragrace (Hack)", "Hack of Dragster", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a875f0a919129b4f1b5103ddd200d2fe", "Atari, Dan Hitchens. Mimi Nyden", "CX2656", "SwordQuest - EarthWorld (1982) (Atari) (PAL)", "AKA Adventure I, SwordQuest I - EarthWorld", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a8916734ff8c64ec3342f4c73fd5b57d", "Atari", "", "Stand Alone Test Cart (1982) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a89a3e0547d6887279c34aba4b17a560", "M Network, Steve Crandall, Patricia Lewis Du Long", "MT4646", "Rocky & Bullwinkle (1983) (Mattel) (Prototype)", "", "Prototype", "", "", "4K", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a8a703e073183a89c94d4d99b9661b7f", "Franklin Cruz", "", "Spice Invaders (Franklin Cruz) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a8b3ea6836b99bea77c8f603cf1ea187", "CCE", "C-861", "Boxing (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a8c447efbec3a2b5d08b05a09999bd92", "", "", "MegaCart Menu", "", "", "", "", "", "", "", "", "", "JOYSTICK", "JOYSTICK", "", "", "", "", "", "", "", "" },
-  { "a8c48b4e0bf35fe97cc84fdd2c507f78", "Puzzy - Bit Corporation", "PG201", "Seamonster (1982) (Puzzy)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a8d0a4a77cd71ac601bd71df5a060e4c", "", "", "Space Shuttle (1983) (Activision) [t2] (Fuel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a8d4a9500b18b0a067a1f272f869e094", "", "", "Red And White Checkerboard Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a8e49d7e24ce293629ca29614862821b", "", "", "Enduro (Genesis)", "Genesis controller (B is acceleration, C is brakes)", "Hack of Enduro", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a91d0858a52de3a2e6468437212d93e8", "", "", "Q-bert (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a936d80083e99d48752ad15c2b5f7c96", "", "", "Room of Doom (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "a93e8ea1f565c3c1e86b708cf0dc2fa9", "Jess Ragan", "", "Kabul! (Jess Ragan) (Hack)", "Hack of Kaboom!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
-  { "a94528ae05dd051894e945d4d2349b3b", "Genus", "", "River Raid (Genus)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a94b8ca630f467b574b614808d813919", "HES", "773-883", "2 Pak Special - Space Voyage, Fire Alert (1992) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a9531c763077464307086ec9a1fd057d", "Atari, John Dunn - Sears", "CX2631 - 49-75152", "Superman (1979) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a957dbe7d85ea89133346ad56fbda03f", "Atari, Brad Stewart", "CX2649, CX2649P", "Asteroids (1981) (Atari) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "a97733b0852ee3096300102cb0689175", "CCE", "C-834", "Fast Eddie (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a9784c24cddb33bd0d14442b97784f3d", "Thomas Jentzsch", "", "Omega Race DC (2003) (TJ) (Omega Race Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a98b649912b6ca19eaf5c2d2faf38562", "", "", "This Planet Sucks (Greg Troutman) (PAL) [!]", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a995b6cbdb1f0433abc74050808590e6", "Imagic, Rob Fulop, Bob Smith", "720106-1A, IA3600", "Riddle of the Sphinx (1982) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a9cb638cd2cb2e8e0643d7a67db4281c", "M Network - INTV - APh Technological Consulting, Larry Zwick", "MT5861", "Air Raiders (1983) (M Network)", "AKA Air Battle", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a9d9e19d0c89fb31780b5d63e1f8c6a4", "AtariAge, Chris Spry", "CX26201", "Zippy the Porcupine (2014) (Sprybug) (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "a9e3c23599c0d77151602f8e31daf879", "", "", "Kung Fu Master (Genesis)", "Genesis controller (C is extra kick modes)", "Hack of Kung Fu Master", "", "", "", "", "", "", "", "GENESIS", "", "", "", "", "", "", "", "", "" },
-  { "aa1c41f86ec44c0a44eb64c332ce08af", "Spectravideo, David Lubar", "SA-218", "Bumper Bash (1983) (Spectravideo)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "PADDLES", "", "", "", "", "", "", "", "", "" },
-  { "aa2c4b32656bde9a75042a4d158583e1", "", "", "Oystron X (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "aa5cfe3b20395aba1d479135943ad85c", "", "", "Defender (Hack) (Unknown)", "", "Hack of Defender", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "aa7bb54d2c189a31bb1fa20099e42859", "CBS Electronics, Ed English", "4L4478", "Mr. Do! (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "aa8c75d6f99548309949916ad6cf33bc", "Bob Montgomery (aka vdub_bobby)", "", "Squish 'Em (2007)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "aa8e4b2cb8a78ffe6b20580033f4dec9", "", "", "Bitmap Demo (13-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "aaac0d277eda054861e613c59c2e4ff2", "JWDA, Todd Marshall", "", "Music Demo (JWDA)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "aab840db22075aa0f6a6b83a597f8890", "Home Vision, R.J.P.G. - Gem International Corp. - VDI", "VCS83124", "Racing Car (1983) (Home Vision) (PAL)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" },
-  { "aad61898633f470ce528e3d7ef3d0adb", "Commavid, Ben Burch", "CM-010", "Rush Hour (1983) (Commavid) (Prototype) [a1]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "aad91be0bf78d33d29758876d999848a", "Activision, David Crane", "AX-018, AX-018-04", "Pitfall! (1981) (Activision) (Prototype)", "Pitfall Harry's Jungle Adventure (Jungle Runner)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "aaea37b65db9e492798f0105a6915e96", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix - Tug of War (2 of 3) (1983) (Arcadia)", "Uses Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "02", "", "", "", "" },
-  { "aafc79ffc32c4c9b2d73c8ada7602cfe", "", "", "Planet Patrol (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ab10f2974dee73dab4579f0cab35fca6", "ITT Family Games", "", "Wilma Wanderer (1983) (ITT Family Games) (PAL)", "AKA Lilly Adventure", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ab2cfcaad3daaf673b2b14fdbb8dac33", "M Network - INTV, David Akers, Joe King, Patricia Lewis Du Long, Jeff Ratcliff", "MT7045", "Bump 'n' Jump (1983) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ab2ea35dcc1098c87455bb8210b018cf", "", "", "Fu Kung! (V0.04 Single Line Resolution) (10-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ab301d3d7f2f4fe3fdd8a3540b7a74f5", "Jone Yuan Telephonic Enterprise Co", "", "IQ 180 (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ab434f4c942d6472e75d5490cc4dd128", "HES", "773-875", "2 Pak Special - Hoppy, Alien Force (1992) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ab48c4af46c8b34c3613d210e1206132", "Andrew Davie & Thomas Jentzsch", "", "Boulder Dash - Demo V2 (2014)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ab4ac994865fb16ebb85738316309457", "Atari, Alan Miller - Sears", "CX2624 - 6-99826, 49-75113", "Basketball (1978) (Atari)", "Console ports are swapped", "Common", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" },
-  { "ab56f1b2542a05bebc4fbccfc4803a38", "Activision - Imagineering, Dan Kitchen, David Lubar", "AK-048-04", "River Raid II (1988) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ab5bf1ef5e463ad1cbb11b6a33797228", "Imagic, Rob Fulop", "720104-1A, 720104-1B, IA3204", "Cosmic Ark (1982) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ab60ea7b707c58d356cad858eb18db43", "", "", "Tazer (John K. Harvey)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ab8d318da4addd39c65b7f9c408df2a6", "", "", "Star Trek (Genesis)", "Genesis controller (B is phaser, C is warp)", "Hack of Star Trek", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "abb740bea0a6842831b4f53112fb8145", "", "", "Qb (V1.01) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "abb741c83f665d73c86d90a7d9292a9b", "Telegames", "", "Space Attack (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "abc64037ca5d5b04ae8a7eedbca3ed74", "", "", "Green and Yellow Number 1 Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "abe40542e4ff2d1c51aa2bb033f09984", "Absolute Entertainment, David Crane", "EAZ-042-04B, EAZ-042-04I", "Skate Boardin' (1987) (Absolute) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ac05c0e53a5e7009ddd75ed4b99949fc", "Atari, Joe Decuir, Steve Mayer, Larry Wagner - Sears", "CX2601 - 99801, 6-99801, 49-75124", "Combat (1977) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ac0ddbcff34d064009591607746e33b8", "Thomas Jentzsch", "", "Atlantis FH (2003) (TJ) (Hack)", "Hack of Atlantis", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ac26d7d37248d1d8eac5eccacdbef8db", "", "", "Snail Against Squirrel (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ac3dd22dd945724be705ddd2785487c2", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692", "Moon Patrol (06-15-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ac53b83e1b57a601eeae9d3ce1b4a458", "Retroactive", "", "Qb (2.15) (Retroactive) (NTSC)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "ac5f78bae0638cf3f2a0c8d07eb4df69", "", "", "Minesweeper (V.99) (Soren Gust) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ac7c2260378975614192ca2bc3d20e0b", "Activision, David Crane", "AG-930-04, AZ-030", "Decathlon (1983) (Activision)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ac9adbd6de786a242e19d4bec527982b", "Activision, Alan Miller - Ariola", "EAG-012-04I, EAX-012, EAX-012-04B - 711 012-720", "Ice Hockey (1981) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "aca09ffea77174b148b96b205109db4d", "Activision, Alan Miller", "AG-007, CAG-007", "Tennis (1981) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "acaa27d214039d89d7031609aafa55c3", "", "", "Sprite Demo 6 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "acb6787b938079f4e74313a905ec3ceb", "", "", "Chronocolor Donkey Kong (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "acb7750b4d0c4bd34969802a7deb2990", "Parker Brothers, Ed Temple", "PB5310", "Amidar (1982) (Parker Bros)", "", "Uncommon", "", "", "", "A", "A", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "acb962473185d7a652f90ed6591ae13b", "Imagic, Dennis Koble", "IA3203, IX-010-04", "Atlantis (1982) (Imagic) (16K)", "AKA Lost City of Atlantis", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ace319dc4f76548659876741a6690d57", "Atari, Steve Wright", "CX2616", "Pele's Soccer (1981) (Atari)", "AKA Pele's Championship Soccer", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ad2e6bfb3b9b9b36ba8bf493ce764c49", "", "", "2600 Collison Demo 1 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ad42e3ca3144e2159e26be123471bffc", "Atari", "CX26163P", "Human Cannonball (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ad72d616030a17634ff29ce8680d3c4c", "Thomas Jentzsch", "", "Reactor - Atari Trak-Ball Hack v1.3 (PAL60) (Full-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ad7e97c19bd25d5aa3999430845c755b", "", "", "Sprite Demo 5 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ad8072675109d13fdd31a2e0403d5cff", "Funvision - Fund. International Co.", "", "Tank City (Funvision)", "AKA Thunderground", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "adb770ff70e9adf08bbb907a7eccd240", "", "", "Inv Demo 3 (2001) (Erik Mooney) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "adb79f9ac1a633cdd44954e2eac14774", "Digivision", "", "Frostbite (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "adf1afac3bdd7b36d2eda5949f1a0fa3", "Quelle - Otto Versand", "495.463 2 - 746381", "Angriff der Luftflotten (1983) (Quelle) (PAL)", "AKA Paris Attack, M.A.D.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "adfbd2e8a38f96e03751717f7422851d", "Champ Games", "CG-01-N", "Lady Bug (NTSC)", "", "Homebrew", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "ae047e9468bda961d8e9e9d8ff52980f", "", "", "Tunnel Demo (Red Spiral) (30-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ae0d4f3396cb49de0fabdff03cb2756f", "Retroactive", "", "Qb (V2.02) (PAL) (2001) (Retroactive)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "ae10527840a1ac24de43730645ed508d", "Charles Morgan", "", "Planet Invaders (Charles Morgan) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ae18c11e4d7ed2437f0bf5d167c0e96c", "", "", "Multi-Color Demo 3 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ae2f1f69bb38355395c1c75c81acc644", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (12-23-1983) (Parker Bros) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "ae465044dfba287d344ba468820995d7", "", "", "Inca Gold (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ae4be3a36b285c1a1dff202157e2155d", "Spectravideo", "SA-210", "Master Builder (1983) (Spectravideo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ae682886058cd6981c4b8e93e7b019cf", "Retroactive", "", "Qb (V0.12) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "ae6cb335470788b94beb5787976e8818", "", "", "Mortal Kurling (02-01-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ae83541cf4a4c0bce0adccd2c1bf6288", "", "", "Maze 003 Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ae97cf8ed21f4154b4360a3cf6c95c5e", "", "", "Teleterm 2600 (John K. Harvey) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "aeb104f1e7b166bc0cbaca0a968fde51", "", "", "Ms. Pac-Man (1999) (Hack)", "Hack of Ms. Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "aec9b885d0e8b24e871925630884095c", "Amiga - Video Soft", "3125", "Surf's Up (1983) (Amiga) (Prototype)", "Uses the Joyboard controller", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "aed0b7bd64cc384f85fdea33e28daf3b", "Atari, Jim Huether, Alan J. Murphy, Robert C. Polaro", "CX2666", "RealSports Volleyball (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "aed82052f7589df05a3f417bb4e45f0c", "Atari, Warren Robinett - Sears", "CX2606 - 6-99825, 49-75112", "Slot Racers (1978) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "af6ab88d3d7c7417db2b3b3c70b0da0a", "Activision, Larry Kaplan, David Crane", "AG-010, AG-010-04", "Kaboom! (1981) (Activision) (4K)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
-  { "af6f3e9718bccfcd8afb421f96561a34", "Atari, Tod Frye", "CX2695", "Xevious (01-18-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "afb3bc45c6a82739cc82582127cd96e6", "Atari - Sculptured Software, Adam Clayton", "CX26151, CX26151P", "Dungeon (11-22-1985) (Atari) (Prototype)", "Dark Chambers Beta", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "afc194534c1b346609ef05eff6d3cef6", "Jone Yuan Telephonic Enterprise Co", "", "Boxing (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "afd2cf258d51ae4965ee21abba3627ab", "Atari - CCW, Christopher H. Omarzu", "CX26104", "Big Bird's Egg Catch (12-08-1982) (Atari) (Prototype)", "Uses the Keypad Controller", "Prototype", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "" },
-  { "afe4eefc7d885c277fc0649507fbcd84", "Atari", "CX26163P", "Ant Party (32 in 1) (1988) (Atari) (PAL)", "AKA Cosmic Swarm", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "afe776db50e3378cd6f29c7cdd79104a", "Thomas Jentzsch", "", "Bobby is Going Home (TJ)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "afe88aae81d99e0947c0cfb687b16251", "Apollo - Games by Apollo", "AP-2006", "Infiltrate (1982) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "aff8cba0f2d2eb239953dd7116894a08", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (3 of 3) (1982) (Starpath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b00088418fc891f3faa3d4ddde6ace94", "", "", "Unknown Title (bin00007 (200102)) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b00a8bc9d7fe7080980a514005cbad13", "K-Tel Vision", "", "Vulture Attack (1982) (K-Tel Vision) (PAL)", "AKA Condor Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b00e8217633e870bf39d948662a52aac", "Konami", "RC 102-X 02", "Marine Wars (1983) (Konami)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b011d8fdc450597c0762c2c0010a9b17", "Thomas Jentzsch", "", "Reactor - Amiga Mouse Hack v1.3 (NTSC) (Half-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b049fc8ac50be7c2f28418817979c637", "Activision - Imagineering, Dan Kitchen, David Lubar", "EAK-048-04, EAK-048-04B", "River Raid II (1988) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b06050f686c6b857d0df1b79fea47bb4", "Activision", "AIZ-001", "Moonsweeper (1988) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "b061e98a4c854a672aadefa233236e51", "Atari, Warren Robinett", "CX2620, CX2620P", "Basic Programming (1979) (Atari) (PAL)", "Uses Keypad Controllers", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "b095009004df341386d22b2a3fae3c81", "", "", "Sub-Scan (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b09b79c9628878be051e89f7f1e77378", "Activision, Larry Kaplan, David Crane - Ariola", "EAG-010, PAG-010 - 711 010-720", "Kaboom! (1981) (Activision) (PAL) (4K)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
-  { "b0a9c6f6c8014c4023e0341ba11ca35e", "The Atari 2600 Connection - John K. Harvey, Tim Duarte", "v75", "Mean Santa (2009) (PAL)", "Released in 2019", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b0ba51723b9330797985808db598fc31", "Atari, Michael Callahan, Preston Stuart", "CX26103", "Alpha Beam with Ernie (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b0c47e426c7f799aee2c40422df8f56a", "", "", "Space Treat (PAL) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b0c9cf89a6d4e612524f4fd48b5bb562", "Atari - GCC", "CX2663", "Combat Two (1982) (Atari) (Prototype)", "AKA Super Combat", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b0e1ee07fbc73493eac5651a52f90f00", "Colin Hughes", "", "Tetris 2600 (Colin Hughes)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "b1276417fb0f79bc52e741bb8f4d8360", "Thomas Jentzsch", "", "Marble Craze - Amiga Mouse Hack v1.0 (NTSC) (TJ)", "Uses Amiga Mouse Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b129d7541cff79ebe33852a83057c524", "Thomas Jentzsch", "", "Marble Craze - Atari Trak-Ball Hack v1.0 (NTSC) (TJ)", "Uses Atari Trak-Ball Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b12a7f63787a6bb08e683837a8ed3f18", "Imagic, Rob Fulop", "720000-200, 720101-1B, 720101-1C, IA3200, IA3200C, IX-006-04", "Demon Attack (1982) (Imagic) [fixed]", "AKA Death from Above", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b1339c56a9ea63122232fe4328373ac5", "Goliath - Hot Shot", "83-215", "Dream Flight (1983) (Goliath) (PAL)", "AKA Nightmare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b1486e12de717013376447ac6f7f3a80", "Spectravideo, Mark Turmell, Quelle", "SA-217, SA-217C - 413.723 8", "Gas Hog - Piraten Schiff (1983) (Spectravideo) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b15026b43c6758609667468434766dd8", "Retroactive", "", "Qb (0.06) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "b16cd9784589219391c839cb68c47b9c", "Video Soft, Jerry Lawson, Dan McElroy", "", "Golf Diagnostic (1983) (Video Soft) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b17b9cc4103844dcda54f77f44acc93a", "Quelle", "377.943 6", "Stopp die Gangster (1983) (Quelle) (PAL)", "AKA Gangster Alley", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b182d9708e00709830caab9cf8205ca0", "Thomas Jentzsch", "", "Reactor - Atari Mouse Hack v1.3 (PAL60) (Half-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b1a6c96e9093352106bc335e96caa154", "Joe Grand", "", "SCSIcide Pre-release 1 (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b1b20536aef4eed9c79dc5804f077862", "", "", "Euchre (NTSC) (09-11-2001) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b1c14b5ac896400cc91c8e5dd67acb59", "", "", "River Raid (208 in 1) (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b1d1e083dc9e7d9a5dc1627869d2ade7", "CCE", "C-1004", "Mario's Bros. (1983) (CCE)", "AKA Mario Bros.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b1e2d5dc1353af6d56cd2fe7cfe75254", "Atari - Axlon, Steve DeFrisco", "CX26171", "MotoRodeo (1991) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "b1fd0b71de9f6eeb5143a97963674cb6", "", "", "Multi-Color Demo 7 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b227175699e372b8fe10ce243ad6dda5", "Atari, Brad Stewart - Sears", "CX2649, 49-75163", "Asteroids (1981) (Atari) [a1]", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "b23ebf427713dd0198b7ef47dbd07ef4", "Jone Yuan Telephonic Enterprise Co", "", "Sky Diver (Jone Yuan) (4K) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b24f6a5820a4b7763a3d547e3e07441d", "CCE", "C-823", "Demon Attack (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b25841173f058380b1771aacd5e7cdf3", "Bit Corporation", "PG205", "Dancing Plate (1982) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b26506fbf411009e5e3f7365f442960e", "Atari, Alan Miller", "CX2642", "Hunt & Score (1978) (Atari) (PAL) (4K)", "Uses the Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b2737034f974535f5c0c6431ab8caf73", "CBS Electronics, Richard K. Balaska Jr., Andy Frank, Stuart Ross", "4L 2520 5000", "Tunnel Runner (1983) (CBS Electronics)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b2761efb8a11fc59b00a3b9d78022ad6", "Atari, Bob Whitehead - Sears", "CX2651 - 99805, 49-75602", "Blackjack (1977) (Atari) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "" },
-  { "b290c2b139344fcff5b312c71b9ac3b2", "Atari", "CX26163P", "UFO (32 in 1) (1988) (Atari) (PAL) (4K)", "AKA Space Jockey", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b29359f7de62fed6e6ad4c948f699df8", "Goliath", "3", "Phantom Tank (1983) (Goliath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b2a6f31636b699aeda900f07152bab6e", "", "", "Space Instigators (Public Release 2) (06-01-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b2ab209976354ad4a0e1676fc1fe5a82", "Atari - Axlon, Tod Frye - Heuristica, Agustin Ortiz", "CX26169", "Shooting Arcade (03-07-1989) (Atari) (Prototype) [a3]", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b2d1e63f7f22864096b7b6c154151d55", "Fabrizio Zavagli", "", "Bounce! (17-03-2003) (Fabrizio Zavagli)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "b2d3bcee001cff2bd2d8a21b2cb55109", "Atari - GCC, Mike Feinstein, Kevin Osborn", "CX2691", "Joust (08-09-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "b2d5d200f0af8485413fad957828582a", "Atari - Bobco, Robert C. Polaro", "CX26155P", "Sprint Master (1988) (Atari) (PAL)", "AKA Sprint 88, Sprint 2000", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b2f0d7217147160b2f481954cedf814b", "", "", "Marquee Drawer (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "b3017e397f74efd53caf8fae0a38e3fe", "Retroactive", "", "Qb (2.12) (Retroactive) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "b311ab95e85bc0162308390728a7361d", "Parker Brothers - Roklan, Joe Gaucher", "PB5080", "Gyruss (1984) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "b31dc989f594764eacfa7931cead0050", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (2 of 3) (1983) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b31e9487efc06f18dfc3d7ebadf54416", "Omegamatrix", "", "Star Wars Arcade (Atari Mouse) v4 (PAL60) (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b31f178aa0d569cccac7959f84e0a724", "Atari, Jerome Domurat, Steve Woita", "CX2699", "Taz (07-13-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b3203e383b435f7e43f9492893c7469f", "Gameworld", "133-003", "Sssnake (1983) (Gameworld) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b36040a2f9ecafa73d835d804a572dbf", "Digitel", "", "Pac Man (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b37f0fe822b92ca8f5e330bf62d56ea9", "Xonox - K-Tel Software - Beck-Tech, Steve Beck", "6210, 7210, 06003. 99001", "Spike's Peak (1983) (Xonox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b392964e8b1c9c2bed12246f228011b2", "", "", "Name This Game (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b4030c38a720dd84b84178b6ce1fc749", "M Network - APh Technological Consulting, Kevin Miller", "MT5687", "International Soccer (1982) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b40dea357d41c5408546e4e4d5f27779", "Digivision", "", "Spider Fighter (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b41fdd4a522e1d5a2721840028684ac2", "", "", "Green and Yellow Number 1 Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "b42df8d92e3118dc594cecd575f515d7", "Mystique - American Multiple Industries", "1003", "Burning Desire (1982) (Mystique) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "b438a6aa9d4b9b8f0b2ddb51323b21e4", "Telegames", "5861 A030", "Bogey Blaster (1988) (Telegames) (PAL)", "AKA Air Raiders", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b451307b8b5e29f1c5f2cf064f6c7227", "", "", "Demo Image Series #6 - Mario (Fixed) (26-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b49331b237c8f11d5f36fe2054a7b92b", "", "", "Condor Attack (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b4a4c87840613f102acb5b3a647d0a67", "", "", "Mobile 48 Sprite Kernel (04-01-2003) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b4daedb43511521db9036d503b3c1b69", "", "", "Sokoban (01-01-2003) (Adam Wozniak) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b4e2fd27d3180f0f4eb1065afc0d7fc9", "Avalon Hill, Jean Baer, Bill 'Rebecca Ann' Heineman, William O. Sheppard", "5002002", "London Blitz (1983) (Avalon Hill)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b4f05e544834d0238a0c263491775edf", "Starpath Corporation, Steve Hales, Stephen H. Landrum", "4 AR-4102", "Suicide Mission (Preview) (1982) (Starpath) (PAL)", "AKA Meteoroids", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "b4f31ea8a6cc9f1fd4d5585a87c3b487", "Mystique - American Multiple Industries, Joel H. Martin", "", "Beat 'Em & Eat 'Em (1982) (Mystique) (PAL)", "Uses the Paddle Controller (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" },
-  { "b4f87ce75f7329c18301a2505fe59cd3", "Videospielkassett - Ariola", "PGP232", "Autorennen (Ariola) (PAL)", "AKA Grand Prix", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b50ae55aac93fbed258bc5a873edd2cb", "Recompile", "", "E.T. The Extra-Terrestrial (Recompile) (Hack)", "www.neocomputer.org/projects/et", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b5110f55ed99d5279f18266d001a8cd5", "Eckhard Stolberg", "", "Auto-mobile Demo (2001) (Eckhard Stolberg)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b56264f738b2eb2c8f7cf5a2a75e5fdc", "Atari - GCC, John Allred, Douglas B. Macrae, Betty Ryan Tylko", "CX2694, CX2694P", "Pole Position (1983) (Atari) (PAL)", "AKA RealSports Driving", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b5657d4c1c732fbb6af150668464247f", "Arcadia Corporation, Stephen H. Landrum", "AR-4400", "Excalibur (Dragonstomper Beta) (1982) (Arcadia) (Prototype)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b59417d083b0be2d49a7d93769880a4b", "Pet Boat", "", "Donkey Kong (1983) (Pet Boat) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b59fd465abf76f64c85652ff29d5952d", "VentureVision, Dan Oliver", "", "Innerspace (1983) (VentureVision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b5a1a189601a785bdb2f02a424080412", "Imagic, Dennis Koble", "720021-1A, IA3410", "Shootin' Gallery (1983) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b5cb9cf6e668ea3f4cc2be00ea70ec3c", "CommaVid, Irwin Gaines - Ariola", "CM-005 - 712 005-720", "Mines of Minos (1982) (CommaVid) (PAL)", "AKA Im Labyrinth des Roboters", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "b5cdbab514ea726a14383cff6db40e26", "Video Gems", "VG-04", "Mission Survive (1983) (Video Gems) (PAL) [a]", "", "", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "b5efe0271d2214e4d5dc798881486884", "Atari - Axlon, Steve DeFrisco", "CX26192", "Klax (06-14-1990) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b6166f15720fdf192932f1f76df5b65d", "Amiga - Video Soft", "3130", "Off Your Rocker (1983) (Amiga) (Prototype)", "Uses the Amiga Joyboard", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b64426e787f04ff23ee629182c168603", "Dynacom", "", "Plaque Attack (1983) (Dynacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b65d4a38d6047735824ee99684f3515e", "Dynacom", "", "MegaBoy (Dynacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b676a9b7094e0345a76ef027091d916b", "Thomas Jentzsch", "", "Mission Survive (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "b6812eaf87127f043e78f91f2028f9f4", "Simage", "", "Eli's Ladder (1984) (Simage)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b6821ac51c4c1dcb283f01be2f047dc1", "Thomas Jentzsch", "", "Rubik's Cube 3D Demo (25-11-2002) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b6960be26bee87d53ba4e2e71cfe772f", "", "", "3-D Corridor (Spiral Words) (31-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b6d52a0cf53ad4216feb04147301f87d", "Imagic, Michael Greene", "720055-1A, IA3312", "No Escape! (1983) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b6e40bce550672e5495a8cdde7075b8b", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (1 of 3) (1983) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b702641d698c60bcdc922dbd8c9dd49c", "Atari, Ian Shepard", "CX26163P", "Space War (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b719ada17771a8d206c7976553825139", "Ron Corcoran", "", "DUP Space Invaders (Ron Corcoran) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b731d35e4ac6b3b47eba5dd0991f452f", "Thomas Jentzsch", "", "Rubik's Cube 3D Demo (Final) (08-01-2003) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b7345220a0c587f3b0c47af33ebe533c", "Quelle", "176.433 1", "Landungskommando (1983) (Quelle) (PAL)", "AKA Strategy X", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b76fbadc8ffb1f83e2ca08b6fb4d6c9f", "Activision, Bob Whitehead", "AG-005, CAG-005, AG-005-04", "Skiing (1980) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b77468d586957d1b7fb4cccda2684f47", "Atari", "CX26163P", "Boxing (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b7903268e235310dc346a164af4c7022", "Thomas Jentzsch", "", "Cat Trax (Thomas Jentzsch) (PAL60)", "NTSC Conversion", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "b79fe32320388a197ac3a0b932cc2189", "Imagic, Bob Smith", "13207, EIZ-001-04I", "Moonsweeper (1983) (Imagic) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "b7a7e34e304e4b7bc565ec01ba33ea27", "Parker Brothers", "PB5820", "Mr. Do!'s Castle (1984) (Parker Bros) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "b7b1d3ce07e75976c43a2dca3866237e", "Atari", "CX26163P", "Freeway Chicken (32 in 1) (1988) (Atari) (PAL) (4K)", "AKA Freeway", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b7d0aae399781b3c18679debda6d32b1", "Thomas Jentzsch", "", "Three.s (v1.02)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b7d7c76e37f372f4e4979b380ed95a58", "AtariAge - Michael Haas", "RC2", "Flappy (2014) (AtariAge) (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b7e459d5416eeb196aaa8e092db14463", "", "", "Push (V0.02) (1998) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b7f184013991823fc02a6557341d2a7a", "", "", "Blue Rod Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b80d50ecee73919a507498d0a4d922ae", "20th Century Fox Video Games - Sirius Software, David Lubar", "11008", "Fantastic Voyage (1982) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b816296311019ab69a21cb9e9e235d12", "Atari, Bob Whitehead - Sears", "CX2652 - 6-99816, 49-75151", "Casino (1979) (Atari)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "" },
-  { "b822fba8b7c8a97ea4e92aeb2c455ef9", "Dactari", "", "Freeway (Dactari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b83579c4450fcbdf2b108903731fa734", "", "", "Mission 3,000 A.D. (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "b83df1f32b4539c324bdf94851b4db55", "Angelino", "", "One On One by Angelino (Basketball Hack)", "Hack of Basketball (1978) (Atari)", "New Release (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b86552198f52cfce721bafb496363099", "Apollo, Tim Martin", "AP-2007", "Kyphus (1982) (Apollo) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b86a12e53ab107b6caedd4e0272aa034", "Funvision - Fund. International Co.", "", "Treasure Hunting (Funvision)", "AKA Pitfall!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b879e13fd99382e09bcaf1d87ad84add", "Zellers", "", "Time Warp (Zellers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b8865f05676e64f3bec72b9defdacfa7", "Activision, David Crane", "AG-004", "Fishing Derby (1980) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b897f9e3f939b9f21566d56db812a84e", "Atari, Jim Huether", "CX26163P", "Flag Capture (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b8e715223ba65cf716b3620a90ca3ec1", "Parker Brothers", "PB5820", "Mr. Do!'s Castle (1984) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "b8ed78afdb1e6cfe44ef6e3428789d5f", "Data Age, J. Ray Dettling", "112-007", "Bermuda Triangle (1983) (Data Age)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b9232c1de494875efe1858fc8390616d", "Panda", "110", "Harbor Escape (1983) (Panda)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b9336ed6d94a5cc81a16483b0a946a73", "Atari, Jerome Domurat, Michael Sierchio", "CX2667, CX2667P", "RealSports Soccer (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "b955eb0e2baf7a437c186bddd4c49958", "Atari, Omegamatrix", "", "Space Invaders Menu (2020) (PAL60) (Hack)", "Hack of Space Invaders", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b958d5fd9574c5cf9ece4b9421c28ecd", "Piero Cavina", "", "Multi-Sprite Game V1.0 (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b95a6274ca0e0c773bfdc06b4c3daa42", "Paul Slocum", "", "3-D Corridor (29-03-2003) (Paul Slocum)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b98cc2c6f7a0f05176f74f0f62c45488", "Spectravideo", "SV-010", "CompuMate (1983) (Spectravideo)", "", "", "", "", "CM", "", "", "", "", "COMPUMATE", "COMPUMATE", "", "", "", "", "", "", "YES", "" },
-  { "b9b4612358a0b2c1b4d66bb146767306", "Commavid, Ben Burch", "CM-010", "Rush Hour (1983) (Commavid) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b9d1e3be30b131324482345959aed5e5", "Activision - Boston Design Center, Rex Bradford", "", "Kabobber (07-25-1983) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "b9f6fa399b8cd386c235983ec45e4355", "Parker Brothers, John Emerson", "931511", "Action Force (1983) (Parker Bros) (PAL)", "AKA G.I. Joe - Cobra Strike", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 55", "", "", "", "" },
-  { "b9f9c0fed0db08c34346317f3957a945", "SuperVision", "405, 427, 806, 808, 813, 816", "Chopper Command (SuperVision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ba257438f8a78862a9e014d831143690", "U.S. Games Corporation - JWDA, Todd Marshall, Robin McDaniel, Henry Will IV", "VC2002", "Squeeze Box (1983) (U.S. Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ba317f83cdfcd58cbc65aac1ccb87bc5", "Thomas Jentzsch", "", "Jammed (2001) (XYPE) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ba3a17efd26db8b4f09c0cf7afdf84d1", "Activision, Larry Miller", "AX-021", "Spider Fighter (1983) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ba3b0eebccc7b791107de5b4abb671b4", "Thomas Jentzsch", "", "Thrust (V0.9) (2000) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ba657d940a11e807ff314bba2c8b389b", "Activision, John Van Ryzin", "AG-038-04", "Cosmic Commuter (1984) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bac28d06dfc03d3d2f4a7c13383e84ee", "Supergame", "", "Demon Attack (Supergame)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bae1a23f9b6acdadf465cfb330ba0acb", "Atari - GCC, Doug Macrae", "CX2677", "Dig Dug (1983) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bae66907c3200bc63592efe5a9a69dbb", "Spectravision - Spectravideo - Quelle", "SA-201 - 412.783 3", "Gangster Alley (1982) (Spectravision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "baf4ce885aa281fd31711da9b9795485", "Atari, Douglas Neubauer", "CX26176", "Radar Lock (1989) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bb18189021d58362d9e4d317cd2e28b7", "Activision, David Crane - Ariola", "EAG-001, PAG-001, EAG-001-04B, EAG-001-04I - 711 001-715", "Dragster (1980) (Activision) (PAL) (4K)", "AKA Dragster Rennen", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bb2b83fff97604f74ada565e0b5bae94", "Thomas Jentzsch", "", "Missile Control - Atari Mouse Hack v1.15 (PAL60) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bb5049e4558daade0f87fed69a244c59", "Atari, Brad Stewart", "CX2649, CX2649P", "Asteroids (1981) (Atari) (PAL) [no copyright]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "bb579404924c40ca378b4aff6ccf302d", "", "", "Lightbulb Lightens, The (PD) (Non Functional)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bb6a5a2f7b67bee5d1f237f62f1e643f", "", "", "Demo Image Series #5 - Animegirl (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bb745c893999b0efc96ea9029e3c62ca", "Play Video", "", "Planet Patrol (1982) (Play Video) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bb756aa98b847dddc8fc170bc79f92b2", "", "", "Golf (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bb9112d478a1a922d2c289a752bba695", "Omegamatrix", "", "SpaceMaster X-7 (Amiga Mouse) (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bbf8c7c9ed280151934aabe138e41ba7", "Amiga", "1130", "Power Play Arcade Video Game Album V (1984) (Amiga) (Prototype)", "Mogul Maniac, Surf's Up, Off Your Rocker, S.A.C. Alert", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bc24440b59092559a1ec26055fd1270e", "", "", "Private Eye (1984) (Activision) [a]", "", "", "", "0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bc3057a35319aae3a5cd87a203736abe", "CCE", "C-845", "Time Warp (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bc33c685e6ffced83abe7a43f30df7f9", "Dynacom", "", "Seaquest (1983) (Dynacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bc4cf38a4bee45752dc466c98ed7ad09", "Atari, Douglas Neubauer, Mimi Nyden", "CX26136", "Solaris (1986) (Atari) (PAL)", "AKA Universe, Star Raiders II, The Last Starfighter", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bc526185ad324241782dc68ba5d0540b", "", "", "Dodge Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bc5389839857612cfabeb810ba7effdc", "Atari, Tod Frye", "CX2671", "SwordQuest - WaterWorld (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bc703ea6afb20bc089f04d8c9d79a2bd", "", "", "Gunfight 2600 - Not mergeable with Colbert wizardry... (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bc97d544f1d4834cc72bcc92a37b8c1b", "", "", "Sky Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bcb31f22856b0028c00d12f0e4c0a952", "Canal 3 - Intellivision", "", "Thunderground (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bcb73b534ed7c613ac379ecd726effb5", "Bob Montgomery (aka vdub_bobby)", "", "Squish 'Em (2007) (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bccb4e2cfad5efc93f6d55dc992118ce", "Activision, Carol Shaw", "AX-020, AX-020-04", "River Raid (1982) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bce4c291d0007f16997faa5c4db0a6b8", "Quelle", "292.651 7", "Weltraumtunnel (1983) (Quelle) (PAL)", "AKA Innerspace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bce93984b920e9b56cf24064f740fe78", "Atari", "CX26163P", "Checkers (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bcef7880828a391cf6b50d5a6dcef719", "Rainbow Vision - Suntek", "SS-009", "Bermuda, The (1983) (Rainbow Vision) (PAL)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bd1bd6f6b928df17a702def0302f46f4", "", "", "Binary To Decimal Routine (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bd39598f067a1193ae81bd6182e756d1", "Telegames", "", "Night Stalker (1988) (Telegames) (PAL)", "AKA Dark Cavern", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bd430c2193045c68d1a20a018a976248", "", "", "Pac Ghost Sprite Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bd551ff1264f5c367a3ad7cf0d2f266c", "Bit Corporation", "R320", "SpaceMaster X-7 (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bda1463e02ae3a6e1107ffe1b572efd2", "Atari, Nick 'Sandy Maiwald' Turner", "CX26111", "Snoopy and the Red Baron (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bdb4b584ddc90c9d2ec7e21632a236b6", "Atari Freak 1", "", "Nitemare at Sunshine Bowl-a-Rama (Atari Freak 1) (Hack)", "Hack of Pac-Man Jr.", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bdbaeff1f7132358ea64c7be9e46c1ac", "20th Century Fox Video Games, Douglas 'Dallas North' Neubauer", "11105", "Mega Force (1982) (20th Century Fox) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bdc381baf7c252c63739c5e9ed087a5c", "", "", "Vertical Ship Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bdecc81f740200780db04a107c3a1eba", "Quelle", "874.254 6", "Super-Cowboy beim Rodeo (1983) (Quelle) (PAL)", "AKA Stampede", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bdf1996e2dd64baf8eff5511811ca6ca", "Tron", "", "H.E.R.O. (Tron)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "be060a704803446c02e6f039ab12eb91", "Parker Brothers, Rex Bradford, Sam Kjellman", "931501", "Star Wars - The Empire Strikes Back (1982) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "be1922bd8e09d74da471287e1e968653", "Cropsy", "", "Hangman Pacman Demo (Cropsy) (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "be2870a0120fd28d25284e9ccdcbdc99", "", "", "Tomb Raider 2600 [REV 01] (Montezuma's Revenge Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "be35d8b37bbc03848a5f020662a99909", "Atari, Joe Decuir, Steve Mayer, Larry Wagner - Sears", "CX2601 - 99801, 6-99801, 49-75124", "Combat (1977) (Atari) (4K) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "be3f0e827e2f748819dac2a22d6ac823", "Puzzy - Bit Corporation", "PG202", "Space Tunnel (1982) (Puzzy)", "AKA Le Tunnel de L'Estace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "be41463cd918daef107d249f8cde3409", "", "", "Berzerk (Voice Enhanced) (Hack)", "Hack of Berzerk", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "be561b286b6432cac71bccbae68002f7", "", "", "Counter Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "be929419902e21bd7830a7a7d746195d", "Activision, Garry Kitchen", "AX-025, AX-025-04", "Keystone Kapers (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "becd908f9d7bb361982c3dc02d6475c6", "Kyle Pittman", "", "THX-1138 (Kyle Pittman) (Hack)", "Hack of Berserk", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bedfbde71fb606601f936b5b057f26f7", "Activision, Garry Kitchen - Ariola", "EAX-025, EAX-025-04I - 711 025-725", "Keystone Kapers (1983) (Activision) (PAL) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "befce0de2012b24fd6cb8b53c17c8271", "", "", "Push (V0.03) (No Illegal Opcodes) (1998) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bf1970b692275b42c4ec0683588eb062", "Thomas Jentzsch", "", "Reactor - Amiga Mouse Hack v1.3 (NTSC) (Full-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bf52327c2197d9d2c4544be053caded1", "HES - Activision", "AG-930-04, AZ-030", "Decathlon (HES) (PAL) (16K)", "AKA Activision Decathlon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bf84f528de44225dd733c0e6a8e400a0", "CCE", "", "Demons to Diamonds (CCE)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 57", "", "", "", "" },
-  { "bf976cf80bcf52c5f164c1d45f2b316b", "Atari, Tod Frye, Mimi Nyden", "CX2657", "SwordQuest - FireWorld (1982) (Atari) (PAL)", "AKA Adventure II, SwordQuest II - FireWorld", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bfa58198c6b9cd8062ee76a2b38e9b33", "", "", "20 Sprites at Once Demo 4 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bfb73aabb2489316cd5882c3cd11d9f9", "AtariAge, Chris Walton & Thomas Jentzsch", "165", "Star Castle Arcade (2014) (AtariAge)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "bff8f8f53a8aeb1ee804004ccbb08313", "", "", "Droid Demo 22 (David Conrad Schweinsberg) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "bffe34516aaa3cbf5d307eab382a7e95", "", "", "Euchre (Release Candidate) (PAL) (28-09-2002) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c00734a2233ef683d9b6e622ac97a5c8", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX26133", "A-Team, The (03-30-1984) (Atari) (Prototype)", "AKA Saboteur", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c00b65d1bae0aef6a1b5652c9c2156a1", "Atari, Joe Decuir - Sears", "CX2621 - 99806, 6-99806, 49-75104", "Video Olympics (1977) (Atari) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "YES", "", "", "AUTO 60", "", "", "", "" },
-  { "c02e1afa0671e438fd526055c556d231", "Atari", "", "A-Team (Atari) (Prototype) (PAL60)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c032c2bd7017fdfbba9a105ec50f800e", "Activision, Charlie Heath", "", "Thwocker (04-09-1984) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c033dc1d7b6fde41b9cadce9638909bb", "", "", "Skeleton (V1.1) (06-09-2002) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c0589bb73858924389077fa3c2e9441a", "SOLID Corp. (D. Scott Williamson)", "CX2655-014", "Star Castle 2600 (SolidCorp) [014]", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "c05f367fa4767ceb27abadf0066df7f4", "Thomas Jentzsch", "", "TomInv (31-07-2001) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c08d0cee43077d3055febb00e5745c1d", "HES - Activision", "", "Super Hit Pak - River Raid, Sky Jinks, Grand Prix, Fishing Derby, Checkers (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c0a68837c60e15d1fc5a40c9a62894bc", "Arcadia Corporation, Kevin Norman", "7 AR-4103", "Killer Satellites (1983) (Arcadia) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c0c7eddefce9015346db88ade3e1e096", "CBS Electronics, Bob Curtiss", "4L 2487 5000", "Solar Fox (1983) (CBS Electronics) (Prototype) (4K)", "RAM must be zero'ed to start correctly", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "c0d2434348de72fa6edcc6d8e40f28d7", "SEGA - Beck-Tech, Steve Beck", "010-01", "Tapper (1984) (SEGA)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c1034a5bfb0bb13cc5bdf86cc58989a7", "Atari, Nick 'Sandy Maiwald' Turner", "CX2665", "Frog Pond (1982) (Atari) (Prototype) (4K) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c118854d670289a8b5d5156aa74b0c49", "Jone Yuan Telephonic Enterprise Co", "", "Skiing (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c11e8473c652619ac6166900150ce215", "AtariAge, Chris Walton", "1.0 (Release)", "Chetiry (2011) (AtariAge) (60k) (PAL)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "50" },
-  { "c126656df6badfa519cc63e681fb3596", "Ron Corcoran", "", "Space Invaders (2002) (Ron Corcoran) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c15042e54c7408498f051d782aaa8945", "Omegamatrix", "", "Millipede (Atari Trak-Ball) v6.5 (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c150c76cbde2c9b5a97eb5399d46c64f", "", "", "Unknown Title (xxx00000 (200203)) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c16c79aad6272baffb8aae9a7fff0864", "U.S. Games Corporation - JWDA, Sylvia Day, Todd Marshall, Robin McDaniel, Henry Will IV", "VC2001", "Gopher (1982) (U.S. Games)", "AKA Gopher Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c16fbfdbfdf5590cc8179e4b0f5f5aeb", "", "", "Wall Break (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c17bdc7d14a36e10837d039f43ee5fa3", "Spectravision - Spectravideo", "SA-203", "Cross Force (1982) (Spectravision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c1a83f44137ea914b495fc6ac036c493", "Atari, Carla Meninsky", "CX2660", "Star Raiders (1982) (Atari) (PAL)", "Uses Joystick (left) and Keypad (right) Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c1b038ce5cb6d85e956c5509b0e0d0d8", "", "", "Rotating Colors Demo 2 (Junkosoft) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c1b1049b88bcd98437d8872d1d62ba31", "", "", "Demo Image Series #4 - Donald (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c1b7aeabc3ec41556d924c8372a9ba5b", "Atari, Robert C. Polaro", "", "Dukes of Hazard (1980) (Atari) (Prototype)", "AKA Stunt Cycle", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c1cb228470a87beb5f36e90ac745da26", "Activision, Bob Whitehead", "AX-015, AX-015-04", "Chopper Command (1982) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c1e6e4e7ef5f146388a090f1c469a2fa", "Bomb - Onbase", "CA283", "Z-Tack (1983) (Bomb)", "AKA Base Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c1f209d80f0624dada5866ce05dd3399", "Telegames", "", "Deadly Discs (1988) (Telegames) (PAL)", "AKA TRON - Deadly Discs", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c1fdd44efda916414be3527a47752c75", "Parker Brothers, John Emerson", "PB5920", "G.I. Joe - Cobra Strike (1983) (Parker Bros)", "Uses the Paddle (left) and Joystick (right) Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c20f15282a1aa8724d70c117e5c9709e", "Video Gems", "VG-02", "Surfer's Paradise (1983) (Video Gems) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c21450c21efb7715746e9fa87ad6f145", "Hozer Video Games", "", "Gunfight 2600 - It could've been soooo cool, but... (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c216b91f5db21a093ded6a5aaec85709", "Jone Yuan Telephonic Enterprise Co", "", "Dragster (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c221607529cabc93450ef25dbac6e8d2", "Eckhard Stolberg", "", "Color Test (26-09-2002) (Eckhard Stolberg)", "", "Homebrew", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c225379e7c4fb6f886ef9c8c522275b4", "Video Mania", "", "Frostbite (1983) (Video Mania)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c225abfb584960efe1f359fc94b73379", "", "", "Joustpong (21-09-2002) (Kirk Israel) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c2410d03820e0ff0a449fa6170f51211", "", "", "Pac-Man (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c246e05b52f68ab2e9aee40f278cd158", "Thomas Jentzsch", "", "Star Wars - Ewok Adventure (Thomas Jentzsch) (Prototype)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c2778507b83d9540e9be5713758ff945", "", "", "Island Flyer Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c28b29764c2338b0cf95537cc9aad8c9", "", "", "Multi-Color Demo 4 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c29d17eef6b0784db4586c12cb5fd454", "Jone Yuan Telephonic Enterprise Co", "", "River Raid (Jone Yuan) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c29f8db680990cb45ef7fef6ab57a2c2", "Parker Brothers - Roklan, Paul Crowley, Bob Curtiss", "931505", "Super Cobra (1983) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c2a37f1c7603c5fd97df47d6c562abfa", "Roger Williams", "", "Bar-Score Demo (2001) (Roger Williams)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c2b5c50ccb59816867036d7cf730bf75", "Salu - Avantgarde Software, Michael Buetepage", "460741", "Ghostbusters II (1992) (Salu) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "c2bcd8f2378c3779067f3a551f662bb7", "Activision, Bob Whitehead - Ariola", "EAG-002, EAG-002-04I, PAG-002 - 711 002-715", "Boxing (1980) (Activision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c2c7a11717e255593e54d0acaf653ee5", "", "", "Chopper Command (208 in 1) (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c2c8eb642765137bb82b83a65232961f", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Mouse Hack v1.1 (PAL) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c2dea467f4a02fa1f06d66f52bc12e6e", "Thomas Jentzsch", "", "Missile Command Atari Trak-Ball Hack v1.3 (NTSC) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c2fbef02b6eea37d8df3e91107f89950", "Champ Games", "CG-02-N", "Conquest Of Mars (NTSC)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c31a17942d162b80962cb1f7571cd1d5", "Home Vision - Gem International Corp. - VDI", "VCS83112", "Sky Alien (1983) (Home Vision) (PAL)", "AKA Sky Aliem", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c3205e3707f646e1a106e09c5c49c1bf", "", "", "Unknown Title (bin00003 (200206)) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c3472fa98c3b452fa2fd37d1c219fb6f", "Atari, Carla Meninsky - Sears", "CX2637 - 49-75158", "Dodge 'Em (1980) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c370c3268ad95b3266d6e36ff23d1f0c", "Atari, Alan Miller", "CX2641, CX2641P", "Surround (1977) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c3a9550f6345f4c25b372c42dc865703", "Atari - Bobco, Robert C. Polaro", "CX2663", "Road Runner (1989) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c3aeb796fdaf9429e8cd6af6346f337e", "", "", "If It's Not One Thing It's Another (1997) (Chris Cracknell)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c3bbc673acf2701b5275e85d9372facf", "Atari, Robert C. Polaro", "CX26157", "Stunt Cycle (07-21-1980) (Atari) (Prototype)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c3e4aa718f46291311f1cce53e6ccd79", "", "", "Hangman Ghost 4letter (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c3ef5c4653212088eda54dc91d787870", "Activision, Bob Whitehead", "AG-002, CAG-002, AG-002-04", "Boxing (1980) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c3f53993ade534b0982ca3a286c85bb5", "", "", "Full Screen Bitmap Drawing System (12-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c4060a31d61ba857e756430a0a15ed2e", "Thomas Jentzsch", "", "Pick 'n Pile (2003) (TJ)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "c41e7735f6701dd50e84ee71d3ed1d8f", "Dynacom", "", "Spider Fighter (1983) (Dynacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c43bd363e1f128e73ba5f0380b6fd7e3", "Atari, Chris Crawford", "", "Wizard (1980) (Atari) (Prototype) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c446288fe62c0c2737639fd788ae4a21", "", "", "Mark's Sound Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "c450a285daa7a3b65188c2c3cf04fb3e", "Wizard Video Games", "007", "Halloween (1983) (Wizard Video Games) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c469151655e333793472777052013f4f", "", "", "Base Attack (Unknown) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c471b97446a85304bbac021c57c2cb49", "First Star Software, Alex Leavens, Shirley Ann Russell", "", "Boing! (1983) (First Star Software) (PAL)", "AKA Bubbles, Soap Suds, The Emphysema Game", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "c47244f5557ae12c61e8e01c140e2173", "Atari - GCC, Mike Feinstein, John Allred", "CX2688, CX2688P", "Jungle Hunt (1983) (Atari) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c47b7389e76974fd0de3f088fea35576", "Funvision - Fund. International Co.", "", "Mighty Mouse (Funvision)", "AKA Gopher", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c482f8eebd45e0b8d479d9b71dd72bb8", "Retroactive", "", "Push (V0.03) (1998) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "c49fe437800ad7fd9302f3a90a38fb7d", "Atari, Dan Hitchens, Mimi Nyden", "CX2697, CX2697P", "Mario Bros. (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c4b73c35bc2f54b66cd786f55b668a82", "Arcadia Corporation, Stephen Harland Landrum", "AR-4101", "Communist Mutants from Space (1982) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c4bbbb0c8fe203cbd3be2e318e55bcc0", "", "", "Atlantis (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c4bc8c2e130d76346ebf8eb544991b46", "Imagic", "", "Imagic Selector ROM (1982) (Imagic) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c4d888bcf532e7c9c5fdeafbb145266a", "", "", "Space Robot (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "c504a71c411a601d1fc3173369cfdca4", "Retroactive", "", "Qb (V2.02) (Stella) (2001) (Retroactive)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "c5124e7d7a8c768e5a18bde8b54aeb1d", "Imagic, Rob Fulop", "720104-2A, IA3204P, EIX-008-04I", "Cosmic Ark (1982) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c517144e3d3ac5c06f2f682ebf212dd7", "Tigervision - Teldec", "7-008 - 3.60006 VG", "Miner 2049er (1983) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c529e63013698064149b9e0468afd941", "", "", "S.I.PLIX 2 (Hack)", "Hack of Kaboom!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
-  { "c52d9bbdc5530e1ef8e8ba7be692b01e", "Atari, Robert C. Polaro", "CX26130", "Holey Moley (02-29-1984) (Atari) (Prototype)", "Uses Keypad Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c5301f549d0722049bb0add6b10d1e09", "Atari, Carla Meninsky, Ed Riddle - Sears", "CX2611 - 99821, 49-75149", "Indy 500 (1977) (Atari)", "Uses the Driving Controllers", "", "", "", "", "", "", "", "", "DRIVING", "DRIVING", "", "", "", "45", "", "", "", "" },
-  { "c5387fc1aa71f11d2fa82459e189a5f0", "Bit Corporation", "PG202", "Space Tunnel (1982) (BitCorp) (PAL)", "AKA Weltraum-Tunnel", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c53c0d10c74325deae9ba84074281983", "The Atari 2600 Connection - John K. Harvey, Tim Duarte", "v75", "Mean Santa (2009)", "Released in 2019", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c541a5f6fc23b40a211196dd78233780", "Atari, Carla Meninsky - Sears", "CX2660 - 49-75187", "Star Raiders (1981) (Atari) (Prototype) (4K)", "Uses Joystick (left) and Keypad (right) Controllers", "Prototype", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "" },
-  { "c54b4207ce1d4bf72fadbb1a805d4a39", "Billy Eno", "", "Sniper (Feb 30) (2001) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c560a3ecb7b751021953819efcfe5b41", "Omegamatrix", "", "Ghostbusters (Genesis)", "Genesis controller", "", "", "", "", "", "", "", "", "GENESIS", "", "", "", "", "", "", "", "", "" },
-  { "c569e57dca93d3bee115a49923057fd7", "", "", "Pac-Space (Pac-Man Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c58708c09ccb61625cda9d15ddcd8be6", "SPIKE the Percussionist", "", "NOIZ Invaders (SPIKE) (2002) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c5930d0e8cdae3e037349bfa08e871be", "Atari, Howard Scott Warshaw - Sears", "CX2655 - 49-75167", "Yars' Revenge (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "c59633dbebd926c150fb6d30b0576405", "Telegames", "5861 A030", "Bogey Blaster (1988) (Telegames)", "AKA Air Raiders", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c5a76bafc4676edb76e0126fb9f0fb2d", "Charles Morgan", "", "Zero Patrol (Charles Morgan) (Hack)", "Hack of Moon Patrol", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c5bab953ac13dbb2cba03cd0684fb125", "SpiceWare - Darrell Spice Jr.", "", "Stay Frosty (SpiceWare)", "Part of Stella's Stocking 2007 Xmas compilation", "Homebrew", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "c5bf03028b2e8f4950ec8835c6811d47", "Atari - Axlon, Tod Frye - Heuristica, Agustin Ortiz", "CX26169", "Shooting Arcade (03-07-1989) (Atari) (Prototype) [a2]", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c5c7cc66febf2d4e743b4459de7ed868", "Atari, Jerome Domurat, Steve Woita", "CX2696", "Asterix (1983) (Atari) (PAL) [a]", "AKA Taz", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c5d2834bf98e90245e545573eb7e6bbc", "CCE", "", "Snoopy and the Red Baron (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c5dd8399257d8862f3952be75c23e0eb", "Atari - GCC", "CX2680", "RealSports Tennis (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c5f71dfbdca9cc96b28643ff4d06aa6f", "Thomas Jentzsch", "", "Centipede - Atari Trak-Ball Hack v1.4 (PAL) (Full-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c5fe45f2734afd47e27ca3b04a90213c", "Atari, Brad Stewart", "CX2622, CX2622P", "Breakout (1978) (Atari) (PAL) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" },
-  { "c63a98ca404aa5ee9fcff1de488c3f43", "Atari", "CX26145", "Venture (1987) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "c6556e082aac04260596b4045bc122de", "Atari - GCC, Dave Payne", "CX2669", "Vanguard (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c6688781f4ab844852f4e3352772289b", "Atari, Tod Frye", "CX2695", "Xevious (08-02-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "c67ff409f28f44883bd5251cea79727d", "", "", "Gunfight 2600 - Music & Bugfixes 1 (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c689148ad9275667924ab334107b517e", "Jone Yuan Telephonic Enterprise Co", "", "Space Raid (Jone Yuan)", "AKA MegaMania", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c68a6bafb667bad2f6d020f879be1d11", "Atari, Michael Kosaka, Peter C. Niday, Robert Vieira", "CX26110", "Crystal Castles (1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c6ae21caceaad734987cb24243793bd5", "CCE", "", "Frostbite (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c6c63da3bc2e47291f63280e057061d0", "128-in-1 Junior Console", "", "Human Cannonball (128-in-1 Junior Console) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c6d48c6ae6461e0e82753540a985ac9e", "Ed Federmeyer", "", "Edtris (1994) (Ed Federmeyer)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c6d7fe7a46dc46f962fe8413c6f53fc9", "Parker Brothers, Mark Lesser", "PB5950", "Lord of the Rings (1983) (Parker Bros) (Prototype) [a]", "Journey to Rivendell (The Lord of the Rings I)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c6db733e0b108c2580a1d65211f06dbf", "Atari, Eric Manghise, Mimi Nyden, Joseph Tung", "CX2640", "RealSports Baseball (07-09-1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c738fc3f5aae1e8f86f7249f6c82ac81", "Atari, Brad Stewart - Sears", "CX2622 - 6-99813, 49-75107", "Breakout (1978) (Atari) (16K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 60", "", "", "", "" },
-  { "c73ae5ba5a0a3f3ac77f0a9e14770e73", "Starpath Corporation, Stephen H. Landrum", "9 AR-4105", "Official Frogger, The (1983) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c745487828a1a6a743488ecebc55ad44", "Rainbow Vision - Suntek", "SS-002", "Galactic (1983) (Rainbow Vision) (PAL)", "AKA The Challenge of.... Nexar", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c74bfd02c7f1877bbe712c1da5c4c194", "Thomas Jentzsch", "", "River Raid Tanks (Thomas Jentzsch) (Hack)", "Hack of River Raid", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c7600d72247c5dfa1ec1a88d23e6c85e", "Arcadia Corporation, Scott Nelson", "13", "Sweat! - The Decathlon Game (1 of 3) (1983) (Arcadia) (Prototype)", "Uses the Paddle Controllers (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c77c35a6fc3c0f12bf9e8bae48cba54b", "Xonox - K-Tel Software - Action Graphics, Michael Schwartz, David Thiel", "6230, 7210, 06004, 99004", "Artillery Duel (1983) (Xonox)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c77d3b47f2293e69419b92522c6f6647", "Panda", "101", "Tank Brigade (1983) (Panda)", "AKA Phantom Tank", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c7900a7fe95a47eef3b325072ad2c232", "Larry Petit", "", "Super Congo Bongo (2003) (Larry Petit) (Hack)", "Hack of Bongo", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c7d5819b26b480a49eb26aeb63cc831e", "Bit Corporation", "PGP210", "Ice Hockey (4 Game in One Light Green) (1983) (BitCorp) (PAL)", "AKA Hockey, Hockey", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c7e43ad79c5e5c029d9f5ffde23e32cf", "", "", "PAL-NTSC Detector (15-11-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c7eab66576696e11e3c11ffff92e13cc", "Atari - GCC", "CX2680, CX2680P", "RealSports Tennis (1983) (Atari) (PAL) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c7f13ef38f61ee2367ada94fdcc6d206", "Parker Brothers - Roklan, Joe Gaucher", "PB5370", "Popeye (1983) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "c82ec00335cbb4b74494aecf31608fa1", "CCE", "", "E.T. - The Extra-Terrestrial (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c830f6ae7ee58bcc2a6712fb33e92d55", "Atari, Michael Kosaka", "CX2687", "Tempest (01-05-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c866c995c0d2ca7d017fef0fc0c2e268", "Retroactive", "", "Qb (2.00) (Retroactive) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "c880c659cdc0f84c4a66bc818f89618e", "Thomas Jentzsch", "", "Open Sesame (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "c89c3138a99fd1fd54367d65f75b0244", "Atari, Omegamatrix", "", "Space Invaders Menu (2020) (PAL) (Hack)", "Hack of Space Invaders", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c8c7da12f087e8d16d3e6a21b371a5d3", "", "", "Demo Image Series #9 - Genius (28-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c8e90fc944596718c84c82b55139b065", "Atari - Roklan, Bob Curtiss", "", "Firefox (1983) (Atari) (Prototype) [a]", "AKA Combat II, Fighter Command", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c8fa5d69d9e555eb16068ef87b1c9c45", "Atari", "CX26144", "Donkey Kong Junior (1987) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c90788d9aa71a78bcc78c015edb22c54", "Thomas Jentzsch", "", "Marble Craze - Atari Trak-Ball Hack v1.0 (PAL60) (TJ)", "Uses Atari Trak-Ball Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c9196e28367e46f8a55e04c27743148f", "Atari", "CX26163P", "Stampede (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c92cfa54b5d022637fdcbdc1ef640d82", "Retroactive", "", "Qb (V2.05) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "c98e8c918a40b4d3a243dd6c49196330", "AtariAge, Omegamatrix", "", "Venture Reloaded (2019) (AtariAge) (PAL60) (Hack)", "Transformative hack of Venture", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "c9b7afad3bfd922e006a6bfc1d4f3fe7", "Atari, Larry Kaplan - Sears", "CX2628 - 6-99842, 49-75117", "Bowling (1979) (Atari)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c9c25fc536de9a7cdc5b9a916c459110", "Activision, Mike Lorenzen", "AX-023", "Oink! (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c9d02d3cfeef8b48fb71cb4520a4aa84", "", "", "Euchre (More for less) (PAL) (22-08-2002) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c9e721eb29c940c2e743485b044c0a3f", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "c9f6e521a49a2d15dac56b6ddb3fb4c7", "Parker Brothers, Rex Bradford", "PB5000", "Star Wars - Jedi Arena (1983) (Parker Bros)", "Uses the Paddle Controllers (swapped)", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 50", "", "", "", "" },
-  { "ca09fa7406b7d2aea10d969b6fc90195", "Activision, Matthew L. Hubbard, Bob Whitehead", "AX-024", "Dolphin (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ca4f8c5b4d6fb9d608bb96bc7ebd26c7", "M Network - INTV - APh Technological Consulting, Hal Finney, Glenn Hightower, Peter Kaminski", "MT4317", "Adventures of TRON (1983) (M Network)", "AKA Tron Joystick", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ca50cc4b21b0155255e066fcd6396331", "Suntek", "SS-031", "UFO Patrol (1983) (Suntek) (PAL)", "AKA X'Mission", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "ca53fc8fd8b3c4a7df89ac86b222eba0", "CCE", "C-812", "Pac Man (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ca54de69f7cdf4d7996e86f347129892", "PlayAround - J.H.M.", "201", "Philly Flasher (1982) (PlayAround)", "Uses the Paddle Controllers, AKA Beat 'Em & Eat 'Em", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" },
-  { "ca7aaebd861a9ef47967d31c5a6c4555", "Atari, Bob Whitehead", "CX26163P", "Homerun (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" },
-  { "ca7abc774a2fa95014688bc0849eee47", "Atari, Michael Kosaka, Peter C. Niday, Robert Vieira", "CX26110", "Crystal Castles (1984) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ca7f166a94eed1a349dec6d6a358bcad", "Activision, Alan Miller - Ariola", "EAG-007, EAG-007-04I, PAG-007 - 711 007-720", "Tennis (1981) (Activision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cac9928a84e1001817b223f0cecaa3f2", "Amiga - Video Soft, Jerry Lawson, Dan McElroy", "", "3-D Genesis (1983) (Amiga) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "cad982c9b45bc5eff34e4ea982d5f1ca", "", "", "Song (17-02-2003) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "cade123747426df69570a2bc871d3baf", "Gakken", "011", "Marine Wars (1983) (Gakken) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cae8f83c06831ec7bb6a3c07e98e9342", "Colin Hughes", "", "Tetris 2600 (Colin Hughes) [o1]", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "cb18d8d5fbdcb1cd7bd36c5423348859", "", "", "RAM-Pong (NTSC) v1.0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cb24210dc86d92df97b38cf2a51782da", "Video Gems", "VG-01", "Missile Control (1983) (Video Gems) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cb4a7b507372c24f8b9390d22d54a918", "ITT Family Games", "554-37 338", "Peter Penguin (1983) (ITT Family Games) (PAL)", "AKA Frisco (Pumuckl-Serie)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cb8399dc0d409ff1f531ef86b3b34953", "", "", "Demo Image Series #12 - Luigi And Mario (01-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cb9626517b440f099c0b6b27ca65142c", "Atari, Larry Kaplan - Sears", "CX2664 - 6-99818", "Brain Games (1978) (Atari) (4K)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "KEYBOARD", "KEYBOARD", "", "", "", "", "", "", "", "" },
-  { "cb96b0cf90ab7777a2f6f05e8ad3f694", "Silvio Mogno", "", "Rainbow Invaders", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cb9b2e9806a7fbab3d819cfe15f0f05a", "Parker Brothers - JWDA, Todd Marshall, Robin McDaniel, Ray Miller", "931513", "Star Wars - Death Star Battle (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cba56e939252b05df7b7de87307d12ca", "", "", "Playfield Text Demo (2001) (Roger Williams)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cbad928e10aeee848786cc55394fb692", "", "", "Fu Kung! (V0.06a Cuttle Cart Compatible) (15-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cbb0ee17c1308148823cc6da85bff25c", "", "", "Rotating Colors Demo 1 (Junkosoft) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cbc373fbcb1653b4c56bfabba33ea50d", "CCE", "", "Super Voleyball (CCE)", "AKA RealSports Volleyball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cbced209dd0575a27212d3eee6aee3bc", "Apollo - Games by Apollo, Ed Salvo, Byron Parks", "AP-2003", "Racquetball (1982) (Apollo) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "cbd981a23c592fb9ab979223bb368cd5", "Atari, Carla Meninsky - Sears", "CX2660 - 49-75187", "Star Raiders (1982) (Atari)", "Uses Joystick (left) and Keypad (right) Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cbe5a166550a8129a5e6d374901dffad", "Atari, Carla Meninsky - Sears", "CX2610 - 49-75127", "Warlords (1981) (Atari)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 50", "", "", "", "" },
-  { "cbeafd37f15e0dddb0540dbe15c545a4", "", "", "Black and White Fast Scolling Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cc03c68b8348b62331964d7a3dbec381", "Jone Yuan Telephonic Enterprise Co", "", "Marauder (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cc12581e079cd18330a89902625b8347", "Dave Neuman", "", "Space Battle (PAL)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cc1939e4769d0c157ace326efcfdcf80", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (3 of 4) (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cc2973680c150886cce1ed8693c3aca2", "Quelle", "874.254 6", "Super-Cowboy beim Rodeo (1983) (Quelle) (PAL) (4K)", "AKA Stampede", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cc3d942c6958bd16b1c602623f59e6e1", "Atari, Bill Aspromonte, John Russell, Michael Sierchio, Robert Zdybel", "CX26114", "Pigs in Space (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cc7138202cd8f6776212ebfc3a820ecc", "Atari - CCW, Christopher H. Omarzu, Preston Stuart, Bruce Williams", "CX26101", "Oscar's Trash Race (03-30-1983) (Atari) (Prototype)", "Uses the Keypad Controllers", "Prototype", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "" },
-  { "cc724ebe74a109e39c0b2784ddc980ca", "Atari, Jerome Domurat, Dave Staugas", "CX2682", "Krull (05-27-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cc74ddb45d7bc4d04c2e6f1907416699", "", "", "Colour Display Programme (1997) (Chris Cracknell)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cca33ae30a58f39e3fc5d80f94dc0362", "", "", "Okie Dokie (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ccb56107ff0492232065b85493daa635", "Bit Corporation", "PG206 [demonstration cartridge]", "Bobby Is Going Home (1983) (BitCorp) (PAL) [demo cart]", "AKA Bobby geht Heim", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ccb5fa954fb76f09caae9a8c66462190", "Answer Software Corporation - TY Associates, Mike Wentz", "ASC1001", "Malagai (1983) (Answer Software)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "ccb807eb79b0ed0f5fdc460445ef703a", "", "", "Superman (Stunt_Cycle_Rules!) (Hack)", "Hack of Superman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ccbd36746ed4525821a8083b0d6d2c2c", "Atari, Brad Stewart - Sears", "CX2649, 49-75163", "Asteroids (1981) (Atari) [no copyright]", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "cccfe9e9a11b1dad04beba46eefb7351", "", "", "Poker Squares (V0.25) (PAL) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ccd6ce508eee4b3fca67212833edcd85", "Otto Versand", "746422", "Hot Wave (Double-Game Package) (1983) (Otto Versand) (PAL)", "AKA Ram It", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ccd92a269a4c2bd64d58cf2c0114423c", "Atari - GCC, Mark Ackerman, Glenn Parker", "CX2675", "Ms. Pac-Man (09-20-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cd032ab6764b55438a7b0bfb5e78595a", "", "", "Hangman Pac-Man 4letter (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cd139ae6d09f3665ad09eb79da3f9e49", "Eric Mooney", "", "Invaders by Erik Mooney (4-24-97) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cd34b3b3ef9e485201e841ba71beb253", "Bradford W. Mott", "", "Hit HMOVE At Various Cycles After WSYNC Test (Bradford W. Mott) (1998) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cd38ad19f51b1048d8e5e99c86a2a655", "", "", "Demo Image Series #5 - Flag (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cd399bc422992a361ba932cc50f48b65", "Arcadia Corporation, Brian McGhie", "AR-4104", "Rabbit Transit (Preview) (1983) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cd3e26786136a4692fd2cb2dfbc1927e", "", "", "Multiple Moving Objects Demo 2 (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cd4423bd9f0763409bae9111f888f7c2", "Jone Yuan Telephonic Enterprise Co", "", "River Raid (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cd4ded1ede63c4dd09f3dd01bda7458c", "Future Video Games", "", "Laser Gate (Future Video Games) (PAL)", "AKA Innerspace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cd568d6acb2f14477ebf7e59fb382292", "Videospielkassette - Ariola", "PGP235", "Fussball (Ariola) (PAL)", "AKA International Soccer", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cd5af682685cfecbc25a983e16b9d833", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX26133", "A-Team, The (05-08-1984) (Atari) (Prototype)", "AKA Saboteur", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cd88ef1736497288c4533bcca339f881", "SEGA - Teldec", "005-10", "Buck Rogers - Planet of Zoom (1983) (SEGA) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "cd8fa2e9f6255ef3d3b9b5a4f24a54f7", "", "", "Daredevil (V2) (Stunt_Cycle_Rules!) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cd98be8a48ebf610c9609a688b9c57f2", "Arcadia Corporation, Steve Hales, Stephen H. Landrum", "4 AR-4102", "Suicide Mission (1982) (Arcadia) (Prototype)", "AKA Meteoroids", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "cd9fea12051e414a6dfe17052067da8e", "Paul Slocum", "", "Marble Craze Demo (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cda38714267978b9a8b0b24bee3529ae", "", "", "Space Instigators (V1.6) (17-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cdadb57b34438805ee322ff05bd3d43e", "Thomas Jentzsch", "", "Centipede - Amiga Mouse Hack v1.4 (PAL60) (Full-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cdb81bf33d830ee4ee0606ee99e84dba", "Arcadia Corporation, Scott Nelson", "AR-4300", "Fireball (1982) (Arcadia) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" },
-  { "cdc1a5c61d7488eadc9aba36166b253d", "Retroactive", "", "Qb (V0.12) (Stella) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "cddabfd68363a76cd30bee4e8094c646", "Computer Magic - CommaVid, John Bronstein", "CM-001", "MagiCard (1981) (CommaVid)", "Uses the Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ce17325834bf8b0a0d0d8de08478d436", "", "", "Boring Freeway (Hack)", "Hack of Freeway", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ce1cbe159b9ae5992dacf09371de5e13", "Atari - GCC, Kevin Osborn", "CX2689", "Kangaroo (01-19-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ce243747bf34a2de366f846b3f4ca772", "Home Vision - Gem International Corp. - VDI", "", "Jacky Jump (1983) (Home Vision) (PAL)", "AKA Bobby Is Going Home", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ce4bbe11d682c15a490ae15a4a8716cf", "", "", "Okie Dokie (Older) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ce5524bb18e3bd8e092273ef22d36cb9", "Carrere Video - JWDA, Todd Marshall, Wes Trager, Henry Will IV - Teldec - Prism", "USC1004", "Commando Raid (1983) (Carrere Video) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ce5cc62608be2cd3ed8abd844efb8919", "Atari - Bobco, Robert C. Polaro", "CX2663", "Road Runner (1989) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ce64812eb83c95723b04fb56d816910b", "Retroactive", "", "Qb (V2.04) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "ce6c4270f605ad3ce5e82678b0fc71f8", "", "", "Vertical Rainbow Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ce82a675c773ff21e0ffc0a4d1c90a71", "", "", "Defender 2 (Genesis)", "Genesis controller (C is smartbomb)", "Hack of Defender 2", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ce8467ae2a3a5bc88ca72a2ce44ce28c", "SOLID Corp. (D. Scott Williamson)", "CX2655-015", "Star Castle 2600 (SolidCorp) (PAL) [015]", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "ce89529d6e98a13ddf3d84827bbdfe68", "", "", "Kung Fu Sprite Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "ce904c0ae58d36d085cd506989116b0b", "Telegames", "5687 A279", "International Soccer (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cea9f72036dc6f7af5eff52459066290", "Retroactive", "", "Qb (2.07) (Retroactive) (Stella)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "ceba7965a93c689bdecdb46a5b2ac0c1", "Thomas Jentzsch", "", "Reactor - Atari Trak-Ball Hack v1.3 (PAL60) (Half-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cedbd67d1ff321c996051eec843f8716", "Ultravision", "1044", "Karate (1982) (Ultravision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cef01595000627ee50863d4290372c27", "", "", "Many Blue Bars and Text Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cef2287d5fd80216b2200fb2ef1adfa8", "Milton Bradley Company", "4363", "Spitfire Attack (1983) (Milton Bradley)", "AKA Flight Commander)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cf0c593c563c84fdaf0f741adb367445", "Retroactive", "", "Qb (V0.05) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "cf3a9ada2692bb42f81192897752b912", "", "", "Air Raiders (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cf3c2725f736d4bcb84ad6f42de62a41", "Rainbow Vision - Suntek", "SS-009", "Bermuda, The (1983) (Rainbow Vision) (PAL) [a]", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cf507910d6e74568a68ac949537bccf9", "SEGA, Jeff Lorenz", "003-01", "Thunderground (1983) (SEGA)", "AKA Underground", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "cf63ffac9da89ef09c6c973083061a47", "CCE", "C-859", "MASH (1983) (CCE)", "AKA M.A.S.H", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cf9069f92a43f719974ee712c50cd932", "Video Gems", "VG-04", "Mission Survive (1983) (Video Gems) (PAL)", "", "", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "cfad2b9ca8b8fec7fb1611d656cc765b", "Bit Corporation", "PG207", "Mission 3,000 A.D. (1983) (BitCorp) (PAL) [demo cart]", "demonstration cartridge", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "cfb3260c603b0341d49ddfc94051ec10", "Dactari - Milmar", "", "Boxing (Dactari - Milmar)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cfb83a3b0513acaf8be4cae1512281dc", "Starpath Corporation", "", "Going-Up (1983) (Starpath) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cfc226d04d7490b69e155abd7741e98c", "Atari, Matthew L. Hubbard", "CX26159", "Double Dunk (1989) (Atari) (PAL)", "AKA Super Basketball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cfce5596a7e8ca13529e9804cad693ef", "Canal 3 - Intellivision", "", "Tennis (Canal 3) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cfd5518c71552b8bb853b0e461e328d7", "Bit Corporation", "R320", "Spider Fighter (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cfd6a8b23d12b0462baf6a05ef347cd8", "Activision, Larry Kaplan", "AX-006", "Bridge (1980) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cfdb4d0427a1ea8085c6bc6eb90259d8", "", "", "Gunfight 2600 - Release Candidate (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cfe2185f84ce8501933beb5c5e1fd053", "", "", "Football (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cfe62ed7125ff9fae99b4c8a367c0399", "Activision, Larry Miller", "AX-026, AX-026-04", "Enduro (1983) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cfee10bd7119f10b136921ced2ee8972", "", "", "Space Instigators (V1.8) (19-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cfef1a2d1f6a5ee7a5e1f43f3056f112", "", "", "Skeleton+ (05-05-2003) (Eric Ball) (NTSC)", "", "", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cff1e9170bdbc29859b815203edf18fa", "Retroactive", "", "Push (V0.01) (1998) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "cff578e5c60de8caecbee7f2c9bbb57b", "George Veeder", "", "Suicide Adventure (George Veeder) (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "cff9950d4e650094f65f40d179a9882d", "Paul Slocum", "", "Mr. Roboto (Paul Slocum) (Hack)", "Hack of Berzerk", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "cfffc4b97d01cc3e7b9f47575f7b11ec", "Xonox - K-Tel Software, Anthony R. Henderson", "99007, 6240", "Tomarc the Barbarian (1983) (Xonox) (PAL60)", "Genesis controller (B is jump and throw, C switches between players)", "Hack of Tomarc the Barbarian", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d00f6f8ba89559e4b20972a478fc0370", "Spiceware", "SW-01", "Medieval Mayhem (PAL)", "", "Homebrew", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "AUTO 55", "", "", "", "" },
-  { "d010e3dfe7366e47561c088079a59439", "Retroactive", "", "Qb (V0.10) (Stella) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "d026716b3c5be2c951cc4c064317c524", "", "", "Fu Kung! (V0.06) (14-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d0498baca989e792db4b8270a02b9624", "", "", "Pac Ghost Sprite Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d071d2ec86b9d52b585cc0382480b351", "UA Limited", "", "Cat Trax (1983) (UA Limited) (1) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "d078674afdf24a4547b4b32890fdc614", "Jone Yuan Telephonic Enterprise Co", "", "Laser Blast (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d078d25873c5b99f78fa267245a2af02", "SEGA - Beck-Tech, Steve Beck, Phat Ho", "006-01", "Congo Bongo (1983) (SEGA) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d0796a0317abf9018d6745086bef411f", "Edward Smith", "", "Alien Attack (2018)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d08fccfbebaa531c4a4fa7359393a0a9", "Activision, David Crane, Bob Whitehead", "", "Venetian Blinds Demo (1981) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d090836f0a4ea8db9ac7abb7d6adf61e", "Hozer Video Games", "", "Yahtzee (Hozer Video Games)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "d09935802d6760ae58253685ff649268", "Telesys, Don Ruffcorn", "1006", "Demolition Herby (1983) (Telesys)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "d09a7504ee8c8717ac3e24d263e7814d", "Activision, Matthew L. Hubbard, Bob Whitehead", "AX-024", "Dolphin (1983) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d09f1830fb316515b90694c45728d702", "Imagic, Brad Stewart", "720105-1A, IA3400", "Fire Fighter (1982) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d0a379946ed77b1b126230ca68461333", "Ataripoll", "", "Atari Invaders (Ataripoll) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d0af33865512e9b6900714c26db5fa23", "Telegames", "", "Armor Ambush (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d0b26e908370683ad99bc6b52137a784", "Apollo - Games by Apollo, Larry Minor, Ernie Runyon, Ed Salvo - RCA Video Jeux", "AP-2004", "Lost Luggage (1982) (Apollo) (PAL)", "AKA La valise piegee", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d0b9df57bfea66378c0418ec68cfe37f", "20th Century Fox Video Games - Sirius, Grady Ward", "11002", "Beany Bopper (1982) (20th Century Fox)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d0b9f705aa5f61f47a748a66009ae2d2", "", "", "Synthcart (14-01-2002) (Paul Slocum)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "d0cb28e1b7bd6c7f683a0917b59f707e", "Atari, Gary Palmer", "CX2661P", "Fun with Numbers (1980) (Atari) (PAL) (4K)", "AKA Basic Math", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d0cdafcb000b9ae04ac465f17788ad11", "Quelle - Otto Versand", "732.273 8 - 600273, 781644", "Lilly Adventure (1983) (Quelle) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d0e05ba5f10e3df3023c5ee787f760ef", "Thomas Jentzsch", "", "Centipede - Atari Mouse Hack v1.4 (PAL) (Half-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d0e15a3ce322c5af60f07343594392af", "Amiga - Video Soft", "3125", "Surf's Up (1983) (Amiga) (Prototype) (4K)", "Uses the Joyboard controller", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d0e9beb2347595c6c7d158e9d83d2da8", "Retroactive", "", "Qb (2.00) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "d100b11be34a1e5b7832b1b53f711497", "", "", "Robotfindskitten2600 (26-04-2003) (Jeremy Penner) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d15655fe355fa57dd541487dc5725145", "Rentacom", "", "Vanguard (Rentacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d170317ae4c7d997a989c7d6567c2840", "Jone Yuan Telephonic Enterprise Co", "", "Stampede (Jone Yuan) (4K) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d175258b2973b917a05b46df4e1cf15d", "Suntek", "SS-032", "Walker (1983) (Suntek) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d17a671029b1532b197defca5f3649a7", "Hozer Video Games", "", "Gunfight 2600 - Limit broken again! (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d17a8c440d6be79fae393a4b46661164", "", "", "Warring Worms (Beta 3) (2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d1a1841b7f2007a24439ac248374630a", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (1 of 4) (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d1a9478b99d6a55e13a9fd4262da7cd4", "U.S. Games Corporation, Garry Kitchen - Vidtec", "VC1001", "Space Jockey (1982) (U.S. Games) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d1b4075925e8d3031a7616d2f02fdd1f", "", "", "Demo Image Series #7 - Two Marios (27-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d1c3520b57c348bc21d543699bc88e7e", "Gameworld", "133-002", "Warplock (1983) (Gameworld) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "YES", "" },
-  { "d1ca47b262f952413c1234117c4e4e21", "Bit Corporation", "R320", "Missile Command (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d1d704a7146e95709b57b6d4cac3f788", "Atari, Warren Robinett", "CX26163P", "Slot Racers (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d20e61c86ed729780feca162166912ca", "Supergame", "32", "Pitfall (1984) (Supergame)", "AKA Pitfall!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d214c7a734e133a5c18e93229435b57a", "Digivision", "", "Mickey (Digivision)", "AKA Sorcerer's Apprentice", "", "", "", "UASW", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d223bc6f13358642f02ddacfaf4a90c9", "Rainbow Vision - Suntek", "SS-003", "Pac-Kong (1983) (Rainbow Vision) (PAL)", "AKA Inca Gold", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d245e2f27c84016041e9496b66b722fe", "", "", "Gunfight 2600 - The Final Kernel (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d25018349c544320bf3fd5092ee072bc", "Activision, Larry Miller", "AX-021", "Spider Fighter (1983) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d28afe0517a046265c418181fa9dd9a1", "", "", "Dodge 'Em (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d2901c34bb6496bb96c7bc78a9e6142a", "Greg Zumwalt", "", "Fish Revenge (2003) (Greg Zumwalt) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d2c4f8a4a98a905a9deef3ba7380ed64", "Mythicon, Bill Bryner, Bruce de Graaf", "MA1001", "Sorcerer (1983) (Mythicon)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d2c8e6aa8172b16c8aa9aae739ac9c5e", "Activision, David Crane", "08-08-1980", "Laser Blast (08-08-1980) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d2c957dd7746521b51bb09fde25c5774", "Eckhard Stolberg", "", "Cubis (6K) (1997) (Eckhard Stolberg)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d2d8c4f1ea7f347c8bcc7d24f45aa338", "", "", "20 Sprites at Once Demo 5 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d2deddb77c8b823e4be9c57cb3c69adc", "Canal 3 - Intellivision", "C 3007", "Snoopy and the Red Baron (Canal 3)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d2f713c78a9ebba9da6d10aeefc6f20f", "Digivision", "", "Enduro (Digivision) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d3171407c3a8bb401a3a62eb578f48fb", "ZiMAG - Emag - Vidco", "GN-080", "Spinning Fireball (1983) (ZiMAG) (Prototype) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "d326db524d93fa2897ab69c42d6fb698", "Parker Brothers - Roklan, Paul Crowley, Bob Curtiss", "931505", "Super Cobra (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d339b95f273f8c3550dc4daa67a4aa94", "", "", "Laser Blast (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d341d39774277cee6a1d378a013f92ac", "Xonox, John Perkins", "6230, 7210, 06004, 99004", "Artillery Duel (1983) (Xonox) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d3423d7600879174c038f53e5ebbf9d3", "U.S. Games Corporation - Western Technologies", "VC2005", "Piece o' Cake (1983) (U.S. Games)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 60", "", "", "", "" },
-  { "d3456b4cf1bd1a7b8fb907af1a80ee15", "Avalon Hill, Duncan Scott", "5003002", "Wall Ball (1983) (Avalon Hill)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "d34b933660e29c0a0a04004f15d7e160", "", "", "Multi-Color Demo 5 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d36308387241e98f813646f346e7f9f7", "King Atari", "", "Ghostbuster 2 (King Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "d39e29b03af3c28641084dd1528aae05", "Funvision - Fund. Int'l Co.", "", "Spider Monster (1982) (Funvision) (PAL)", "AKA Spider Kong", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d3bb42228a6cd452c111c1932503cc03", "UA Limited", "", "Funky Fish (1983) (UA Limited) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "d44d90e7c389165f5034b5844077777f", "Parker Brothers, Larry Gelberg", "PB5065", "Star Wars - Ewok Adventure (1983) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d45bf71871b196022829aa3b96bfcfd4", "Activision, Steve Cartwright", "AX-017, AX-017-04", "MegaMania (1982) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d45ebf130ed9070ea8ebd56176e48a38", "SEGA, Jeff Lorenz", "001-01", "Tac-Scan (1983) (SEGA)", "Uses the Paddle Controllers (right only)", "", "", "", "", "", "", "", "YES", "", "", "YES", "", "", "AUTO 60", "", "", "YES", "" },
-  { "d47387658ed450db77c3f189b969cc00", "PlayAround - J.H.M.", "206", "Westward Ho (1982) (PlayAround) (PAL)", "AKA Custer's Revenge", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d4806775693fcaaa24cf00fc00edcdf3", "Atari - Bobco, Robert C. Polaro", "CX26140, CX26140P", "Desert Falcon (1987) (Atari) (PAL)", "AKA Nile Flyer, Sphinx", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d483f65468d9a265661917bae1a54f3e", "Joe Grand", "", "SCSIcide Pre-release 3 (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d4942f4b55313ff269488527d84ce35c", "Atari - GCC, Mark Ackerman, Glenn Parker", "CX2675, CX2675P", "Ms. Pac-Man (1982) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d49aff83f77a1b9041ad7185df3c2277", "", "", "Space Treat (60% complete) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d4aa89e96d2902692f5c45f36903d336", "", "", "Euchre (NTSC) (Erik Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d4c590ccfb611a73b3331359700c01a3", "", "", "Sprite Movement Demo 2 (2001) (Roger Williams)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d541b20eae221a8ee321375e5971e766", "Arcadia Corporation, Stephen H. Landrum", "AR-4101", "Communist Mutants from Space (Preview) (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d54cd41ecfd59e4b72d2c086152b9a75", "Amiga - Video Soft - Michael K. Glass, Jerry Lawson", "1110", "Power Play Arcade Video Game Album (1983) (Amiga) (Prototype)", "3-D Ghost Attack only (3-D Genesis & 3-D Havoc missing in ROM)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "d5618464dbdc2981f6aa8b955828eeb4", "CCE", "C-829", "Megamania (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d563ba38151b8204c9f5c9f58e781455", "Atari, Brad Stewart - Sears", "CX2649, 49-75163", "Asteroids (1981) (Atari) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "d573089534ca596e64efef474be7b6bc", "Parker Brothers, John Emerson", "931511", "Action Force (1983) (Parker Bros) (PAL) [a]", "AKA G.I. Joe - Cobra Strike", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 55", "", "", "", "" },
-  { "d57913088e0c49ac3a716bf9837b284f", "Activision, Garry Kitchen", "EAZ-032", "Pressure Cooker (1983) (Activision) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d57eb282d7540051bc9b5427cf966f03", "Atari Troll", "", "Custer's Viagra (Atari Troll) (Hack)", "Hack of Custer's Revenge", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d597d35c6022c590d6e75e865738558a", "", "", "Sprite Color Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d5aa7472e7f2cc17e893a1a36f8dadf0", "", "", "Overhead Adventure Demo 5 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d5c6b81212ad86fd9542a1fedaf57cae", "", "", "Sprite Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d5d2d44fb73785996ccc24ae3a0f5cef", "Robby", "", "Grand Prix (Robby)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d5e17022d1ecc20fd9b53dc464c302f1", "Activision, Carol Shaw", "EAX-020", "River Raid (1982) (Activision) (SECAM)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d5e27051512c1e7445a9bf91501bda09", "Activision, David Crane", "AG-008", "Laser Blast (1981) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d5e5b3ec074fff8976017ef121d26129", "Star Game", "003", "River Raid (Star Game)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d5f965c159e26a1fb49a22a47fbd1dd0", "Supergame", "", "River Raid II (Supergame)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d605ed12f4eaaaec3dcd5aa909a4bad7", "", "", "Chronocolor Frame Demo (10-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d61629bbbe035f45552e31cef7d591b2", "", "", "Atari Logo Demo (PD) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d62283aed0f4199adb2333de4c263e9c", "Atari, Alan J. Murphy, Nick 'Sandy Maiwald' Turner", "CX2615", "Demons to Diamonds (1982) (Atari) (PAL)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 57", "", "", "", "" },
-  { "d62d7d1a974c31c5803f96a8c1552510", "", "", "StarMaster (Unknown) (PAL)", "Use Color/BW switch to change between galactic chart and front views", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d632b74fea533d593af82cf16e7c5e4a", "", "", "Fu Kung! (V0.13) (01-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "d65028524761ef52fbbdebab46f79d0f", "CCE", "", "Galaxian (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d65900fefa7dc18ac3ad99c213e2fa4e", "", "", "Guntest (2000) (Eckhard Stolberg)", "Light Gun Test (based on Sentinel code)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d69559f9c9dc6ef528d841bf9d91b275", "Activision, Alan Miller", "AX-016", "StarMaster (1982) (Activision)", "Use Color/BW switch to change between galactic chart and front views", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d6a44277c3eb4f9d039185e0ecf7bfa6", "", "", "Trick (1997) (Eckhard Stolberg)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d6acff6aed0f04690fe4024d58ff4ce3", "Spectravision - Spectravideo - Quelle", "SA-202 - 412.851 8", "Planet Patrol (1982) (Spectravision) (PAL) [different spaceship]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d6b8beeb05e5b730084d4b8f381bbf8d", "", "", "208 in 1 Game Select ROM (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d6d1ddd21e9d17ea5f325fa09305069c", "Funvision - Fund. International Co.", "", "Time Warp (1982) (Funvision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d6d5dd8fd322d3cf874e651e7b6c1657", "", "", "How to Draw a Playfield (1997) (Nick Bensema) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d6dc9b4508da407e2437bfa4de53d1b2", "Bomb - Onbase", "CA283", "Z-Tack (1983) (Bomb) (PAL)", "AKA Base Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d726621c676552afa503b7942af5afa2", "Atari, Bob Whitehead", "CX26163P", "Blackjack (32 in 1) (1988) (Atari) (PAL) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d73ad614f1c2357997c88f37e75b18fe", "Goliath", "7", "Space Tunnel (1983) (Goliath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d74a81fcd89c5cf0bd4c88eb207ebd62", "", "", "Poker Squares (V0.00a) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d763e3a9cdcdd56c715ec826106fab6a", "Activision, David Crane", "AG-001", "Dragster (1980) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d7759fa91902edd93f1568a37dc70cdb", "Atari, Robert C. Polaro", "CX26157", "Stunt Cycle (1980) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d782543818b6320e4f60d77da2b596de", "Atari", "CX26163P", "Fishing Derby (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d787ec6785b0ccfbd844c7866db9667d", "Retroactive", "", "Qb (V0.04) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "d7891b0faa4c7f764482762d0ed427a5", "", "", "Bars and Text Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d7b2259f6bb57bf37eac82365c1f8ad6", "Parker Brothers, Mike Brodie", "PB5320", "Super Cobra (1983) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d7b58303ec8d8c4dbcbf54d3b9734c7e", "", "", "Paddle Demo (Joe Grand) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d7dd56677e4ec1e6627419478a4a9668", "", "", "Shadow Keep (Fixed) (04-03-2003) (Andrew Towers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d7f5bf138cfc7feab7b8ef1534c8b477", "", "", "Eric Bergstrom's KC-135 (Radar Map) (Aaron Bergstrom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d816fea559b47f9a672604df06f9d2e3", "Atari, Gary Palmer", "CX26163P", "Fun with Numbers (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d81bb6965e6c99b3be99ffd8978740e4", "", "", "Gunfight 2600 - The Final Kernel Part 3 (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d82675ce67caf16afe5ed6b6fac8aa37", "Thomas Jentzsch", "", "Robot City (V0.23) (13-11-2002) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d8295eff5dcc43360afa87221ea6021f", "Spectravideo", "SA-212", "Mangia' (1983) (Spectravideo) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d82c8a58098a6b46c5b81c16180354d1", "Dennis Debro", "", "Climber 5 (30-10-2002) (Dennis Debro) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d85f1e35c5445ac898746719a3d93f09", "Suntek", "SS-034", "Farmyard Fun (1983) (Suntek) (PAL)", "AKA Play Farm", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d86deb100c6abed1588aa84b2f7b3a98", "Atari, Bob Whitehead - Sears", "CX2625 - 6-99827, 49-75114", "Football (1979) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d88691c995008b9ab61a44bb686b32e4", "", "", "Warring Worms (07-02-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d89262907e70c13dff23356c4a9055d0", "Bit Corporation", "R320", "Video Pinball (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d89fedded0436fdeda7c3c37e2fb7cf1", "", "", "Surround (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d8acaa980cda94b65066568dd04d9eb0", "CCE", "", "Sea Hunt (CCE)", "AKA Skindiver", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d8b2c81cea5af04f795eb3dc6573d72b", "", "", "Tunnel Demo 2 (27-03-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d8df256c0d89e494a9fb3e9abb8e44ac", "Imagic, Michael Greene", "IA3312P", "No Escape! (1982) (Imagic) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d8e4c8e2d210270cd1e0f6d1b4582b91", "Imagic, Mark Klein", "EIZ-003-04I", "Subterranea (1983) (Imagic) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d90205e29bb73a4cdf28ea7662ba0c3c", "Thomas Jentzsch", "", "Boulderdash Demo (Brighter Version) (09-12-2002) (TJ)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "d912312349d90e9d41a9db0d5cd3db70", "CCE", "C-818", "Star Voyager (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d9548ad44e67edec202d1b8b325e5adf", "Apollo - Games by Apollo, Dan Oliver - RCA Video Jeux", "AP-2002", "Space Cavern (1982) (Apollo) (PAL)", "AKA Les guerriers de l'espace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d968de2b4ff18bfe4a95066cde310578", "Thomas Jentzsch", "", "Centipede - Amiga Mouse Hack v1.4 (PAL) (Half-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d97e3d0b4575ce0b9a6132e19cfeac6e", "Fabrizio Zavagli", "", "Space Treat (061002) (PD)", "Won't work with Stella < V1.2", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d97fd5e6e1daacd909559a71f189f14b", "M Network, Steve Crandall, Patricia Lewis Du Long", "MT4646", "Rocky & Bullwinkle (04-20-1983) (M Network) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d9ab6b67a17da51e5ad13717e93fa2e2", "Thomas Jentzsch", "", "Turbo (Coleco) Prototype Fake v0.1 (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d9b49f0678776e04916fa5478685a819", "Activision, John Van Ryzin - Ariola", "EAZ-036-04, EAZ-036-04B, EAZ-036-04I - 711 036-720", "H.E.R.O. (1984) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d9bd343533b61389b270c0787210943b", "Atari, Douglas 'Solaris' Neubauer", "CX26134", "Last Starfighter (1984) (Atari) (Prototype)", "Genesis controller (C switches to map mode)", "Hack of Last Starfighter (Solaris prototype)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "d9c9cece2e769c7985494b1403a25721", "SOLID Corp. (D. Scott Williamson)", "CX2655*", "Star Castle 2600 (SolidCorp)", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "d9da2ae7c7894a29b43b3c6b79f3b7a2", "Atari, Rob Fulop", "CX2633, CX2633P", "Night Driver (1980) (Atari) (PAL) (4K)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "YES", "" },
-  { "d9fbf1113114fb3a3c97550a0689f10f", "ZiMAG - Emag - Vidco", "713-111 - GN-050", "Pizza Chef (1983) (ZiMAG) (Prototype)", "AKA Pizza Time", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "da0fb2a484d0d2d8f79d6e063c94063d", "", "", "Air Raiders (1982) (Unknown) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "da4e3396aa2db3bd667f83a1cb9e4a36", "Activision, Steve Cartwright", "AX-027", "Plaque Attack (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "da5096000db5fdaa8d02db57d9367998", "Digitel", "", "River Raid (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "da6465a34d2e44d26aa9a2a0cd1bce4d", "Absolute Entertainment, Alex DeMeo", "AG-041-04", "Title Match Pro Wrestling (1987) (Absolute) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "da66d75e4b47fab99733529743f86f4f", "Digitel", "", "Chopper Command (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "da732c57697ad7d7af414998fa527e75", "Atari - Glenn Axworthy", "CX26129", "Midnight Magic (1986) (Atari) (PAL)", "AKA Pinball Wizard", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "da79aad11572c80a96e261e4ac6392d0", "Salu - Ubi Soft, Dennis M. Kiss", "460673", "Pick 'n' Pile (1990) (Salu) (PAL)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "YES", "" },
-  { "da7a17dcdaa62d6971393c0a6faf202a", "", "", "Flag Capture (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dab844deed4c752632b5e786b0f47999", "", "", "Super Challenge Baseball (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dac38b4dd3da73bb7b2e9d70c61d2b7c", "", "", "Hangman Monkey Biglist3 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dac5c0fe74531f077c105b396874a9f1", "Atari - GCC", "CX2680", "RealSports Tennis (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dac762e4d01d445bdef20b7771f6570e", "Atari, Carla Meninsky, Ed Riddle - Sears", "CX2611 - 99821, 49-75149", "Indy 500 (1977) (Atari) (4K) [a]", "Uses the Driving Controllers", "", "", "", "", "", "", "", "", "DRIVING", "DRIVING", "", "", "", "45", "", "", "", "" },
-  { "dad2ab5f66f98674f12c92abcfbf3a20", "", "", "Blue and White Sprite Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "daeb54957875c50198a7e616f9cc8144", "20th Century Fox Video Games, Douglas 'Dallas North' Neubauer", "11005", "Mega Force (1982) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "daef7d8e5a09981c4aa81573d4dbb380", "Adam Thornton", "", "Lord of the Rings (Adam Thornton) (Hack)", "Hack of Dark Mage", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "dafc3945677ccc322ce323d1e9930beb", "Atari", "", "A-Team (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "db1753cc702c18d3917ec7f3b0e8659f", "", "", "Frame Counter 2 (2001) (Jake Patterson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "db339aea2b65b84c7cfe0eeab11e110a", "", "", "Chronocolor Frame Demo 2 (10-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "db4eb44bc5d652d9192451383d3249fc", "CBS Electronics - E.F. Dreyer - VSS, Ed Salvo", "4L 2738 0000", "Mountain King (1983) (CBS Electronics)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "db5073bd75eb05f7d62a7268396d1e77", "Atari", "CX26163P", "Golf (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "db76f7a0819659d9e585f2cdde9175c7", "Xonox", "99005, 6220, 6250", "Robin Hood (1983) (Xonox) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "db80d8ef9087af4764236f7b5649fa12", "M Network, Steve Crandall, Patricia Lewis Du Long", "MT4646", "Rocky & Bullwinkle (1983) (Mattel) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "db971b6afc9d243f614ebf380af0ac60", "Gammation, Robert L. Esken Jr.", "", "Gamma-Attack (1983) (Gammation)", "Uses right joystick controller", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" },
-  { "dba270850ae997969a18ee0001675821", "Greg Troutman", "", "Dark Mage (Greg Troutman) (PD) (4K)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "dbabb80e92ff18d8eecf615c0539151e", "", "", "Sprite Demo 3 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dbb10b904242fcfb8428f372e00c01af", "Atari, John Dunn", "CX2631, CX2631P", "Superman (1979) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dbba14a0f69f0e13fdccb3fde3baedca", "Thomas Jentzsch", "", "Reactor - Atari Trak-Ball Hack v1.3 (NTSC) (Full-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dbc7485ad5814d466de780a3e7ed3b46", "Kyle Pittman", "", "Pink Floyd (Kyle Pittman) (PD)", "Hack of Adventures of Tron (Mattel)", "New Release (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dbc8829ef6f12db8f463e30f60af209f", "Data Age", "DA1001", "Encounter at L-5 (1982) (Data Age)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 50", "", "", "", "" },
-  { "dbdaf82f4f0c415a94d1030271a9ef44", "CCE", "", "Kaboom! (CCE)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
-  { "dbdd21e1ee3d72119e8cd14d943c585b", "", "", "Slot Machine (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dc13df8420ec69841a7c51e41b9fbba5", "Atari, Mimi Nyden, Steve Woita", "CX26132", "Garfield (06-21-1984) (Atari) (Prototype)", "AKA Garfield on the Run", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dc33479d66615a3b09670775de4c2a38", "Suntek", "SS-033", "I.Q. Memory Teaser (1983) (Suntek) (PAL)", "AKA IQ 180", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dc81c4805bf23959fcf2c649700b82bf", "Imagic, Michael Greene", "720055-2A, IA3312P", "No Escape! (1983) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dc905b22de0f191a029df13eddfcabc4", "Atari, Warren Robinett", "", "Elf Adventure (05-02-83) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dc97cbcf091a5ef4ca7fe95dc0848036", "Atari - Roklan, Joe Gaucher, Alex Leavens", "CX2683", "Crazy Climber (1983) (Atari) (Prototype) [a2]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dca90ea1084a2fdbe300d7178ca1a138", "Imagic, Dennis Koble", "IA3000P", "Trick Shot (1982) (Imagic) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "dca941dab5c6f859b71883b13ade9744", "", "", "Hangman Pac-Man Biglist2 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dcba0e33aa4aed67630a4b292386f405", "Retroactive", "", "Qb (V2.08) (Half Speed Version) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "dcc2956c7a39fdbf1e861fc5c595da0d", "M Network - INTV - APh Technological Consulting, David Rolfe", "MT5664", "Frogs and Flies (1982) (M Network)", "AKA Frogs 'n' Flies", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dcec46a98f45b193f07239611eb878c2", "", "", "Bars and Text Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dd08e18cfee87a0e7fc19a684b36e124", "Atari - GCC, Kevin Osborn", "CX2689, CX2689P", "Kangaroo (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dd0cbe5351551a538414fb9e37fc56e8", "Xonox - K-Tel Software - Product Guild, Anthony R. Henderson", "99006, 6220", "Sir Lancelot (1983) (Xonox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dd0de0f61af2a2a4878e377b880a3933", "SOLID Corp. (D. Scott Williamson)", "CX2655-013", "Star Castle 2600 (SolidCorp) [013]", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "dd10b5ee37fdbf909423f2998a1f3179", "", "", "Space Instigators (V1.9) (21-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dd13a16d14100819f79b1ce3a5bf499c", "Thomas Jentzsch", "", "Missile Control - Atari Mouse Hack v1.15 (PAL) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dd1422ffd538e2e33b339ebeef4f259d", "Atari, Michael Sierchio", "", "Football Demo (1982) (Atari)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dd17711a30ad60109c8beace0d4a76e8", "", "", "Karate (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dd1842ba0f3f9d94dccb21eaa0f069b7", "Bit Corporation", "R320", "Defender (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dd45e370aceff765f1e72c619efd4399", "Bit Corporation", "PG201", "Sea Monster (1982) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dd4f4e0fbd81762533e39e6f5b55bb3a", "Thomas Jentzsch", "", "Turbo WIP (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dd7598b8bcb81590428900f71b720efb", "Xonox - K-Tel Software - Computer Magic", "99005, 6220, 6250", "Robin Hood (1983) (Xonox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dd7884b4f93cab423ac471aa1935e3df", "Atari, Brad Stewart - Sears", "CX2649, 49-75163", "Asteroids (1981) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "dd8a2124d4eda200df715c698a6ea887", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (3 of 3) (1982) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dd92d6ad50976f881d86b52d38616118", "SpkSoft", "", "River Raid (SpkSoft) [h1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dda23757407c4e217f64962c87ad0c82", "Atari Freak 1", "", "Nitemare at Sunshine Bowl-a-Rama (Atari Freak 1) (Hack) [a]", "Hack of Pac-Man Jr.", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ddd1efc1862cd3eb3baf4cba81ff5050", "", "", "Max3 (2001) (Maxime Beauvais) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "de0173ed6be9de6fd049803811e5f1a8", "Xonox - K-Tel Software - Product Guild, Anthony R. Henderson", "99008, 6240", "Motocross Racer (1983) (Xonox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "de07e9cb43ad8d06a35f6506e22c62e9", "", "", "Oh No! (Version 4) (22-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "de1a636d098349be11bbc2d090f4e9cf", "", "", "Pressure Gauge (Hozer Video Games)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "de1e9fb700baf8d2e5ae242bffe2dbda", "Activision - Imagineering, Mike Reidel", "EAK-043-04I", "Commando (1988) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "de24f700fd28d5b8381de13abd091db9", "CCE", "", "Plaque Attack (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "de29e46dbea003c3c09c892d668b9413", "Coleco - Woodside Design Associates, Steve 'Jessica Stevens' Kitchen", "4L1717, 4L1718, 4L1719, 4L2277", "Carnival (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "de3d0e37729d85afcb25a8d052a6e236", "Spectravision - Spectravideo", "SA-204", "Tapeworm (1982) (Spectravision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "de4436eaa41e5d7b7609512632b90078", "Activision, David Crane", "AX-014, AX-014-04", "Grand Prix (1982) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "de5aab22e5aba5edcb29a3e7491ff319", "Star Game", "001", "Donkey Kong (Star Game)", "AKA Inca Gold", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "de61a0b171e909a5a4cfcf81d146dbcb", "Rainbow Vision - Suntek", "SS-005", "Tom Boy (1983) (Rainbow Vision) (PAL)", "AKA Pitfall!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "de62f8a30298e2325249fe112ecb5c10", "CCE", "C-810", "Enduro (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "de78b3a064d374390ac0710f95edde92", "Bomb - Onbase", "CA281", "Assault (1983) (Bomb)", "AKA Sky Alien", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "de7a64108074098ba333cc0c70eef18a", "", "", "Nuts (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "de7bca4e569ad9d3fd08ff1395e53d2d", "Thomas Jentzsch", "", "Thrust (V1.22) (2000) (TJ)", "Supports BoosterGrip", "New Release", "", "", "", "", "", "", "", "BOOSTERGRIP", "", "", "", "", "", "", "", "", "" },
-  { "de8443ff47283e7b274a7838cb071fb6", "Atari, Lou Harp", "CX26122", "Sinistar (01-04-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dea0ade296f7093e71185e802b500db8", "CCE", "", "Fishing Derby (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "deb39482e77f984d4ce73be9fd8adabd", "Activision, David Lubar", "AK-048-04", "River Raid II (1988) (Activision) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ded26e1cb17f875a9c17515c900f9933", "", "", "Space Treat (29-12-2002) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "df12953b919844dad2070ed2e70c9fa2", "Amiga - Video Soft", "3135", "S.A.C. Alert (1983) (Amiga) (Prototype) (PAL)", "Uses Joyboard", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "df2745d585238780101df812d00b49f4", "Bit Corporation", "PG202", "Space Tunnel (1982) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "df3e6a9b6927cf59b7afb626f6fd7eea", "", "", "Tuby Bird (208 in 1) (Unknown) (PAL)", "AKA Dolphin", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "df40af244a8d68b492bfba9e97dea4d6", "Franklin Cruz", "", "Asteroids 2 (Franlin Cruz) (Hack)", "Hack of Asteroids", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "df5cc5cccdc140eb7107f5b8adfacda1", "Cracker Jack Productions", "", "Lumberman (Cracker Jack) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "df62a658496ac98a3aa4a6ee5719c251", "Atari, Tom Reuterdahl - Sears", "CX2626 - 6-99829, 49-75116", "Miniature Golf (1979) (Atari)", "AKA Arcade Golf", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "df6a28a89600affe36d94394ef597214", "Apollo - Games by Apollo, Dan Oliver", "AP-2002", "Space Cavern (1982) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "df6a46714960a3e39b57b3c3983801b5", "Puzzy - Bit Corporation", "PG201", "Sea Monster (1982) (Puzzy) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "df753cb87d3af4d03f694ab848638108", "CBS Electronics, Bob Curtiss", "4L1845, 4L1852, 4L1853, 4L1854", "Solar Fox (1983) (CBS Electronics) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "df91277a3569344b89e6e8bd5bebc8d1", "Thomas Jentzsch", "", "Marble Craze - Amiga Mouse Hack v1.0 (PAL) (TJ)", "Uses Amiga Mouse Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "df95e4af466c809619299f49ece92365", "Atari - CCW, Michael Callahan, Preston Stuart", "CX26103", "Alpha Beam with Ernie (06-03-1983) (Atari) (Prototype) (PAL)", "Uses Keypad Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dfad86dd85a11c80259f3ddb6151f48f", "HES - Imagineering, David Lubar", "535", "My Golf (1990) (HES) (PAL) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dfafa3fa58f5cc3f0342cca475df6095", "", "", "Space Treat (V1.1 Beta) (24-12-2002) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dfc03ef371cf5163f54c50d8ee73c8cf", "Atari, Gary Palmer", "CX2661", "Fun with Numbers (1980) (Atari) (4K)", "AKA Basic Math", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dfc3dbbb39f05d7dd8ee3ac987478970", "", "", "Imagic Selector ROM (1982) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dfcdd6f593bb7b05dbc2e8e1fc6ee0de", "", "", "Gunfight 2600 - Scenarios complete (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dfe034297200dff672df9533ed1449a9", "", "", "Sprite Movement Demo 1 (2001) (Roger Williams)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dfe6aa7443bb813cefa35a4cf4887422", "", "", "This Planet Sucks (Greg Troutman) [a1]", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "dff33523ccd2fdc8912e84cab8e0d982", "", "", "Fu Kung! (V0.03) (10-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e01e00504e6d4b88fa743c0bbe8a96e5", "", "", "Qb (Special Edition, some bugfixes) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "e020f612255e266a8a6a9795a4df0c0f", "Telegames - VSS", "7062 A305", "Universal Chaos (1988) (Telegames) (PAL)", "AKA Targ", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e02156294393818ff872d4314fc2f38e", "Sancho - Tang's Electronic Co.", "TEC005", "Dice Puzzle (1983) (Sancho) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "e0221c95aa657f5764eeeb64c8429258", "", "", "Tomb Raider 2600 [REV 02] (Montezuma's Revenge Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e03b0b091bea5bc9d3f14ee0221e714d", "CBS Electronics, Bob Curtiss", "4L1852, 4L1853, 4L1854, 4L1855", "Solar Fox (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e040df95a055b18ebdb094e904cb71b2", "", "", "Score Demo (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e04f1c1e4401d584d3f4343410a5bcc4", "Wizard Video Games - MicroGraphic Image, Robert Barber, Tim Martin", "007", "Halloween (1983) (Wizard Video Games) (Prototype) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e0b24c3f40a46cda52e29835ab7ad660", "Quelle - Otto Versand", "626.502 9 - 746381", "Top Gun (1983) (Quelle) (PAL)", "AKA Air Raiders", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e0cf2dcc4c1348c468f5bb1e421c9164", "", "", "Invader Sprites in a Line Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e0de3773f5b867795db557be7b8a703e", "", "", "Boulderdash (13 Blocks Wide) (02-04-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e0eff071f578ecf19edc2ab276644e46", "", "", "Gas Gauge Demo (2001) (Joe Grand) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e1029676edb3d35b76ca943da7434da8", "Atari, Robert C. Polaro, Alan J. Murphy - Sears", "CX2609 - 49-75186", "Defender (10-30-1981) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e10bf1af6bf3b4a253c5bef6577fe923", "Rob Kudla", "", "Space Invaders (1978) (Atari) [h1]", "Hack of Space Invaders (Atari)", "New Release (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e10d2c785aadb42c06390fae0d92f282", "Parker Brothers, Dawn Stockbridge", "PB5910", "Strawberry Shortcake - Musical Match-Ups (1983) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e1143b72a30d4d3fee385eec38b4aa4d", "", "", "Word Zapper (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e12e32dee68201b6765fcd0ed54d6646", "Atari, Larry Kaplan", "CX2612, CX2612P", "Street Racer (1977) (Atari) (PAL)", "Uses the Paddle Controllers (swapped)", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "AUTO 75", "", "", "", "" },
-  { "e13818a5c0cb2f84dd84368070e9f099", "CCE", "C-839", "Misterious Thief, A (1983) (CCE)", "AKA A Mysterious Thief", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "e13c7627b2e136b9c449d9e8925b4547", "Atari, Alan Miller - Sears", "CX2624 - 6-99826, 49-75113", "Basketball (1978) (Atari) (4K)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e1486c7822c07117b4f94a32e5ed68c1", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (06-14-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e14dc36b24fe22c04fa076e298f2e15f", "Activision, Larry Kaplan, David Crane", "AG-010, AG-010-04", "Kaboom! (1981) (Activision) (16K)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
-  { "e14feddeb82f5160ed5cf9ca4078e58d", "", "", "SpaceMaster X-7 (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e150f0d14f013a104b032305c0ce23ef", "Spectravision - Spectravideo", "SA-205", "China Syndrome (1982) (Spectravision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "e15b5525cf8f77297b322838df8d999c", "", "", "Sprite Demo 0 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e171558c51bb3bac97bfa79fa2c1a19c", "", "", "Warring Worms (Tim Strauss Edition) (20-12-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e17699a54c90f3a56ae4820f779f72c4", "Rainbow Vision - Suntek", "SS-020", "Tuby Bird (1983) (Rainbow Vision) (PAL)", "AKA Dolphin", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e18abe87035379c56b435bfe8175077b", "Grimlock", "", "Rumble 2600 (Grimlock) (Hack)", "Hack of Mario Bros.", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e1a51690792838c5c687da80cd764d78", "20th Century Fox, John Russell", "", "Alligator People (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e1b90f1e01b1a316d7bbf141525cc00e", "", "", "Sky Jinks (Unknown) (PAL) (4K) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e1d5c8213e82820128fa9c4775f1e166", "Jess Ragan", "", "Jungle King (2003) (Jess Ragan) (Hack)", "Hack of Jungle Hunt", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e1d79e4e7c150f3861256c541ec715a1", "", "", "Space Jockey (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e1e09e2f280e8e142121a377d0dc1b46", "Thomas Jentzsch", "", "Thrust (V1.21) (2000) (TJ)", "Bugfixed", "New Release", "", "", "", "", "", "", "", "BOOSTERGRIP", "", "", "", "", "", "", "", "", "" },
-  { "e1efe2ef7664bb6758b1a22ff8ea16a1", "Dynacom", "", "Enduro (1983) (Dynacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e1f88da6da8a7d521ca1dcbf2bc6978b", "Activision, Bob Whitehead - Ariola", "EAG-005, PAG-005, EAG-005-04B - 711 005-715", "Skiing (1980) (Activision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e21ee3541ebd2c23e817ffb449939c37", "Tigervision - Software Electronics Corp., Karl T. Olinger - Teldec", "7-001", "King Kong (1982) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e227be19f572f6900e314213ae9a4deb", "Atari, Dan Hitchens, Mimi Nyden", "CX2656", "SwordQuest - EarthWorld (1982) (Atari) (Prototype)", "AKA Adventure I, SwordQuest I - EarthWorld", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e237ee91514d5ed535c95a14fc608c11", "Activision, Matthew L. Hubbard, Bob Whitehead", "AX-024", "Dolphin (1983) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e2389c0be5b5b84e0d3ca36ec7e67514", "Retroactive", "", "Qb (V2.09) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "e24d7d879281ffec0641e9c3f52e505a", "Parker Brothers, Mark Lesser", "PB5950", "Lord of the Rings (1983) (Parker Bros) (Prototype)", "Journey to Rivendell (The Lord of the Rings I)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e25e173740f7ecc0e23025445c4591f3", "Greg Zumwalt", "", "Comitoid (Greg Zumwalt)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e275cbe7d4e11e62c3bfcfb38fca3d49", "M Network - INTV - APh Technological Consulting, Ken Smith", "MT5658", "Super Challenge Football (1982) (M Network)", "AKA Pro Football", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e27d518993b0a010f16e92b971ecdcdd", "Manuel Polik", "", "Star Fire (2003) (XYPE) (PAL)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e28113d10c0c14cc3b5f430b0d142fcb", "CCE", "C-816", "Keystone Kappers (1983) (CCE) [a]", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e2846af3e4d172b251ab77cbdd01761e", "Steve Engelhardt", "", "Adventure Plus (2003) (Steve Engelhardt) (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e2904748da63dfefc8816652b924b642", "Jone Yuan Telephonic Enterprise Co", "", "Catch Time (Jone Yuan)", "AKA Plaque Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e2b682f6e6d76b35c180c7d847e93b4f", "", "", "Dodge Demo 4 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e2c1b60eaa8eda131632d73e4e0c146b", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692", "Moon Patrol (07-04-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e2c89f270f72cd256ed667507fa038a2", "Starpath Corporation, Stephen H. Landrum", "AR-4101", "Communist Mutants from Space (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e2ca84a2bb63d1a210ebb659929747a9", "Telesys, Don 'Donyo' Ruffcorn", "1002", "Cosmic Creeps (1982) (Telesys) (PAL)", "AKA Space Maze, Spaze Maze", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "e2eccbbe963f80f291cb1f18803bf557", "Atari, Joe Decuir, Steve Mayer, Larry Wagner", "CX26163P", "Combat (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e30f3a37032da52d7815b5a409f6d4b4", "SEGA, Fred Mack", "", "Bear Game Demo (1983) (SEGA)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e314b42761cd13c03def744b4afc7b1b", "Activision, David Crane, Dan Kitchen", "AZ-108-04", "Ghostbusters (1985) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e34c236630c945089fcdef088c4b6e06", "Activision, Steve Cartwright, David Crane - Ariola", "EAB-035-04 - 711 035-721", "Pitfall II (1984) (Activision) (PAL)", "Lost Caverns", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e3533684a7ef930a7fbd0c4dd8ec4847", "CCE", "C-856", "Pimball (1983) (CCE)", "AKA Video Pinball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e3600be9eb98146adafdc12d91323d0f", "Atari, Carol Shaw", "CX2618, CX2618P", "3-D Tic-Tac-Toe (1980) (Atari) (PAL)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e363e467f605537f3777ad33e74e113a", "Atari, Bob Whitehead - Sears", "CX2603 - 99803, 49-75601", "Star Ship (1977) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e377c3af4f54a51b85efe37d4b7029e6", "20th Century Fox Video Games, Beck-Tech, Steve Beck", "11035", "Save the Whales (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e37c8055d70979af354251ebe9f1b7dd", "HES", "", "Mega Funpak - Gorf, P. Patrol, Pacman, Skeet Shoot (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e38dc1f81a02e325562cd285123f579b", "Atari - GCC, Mike Feinstein", "CX2681, CX2681P", "Battlezone (1983) (Atari) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e39843c56b7a4a08b18fa7949ec3ee6b", "", "", "Joshua Invaders (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e39a13b13dc82c5fdbfbbfd55ba1230e", "", "", "Analog Clock (Additional Frame Info) (V0.0) (20-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e3c0451d29dad724231bc5818ec4bae0", "", "", "Single-Scanline Positioning Demo 1 (2001) (Roger Williams)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e3c35eac234537396a865d23bafb1c84", "TechnoVision - Video Technology", "TVS1001", "Nuts (1983) (TechnoVision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e3ed4ba3361756970f076e46e9cad1d2", "", "", "Tennis (Unknown) (PAL) (4K) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e40a818dac4dd851f3b4aafbe2f1e0c1", "Atari, Bill Aspromonte, Dr. Lee Salk", "CX26135", "Peek-A-Boo (1984) (Atari) (Prototype)", "Uses the Keypad Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e42b937c30c617241ca9e01e4510c3f6", "", "", "Pitfall! (No Walls Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e434c0e161dd3c3fb435eb6bad2e182c", "Atari - GCC, Mike Feinstein, Brad Rice", "CX2681", "Battlezone (05-02-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e48d3a4056ede9393586421996db1ae8", "Thomas Jentzsch", "", "Centipede - Atari Trak-Ball Hack v1.4 (PAL60) (Full-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e49ac0ec879a0d7820bc2598fc2cfcd4", "CCE", "", "Kaboom! (CCE) (4K)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
-  { "e4a0b28befaaa2915df1fa01238b1e29", "", "", "Gunfight 2600 - Red River (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e4afe157c09962cf39cdb25845d83d47", "Activision, David Crane - Ariola", "EAG-009, PAG-009 - 711 009-720", "Freeway (1981) (Activision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e4b12deaafd1dbf5ac31afe4b8e9c233", "Adam Thornton", "", "Lord of the Rings (Adam Thornton) (Hack) [a]", "Hack of Dark Mage", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "e4bff1d5df70163c0428a1ead309c22d", "Atari, Robert C. Polaro, Alan J. Murphy", "CX2609, CX2609P", "Defender (1982) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e4c00beb17fdc5881757855f2838c816", "20th Century Fox Video Games - Sirius, Ed Hodapp", "11004", "Deadly Duck (1982) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e4c2077a18e3c27f4819aa7757903aa0", "", "", "Many Blue Bars Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e4c666ca0c36928b95b13d33474dbb44", "Arcadia Corporation, Steve Hales, Stephen H. Landrum", "4 AR-4102", "Suicide Mission (1982) (Arcadia)", "AKA Meteoroids", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "e4d41f2d59a56a9d917038682b8e0b8c", "Cody Pittman", "", "Kiss Meets Pacman (Cody Pittman) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e4e9125a8741977583776729359614e1", "SnailSoft", "", "Comitoid beta 4 (SnailSoft)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e4fa739c81b003c92bea7da5e84c7feb", "Akor", "", "TV Boy (1992) (Akor) (NTSC) [bad dump]", "Includes 127 games", "", "", "", "", "", "", "", "", "JOYSTICK", "JOYSTICK", "", "", "", "", "", "", "", "" },
-  { "e505bd8e59e31aaed20718d47b15c61b", "Funvision - Fund. Int'l Co.", "", "Space War (1982) (Funvision) (PAL)", "AKA Condor Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e51030251e440cffaab1ac63438b44ae", "Parker Brothers - On-Time Software, Joe Gaucher, Louis Marbel", "PB5110", "James Bond 007 (1984) (Parker Bros)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "e51c23389e43ab328ccfb05be7d451da", "Arcadia Corporation, Scott Nelson", "13", "Sweat! - The Decathlon Game (1983) (Arcadia) (Prototype)", "Uses the Paddle Controllers (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e5359cbbbff9c6d7fe8aeff5fb471b46", "CCE", "C-849", "Boom Bang (1983) (CCE)", "AKA Crackpots", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e549f1178e038fa88dc6d657dc441146", "Atari, Bob Whitehead - Sears", "CX2625 - 6-99827, 49-75114", "Football (1979) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e556e07cc06c803f2955986f53ef63ed", "Coleco - Individeo, Ed Temple", "2665", "Front Line (1984) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e558be88eef569f33716e8e330d2f5bc", "Shock Vision", "", "Keystone Kapers (Shock Vision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e56da674188ba2f02c7a0a343a01236f", "", "", "This Planet Sucks Demo 4 (Greg Troutman) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e59d022d524d05acc19515598c831e4d", "Alessandro Ciceri", "", "MagiCard+ (alex_79) WIP_20150118 (PAL)", "MagiCard hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e5a6e0bb7d56e2f08b237e15076e5699", "", "", "Color Table Display Helper (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e5bacf526036d3c8c99db5b030cf00e7", "", "", "Starmaster (Genesis)", "Genesis controller (C switches to map mode)", "Hack of Starmaster", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e5d5085123a98c1e61818caa2971e999", "", "", "Euchre (PAL) (Erik Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e5d72ff8bab4450be57785cc9e83f3c0", "Telegames", "6082 A145", "Kung Fu Superkicks (1988) (Telegames) (PAL)", "AKA Chuck Norris Superkicks", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e5ecd78edd24326a968809decbc7b916", "Imagic, Bob Smith", "720020-1A, IA3611", "Cheese (Dragonfire Beta) (05-21-1982) (Imagic) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "e5f17b3e62a21d0df1ca9aee1aa8c7c5", "CommaVid, John Bronstein", "CM-003", "Cosmic Swarm (1982) (CommaVid)", "AKA Termite", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "e5f360226dc552aba3e7e9b202330f48", "Supercat", "", "Mega Bitmap Demo (2007) (Supercat)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "e5f84930aa468db33c0d0f7b26dd8293", "CCE", "C-826", "Grand Prix (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e5fcc62e1d73706be7b895e887e90f84", "", "", "Air-Sea Battle (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e600f5e98a20fafa47676198efe6834d", "Parker Brothers - Roklan, Joe Gaucher", "PB5080", "Gyruss (1984) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "e609e8a007127b8fcff79ffc380da6b1", "", "", "Multi-Sprite Game V2.3 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e61210293b14c9c4ecc91705072c6a7e", "Gameworld", "133-005", "Bugs (1983) (Gameworld) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 50", "", "", "", "" },
-  { "e62e60a3e6cb5563f72982fcd83de25a", "Jone Yuan Telephonic Enterprise Co", "", "End of the World (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e63a87c231ee9a506f9599aa4ef7dfb9", "Tigervision, Warren Schwader", "7-003", "Threshold (1982) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e63efdfda9a4003dcd77a854a781a06a", "Paul Slocum", "", "Combat Rock (PD) (Hack) [a]", "Hack of Combat", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e643aaec9a9e1c8ab7fe1eae90bc77d7", "Roger Williams", "", "Asymmetric Playfield (Roger Williams)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e64a8008812327853877a37befeb6465", "Answer Software Corporation - TY Associates, Mike Wentz", "ASC1002", "Gauntlet (1983) (Answer Software)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e6508b878145187b87b9cded097293e7", "", "", "Oystron (V2.8) (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e66e5af5dea661d58420088368e4ef0d", "Activision, Bob Whitehead", "AG-011", "Stampede (1981) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e67b0ed32fd9d28d12ab3775d52e8c3a", "Atari, Omegamatrix", "", "Video Olympics Menu (2020) (Hack)", "Hack of Video Olympics", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "AUTO 60", "", "", "", "" },
-  { "e6d5948f451a24994dfaaca51dfdb4e1", "Jone Yuan Telephonic Enterprise Co", "", "Football (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e6de4ef9ab62e2196962aa6b0dedac59", "Imagic, Wilfredo Aguilar, Michael Becker, Dennis Koble", "720113-2A, 13206", "Solar Storm (1983) (Imagic) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 45", "", "", "", "" },
-  { "e6e5bb0e4f4350da573023256268313d", "Thomas Jentzsch", "", "Missile Control (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e6f49a1053c79211f82be4d90dc9fe3d", "", "", "Gunfight 2600 - Little progress... (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e723ad8f406cb258b89681ef4cef0eff", "Thomas Jentzsch", "", "Sadoom (TJ) (PAL) (Hack)", "Hack of Kaboom!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
-  { "e72eb8d4410152bdcb69e7fba327b420", "Atari, Douglas Neubauer, Mimi Nyden", "CX26136", "Solaris (1986) (Atari)", "AKA Universe, Star Raiders II, The Last Starfighter", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e72ee2d6e501f07ec5e8a0efbe520bee", "Imagic, Dave Johnson", "720119-2A, 13211, EIX-004-04I", "Quick Step! (1983) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e73838c43040bcbc83e4204a3e72eef4", "CCE", "", "Apples and Dolls (CCE)", "AKA Open, Sesame!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "e74022cfe31ec8908844718dfbdedf7a", "", "", "Space Treat (30-12-2002) (Fabrizio Zavagli) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e77ec259e1387bc308b0534647a89198", "Parker Brothers, David Lamkins, Laura Nikolich", "931503", "Spider-Man (1982) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e77f332b71f13884c84771e7a121182d", "Jone Yuan Telephonic Enterprise Co", "", "Hey! Stop! (Jone Yuan)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e784a9d26707cfcd170a4c1c60422a72", "Quelle", "147.443 6", "Gefecht im All (1983) (Quelle) (PAL)", "AKA Space Jockey", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e7864caaf9ec49ed67b1904ce8602690", "", "", "Donkey Kong 2K3 Pic (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e7a758bb0b43d0f7004e92b9abf4bc83", "", "", "Troll's Adventure (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e7dd8c2e6c100044002c1086d02b366e", "Activision, Steve Cartwright - Ariola", "EAX-013, PAX-013, 711 013-720", "Barnstorming (1982) (Activision) (PAL)", "AKA Die tollkeuhnen Flieger", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e7f005ddb6902c648de098511f6ae2e5", "Spectravideo - Universum", "SV-010", "CompuMate (1983) (Spectravideo) (PAL)", "", "", "", "", "CM", "", "", "", "", "COMPUMATE", "COMPUMATE", "", "", "", "", "", "", "YES", "80" },
-  { "e800e4aec7c6c54c9cf3db0d1d030058", "", "", "Qb (2.06) (Retroactive) (Stella)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "e80a4026d29777c3c7993fbfaee8920f", "", "", "Frisco (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e823b13751e4388f1f2a375d3560a8d7", "Arcadia Corporation, Stephen Harland Landrum", "AR-4105", "Official Frogger (Preview) (1983) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e879b7093ac4cfad74c88d636ca97d00", "", "", "Poker Squares (V0.0f) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e88340f5bd2f03e2e9ce5ecfa9c644f5", "", "", "Lock 'n' Chase (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e8a3473bf786cf796d1336d2d03a0008", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (12-05-1983) (Parker Bros) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "e8aa36e3d49e9bfa654c25dcc19c74e6", "Atari, Joe Decuir, Larry Caplan, Steve Mayer, Larry Wagner", "CX2601, CX2601P", "Combat (1977) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e8e7b9bdf4bf04930c2bcaa0278ee637", "", "", "Boring Taz (Hack)", "Hack of Taz", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e8f7679359c4f532f5d5e93af7d8a985", "", "", "Hangman Invader Original Words (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e9034b41741dcee64ab6605aba9de455", "Digivision", "", "Phanton Tank (Digivision)", "AKA Phantom Tank", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e908611d99890733be31733a979c62d8", "Atari, Dan Hitchens, Mimi Nyden", "CX2697", "Mario Bros. (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e91d2ecf8803ae52b55bbf105af04d4b", "Atari, Howard Scott Warshaw", "CX2655, CX2655P", "Yars' Revenge (1982) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "e923001015bedd7901569f035d9c592c", "", "", "Adventure II (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e927ecf80f3784d745abd8368d78f2f3", "", "", "Space Instigators (V1.8) (19-10-2002) (CT) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e932f44fad2a66b6d5faec9addec208e", "", "", "Atari Logo Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e94632b0d863dd76459d689a9865bb33", "Jone Yuan Telephonic Enterprise Co", "", "Combat (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e957eb4612d6bd5940d3492dfa749668", "", "", "Tunnel Demo (27-03-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e959b5a2c882ccaacb43c32790957c2d", "", "", "Phantom II & Pirate (NTSC)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e97eafd0635651d3999cece953c06bd5", "", "", "M.A.S.H (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e9be3e8e4a7e73dd63ed4235a3a1a25f", "", "", "MMetall (Hack)", "Hack of Miniature Golf", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e9c5d04643855949a23ff29349af74ea", "", "", "SCSIcide (Score Hack 2) (24-02-2001) (Joe Grand) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e9c71f8cdba6037521c9a3c70819d171", "Action Hi Tech - Hi-Score", "", "Bank Heist (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e9cb18770a41a16de63b124c1e8bd493", "Parker Brothers - Roklan, Joe Gaucher", "931519", "Popeye (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "e9db2f91efe6ff7ea3546e2c2578fb09", "Omegamatrix", "", "Millipede (Atari Mouse) v6.5 (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "PAL60", "", "", "" },
-  { "e9e646f730b8400cd5da08c849ef3e3b", "Tron", "", "Enduro (Tron)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e9e6ad30549a6e2cd89fe93b7691d447", "Atari - Bobco, Robert C. Polaro", "CX26140, CX26140P", "Desert Falcon (05-27-1987) (Atari) (Prototype) (PAL)", "AKA Nile Flyer, Sphinx", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "e9f25c7af4f27c9e1b5b8f6fe6141e8c", "Champ Games", "CG-03-N", "Scramble (NTSC)", "Compatible with Genesis controller", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "YES", "" },
-  { "ea38fcfc06ad87a0aed1a3d1588744e4", "Atari, Lou Harp", "CX26122", "Sinistar (01-XX-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ea6d40db5498d6386571a76df448aa4c", "", "", "Vertical Playfield Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ea7e25ade3fe68f5b786ee0aa82b1fe5", "", "", "Galatic (208 in 1) (Unknown) (PAL)", "AKA Challenge of.... Nexar, The", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ea832e2cb6aae6f525f07452c381fa48", "", "", "Polar to Cartesian and VV (2001) (Roger Williams)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ea86176b27ab0da8cce8f0179884bfaa", "", "", "Demo Image Series #10 - It's Art (28-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "eaacfcdc1d4ee1258429b7ae7f084125", "Telegames", "6057 A227", "Quest for Quintana Roo (1989) (Telegames)", "Genesis controller (B is action button, C chooses tool or weapon)", "Hack of Quest for Quintana Roo", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ead60451c28635b55ca8fea198444e16", "Sancho - Tang's Electronic Co.", "TEC004", "Nightmare (1983) (Sancho) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "eada0dd61ce13f8317de774dc1e68604", "", "", "2600 Digital Clock (Demo 1) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "eae0c06ee61c63b81cd016096fc901b0", "Joe Grand", "", "SCSIcide (v1.0) (2001) (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "eae6a5510055341d3abeb45667bb3e9b", "HES", "", "Wall Defender (HES) (PAL)", "AKA Wall Break (Planet Patrol if right difficulty = 'A')", "", "", "0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "eaf744185d5e8def899950ba7c6e7bb5", "Atari", "CX26172", "Xenophobe (1991) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "eafe8b40313a65792e88ff9f2fe2655c", "Eric Ball", "ELB004", "Skeleton+ (NTSC)", "Stereo sound", "Homebrew", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "eb3d680699f8762f71f38e28e321234d", "", "", "Fu Kung! (V0.01) (08-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "eb4252faff7a4f2ba5284a98b8f78d1a", "", "", "John K Harvey's Equalizer (NTSC) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "eb46e99ec15858f8cd8c91cef384ce09", "Goliath - Hot Shot", "83-113", "Ground Zero (1983) (Goliath) (PAL)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "eb503cc64c3560cd78b7051188b7ba56", "Star Game", "043", "Moto Laser (Star Game)", "AKA Mega Force", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "eb634650c3912132092b7aee540bbce3", "Atari, Eric Manghise, Mimi Nyden, Joseph Tung", "CX2640", "RealSports Baseball (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "eb6d6e22a16f30687ade526d7a6f05c5", "Atari", "CX26150P", "Q-bert (1987) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "eb71743c6c7ccce5b108fad70a326ad9", "", "", "Euchre (25-11-2001) (Erik Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "eb7934360658a29c50aeaff20bfda23b", "Activision, John Van Ryzin", "EAZ-036-04", "H.E.R.O. (1984) (Activision) (SECAM)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "eb92193f06b645df0b2a15d077ce435f", "Starpath Corporation, Steve Hales, Stephen H. Landrum", "4 AR-4102", "Suicide Mission (1982) (Starpath) (PAL)", "AKA Meteoroids", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "eb9712e423b57f0b07ccd315bb9abf61", "Retroactive", "", "Qb (V2.04) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "eb9f8b84c193d9d93a58fca112aa39ed", "", "", "Register Twiddler Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ebcb084a91d41865b2c1915779001ca7", "JVP", "", "Bob Is Going Home (JVP)", "AKA Bobby Is Going Home", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ebcbc8a181a738e13df6216e5c329230", "Activision, Steve Cartwright", "AX-022", "Seaquest (1983) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ebd2488dcace40474c1a78fa53ebfadf", "Skill Screen Games, Herman Quast", "SSG001", "Extra Terrestrials (1984) (SSG)", "The only Canadian-designed and manufactured Atari 2600 game from the 1980's", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ebdc5716b85c4ff44fa357cb697d6cef", "Thomas Jentzsch", "", "Centipede - Amiga Mouse Hack v1.4 (NTSC) (Half-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ebf2dff78a08733251bf3838f02f7938", "Commavid, Ben Burch", "CM-010", "Rush Hour (1983) (Commavid) (Prototype) [a2]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ebf9038e927e6a0db3e0d170c59911e6", "", "", "Pac-2600 (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ec3beb6d8b5689e867bafb5d5f507491", "U.S. Games Corporation - Vidtec - JWDA, Todd Marshall, Henry Will IV", "VC1003", "Word Zapper (1982) (U.S. Games)", "AKA Word Grabber", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ec407a206b718a0a9f69b03e920a0185", "Quelle", "876.482 1", "Landung in der Normandie (1983) (Quelle) (PAL)", "AKA Commando Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ec5c861b487a5075876ab01155e74c6c", "Apollo - Games by Apollo, Ed Salvo, Byron Parks", "AP-2001", "Spacechase (1982) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ece463abde92e8b89bcd867ec71751b8", "Puzzy - Bit Corporation", "PG205", "Dancing Plate (1982) (Puzzy) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "ece908d77ab944f7bac84322b9973549", "", "", "Tom Boy (Unknown) (PAL60)", "AKA Pitfall!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ecf51385384b468834611d44a8429c03", "20th Century Fox Video Games, Douglas 'Dallas North' Neubauer", "11105", "Mega Force (1982) (20th Century Fox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ecfa04523dde82fe42cdc7315a8f61b6", "Activision, David Crane - Ariola", "EAG-004, PAG-004 - 711 004-715", "Fishing Derby (1980) (Activision) (PAL) (4K)", "AKA Schneller als der Hai", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ed014beeeb77dbb2bbcf9b5f6850b2f4", "", "", "Green Bar Text Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ed0451010d022b96a464febcba70b9c4", "PlayAround - J.H.M.", "203", "Knight on the Town (1982) (PlayAround) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "ed0ab909cf7b30aff6fc28c3a4660b8e", "Panda", "105", "Stunt Man (1983) (Panda)", "AKA Nightmare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ed1306436ce237afc5a7ed3f77134202", "HES", "771-341", "2 Pak Special - Dolphin, Pigs n' Wolf (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ed1492d4cafd7ebf064f0c933249f5b0", "CCE", "", "Video Cube (CCE)", "AKA Atari Video Cube", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ed1a784875538c7871d035b7a98c2433", "Bit Corporation", "R320", "Save Our Ship (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ed2218b3075d15eaa34e3356025ccca3", "Atari, Richard Maurer", "CX2635, CX2635P", "Maze Craze (1980) (Atari) (PAL)", "AKA A Game of Cops 'n Robbers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ed5ccfc93ad4561075436ee42a15438a", "Atari, Tom Reuterdahl", "CX2626, CX2626P", "Miniature Golf (1979) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ed8f319e82d355832195eb7715644795", "Activision, Larry Kaplan, David Crane", "AG-010, AG-010-04", "Kaboom! (1981) (Activision) (8K)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
-  { "eddef10fdc0029301064115ae0cd41d4", "CCE", "", "Freeway (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ede4ab11ca346bd023b2c21d941e0c50", "Activision, David Crane", "EAZ-030", "Decathlon (1983) (Activision) (SECAM)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ede7e8bf865b0afb4744f86d13624f9a", "", "", "Demo Image Series #2 - Clown (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "edf69b123e06eaf8663cc78d8aeba06e", "SpkSoft 98", "", "River Raid (SpkSoft 98) [h1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ee28424af389a7f3672182009472500c", "Atari, Carol Shaw - Ralph Lauren", "", "Polo (1978) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ee456542b93fa8d7e6a8c689b5a0413c", "", "", "Chronocolor Donkey Kong Clean (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ee4c186123d31a279ed7a84d3578df23", "Atari, Carol Shaw, Nick 'Sandy Maiwald' Turner", "CX2608", "Super Breakout (1982 - 1981) (Atari) (PAL)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 45", "", "", "", "" },
-  { "ee659ae50e9df886ac4f8d7ad10d046a", "Exus Corporation", "", "Video Reflex (1983) (Exus)", "AKA Foot Craz", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ee6665683ebdb539e89ba620981cb0f6", "Coleco", "2658", "Berenstain Bears (1983) (Coleco)", "Uses the KidVid Controller", "Unbelievably Rare", "", "", "", "A", "", "", "", "", "KIDVID", "", "", "", "", "", "", "", "" },
-  { "ee67dc0b01746372d2b983d88f48e24f", "", "", "Scroller Demo (02-01-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ee681f566aad6c07c61bbbfc66d74a27", "Activision", "", "Unknown Activision Game (10-29-1982) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ee6cbedf6c0aac90faa0a8dbc093ffbe", "CCE", "", "My Golf (CCE) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ee8027d554d14c8d0b86f94737d2fdcc", "Canal 3 - Intellivision", "", "Yars' Revenge (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "ee84bdc5dae268e227e407c7b5e6b6b7", "", "", "Marilyn Monroe Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ee9caee4eb958284fb10c277b14537f1", "Carrere Video, Garry Kitchen - Teldec", "USC1001", "Space Jockey (1983) (Carrere Video) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "eea0da9b987d661264cce69a7c13c3bd", "Coleco", "2454", "Zaxxon (1983) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "eeb92f3f46df841487d1504f2896d61a", "Cody Pittman", "", "Corys Adventure (Cody Pittman) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "eec61cc4250df70939d48fe02d7122ac", "Activision, Bob Whitehead - Ariola", "EAG-005, PAG-005, EAG-005-04B - 711 005-715", "Skiing (1980) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "eed9eaf1a0b6a2b9bc4c8032cb43e3fb", "Atari - Axlon, Steve DeFrisco", "CX26192", "Klax (1991) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "eee7695ae3eea7818321df0b790b31f3", "", "", "Sound Paddle V2 (Dennis Caswell & Jim Nitchals) (PD)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "01", "", "", "", "" },
-  { "ef263d40a23483ab339cac44d9515a56", "Thomas Jentzsch", "", "Fatal Run (TJ)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ef3a4f64b6494ba770862768caf04b86", "Activision, Bob Whitehead", "AG-034-04", "Private Eye (1984) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ef60b06fddb675b0d783afbfa5fc5232", "", "", "Many Blue Bars and Text Demo 4 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ef66af190840871409fe1702d2483554", "Andrew Davie, Paul Slocum, Christopher Tumber", "", "DiscoTech (12-02-2003) (Andrew Davie)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ef71e9fb0d8d477226d8d42261fbf0a7", "Piero Cavina", "", "Multi-Sprite Demo V2.0 (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ef76ea05655a0b62cb1018c92b9b4b7d", "Gakken", "010", "Strategy X (1983) (Gakken) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "efa1098c7d091b940c2543abe372f036", "Scott Stilphen", "", "E.T. The Extra-Terrestrial (Scott Stilphen) (Hack)", "Hack of E.T. The Extra-Terrestrial", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "efb47d70b2965ce689e2c5757616b286", "", "", "Time Test Demo (Eckhard Stolberg) (PAL) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "efd387430a35a659ff569a9a0ec22209", "Atari - GCC", "CX26118", "Millipede (1984) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "efefc02bbc5258815457f7a5b8d8750a", "CBS Electronics, Richard K. Balaska Jr.", "4L 2520 5000", "Tunnel Runner (1983) (CBS Electronics) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "effa3a7ce078c6d83bf43174a7bfdb1f", "Thomas Jentzsch", "", "Centipede - Atari Mouse Hack v1.4 (NTSC) (Half-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "efffafc17b7cb01b9ca35324aa767364", "", "", "Circus Atari (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f02ba8b5292bf3017d10553c9b7b2861", "Atari", "CX26172", "Xenophobe (1991) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f032b2f2d8323404a6b4541f92dd1825", "", "", "Many Blue Bars and Text Demo 3 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f047df70d3d08e331122cd2de61d6af8", "Dave Neuman", "", "Space Battle (NTSC)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f04ee80011d95798006378643650aaa7", "Atari, Bill Aspromonte, John Russell, Michael Sierchio, Robert Zdybel", "CX26114", "Pigs in Space (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f0510abbfbe24ead552e92e3841f63f3", "Thomas Jentzsch", "", "Reactor - Atari Mouse Hack v1.3 (NTSC) (Full-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f0536303f49006806bac3aec15738336", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (4 of 4) (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f0541d2f7cda5ec7bab6d62b6128b823", "Atari, Paul Donaldson", "", "Bionic Breakthrough (1984) (Atari) (Prototype)", "Uses Mindlink Controller (left only)", "Prototype", "", "", "", "", "", "", "", "MINDLINK", "", "", "", "", "", "", "", "", "" },
-  { "f060826626aac9e0d8cda0282f4b7fc3", "Atari, David Crane - Sears", "CX2605 - 6-99822, 49-75109", "Outlaw (1978) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f0631c6675033428238408885d7e4fde", "Paul Slocum", "", "Test Cart (2002) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "f066bea7ab0a37b83c83c924a87c5b67", "", "", "Air Raiders (1982) (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f0a6e99f5875891246c3dbecbf2d2cea", "Atari, James Andreasen - Sears", "CX2654 - 49-75141", "Haunted House (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f0b7db930ca0e548c41a97160b9f6275", "Atari, Larry Wagner, Bob Whitehead - Sears", "CX2645 - 49-75181", "Video Chess (1979) (Atari)", "AKA Computer Chess", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f0cacae1d1b79ee92f0dc035f42e0560", "", "", "Boring Donkey Kong (Hack)", "Hack of Donkey Kong", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f0d393dbf4164a688b2346770c9bbd12", "", "", "Racquetball (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "f0daaa966199ef2b49403e9a29d12c50", "", "", "Mr. Postman (Unknown)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f0de4f49e95d529569e8788d5a7b4d30", "Thomas Jentzsch", "", "Reactor - Atari Mouse Hack v1.3 (PAL60) (Full-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f0e0addc07971561ab80d9abe1b8d333", "Imagic, Rob Fulop", "720000-200, 720101-1B, 720101-1C, IA3200, IA3200C, IX-006-04", "Demon Attack (1982) (Imagic)", "AKA Death from Above", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f0ef9a1e5d4027a157636d7f19952bb5", "Atari - Axlon, Tod Frye - Heuristica, Agustin Ortiz", "CX26169", "Shooting Arcade (03-07-1989) (Atari) (Prototype) [a5]", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f10e3f45fb01416c87e5835ab270b53a", "Suntek", "SS-024", "Ski Run (1983) (Suntek) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f1127ade54037236e75a133b1dfc389d", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (Preview) (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f11cfab087fcbd930ab8b0becc5b2e5a", "Canal 3 - Intellivision", "", "River Raid (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f12afbffa080dd3b2801dd14d4837cf6", "Atari, Michael Kosaka, Peter C. Niday, Robert Vieira", "CX26110", "Crystal Castles (01-04-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "f137211537438b1fce3d811baef25457", "", "", "Incoming (02-10-2002) (Ben Larson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f1489e27a4539a0c6c8529262f9f7e18", "Champ Games", "CG-01-P", "Lady Bug (PAL60)", "", "Homebrew", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "f14d5e96ec3380aef57a4b70132c6677", "Goliath - Hot Shot", "83-414", "Pac Kong (1983) (Goliath) (PAL)", "AKA Inca Gold", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f1554569321dc933c87981cf5c239c43", "Atari - Glenn Axworthy", "CX26129", "Midnight Magic (1986) (Atari)", "AKA Pinball Wizard", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "f16c709df0a6c52f47ff52b9d95b7d8d", "Atari, Alan Miller - Sears", "CX2662 - 6-99811", "Hangman (1978) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f16ef574d2042ed8fe877d6541f4dba4", "Spectravision - Spectravideo", "SA-201", "Gangster Alley (1982) (Spectravision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f1929bb9b5db22d98dd992aa3fe72920", "", "", "Cube Conquest (Improved Interlace) (Billy Eno) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "f19aba18f86e415812480ad2be221425", "Chris Larkin", "", "Solaris Trainer (2002) (Chris Larkin) (Hack)", "Hack of Solaris", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f1a0a23e6464d954e3a9579c4ccd01c8", "20th Century Fox, Douglas 'Dallas North' Neubauer", "11006", "Alien (1982) (20th Century Fox)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "f1ae6305fa33a948e36deb0ef12af852", "Andreas Dietrich", "", "Donkey Kong VCS (2017) (1.0)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "f1b2ea568b3e156e3f2849dac83591f6", "", "", "Sprite Demo (1997) (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f1b7edff81ceef5af7ae1fa76c8590fc", "Atari, Richard Maurer", "CX2632, CX2632P", "Space Invaders (1980) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f1beca5a198cf08190487e5c27b8e540", "", "", "Fu Kung! (V0.16) (2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f1e375d921858467166e53bcec05803f", "Jeffry Johnston", "", "Radial Pong - Version 3 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f1eeeccc4bba6999345a2575ae96508e", "Video Gems", "VG-03", "Steeplechase (1983) (Video Gems) (PAL)", "", "", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "f1fe06ebe2900eac4cdd17799389a102", "Atari, Jim Huether", "CX26163P", "Sky Diver (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f20675c8b98518367b9f5b8ee6f7c8ea", "Atari", "CX26163P", "Stampede (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f20bd756f3990e06c492f53cd0168e68", "", "", "Skeleton+ (03-05-2003) (Eric Ball) (NTSC)", "", "", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f21813aa050437f0dbc8479864acec6d", "", "", "Sneak 'n Peek (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f23d19b73dac50cc6149316912b8ee53", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Amiga Mouse Hack v1.1 (PAL) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f240ba9f8092d2e8a4c7d82c554bf509", "Quelle", "463.860 7", "Strahlen der Teufelsvoegel (1983) (Quelle) (PAL)", "AKA Atlantis", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f280976d69d6e27a48506bd6bad11dcd", "Atari, Larry Kaplan", "CX2664, CX2664P", "Brain Games (1978) (Atari) (PAL)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "KEYBOARD", "KEYBOARD", "", "", "", "", "", "", "", "" },
-  { "f283cc294ece520c2badf9da20cfc025", "Atari - CCW, Christopher H. Omarzu", "CX26104", "Big Bird's Egg Catch (1983) (Atari) (PAL)", "Uses Kids/Keypad Controllers", "Rare", "", "", "", "", "", "", "", "KEYBOARD", "KEYBOARD", "", "", "", "", "", "", "", "" },
-  { "f28c07767b3e90a2689ade5b5e305874", "Canal 3 - Intellivision", "C 3014", "Keystone Kapers (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f2d40c70cf3e1d03bc112796315888d9", "Atari - CCW, Michael Callahan, Preston Stuart", "CX26103", "Alpha Beam with Ernie (1983) (Atari) (PAL)", "Uses Keypad Controllers", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f2d4d6187903cac2d5ea8ed90dad120d", "Digimax", "", "River Raid II (Digimax)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f2e4fb2d3600c0f76d05864e658cc57b", "", "", "Marble Craze (Kernel) (17-02-2002) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f2f2cb35fdef063c966c1f5481050ea2", "", "", "Ram It (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f2f59629d7341c97644405daeac08845", "Jone Yuan Telephonic Enterprise Co", "", "Bobby Is Going Home (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f303630a2d7316787aecd67fff6b2e33", "AtariAge - Fred Quimby", "", "Gingerbread Man (Fred Quimby)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f3213a8a702b0646d2eaf9ee0722b51c", "Atari, Carol Shaw - Sears", "CX2618 - 49-75123", "3-D Tic-Tac-Toe (1980) (Atari) (4K)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f33f1d0f7819c74148dacb48cbf1c597", "Retroactive", "", "Qb (2.00) (Retroactive) (Stella)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "f344ac1279152157d63e64aa39479599", "Tigervision", "7-012", "Espial (1984) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f34dd3b8156aaf113cb621b2e51d90b8", "Joe Grand", "", "SCSIcide Pre-release 5 (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f34f08e5eb96e500e851a80be3277a56", "Atari, Brad Stewart - Sears", "CX2622 - 6-99813, 49-75107", "Breakout (1978) (Atari)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 60", "", "", "", "" },
-  { "f367e58667a30e7482175809e3cec4d4", "ZiMAG - Emag - Vidco", "708-111 - GN-040", "Cosmic Corridor (1983) (ZiMAG)", "AKA Space Tunnel", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f38358cd8f5ecfedffd5aca1aa939f18", "Universal Gamex Corporation, Alan Roberts", "1005", "X-Man (1983) (Universal) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f39e4bc99845edd8621b0f3c7b8c4fd9", "AtariAge", "", "Toyshop Trouble (AtariAge)", "F8 Emulator Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f3c431930e035a457fe370ed4d230659", "", "", "Crackpots (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f3cd0f886201d1376f3abab2df53b1b9", "Commavid, Ben Burch", "CM-010", "Rush Hour (1983) (Commavid) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f3dfae774f3bd005a026e29894db40d3", "Otto Versand", "649635", "See Saw (Double-Game Package) (1983) (Otto Versand) (PAL)", "AKA Circus Atari", "", "", "", "", "", "", "", "", "JOYSTICK", "JOYSTICK", "", "", "", "", "", "", "", "" },
-  { "f3f5f72bfdd67f3d0e45d097e11b8091", "Sears Tele-Games, Marilyn Churchill, Matthew L. Hubbard", "CX2647 - 49-75142", "Submarine Commander (1982) (Sears)", "AKA Seawolf 3", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f3f92aad3a335f0a1ead24a0214ff446", "", "", "Spectrum Color Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f40e437a9ebf0bdfe26204152f74f868", "Bit Corporation", "R320", "Jawbreaker (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f4204fc92d17ed4cb567c40361ad58f1", "Inky", "", "Beanie Baby Bash (Inky) (Hack)", "Hack of Beany Bopper", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f4469178cd8998cb437fa110a228eaca", "Digitel", "", "Frostbite (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f45644ff82b533a781a1ee50f2e95f3c", "", "", "Overhead Adventure Demo 6 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f457674cef449cfd85f21db2b4f631a7", "U.S. Games Corporation - JWDA, Todd Marshall, Wes Trager, Henry Will IV", "VC1004", "Commando Raid (1982) (U.S. Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f473f99e47d4026a7a571184922ebf04", "Philip R. Frey", "", "Donkey Claus (Philip R. Frey) (Hack)", "Hack of Donkey Kong", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f48022230bb774a7f22184b48a3385af", "Atari, Rob Fulop - Sears", "CX2633 - 49-75119", "Night Driver (1980) (Atari) (4K)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "YES", "" },
-  { "f48735115ec302ba8bb2d2f3a442e814", "", "", "Dancing Plate (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "f49a34f1fdd7dc147cbf96ce2ce71b76", "", "", "Qb (Special Edition) (PAL) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "f4a09f906cc37be31224433f576d77d3", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Trak-Ball Hack v1.2 (PAL) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f4ab6bd5f80d8988141edde4c84b23b5", "Atari, Alan Miller", "CX2624, CX2624P", "Basketball (1978) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f4b8a47a95b61895e671c3ec86ffd461", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (01-03-1984) (Parker Bros) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "f4c2e50b01dff99bddbe037b3489511c", "", "", "Hypnotic (V0.04) (2001) (Inkling) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f4c6621f1a0b4d27081123c08d7d1497", "CCE", "C-838", "Immies & Aggies (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f4cf6881b65c424095dc25dc987f151f", "", "", "128 in 1 Game Select ROM (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f4dabd5bcc603e8464a478208037d423", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (08-21-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f526d0c519f5001adb1fc7948bfbb3ce", "Mythicon, Bill Bryner, Bruce de Graaf", "MA1003", "Star Fox (1983) (Mythicon)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f52f40299fd238c6ffd9e6107050dc76", "Activision, Bob Whitehead - Ariola", "EAG-011, PAG-011 - 711 011-715", "Stampede (1981) (Activision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f539e32bf6ce39c8ca47cb0cdd2c5cb8", "Control Video Corporation", "", "GameLine Master Module ROM (1983) (Control Video)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f542b5d0193a3959b54f3c4c803ba242", "Atari, Tom Rudadahl - Sears", "CX2634 - 49-75121", "Golf (1980) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f5445b52999e229e3789c39e7ee99947", "Atari, Jim Huether", "CX26163P", "Flag Capture (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f5a2f6efa33a3e5541bc680e9dc31d5b", "Suntek", "SS-022", "Motocross (1983) (Suntek) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f5a3e051730d45fea518f2e8b926565b", "Robby", "", "Keystone Kapers (Robby)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f5aa6bd10f662199c42e43863a30106c", "", "", "Music Kit (V1.0) - Song Player (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "f5d103a9ae36d1d4ee7eef657b75d2b3", "Starpath Corporation, Stephen H. Landrum", "9 AR-4105", "Official Frogger, The (Preview) (1983) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f613aad84d2163d6b197b220bfec1b7e", "", "", "X-Doom V.27 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f661f129644f338b13d9f4510d816c03", "Atari, David Crane", "CX26163P", "Outlaw (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f6676e3fe901eb8515fc7ae310302c3c", "Activision, David Crane", "AG-008", "Laser Blast (1981) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f67181b3a01b9c9159840b15449b87b0", "Atari, Nick 'Sandy Maiwald' Turner", "CX2665", "Frog Pond (08-27-1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f687ec4b69611a7f78bd69b8a567937a", "Activision, Alan Miller - Ariola", "EAZ-028 - 711 028-725", "Robot Tank (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f69a39b215852a0c2764d2a923c1e463", "", "", "Move a Blue Blob Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f69bb58b815a6bdca548fa4d5e0d5a75", "Atari, Larry Kaplan", "CX26163P", "Bowling (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f69d4fcf76942fcd9bdf3fd8fde790fb", "CCE", "", "Aquaventure (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f6a282374441012b01714e19699fc62a", "ZiMAG - Emag - Vidco", "710-111 - GN-010", "I Want My Mommy (1983) (ZiMAG)", "AKA Open, Sesame!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "f6a9ea814d15b85bffe980c927df606b", "", "", "Missile Command (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "f6b5ebb65cbb2981af4d546c470629d7", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (09-13-1984) (Coleco) (Prototype) [a]", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f6c13e816e58c8c62f82b2c8b91a2d67", "", "", "Scrolling Playfield 2 (Junkosoft) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f6d512bef1bf253dc935d0e13c3d1462", "", "", "Slot Racers (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f6daebc0424fa0f8d9aaf26c86df50f4", "Brian Watson", "", "Color Tweaker (V1.0) (2001) (B. Watson)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f6efa00ae99aaf33e427b674bcfd834d", "", "", "2600 Digital Clock (Demo 3) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f6f1b27efc247a0e8d473ddb4269ff9e", "Rainbow Vision - Suntek", "SS-015", "Catch Time (1983) (Rainbow Vision) (PAL)", "AKA Plaque Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f70e3f3bb2d19ec2aaec8f78dc43744f", "Jone Yuan Telephonic Enterprise Co", "", "Pooyan (Jone Yuan) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f714a223954c28eccf459295517dcae6", "", "", "Big - Move This Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f7154add27b95cd90464dbed8cfd7557", "Fabrizio Zavagli", "", "Space Treat Deluxe (2003) (PAL)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f724d3dd2471ed4cf5f191dbb724b69f", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX2659", "Raiders of the Lost Ark (1982) (Atari)", "Console ports are swapped", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "" },
-  { "f736864442164b29235e8872013180cd", "Telegames - VSS", "6057 A227", "Quest for Quintana Roo (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f73d2d0eff548e8fc66996f27acf2b4b", "CCE", "C-813", "Pitfall (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f7424985bac41067502b4a05b64cb75a", "Activision, Steve Cartwright", "AX-027", "Plaque Attack (1983) (Activision)", "Genesis controller (B is fire up, C is fire down)", "Hack of Plaque Attack", "", "", "", "", "", "", "", "GENESIS", "", "", "", "", "", "", "", "", "" },
-  { "f74ad642552385c3daa203a2a6fc2291", "Eckhard Stolberg", "", "Cubis (1997) (Eckhard Stolberg)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f750b5d613796963acecab1690f554ae", "Manuel Polik", "", "Gunfight 2600 (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f75872946e82ad74d48eae5bc28f5f0e", "Sears Tele-Games, Jim Huether", "CX2614 - 49-75126", "Steeplechase (04-15-1980) (Sears) (Prototype)", "Uses the Paddle Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f777444fc21a5925e066b68b1d350575", "", "", "Marble Craze (Kernel Works) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f77f5fc3893da5d00198e4cd96544aad", "Canal 3 - Intellivision", "", "Stampede (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f7856e324bc56f45b9c8e6ff062ec033", "Atari, Jerome Domurat, Michael Sierchio", "CX2667", "RealSports Soccer (1983) (Atari) [no opening tune]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "f78c125b5da483c41e51522947d6c4ce", "", "", "Sound Paddle V1 (Dennis Caswell & Jim Nitchals) (PD)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "01", "", "", "", "" },
-  { "f7a138eed69665b5cd1bfa796a550b01", "Tigervision - Teldec", "7-012 - 3.60016 VC", "Espial (1984) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f7a651972d78f9ba485b14690452d4be", "Paul Slocum", "", "Homestar Runner Demo #2 (2004-03-29)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "f7af41a87533524d9a478575b0d873d0", "Quelle", "495.663 7", "Spiderman (1983) (Quelle) (PAL)", "AKA Spider-Man", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f7d6592dcb773c81c278140ed4d01669", "Activision, David Crane, Dan Kitchen", "EAG-108-04, EAZ-108-04B", "Ghostbusters (1985) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f7e07080ed8396b68f2e5788a5c245e2", "Video Game Cartridge - Ariola", "TP-617", "Farmyard Fun (Ariola)", "AKA Play Farm", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f7ec2f2bdbe8fbea048c0d5fa6503b0b", "Akor", "", "TV Boy (1992) (Akor) (PAL)", "Includes 127 games", "", "", "", "", "", "", "", "", "JOYSTICK", "JOYSTICK", "", "", "", "", "", "", "", "" },
-  { "f7f50d9c9d28bcc9f7d3075668b7ac89", "Activision, David Crane - Ariola", "EAG-008, PAG-008, EAG-008-04I - 711 008-720", "Laser Blast (1981) (Activision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f7fac15cf54b55c5597718b6742dbec2", "Spiceware", "SW-01", "Medieval Mayhem (NTSC)", "", "Homebrew", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "AUTO 55", "", "", "", "" },
-  { "f802fa61011dd9eb6f80b271bac479d0", "Suntek", "SS-023", "Mole Hunter (1983) (Suntek) (PAL)", "AKA Topy", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f80cf77164079d774b9b0fae33dffca9", "", "", "Fu Kung! (V0.15) (Negative Version) (05-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f8240e62d8c0a64a61e19388414e3104", "Activision, Steve Cartwright", "AX-013", "Barnstorming (1982) (Activision)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f825c538481f9a7a46d1e9bc06200aaf", "Atari, Richard Maurer - Sears", "CX2635 - 49-75157", "Maze Craze (1980) (Atari)", "AKA A Game of Cops 'n Robbers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "NTSC", "", "", "" },
-  { "f844f4c6f3baaaf5322657442d6f29eb", "Atari, Sam Comstock, Richard Dobbis, Nick 'Sandy Maiwald' Turner", "CX26111", "Snoopy and the Red Baron (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f847fb8dba6c6d66d13724dbe5d95c4d", "Absolute Entertainment, David Crane", "AG-042-02, AG-042-04", "Skate Boardin' (1987) (Absolute)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f8582bc6ca7046adb8e18164e8cecdbc", "", "", "Panda Chase (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f8648d0c6ad1266434f6c485ff69ec40", "CCE", "", "Oink! (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f8811d45a9935cca90c62f924712f8e6", "Jone Yuan Telephonic Enterprise Co", "", "Chopper Command (Jone Yuan) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f8b2a6a4d73ebff10d805a9b59041986", "Activision, Larry Kaplan - Ariola", "EAX-006, PAX-006 - 771 006-720", "Bridge (1980) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f8bfd99163d2c4ec688357786e6fba28", "", "", "Eckhard Stolberg's Scrolling Text Demo 2 (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f8c1c4a41303bd40b0d6c81bfaf8573b", "HES", "773-891", "2 Pak Special - Dungeon Master, Creature Strike (1992) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f8fbe2b07345086fc867bceeaf38dc48", "Atari, Eric Manghise, Mimi Nyden, Joseph Tung", "CX2640", "RealSports Baseball (1982) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f8ff34b53d86f55bd52d7a520af6d1dc", "", "", "Big Dig (04-04-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f90b5da189f24d7e1a2117d8c8abc952", "Atari, David Crane - Sears", "CX2653 - 6-99823, 49-75111", "Slot Machine (1979) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f91fb8da3223b79f1c9a07b77ebfa0b2", "Atari, Alan J. Murphy, Nick 'Sandy Maiwald' Turner - Sears", "CX2615 - 49-75140", "Demons to Diamonds (1982) (Atari)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 57", "", "", "", "" },
-  { "f93d7fee92717e161e6763a88a293ffa", "20th Century Fox Video Games - Lazer Micro Systems - Dunhill Electronics, B. Winston Hendrickson, Randall Hyde, Mark V. Rhoads, John Simonds", "11013", "Porky's (1983) (20th Century Fox)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f9420173efcb4b9f2b01c2a7b595cca7", "CCE", "", "Laser Blast (CCE) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f954381f9e0f2009d1ac40dedd777b1a", "Thomas Jentzsch", "", "Robot City (V0.18) (01-09-2002) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f9655ed51462ecfc690c7b97cec649f9", "Andrew Wallace", "", "Laseresal 2002 (PAL) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f965cc981cbb0822f955641f8d84e774", "Answer Software Corporation - TY Associates, Kim Ellis", "ASC2001", "Confrontation (1983) (Answer) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "f9660ebed66fee8bdfdf07b4faa22941", "VGS", "", "Vanguard (VGS)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f9677b2ec8728a703eb710274474613d", "Atari, Ian Shepard", "CX2604, CX2604P", "Space War (1978) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f97dee1aa2629911f30f225ca31789d4", "Avalon Hill, Jean Baer, Bill 'Rebecca Ann' Heineman, Jim Jacob", "5005002", "Out of Control (1983) (Avalon Hill)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f98d2276d4a25b286135566255aea9d0", "Digitel", "", "Name This Game (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f98d869f287d2ce4f8fb36e0686929d9", "", "", "Skeleton+ (17-04-2003) (Eric Ball) (NTSC)", "", "", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f991e0670b5f67faa6b6211e9bd81b91", "Nukey Shay, Omegamatrix", "", "Double Dragon (Genesis) (PAL) V2", "Genesis controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f992a39b46aa48188fab12ad3809ae4a", "", "", "Sky Jinks (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f9967369943209b4788d4e92cefc0795", "Atari", "CX26163P", "Fishing (32 in 1) (1988) (Atari) (PAL) (4K)", "AKA Fishing Derby", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f9cef637ea8e905a10e324e582dd39c2", "CCE", "", "Private Eye (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f9d51a4e5f8b48f68770c89ffd495ed1", "Atari, Tod Frye, Mimi Nyden", "CX2657", "SwordQuest - FireWorld (1982) (Atari)", "AKA Adventure II, SwordQuest II - FireWorld", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f9da42f91a1c5cfa344d2ff440c6f8d4", "ZUT", "", "Pac Invaders (ZUT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f9de91d868d6ebfb0076af9063d7195e", "", "", "Maze Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "f9e99596345a84358bc5d1fbe877134b", "Activision, Larry Kaplan, David Crane - Ariola", "EAG-010, PAG-010 - 711 010-720", "Kaboom! (1981) (Activision) (PAL)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
-  { "fa0570561aa80896f0ead05c46351389", "Tigervision", "7-008", "Miner 2049er (1983) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fa1b060fd8e0bca0c2a097dcffce93d3", "Atari - CCW, Christopher H. Omarzu, Preston Stuart, Bruce Williams", "CX26101", "Oscar's Trash Race (1984) (Atari)", "Uses the Keypad Controllers", "", "", "", "", "", "", "", "", "KEYBOARD", "KEYBOARD", "", "", "", "", "", "", "", "" },
-  { "fa2be8125c3c60ab83e1c0fe56922fcb", "Camelot - DSD, Michael Doherty, Clyde Hager - Johnson & Johnson", "", "Tooth Protectors (1983) (Camelot)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "fa3de71841c0841db6a741884a6b6b2f", "", "", "Warring Worms (17-02-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fa4404fabc094e3a31fcd7b559cdd029", "Atari, Alan J. Murphy, Robert C. Polaro", "CX26100", "Bugs Bunny (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fa529ec88eca679f6d5fd0ccb2120e46", "", "", "20 Sprites at Once Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fa6fe97a10efb9e74c0b5a816e6e1958", "ZiMAG - Emag - Vidco", "707-111 - GN-030", "Tanks But No Tanks (1983) (ZiMAG)", "AKA Phantom Tank", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fa7ce62e7fd77e02b3e2198d70742f80", "Atari, Peter C. Niday", "CX26108", "Donald Duck's Speedboat (04-18-1983) (Atari) (Prototype) (PAL)", "AKA Donald Duck's Regatta", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fa7e11a3dbea4365975cd2f094e61d25", "Tim Snider", "", "Mystery Science Theater 2600 (1999) (Tim Snider) (Hack)", "Hack of Megamania", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fa98d48cd609c9babc819e0a1bd8d598", "AtariAge (Chris Walton)", "", "Juno First (2009) (PAL60)", "AtariVox supported", "Homebrew", "", "", "", "", "", "", "", "", "ATARIVOX", "", "", "", "", "", "", "YES", "" },
-  { "fab7b04b9f42df761eb6f2bc445eaa99", "20th Century Fox Video Games - Sirius Software, David Lubar", "11008", "Fantastic Voyage (11-04-1982) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fabca526d57de46768b392f758f1a008", "", "", "Laseresal 2600 (16-12-2001) (Andrew Wallace) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fac28963307b6e85082ccd77c88325e7", "CCE", "", "Berzerk (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fadb89f9b23beb4d43a7895c532757e2", "Galaga Games", "", "River Raid (1984) (Galaga Games) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fae0b86934a7c5a362281dffebdb43a0", "Retroactive", "", "Qb (2.07) (Retroactive) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "faebcb2ef1f3831b2fc1dbd39d36517c", "Atari, Jerome Domurat, Steve Woita", "CX2696", "Asterix (1984) (Atari) (PAL)", "AKA Taz", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "faed2ef6b44894f8c83f2b50891c35c6", "CCE", "", "Super Baseball (CCE)", "AKA RealSports Baseball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "faffd84f3a8eceee2fa5ea5b0a3e6678", "Suntek", "SS-025", "Spectracube Invasion (1983) (Suntek) (PAL)", "AKA Immies & Aggies", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fb09ee4ccd47ae74a3c314f0d8a40344", "", "", "Titans (SnailSoft)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fb0c32ef7af5b45486db663510094be8", "", "", "Demo Image Series #15 - Three Marios (NTSC) (Non-Interleave) (06-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fb0e84cee4c108d24253bcb7e382cffd", "", "", "Interleaved ChronoColour Demo (SECAM) (05-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fb27afe896e7c928089307b32e5642ee", "M Network - INTV - APh Technological Consulting, Jeff Ronne, Brett Stutz", "MT5662", "TRON - Deadly Discs (1983) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fb4ca865abc02d66e39651bd9ade140a", "Arcadia Corporation, Brian McGhie", "AR-4104", "Rabbit Transit (1983) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fb531febf8e155328ec0cd39ef77a122", "", "", "Worm War I (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "fb5c8af97bd8ffe88323656f462645a7", "", "", "Interlace Demo (Glenn Saunders)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "fb833ed50c865a9a505a125fc9d79a7e", "ITT Family Games", "", "Pumuckl I (1983) (ITT Family Games) (PAL)", "AKA Panda Chase", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fb884ffd89013331a6f01ae3f6abd214", "Activision, David Crane", "", "Venetian Blinds Demo (1982) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fb88baa01afd34e0e4b601e1d29bc806", "Manuel Polik", "", "Star Fire (2003) (XYPE)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fb88c400d602fe759ae74ef1716ee84e", "20th Century Fox Video Games, Bill Aspromonte", "11031", "Crash Dive (1983) (20th Century Fox)", "AKA Voyage to the Bottom of the Sea", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fb91da78455d9b1606913fbf8c859772", "", "", "Split Screen (Ballblazer) Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fb91dfc36cddaa54b09924ae8fd96199", "Parker Brothers, Mark Lesser", "PB5590", "Frogger II (1984) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "fb978f1c053e8061cc37a726639f43f7", "Atari - Axlon, Tod Frye - Heuristica, Agustin Ortiz", "CX26169", "Shooting Arcade (03-07-1989) (Atari) (Prototype)", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fbac6476e7b2b20d246202af81662c88", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (Preview) (1982) (Starpath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fbb0151ea2108e33b2dbaae14a1831dd", "Thomas Jentzsch", "", "Robot Tank TV (Thomas Jentzsch) (Hack)", "Uses two simultaneous Joystick Controllers, Hack of Robot Tank", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fbb4f3debf48dc961b559384467f2057", "Digitel", "", "River Raid III (1985) (Digitel)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fbe554aa8f759226d251ba6b64a9cce4", "Atari - GCC, Mike Feinstein, Brad Rice", "CX2681, CX2681P", "Battlezone (1983) (Atari) (PAL)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fbfebee9c14694719e3eda4854dc42ee", "Jake Patterson", "", "Baubles 3 (Jake Patterson) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fc2104dd2dadf9a6176c1c1c8f87ced9", "Coleco - Woodside Design Associates, Harley H. Puthuff Jr.", "2663", "Time Pilot (1983) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fc2233fc116faef0d3c31541717ca2db", "Atari, Tod Frye", "CX2646", "Pac-Man (1982) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fc24a94d4371c69bc58f5245ada43c44", "Atari - Axlon, Steve DeFrisco", "CX26170", "Secret Quest (1989) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fc6052438f339aea373bbc999433388a", "Atari, David Crane", "CX2653P", "Slot Machine (1979) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fc668a2251dd79cbd903d4fa0e558f96", "Thomas Jentzsch", "", "Thrust (V1.1) (2000) (TJ) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fc92d74f073a44bc6e46a3b3fa8256a2", "", "", "Megademo (19xx) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fc9c1652fe3a2cade6188f4d3692481f", "Andrew Davies", "", "Andrew Davies early notBoulderDash demo (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "fca4a5be1251927027f2c24774a02160", "Activision, John Van Ryzin", "AZ-036-04", "H.E.R.O. (1984) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fcbbd0a407d3ff7bf857b8a399280ea1", "ZiMAG - Emag - Vidco", "GN-070", "Mysterious Thief, A (1983) (ZiMAG) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "fcbdf405f0fc2027b0ea45bb5af94c1a", "Amiga - Video Soft, Michael K. Glass, Jerry Lawson", "", "3-D Ghost Attack (1983) (Amiga) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "fcea12625c071ddc49f4e409f4038c60", "Fabrizio Zavagli", "", "Balls! (16-09-2002) (Fabrizio Zavagli)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
-  { "fcf8e306f6615f74feba5cb25550038c", "", "", "Blue Dot Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fd0e5148162e8ec6719445d559f018a9", "Activision, Steve Cartwright - Ariola", "EAX-022, EAX-022-04I - 711 022-720", "Seaquest (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fd10915633aea4f9cd8b518a25d62b55", "Atari, John Dunn", "CX2631, CX2631P", "Superman (1979) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fd16949913aaab5beaefed73bf2ca67c", "Atari - GCC, John Allred, Mike Feinstein", "CX2688", "Jungle Hunt (02-03-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fd4f5536fd80f35c64d365df85873418", "Atari - Bobco, Robert C. Polaro", "CX26140", "Desert Falcon (1987) (Atari)", "AKA Nile Flyer, Sphinx", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fd6e507b5df68beeeddeaf696b6828fa", "", "", "Boxing (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fd7464edaa8cc264b97ba0d13e7f0678", "HES", "771-333", "2 Pak Special - Challenge, Surfing (1990) (HES) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fd78f186bdff83fbad7f97cb583812fe", "Amiga - Video Soft", "3125", "Surf's Up (1983) (Amiga) (Prototype) [a2]", "Uses the Joyboard controller", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fd8b4ee0d57605b35e236e814f706ff1", "Atari - GCC, Mike Feinstein, John Mracek", "CX2673, CX2673P", "Phoenix (1982) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fd9b321cee5fbb32c39ba3ca5d9ec7cf", "Jeffry Johnston", "", "Radial Pong - Version 5 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fdd4995a50395db14f518f63c2d63438", "", "", "Oh No! (Version 3) (18-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fde42e39710e75e9e4d4d75440f8e4e5", "Thomas Jentzsch", "", "Coke Zero (v1.0) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fdf0de38517e0cf7f0885f98ccc95836", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (2 of 4) (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fdf6680b2b1e8054293a39700a765692", "", "", "Alpha Demo - The Beta Demo 2 (2000) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fe0b7f27e3ad50bbf9ff468ee56d553d", "", "", "Lines Demo (Eckhard Stolberg) (PAL) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fe0bc4bb92c1c4de7d5706aaa8d8c10d", "", "", "Sprite Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fe3b461d4c8b179fe68bc77760294c25", "Atari, Joe Decuir", "CX2621, CX2621P", "Video Olympics (1977) (Atari) (PAL) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "YES", "", "", "", "", "", "", "" },
-  { "fe641247a4ab9bee970e19ab55f23b25", "20th Century Fox Video Games, Beck-Tech, Steve Beck", "11035", "Save the Whales (02-07-1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fe67087f9c22655ce519616fc6c6ef4d", "Atari - Zip Technology, Randy Bowker, Bruce Williams", "CX26142", "Crack'ed (11-28-1988) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fe6abc0f63e31e2646c9c600926b5b7f", "Atari", "CX26137", "4 in 1 (02-19-1987) (Atari) (Prototype)", "Home Run, Canyon Bomber, Sky Diver, Night Driver", "Prototype", "", "", "4IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fe870018332a0221eb59fb18b0c6bccc", "", "", "Incoming (08-11-2002) (Ben Larson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fe9ae625d924b54c9f8a14ac9a0f6c6d", "BG Dodson", "", "High Bid! (BG Dodson) (Hack)", "Hack of Pepsi Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "feba8686fd0376015258d1152923958a", "", "", "Super Circus (Unknown) (PAL)", "AKA Circus Atari", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fec0c2e2ab0588ed20c750b58cf3baa3", "Activision - Cheshire Engineering, David Rolfe, Larry Zwick", "EAZ-037-04, EAZ-037-04I", "Beamrider (1984) (Activision) (PAL)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "fece458a8023a809a5006867feca40e8", "", "", "SCSIcide (24-02-2001) (Joe Grand) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "feec54aac911887940b47fe8c9f80b11", "Atari, Rob Fulop", "CX2633, CX2633P", "Night Driver (1980) (Atari) (PAL)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "YES", "" },
-  { "feedcc20bc3ca34851cd5d9e38aa2ca6", "Atari, David Crane - Sears", "CX2607 - 6-99828, 49-75115", "Canyon Bomber (1979) (Atari)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "YES", "", "", "10", "", "", "", "" },
-  { "ff1523783e0e76a3b0d1f7f0d1cb3050", "Thomas Jentzsch", "", "Marble Craze - Atari Trak-Ball Hack v1.0 (PAL) (TJ)", "Uses Atari Trak-Ball Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ff3bd0c684f7144aeaa18758d8281a78", "Atari, Bob Whitehead", "CX2651", "Blackjack (1977) (Atari) (PAL)", "Uses the Paddle Controllers", "Rare", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "" },
-  { "ff5a9e340d96df6f5a5b6eb038e923bd", "", "", "Space Shuttle (1983) (Activision) [t1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ff7627207e8aa03730c35c735a82c26c", "Atari, Bob Whitehead", "CX26163P", "Blackjack (32 in 1) (1988) (Atari) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "" },
-  { "ff86fc8ffa717bb095e8471638c1c31c", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix - Bop a Buggy (1 of 3) (1983) (Arcadia) (PAL)", "Uses Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 56", "", "", "", "" },
-  { "ff87d58125ae517eb7b09a0475a1ccdc", "", "", "SCSIcide (Score Hack 1) (24-02-2001) (Joe Grand) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ffb1cd548563158ce33f9d10268187e7", "Erik Eid", "", "Euchre (Beta) (NTSC) (12-09-2002) (Erik Eid)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ffc0ff4305dd46b4b459885bd1818e2e", "Barry Laws Jr.", "", "Star Wars - The Battle of Alderaan (Star Strike Hack)", "Hack of Star Strike (Mattel)", "New Release (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ffdc0eb3543404eb4c353fbdddfa33b6", "CCE", "C-827", "Chopper Command (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ffe51989ba6da2c6ae5a12d277862e16", "Atari - Sears", "CX2627 - 6-99841", "Human Cannonball (1979) (Atari) (4K)", "AKA Cannon Man", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
-  { "ffebb0070689b9d322687edd9c0a2bae", "", "", "Spitfire Attack (1983) (Milton Bradley) [h1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }
+static const BSPF::array2D<const char*, DEF_PROPS_SIZE, 27> DefProps = {{
+  { "000509d1ed2b8d30a9d94be1b3b5febb", "Greg Zumwalt", "", "Jungle Jane (2003) (Greg Zumwalt) (Hack)", "Hack of Pitfall!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0060a89b4c956b9c703a59b181cb3018", "CommaVid, Irwin Gaines - Ariola", "CM-008 - 712 008-720", "Cakewalk (1983) (CommaVid) (PAL)", "AKA Alarm in der Backstube", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "007d18dedc1f0565f09c42aa61a6f585", "CCE", "C-843", "Worm War I (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "008543ae43497af015e9428a5e3e874e", "Retroactive", "", "Qb (V2.09) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "00b7b4cbec81570642283e7fc1ef17af", "SEGA - Beck-Tech, Steve Beck, Phat Ho", "006-01", "Congo Bongo (1983) (SEGA)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "00ce0bdd43aed84a983bef38fe7f5ee3", "20th Century Fox, Bill Aspromonte", "11012", "Bank Heist (1983) (20th Century Fox)", "AKA Bonnie and Clyde, Cops 'n' Robbers, Holdup, Rooring 20's", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "00ce76ad69cdc2fa36ada01ae092d5a6", "Bit Corporation", "PGP214", "Cosmic Avenger (4 Game in One) (1983) (BitCorp) (PAL)", "AKA StarMaster", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "00dc28b881989c39a6cf87a892bd3c6b", "CCE", "", "Krull (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "00e19ebf9d0817ccfb057e262be1e5af", "Atari, Ed Logg, Carol Shaw", "CX2639, CX2639P", "Othello (1981) (Atari) (PAL) [no grid markers]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "00e55b27fe2e96354cd21b8b698d1e31", "", "", "Phoenix (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "00eaee22034aff602f899b684c107d77", "Rainbow Vision - Suntek - Sunteck Corp", "SS-001", "Time Race (1983) (Rainbow Vision) (PAL)", "AKA Space Jockey", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "00f7985c20b8bdf3c557fac4d3f26775", "Aaron Curtis", "", "AStar (NTSC)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "012020625a3227815e47b37fd025e480", "Rob Kudla", "", "Better Space Invaders (1999) (Rob Kudla) (Hack) [a]", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "01293bd90a4579abb7aed2f7d440681f", "Century", "", "Snoopy (1983) (Century) (PAL)", "AKA Snoopy and the Red Baron", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "01297d9b450455dd716db9658efb2fae", "TechnoVision - Video Technology", "TVS1002", "Save Our Ship (1983) (TechnoVision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "012b8e6ef3b5fd5aabc94075c527709d", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix (1983) (Arcadia)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 56", "", "", "", "" },
+  { "0164f26f6b38a34208cd4a2d0212afc3", "Coleco, Ed English", "2656", "Mr. Do! (1983) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "0173675d40a8d975763ee493377ca87d", "CBS Electronics, Ed English", "4L1751", "Roc 'n Rope (1984) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "01abcc1d2d3cba87a3aa0eb97a9d7b9c", "Jone Yuan Telephonic Enterprise Co", "", "Topy (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "01b09872dcd9556427761f0ed64aa42a", "Galaga Games", "", "River Raid (1984) (Galaga Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "01cb3e8dfab7203a9c62ba3b94b4e59f", "Atari, Mimi Nyden, Scott Smith, Robert Vieira", "CX26127", "Gremlins (1984) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "01e5c81258860dd82f77339d58bc5f5c", "CCE", "", "Corrida da Matematica (CCE)", "AKA Math Gran Prix", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "01e60a109a6a67c70d3c0528381d0187", "ITT Family Games, Perry Rhodan-Serie", "554-33 383", "Fire Birds (1983) (ITT Family Games) (PAL)", "AKA Sky Alien", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "01f584bf67b0e464014a8c8b5ea470e3", "Arcadia Corporation, Dennis Caswell", "5 AR-4200", "Labyrinth (Escape from the Mindmaster Beta) (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "02066b17f29082412c6754c1a2d6302e", "", "", "Demo Image Series #3 - Baboon (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "024365007a87f213cbe8ef5f2e8e1333", "Atari, Frank Hausman, Mimi Nyden, Steve Woita", "CX2686", "Quadrun (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "025668e36a788e8af8ac4f1be7e72043", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX2659", "Raiders of the Lost Ark (06-14-82) (Atari) (Prototype)", "Console ports are swapped", "Prototype", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "026180bf641ff17d8577c33facf0edea", "Activision, Steve Cartwright", "AX-022", "Seaquest (1983) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0277c449fae63f6f1c8f94dedfcf0058", "", "", "Laser Demo (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "027a59a575b78860aed780b2ae7d001d", "CCE", "", "Pressure Cooker (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "028024fb8e5e5f18ea586652f9799c96", "Coleco - Woodside Design Associates, Steve 'Jessica Stevens' Kitchen", "2468", "Carnival (1982) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "02811151906e477d47c135db5b1699c6", "", "", "FlickerSort Demo (Updated) (20-04-2002) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "02a5fc90a0d183f870e8eebac1f16591", "HES", "771-422", "2 Pak Special - Star Warrior, Frogger (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "02ab2c47bc21e7feafa015f90d7df776", "Atari", "MA017600", "Diagnostic Test Cartridge 2.6 (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "02ced7ea2b7cb509748db6bfa227ebec", "Parker Brothers, Ed English, David Lamkins", "931502", "Frogger (1982) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "02cee0b140d2f1a1efcfb1d482a5c392", "Atari, Ed Logg, Carol Shaw - Sears", "CX2639 - 49-75162", "Othello (1981) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "02dcba28c614fec7ca25955327128abb", "Andrew Wallace", "", "Laseresal 2002 (PAL) (PD) [a]", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "02e3f4ba156fb578bef7d7a0bf3400c1", "", "", "Booster (Junkosoft) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "033e21521e0bf4e54e8816873943406d", "20th Century Fox Video Games - Sirius Software, Dan Thompson", "11020", "Earth Dies Screaming, The (1983) (20th Century Fox)", "The Day the Earth Stood Still", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "034c1434280b0f2c9f229777d790d1e1", "Telegames", "5665 A016", "Baseball (1988) (Telegames) (PAL)", "AKA Super Challenge Baseball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0375f589f7da06d2d2be532e0d4d4b94", "", "", "Push (V0.04) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0383dc02cb82302da3d155fd108bfe3a", "AtariAge, Chris Spry", "CX26200", "Princess Rescue (2013) (Sprybug) (PAL60)", "Compatible with Genesis controller", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "038e1e79c3d4410defde4bfe0b99cc32", "Atari, Tod Frye, Gary Shannon", "", "Aquaventure (08-12-1983) (Atari) (Prototype)", "AKA Sea Sentinel", "Unbelievably Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "039cf18b459d33b8a8fca31d06c4c244", "", "", "Demo Image Series #0 (12-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "03b1051c9374678363c899914412cfc5", "", "", "Incoming (30-10-2002) (Ben Larson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "03c3f7ba4585e349dd12bfa7b34b7729", "SEGA, Jeff Lorenz", "004-01", "Star Trek - Strategic Operations Simulator (1983) (SEGA)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "03fbcee0bc80e31f27254aea3d920510", "Bit Corporation", "R320", "Trick Shot (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "03ff9e8a7af437f16447fe88cea3226c", "Bomb - Onbase", "CA285", "Wall-Defender (1983) (Bomb)", "AKA Wall Break", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "04014d563b094e79ac8974366f616308", "Atari, Andrew Fuchs, Courtney Granner, Jeffrey Gusman, Mark R. Hahn", "CX2690", "Pengo (1984) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "041b5e56bbc650db574bd8db3fae2696", "Thomas Jentzsch", "", "Thrust (V1.0) (2000) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "043f165f384fbea3ea89393597951512", "Spectravision - Spectravideo", "SA-202", "Planet Patrol (1982) (Spectravision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0443cfa9872cdb49069186413275fa21", "M Network - INTV, Patricia Lewis Du Long, Ron Surratt", "MT4518", "BurgerTime (1983) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "045035f995272eb2deb8820111745a07", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (1983) (Arcadia)", "AKA Jungle Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "047ac3b9faea64522b7a23c4465a7aa8", "", "", "Defender (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "04856e3006a4f5f7b4638da71dad3d88", "Atari, Douglas Neubauer", "CX26176", "Radar Lock (1989) (Atari) (PAL)", "AKA Dog Fight", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "049626cbfb1a5f7a5dc885a0c4bb758e", "", "", "MegaMania (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "04b488d4eef622d022a0021375e7e339", "Home Vision - Gem International Corp. - VDI", "VCS83107", "Tennis (1983) (Home Vision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "04cf9e6898007024622ed6a0b295961f", "Bit Corporation", "R320", "Tennis (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "04dfb4acac1d0909e4c360fd2ac04480", "Thomas Jentzsch", "", "Jammed (2001) (XYPE) (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "04e737c9d53cd84bfd5ee679954e4706", "Jone Yuan Telephonic Enterprise Co", "", "Checkers (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "04fccc7735155a6c1373d453b110c640", "HES - Imagineering, David Lubar", "535", "My Golf (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0519f395d5f7d76be813b834aa51c0be", "Atari, Ian Shepard", "CX2604", "Space War (1978) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0546f4e6b946f38956799dd00caab3b1", "Thomas Jentzsch", "", "My Golf (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "056f5d886a4e7e6fdd83650554997d0d", "Parker Brothers, Ed Temple", "931504", "Amidar (1982) (Parker Bros) (PAL)", "", "Uncommon", "", "", "", "A", "A", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "056ff67dd9715fafa91fb8b0ddcc4a46", "", "", "Frisco (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "05824fcbe615dbca836d061a140a50e0", "Jeffry Johnston", "", "Radial Pong - Version 9 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "05aedf04803c43eb5e09dfd098d3fd01", "", "", "Keystone Kapers (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "05aff8f626ef870432ae3b3d9d5aa301", "Activision, Bob Whitehead", "AG-019", "Sky Jinks (1982) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "05b45ba09c05befa75ac70476829eda0", "Parker Brothers, Rex Bradford", "931507", "Star Wars - Jedi Arena (1983) (Parker Bros) (PAL)", "Uses the Paddle Controllers (swapped)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 50", "", "", "", "" },
+  { "05c60458ec69e7fe8b1be973852d84f1", "", "", "Test (1996) (J.V. Matthews) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "05c765a63e61882abd1c2d627b652225", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Amiga Mouse Hack v1.1 (NTSC) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "05ccf96247af12eef59698f1a060a54f", "Otto Versand", "600273", "King Arthur (1983) (Otto Versand) (PAL)", "AKA Dragonfire (Double-Game Package)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "05d61b925d3d2474bab83f0a79bb5df1", "Eckhard Stolberg", "", "Cosmic Ark Stars (1997) (Eckhard Stolberg)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "05eb4347f0ec8f4783983ca35ffd8d1b", "", "", "Qb (2.06) (Retroactive) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "05ebd183ea854c0a1b56c218246fbbae", "Atari, Dan Hitchens", "CX2656", "SwordQuest - EarthWorld (1982) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "05f11fb2e45c4e47424d3cb25414d278", "", "", "Boring (NTSC) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "060c865c782debb047e6fd101c8923fc", "Atari", "CX26163P", "Freeway Rabbit (32 in 1) (1988) (Atari) (PAL) (4K)", "AKA Freeway", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0614ed51acd027d531e7c85c4f435292", "", "", "Narnia (Glenn Saunders) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0619e1c3286bbfbace040b8c3ec5add2", "Omegamatrix", "", "Millipede (Atari Trak-Ball) v6.5 (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "PAL60", "", "", "" },
+  { "0651216c4a4a9c9ac5ada3013a317c72", "Jone Yuan Telephonic Enterprise Co", "", "Fishing Derby (Jone Yuan) (4K) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "06742cf522f23797157f215a1dc8a1a9", "", "", "Healthbars (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0685bd0bcb975ceef7041749a5454a48", "Piero Cavina", "", "11 Sprite Demo (Piero Cavina) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "069c17beb1e8e0557adb8539fdcf6cba", "", "", "Phantom II & Pirate (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "06b0194ce992584c365278e0d7323279", "Activision", "", "Unknown Activision Game #2 (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "06b6c5031b8353f3a424a5b86b8fe409", "Activision, Mike Lorenzen - Ariola", "EAX-023 - 711 023-720", "Oink! (1983) (Activision) (PAL)", "AKA Das Schweinchen und der Wolf", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "06cfd57f0559f38b9293adae9128ff88", "Telegames", "4317 A009", "Adventures on GX-12 (1988) (Telegames) (PAL)", "AKA Adventures of Tron", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "06d2f7674cea977607f74c464ce600a2", "CBS Electronics, Alex Nevelson", "4L 2737 0000", "Omega Race (1983) (CBS Electronics) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "BOOSTERGRIP", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "06db908011065e5ebb37f4e253c2a0b0", "", "", "Gopher (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "06e5dc181a8eda1c31cc7c581c68b6ef", "", "", "Tac-Scan (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "071f84d10b343c7c05ce3e32af631687", "Rainbow Vision - Suntek", "SS-019", "Curtiss (1983) (Rainbow Vision) (PAL)", "AKA Atlantis", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "072a6ea2181ca0df88ac0dedc67b239d", "", "", "Multiple Missiles Demo (19-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "073cb76b006af034fd150be3f5e0e7e6", "", "", "Mobile 48 Sprite Kernel (Bug Fixed) (10-01-2003) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "073d7aff37b7601431e4f742c36c0dc1", "", "", "Bermuda (Unknown) (PAL)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "074ec425ec20579e64a7ded592155d48", "Atari - Sculptured Software, Steve Aguirre", "CX26162", "Fatal Run (Ultimate Driving) (1991) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "075069ad80cde15eca69e3c98bd66714", "CCE", "C-803", "Bobby Is Going Home (1983) (CCE)", "AKA Bobby Vai Para Casa", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0751f342ee4cf28f2c9a6e8467c901be", "Atari, Mimi Nyden, Joseph Tung", "CX26152", "Super Baseball (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "07973be3ecfd55235bf59aa56bdef28c", "Suntek", "SS-036", "Criminal Pursuit (1983) (Suntek) (PAL)", "AKA A Mysterious Thief", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "079fe9103515d15bc108577e234a484d", "", "", "Multi-Color Demo 0 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "07a3af1e18b63765b6807876366f5e8a", "Joe Grand", "", "SCSIcide Pre-release 2 (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "07c76f2d88552d20ad2c0ed7aef406c6", "Cody Pittman", "", "Blob (Cody Pittman) (Hack)", "Hack of Halloween", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "07f42847a79e4f5ae55cc03304b18c25", "Zellers", "", "Sea Hawk (Zellers)", "AKA Seahawk", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "07f84db31e97ef8d08dc9fa8a5250755", "Supergame", "", "Enduro (1984) (Supergame)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "07f91e33e76f53bb9d2731fd5d8a35a5", "Atari", "CX2632", "Space Invaders (1978) (Atari) [t1]", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0805366f1b165a64b6d4df20d2c39d25", "Atari, Dan Hitchens", "CX2650", "Berzerk (1982) (Atari) (PAL)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "08188785e2b8300983529946dbeff4d2", "Atari, Carla Meninsky, Ed Riddle - Sears", "CX2611 - 99821, 49-75149", "Indy 500 (1977) (Atari) (4K)", "Uses the Driving Controllers", "", "", "", "", "", "", "", "", "DRIVING", "", "", "DRIVING", "", "", "", "", "", "45", "", "", "", "" },
+  { "081e2c114c9c20b61acf25fc95c71bf4", "Parker Brothers, Ed English, David Lamkins", "PB5300", "Frogger (1982) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "082fdc8bd47fef01482ce5883c4ffdb8", "Charles Morgan", "", "Tanks DX (Charles Morgan) (Hack)", "Hack of Tanks But No Tanks", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0832fb2ee654bf9382bc57d2b16d2ffc", "Apollo - Games by Apollo, Ed Salvo", "AP-1001", "Skeet Shoot (1981) (Apollo) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "083e7cae41a874b2f9b61736c37d2ffe", "Imagic, Rob Fulop, Bob Smith", "720106-2A, IA3600P, EIX-009-04I", "Riddle of the Sphinx (1982) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "085322bae40d904f53bdcc56df0593fc", "Parker Brothers, Dave Engman, Dawn Stockbridge", "PB5340", "Tutankham (1983) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0856f202b18cd46e44fd1dc3b42e9bfb", "", "", "Frame Counter 1 (2001) (Jake Patterson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0866e22f6f56f92ea1a14c8d8d01d29c", "Androbot - Western Technologies, Michael Case, Lenny Carlson", "", "AndroMan on the Moon (1984) (Western Tech) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0891252ee4e307689febccf3cfd8a8ab", "Thomas Jentzsch", "", "Centipede - Atari Trak-Ball Hack v1.4 (PAL60) (Half-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0894aa7be77521f9df562be8d9555fe6", "CBS Electronics, Dan Kitchen, Garry Kitchen", "4L1700, 4L1701, 4L1702, 4L1802, 4L2274", "Donkey Kong (1982) (CBS Electronics) (PAL) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "08989fa4ff537f5dbd611aff4019521a", "Atari, Gary Palmer", "CX26163P", "Fun with Numbers (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "08bd4c1dcc843f6a0b563d9fd80b3b11", "Quelle", "343.273 9", "Phantompanzer II (1983) (Quelle) (PAL)", "AKA Thunderground", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "08bf437d012db07b05ff57a0c745c49e", "Arcadia Corporation, Steve Hales, Stephen H. Landrum", "4 AR-4102", "Meteoroids (1982) (Arcadia) (Prototype)", "Suicide Mission Beta", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "08d1b6d75206edb999252caf542a2c7f", "Larry Petit", "", "Super Home Run (2003) (Larry Petit) (Hack)", "Hack of Home Run", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "08d60a58a691c7f690162850302dc0e1", "", "", "Poker Squares (V0.27) (PAL) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "08e5960bb52d9a3e2c9954677b5e4472", "Atari - CCW, Christopher H. Omarzu, Preston Stuart, Bruce Williams", "CX26101", "Oscar's Trash Race (10-20-1982) (Atari) (Prototype)", "Uses the Keypad Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "08ea2fdaa22e5802c839ee7dfb0483dc", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Trak-Ball Hack v1.2 (PAL60) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "08f4dc6f118f7c98e2406c180c08e78e", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix - Tug of War (2 of 3) (1983) (Arcadia) (PAL)", "Uses Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "02", "", "", "", "" },
+  { "08f853e8e01e711919e734d85349220d", "Atari, Jerome Domurat, Michael Sierchio", "CX2667", "RealSports Soccer (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0906c6e0e4bda9c10cfa4c5fc64d2f4b", "Retroactive", "", "Qb (V0.12) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "090f0a7ef8a3f885048d213faa59b2f8", "Carrere Video - Western Technologies, John Hall - Teldec - Prism", "USC1012", "M.A.D. (1983) (Carrere Video) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "09274c3fc1c43bf1e362fda436651fd8", "Thomas Jentzsch", "", "Acid Drop (TJ)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "09388bf390cd9a86dc0849697b96c7dc", "Absolute Entertainment, Alex DeMeo", "AG-045-04, AK-045-04", "Pete Rose Baseball (1988) (Absolute)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0945081a6bd00345ff3d58eb7a07330a", "", "", "Stampede (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0956285e24a18efa10c68a33846ca84d", "Dismac", "", "Viagem Espacial (Dismac)", "AKA Star Voyager", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0963aa9f7f6cf5a36ff700001583624e", "Franklin Cruz", "", "Space Invaders 2 (Hack) [o1]", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "096649575e451508006b17e0353259a5", "Justin J. Scott", "", "Yar Vs. Yar (2002) (Justin J. Scott) (Hack)", "Hack of Yars' Revenge", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "097074f24cde141fe6a0f26a10333265", "", "", "Marble Craze (V0.90) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "097936b07e0e0117b9026ae6835eb168", "Imagic, Dennis Koble", "720100-2B, IA3000P", "Trick Shot (1982) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "09abfe9a312ce7c9f661582fdf12eab6", "Atari, Douglas Neubauer", "CX26154", "Super Football (1988) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "09e1ecf9bd2a3030d5670dba7a65e78d", "Atari, James Andreasen", "CX2654", "Haunted House (1982) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "09e9ba0762fd0c3cf3c2e072cff79cac", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (1984) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "09f89bbfa2ab00f1964d200e12d7ced0", "Atari", "MA017600", "Diagnostic Test Cartridge 2.6 (1982) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0a1b98937911d621b004b1617446d124", "", "", "Hangman Pac-Man Biglist1 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0a981c03204ac2b278ba392674682560", "Atari, Bob Whitehead - Sears", "CX2651 - 99805, 49-75602", "Blackjack (1977) (Atari)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0aa208060d7c140f20571e3341f5a3f8", "U.S. Games Corporation - Western Technologies,  Jeff Corsiglia, Paul Allen Newell, Tom Sloper", "VC1009", "Towering Inferno (1982) (U.S. Games)", "Uses the Joystick Controllers (swapped)", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "0abf64ca504a116adca80f77f85e00fb", "", "", "Cube Conquest (Billy Eno) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0ac0d491763153fac75f5337ce32a9d6", "", "", "SPAM Image Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0acaf71e60b89f6b6eab63db6ab84510", "", "", "This Planet Sucks (Greg Troutman) [a2]", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0aceb7c3bd13fe048b77a1928ed4267d", "Imagic, Bob Smith", "720102-2B, IA3201P, EIX-011-04I", "Star Voyager (1982) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0ad9a358e361256b94f3fb4f2fa5a3b1", "Atari, Carol Shaw, Nick 'Sandy Maiwald' Turner - Sears", "CX2608 - 49-75165", "Super Breakout (1982 - 1981) (Atari) [a]", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 45", "", "", "", "" },
+  { "0adb21206de92e8aec5ef295805ebb90", "", "", "Solaris (Genesis)", "Genesis controller (C switches to map mode)", "Hack of Solaris", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0ae3497e731ca0bf6a77b23441d9d9f9", "", "", "Analog Clock (V0.0) (20-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0af51ceb4aecc7a8fc89781ac44a1973", "Barry Laws Jr.", "", "Face Invaders Deluxe (Barry Laws Jr.) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0afe6ae18966795b89314c3797dd2b1e", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692, CX2692P", "Moon Patrol (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0b01909ba84512fdaf224d3c3fd0cf8d", "", "", "Revenge of the Apes (Hack)", "Hack of Planet of the Apes", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0b1056f1091cfdc5eb0e2301f47ac6c3", "Tigervision - Software Electronics Corp., Karl T. Olinger - Teldec", "7-001 - 3.60001 VE", "King Kong (1982) (Tigervision) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0b17ed42984000da8b727ca46143f87a", "Atari - CCW, Christopher H. Omarzu", "CX26104", "Big Bird's Egg Catch (05-17-1983) (Atari) (Prototype)", "Uses the Keypad Controller", "Prototype", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0b24658714f8dff110a693a2052cc207", "CCE", "C-815", "Seaquest (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0b33252b680b65001e91a411e56e72e9", "CCE", "C-832", "Atlantis (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0b4e793c9425175498f5a65a3e960086", "CCE", "", "Kung Fu Master (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0b55399cf640a2a00ba72dd155a0c140", "Imagic, Wilfredo Aguilar, Michael Becker, Rob Fulop", "720111-1A, 03205", "Fathom (1983) (Imagic)", "AKA Scuba", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "0b577e63b0c64f9779f315dca8967587", "Videospielkassette - Ariola", "PGP236", "Raketen-Angriff (Ariola) (PAL)", "AKA Missile Control", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0b8d3002d8f744a753ba434a4d39249a", "Sears Tele-Games, Robert Zdybel", "CX2619 - 49-75159", "Stellar Track (1981) (Sears)", "AKA Stella Trak", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "0bf19e40d5cd8aa5afb33b16569313e6", "Atari, Jerome Domurat, Andrew Fuchs, Dave Staugas, Robert Vieira", "CX26118", "Millipede (01-04-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0bf1e354304f46c0caf8fc0f6f5e9525", "Arcadia Corporation, Stephen Harland Landrum", "AR-4105", "Official Frogger (1983) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0bfabf1e98bdb180643f35f2165995d0", "Atari, Bob Whitehead - Sears", "CX2623 - 6-99819, 49-75108, 49-75125", "Home Run (1978) (Atari)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0c0392db94a20e4d006d885abbe60d8e", "", "", "Dodge Demo 3 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0c336f83b0e6e3bc86c77f368448e77b", "Bit Corporation", "R320", "Circus Atari (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0c35806ff0019a270a7acae68de89d28", "Froggo", "FG1003", "Task Force (1987) (Froggo)", "AKA Gangster Alley", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0c48e820301251fbb6bcdc89bd3555d9", "Atari, Bill Aspromonte, Andrew Fuchs", "CX26120", "Stargate (1984) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0c54811cf3b1f1573c9164d5f19eca65", "Activision, David Crane - Ariola", "EAG-001, PAG-001, EAG-001-04B, EAG-001-04I - 711 001-715", "Dragster (1980) (Activision) (PAL)", "AKA Dragster Rennen, Drag Strip", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0c72cc3a6658c1abd4b735ef55fa72e4", "Dion Olsthoorn", "v1.3", "Amoeba Jump (2018) (Dionoid) (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0c7926d660f903a2d6910c254660c32c", "Atari, Larry Kaplan", "CX2602, CX2602P", "Air-Sea Battle (1977) (Atari) (PAL)", "AKA Anti-Aircraft", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0c7bd935d9a7f2522155e48315f44fa0", "Carrere Video - Western Technologies, Jeff Corsiglia, Paul Allen Newell, Tom Sloper - Teldec - Prism", "USC1009", "Infernal Tower (1983) (Carrere Video) (PAL)", "AKA Towering Inferno", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "0c80751f6f7a3b370cc9e9f39ad533a7", "Atari, Carla Meninsky", "CX2610", "Warlords (1981) (Atari) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
+  { "0cb7af80fd0ddef84844481d85e5d29b", "", "", "Mr. Pac-Man (El Destructo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0cc8224ff1edfe458e8629e9e5fe3f5b", "Thomas Jentzsch", "", "Trick 12 (2001) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0cdd9cc692e8b04ba8eb31fc31d72e5e", "Thomas Jentzsch", "", "Wing War (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0cebb0bb45a856b23f56d21ce7d1bc34", "20th Century Fox Video Games, Bill Aspromonte", "11131", "Crash Dive (1983) (20th Century Fox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0cec9e46a25d338bf595a29aa2606516", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Mouse Hack v1.1 (PAL60) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0cfdd2f3b243cac21f38a0f09f54bead", "", "", "Overhead Adventure Demo 4 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0d07d2c1be1a5eaaea235a533bcda781", "", "", "Scrolling Playfield 1 (Junkosoft) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0d08558f34a47e4eaa39d01c8efb81f0", "Thomas Jentzsch", "", "Missile Control - Atari Mouse Hack v1.15 (NTSC) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0d09cff0d28033c02c3290edfc3a5cea", "Atari, Jerome Domurat, Steve Woita", "CX2699", "Taz (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0d1b3abf681a2fc9a6aa31a9b0e8b445", "Atari", "CX26163P", "Laser Blast (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0d27c7f5db349b592f70f68daf5e8f3b", "", "", "Space Instigators (21-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0d35618b6d76ddd46d2626e9e3e40db5", "", "", "X-Doom V.26 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0d5af65ad3f19558e6f8e29bf2a9d0f8", "Atari - Sculptured Software, Adam Clayton", "CX26151, CX26151P", "Dark Chambers (1989) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "0d6b974fe58a1bdd453600401c407856", "Atari", "", "128-in-1 Junior Console (Chip 3 or 4) (1991) (Atari) (PAL)", "Actually contains only 16 games, not 32", "", "", "", "16IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0d786a41695e5fc8cffd05a6dbb3f659", "", "", "Scrolling Playfield With Score (10-02-2003) (Aaron Bergstrom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0d7e630a14856f4d52c9666040961d4d", "", "", "Wavy Line Test (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0d90a0ee73d55539b7def24c88caa651", "Activision, Bob Whitehead", "AG-005, CAG-005, AG-005-04", "Skiing (1980) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0db4f4150fecf77e4ce72ca4d04c052f", "Atari, Carol Shaw - Sears", "CX2618 - 49-75123", "3-D Tic-Tac-Toe (1980) (Atari)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0dd4c69b5f9a7ae96a7a08329496779a", "Tigervision - Software Electronics Corp., Karl T. Olinger - Teldec", "7-001 - 3.60001 VE", "King Kong (1982) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0de53160a8b54c3aa5aed8d68c970b62", "Quelle", "806.174 9", "Fuchs & Schweinchen Schlau (1983) (Quelle) (PAL)", "AKA Oink!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0dfbdadf8f1bc718e7e1bb3ccd5fef3d", "", "", "Mr. Pac-Man (New start tune) (El Destructo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0e0808227ef41f6825c06f25082c2e56", "", "", "Candi (Hack) [a]", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0e08cd2c5bcf11c6a7e5a009a7715b6a", "", "", "Boing! (PD) [a1]", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0e224ea74310da4e7e2103400eb1b4bf", "Atari, Peter C. Niday, Gary Shannon, Howard Scott Warshaw", "", "Mind Maze (10-10-1984) (Atari) (Prototype)", "Uses the MindLink controller", "Prototype", "", "", "", "", "", "", "", "", "", "", "MINDLINK", "", "", "", "", "", "", "", "", "", "" },
+  { "0e23d0ed4c33b2011ab4cc93a7619683", "Thomas Jentzsch", "", "Centipede - Amiga Mouse Hack v1.4 (PAL60) (Half-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0e4b2b6e014a93ef8be896823da0d4ec", "", "", "Skiing (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0e713d4e272ea7322c5b27d645f56dd0", "Home Vision - Gem International Corp. - VDI", "VCS83105", "Panda Chase (1983) (Home Vision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0e7e73421606873b544e858c59dc283e", "Digivision", "", "Super Soccer (Digivision)", "AKA RealSports Soccer", "", "", "", "F8", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "0e86470791b26292abe1c64545c47985", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix - Down on the Line (3 of 3) (1983) (Arcadia) (PAL)", "Uses Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "01 70", "", "", "", "" },
+  { "0ec93f519bb769e0d9f80e61f6cc8023", "Atari - GCC, John Allred, Mike Feinstein", "CX2688", "Jungle Hunt (02-25-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0ecdb07bf9b36ef18f3780ef48e6c709", "Bit Corporation", "PG209", "Mr. Postman (1983) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0eebfb60d437796d536039701ec43845", "Fabrizio Zavagli", "", "Cakewalk (Fabrizio Zavagli)", "NTSC Conversion", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0eecb5f58f55de9db4eedb3a0f6b74a8", "Xonox - Beck-Tech", "6210, 06002, 06004, 99002", "Ghost Manor (1983) (Xonox) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0ef64cdbecccb7049752a3de0b7ade14", "Atari, Joe Decuir, Larry Caplan, Steve Mayer, Larry Wagner", "CX26163P", "Combat (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0efc91e45f61023cda9d086a7d3c402f", "B.J. Best (aka bjbest60)", "", "Space Cactus Canyon (2017)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "0effef4a341f8eebab65621c60c48787", "Thomas Jentzsch", "", "Reactor - Atari Trak-Ball Hack v1.3 (PAL) (Full-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0f14c03050b35d6b1d8850b07578722d", "Jeffry Johnston", "", "Radial Pong - Version 10 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0f24ca5668b4ab5dfaf217933c505926", "", "", "Fantastic Voyage (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0f2e09c71cc216f79d22a804152ba24b", "Bob Colbert", "", "Scroller Demo (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "0f341d1f4e144e3163d9a5fc5a662b79", "", "", "RUN Platform Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "0f39fc03d579d0d93a6b729a3746843e", "Atari, Sam Comstock, Richard Dobbis, Nick 'Sandy Maiwald' Turner", "CX26111", "Snoopy and the Red Baron (05-27-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0f604cd4c9d2795cf5746e8af7948064", "Champ Games", "CG-02-N", "Conquest Of Mars (2010) (NTSC)", "Rev 2 release", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0f643c34e40e3f1daafd9c524d3ffe64", "Atari, Robert C. Polaro, Alan J. Murphy - Sears", "CX2609 - 49-75186", "Defender (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0f6676b05621f80c670966e2995b227a", "", "", "Globe Trotter Demo 1 (24-03-2003) (Weston)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0f738dc44437557624eb277ed7ad91c9", "", "", "Grand Prix (Unknown) (PAL)", "AKA Grand Prix", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0f8043715d66a4bbed394ef801d99862", "Quelle", "684.733 9", "Robin Hood (1983) (Quelle) (PAL)", "AKA Save Our Ship", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0f95264089c99fc2a839a19872552004", "Activision, David Crane", "AG-009, AG-009-04", "Freeway (1981) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0fba7d8c3520bdb681f75494e498ec36", "", "", "Gunfight 2600 - Final Run (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0fbf618be43d4396856d4244126fe7dc", "Quelle", "805.784 6", "Labyrinth (1983) (Quelle) (PAL)", "AKA Maze Craze", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0fc161704c46e16f7483f92b06c1558d", "CCE", "C-853", "Spider Fighter (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0fcff6fe3b0769ad5d0cf82814d2a6d9", "Suntek", "SS-027", "Zoo Fun (1983) (Suntek) (PAL)", "AKA Panda Chase", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0fd72a13b3b6103fc825a692c71963b4", "Imagic, Rob Fulop", "720104-2A, IA3204P, EIX-008-04I", "Cosmic Ark (1982) (Imagic) (PAL) [selectable starfield]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "0fee596b974c9d3e70b367a3671599b6", "Bit Corporation", "R320", "Name This Game (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "101ab60f4000a5d13792ef0abad5f74b", "Atari, Jerome Domurat, Peter C. Niday, Robert Vieira", "CX26109", "Sorcerer's Apprentice (1983) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "102672bbd7e25cd79f4384dd7214c32b", "Atari, Alan Miller - Sears", "CX2642 - 6-99814", "Hunt & Score - Memory Match (1978) (Atari)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "103e9d616328969f5d7b4e0a381b25d5", "", "", "Playfield Illustration and Logo Demo (2001) (Jake Patterson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "103f1756d9dc0dd2b16b53ad0f0f1859", "Home Vision, Gem International Corp.", "", "Go Go Home Monster (1983) (Home Vision) (PAL)", "AKA Go Go Home", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "104468e44898b8e9fa4a1500fde8d4cb", "AtariAge, Chris Spry", "CX26200", "Princess Rescue (2013) (Sprybug)", "Compatible with Genesis controller", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "106326c262dfd3e8eaeabd961d2a0519", "", "", "PAL-NTSC Detector (15-11-2002) (CT)[a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "106855474c69d08c8ffa308d47337269", "Atari - Sculptured Software, Adam Clayton", "CX26151", "Dark Chambers (1989) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "107cc025334211e6d29da0b6be46aec7", "Atari, Bob Smith - Sears", "CX2648 - 49-75161", "Video Pinball (1981) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1086ff69f82b68d6776634f336fb4857", "Activision, David Crane", "AG-009", "Bloody Human Freeway (1981) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "10958cd0a1a81d599005f1797ab0e51d", "", "", "Centipede 2k (2000) (PD) (Hack)", "Hack of Centipede", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "10a3cd14e5dcfdde6ff216a14ce7b7dd", "Atari", "CX262, CX2627P", "Human Cannonball (1979) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "10af8728f975aa35a99d0965de8f714c", "Dinatronic", "", "Seaquest (Dinatronic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "10c47acca2ecd212b900ad3cf6942dbb", "Atari - Axlon, Tod Frye - Heuristica, Agustin Ortiz", "CX26169", "Shooting Arcade (03-07-1989) (Atari) (Prototype) [a4]", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "10c8cfd8c37522f11d47540ff024e5f9", "Canal 3 - Intellivision", "C 3016", "Demon Attack (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "10eae73a07b3da044b72473d8d366267", "Funvision - Fund. Int'l Co.", "", "Karate (1982) (Funvision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "10f0ecaf962aef1fc28abed870b01b65", "Atari, Paul Donaldson", "", "Bionic Breakthrough (06-22-1984) (Atari) (Prototype)", "Uses the Mindlink Controller", "Prototype", "", "", "", "", "", "", "", "MINDLINK", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "10f62443f1ae087dc588a77f9e8f43e9", "Atari, Carla Meninsky", "CX2637, CX2637P", "Dodge 'Em (1980) (Atari) (PAL) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "110ac8ecaf1b69f41bc94c59dfcb8b2d", "", "", "Demon Attack (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "111029770226b319524134193886a10e", "Hozer Video Games", "", "Gunfight 2600 - One Limit Reached! (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "11330eaa5dd2629052fac37cfe1a0b7d", "128-in-1 Junior Console", "", "Human Cannonball (128-in-1 Junior Console) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "113cd09c9771ac278544b7e90efe7df2", "Atari, Ed Logg, Carol Shaw - Sears", "CX2639 - 49-75162", "Othello (1981) (Atari) [no grid markers]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "114c599454d32f74c728a6e1f71012ba", "Activision, Bob Whitehead - Ariola", "EAX-015, EAX-015-04I - 711 015-725", "Chopper Command (1982) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "11bcf5c752088b5aaf86d6c7a6a11e8d", "Atari, Jerome Domurat, Andrew Fuchs, Dave Staugas, Robert Vieira", "CX26118", "Millipede (1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "11e7e0d9437ec98fa085284cf16d0eb4", "", "", "Bowling (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "11f9532557e4c9569f4b242164006161", "Chris Walton, Justin Hairgrove, Tony Morse", "", "Hunchy II (2005) (PAL)", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1201c18cf00d2c236f42e4d7d8c86aa1", "", "", "Nick Bensema Demo (Nick Bensema)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "12080205f669b8e7783b976f8cf3d8bb", "Omegamatrix", "", "Star Wars Arcade (Amiga Mouse) v4 (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "12123b534bdee79ed7563b9ad74f1cbd", "Absolute Entertainment, Alex DeMeo", "AG-041-04", "Title Match Pro Wrestling (1987) (Absolute)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1228c01cd3c4b9c477540c5adb306d2a", "Atari, Alan Miller", "CX26163P", "Basketball (32 in 1) (1988) (Atari) (PAL)", "Console ports are swapped", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1266b3fd632c981f3ef9bdbf9f86ce9a", "Activision, Bob Whitehead", "EAZ-034-04, EAZ-034-04I", "Private Eye (1984) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1267e3c6ca951ff1df6f222c8f813d97", "", "", "Dragonfire (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "126f7f64b7b00e25dcf5e3710b4cf8b8", "Atari - GCC", "CX2676", "Centipede (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1278f74ca1dfaa9122df3eca3c5bcaad", "Rainbow Vision - Suntek", "SS-013", "Bi! Bi! (Rainbow Vision) (PAL)", "AKA Skindiver", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1287535256bf5dff404839ac9e25c3e7", "PacManPlus", "Rev 2", "Alien Pac-Man (PacManPlus) (Hack)", "Hack of Alien", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "12937db3d4a80da5c4452b752891252d", "Digitel", "", "Megamania (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "12bca8305d5ab8ea51fe1cfd95d7ab0e", "Epyx, Steven A. Baker, Tod Frye, Peter Engelbrite", "80561-00250", "Summer Games (1987) (Epyx) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "12d7e0d6b187889f8d150bf7034d1db2", "", "", "Poker Squares (V0.0e) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "130c5742cd6cbe4877704d733d5b08ca", "Home Vision - Gem International Corp. - VDI", "VCS83109", "World End (1983) (Home Vision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1323c45d660f5a5b6d5ea45c6c4cbe4a", "Canal 3 - Intellivision", "", "Enduro (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "133456269a03e3fdae6cddd65754c50d", "Tigervision - Software Electronics Corporation - Teldec", "7-006 - 3.60008 VG", "Springer (1983) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "133a4234512e8c4e9e8c5651469d4a09", "Atari, Andrew Fuchs, Jeffrey Gusman, Dave Jolly, Suki Lee", "CX26117", "Obelix (1984) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "133b56de011d562cbab665968bde352b", "Activision, John Van Ryzin", "AG-038-04", "Cosmic Commuter (1984) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1343de49c2a50d99176255f99f0d0234", "Gray Games & AtariAge", "", "E.T. Book Cart (PAL)", "Charles F. Gray & Michael Rideout", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "55" },
+  { "13448eb5ba575e8d7b8d5b280ea6788f", "Digivision", "", "Crackpots (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1345e972dbe08ea3e70850902e20e1a5", "Greg Troutman", "", "Dark Mage (rough beta) (Greg Troutman) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "1351c67b42770c1bd758c3e42f553fea", "Digivision", "", "Keystone Kapers (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "135708b9a7dd20576c1b66ab2a41860d", "", "", "Hangman Man Biglist1 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "13584411da0a8d431991035423fdc0dc", "Jone Yuan Telephonic Enterprise Co", "", "Skiing (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1367e41858be525710eb04d0dab53505", "Kyle Pittman", "", "Zelda (2003) (Kyle Pittman) (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "136f75c4dd02c29283752b7e5799f978", "Atari, Dan Hitchens - Sears", "CX2650 - 49-75168", "Berzerk (1982) (Atari)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "13895ef15610af0d0f89d588f376b3fe", "Tigervision, Rorke Weigandt", "7-005", "Marauder (1982) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "13a37cf8170a3a34ce311b89bde82032", "Atari - GCC, Mark Ackerman, Tom Calderwood, Glenn Parker", "CX2684, CX2684P", "Galaxian (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "13a991bc9c2ff03753aeb322d3e3e2e5", "Funvision - Fund. International Co.", "", "Galactic (Funvision) (PAL)", "AKA Condor Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "13aa1f9ac4249947e4af61319d9a08f2", "Atari - GCC", "CX2680, CX2680P", "RealSports Tennis (1983) (Atari) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "13abc32f803165c458bb086fa57195fb", "Christian Samuel", "", "E.T. The Extra-Testical (Christian Samuel) (Hack)", "Hack of E.T. The Extra-Terrestrial", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "13ccc692f111d52fec75d83df16192e2", "Canal 3 - Intellivision", "", "Fishing Derby (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "13d8326bf5648db4dafce45d25e62ddd", "", "", "Atari Logo Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "13dfb095e519a555a5b60b7d9d7169f9", "", "", "Red Line Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "140909d204abd6841c64cdad4d7765b4", "", "", "Moving Blue Ladder Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "14163eb2a3ddd35576bd8527eae3b45e", "", "", "Multi-Color Demo 6 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1423f560062c4f3c669d55891a2bcbe7", "CCE", "C-859", "MASH (1983) (CCE) [a]", "AKA M.A.S.H", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1428029e762797069ad795ce7c6a1a93", "", "", "Thunderground (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "143918368f4f4dfff90999188c0197c9", "", "", "Unknown Title (bin00016 (200110)) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1442d1b35a6478fba22ae7dd1fcb5634", "Thomas Jentzsch", "", "Thrust (V0.2) (2000) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "148471144ccebd7f6aa9aa9215896533", "Parker Brothers - JWDA, Todd Marshall", "PB5550", "Q-bert's Qubes (1984) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "149b543c917c180a1b02d33c12415206", "CCE", "C-857", "Superman (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "14a56b493a8d9d10e94a3e100362e3a2", "Hozer Video Games", "", "Gunfight 2600 - Early Play-kernel (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "14b1e30982962c72f426e2e763eb4274", "Atari, Carol Shaw - Ralph Lauren", "", "Polo (1978) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "14c2548712099c220964d7f044c59fd9", "First Star Software, Alex Leavens, Shirley Ann Russell", "", "Boing! (1983) (First Star Software)", "AKA Bubbles, Soap Suds, The Emphysema Game", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "14d365bbfaac3d20c6119591f57acca4", "", "", "Video Life (Unknown) (4K) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "14dbb3686dd31964332dc2ef0c55cad0", "", "", "Demo Image Series #15 - Three Marios (PAL) (Non-Interleave) (06-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "151c33a71b99e6bcffb34b43c6f0ec23", "Parker Brothers, Laura Nikolich", "", "Care Bears (1983) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "151fa3218d8d7600114eb5bcd79c85cb", "Atari - CCW, Christopher H. Omarzu", "CX26104", "Big Bird's Egg Catch (05-02-1983) (Atari) (Prototype)", "Uses the Keypad Controller", "Prototype", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "152c253478b009c275e18cd731b48561", "", "", "Quest (11-10-2002) (Chris Larkin)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "153f40e335e5cb90f5ce02e54934ab62", "Absolute Entertainment, Alex DeMeo", "EAZ-041-04I", "Title Match Pro Wrestling (1987) (Absolute) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1542662f665d2ffaa77b4b897dd2e2af", "", "", "Starfield (V1.0) (2002) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "155fa7f479dcba3b10b1494e236d6010", "Skyworks", "", "Tomcat (2002) (Skyworks) (PAL)", "AKA The F-14 Flight Simulator", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "157356f80c709ab675961d8b8b207e20", "", "", "Multi-Sprite Game V2.5 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "157bddb7192754a45372be196797f284", "Atari, Warren Robinett - Sears", "CX2613, 49-75154", "Adventure (1980) (Atari)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "159e5cd6ccb968015f49aed5adbc91eb", "Justin J. Scott", "", "Yar's Defeat (2002) (Justin J. Scott) (Hack)", "Hack of Yars' Revenge", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "15a0d59304dece2c7d0580f3ea3527f0", "Atari, Jerome Domurat, Peter C. Niday", "CX26115", "Dumbo's Flying Circus (04-04-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "15b498199ed0ed28057bf0dbdce9b8d8", "Thomas Jentzsch", "", "Jammed (V0.2) (Demo) (2001) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "15b9f5e2439bfaa08874b5184261c777", "Bit Corporation", "R320", "Space Invaders (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "15bcd74f2f1f2a63e1aa93e90d2c0555", "", "", "Incoming (22-08-2002) (Ben Larson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "15bf2ef7583bfcbbba630847a1dc5539", "Erik Eid", "", "Euchre (Jul 15) (2002) (Eric Eid) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "15c11ab6e4502b2010b18366133fc322", "Atari - Axlon, Tod Frye - Heuristica, Augustin Ortiz", "CX26169", "Shooting Arcade (09-19-1989) (Atari) (Prototype)", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "15dd21c2608e0d7d9f54c0d3f08cca1f", "Data Age, J. Ray Dettling", "112-008", "Frankenstein's Monster (1983) (Data Age)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "15fe28d0c8893be9223e8cb2d032e557", "", "", "Towering Inferno (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "1619bc27632f9148d8480cd813aa74c3", "Thomas Jentzsch", "", "Steeple Chase (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "161ded4a85d3c78e44fffd40426f537f", "Thomas Jentzsch", "", "JtzBall (Alpha) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "16229d61d7b0c89b01853660a8da22bb", "", "", "spin4a50", "", "", "", "", "4A50", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "163e7e757e2dc44469123ff0e5daec5e", "", "", "Many Blue Bars and Text Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "169d4c7bd3a4d09e184a3b993823d048", "", "", "Superman (Unknown) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "16cb43492987d2f32b423817cdaaf7c4", "Atari, Larry Kaplan - Sears", "CX2602 - 99802, 6-99802, 49-75102", "Air-Sea Battle (1977) (Atari)", "AKA Target Fun (Anti-Aircraft)", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "16cc6d1b4ddce51c767a1ba8e5ff196c", "", "", "Big - Move This Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "16d69f71bf5846639be5ff16483f0498", "Bit Corporation", "R320", "Golf (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "16e04823887c547dc24bc70dff693df4", "Atari", "CX26163P", "Tennis (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "16ee443c990215f61f7dd1e55a0d2256", "Spectravideo, David Lubar", "SA-218, SA-218C", "Bumper Bash (1983) (Spectravideo) (PAL)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "PADDLES", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "16f494f20af5dc803bc35939ef924020", "Mark De Smet", "", "Video Simon (Mark De Smet)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "170e7589a48739cfb9cc782cbb0fe25a", "M Network - INTV - APh Technological Consulting, Hal Finney", "MT5666", "Astroblast (1982) (M Network) [fixed]", "Can also use left joystick", "Uncommon", "", "", "", "", "", "", "", "PADDLES", "", "", "", "", "", "YES", "", "", "AUTO 55", "", "", "", "" },
+  { "171cd6b55267573e6a9c2921fb720794", "Kurt Howe", "", "Adventure 34 (Kurt Howe) (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "171ebf135b13ba907f462c10d88a2c25", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Amiga Mouse Hack v1.1 (PAL60) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1733772165d7b886a94e2b4ed0f74ccd", "", "", "Boring Journey Escape (Hack)", "Hack of Journey - Escape", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1738b2e3f25ab3eef3cecb95e1d0d957", "", "", "Hangman Monkey Biglist1 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "17512d0c38f448712f49f36f9d185c4e", "Retroactive", "", "Qb (Release Candidate #1) (Retroactive)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "17515a4d0b7ea5029ffff7dfa8456671", "Piero Cavina", "", "Multi-Sprite Demo V1.1 (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "176d3fba7d687f2b23158098e103c34a", "Zach Matley", "", "Combat AI (16-02-2003) (Zach Matley)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "177504abd4260c4265e1338955e9fa47", "HCC Software", "", "Pitfall! (Steroids Hack)", "Hack of Pitfall! (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1782929e1c214b70fb6884f77c207a55", "Activision, David Crane", "AX-018, AX-018-04", "Pitfall! (1982) (Activision) (Prototype)", "Pitfall Harry's Jungle Adventure (Jungle Runner)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "17ba72433dd41383065d4aa6dedb3d91", "", "", "SCSIcide (09-06-2001) (Joe Grand)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "17badbb3f54d1fc01ee68726882f26a6", "M Network - INTV - APh Technological Consulting, Hal Finney, Bruce Pedersen", "MT5659", "Space Attack (1982) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "17bbe288c3855c235950fea91c9504e9", "Dismac", "", "Pega Ladrao (Dismac)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "17c0a63f9a680e7a61beba81692d9297", "U.S. Games Corporation - Western Technologies, Jeff Corsiglia, David Johnson, Tom Sloper", "VC2004", "Picnic (1983) (U.S. Games)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" },
+  { "17d000a2882f9fdaa8b4a391ad367f00", "Atari - GCC", "CX2676", "Centipede (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "17ee158d15e4a34f57a837bc1ce2b0ce", "Atari - GCC, Mike Feinstein, Kevin Osborn", "CX2691, CX2691P", "Joust (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "17ee23e5da931be82f733917adcb6386", "Salu, Dennis M. Kiss", "460758", "Acid Drop (1992) (Salu) (PAL)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1802cc46b879b229272501998c5de04f", "Atari - CCW, Christopher H. Omarzu", "CX26104", "Big Bird's Egg Catch (1983) (Atari)", "Uses Kids/Keypad Controllers", "Rare", "", "", "", "", "", "", "", "KEYBOARD", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" },
+  { "183020a80848e06a1238a1ab74079d52", "Thomas Jentzsch", "", "Missile Command (Amiga Mouse) (2002) (TJ) (PAL)", "Uses Amiga Mouse Controller", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "1862fca4f98e66f363308b859b5863af", "Atari", "", "128-in-1 Junior Console (Chip 1 of 4) (1991) (Atari) (PAL)", "Actually contains only 16 games, not 32", "", "", "", "16IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "18a970bea7ac4d29707c8d5cd559d03a", "", "", "Bridge (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "18b28b386abdadb3a700ac8fb68e639a", "Manuel Polik", "", "Gunfight 2600 (MP) (PAL)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "18b476a34ce5e6db2c032029873ac39b", "Bit Corporation", "R320", "Atlantis (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "18be8981b8201638f3ed8ae92bb4c215", "Thomas Jentzsch", "", "Missile Control - Amiga Mouse Hack v1.15 (PAL60) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "18bebbbd41c234f82b1717b1905e6027", "", "", "Space Instigators (Public Release) (02-01-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "18d26111cef66dff0c8af8cf0e117843", "", "", "Tunnel Demo (Cycling Colours 2) (29-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "18dc28bc22402f21e1c9b81344b3b8c5", "Atari - GCC, Mark Ackerman, Glenn Parker", "CX2684, CX2684P", "Galaxian (1983) (Atari) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "18ed63e3ce5bc3dd2d8bd188b807f1a2", "", "", "Stell-A-Sketch (Bob Colbert) (PD) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "18f299edb5ba709a64c80c8c9cec24f2", "Home Vision - Gem International Corp. - VDI", "VCS83111", "Asteroid Fire (1983) (Home Vision) (PAL)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "19098c46da0640f2b5763167dea6c716", "Andrew Wallace", "", "Laseresal 2002 (NTSC) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "191449e40b0c56411c70772706f79224", "", "", "Multi-Color Demo 2 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "19162393786098d50587827588198a86", "Jone Yuan Telephonic Enterprise Co", "", "Flag Capture (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "191ac4eec767358ee3ec3756c120423a", "", "", "Checkers (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "192aa2e8c795c9e10a7913e5d41feb81", "Atari - GCC, Jaques Hugon, Seth Lipkin", "CX26125", "Los Angeles 1984 Games (1984) (Atari) (Prototype) (PAL)", "AKA Track and Field (Uses Track & Field Controller)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "193f060553ba0a2a2676f91d9ec0c555", "Atari, Carol Shaw", "CX2636, CX2636P", "Video Checkers (1980) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1942bdb7abc75e412068330a9082b0ff", "Atari, Omegamatrix", "", "Super Breakout Menu (2020) (PAL) (Hack)", "Hack of Super Breakout", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 55", "", "", "", "" },
+  { "1986f864e32e3e8d198b5becf3022257", "Thomas Jentzsch", "", "Reactor - Atari Trak-Ball Hack v1.3 (PAL) (Half-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "199985cae1c0123ab1aef921daace8be", "", "", "Euchre (Release Candidate 2) (PAL) (01-10-2002) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "199eb0b8dce1408f3f7d46411b715ca9", "Parker Brothers, David Lamkins, Laura Nikolich", "PB5900", "Spider-Man (1982) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "19a9d3f9fa1b1358fb53009444247aaf", "", "", "Blackjack (Unknown) (PAL) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "19abaf2144b6a7b281c4112cff154904", "Atari, Brad Stewart", "CX2649, CX2649P", "Asteroids (1981) (Atari) (PAL) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "19b3b807507653516985ba95da92499d", "Joe Gaucher", "", "VCS Draw Demo (Joe Gaucher)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "19d6956ff17a959c48fcd8f4706a848d", "PlayAround - J.H.M.", "202", "Burning Desire (1982) (PlayAround)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "19d9b5f8428947eae6f8e97c7f33bf44", "", "", "Fortress (Dual Version) (20-04-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "19e739c2764a5ab9ed08f9095aa2af0b", "Atari, Andrew Fuchs, Jeffrey Gusman, Dave Jolly, Suki Lee", "CX26117", "Obelix (1984) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "19e761e53e5ec8e9f2fceea62715ca06", "Panda", "104", "Scuba Diver (1983) (Panda)", "AKA Skindiver", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1a23540d91f87584a04f184304a00648", "", "", "Race Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1a613ce60fc834d4970e1e674b9196b3", "Home Vision - Gem International Corp. - VDI", "VCS83135", "Tanks War (1983) (Home Vision) (PAL)", "AKA Phantom Tank", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1a624e236526c4c8f31175e9c89b2a22", "Rainbow Vision - Suntek", "SS-007", "Space Raid (1983) (Rainbow Vision) (PAL) [a]", "AKA MegaMania", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1a8204a2bcd793f539168773d9ad6230", "Atari, Rob Fulop - Sears", "CX2638 - 49-75166", "Missile Command (1981) (Atari) [no initials]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1aa7344b563c597eecfbfcf8e7093c27", "David Marli", "", "Slot Invaders (David Marli) (Hack)", "Hack of Slot Machine", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1b0f3d7af668eeea38ddd6182d8f48fb", "Jone Yuan Telephonic Enterprise Co", "", "Cosmic Swarm (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "1b1daaa9aa5cded3d633bfcbeb06479c", "", "", "Ship Demo (V 1502) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1b22a3d79ddd79335b69c94dd9b3e44e", "Tron", "", "Moon Patrol (Tron)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1b4b06c2a14ed3ee73b7d0fd61b6aaf5", "Arcadia Corporation, Stephen H. Landrum", "AR-4400", "Excalibur (Dragonstomper Beta) (1982) (Arcadia) (Prototype) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1b5a8da0622bffcee4c5b42aed4e0ef0", "Akor", "", "TV Boy II (1992) (Akor)", "Includes 127 games", "", "", "", "", "", "", "", "", "JOYSTICK", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "" },
+  { "1b8c3c0bfb815b2a1010bba95998b66e", "Telegames", "", "Frogs and Flies (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1b8d35d93697450ea26ebf7ff17bd4d1", "Quelle - Otto Versand", "176.764 9 - 781644", "Marineflieger (1983) (Quelle) (PAL)", "AKA Seahawk", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1bb91bae919ddbd655fa25c54ea6f532", "Suntek", "SS-026", "Treasure Island (1983) (Suntek) (PAL)", "AKA Treasure Discovery", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1bc2427ac9b032a52fe527c7b26ce22c", "Intellivision Productions - M Network - APh Technological Consulting, Bruce Pedersen, Larry Zwick", "MT5860", "Sea Battle (1983) (M Network)", "High Seas", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1bef389e3dd2d4ca4f2f60d42c932509", "Dimax - Sinmax", "SM8001", "Space Robot (1983) (Dimax - Sinmax) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "1bf503c724001b09be79c515ecfcbd03", "", "", "Bumper Bash (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1bfae770e089fa81412d04eb299f4c3f", "Thomas Jentzsch", "", "Marble Craze - Atari Mouse Hack v1.0 (NTSC) (TJ)", "Uses Atari Mouse Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1c3f3133a3e5b023c77ecba94fd65995", "CCE", "C-830", "Planet Patrol (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1c5796d277d9e4df3f6648f7012884c4", "Rainbow Vision - Suntek", "SS-012", "Hey! Stop! (1983) (Rainbow Vision) (PAL)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1c666ba5aac19b81671357e76062989b", "Nukey Shay, Omegamatrix", "", "Double Dragon (Genesis) (PAL60) V2", "Genesis controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1c6eb740d3c485766cade566abab8208", "Atari, Michael Kosaka, Peter C. Niday, Robert Vieira", "CX26110", "Crystal Castles (1984) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1c85c0fc480bbd69dc301591b6ecb422", "CCE", "", "Super Box (CCE)", "AKA RealSports Boxing", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1c8c42d1aee5010b30e7f1992d69216e", "PlayAround - J.H.M.", "205", "Gigolo (1982) (PlayAround)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "1cad3b56cc0e6e858554e46d08952861", "Jone Yuan Telephonic Enterprise Co", "", "Chopper Command (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1cafa9f3f9a2fce4af6e4b85a2bbd254", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX2659", "Raiders of the Lost Ark (1982) (Atari) (PAL)", "Console ports are swapped", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1cca2197d95c5a41f2add49a13738055", "Atari, Larry Kaplan - Sears", "CX2664 - 6-99818", "Brain Games (1978) (Atari)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" },
+  { "1cf59fc7b11cdbcefe931e41641772f6", "SEGA", "005-01", "Buck Rogers - Planet of Zoom (1983) (SEGA)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "1d1d2603ec139867c1d1f5ddf83093f1", "Atari, Larry Kaplan - Sears", "CX2602 - 99802, 6-99802, 49-75102", "Air-Sea Battle (1977) (Atari) (4K)", "AKA Target Fun (Anti-Aircraft)", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1d284d6a3f850bafb25635a12b316f3d", "CCE", "", "H.E.R.O. (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1d2a28eb8c95da0d6d6b18294211839f", "", "", "Fishing Derby (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1d4e0a034ad1275bc4d75165ae236105", "20th Century Fox Video Games, Mark Klein", "11034", "Pick Up (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1d5eac85e67b8cff1377c8dba1136929", "", "", "Chronocolor Donkey Kong Sideways (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1d6ed6fe9dfbde32708e8353548cbb80", "Jone Yuan Telephonic Enterprise Co", "", "Super Challenge Baseball (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1d72cc6ee466a4af1b27587b900ed430", "Atari, Omegamatrix", "", "Space Invaders Menu (2020) (Hack)", "Hack of Space Invaders", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1da2da7974d2ca73a823523f82f517b3", "Spectravision - Spectravideo - Sirius Software, David Lubar", "SA-206", "Challenge of.... Nexar, The (1982) (Spectravision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1db3bc4601f22cf43be7ce015d74f59a", "", "", "Ship Demo (V 10) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1e060a8025512ad2127e3da11e212ccc", "Arcadia Corporation, Scott Nelson", "13", "Sweat! - The Decathlon Game (3 of 3) (1983) (Arcadia) (Prototype)", "Uses the Paddle Controllers (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1e0ef01e330e5b91387f75f700ccaf8f", "Quelle - Otto Versand", "686.561 2 - 781627", "Mein Weg (1983) (Quelle) (PAL)", "AKA Challenge", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "1e1290ea102e12d7ac52820961457e2b", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (12-15-1983) (Parker Bros) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "1e272d09c0e55f5ef14fcb76a735f6d7", "Atari, David Crane", "CX26163P", "Slot Machine (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1e31b3a48865ba98d4d1aa5205115983", "Atari - Roklan, Bob Curtiss", "", "Firefox (1983) (Atari) (Prototype)", "AKA Combat II, Fighter Command", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1e587ca91518a47753a28217cd4fd586", "Telesys, Jim Rupp, Jack Woodman", "1001", "Coco Nuts (1982) (Telesys)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1e750000af77cc76232f4d040f4ab060", "Jone Yuan Telephonic Enterprise Co", "", "Raft Rider (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1e85f8bccb4b866d4daa9fcf89306474", "Atari, Lou Harp", "CX26122", "Sinistar (02-13-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1e89f722494608d6ea15a00d99f81337", "", "", "River Raid (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "NTSC50", "", "", "" },
+  { "1ea1abcd2d3d3d628f59a99a9d41b13b", "Jone Yuan Telephonic Enterprise Co", "", "Stampede (Jone Yuan) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1ea980574416bfd504f62575ba524005", "Atari - GCC, Mark Ackerman, Glenn Parker", "CX2675", "Ms. Pac-Man (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1ec57bbd27bdbd08b60c391c4895c1cf", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX26119", "Saboteur (09-02-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1ec5bef77b91e59313cba205f15b06d7", "", "", "Overhead Adventure Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1ede4f365ce1386d58f121b15a775e24", "Parker Brothers, Dave Hampton, Tom Sloper", "931517", "Q-bert (1983) (Parker Bros) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1ee2cfc7d0333b96bd11f7f3ec8ce8bc", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (4 of 4) (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1ee9c1ba95cef2cf987d63f176c54ac3", "Atari - GCC, Mark Ackerman, Glenn Parker", "CX2675, CX2675P", "Ms. Pac-Man (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1ef04e7e508296a8d9eb61cc7dae2e5d", "SOLID Corp. (D. Scott Williamson)", "CX2655-069", "Star Castle 2600 (SolidCorp) [069]", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "1f21666b8f78b65051b7a609f1d48608", "K-Tel Vision", "", "Vulture Attack (1982) (K-Tel Vision)", "AKA Condor Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1f2ae0c70a04c980c838c2cdc412cf45", "Atari - GCC", "CX2698", "Rubik's Cube (1984) (Atari)", "AKA Atari Video Cube", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1f349dd41c3f93c4214e5e308dccb056", "", "", "Virtual Pet Demo 2 (CRACKERS) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1f40eefc7447336ae6cd8ffa5eb325be", "Atari, Chris Crawford", "", "Wizard (1980) (Atari) (Prototype) (4K) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1f562b89d081e36d58e6fc943512ec05", "", "", "Hangman Man Biglist2 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1f5a2927a0b2faf87540b01d9d7d7fd1", "Pet Boat", "", "Tennis (Pet Boat) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1f60e48ad98b659a05ce0c1a8e999ad9", "", "", "Mondo Pong V2 (Piero Cavina) (PD)", "Uses the Paddle Controllers", "New Release", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "", "", "", "", "01", "", "", "", "" },
+  { "1f773a94d919b2a3c647172bbb97f6b4", "Atari, Jerome Domurat, Peter C. Niday", "CX26115", "Dumbo's Flying Circus (07-11-1983) (Atari) (Prototype) (PAL)", "AKA Dumbo Flies Home", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1fa58679d4a39052bd9db059e8cda4ad", "Imagic, Dan Oliver", "720118-1A, 03208", "Laser Gates (1983) (Imagic)", "AKA Innerspace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1fa7a42c2c7d6b7a0c6a05d38c7508f4", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (09-04-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "1fa86282403fa35d103ab88a9d603c31", "SpiceWare - Darrell Spice Jr.", "", "Stay Frosty (SpiceWare) (PAL60)", "Part of Stella's Stocking 2007 Xmas compilation", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "1fab68fd67fe5a86b2c0a9227a59bb95", "20th Century Fox Video Games - Videa, Lee Actor", "", "Lasercade (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "200309c8fba0f248c13751ed4fc69bab", "Jeffry Johnston", "", "Radial Pong - Version 1 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2008c76deba5953201ef75a09b2ff7dc", "", "", "Fortress (21-04-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "200a9d2a7cb4441ce4f002df6aa47e38", "", "", "Doomzerk (PD) (Hack)", "Hack of Berzerk", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2016726db38ad6a68b4c48ba6fe51557", "Piero Cavina, Erik Mooney", "", "INV 2 (Piero Cavina, Erik Mooney)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "203049f4d8290bb4521cc4402415e737", "Tigervision, Robert H. O'Neil - Teldec", "7-007 - 3.60005 VG", "Polaris (1983) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "203abb713c00b0884206dcc656caa48f", "Imagic, Bob Smith", "720114-1A, 03207, IZ-001-04", "Moonsweeper (1983) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "203b1efc6101d4b9d83bb6cc1c71f67f", "Quelle", "685.996 1", "Teller-Jonglieren! (1983) (Quelle) (PAL)", "AKA Dancing Plate", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "205070b6a0d454961dd9196a8e81d877", "", "", "Hangman Monkey Biglist2 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2058cf3fefad4d2bc03ed817cedddcd4", "Thomas Jentzsch", "", "Reactor - Amiga Mouse Hack v1.3 (PAL60) (Full-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2091af29b4e7b86914d79d9aaa4cbd20", "CBS Electronics - Woodside Design Associates, Harley H. Puthuff Jr.", "4L1802", "Donkey Kong Junior (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "20ae62fb69c6cc6e8098cca8cd080487", "Zirok", "", "Tennis (Zirok)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "20d4457ba22517253fcb62967af11b37", "Atari, Eric Manghise, Mimi Nyden, Joseph Tung", "CX2640", "RealSports Baseball (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "20dca534b997bf607d658e77fbb3c0ee", "Mythicon, Bill Bryner, Bruce de Graaf", "MA1002", "Fire Fly (1983) (Mythicon)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "20edcc3aa6c189259fa7e2f044a99c49", "Spectravision - Spectravideo", "SA-201", "Gangster Alley (1982) (Spectravision) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "211774f4c5739042618be8ff67351177", "Atari - GCC, Mark Ackerman, Tom Calderwood, Glenn Parker", "CX2684", "Galaxian (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "211f76dff0b7dad3f6fcac9d938ee61a", "JSK", "", "Custer's Viagra (JSK) (Hack) [a]", "Hack of Custer's Revenge", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "211fbbdbbca1102dc5b43dc8157c09b3", "Apollo", "AP-2009", "Final Approach (1982) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2124cf92978c46684b6c39ccc2e33713", "", "", "Sea Monster (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "21299c8c3ac1d54f8289d88702a738fd", "K-Tel Vision", "", "Spider Maze (1982) (K-Tel Vision)", "AKA Spider Kong", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "212d0b200ed8b45d8795ad899734d7d7", "Atari, Richard Maurer, Christopher H. Omarzu - Coca Cola", "", "Pepsi Invaders (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "213e5e82ecb42af237cfed8612c128ac", "Sancho - Tang's Electronic Co.", "TEC006", "Forest (1983) (Sancho) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "2162266b906c939b35c84ff9a0f50ad1", "Atari, Larry Kaplan", "CX2664, CX2664P", "Brain Games (1978) (Atari) (PAL) (4K)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" },
+  { "2179dfd7edee76efafe698c1bc763735", "", "", "Yellow Submarine (Cody Pittman) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "217b1452881264ac75126bf77b8d0db8", "Thomas Jentzsch", "", "Centipede - Atari Trak-Ball Hack v1.4 (NTSC) (Full-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "218b76f5a4142dc2ea9051a768583d70", "Atari - GCC, Mark Ackerman, Glenn Parker", "CX2684, CX2684P", "Galaxian (1983) (Atari) (PAL) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "218c0fe53dfaaa37f3c823f66eafd3fc", "Atari, Alan Miller", "CX2624, CX2624P", "Basketball (1978) (Atari) (PAL)", "Console ports are swapped", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "21a96301bb0df27fde2e7eefa49e0397", "Data Age", "DA1003", "Sssnake (1982) (Data Age)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "21b09c40295c2d7074a83ae040f22edf", "", "", "Marble Craze (V0.90) (Easy Version) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "21d2c435bcccde7792d82844b3cf60f4", "Atari - GCC, Doug Macrae", "CX2677, CX2677P", "Dig Dug (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "21d7334e406c2407e69dbddd7cec3583", "Activision, Bob Whitehead", "AG-011", "Stampede (1981) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2228c67d25e507603d4873d3934f0757", "", "", "Fu Kung! (V0.10) (28-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "22319be7a640af5314ec3c482cceb676", "", "", "Joustpong (05-07-2002) (Kirk Israel) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2240655247d6de1c585564004a853ab7", "", "", "Fu Kung! (V0.17) (07-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "225522777dc7155627808bde0c1d0ef0", "", "", "This Planet Sucks Demo 1 (Greg Troutman) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "22675cacd9b71dea21800cbf8597f000", "Atari, David Crane", "CX2605, CX2605P", "Outlaw (1978) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "227532d82505c3c185a878273c285d5f", "", "", "Hangman Man Original Words (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "22abbdcb094d014388d529352abe9b4b", "Apollo", "AP-2012", "Squoosh (1983) (Apollo) (Prototype) [a]", "AKA Vat's Incredible!, The Grape Escape", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "22b22c4ce240303012e8a9596ae8d189", "", "", "Skeleton+ (03-05-2003) (Eric Ball) (PAL)", "", "", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "22f6b40fc82110d68e50a1208ae0bb97", "", "", "Purple Bar Demo (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2319922df4d0c820b3e5f15faa870cc3", "Atari - GCC, Mike Feinstein", "CX2681, CX2681P", "Battlezone (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2327456f86d7e0deda94758c518d05b3", "Digitel", "", "Mr. Postman (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2351d26d0bfdee3095bec9c05cbcf7b0", "", "", "Warring Worms (19-01-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2353725ec98e0f0073462109e886efd7", "Champ Games", "CG-03-P", "Scramble (PAL60)", "Compatible with Genesis controller", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "235436ab0832370e73677c9c6f0c8b06", "", "", "Beast Invaders (Double Shot) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2365e1534d67f94d8670394ab99150ce", "Thomas Jentzsch", "", "Missile Command (Atari Mouse) (2002) (TJ)", "Uses Atari ST Mouse Controller", "Homebrew", "", "", "", "", "", "", "", "ATARIMOUSE", "", "", "ATARIMOUSE", "", "", "", "", "", "", "", "", "YES", "" },
+  { "23d445ea19a18fb78d5035878d9fb649", "CBS Electronics - JWDA, Sylvia Day, Todd Marshall, Henry Will IV", "4L1818, 4L1819, 4L1820, 4L1821", "Mouse Trap (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "23e4ca038aba11982e1694559f3be10f", "", "", "Big Dig (V3) (20-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "23fad5a125bcd4463701c8ad8a0043a9", "CCE", "C-840", "Stone Age (1983) (CCE)", "Uses the Joystick Controllers (swapped)", "", "", "", "", "A", "A", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "240bfbac5163af4df5ae713985386f92", "Activision, Steve Cartwright", "AX-022", "Seaquest (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2432f33fd278dea5fe6ae94073627fcc", "CBS Electronics, Tom DiDomenico", "4L2477, 4L2482, 4L2485, 4L4171", "Blueprint (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "2434102f30eeb47792cf0825e368229b", "Sparrow - Enter-Tech, Paul Walters, Rick Harris, George Hefner, Barbara Ultis", "", "Arkyology (1983) (Sparrow) (Prototype)", "ROM must be started in bank 0", "Prototype", "", "0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "24385ba7f5109fbe76aadc0a375de573", "CCE", "", "Xevious (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "2447e17a4e18e6b609de498fe4ab52ba", "CCE", "", "Super Futebol (CCE)", "AKA RealSports Soccer", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "244c6de27faff527886fc7699a41c3be", "", "", "Matt Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2450dfa1df70d12b60683185775efed8", "Jeffry Johnston", "", "Radial Pong - Version 7 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "24544ee5d76f579992d9522e9b238955", "Carrere Video - Western Technologies, Jeff Corsiglia, David Johnson, Tom Sloper - Teldec - Prism", "USC2004", "Picnic (1983) (Carrere Video) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" },
+  { "245f07c8603077a0caf5f83ee6cf8b43", "Home Vision - Thomas Jentzsch", "", "Parachute (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "24759be31e8fe55d2829fd86bdf3181f", "Hozer Video Games", "", "Gunfight 2600 - Worst Nightmare... (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "247fa1a29ad90e64069ee13d96fea6d6", "CCE", "C-867", "Radar (1983) (CCE)", "AKA Exocet", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "248668b364514de590382a7eda2c9834", "CBS Electronics, Richard K. Balaska Jr., Bob Curtiss, Alex Leavens, Alex Nevelson", "", "Kick-Man (01-08-82) (CBS Electronics) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2496d404bfc561a40a80bea6a69695c3", "CCE", "C-1007", "Jungle Hunt (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "24ad538291eb5f5cac4b9998f3b851c3", "", "", "Gunfight 2600 - This time it's your decission! (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "24aff972d58990f9b88a6d787c796f1e", "CBS Electronics", "4L1767, 4L1768, 4L1769, 4L1770", "Smurf (1982) (CBS Electronics) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "24b5f4bbdb853eca38ea0cae2dfe73a1", "", "", "Home Run (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "24b9adac1b4f85b0bac9bf9b9e180906", "Angelino", "", "Space 2002 (Angelino) (Hack)", "Hack of Space Jockey", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "24d018c4a6de7e5bd19a36f2b879b335", "Activision, Larry Miller", "AX-021", "Spider Fighter (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "24d9a55d8f0633e886a1b33ee1e0e797", "Thomas Jentzsch", "", "Dragon Defender (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "24df052902aa9de21c2b2525eb84a255", "Imagic, Dennis Koble", "720000-100, 720100-1B, IA3000, IA3000C", "Trick Shot (1982) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "24fbf8250a71611e40ef18552e61b009", "", "", "Movable Grid Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2516f4f4b811ede4ecf6fbeb5d54a299", "Quelle", "701.134 9", "Schiessbude (1983) (Quelle) (PAL)", "AKA Carnival", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2517827950fee41a3b9de60275c8aa6a", "Atari", "CX26163P", "Fishing (32 in 1) (1988) (Atari) (PAL)", "AKA Fishing Derby", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "25265d0e7f88b3026003809f25ee025e", "Atari - GCC, Ava-Robin Cohen", "CX26123", "Jr. Pac-Man (1984) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "25472dfdeef6a42581a231d631d6b04d", "", "", "Gunfight 2600 - Design thoughts (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "25710bde8fa181b0c5cf0846b983bec1", "", "", "Demo Image Series #15 - Three Marios (NTSC) (06-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "257bc3b72a6b5db3fd0d47619125b387", "CBS Electronics", "4L 2737 0000", "Omega Race (1983) (CBS Electronics) [a]", "Set right difficulty to 'A' for BoosterGrip in both ports", "", "", "", "", "", "", "", "", "BOOSTERGRIP", "", "", "BOOSTERGRIP", "", "", "", "", "", "", "", "", "", "" },
+  { "25a21c47afe925a3ca0806876a2b4f3f", "Quelle", "685.640 5", "Der kleine Baer (1983) (Quelle) (PAL)", "AKA Frostbite", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "25b52bf8dd215bcbd59c9abdb55c44f8", "Atari - GCC, Betty Ryan Tylko, Doug Macrae", "CX2694, CX2694P", "Pole Position (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "25b6dc012cdba63704ea9535c6987beb", "Avalon Hill, Jean Baer, Bill Hood", "5004002", "Shuttle Orbiter (1983) (Avalon Hill)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "25bb080457351be724aac8a02021aa92", "CBS Electronics", "4L1784, 4L1786, 4L1787, 4L2277", "Zaxxon (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "25d4be3309b89583c6b39d9f93bf654f", "Activision, Bob Whitehead", "AX-015, AX-015-04", "Chopper Command (1982) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "25e73efb9a6edf119114718bd2f646ba", "Atari, Suki Lee", "CX26113", "Miss Piggy's Wedding (1983) (Atari) (Prototype) (4K) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "25f2e760cd7f56b88aac88d63757d41b", "Activision, Bob Whitehead - Ariola", "EAG-002, EAG-002-04I, PAG-002 - 711 002-715", "Boxing (1980) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "25f879ff678130fea615ac418e7943f1", "Activision, Garry Kitchen", "EAX-025", "Keystone Kapers (1983) (Activision) (SECAM)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "25f9cf703575c5d63048c222f5463758", "", "", "Multi-Sprite Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "260c787e8925bf3649c8aeae5b97dcc0", "Thomas Jentzsch", "", "Hell Driver (Thomas Jentzsch)", "NTSC Conversion, joystick ports swapped", "Homebrew", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "262ccb882ff617d9b4b51f24aee02cbe", "Atari, Douglas Neubauer", "CX26154, CX26154P", "Super Football (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "265a85f66544eaf95fda06c3d9e48abf", "", "", "Tunnel Demo (Cycling Colours) (29-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "265c74a956500bd31efd24adc6d5ccf6", "Activision, Larry Miller", "AX-026, AX-026-04", "Enduro (1983) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2683d29a282dd059535ac3bb250f540d", "", "", "Space Treat (12-01-2003) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "268f46038e29301568fa9e443e16e960", "Atarius Maximum", "", "Pitfall Unlimited (Atarius Maximus) (Hack)", "Hack of Pitfall", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "26bc2bdf447a17376aea7ef187ff6e44", "", "", "Amanda Invaders (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "26f4f8b098609164effef7809e0121e1", "", "", "Oystron (V2.7) (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "270229c6d5578446e6a588492e4e5910", "", "", "Space Invaders 2 (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2712e91f6f1dc55e90e2b14b27c042ac", "Omegamatrix", "", "SpaceMaster X-7 (Amiga Mouse) (PAL60) (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "271bfd5dc2673d382019f1fb6cab9332", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (Preview) (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "273ce50db5a0d6da7ea827a54f44dee9", "", "", "Island Flyer Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "274d17ccd825ef9c728d68394b4569d2", "Playaround - J.H.M.", "202", "Bachelorette Party (1982) (Playaround)", "AKA Bachelor Party, Uses the paddle controllers", "Extremely Rare", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "YES", "" },
+  { "277c7281ac945b8331e2e6fcad560c11", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (2 of 3) (1983) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "277cca62014fceebb46c549bac25a2e3", "Activision, Bob Whitehead", "AG-002, CAG-002, AG-002-04", "Boxing (1980) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "277fa4b9a6bb7a8dcea2c5f38a4c25f0", "Atari, Alan J. Murphy, Robert Zdybel", "CX2668", "RealSports Football (1982) (Atari) (Prototype)", "AKA Football II", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "278155fc9956e9b6ef2359eb238f7c7f", "", "", "Donkey Kong Junior (Unknown) (Hack)", "Hack of Donkey Kong Junior", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2783006ee6519f15cbc96adae031c9a9", "Telegames", "", "Night Stalker (1989) (Telegames) (PAL) [a]", "AKA Dark Cavern", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "278531cc31915747018d22145823d2c9", "", "", "Defender MegaDrive (PAL) (Genesis)", "Genesis controller (C is smartbomb)", "Hack of Defender", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "278f14887d601b5e5b620f1870bc09f6", "Thomas Jentzsch", "", "SWOOPS! (v0.96) (TJ)", "Uses the Joystick (L) and Paddle (R) Controllers", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "27a5d2d0c74c8e4b2c05b94c9f098eea", "Atari, Omegamatrix", "", "Video Olympics Menu (2020) (PAL60) (Hack)", "Hack of Video Olympics", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "AUTO 60", "", "", "", "" },
+  { "27baecd618e7e53dc11f2a9c559f529d", "Omegamatrix", "", "Star Wars Arcade (Atari Trak-Ball) v4 (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "27c4c2af4b46394bb98638af8e0f6e9d", "Atari, Jerome Domurat, Peter C. Niday, Robert Vieira", "CX26109", "Sorcerer's Apprentice (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "27c6a2ca16ad7d814626ceea62fa8fb4", "Parker Brothers, Mark Lesser", "PB5590", "Frogger II (1984) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "27f9e2e1b92af9dc17c6155605c38e49", "CCE", "", "Nightmare (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2808dc745ff4321dc5c8122abef6711f", "Retroactive", "", "Qb (2.11) (Retroactive) (Stella)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "28148a52b1955ce12c7a74d3a3e620a4", "CCE", "", "Freeway (CCE) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "281ff9bd0470643853de5cbd6d9e17f5", "Eckhard Stolberg", "", "Cubis (EM) (1997) (Eckhard Stolberg)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2823364702595feea24a3fbee138a243", "Bit Corporation", "PG206", "Bobby Is Going Home (1983) (BitCorp) (PAL)", "AKA Bobby geht Heim", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2825f4d068feba6973e61c84649489fe", "", "", "Boom Bang (Unknown) (PAL)", "AKA Crackpots", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "282a77841cb3d33af5b56151acba770e", "Otto Versand", "311388", "Black Hole (1983) (Otto Versand) (PAL)", "AKA Cosmic Ark (Double-Game Package)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "283cb03ee031c842beabdad1aa4e7dbc", "Bit Corporation", "R320", "Demon Attack (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "283dee88f295834c4c077d788f151125", "Retroactive", "", "Qb (2.11) (Retroactive) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "284ca61b2407bdba3938048b0a559015", "Atari, Tod Frye", "CX2695", "Xevious (05-25-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "2854e5dfb84173fafc5bf485c3e69d5a", "Canal 3 - Intellivision", "C 3004", "Moon Patrol (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2880c6b59bd54b153174676e465167c7", "Tron", "", "Donkey Kong Jr. (Tron)", "AKA Donkey Kong Junior", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "28a2bea8f84936cb2e063f857414cda0", "Thiago Paiva", "", "Mega Mania Raid (1999) (Thiago Paiva) (Hack)", "Hack of Megamania", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "28a4cd87fb9de4ee91693a38611cb53c", "", "", "Skeleton (V1.1) (NTSC) (24-10-2002) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "28d5df3ed036ed63d33a31d0d8b85c47", "Bit Corporation", "PG204", "Open, Sesame! (1983) (BitCorp) (PAL)", "AKA Sesam, Offne Dich", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "2903896d88a341511586d69fcfc20f7d", "Activision, David Crane", "AX-014, AX-014-04", "Grand Prix (1982) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "291bcdb05f2b37cdf9452d2bf08e0321", "Atari", "CX26163P", "32 in 1 Game Cartridge (1988) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "32IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "291cc37604bc899e8e065c30153fc4b9", "Activision, Carol Shaw", "AX-020, AX-020-04", "River Raid (1982) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "291dd47588b9158beebe4accc3a093a6", "Atari", "", "32 in 1 Console ROM (02-10-1989) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "32IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "292a0bb975b2587f9ac784c960e1b453", "", "", "Qb (05-02-2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "292f2446a0325b7b423e88a2ebfeb5a0", "", "", "Cube Conquest (Non Interlaced) (Billy Eno) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "29396db58406084e416032c372734a3e", "", "", "Gunfight 2600 - Fixed Beta Release! (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2942680c47beb9bf713a910706ffabfe", "", "", "Blue Line Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "294762000e853b4319f9991c1ced5dfc", "", "", "T.F. Space Invaders (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "295f3679bdf91ca5e37da3f787b29997", "", "", "Exorcise (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "29630a20d356fb58685b150bfa8f00c3", "M Network, Kevin Miller", "MT5687", "International Soccer (1982) (Mattel) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "297236cb9156be35679f83c4e38ee169", "Exus Corporation", "", "Video Reflex (1983) (Exus) [no roman numbers]", "AKA Foot Craz (no roman numbers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "297c405afd01f3ac48cdb67b00d273fe", "Atari - GCC, Ava-Robin Cohen", "CX26123, CX26123P", "Jr. Pac-Man (1986) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2982e655dffc89d218a0a3072cfc6811", "", "", "Mini Golf 812631 (Hack)", "Hack of Miniature Golf", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "298387b0637173d2002770a649b4fbca", "", "", "S.I.PLIX 2 (Hack) [a]", "Hack of Kaboom!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
+  { "29843f43b81f3736bf35c00b1bb88fb2", "Gray Games & AtariAge", "", "E.T. Book Cart (NTSC)", "Charles F. Gray & Michael Rideout", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "55" },
+  { "29949f893ef6cb9e8ecb368b9e99eee4", "Erik Eid", "", "Euchre (Alpha) (NTSC) (31-08-2002) (Erik Eid)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "29dfa26b7988af9984d617708e4fc6e2", "", "", "Boulderdash Demo (05-04-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2a0ba55e56e7a596146fa729acf0e109", "Activision, Bob Whitehead", "AG-019", "Sky Jinks (1982) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2a10053fd08664c7cfbbb104386ed77f", "", "", "Alpha Demo - The Beta Demo (2000) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2a1b454a5c3832b0240111e7fd73de8a", "Tigervision, Bill Hogue", "7-011", "Miner 2049er Volume II (1983) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "2a2f46b3f4000495239cbdad70f17c59", "CommaVid, John Bronstein - Ariola", "CM-003 - 712 003-720", "Cosmic Swarm (1982) (CommaVid) (PAL)", "AKA Angriff der Termiten", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "2a33e21447bf9e13dcfed85077ff6b40", "", "", "Backwards Cannonball v2 (Hack)", "Hack of Human Cannonball", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2a360bc85bf22de438651cf92ffda1de", "Bit Corporation", "PGP213", "Spy Vs. Spy (4 Game in One) (1983) (BitCorp) (PAL)", "AKA Chopper Command", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2a9f9001540c55a302befd8e9d54b47b", "Atari, Dan Hitchens", "CX2697, CX2697P", "Mario Bros. (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2aa5e56d36c2e58b6f2856109f2099a9", "Atari, Larry Kaplan - Sears", "CX2628 - 6-99842, 49-75117", "Bowling (1979) (Atari) (4K) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2aba6a1b01a5859e96d6a66d2286772f", "Activision, Steve Cartwright", "AX-027", "Plaque Attack (1983) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2abc3d46b3f2140160759e2e10bc86d9", "", "", "Gunfight 2600 - Beta Release! (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2ac3a08cfbf1942ba169c3e9e6c47e09", "Activision, Dan Kitchen", "EAK-046-04B", "Fighter Pilot (1988) (Activision) (PAL)", "AKA Tomcat - The F-14 Fighter Simulator", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2ae700c9dba843a68dfdca40d7d86bd6", "TechnoVision - Thomas Jentzsch", "", "Pharaoh's Curse (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "2aeedcc6eb1602efb77161b0cef832ab", "SOLID Corp. (D. Scott Williamson)", "CX2655-025", "Star Castle 2600 (SolidCorp) [025]", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "2b1589c7e1f394ae6a1c046944f06688", "Carrere Video - JWDA, Todd Marshall, Robin McDaniel, Wes Trager, Henry Will IV - Teldec - Prism", "USC2003", "Eggomania (1983) (Carrere Video) (PAL)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 60", "", "", "", "" },
+  { "2b27eb194e13f3b38d23c879cc1e3abf", "Quelle", "402.272 9", "Super-Ferrari (1983) (Quelle) (PAL)", "AKA Enduro", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2b42da79a682ed6e2d735facbf70107e", "", "", "DKjr Improved (Hack)", "Hack of Donkey Kong Jr.", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2b430c00dc79e495762ac59b2f9b4fcd", "Activision, David Crane", "AX-018, AX-018-04", "Pitfall! (1982) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2b71a59a53be5883399917bf582b7772", "Greg Troutman", "", "Dark Mage (final beta) (Greg Troutman) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "2ba02f509a4991aa176ba8d9e540df3d", "Atari, Mark R. Hahn", "CX2678", "Dukes of Hazzard (1983) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2bb0a1f1dee5226de648eb5f1c97f067", "Robby", "", "Enduro (Robby)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2bb9f4686f7e08c5fcc69ec1a1c66fe7", "Atari - GCC, John Allred, Mike Feinstein", "CX2688", "Jungle Hunt (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2bc26619e31710a9884c110d8430c1da", "Atari, Bob Whitehead", "CX2652, CX2652P", "Casino (1979) (Atari) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2bc6c53b19e0097a242f22375a6a60ff", "", "", "Droid Demo 2 (David Conrad Schweinsberg) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2bee7f226d506c217163bad4ab1768c0", "Xonox - K-Tel Software - Beck-Tech, Steve Beck", "6210, 06002, 06004, 99002", "Ghost Manor (1983) (Xonox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2bf34b6ad7d2317a2d0808b3fb93571b", "", "", "Easy Playfield Graphics (1997) (Chris Cracknell)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2c0dc885d5ede94aa664bf3081add34e", "", "", "Earth Dies Screaming, The (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2c29182edf0965a7f56fe0897d2f84ba", "Atari - Axlon, Steve DeFrisco", "CX26192", "Klax (08-18-1990) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2c2aea31b01c6126c1a43e10cacbfd58", "Paul Slocum", "", "Synthcart (2002) (Paul Slocum)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "2c3b2843295c9d6b16996971180a3fe9", "HES - Activision", "", "Sports Action Pak - Enduro, Ice Hockey, Fishing Derby, Dragster (1988) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2c3b9c171e214e9e46bbaa12bdf8977e", "Bit Corporation", "R320", "Othello (32 in 1) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2c45c3eb819a797237820a1816c532eb", "Atari", "CX26163P", "Boxing (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2c8835aed7f52a0da9ade5226ee5aa75", "Arcadia Corporation, Stephen H. Landrum", "AR-4101", "Communist Mutants from Space (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2c8c11295d8613f875b7bcf5253ab9bb", "Fabrizio Zavagli", "", "Kool Aid Man (PAL Conversion) (16-11-2002) (Fabrizio Zavagli) (PAL60)", "PAL60 Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2c9fadd510509cc7f28f1ccba931855f", "", "", "Hangman Invader Biglist1 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2ca6445204ffb7686ddee3e33ba64d5b", "Alex Herbert", "", "AtariVox Test ROM", "Uses the AtariVox controller", "", "", "", "", "", "", "", "", "", "", "", "ATARIVOX", "", "", "", "", "", "", "", "", "", "" },
+  { "2cb42cf62b2f25f59f909b5447821b14", "Atari, Christopher H. Omarzu - Children's Computer Workshop", "CX26104", "Big Bird's Egg Catch (1983) (Atari) (PAL) [a]", "Uses Kids/Keypad Controllers", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" },
+  { "2cc3049b7feb8e92f1870f1972629757", "Video Soft", "", "Atom Smasher (1984) (Video Soft) (Prototype) [stack pointer fix]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2cccc079c15e9af94246f867ffc7e9bf", "PlayAround - J.H.M.", "203", "Jungle Fever (1982) (PlayAround)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "2cefa695df2ed020899a7df7bb1e3a95", "Manuel Polik, Fabrizio Zavagli", "", "A-Team (2002) (Manuel Polik) (Hack)", "Hack of A-Team", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2cf20f82abcae2decff88db99331e071", "Activision, Mike Lorenzen", "AX-023", "Oink! (1983) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2cfb188c1091cc7ec2a7e60064d2a758", "", "", "Space Invaders Hack Demo (2003) (SnailSoft)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2d15b092e8350912ec4b2e5e750fa1c6", "Wizard Video Games, Bob Davis, Robert H. O'Neil", "", "Texas Chainsaw Massacre, The (1982) (Wizard Video Games) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2d16a8b59a225ea551667be45f554652", "Quelle", "802.744 3", "Der Geheimkurier (1983) (Quelle) (PAL)", "AKA Mr. Postman", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2d1cf85fbc732856bf76470cd4060f4a", "", "", "Daredevil (V1) (Stunt_Cycle_Rules!) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2d2c5f0761e609e3c5228766f446f7f8", "Atari - Axlon, Steve DeFrisco", "CX26170, CX26170P", "Secret Quest (1989) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2d33a44e82f88d05f6c50577218c0cae", "AtariAge - Michael Haas", "RC2", "Flappy (2014) (AtariAge)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2d38a96f92952b301eefdf25a5e6976b", "Omegamatrix", "", "Star Wars Arcade (Atari Mouse) (Y_Inverted) v4 (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2d405da70af82b20a6b3ecc3d1d2c4ec", "Genus", "", "Pitfall (Genus)", "AKA Pitfall!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2d6388a8389f1d59108fd169c3356d79", "Thomas Jentzsch", "", "Reactor - Atari Mouse Hack v1.3 (NTSC) (Half-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2d63b452f897818c52b3fceeb080a4d0", "HES - Absolute Entertainment", "", "Pete Rose Baseball (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2d6741cda3000230f6bbdd5e31941c01", "CBS Electronics - VSS", "80110", "Targ (1983) (CBS Electronics) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2d69a5f23784f1c2230143292a073b53", "", "", "Qb (Fixed background animation) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "2d6da0eb85eabc93270e5bb8a466ca51", "", "", "Sprite Demo 7 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2d76c5d1aad506442b9e9fb67765e051", "Apollo - Games by Apollo, Larry Minor, Ernie Runyon, Ed Salvo", "AP-2004", "Lost Luggage (1982) (Apollo) [no opening scene]", "AKA Airport Mayhem", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2d9e5d8d083b6367eda880e80dfdfaeb", "QDI, Mike Montana, Rich Montana - Selchow & Righter", "87", "Glib (1983) (QDI)", "AKA Video Word Game", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2d9e65959808a6098c16c82a59c9d9dc", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (1 of 3) (1982) (Starpath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2dbc92688f9ba92a7e086d62be9df79d", "", "", "How to Draw a Playfield (1997) (Jim Crawford) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2dbdca3058035d2b40c734dcf06a86d9", "Thomas Jentzsch", "", "Asteroids DC+ (Thomas Jentzsch) (Hack)", "Uses the Joystick (left) or Driving (right) Controller", "Hack", "", "", "", "", "", "", "", "", "", "", "DRIVING", "", "", "", "", "", "58", "", "", "YES", "" },
+  { "2dcf9ce486393cd36ca0928cd53b96cb", "Atari - GCC, Mike Feinstein, John Allred", "CX2688, CX2688P", "Jungle Hunt (1983) (Atari) (PAL) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2de41a11c6767e54a5ee9ebaffec72af", "Gray Games & AtariAge", "", "E.T. Book Cart (PAL60)", "Charles F. Gray & Michael Rideout", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "55" },
+  { "2dfec1615c49501fefc02165c81955e6", "", "", "Song (05-11-2002) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "2e0aed5bb619edcefa3fafb4fbe7c551", "", "", "Qb (2.06) (Retroactive) (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "2e2acef8513edcca991e7e5149412e11", "Parker Brothers, Larry Gelberg, Gary Goltz", "PB5065", "Star Wars - Ewok Adventure (1983) (Parker Bros) (Prototype) (16K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2e3728f3086dc3e71047ffd6b2d9f015", "Atari, David Crane", "CX26163P", "Outlaw (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2e5b184da8a27c4d362b5a81f0b4a68f", "Atari", "", "Rabbit Transit (08-29-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2e663eaa0d6b723b645e643750b942fd", "Atari, Tom Rudadahl - Sears", "CX2634 - 49-75121", "Golf (1980) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2e7e9c6dcfcceaffc6fa73f0d08a402a", "CCE", "C-818", "Star Voyager (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2e82a1628ef6c735c0ab8fa92927e9b0", "Atari, Jerome Domurat, Peter C. Niday, Robert Vieira", "CX26109", "Sorcerer's Apprentice (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2e842c2ee22e9dad9df16eed091315c4", "HES", "701-157", "2 Pak Special - Moto-cross, Boom Bang (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2eaf8fa9e9fdf1fcfc896926a4bdbf85", "Arcadia Corporation, Stephen H. Landrum", "AR-4400", "Excalibur Version 39 (Dragonstomper Beta) (1982) (Arcadia) (Prototype)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2ec6b045cfd7bc52d9cdfd1b1447d1e5", "Activision, David Crane - Ariola", "EAG-009, PAG-009 - 711 009-720", "Freeway (1981) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2eda6a49a49fcb2b674ea9e160b6a617", "Kyle Pittman", "", "Rambo in Afghanistan (Kyle Pittman) (Hack)", "Hack of Riddle of the Sphinx", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2ef36341d1bf42e02c7ea2f71e024982", "", "", "Space Invaders (Explosion Hack)", "Hack of Space Invaders (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2f0546c4d238551c7d64d884b618100c", "SEGA, Jeff Lorenz", "", "Ixion (1984) (SEGA) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2f0a8bb4e18839f9b1dcaa2f5d02fd1d", "CCE", "", "Super Futebol (CCE) [a]", "AKA RealSports Football", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "2f11ba54609777e2c6a5da9b302c98e8", "Atari - GCC", "CX2676", "Centipede (1982) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2f16663b01591539624d0ef52934a17d", "M Network", "", "Rocky and Bullwinkle", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2f2f9061398a74c80420b99ddecf6448", "Rentacom - Brazil", "", "Bobby Is Going Home (Rentacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2f66ebf037321ed0442ac4b89ce22633", "Baroque Gaming (Brian Eno)", "", "Warring Worms (Beta 2) (2002) (Baroque Gaming)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2f7772879a1ed04f660aa9d77a86a4bd", "", "", "Yars' Revenge (Genesis)", "Genesis controller (C is zorlon cannon)", "Hack of Yars' Revenge", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "2f77f015fc880b05f28e84156f989a0c", "", "", "Plane Demo (Gonzalo) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2f7949f71076db42480d3f5036b4a332", "", "", "Name This Game (208 in 1) (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "2facd460a6828e0e476d3ac4b8c5f4f7", "Sancho - Tang's Electronic Co.", "", "Words-Attack (1983) (Sancho) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "3025bdc30b5aec9fb40668787f67d24c", "", "", "Demo Image Series #14 - Two Marios (4K Interleaved Chronocolour Vertical Movement) (05-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "303242c239474f2d7763b843de58c1c3", "CCE", "", "Laser Blast (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "304512528a5530a9361e8a231ed9a6de", "Thomas Jentzsch", "", "River Raid Plus (Thomas Jentzsch) (Hack)", "Hack of River Raid", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "30512e0e83903fc05541d2f6a6a62654", "Atari, Jim Huether - Sears", "CX2644 - 6-99824", "Flag Capture (1978) (Atari)", "AKA Capture the Flag", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "30516cfbaa1bc3b5335ee53ad811f17a", "Wizard Video Games - MicroGraphic Image, Robert Barber, Tim Martin", "007", "Halloween (1983) (Wizard Video Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3051b6071cb26377cd428af155e1bfc4", "Atari, David Crane - Sears", "CX2607 - 6-99828, 49-75115", "Canyon Bomber (1979) (Atari) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "", "YES", "", "", "10", "", "", "", "" },
+  { "30685b9b6ebd9ba71536dd7632a1e3b6", "Dactari - Milmar", "", "Tennis (Dactari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3091af0ef1a61e801f4867783c21d45c", "CCE", "C-862", "Crackpots (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "30997031b668e37168d4d0e299ccc46f", "", "", "John K Harvey's Equalizer (PAL) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "30c92c685224dc7a72b9bbe5eb62d004", "", "", "Hangman Monkey Original Words (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "30e012e8d50330c8972f126b8e913bc4", "", "", "Indy 500 (Hack) [a2]", "Hack of Indy 500", "Hack", "", "", "", "", "", "", "", "DRIVING", "", "", "DRIVING", "", "", "", "", "", "", "", "", "", "" },
+  { "30e0ab8be713208ae9a978b34e9e8e8c", "Atari, Mike Lorenzen", "CX2630, CX2630P", "Circus Atari (1980) (Atari) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 55", "", "", "", "" },
+  { "30f0b49661cfcfd4ec63395fab837dc3", "SEGA, Jeff Lorenz - Teldec", "004-01", "Star Trek - Strategic Operations Simulator (1983) (SEGA) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "3105967f7222cc36a5ac6e5f6e89a0b4", "SEGA, Jeff Lorenz", "011-01, 011-02", "Spy Hunter (1984) (SEGA)", "Uses Joystick Coupler (Dual Control Module)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "310ba30e25ea8957e58180b663503c0c", "Ed Federmeyer", "", "Sound X6 (1994) (Ed Federmeyer)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "31235a27b065c2863048fa84db330dc6", "Thomas Jentzsch", "", "Missile Control - Amiga Mouse Hack v1.15 (PAL) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "313243fc41e49ef6bd3aa9ebc0d372dd", "", "", "Fast Food (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "31512cdfadfd82bfb6f196e3b0fd83cd", "Tigervision", "7-004", "River Patrol (1984) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3177cc5c04c1a4080a927dfa4099482b", "Atari - Imagineering, Alex DeMeo", "CX26135", "RealSports Boxing (1987) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "317a4cdbab090dcc996833d07cb40165", "Goliath - Hot Shot", "83-312", "Missile War (1983) (Goliath) (PAL)", "AKA Astrowar", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "318046ae3711c05fd16e479b298e5fcc", "Retroactive", "", "Qb (V2.08) (Stella) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "318a9d6dda791268df92d72679914ac3", "Activision, Steve Cartwright", "AX-017, AX-017-04", "MegaMania (1982) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "319a142aab6260842ab616382848c204", "", "", "Marble Craze (05-02-2002) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "31bb9b8ceed46cb3e506777a9e65f3ce", "Bit Corporation", "", "4 Game in One Light Green (1983) (BitCorp) (PAL)", "Phantom UFO, Ice Hockey, Cosmic Avenger, Spy Vs. Spy", "", "", "", "4IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "31c5fd55a39db5ff30a0da065f86c140", "Dactari - Milmar", "", "Enduro (Dactari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "31d08cb465965f80d3541a57ec82c625", "Atari, Alan Miller - Sears", "CX2641 - 99807, 49-75105", "Surround (1977) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "31df1c50c4351e144c9a378adb8c10ba", "Quelle", "687.463 0", "Die Ratte und die Karotten (1983) (Quelle) (PAL)", "AKA Gopher", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "31e518debba46df6226b535fa8bd2543", "Atari, Douglas 'Solaris' Neubauer, Mimi Nyden", "CX26134", "Last Starfighter (1984) (Atari) (Prototype)", "Solaris Beta", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "31f4692ee2ca07a7ce1f7a6a1dab4ac9", "Atari, Alan Miller", "CX2642", "Game of Concentration (1980) (Atari) (4K)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "31fcbce1cfa6ec9f5b6de318e1f57647", "Atari, Jerome Domurat, Peter C. Niday", "CX26115", "Dumbo's Flying Circus (1983) (Atari) (Prototype) (PAL)", "AKA Dumbo Flies Home", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "32199271dc980eb31a2cc96e10a9e244", "", "", "Radial Pong - Version 12 (Jeffry Johnston) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "321c3451129357af42a375d12afd4450", "Atari - Imagineering, Dan Kitchen", "CX26177", "Ikari Warriors (1991) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "32244e55ce6ec6bfbd763f33384bdc2e", "Activision, Steve Cartwright", "AX-027", "Plaque Attack (1983) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3225676f5c0c577aeccfaa7e6bedd765", "CCE", "C-1002", "Pole Position (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "322b29e84455aa41e7cc9af463bffa89", "Atari - Bobco, Robert C. Polaro", "CX2663", "Road Runner (06-25-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "324cb4a749bcac4f3db9da842b85d2f7", "Dennis Debro", "", "Climber 5 (01-05-2003) (Dennis Debro)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "327468d6c19697e65ab702f06502c7ed", "Charles Morgan", "", "Aster-Hawk (2002) (Charles Morgan) (Hack)", "Hack of Asteroids", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "3276c777cbe97cdd2b4a63ffc16b7151", "Atari - GCC, Mike Feinstein, Kevin Osborn", "CX2691", "Joust (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "3278158e5c1f7eb5c5d28ccfd7285250", "Dactari - Milmar", "", "Megamania (Dactari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "327fe8cf94f3a45c35a840a453df1235", "", "", "Spice Girls Rule Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "328949872e454181223a80389d03c122", "", "", "Home Run (Unknown) (PAL)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "32ae78abbb5e677e2aabae5cc86cec29", "Atari, Christopher H. Omarzu, Courtney Granner", "CX26112", "Good Luck, Charlie Brown (04-18-1984) (Atari) (Prototype)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "32d1260ea682e1bb10850fa94c04ec5f", "Atari, Alan Miller", "CX26163P", "Basketball (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "32dcd1b535f564ee38143a70a8146efe", "Xonox - K-Tel Software - Product Guild, Anthony R. Henderson", "99007, 6240", "Tomarc the Barbarian (1983) (Xonox)", "AKA Thundarr the Barbarian", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "32e65d1e4dfcbcd9b57fee72cafe074c", "", "", "Eckhard Stolberg's Scrolling Text Demo 3 (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "32ecb5a652eb73d287e883eea751d99c", "Dactar - Milmar", "", "Bowling (Dactar - Milmar)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "32f4e47a71601ab06cfb59e1c6a0b846", "Ed Federmeyer", "", "Sound X (1994) (Ed Federmeyer)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3316ee2f887e9cb9b54dd23c5b98c3e2", "", "", "Texas Golf (miniature Gold Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "331938989f0f33ca39c10af4c09ff640", "Zach Matley", "", "Combat - Tank AI (19-04-2003) (Zach Matley)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "332f01fd18e99c6584f61aa45ee7791e", "", "", "X'Mission (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "3347a6dd59049b15a38394aa2dafa585", "Parker Brothers - JWDA, Henry Will IV", "PB5760", "Montezuma's Revenge (1984) (Parker Bros)", "Featuring Panama Joe", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "335793736cbf6fc99c9359ed2a32a49d", "", "", "Analog Clock (V0.0) (20-01-2003) (AD) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "335a7c5cfa6fee0f35f5824d1fa09aed", "SEGA - Beck-Tech, Steve Beck, Phat Ho - Teldec", "006-01 - 3.60105 VG", "Congo Bongo (1983) (SEGA) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3367eeba3269aa04720abe6169767502", "", "", "Space Treat (30-12-2002) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "336ea20d38f98926919d4b4651d1a03f", "Omegamatrix", "", "Omega Race (Genesis) V2", "Genesis controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3391f7c4c656793f92299f4187e139f7", "Commavid, Ben Burch", "CM-010", "Rush Hour (1983) (Commavid) (Prototype) [a4]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "33cac5e767a534c95d292b04f439dc37", "Jone Yuan Telephonic Enterprise Co", "", "Tapeworm (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "33d68c3cd74e5bc4cf0df3716c5848bc", "CBS Electronics, Tom DiDomenico", "4L 2486 5000", "Blueprint (1983) (CBS Electronics)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "33ed6dfac4b9ea2f81f778ceddbb4a75", "Activision", "", "River Raid (1982) (SpkSoft) [t1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "340f546d59e72fb358c49ac2ca8482bb", "Sancho - Tang's Electronic Co.", "TEC003", "Skindiver (1983) (Sancho) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "34340c8eecd1e557314789cc6477e650", "Joe Grand", "", "SCSIcide Pre-release 4 (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "345488d3b014b684a181108f0ef823cb", "CBS Electronics, Tom DiDomenico", "4L 2486 5000", "Blueprint (1983) (CBS Electronics) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "345758747b893e4c9bdde8877de47788", "CBS Electronics, Joseph Biel", "4L1802, 4L1803, 4L1804, 4L2278", "Venture (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "345769d085113d57937198262af52298", "Rainbow Vision - Suntek", "SS-007", "Space Raid (1983) (Rainbow Vision) (PAL)", "AKA MegaMania", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "346555779a2d51b48833463b5433472f", "Thomas Jentzsch", "", "Thrust (V0.1) (2000) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "348615ffa30fab3cec1441b5a76e9460", "Activision, Alan Miller - Ariola", "EAX-016, PAX-016 - 711 016-725", "StarMaster (1982) (Activision) (PAL) [fixed]", "Use Color/BW switch to change between galactic chart and front views", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "34b269387fa1aa5a396636f5ecdd63dd", "", "", "Marble Craze (mc7_23) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "34c808ad6577dbfa46169b73171585a3", "Apollo", "AP-2012", "Squoosh (1983) (Apollo) (Prototype)", "AKA Vat's Incredible!, The Grape Escape", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "34ca2fcbc8ba4a0b544acd94991cfb50", "Atari, Robert C. Polaro", "", "Dukes of Hazzard (1980) (Atari) (Prototype) (4K)", "AKA Stunt Cycle", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "34e37eaffc0d34e05e40ed883f848b40", "Retroactive", "", "Qb (2.15) (Retroactive) (Stella)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "34f4b1d809aa705ace6e46b13253fd3b", "Aaron Bergstrom", "", "Nothern Alliance (Aaron Bergstrom) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "34fd4fcb40ff5babce67f8b806d5969c", "", "", "Boxing (Dactari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "350e0f7b562ec5e457b3f5af013648db", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX26119", "Saboteur (06-09-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "35156407e54f67eb1f625450d5c093e1", "", "", "Mouse Trap (Genesis)", "Genesis controller (C changes to dog)", "Hack of Mouse Trap", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "35163b56f4a692a232ae96ad3e23310f", "Retroactive", "", "Qb (2.12) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "3545eb3b8b1e7dc19f87d231ab0b1d4c", "CBS Electronics - Roklan, Joe Hellesen, Joe Wagner", "M8774, M8794", "Wizard of Wor (1982) (CBS Electronics) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3556e125681aea864e17b09f3f3b2a75", "", "", "Incoming (2 Player Demo) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3576037c9281656655fa114a835be553", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (1 of 4) (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3577e19714921912685bb0e32ddf943c", "TechnoVision - Video Technology", "TVS1003", "Pharaoh's Curse (1983) (TechnoVision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "35ae903dff7389755ad4a07f2fb7400c", "", "", "Colored Wall Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "35b10a248a7e67493ec43aeb9743538c", "Dor-x", "", "Defender (Dor-x) (Hack)", "Hack of Defender", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "35b43b54e83403bb3d71f519739a9549", "Parker Brothers, Dave Engman, Isabel Garret", "", "McDonald's (06-06-1983) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "35be55426c1fec32dfb503b4f0651572", "Men-A-Vision", "", "Air Raid (Men-A-Vision) (PAL)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "35fa32256982774a4f134c3347882dff", "Retroactive", "", "Qb (V0.05) (Macintosh) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "360ba640f6810ec902b01a09cc8ab556", "Atari, Jerome Domurat, Steve Woita", "CX2699", "Taz (06-15-1983) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "360c0dcb11506e73bd0b77207c81bc62", "Digitel", "", "Enduro (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3619786f6a32efc1e4a262d5aca8a070", "Atari, John Dunn - Sears", "CX2631 - 49-75152", "Superman (1979) (Atari) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3624e5568368929fabb55d7f9df1022e", "Activision - Imagineering, Donald Hahn, Dan Kitchen", "EAK-050-04", "Double Dragon (1989) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "36306070f0c90a72461551a7a4f3a209", "U.S. Games Corporation - JWDA, Roger Booth, Sylvia Day, Ron Dubren, Todd Marshall, Robin McDaniel, Wes Trager, Henry Will IV", "VC1007", "Name This Game (1983) (U.S. Games)", "AKA Octopussy", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "36547bc6faa5132b87504e18d088e1d7", "", "", "Cosmic Swarm (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "367411b78119299234772c08df10e134", "Atari", "CX26163P", "Skiing (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3685060707df27d4091ba0ea2dc4b059", "", "", "PezZerk - PezMan in Ghost Manor (Hack)", "Hack of Berzerk", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "368d88a6c071caba60b4f778615aae94", "Atari, Matthew L. Hubbard", "CX26159", "Double Dunk (1989) (Atari)", "AKA Super Basketball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "36a701c60a9f9768d057bc2a83526a80", "", "", "Cube Conquest (Interlaced) (Billy Eno) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "36b20c427975760cb9cf4a47e41369e4", "Coleco - Woodside Design Associates - Imaginative Systems Software, Garry Kitchen", "2451", "Donkey Kong (1982) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "36c29ceee2c151b23a1ad7aa04bd529d", "Atari - GCC, Ava-Robin Cohen", "CX26123", "Jr. Pac-Man (1986) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "36c31bb5daeb103f488c66de67ac5075", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix - Bop a Buggy (1 of 3) (1983) (Arcadia)", "Uses Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 56", "", "", "", "" },
+  { "36c993dc328933e4dd6374a8ffe224f4", "Gameworld, J. Ray Dettling", "133-007", "Bermuda Triangle (1983) (Gameworld) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "36e47ed74968c365121eab60f48c6517", "Quelle", "343.373 7", "Master Builder (1983) (Quelle) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "36edef446ab4c2395666efc672b92ed0", "Atari - Axlon, John Vifian", "CX26168", "Off the Wall (1989) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "36f9a953ebdd9a8be97ccf27a2041903", "", "", "Chinese Character Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "37252757a79dc5b174e3c03d6ea0bdcb", "", "", "Sky Diver (Unknown) (PAL) (4K) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "372bddf113d088bc572f94e98d8249f5", "Bomb - Onbase", "CA285", "Wall-Defender (1983) (Bomb) (PAL)", "AKA Wall Break", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "373b8a081acd98a895db0cb02df35673", "", "", "Demo Image Series #5 - Boofly (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3750f2375252b6a20e4628692e94e8b1", "Dismac", "", "Ases do Ar (Dismac)", "AKA Sky Jinks", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "37527966823ee9243d34c7da8302774f", "", "", "Word Zapper (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "376944889dcfa96c73d3079f308e3d32", "Retroactive", "", "Qb (0.11) (Retroactive) (Stella)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "3783f12821b88b08814da8adb1a9f220", "", "", "Mission Survive (PAL) (Genesis)", "Genesis controller (C is vertical fire)", "Hack of Mission Survive)", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "378a62af6e9c12a760795ff4fc939656", "Atari - Axlon, Steve DeFrisco", "CX26171", "MotoRodeo (1991) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "378c118b3bda502c73e76190ca089eef", "Atari, Alan Miller", "CX2662P", "Hangman (1978) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "37ab3affc7987995784b59fcd3fcbd31", "", "", "Sprite Test (29-11-2002) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "37b98344c8e0746c486caf5aaeec892a", "K-Tel Vision", "6", "Spider Maze (1982) (K-Tel Vision) (PAL)", "AKA Spider Kong", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "37e828675d556775ae8285c0caf7d11c", "AtariAge - Fred Quimby", "", "Gingerbread Man (Fred Quimby) (Genesis)", "Genesis controller (C throws cookie)", "New Release", "", "", "", "", "", "", "", "GENESIS", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "37f42ab50018497114f6b0f4f01aa9a1", "", "", "Droid Demo 2-M (David Conrad Schweinsberg) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "37fd7fa52d358f66984948999f1213c5", "Rainbow Vision - Suntek", "SS-004", "Pyramid War (1983) (Rainbow Vision) (PAL) [a2]", "AKA Chopper Command", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "384db97670817103dd8c0bbdef132445", "Atari - Sears", "CX2626 - 6-99829, 49-75116", "Miniature Golf (1979) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "384f5fbf57b5e92ed708935ebf8a8610", "20th Century Fox Video Games, John W.S. Marvin", "11009", "Crypts of Chaos (1983) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3856b9425cc0185ed770376a62af0282", "Kyle Pittman", "", "Yellow Submarine (Kyle Pittman) (Hack)", "Hack of Bermuda Triangle", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "386ff28ac5e254ba1b1bac6916bcc93a", "Arcadia Corporation, Scott Nelson", "AR-4300", "Fireball (1982) (Arcadia)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" },
+  { "3882224adbd0ca7c748b2a1c9b87263e", "Atari, Tod Frye", "CX2657", "SwordQuest - FireWorld (1982) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3889351c6c2100b9f3aef817a7e17a7a", "CCE", "", "Dolphin (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3897744dd3c756ea4b1542e5e181e02a", "Atari, Jerome Domurat, Peter C. Niday", "CX26115", "Dumbo's Flying Circus (05-05-1983) (Atari) (Prototype)", "AKA Dumbo Flies Home", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "38bd172da8b2a3a176e517c213fcd5a6", "Atari", "MA017600", "Diagnostic Test Cartridge 2.6 (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "38c362dcd5cad5a62e73ae52631bd9d8", "Jake Patterson", "", "Baubles (14-11-2001) (Jake Patterson) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "38cf93eacfb2fa9a2c5e39059ff35a74", "Greg Zumwalt", "", "WacMan (2003) (Greg Zumwalt) (Hack)", "Hack of Ms. Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "38de7b68379770b9bd3f7bf000136eb0", "Imagic, Mark Klein", "EIZ-003-04I", "Subterranea (1983) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "391764720140c432aec454a468f77a40", "Video Game Program", "", "Miss Pack Man (Video Game Program) (PAL)", "AKA Ms. Pac-Man", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "392d34c0498075dd58df0ce7cd491ea2", "Atari, Frank Hausman, Mimi Nyden, Steve Woita", "CX2686", "Quadrun (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "392f00fd1a074a3c15bc96b0a57d52a1", "Atari, Rob Fulop - Sears", "CX2633 - 49-75119", "Night Driver (1980) (Atari)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "YES", "" },
+  { "393948436d1f4cc3192410bb918f9724", "Activision, Carol Shaw", "AX-020, AX-020-04", "River Raid (1982) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "393e41ca8bdd35b52bf6256a968a9b89", "U.S. Games Corporation - Western Technologies, John Hall", "VC1012", "M.A.D. (1983) (U.S. Games)", "AKA Missile Intercept, Mutually Assured Destruction", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3947eb7305b0c904256cdbc5c5956c0f", "Jone Yuan Telephonic Enterprise Co", "", "Lilly Adventure (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "396f7bc90ab4fa4975f8c74abe4e81f0", "Atari, Larry Kaplan - Sears", "CX2612 - 99804, 49-75103", "Street Racer (1977) (Atari)", "Uses the Paddle Controllers (swapped)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "AUTO 60", "", "", "", "" },
+  { "3974e2d1f614fbd3a092533ecae2e84d", "Alessandro Ciceri", "", "MagiCard+ (alex_79) WIP_20150118", "MagiCard hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "39790a2e9030751d7db414e13f1b6960", "", "", "Robotfindskitten2600 (26-04-2003) (Jeremy Penner) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "39a6a5a2e1f6297cceaa48bb03af02e9", "", "", "Pitfall 2 Plus (Hack)", "Hack of Pitfall 2", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "39b94d41bd3b01c12b4054c1a8733783", "SOLID Corp. (D. Scott Williamson)", "CX2655-016", "Star Castle 2600 (SolidCorp) [016]", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "39c78d682516d79130b379fa9deb8d1c", "Apollo - Games by Apollo, Ed Salvo", "AP-1001", "Skeet Shoot (1981) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "39d36366ae7e6dfd53393fb9ebab02a0", "CCE", "C-811", "River Raid (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "39da69ff9833f8c143f03b6e0e7a996b", "Charles Morgan", "", "Ventrra Invaders 2002 (Charles Morgan) (Hack)", "Hack of Megamania", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "39fe316952134b1277b6a81af8e05776", "Robby", "18", "River Raid (Robby)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3a10562937a766cbbb77203d029b00e1", "Carrere Video - JWDA, Garry Kitchen, Paul Willson - Teldec - Prism", "USC1002", "Sneak 'n Peek (1983) (Carrere Video) (PAL)", "AKA Der Unsichtbare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3a2e2d0c6892aa14544083dfb7762782", "Atari, Rob Fulop - Sears", "CX2638 - 49-75166", "Missile Command (1981) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "3a35d7f1dc2a33565c8dca52baa86bc4", "", "", "Rubik's Cube Demo 2 (23-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3a51a6860848e36e6d06ffe01b71fb13", "Retroactive", "", "Qb (2.07) (Retroactive) (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "3a521b7e29123b2d38e34e3ff8dc255c", "Thomas Jentzsch", "", "Centipede - Atari Mouse Hack v1.4 (NTSC) (Full-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3a526e6a1f9fe918af0f2ce997dfea73", "CBS Electronics, Dan Kitchen, Garry Kitchen", "4L1700, 4L1701, 4L1702, 4L1802, 4L2274", "Donkey Kong (1982) (CBS Electronics) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3a53963f053b22599db6ac9686f7722f", "", "", "Word Zapper (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3a771876e4b61d42e3a3892ad885d889", "Atari, Bill Aspromonte, Andrew Fuchs", "CX26120", "Defender II (1987) (Atari)", "AKA Stargate", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3aad0ef62885736a5b8c6ccac0dbe00c", "Dynacom", "", "Atlantis (1983) (Dynacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3ab5d138e26d88c8190e7cc629a89493", "", "", "Phased Color Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "3ac6c50a8e62d4ce71595134cbd8035e", "Absolute Entertainment, Dan Kitchen", "AK-046-04", "Tomcat (1988) (Absolute)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3ad3dc799211ccd424d7c6d454401436", "Probe 2000 - NAP", "", "Power Lords (1983) (Probe) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3ad58b53a1e972396890bd86c735e78d", "Arcadia Corporation, Stephen H. Landrum", "AR-4400", "Excalibur Version 36 (Dragonstomper Beta) (1982) (Arcadia) (Prototype)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3b040ed7d1ef8acb4efdeebebdaa2052", "Tigervision", "7-008", "Miner 2049er (1983) (Tigervision) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3b097a7ed5bd2a84dc3d3ed361e9c31c", "", "", "Interleaved ChronoColour Demo (PAL) (05-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3b10106836565e5db28c7823c0898fbb", "Xonox - Beck-Tech", "6210, 06002, 06004, 99002", "Ghost Manor (1983) (Xonox) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3b2c32fcd331664d037952bcaa62df94", "Xonox", "6230, 6250", "Super Kung-Fu (1983) (Xonox) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3b5751a8d20f7de41eb069f76fecd5d7", "", "", "Eckhard Stolberg's Scrolling Text Demo 4 (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3b64a00ce147c3c29f7f8f8e531d08d8", "", "", "This Planet Sucks (16K) (Greg Troutman)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3b69f8929373598e1752f43f8da61aa4", "Apollo - Games by Apollo - RCA Video Jeux", "AP-2006", "Infiltrate (1921) (Apollo) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "3b6dba1a24bb2893bd3bd0593f92016b", "CBS Electronics / Thomas Jentzsch", "", "Omega Race JS (TJ)", "Hack of Omega Race (CBS Electronics)", "New Release (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3b76242691730b2dd22ec0ceab351bc6", "M Network - INTV, Connie Goldman, Joe King, Patricia Lewis Du Long, Gerald Moore, Mike Sanders, Jossef Wagner", "MT4319", "Masters of the Universe (1983) (M Network)", "", "", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "3b80b8f52a0939e16b5059f93a3fc19a", "V007", "", "Virtual Pet (V007) (after Demo 2) (CRACKERS) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3b86a27132fb74d9b35d4783605a1bcb", "Atari, Chris Crawford", "", "Wizard (1980) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3b8aacf5f5638492b926b5124de19f18", "Atari, Tod Frye - Sears", "CX2646 - 49-75185", "Pac-Man (1981) (Atari) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3b91c347d8e6427edbe942a7a405290d", "Parker Brothers", "PB5350", "Sky Skipper (1983) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3b9480bb6fb1e358c9c0a64e86945aee", "", "", "Title Match Pro Wrestling (2002) (Skyworks)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3b966bf3c2ca34ac6ca1de4cf6383582", "", "", "Double-Height 6-Digit Score Display (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3bb9793c60c92911895cf44530846136", "Jone Yuan Telephonic Enterprise Co", "", "Dragster (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3c21a89bc38d8cd0b010a2916bcff5c2", "", "", "Colony 7 - CX-22 Hack v0.4 (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "50" },
+  { "3c3a2bb776dec245c7d6678b5a56ac10", "", "", "Unknown Title (bin00003) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3c4223316c835ceaad619651e25df0f9", "", "", "Defender (Genesis)", "Genesis controller (C is smartbomb)", "Hack of Defender", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3c4a6f613ca8ba27ce9e43c6c92a3128", "", "", "Qb (V0.04) (Non-Lax Version) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "3c57748c8286cf9e821ecd064f21aaa9", "Atari, Jerome Domurat, Andrew Fuchs, Dave Staugas, Robert Vieira", "CX26118", "Millipede (1984) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3c72ddaf41158fdd66e4f1cb90d4fd29", "Dismac", "", "Comando Suicida (Dismac)", "AKA Chopper Command", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3c7a7b3a0a7e6319b2fa0f923ef6c9af", "Atari - Roklan, Joe Gaucher", "", "Racer (1982) (Atari) (Prototype)", "ROM must be started in bank 0", "Prototype", "", "0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3c7a96978f52b2b15426cdd50f2c4048", "", "", "Overhead Adventure Demo 3 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3c82e808fe0e6a006dc0c4e714d36209", "Activision, David Crane", "AG-004", "Fishing Derby (1980) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3c853d864a1d5534ed0d4b325347f131", "Telesys, Don 'Donyo' Ruffcorn", "1002", "Cosmic Creeps (1982) (Telesys)", "AKA Space Maze, Spaze Maze", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "3c8e57a246742fa5d59e517134c0b4e6", "Parker Brothers, Rex Bradford, Sam Kjellman", "PB5050", "Star Wars - The Empire Strikes Back (1982) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3ca51b5c08f5a0ecfb17d0c1ec6d0942", "Atari, James Andreasen - Sears", "CX2654 - 49-75141", "Haunted House (09-28-81) (Atari) (Prototype)", "AKA Mystery Mansion, Graves' Manor, Nightmare Manor", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3caa902ac0ce4509308990645876426a", "Atari - GCC, Dave Payne", "CX2669, CX2669P", "Vanguard (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3cbdf71bb9fd261fbc433717f547d738", "CCE", "C-803", "Bobby Is Going Home (1983) (CCE) (PAL)", "AKA Bobby Vai Para Casa", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3cdd91e1c28d28e856c0063d602da166", "", "", "Stell-A-Sketch (03-11-1997) (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "3d1e83afdb4265fa2fb84819c9cfd39c", "Coleco - JWDA, Todd Marshall, Robin McDaniel, Henry Will IV", "2465", "Smurf - Rescue in Gargamel's Castle (1983) (Coleco)", "AKA Smurf, Smurf Action", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3d2367b2b09c28f1659c082bb46a7334", "Imagic, Dennis Koble", "720103-2A, IA3203P, EIX-010-04I", "Atlantis (1982) (Imagic) (PAL)", "AKA Lost City of Atlantis", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3d2652cbea462a886a41791dd7c8d073", "", "", "Ritorno dei frattelli di Mario (Mario Bros Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3d48b8b586a09bdbf49f1a016bf4d29a", "Video Game Cartridge - Ariola", "TP-606", "Hole Hunter (Video Game Cartridge)", "AKA Topy", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3d6fc7a19be76d808aa233415cb583fc", "CCE", "C-833", "Target Practice (1983) (CCE)", "AKA Carnival", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3d7749fb9c2f91a276dfe494495234c5", "Jone Yuan Telephonic Enterprise Co", "", "Checkers (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3d7aad37c55692814211c8b590a0334c", "Atari, Dan Oliver", "", "Telepathy (1983) (Atari) (Prototype)", "Uses both left joystick and right Mindlink controllers (press Fire on respective controller to begin)", "Prototype", "", "", "", "", "", "", "", "", "", "", "MINDLINK", "", "", "", "", "", "78", "", "", "", "" },
+  { "3d8a2d6493123a53ade45e3e2c5cafa0", "Atari, Jim Huether - Sears", "CX2629 - 6-99843, 49-75118", "Sky Diver (1979) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3d934bb980e2e63e1ead3e7756928ccd", "Activision, Steve Cartwright - Ariola", "EAX-017, EAX-017-04I - 711 017-720", "MegaMania (1982) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3d9c2fccf8b11630762ff00811c19277", "", "", "Challenge of.... Nexar, The (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3da7cc7049d73d34920bb73817bd05a9", "Activision, Mike Lorenzen", "AX-023", "Oink! (1983) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3dfb7c1803f937fadc652a3e95ff7dc6", "Dimax - Sinmax", "SM8001", "Space Robot (Dimax - Sinmax)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "3e03086da53ecc29d855d8edf10962cb", "CBS Electronics - Roklan, Joe Gaucher, Alex Leavens", "4L1751, 4L1752, 4L1753, 4L2275", "Gorf (1982) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "3e1682ddaec486d8b6b90b527aaa0fc4", "Thomas Jentzsch", "", "Robot City (V0.12) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3e22c7eaf6459b67388602e4bebbb3a8", "CommaVid, John Bronstein - Ariola", "CM-003 - 712 003-720", "Cosmic Swarm (1982) (CommaVid) (PAL) (4K)", "AKA Angriff der Termiten", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3e33ac10dcf2dff014bc1decf8a9aea4", "Spectravideo - Video Games Industries Corporation, Michael Schwartz - Ralston Purina", "", "Chase the Chuckwagon (1983) (Spectravideo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "3e49da621193d2611a4ea152d5d5ca3a", "", "", "Atari Logo Demo 3 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3e4b1137433cc1e617b5508619e13063", "", "", "Asteroids (Genesis)", "Genesis controller (C is hyperspace)", "Hack of Asteroids", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "3e5ca1afaa27c5da3c54c9942fec528b", "", "", "2600 Digital Clock (Demo 2) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3e6dab92009d6034618cb6b7844c5216", "", "", "Ed Invaders (Hack)", "Hack of Pepsi Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3e7d10d0a911afc4b492d06c99863e65", "VGS", "", "Super Tenis (VGS)", "AKA RealSports Tennis", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3e88cca5b860d0bd8947479e74c44284", "Atari, Lou Harp", "CX26122", "Sinistar (01-23-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3e899eba0ca8cd2972da1ae5479b4f0d", "Coleco, Joseph Biel", "2457", "Venture (1982) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "3e90cf23106f2e08b2781e41299de556", "Activision, David Crane", "AX-018, AX-018-04", "Pitfall! (1982) (Activision)", "Pitfall Harry's Jungle Adventure (Jungle Runner)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3eae062a9b722bda1255d474a87eca5c", "Atari, David Crane", "CX2605, CX2605P", "Outlaw (1978) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3eb1e34a4f0eec36f12e7336badcecf2", "Jake Patterson", "", "Baubles (V0.001) (2001) (Jake Patterson) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3eb21313ea5d5764c5ed9160a5a55a83", "Activision, Alan Miller", "AX-012, CAX-012, AX-012-04", "Ice Hockey (1981) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3ec12372ca3e870b11ca70edc7ec26a4", "CommaVid, John Bronstein", "CM-002", "Video Life (1981) (CommaVid) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "3eccf9f363f5c5de0c8b174a535dc83b", "", "", "Plaque Attack (Unknown) (PAL)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3ef9573536730dcd6d9c20b6822dbdc4", "Atari, Larry Wagner, Bob Whitehead", "CX2645, CX2645P", "Video Chess (1979) (Atari) (PAL)", "AKA Computer Chess", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3f01bd6d059396f495a4cde7de0ab180", "", "", "Qb (Special Edition) (NTSC) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "3f039981255691d3859d04ef813a1264", "Xonox, John Perkins", "6230, 7210, 06004, 99004", "Artillery Duel (1983) (Xonox) [a]", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3f251c50aa7237e61a38ab42315ebed4", "Thomas Jentzsch", "", "Ikari Warriors (1990) (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3f3ad2765c874ca13c015ca6a44a40a1", "CCE", "C-862", "Crackpots (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3f540a30fdee0b20aed7288e4a5ea528", "Atari - GCC", "CX2670", "Atari Video Cube (1983) (Atari)", "AKA Atari Cube, Video Cube", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3f58f972276d1e4e0e09582521ed7a5b", "Telegames", "6082 A145", "Kung Fu Superkicks (1988) (Telegames)", "AKA Chuck Norris Superkicks", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3f5a43602f960ede330cd2f43a25139e", "Activision, Alan Miller", "AG-003", "Checkers (1980) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3f6938aa6ce66e6f42e582c1eb19b18c", "Jone Yuan Telephonic Enterprise Co", "", "Laser Blast (Jone Yuan) (4K) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3f6dbf448f25e2bd06dea44248eb122d", "", "5687 A279", "Soccer (1988) (Telegames)", "AKA International Soccer", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3f75a5da3e40d486b21dfc1c8517adc0", "Atari, Jim Huether", "CX26163P", "Sky Diver (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3f9431cc8c5e2f220b2ac14bbc8231f4", "", "", "Colors Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3f96eb711928a6fac667c04ecd41f59f", "Bit Corporation", "PGP218", "Rodeo Champ (4 Game in One Dark Green) (1983) (BitCorp) (PAL)", "AKA Stampede", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3f9cb1aba8ec20e2c243ae642f9942bf", "", "", "New Questions (1998) (John K. Harvey) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3fd1f9d66a418c9f787fc5799174ddb7", "Aaron Curtis", "", "AStar (PAL)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3fd53bfeee39064c945a769f17815a7f", "CCE", "", "Sea Hawk (CCE)", "AKA Seahawk", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3fe43915e5655cf69485364e9f464097", "CCE", "C-863", "Fisher Price (1983) (CCE)", "AKA Skindiver", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "3ff5165378213dab531ffa4f1a41ae45", "Otto Versand", "311377", "Pygmy (1983) (Otto Versand) (PAL)", "AKA Lock 'n' Chase (Double-Game Package)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4026ad38ba5ce486e88383dc27d7a46f", "Nukey Shay, Omegamatrix", "", "Double Dragon (Genesis) V2", "Genesis controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "402b1ca3c230a60fb279d4a2a10fa677", "", "", "3-D Tic-Tac-Toe (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "402d876ec4a73f9e3133f8f7f7992a1e", "Alex Herbert", "", "Man Goes Down (2006) (A. Herbert) (Prototype)", "Uses AtariVox controller", "Homebrew", "", "", "", "", "", "", "", "", "", "", "ATARIVOX", "", "", "", "", "", "", "", "", "", "" },
+  { "405f8591b6941cff56c9b392c2d5e4e5", "Telegames", "", "Star Strike (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4066309eb3fa3e7a725585b9814bc375", "", "", "Multi Ball Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4066d7d88ec4a2c656127a67fa52dcf1", "", "", "Overhead Adventure Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "407a0c6cc0ff777f67b669440d68a242", "Erik Eid", "", "Euchre (Alpha) (PAL) (31-08-2002) (Erik Eid)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4093382187f8387e6d011883e8ea519b", "", "", "Go Go Home (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "40aa851e8d0f1c555176a5e209a5fabb", "", "", "Euchre (More for less) (NTSC) (22-08-2002) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "40b1832177c63ebf81e6c5b61aaffd3a", "Atari, Peter C. Niday", "", "Rubik's Cube 3-D (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "40b59249e05135bca33861e383735e9e", "Atari", "CX26163P", "Skiing (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "40d8ed6a5106245aa79f05642a961485", "Xonox - K-Tel Software - Beck-Tech, Steve Beck", "6210, 06002, 06004, 99002", "Ghost Manor (1983) (Xonox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "40d9f5709877ecf3dd1184f9791dd35e", "Dactari - Milmar", "", "Skiing (Dactari - Milmar)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "40e12c008037a323a1290c8fa4d2fe7f", "", "", "Skeleton (NTSC) (06-09-2002) (Eric Ball)", "", "", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "40eb4e263581b3dfec6dd8920b68e00f", "Sears Tele-Games, Marilyn Churchill, Matthew L. Hubbard", "CX2647 - 49-75142", "Seawolf 3 (03-23-1981) (Sears) (Prototype) (PAL)", "Submarine Commander Beta", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "413c925c5fdcea62842a63a4c671a5f2", "Activision, Larry Kaplan", "AX-006", "Bridge (1980) (Activision) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4153dd2beed648e9dc082140ebe8e836", "Thomas Jentzsch", "", "Coke Zero (v1.0) (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "415c11fcac66bbd2ace2096687774b5a", "", "", "Fu Kung! (V0.00) (07-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4181087389a79c7f59611fb51c263137", "Atari, Suki Lee", "CX26113", "Miss Piggy's Wedding (06-24-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "41810dd94bd0de1110bedc5092bef5b0", "Funvision - Fund. International Co.", "", "Dragon Treasure (Funvision)", "AKA Dragonfire", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "41818738ab1745e879024a17784d71f5", "CCE", "C-832", "Atlantis (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4189adfc1b30c121248876e3a1a3ac7e", "Eric Ball", "", "Skeleton (Complete) (06-09-2002) (Eric Ball)", "", "New Release", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4191b671bcd8237fc8e297b4947f2990", "Exus Corporation", "", "Video Jogger (1983) (Exus)", "AKA Foot Craz", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "41b554c6970b18670acc7b6baef8ed2e", "Thomas Jentzsch", "", "Reactor - Amiga Mouse Hack v1.3 (PAL) (Half-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "41c4e3d45a06df9d21b7aae6ae7e9912", "CCE", "C-826", "Grand Prix (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "41f252a66c6301f1e8ab3612c19bc5d4", "Atari - GCC, Mike Feinstein, Brad Rice", "CX2681", "Battlezone (1983) (Atari)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4209e9dcdf05614e290167a1c033cfd2", "CommaVid, John Bronstein", "CM-002", "Video Life (1984) (CommaVid) [higher sounds]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "42249ec8043a9a0203dde0b5bb46d8c4", "CCE", "", "Resgate Espacial (CCE)", "AKA Moonsweeper", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "4233eb824c2b4811abef9b6d00355ae9", "Retroactive", "", "Qb (V0.10) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "4251b4557ea6953e88afb22a3a868724", "Thomas Jentzsch", "", "Robot City (V1.1) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "425ee444a41d218598893d6b6e03431a", "Thomas Jentzsch", "", "Invaders Demo (2001) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4279485e922b34f127a88904b31ce9fa", "", "", "Enduro (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "428b2d36f5d716765460701f7016ac91", "Andrew Wallace", "", "Brooni (2001) (Andrew Wallace) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "42ae81ae8ac51e5c238639f9f77d91ae", "", "", "Multi-Sprite Demo 2 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "42b2c3b4545f1499a083cfbc4a3b7640", "U.S. Games Corporation - JWDA, Todd Marshall, Robin McDaniel, Wes Trager, Henry Will IV", "VC2003", "Eggomania (1982) (U.S. Games)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 60", "", "", "", "" },
+  { "42b3ab3cf661929bdc77b621a8c37574", "Robby", "", "Volleyball (Robby)", "AKA RealSports Volleyball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "42b5e3a35b032f033809afb0ea28802d", "Atari, Mimi Nyden, Scott Smith, Robert Vieira", "CX26127", "Gremlins (03-12-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "42cdd6a9e42a3639e190722b8ea3fc51", "Activision, Alan Miller", "AG-007, CAG-007", "Tennis (1981) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "42dcc02777b0bcfacd85aeb61d33558a", "", "", "Human Cannonball (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "42e0ec5ab8f5deba53e4169ff2a5efbe", "", "", "Atari Logo Demo 5 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4311a4115fb7bc68477c96cf44cebacf", "", "", "Challenge (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4326edb70ff20d0ee5ba58fa5cb09d60", "Atari - GCC, Kevin Osborn", "CX2689", "Kangaroo (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "435fd469f088468c4d66be6b5204d887", "Atari - GCC", "CX2680, CX2680P", "RealSports Tennis (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "438968a26b7cfe14a499f5bbbbf844db", "", "", "Raft Rider (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "43adf60ebdd6b5a0fae21594ecf17154", "Jone Yuan Telephonic Enterprise Co", "", "Stampede (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "43c6cfffeddab6b3787357fed9d44529", "20th Century Fox Video Games, Frank Cohen, Douglas 'Dallas North' Neubauer", "11111", "M.A.S.H (1983) (20th Century Fox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "43f33c6dfdeaf5138ce6e6968ad7c5ce", "Jeffry Johnston", "", "Radial Pong - Version 11 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "43f8459d39fb4eddf9186d62722ff795", "", "", "Skeleton+ (17-04-2003) (Eric Ball) (PAL)", "", "", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "442602713cb45b9321ee93c6ea28a5d0", "", "", "Demon Attack (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4427f06085bb4c22ff047027f7acecc2", "Parker Brothers, Rex Bradford", "PB5000", "Star Wars - Jedi Arena (1983) (Parker Bros) (Prototype)", "Uses the Paddle Controllers (swapped)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 50", "", "", "", "" },
+  { "442b7863683e5f084716fda050474feb", "Eckhard Stolberg", "", "Frame Timed Sound Effects-EM (Eckhard Stolberg)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4431428a7500c96fc0e2798a5dbd36d6", "", "", "Kangaroo (Genesis)", "Genesis controller (B is punch, C is jump)", "Hack of Kangaroo", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4474b3ad3bf6aabe719a2d7f1d1fb4cc", "Activision - Imagineering, Dan Kitchen, Garry Kitchen", "EAX-039-04B, EAX-039-04I", "Kung-Fu Master (1987) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4476c39736090dabac09f6caf835fc49", "", "", "Text Screen (25-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "448c2a175afc8df174d6ff4cce12c794", "Activision, David Crane", "AB-035-04", "Pitfall II (1983) (Activision) [a2]", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "44e9c4a047c348dbeb7ace60f45484b4", "", "", "Moon Patrol Arcade (Genesis)", "Genesis controller (C is jump)", "Hack of Moon Patrol", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "44f71e70b89dcc7cf39dfd622cfb9a27", "Tigervision, Robert H. O'Neil", "7-007", "Polaris (1983) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "45027dde2be5bdd0cab522b80632717d", "Epyx, Steven A. Baker, Tod Frye, Peter Engelbrite", "80561-00250", "Summer Games (1987) (Epyx)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "45040679d72b101189c298a864a5b5ba", "20th Century Fox Video Games - Sirius Software, David Lubar", "11022", "SpaceMaster X-7 (1983) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4543b7691914dfd69c3755a5287a95e1", "CommaVid, Irwin Gaines", "CM-005", "Mines of Minos (1982) (CommaVid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "456453a54ca65191781aef316343ae00", "", "", "Full Screen Bitmap (3-D Green) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4565c1a7abce773e53c75b35414adefd", "Arcadia Corporation", "", "Supercharger BIOS (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "457b03cd48ff6d895795ef043c6b0f1e", "AtariAge, Chris Spry", "CX26201", "Zippy the Porcupine (2014) (Sprybug)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "457e7d4fcd56ebc47f5925dbea3ee427", "Carrere Video - JWDA, Garry Kitchen - Teldec - Prism", "USC1001", "Space Jockey (1983) (Carrere Video) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "457f4ad2cda5f4803f122508bfbde3f5", "", "", "Canyon Bomber (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "458883f1d952cd772cf0057abca57497", "", "", "Fishing Derby (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "45a095645696a217e416e4bd2baea723", "Digivision", "", "Snoopy (Digivision)", "AKA Snoopy and the Red Baron", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "45a4f55bb9a5083d470ad479afd8bca2", "CommaVid, Joseph Biel", "", "Frog Demo (1983) (CommaVid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "45beef9da1a7e45f37f3f445f769a0b3", "Atari, Suki Lee", "CX2658", "Math Gran Prix (1982) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "45c4413dd703b9cfea49a13709d560eb", "Jone Yuan Telephonic Enterprise Co", "", "Challenge of.... Nexar, The (Jone Yuan) (Hack)", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "45cb0f41774b78def53331e4c3bf3362", "Carrere Video - JWDA, Roger Booth, Sylvia Day, Todd Marshall, Robin McDaniel, Wes Trager, Henry Will IV - Teldec - Prism", "USC1007", "Octopus (1983) (Carrere Video) (PAL)", "AKA Name This Game", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4605a00f5b44a9cbd5803a7a55de150e", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (07-03-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "461029ab23800833e9645be3e472d470", "", "", "Combat TC (v0.1)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "46258bd92b1f66f4cb47864d7654f542", "Zellers", "", "Turmoil (Zellers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "463dd4770506e6c0ef993a40c52c47be", "Arcadia Corporation, Steve Hales, Stephen H. Landrum", "4 AR-4102", "Suicide Mission (Preview) (1982) (Arcadia)", "AKA Meteoroids", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "463e66ad98806a49106cffa49c08e2ed", "", "", "Interlace Game Demo (01-09-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "467340a18158649aa5e02a4372dcfccd", "Activision, John Van Ryzin - Ariola", "EAZ-036-04, EAZ-036-04B, EAZ-036-04I - 711 036-720", "H.E.R.O. (1984) (Activision) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4689081b7363721858756fe781cc7713", "", "", "Oystron (V2.6) (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "468f2dec984f3d4114ea84f05edf82b6", "Tigervision - Teldec", "7-011 - 3.60015 VG", "Miner 2049er Volume II (1983) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "4690fdb70c86604bb35da26696818667", "", "", "Euchre (Release Candidate) (NTSC) (28-09-2002) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "469473ff6fed8cc8d65f3c334f963aab", "Atari, Bruce Poehlman, Gary Stark", "", "Dune (07-10-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "46c021a3e9e2fd00919ca3dd1a6b76d8", "Atari, Jim Huether - Sears", "CX2629 - 6-99843, 49-75118", "Sky Diver (1979) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "46c43fdcbce8fde3a91ebeafc05b7cbd", "", "", "Invaders Demo (PAL) (2001) (Eckhard Stolberg)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "46dc526773808c8b9bb2111f24e5704c", "Omegamatrix", "", "SpaceMaster X-7 (Atari Mouse) (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "46e9428848c9ea71a4d8f91ff81ac9cc", "Telegames", "", "Astroblast (1988) (Telegames) (PAL)", "Can also use left joystick", "", "", "", "", "", "", "", "", "PADDLES", "", "", "", "", "", "YES", "", "", "AUTO 55", "", "", "", "" },
+  { "4702d8d9b48a332724af198aeac9e469", "Atari, Jerome Domurat, Steve Woita", "CX2699", "Taz (1983) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "470878b9917ea0348d64b5750af149aa", "Atari, Suki Lee - Sears", "CX2658 - 49-75128", "Math Gran Prix (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "471f7bdc933e8db0e44aa3dde2dd92af", "Omegamatrix", "", "Millipede (Atari Mouse) v6.5 (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "47464694e9cce07fdbfd096605bf39d4", "Activision, Dan Kitchen", "EAK-050-04", "Double Dragon (1989) (Activision) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "47585c047802dd9af888b998fb921f32", "Omegamatrix", "", "Star Wars Arcade (Atari Trak-Ball) v4 (PAL60) (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4767356fa0ed3ebe21437b4473d4ee28", "Atari, Dan Hitchens, Mimi Nyden", "CX2685", "Gravitar (04-12-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "47711c44723da5d67047990157dcb5dd", "CCE", "", "Ice Hockey (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "47911752bf113a2496dbb66c70c9e70c", "Atari - CCW, Christopher H. Omarzu, Preston Stuart, Bruce Williams", "CX26101", "Oscar's Trash Race (1984) (Atari) (PAL)", "Uses the Keypad Controllers", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" },
+  { "4799a40b6e889370b7ee55c17ba65141", "Konami", "RC 100-X 02", "Pooyan (1983) (Konami)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "47aad247cce2534fd70c412cb483c7e0", "Rainbow Vision - Suntek", "SS-010", "Mafia (1983) (Rainbow Vision) (PAL)", "AKA Gangster Alley", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "47abfb993ff14f502f88cf988092e055", "Zellers", "", "Inca Gold (Zellers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "47aef18509051bab493589cb2619170b", "", "", "Stell-A-Sketch (Bob Colbert) (PD)", "Uses Driving, Joystick, or Amiga/Atari ST Mouse Controllers", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "47b82d47e491ac7fdb5053a88fccc832", "Atari Freak 1, Franklin Cruz", "", "Asteroid 2 (Atari Freak 1) (Hack)", "Hack of Asteroids", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "47cd61f83457a0890de381e478f5cf5f", "Imagic, Wilfredo Aguilar, Michael Becker, Rob Fulop", "720111-2A, 13205", "Fathom (1983) (Imagic) (PAL)", "AKA Scuba", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "481d20ec22e7a63e818d5ef9679d548b", "Atari", "CX26163P", "Freeway Rabbit (32 in 1) (1988) (Atari) (PAL)", "AKA Freeway", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "481f9a742052801cc5f3defb41cb638e", "Jeffry Johnston", "", "Radial Pong - Version 4 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "48287a9323a0ae6ab15e671ac2a87598", "Zellers", "", "Laser Volley (Zellers)", "AKA Innerspace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4834b7b28ea862227ac7e40053fb52a5", "Nukey Shay", "", "Montezuma's Revenge (Genesis) (F6_Conversion)", "Genesis controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "48411c9ef7e2cef1d6b2bee0e6055c27", "Telesys, Don Ruffcorn, Jack Woodman", "1003", "Fast Food (1982) (Telesys) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "484b0076816a104875e00467d431c2d2", "Atari", "CX26150", "Q-bert (1987) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4857f8bb88bb63c640d3ea5aac7f5d6d", "Atari, James Andreasen - Sears", "CX2654 - 49-75141", "Haunted House (08-12-81) (Atari) (Prototype)", "AKA Mystery Mansion, Graves' Manor, Nightmare Manor", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4868a81e1b6031ed66ecd60547e6ec85", "Eric Mooney", "", "Invaders by Erik Mooney (V2.1) (1-3-98) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "487193a7b7fe57a1bbc2f431f628bd5f", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Trak-Ball Hack v1.1 (NTSC) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4884b1297500bd1243659e43c7e7579e", "Atari - Axlon, Tod Frye", "CX26178", "Save Mary! (10-24-1991) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4892b85c248131d6a42c66a4163a40d0", "Canal 3 - Intellivision", "", "Tac-Scan (Canal 3)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "YES", "", "", "AUTO 60", "", "", "", "" },
+  { "48bcf2c5a8c80f18b24c55db96845472", "Activision, John Van Ryzin - Ariola", "EAZ-036-04, EAZ-036-04B, EAZ-036-04I - 711 036-720", "H.E.R.O. (1984) (Activision) (PAL) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "48e5c4ae4f2d3b62b35a87bca18dc9f5", "Quelle", "476.774 5", "Bobby geht nach Hause (1983) (Quelle) (PAL)", "AKA Bobby Is Going Home", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "48f18d69799a5f5451a5f0d17876acef", "ZiMAG - Emag - Vidco", "GN-070", "Mysterious Thief, A (1983) (ZiMAG) (Prototype) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "4901c05068512828367fde3fb22199fe", "Imagic, Rob Fulop", "720101-2B, IA3200P, EIX-006-04I", "Demon Attack (1982) (Imagic) (PAL)", "AKA Death from Above", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4904a2550759b9b4570e886374f9d092", "Parker Brothers, Charlie Heath", "931506", "Reactor (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "490e3cc59d82f85fae817cdf767ea7a0", "", "", "Berzerk (Unknown) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "490eed07d4691b27f473953fbea6541a", "Activision, Steve Cartwright, David Crane", "AB-035-04", "Pitfall II (1983) (Activision) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "49366f41aa7a54baf263426e99ce4312", "", "", "POP-MDM-Test (PAL) (63 games)", "", "", "", "", "MDM", "", "", "", "", "JOYSTICK", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "" },
+  { "493daaf9fb1ba450eba6b8ed53ffb37d", "", "", "3-D Corridor Demo (27-03-2003) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "493de059b32f84ab29cde6213964aeee", "Atari, Bill Aspromonte, Andrew Fuchs", "CX26120", "Stargate (1984) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "493e90602a4434b117c91c95e73828d1", "Telegames", "", "Lock 'n' Chase (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4947c9de2e28b2f5f3b0c40ce7e56d93", "", "", "3-D Corridor Demo 2 (29-03-2003) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "494cda91cc640551b4898c82be058dd9", "Andreas Dietrich", "", "Donkey Kong VCS (2017) (1.0) (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "49571b26f46620a85f93448359324c28", "", "", "Save Our Ship (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "497c811026367c08fd838c9c59e5041d", "Omegamatrix", "", "SpaceMaster X-7 (Atari Trak-Ball) (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "497f3d2970c43e5224be99f75e97cbbb", "CommaVid, John Bronstein", "CM-002", "Video Life (1984) (CommaVid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "4981cefe5493ea512284e7f9f27d1e54", "Home Vision - Gem International Corp. - VDI", "VCS83136", "Cosmic War (1983) (Home Vision) (PAL)", "AKA Space Tunnel", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4999b45be0ab5a85bac1b7c0e551542b", "CCE", "", "Double Dragon (CCE) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "499b612f6544ae71d4915aa63e403e10", "Atari, Carol Shaw", "CX26163P", "Checkers (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "49f2cef5269fd06218be9f9474c74f8d", "Rentacom", "", "Time Pilot (Rentacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4a196713a21ef07a3f74cf51784c6b12", "Jone Yuan Telephonic Enterprise Co", "", "Frogs and Flies (Jone Yuan) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4a2fe6f0f6317f006fd6d4b34515448b", "", "", "Warring Worms (Midwest Classic Edition) (08-06-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4a45c6d75b1ba131f94a9c13194d8e46", "", "", "How to Draw a Playfield II (Joystick Hack) (1997) (Eric Bacher) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4a5fddf89801336637ac8e57a7c9a881", "Amiga", "1125", "Power Play Arcade Video Game Album IV (1984) (Amiga) (Prototype)", "Atlantis, Cosmic Ark, Dragonfire", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4a6be79310f86f0bebc7dfcba4d74161", "", "", "Demolition Herby (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "4a7eee19c2dfb6aeb4d9d0a01d37e127", "Hozer Video Games", "", "Crazy Valet (Hozer Video Games)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4a8c743396b8ad69d97e6fd3dd3e3132", "Arcadia Corporation", "", "Supercharger BIOS (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4a9009620038f7f30aaeb2a00ae58fde", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (3 of 3) (1983) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4ab2ebd95a8f861ea451abebdad914a5", "Nukey Shay, Thomas Jentzsch", "PAL conversion (F6)", "Montezuma's Revenge (PAL) (Genesis)", "Genesis controller (B jumps left, C jumps right)", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4ab4af3adcdae8cdacc3d06084fc8d6a", "Nick Bensema", "", "Sucky Zepplin (Nick Bensema) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4abb4c87a4c5f5d0c14ead2bb36251be", "Atari - Imagineering, Alex DeMeo", "CX26135, CX26135P", "RealSports Boxing (1987) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4ac9f40ddfcf194bd8732a75b3f2f214", "Atari - CCW, Stephan R. Keith, Laura Scholl, Preston Stuart", "CX26106", "Grover's Music Maker (12-29-1982) (Atari) (Prototype)", "Uses Keypad Controller", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4ae8c76cd6f24a2e181ae874d4d2aa3d", "", "", "Flash Gordon (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4af4103759d603c82b1c9c5acd2d8faf", "Imagic, Bob Smith", "720114-2A, 13207, EIZ-001-04I", "Moonsweeper (1983) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "4afa7f377eae1cafb4265c68f73f2718", "Ed Fries", "", "Halo 2600 (2010) (Ed Fries)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4afe528a082f0d008e7319ebd481248d", "", "", "Multi-Color Demo 1 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4b143d7dcf6c96796c37090cba045f4f", "Atari, Jim Huether - Sears", "CX2644 - 6-99824", "Flag Capture (1978) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4b205ef73a5779acc5759bde3f6d33ed", "", "", "Berzerk (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4b27f5397c442d25f0c418ccdacf1926", "Atari, Warren Robinett", "CX2613, 49-75154", "Adventure (1980) (Atari) (PAL)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4b379b885e2694f992c6cc932f18327f", "Omegamatrix", "", "SpaceMaster X-7 (Atari Mouse) (PAL60) (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4b71197153d651480830638cb6a03249", "Atari, Larry Kaplan", "CX26163P", "Bowling (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4b753a97aee91e4b3e4e02f5e9758c72", "Glenn Saunders, Roger Williams", "", "Asymmetric Reflected Playfield (Glenn Saunders)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4b94fd272785d7ec6c95fb7279d0f522", "Atari - CCW, Christopher H. Omarzu, Preston Stuart, Bruce Williams", "CX26101", "Oscar's Trash Race (12-03-1982) (Atari) (Prototype)", "Uses the Keypad Controllers", "Prototype", "", "", "", "", "", "", "", "KEYBOARD", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" },
+  { "4b9581c3100a1ef05eac1535d25385aa", "", "", "IQ 180 (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4baada22435320d185c95b7dd2bcdb24", "Atari, Jerome Domurat, Dave Staugas", "CX2682", "Krull (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4bcc7f6ba501a26ee785b7efbfb0fdc8", "Atari, Andrew Fuchs, Courtney Granner, Jeffrey Gusman, Mark R. Hahn", "CX2690", "Pengo (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4bdae9246d6ee258c26665512c1c8de3", "Atari", "CX26163P", "Human Cannonball (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4bdf54a454470ba015a217a8f5e61320", "Omegamatrix", "", "Millipede (Amiga Mouse) v6.5 (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "PAL60", "", "", "" },
+  { "4c030667d07d1438f0e5c458a90978d8", "Retroactive", "", "Qb (V2.03) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "4c0fb2544ae0f8b5f7ae8bce7bd7f134", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix (Preview) (1983) (Arcadia)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4c205f166157154df2f1ef60d87e552f", "", "", "Single-Scanline Positioning Demo 2 (2001) (Roger Williams)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4c39a2c97917d3d71739b3e21f60bba5", "", "", "Whale (Sub Scan Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4c462b2b6fb0a19a1437eb2c3dc20783", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (1 of 3) (1983) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4c4ce802cbfd160f7b3ec0f13f2a29df", "", "", "Beta Demo (V1.1) (26-09-2002) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4c606235f4ec5d2a4b89139093a69437", "Andrew Davies", "", "Andrew Davies early notBoulderDash demo (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "4c6afb8a44adf8e28f49164c84144bfe", "CCE", "C-806", "Mission 3,000 A.D. (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4c8832ed387bbafc055320c05205bc08", "Atari, Joe Decuir, Steve Mayer, Larry Wagner - Sears", "CX2601 - 99801, 6-99801, 49-75124", "Combat (1977) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4c8970f6c294a0a54c9c45e5e8445f93", "Xonox - K-Tel Software - Product Guild, Anthony R. Henderson", "99006, 6220", "Sir Lancelot (1983) (Xonox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4c9307de724c36fd487af6c99ca078f2", "Imagic, Brad Stewart", "720106-1A, IA3409", "Sky Patrol (1982) (Imagic) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4ca0959f846d2beada18ecf29efe137e", "Atari, Jim Huether, Alan J. Murphy, Robert C. Polaro", "CX2666, CX2666P", "RealSports Volleyball (1982) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4ca73eb959299471788f0b685c3ba0b5", "Activision, Steve Cartwright", "AX-031", "Frostbite (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4ca90ba45eced6f5ad560ea8938641b2", "", "", "Hangman Man Wordlist (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4cabc895ea546022c2ecaa5129036634", "Funvision - Fund. International Co.", "", "Ocean City (Funvision)", "AKA Atlantis", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4cd796b5911ed3f1062e805a3df33d98", "Tigervision - Software Electronics Corporation - Teldec", "7-006", "Springer (1983) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4d06f72cc3d8934579c11ff8f375c260", "Bit Corporation", "R320", "Bowling (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4d0a28443f7df5f883cf669894164cfa", "", "", "Beast Invaders (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4d2cef8f19cafeec72d142e34a1bbc03", "HES", "771-422", "2 Pak Special - Star Warrior, Frogger (1990) (HES) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4d38e1105c3a5f0b3119a805f261fcb5", "Bit Corporation", "PGP212", "Phantom UFO (4 Game in One Light Green) (1983) (BitCorp) (PAL)", "AKA Spider Fighter", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4d502d6fb5b992ee0591569144128f99", "Atari - Axlon, Tod Frye", "CX26178", "Save Mary! (11-21-1989) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4d5f6db55f7f44fd0253258e810bde21", "Fabrizio Zavagli", "", "Betterblast (Fabrizio Zavagli) (Hack)", "Hack of Astroblast", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4d7517ae69f95cfbc053be01312b7dba", "Atari, Alan Miller - Sears", "CX2641 - 99807, 49-75105", "Surround (1977) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4d77f291dca1518d7d8e47838695f54b", "Data Age", "DA1004", "Airlock (1982) (Data Age)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4d8396deeabb40b5e8578276eb5a8b6d", "Otto Versand", "781698", "Volleyball (1983) (Otto Versand) (PAL)", "AKA RealSports Volleyball (Double-Game Package)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4dbd7e8b30e715efc8d71d215aec7fe7", "Bit Corporation", "R320", "Air Raiders (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4dbf47c7f5ac767a3b07843a530d29a5", "Ric Pryor", "", "Breaking News (2002) (Ric Pryor) (Hack)", "Hack of Bump 'n' Jump", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4dcc7e7c2ec0738e26c817b9383091af", "", "", "Unknown Title (bin00026 (200110)) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4dd6c7ab9ef77f2b4950d8fc7cd42ee1", "Retroactive", "", "Qb (V2.04) (Stella) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "4df6124093ccb4f0b6c26a719f4b7706", "Atari, Brad Stewart - Sears", "CX2622 - 6-99813, 49-75107", "Breakout (1978) (Atari) [a]", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 60", "", "", "", "" },
+  { "4df9d7352a56a458abb7961bf10aba4e", "", "", "Racing Car (Unknown)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4e01d9072c500331e65bb87c24020d3f", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX26119", "Saboteur (06-15-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4e02880beeb8dbd4da724a3f33f0971f", "Imagic, Michael Greene", "EIZ-002-04I", "Wing War (1983) (Imagic) (PAL)", "AKA Flap!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4e15ddfd48bca4f0bf999240c47b49f5", "Avalon Hill, Jean Baer, Jim Jacob", "5001002", "Death Trap (1983) (Avalon Hill)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "4e2c884d04b57b43f23a5a2f4e9d9750", "", "", "Baby Center Animation (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "4e37992a37ea36489283f7eb90913bbc", "Kris", "", "Hangman Ghost Halloween (Kris) (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4e4895c3381aa4220f8c2795d6338237", "", "", "Backwards Cannonball v1 (Hack)", "Hack of Human Cannonball", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4e66c8e7c670532569c70d205f615dad", "Atari - GCC", "CX2680, CX2680P", "RealSports Tennis (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4e86866d9cde738d1630e2e35d7288ce", "Supergame", "", "River Raid III (Supergame)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4e99ebd65a967cabf350db54405d577c", "Coleco", "2663", "Time Pilot (1983) (Coleco) [b1]", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4eb4fd544805babafc375dcdb8c2a597", "Inspirational Video Concepts, Steve Shustack", "321430", "Red Sea Crossing (1983) (Inspirational Video Concepts)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4edb251f5f287c22efc64b3a2d095504", "Atari", "", "Atari VCS Point-of-Purchase ROM (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4f0071946e80ca68edfdccbac86dcce0", "", "", "Virtual Pet Demo 1 (CRACKERS) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4f2d47792a06da224ba996c489a87939", "HES - Activision", "223", "Super Action Pak - Pitfall, Barnstorming, Grand Prix, Laser Blast (1988) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4f32b24869d8c1310fecf039c6424db6", "U.S. Games Corporation - JWDA, Todd Marshall", "", "3-D Zapper (12-15-82) (U.S. Games) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "4f618c2429138e0280969193ed6c107e", "Activision, Alan Miller", "AZ-028, AG-028-04", "Robot Tank (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4f634893d54e9cabe106e0ec0b7bdcdf", "Retroactive", "", "Qb (2.14) (Retroactive) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "4f64d6d0694d9b7a1ed7b0cb0b83e759", "20th Century Fox Video Games, John Russell", "11016", "Revenge of the Beefsteak Tomatoes (1983) (20th Century Fox)", "AKA Revenge of the Cherry Tomatoes", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4f6702c3ba6e0ee2e2868d054b00c064", "Activision - Woodside Design Associates, Steve 'Jessica Stevens' Kitchen - Ariola", "EAZ-033 - 711 033-725", "Space Shuttle (1983) (Activision) (PAL)", "A Journey Into Space, Eine Reise ins All", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4f781f0476493c50dc578336f1132a67", "", "", "Indy 500 (Unknown) (PAL) (4K)", "Uses Driving Controllers", "", "", "", "", "", "", "", "", "DRIVING", "", "", "DRIVING", "", "", "", "", "", "45", "", "", "", "" },
+  { "4f7b07ec2bef5ccffe06403a142f80db", "Apollo - Games by Apollo, Ed Salvo, Byron Parks", "AP-2003", "Racquetball (1982) (Apollo) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "4f82d8d78099dd71e8e169646e799d05", "", "", "Miniature Golf (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4f89b897444e7c3b36aed469b8836839", "Atari", "CX26190", "BMX Air Master (1989) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4fae08027365d31c558e400b687adf21", "", "", "Qb (V2.17) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "4faeb04b1b7fb0fa25db05753182a898", "", "", "2600 Digital Clock (V x.xx) (PD) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4fbe0f10a6327a76f83f83958c3cbeff", "CCE", "C-816", "Keystone Kappers (1983) (CCE)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "4fc1b85b8074b4b9436d097900e34f29", "John K. Harvey", "", "John K. Harvey's Equalizer (John K. Harvey)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "50200f697aeef38a3ce31c4f49739551", "Mystique - American Multiple Industries, Joel H. Martin", "", "Custer's Revenge (1982) (Mystique) (PAL60)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "502044b1ac111b394e6fbb0d821fca41", "", "", "Hangman Invader 4letter (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "502168660bfd9c1d2649d415dc89c69d", "Activision, Bob Whitehead - Ariola", "EAG-019, EAG-019-04I - 711 019-715", "Sky Jinks (1982) (Activision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "504688d49a41bf03d8a955512609f3f2", "Thomas Jentzsch", "", "SWOOPS! (v0.94) (TJ)", "Uses the Joystick (L) and Paddle (R) Controllers", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "50568c80ac61cab789d9923c9b05b68e", "Ebivision", "", "Merlin's Walls - Standard Edition (1999) (Ebivision)", "Image rotated 90 degrees CW", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5069fecbe4706371f17737b0357cfa68", "Apollo - Games by Apollo, Steve Stringfellow", "AP-2005", "Shark Attack (1982) (Apollo) (PAL)", "AKA Lochjaw", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5079bfbc7b8f5770f84215ed2e3bdd1b", "Omegamatrix (2012)", "", "Genesis Button Tester", "", "Homebrew", "", "", "", "", "", "", "", "GENESIS", "", "", "GENESIS", "", "", "", "", "", "", "", "", "", "" },
+  { "50a410a5ded0fc9aa6576be45a04f215", "Activision, Bob Whitehead - Ariola", "EAG-019, EAG-019-04I - 711 019-715", "Sky Jinks (1982) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "50c7edc9f9dc0369abcdab3b4efeb5e9", "U.S. Games Corporation - JWDA, Todd Marshall", "", "3-D Zapper (U.S. Games) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "50ef88f9a5e0e1e6b86e175362a27fdb", "", "", "Multi-Sprite Game V2.4 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "512e874a240731d7378586a05f28aec6", "Tigervision, Rorke Weigandt - Teldec", "7-005", "Marauder (1982) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5131ab3797fe8c127e3e135b18b4d2c8", "Activision, David Crane", "AG-004", "Fishing Derby (1980) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "514f911ecff2be5eeff2f39c49a9725c", "Parker Brothers", "931510", "Sky Skipper (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "515046e3061b7b18aa3a551c3ae12673", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692", "Moon Patrol (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "516ffd008057a1d78d007c851e6eff37", "Parker Brothers, Dawn Stockbridge", "PB5910", "Strawberry Shortcake - Musical Match-Ups (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "517592e6e0c71731019c0cebc2ce044f", "Parker Brothers - JWDA, Todd Marshall", "PB5550", "Q-bert's Qubes (1984) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "517923e655755086a3b72c0b17b430e6", "Tron", "", "Super Tennis (Tron)", "AKA RealSports Tennis", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5188fee071d3c5ef0d66fb45c123e4a5", "Gameworld", "133-001", "Encounter at L-5 (1983) (Gameworld) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 50", "", "", "", "" },
+  { "519f007c0e14fb90208dbb5199dfb604", "Amiga - Video Soft", "", "Depth Charge (1983) (Amiga) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "51c1ddc9d6d597f71fb7efb56012abec", "Bit Corporation", "R320", "Lock 'n' Chase (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "51de328e79d919d7234cf19c1cd77fbc", "Atari, Mark R. Hahn", "CX2678", "Dukes of Hazzard (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "51e390424f20e468d2b480030ce95d7b", "Video Game Program", "", "Fire Bird (Video Game Program) (PAL)", "AKA Phoenix", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "51f15b39d9f502c2361b6ba6a73464d4", "", "", "Amanda Invaders (PD) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "51f211c8fc879391fee26edfa7d3f11c", "Activision, Bob Whitehead", "AX-015, AX-015-04", "Chopper Command (1982) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "521f4dd1eb84a09b2b19959a41839aad", "Bit Corporation", "PG206", "Bobby Is Going Home (1983) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "522b27a8afeb951b5a5a667f8d1a46a1", "Omegamatrix", "", "Millipede (Amiga Mouse) v6.5 (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "522c9cf684ecd72db2f85053e6f6f720", "Rainbow Vision - Suntek", "SS-008", "Year 1999, The (1983) (Rainbow Vision) (PAL)", "AKA Condor Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "52385334ac9e9b713e13ffa4cc5cb940", "CCE", "C-804", "Open, Sesame! (1983) (CCE)", "AKA Abre-te, Sesamo!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "523f5cbb992f121e2d100f0f9965e33f", "Joe Grand", "", "SCSIcide (1.30) (CGE 2001 Release) (Joe Grand)", "Uses the Paddle Controllers", "New Release", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "", "" },
+  { "524693b337f7ecc9e8b9126e04a232af", "", "", "Euchre (19-08-2001) (Eric Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5256f68d1491986aae5cfdff539bfeb5", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692", "Moon Patrol (07-26-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "525ea747d746f3e80e3027720e1fa7ac", "Activision, Garry Kitchen - Ariola", "EAZ-032 - 771 032-712", "Pressure Cooker (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "525f2dfc8b21b0186cff2568e0509bfc", "Activision, David Crane", "AG-930-04, AZ-030", "Decathlon (1983) (Activision) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "52615ae358a68de6e76467e95eb404c7", "", "", "DJdsl-wopd (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "528400fad9a77fd5ad7fc5fdc2b7d69d", "Starpath Corporation, Stephen H. Landrum, Jon Leupp", "11 AR-4201", "Sword of Saros (1983) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "52a0003efb3b1c49fcde4dbc2c685d8f", "Atari, Alan Miller - Sears", "CX2641 - 99807, 49-75105", "Surround (1977) (Atari) (4K) [a]", "", "", "", "", "2K", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "52b448757081fd9fabf859f4e2f91f6b", "", "", "Worm War I (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "52bae1726d2d7a531c9ca81e25377fc3", "", "", "Space Instigators (V1.8 Fixed) (20-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "52e1954dc01454c03a336b30c390fb8d", "Retroactive", "", "Qb (2.14) (Retroactive) (Stella)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "52e9db3fe8b5d336843acac234aaea79", "", "", "Fu Kung! (V0.11) (28-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5305f69fbf772fac4760cdcf87f1ab1f", "Jone Yuan Telephonic Enterprise Co", "", "Ski Run (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5324cf5b6dc17af4c64bf8696c39c2c1", "Imagic, Dennis Koble", "IA3203, IX-010-04", "Atlantis (1982) (Imagic) (8K)", "AKA Lost City of Atlantis", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "533661e9bccd8a9f80ce3765f282c92f", "Omegamatrix", "", "Star Wars Arcade (Atari Trak-Ball) (Y Inverted) v4 (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5336f86f6b982cc925532f2e80aa1e17", "Parker Brothers - JWDA, Todd Marshall, Robin McDaniel, Ray Miller", "PB5060", "Star Wars - Death Star Battle (1983) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "534e23210dd1993c828d944c6ac4d9fb", "M Network, Stephen Tatsumi, Jane Terjung - Kool Aid", "MT4648", "Kool-Aid Man (1983) (M Network)", "AKA Kool Aid Pitcher Man", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5355f80cacf0e63a49cbf4ade4e27034", "Christian Samuel", "", "Cute Dead Things House (Christian Samuel) (Hack)", "Hack of Haunted House", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5360693f1eb90856176bd1c0a7b17432", "", "", "Oystron (V2.85) (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "536bf56baa70acb17113884ac41f2820", "Atari, Omegamatrix", "", "Video Olympics Menu (2020) (PAL) (Hack)", "Hack of Video Olympics", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "AUTO 60", "", "", "", "" },
+  { "537ed1e0d80e6c9f752b33ea7acbe079", "", "", "A-VCS-tec Challenge (beta 5) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5385cf2a04de1d36ab55c73174b84db0", "Paul Slocum", "", "Combat Rock (PD) (Hack)", "Hack of Combat", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "539d26b6e9df0da8e7465f0f5ad863b7", "Atari, Carol Shaw - Sears", "CX2636 - 49-75156", "Video Checkers (1980) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "539f3c42c4e15f450ed93cb96ce93af5", "Dion Olsthoorn", "v1.3", "Amoeba Jump (2018) (Dionoid)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "53b66f11f67c3b53b2995e0e02017bd7", "CCE", "C-1005", "Super Tennis (1983) (CCE)", "AKA RealSports Tennis", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "53bd1c7c972ae634c912331a9276c6e3", "Atari, Nick 'Sandy Maiwald' Turner", "CX2665", "Frog Pond (1982) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "53d181cde2e0219b5754caad246fcb66", "", "", "Missile Demo (1998) (Ruffin Bailey) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "53e03df47e76329b701641f8bdc206f5", "Thomas Jentzsch", "", "Centipede - Atari Trak-Ball Hack v1.4 (PAL) (Half-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "53f147b9746fdc997c62f3dd67888ee5", "Activision, Bob Whitehead", "AG-011", "Stampede (1981) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "540075f657d4b244a1f74da1b9e4bf92", "Bit Corporation", "PGP230", "Festival (4 Game in One Dark Green) (1983) (BitCorp) (PAL)", "AKA Carnival", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5409d20c1aea0b89c56993aec5dc5740", "", "", "Carnival Shooter (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "541cac55ebcf7891d9d51c415922303f", "SpiceWare - Darrell Spice Jr.", "SW-05", "Stay Frosty 2", "AtariAge Holiday Greetings 2014", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "5428cdfada281c569c74c7308c7f2c26", "Activision, Larry Kaplan, David Crane", "AG-010, AG-010-04", "Kaboom! (1981) (Activision)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
+  { "542c6dd5f7280179b51917a4cba4faff", "ZiMAG - Emag - Vidco", "GN-080", "Spinning Fireball (1983) (ZiMAG) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5438e84b90e50a5362f01cc843b358d4", "Arcadia Corporation, Scott Nelson", "3 AR-4300", "Fireball (1982) (Arcadia) (Prototype)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "543b4b8ff1d616fa250c648be428a75c", "Warren Robinett", "", "Adventure (1978) (Warren Robinett) (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "545048ccb045f9efc6cf2b125cd0dfa8", "Arcadia Corporation, Stephen Harland Landrum, Jon Leupp", "AR-4201", "Sword of Saros (1983) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "54785fa29e28aae6038929ba29d33d38", "", "", "Poker Squares (V0.19) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "54836a8f23913e9a77c7f2665baf36ac", "Bit Corporation", "PG204", "Open, Sesame! (1982) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5494b9ee403d9757f0fd1f749e80214a", "Larry Petit", "", "Xenophobe Arcade (2003) (Larry Petit) (Hack)", "Hack of Xenophobe", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "54a1c1255ed45eb8f71414dadb1cf669", "Spectravideo", "SA-212", "Mangia' (1983) (Spectravideo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "54bafc299423f5a50b8bc3a797914706", "SOLID Corp. (D. Scott Williamson)", "CX2655*", "Star Castle 2600 (SolidCorp) (PAL)", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "54da3b0b3f43f5b37911c135b9432b49", "", "", "Halloween III Revision (Hack)", "Hack of Kaboom!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
+  { "54f7efa6428f14b9f610ad0ca757e26c", "Apollo - Games by Apollo, Steve Stringfellow", "AP-2005", "Shark Attack (1982) (Apollo)", "AKA Lochjaw", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "551a64a945d7d6ece81e9c1047acedbc", "Matthias Jaap", "", "Coffee Cup Soccer (Matthias Jaap) (Hack)", "Hack of Pele's Soccer", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5524718a19107a04ec3265c93136a7b5", "Thomas Jentzsch", "", "RealSports Basketball (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "553dbf9358cfd2195e2fa0e08b01fb6a", "Atari - GCC, Mike Feinstein, Kevin Osborn", "CX2691", "Joust (07-05-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "554fd5775ca6d544818c96825032cf0d", "Atari - Roklan, Bob Curtiss", "", "Firefox (06-01-83) (Atari) (Prototype)", "AKA Combat II, Fighter Command", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "557e893616648c37a27aab5a47acbf10", "Atari - Axlon, Tod Frye - Heuristica, Augustin Ortiz", "CX26169", "Shooting Arcade (01-16-1990) (Atari) (Prototype) (PAL)", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "559317712f989f097ea464517f1a8318", "Panda", "100", "Space Canyon (1983) (Panda)", "AKA Space Cavern", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "55949cb7884f9db0f8dfcf8707c7e5cb", "Atari, Ed Logg, Carol Shaw - Sears", "CX2639 - 49-75162", "Othello (1981) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "55ace3c775f42eb46f08bb1dca9114e7", "", "", "Shadow Keep (04-03-2003) (Andrew Towers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "55ef6ab2321ca0c3d369e63d59c059c8", "", "", "Pitfall! (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "55ef7b65066428367844342ed59f956c", "Atari - Roklan, Joe Gaucher, Alex Leavens", "CX2683", "Crazy Climber (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "56210a3b9ea6d5dd8f417a357ed8ca92", "Probe 2000 - NAP, Roger Booth, Todd Marshall, Robin McDaniel, Jim Wickstead", "3152VC", "Pursuit of the Pink Panther (Probe) (Prototype) [bad dump]", "AKA Adventures of the Pink Panther", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "56300ed31fef018bd96768ccc982f7b4", "HES - Activision", "559", "Rad Action Pak - Kung-Fu Master, Freeway, Frostbite (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5641c0ff707630d2dd829b26a9f2e98f", "Joystik", "", "Motocross (Joystik)", "AKA Motocross Racer", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5643ee916f7dc760148fca4db3aa7d10", "", "", "Moon Patrol (Genesis)", "Genesis controller (C is jump)", "Hack of Moon Patrol", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5678ebaa09ca3b699516dba4671643ed", "Coleco, Sylvia Day, Henry Will IV", "2459", "Mouse Trap (1982) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "568371fbae6f5e5b936af80031cd8888", "", "", "Robotfindskitten2600 (26-04-2003) (Jeremy Penner)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "56f72247eb9ebfd33bfd0cca23ab7ef4", "Omegamatrix", "", "Star Wars Arcade (Amiga Mouse) v4 (PAL60) (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "571c6d9bc71cb97617422851f787f8fe", "Activision, David Crane - Ariola", "EAG-004, PAG-004 - 711 004-715", "Fishing Derby (1980) (Activision) (PAL)", "AKA Schneller als der Hai", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "572d0a4633d6a9407d3ba83083536e0f", "Funvision - Fund. International Co.", "", "Busy Police (Funvision)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "575c0fb61e66a31d982c95c9dea6865c", "", "", "Blackjack (Unknown) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "57939b326df86b74ca6404f64f89fce9", "Atari, Sam Comstock, Richard Dobbis, Nick 'Sandy Maiwald' Turner", "CX26111", "Snoopy and the Red Baron (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "579baa6a4aa44f035d245908ea7a044d", "Jess Ragan", "", "Galaxian Enhanced Graphics (Jess Ragan) (Hack)", "Hack of Galaxian", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "57a66b6db7efc5df17b0b0f2f2c2f078", "Retroactive", "", "Qb (V2.08) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "57c5b351d4de021785cf8ed8191a195c", "Atari - CCW, Gary Stark", "CX26102", "Cookie Monster Munch (1983) (Atari)", "Uses Kids/Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" },
+  { "5835a78a88f97acea38c964980b7dbc6", "", "", "Cosmic Creeps (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "5846b1d34c296bf7afc2fa05bbc16e98", "Atari - Sears", "CX2643 - 6-99815", "Codebreaker (1978) (Atari)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "58513bae774360b96866a07ca0e8fd8e", "Mystique - American Multiple Industries, Joel H. Martin", "1001", "Custer's Revenge (1982) (Mystique)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "585600522b1f22f617652c962e358a5d", "", "", "Multi-Sprite Game V2.2 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "585f73010e205ae5b04ee5c1a67e632d", "", "", "Daredevil (V3) (Stunt_Cycle_Rules!) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5864cab0bc21a60be3853b6bcd50c59f", "", "", "Commando Raid (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "58746219d8094edff869f0f5c2aeaad5", "Jone Yuan Telephonic Enterprise Co", "", "Bowling (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5894c9c0c1e7e29f3ab86c6d3f673361", "Activision - Woodside Design Associates, Steve 'Jessica Stevens' Kitchen", "AZ-033, AZ-033-04", "Space Shuttle (1983) (Activision)", "A Journey Into Space", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "589c73bbcd77db798cb92a992b4c06c3", "Xonox - K-Tel Software - Action Graphics, Michael Schwartz, David Thiel", "6230, 7210, 06004, 99004", "Artillery Duel (1983) (Xonox) (PAL60)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "58a82e1da64a692fd727c25faef2ecc9", "CCE", "C-824", "Jaw Breaker (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "58c396323ea3e85671e34c98eb54e2a4", "Brian Watson", "", "Color Tweaker (B. Watson)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "58d331c23297ed98663d11b869636f16", "", "", "Fu Kung! (V0.09) (26-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "58e313e2b5613b2439b5f12bb41e3eef", "", "", "Cube Conquest (Demo Interlace) (Billy Eno) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "590ac71fa5f71d3eb29c41023b09ade9", "Atari - GCC, Mark Ackerman, Tom Calderwood, Glenn Parker", "CX2684", "Galaxian (01-05-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "59135f13985b84c4f13cc9e55eec869a", "", "", "Multi-Sprite Game V2.0 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "594437a35603c3e857b5af75b9718b61", "HES - Activision", "", "Robot Tank (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "594dbc80b93fa5804e0f1368c037331d", "Telesys, Alex Leavens", "", "Bouncin' Baby Bunnies (1983) (Telesys) (Prototype)", "AKA Baby Boom Boom, Bouncing Baby Monkeys", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5961d259115e99c30b64fe7058256bcf", "Universal Gamex Corporation, Miguel Castillo, H.K. Poon", "GX-001", "X-Man (1983) (Universal)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "59734e1cc41822373845a09c51e6ba21", "Activision, John Van Ryzin", "AG-038-04", "Cosmic Commuter (1984) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "598a4e6e12f8238b7e7555f5a7777b46", "Tigervision", "7-008", "Miner 2049er (1983) (Tigervision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "599cbf919d47a05af975ad447df29497", "Jake Patterson", "", "Baubles (V0.002) (2001) (Jake Patterson) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "59b70658f9dd0e2075770b07be1a35cf", "Thomas Jentzsch", "", "Surfer's Paradise (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "59d33e00c07665395209c1e55da0b139", "", "", "Imagic Selector ROM (1982) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "59e53894b3899ee164c91cfa7842da66", "Data Age", "", "Survival Run (1983) (Data Age) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "59e96de9628e8373d1c685f5e57dcf10", "PlayAround - J.H.M.", "204", "Beat 'Em & Eat 'Em (1982) (PlayAround)", "Uses the Paddle Controllers", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" },
+  { "59f596285d174233c84597dee6f34f1f", "CCE", "C-811", "River Raid (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5a0ff99ba10bd26d542e1d6f59f56850", "Champ Games", "CG-04-P", "Super Cobra Arcade (PAL60)", "Compatible with Genesis controller", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "5a17e30e6e911e74ccd7b716d02b16c6", "Activision, Dan Kitchen", "AX-029", "Crackpots (1983) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5a272012a62becabcd52920348c7c60b", "Star Game", "", "Pitfall (Star Game)", "AKA Pitfall!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5a2f2dcd775207536d9299e768bcd2df", "Otto Versand", "781698", "Flippern (Double-Game Package) (1983) (Otto Versand) (PAL)", "AKA Video Pinball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5a4205aeedd3b0588f973f38bbd9dfd4", "Thomas Jentzsch", "", "Centipede - Amiga Mouse Hack v1.4 (PAL) (Full-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5a5390f91437af9951a5f8455b61cd43", "Retroactive", "", "Qb (0.11) (Retroactive) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "5a6febb9554483d8c71c86a84a0aa74e", "CCE", "C-1003", "Donkey Kong Jr (1983) (CCE)", "AKA Donkey Kong Junior", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5a734779d797ccef25dc8acfa47244c7", "", "", "Oh No! (Version 2) (18-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5a80b857eb8b908ab477ec4ef902edc8", "Activision, Bob Whitehead", "AG-002, CAG-002, AG-002-04", "Boxing (1980) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5a81ad4e184050851e63c8e16e3dac77", "Jone Yuan Telephonic Enterprise Co", "Hack", "Sky Diver (Jone Yuan) (Hack)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5a8afe5422abbfb0a342fb15afd7415f", "Atari - Bobco, Robert C. Polaro", "CX26155", "Sprint Master (1988) (Atari)", "AKA Sprint 88, Sprint 2000", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5a93265095146458df2baf2162014889", "Activision, Steve Cartwright - Ariola", "EAX-031, EAX-031-04B - 711 031-717", "Frostbite (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5a9685c4d51a6c1d6a9544946d9e8dc3", "AtariAge", "", "Grandma's Revenge (AtariAge)", "Can use Driving Controller in right port", "", "", "", "", "", "", "", "", "", "", "", "DRIVING", "", "", "", "", "", "", "", "", "", "" },
+  { "5a9d188245aff829efde816fcade0b16", "CCE", "C-808", "Phantom Tank (1983) (CCE) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5acf9865a72c0ce944979f76ff9610f0", "", "", "Dodge Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5ae73916fa1da8d38ceff674fa25a78a", "CCE", "", "Barnstorming (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5aea9974b975a6a844e6df10d2b861c4", "Atari, Dan Hitchens. Mimi Nyden", "CX2656", "SwordQuest - EarthWorld (1982) (Atari)", "AKA Adventure I, SwordQuest I - EarthWorld", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5af9cd346266a1f2515e1fbc86f5186a", "SEGA", "002-01", "Sub-Scan (1983) (SEGA)", "AKA Subterfuge", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5b124850de9eea66781a50b2e9837000", "PlayAround - J.H.M.", "205", "Bachelor Party (1982) (PlayAround)", "Uses the paddle controllers", "Extremely Rare", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "YES", "" },
+  { "5b574faa56836da0866ba32ae32547f2", "", "", "Tomb Raider 2600 [REV 03] (Montezuma's Revenge Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5b5d04887922b430de0b7b2a21f9cd25", "", "", "Omega Race (Genesis)", "Genesis controller (B is thrust, C is fire)", "Hack of Omega Race", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5b6f5bcbbde42fc77d0bdb3146693565", "", "", "Seaquest (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5b7ea6aa6b35dc947c65ce665fde624b", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (2 of 3) (1982) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5b85e987e2b1618769d97ba9182333d0", "Atari - GCC, Mike Feinstein, Brad Rice", "CX2681", "Battlezone (05-12-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5b92a93b23523ff16e2789b820e2a4c5", "Activision - Imagineering, Dan Kitchen, Garry Kitchen", "AG-039-04", "Kung-Fu Master (1987) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5b98e0536c3f60547dd708ae22adb04b", "Ben Hudman", "", "Donkey Kong Gingerbread Man (Ben Hudman) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5b9c2e0012fbfd29efd3306359bbfc4a", "HES", "", "2 Pak Special - Hoppy, Alien Force (1992) (HES) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5babe0cad3ec99d76b0aa1d36a695d2f", "Coleco - Individeo, Ed Temple", "2654", "Looping (1983) (Coleco) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5bba254e18257e578c245ed96f6b003b", "", "", "Music Effects Demo (21-01-2003) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "5bbab3f3e4b47e3e23f9820765dbb45c", "", "", "Pitfall! (says 1985) [h1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5bbb75b49b2bccef9c91ff84bb249c80", "Thomas Jentzsch", "", "Missile Control - Atari Trak-Ball Hack v1.15 (NTSC) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5bc9998b7e9a970e31d2cb60e8696cc4", "Jack Kortkamp", "", "Borgwars Asteroids (2003) (Jack Kortkamp) (Hack)", "Hack of Asteroids", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "5bcc83677d68f7ef74c1b4a0697ba2a8", "Activision, Alan Miller", "AX-012, CAX-012, AX-012-04", "Ice Hockey (1981) (Activision) (16K)", "", "", "", "", "4K", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5bd79139a0c03b63f6f2cf00a7d385d2", "Marc de Smet", "", "An Exercise In Minimalism (V1) (1999) (Marc de Smet) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5be03a1fe7b2c114725150be04b38704", "Atari, Alan Miller", "CX2642", "Hunt & Score (1978) (Atari) (PAL)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5c0227ad63300670a647fcebf595ea37", "Josh", "", "Battle for Naboo (Josh) (Hack)", "Hack of Atlantis", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5c0520c00163915a4336e481ca4e7ef4", "Rainbow Vision - Suntek", "SS-004", "Pyramid War (1983) (Rainbow Vision) (PAL) [a1]", "AKA Chopper Command", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5c19f6da638c4c7c1f98d09e63df43e4", "Canal 3 - Intellivision", "", "Cosmic Ark (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5c1b1aa78b7609d43c5144c3b3b60adf", "", "", "Demo Image Series #8 - Two Marios (Different Interlacing) (27-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5c3a6d27c026f59a96b7af91e8b1bf26", "PlayAround - J.H.M.", "", "PlayAround Demo (PlayAround) (1982)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5c618a50dfa23daac97ba459b9ff5206", "Steve Engelhardt", "", "Berzerk Renegade (2002) (Steve Engelhardt) (Hack)", "Hack of Room of Doom", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "5c73693a89b06e5a09f1721a13176f95", "", "", "Wavy Line Test 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5c86e938e0845b9d61f458539e9a552b", "Atari, Alan Miller", "CX26163P", "Surround (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5cbd7c31443fb9c308e9f0b54d94a395", "Spectravideo, Mark Turmell", "SA-217", "Gas Hog (1983) (Spectravideo) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5ce98f22ade915108860424d8dde0d35", "", "", "Hangman Man Biglist3 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5ced13931c21ef4fc77d3fe801a1cbfa", "CCE", "C-828", "Missile Command (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5d0e8a25cbd23e76f843c75a86b7e15b", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (09-07-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5d132d121aabc5235dd039dfc46aa024", "", "", "Basketball (208 in 1) (Unknown) (PAL) (Hack)", "Console ports are swapped", "Hack", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5d25df9dc2cde746ceac48e834cf84a7", "Activision - Woodside Design Associates, Steve 'Jessica Stevens' Kitchen", "EAZ-033", "Space Shuttle (1983) (Activision) (SECAM)", "A Journey Into Space", "", "", "", "FE", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5d2cc33ca798783dee435eb29debf6d6", "Activision - Imagineering, Mike Reidel", "AK-043-04", "Commando (1988) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5d7293f1892b66c014e8d222e06f6165", "Atari - Axlon, Tod Frye - Heuristica, Agustin Ortiz", "CX26169", "Shooting Arcade (03-07-1989) (Atari) (Prototype) [a1]", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5d799bfa9e1e7b6224877162accada0d", "Spectravision - Spectravideo - Sirius Software, David Lubar", "SA-206", "Challenge of.... Nexar, The (1982) (Spectravision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5d8f1ab95362acdf3426d572a6301bf2", "Thomas Jentzsch", "", "SWOOPS! (v0.96) (TJ) (PAL)", "Uses the Joystick (L) and Paddle (R) Controllers", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5d8fb14860c2f198472b233874f6b0c9", "", "", "Boing! (PD) [a2]", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5d9592756425192ec621d2613d0e683d", "CCE", "C-839", "Misterious Thief, A (1983) (CCE) [a]", "AKA A Mysterious Thief", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5da8fd0b5ed33a360bff37f8b5d0cd58", "Tron", "", "Pole Position (Tron)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5dae540347cf0a559962d62604ecf750", "Canal 3 - Intellivision", "", "Freeway (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5db9e5bf663cad6bf159bc395f6ead53", "Goliath - Hot Shot", "83-212", "Time Race (1983) (Goliath) (PAL)", "AKA Space Jockey", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5dccf215fdb9bbf5d4a6d0139e5e8bcb", "Froggo", "FG1009", "Sea Hunt (1987) (Froggo)", "AKA Skindiver", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5de8803a59c36725888346fdc6e7429d", "Atari, John Dunn - Sears", "CX2631 - 49-75152", "Superman (1979) (Atari) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5df32450b9fbcaf43f9d83bd66bd5a81", "Eric Ball", "", "Atari Logo Playfield Demo (2001) (Eric Ball) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5df559a36347d8572f9a6e8075a31322", "Digivision", "", "Enduro (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5e0c37f534ab5ccc4661768e2ddf0162", "Telegames - VSS, Ed Salvo", "5667 A106", "Glacier Patrol (1988) (Telegames)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5e1b4629426f4992cf3b2905a696e1a7", "Activision - Bobco, Robert C. Polaro", "AK-049-04", "Rampage! (1989) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5e1b7a6078af428ef056fe85a37a95ca", "Activision, David Crane", "AX-014, AX-014-04", "Grand Prix (1982) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5e1cd11a6d41fc15cf4792257400a31e", "Philip R. Frey", "", "Return of Mario Bros (Philip R. Frey) (Hack)", "Hack of Mario Bros.", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5e201d6bfc520424a28f129ee5e56835", "Universal Gamex Corporation, Miguel Castillo, H.K. Poon", "GX-001", "X-Man (1983) (Universal) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5e2495d43b981010304af55efed1e798", "Jone Yuan Telephonic Enterprise Co", "", "Math Gran Prix (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5e43c0391f7412ae64fae6f3742d6ee9", "Thomas Jentzsch, Paul Slocum", "", "Thrust+ Platinum (v1.27)", "", "New Release, supports BoosterGrip", "", "", "", "", "", "", "", "BOOSTERGRIP", "", "", "DRIVING", "", "", "", "", "", "", "", "", "", "" },
+  { "5e99aa93d0acc741dcda8752c4e813ce", "", "", "2600 Digital Clock (V b2) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5ec73ac7d2ac95ac9530c6d33e713d14", "Arcadia Corporation, Scott Nelson", "13", "Sweat! - The Decathlon Game (2 of 3) (1983) (Arcadia) (Prototype)", "Uses the Paddle Controllers (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5eeb81292992e057b290a5cd196f155d", "Wizard Video Games - VSS, Ed Salvo", "008", "Texas Chainsaw Massacre, The (1983) (Wizard Video)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5ef303b9f0aa8cf20720c560e5f9baa1", "Atari, Jim Huether", "CX2629, CX2629P", "Sky Diver (1979) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5f1b7d5fa73aa071ba0a3c2819511505", "CCE", "", "Cosmic Commuter (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5f2b4c155949f01c06507fb32369d42a", "Apollo, Ed Salvo", "AP-1001", "Skeet Shoot (1981) (Apollo) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5f316973ffd107f7ab9117e93f50e4bd", "", "", "Commando Raid (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5f39353f7c6925779b0169a87ff86f1e", "Atari - GCC, John Allred, Douglas B. Macrae, Betty Ryan Tylko", "CX2694", "Pole Position (1983) (Atari) [a]", "AKA RealSports Driving", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5f46d1ff6d7cdeb4b09c39d04dfd50a1", "Atari, Gary Palmer", "CX2661P", "Fun with Numbers (1980) (Atari) (PAL)", "AKA Basic Math", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5f4ebf8a1e5f5f7b9ff3e3c6affff3e6", "Bit Corporation", "R320", "Donkey Kong (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5f560837396387455c9dcb05cdd4b053", "Canal 3 - Intellivision", "", "Eggomania (Canal 3)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 60", "", "", "", "" },
+  { "5f681403b1051a0822344f467b05a94d", "Atari, Howard Scott Warshaw - Sears", "CX2655 - 49-75167", "Yars' Revenge (1982) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "5f708ca39627697e859d1c53f8d8d7d2", "Atari, Warren Robinett - Sears", "CX2606 - 6-99825, 49-75112", "Slot Racers (1978) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5f73e7175474c1c22fb8030c3158e9b3", "Atari, Nick 'Sandy Maiwald' Turner", "CX2665", "Frog Pond (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5f786b67e05fb9985b77d4beb35e06ee", "Atari, Bill Aspromonte, Andrew Fuchs", "CX26120", "Defender II (1987) (Atari) (PAL)", "AKA Stargate", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5f7ae9a7f8d79a3b37e8fc841f65643a", "Atari, Jerome Domurat, Peter C. Niday, Robert Vieira", "CX26109", "Sorcerer's Apprentice (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5f7de62a408b9de3a1168898298fd31d", "", "", "Super Cobra (Genesis)", "Genesis controller (B is bomb, C is laser)", "Hack of Super Cobra", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5f950a2d1eb331a1276819520705df94", "20th Century Fox Video Games - Micro Computer Technologies, Jim Collas", "", "Heart Like a Wheel (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "5f9b62350b31be8bd270d9a241cbd50e", "Telegames", "5658 A088", "Football (1988) (Telegames) (PAL)", "AKA Super Challenge Football", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5faffe1c4c57430978dec5ced32b9f4a", "Dactari - Milmar", "", "Volleyball (Dactari - Milmar)", "AKA RealSports Volleyball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "5fb71cc60e293fe10a5023f11c734e55", "", "", "This Planet Sucks (Fix) (27-12-2002) (Greg Troutman)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "600d48eef5c0ec27db554b7328b3251c", "", "", "Bars and Text Demo 3 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6015a9cef783e97e98a2aa2cf070ae06", "Thomas Jentzsch", "", "Battlezone TC (Thomas Jentzsch) (Hack)", "Uses two simultaneous Joystick Controllers, Hack of Battlezone", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "60358edf0c2cc76b1e549e031e50e130", "Manuel Polik", "", "Cyber Goth Galaxian (Manuel Polik) (Hack)", "Hack of Galaxian", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "603c7a0d12c935df5810f400f3971b67", "Bit Corporation", "PG209", "Mr. Postman (1983) (BitCorp) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6041f400b45511aa3a69fab4b8fc8f41", "Apollo, Ban Tran", "AP-2010", "Wabbit (1982) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "604e09724555807c28108049efe34a13", "", "", "Sokoban (01-01-2003) (Adam Wozniak)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6058e40ce79d7434c7f7477b29abd4a5", "", "", "Rubik's Cube Demo (23-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "605dcb73d22f4efdb90ef9da2f290f7c", "Atari, Larry Kaplan", "CX26163P", "Air-Sea Battle (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "605fd59bfef88901c8c4794193a4cbad", "Data Age", "", "Secret Agent (1983) (Data Age) (Prototype)", "Uses the Paddle Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 45", "", "", "", "" },
+  { "606c2c1753051e03c1f1ac096c9d2832", "Jone Yuan Telephonic Enterprise Co", "", "Crackpots (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6076b187a5d8ea7a2a05111c19b5d5cd", "", "", "Fu Kung! (V0.14) (01-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "60a61da9b2f43dd7e13a5093ec41a53d", "VentureVision, Dan Oliver", "VV2001", "Rescue Terra I (1982) (VentureVision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "60bbd425cb7214ddb9f9a31948e91ecb", "Activision, Bob Whitehead", "AG-005, CAG-005, AG-005-04", "Skiing (1980) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "60cd61a2dfccb0e2736434f9792c1672", "Amiga - Video Soft, Frank Ellis, Jerry Lawson", "2110", "3-D Havoc (1983) (Amiga) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "60d304582d33e2957b73eb300a7495bb", "", "", "Jam Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "60e0ea3cbe0913d39803477945e9e5ec", "Atari, Joe Decuir - Sears", "CX2621 - 99806, 6-99806, 49-75104", "Video Olympics (1977) (Atari)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "PADDLES_IAXDR", "", "", "YES", "", "", "AUTO 60", "", "", "", "" },
+  { "613abf596c304ef6dbd8f3351920c37a", "", "", "Boring Pac-Man (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6141c095d0aee4e734bebfaac939030a", "Rainbow Vision - Suntek", "SS-017", "Mariana (1983) (Rainbow Vision) (PAL)", "AKA Seaquest", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "61426cee013306e7f7367534ab124747", "", "", "One Blue Bar Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "615a3bf251a38eb6638cdc7ffbde5480", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX2674", "E.T. - The Extra-Terrestrial (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "61621a556ad3228f0234f5feb3ab135c", "", "", "Fu Kung! (V0.05 Cuttle Card Compattle Revision) (14-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "61631c2f96221527e7da9802b4704f93", "Activision - Imagineering, Mike Reidel", "AK-043-04", "Commando (1988) (Activision) [different logo]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "61719a8bdafbd8dab3ca9ce7b171b9e2", "", "", "Enduro (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "61728c6cfb052e62a9ed088c5bf407ba", "", "", "Sprite Demo 4 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "619de46281eb2e0adbb98255732483b4", "", "", "Time Warp (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "61baadddc2c8f6e5faa57d4d0f285462", "", "", "208-in-1 MDM-Test (PAL) (127 games)", "", "", "", "", "MDM", "", "", "", "", "JOYSTICK", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "" },
+  { "61dbe94f110f30ca4ec524ae5ce2d026", "CCE", "C-820", "Space Invaders (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "61e0f5e1cc207e98704d0758c68df317", "Star Game", "007", "Tennis (Star Game)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "61ef8c2fc43be9a04fe13fdb79ff2bd9", "", "", "Gas Gauge Demo - Revisited (2001) (Joe Grand) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6205855cc848d1f6c4551391b9bfa279", "", "", "Euchre (Release Candidate 2) (NTSC) (01-10-2002) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6238ac888871fec301d1b9fc4fc613c9", "Thomas Jentzsch", "", "Marble Craze - Atari Mouse Hack v1.0 (PAL) (TJ)", "Uses Atari Mouse Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "624e0a77f9ec67d628211aaf24d8aea6", "Panda", "108", "Sea Hawk (1983) (Panda)", "AKA Seahawk", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "626d67918f4b5e3f961e4b2af2f41f1d", "Atari", "50008", "Diagnostic Test Cartridge 2.0 (1980) (Atari) (Prototype)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6272f348a9a7f2d500a4006aa93e0d08", "Atari, Jerome Domurat, Michael Sierchio", "CX2667, CX2667P", "RealSports Soccer (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "62899430338e0538ee93397867d85957", "Gameworld", "133-004", "Airlock (1983) (Gameworld) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "62921652f6634eb1a0940ed5489c7e18", "", "", "SCSIcide (V1.09) (2001) (Joe Grand)", "", "", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "", "" },
+  { "62992392ea651a16aa724a92e4596ed6", "Eric Mooney", "", "Invaders by Erik Mooney (Beta) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "62d1f50219edf9a429a9f004c19f31b3", "JWDA, Todd Marshall", "", "Euro Gen (02-01-83) (JWDA) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "62ee2b8f59e9cd6285bbdb674a952e8b", "Probe 2000 - NAP, Roger Booth, Todd Marshall, Robin McDaniel, Jim Wickstead", "3152VC", "Pursuit of the Pink Panther (Probe) (Prototype)", "AKA Adventures of the Pink Panther", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "62f74a2736841191135514422b20382d", "", "", "Pharaoh's Curse (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "PAL60", "", "YES", "" },
+  { "62ffd175cac3f781ef6e4870136a2520", "", "", "2600 Digital Clock (V x.xx) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "63166867f75869a3592b7a94ea62d147", "", "", "Indy 500 (Hack) [a1]", "Hack of Indy 500", "Hack", "", "", "", "", "", "", "", "DRIVING", "", "", "DRIVING", "", "", "", "", "", "", "", "", "", "" },
+  { "6333ef5b5cbb77acd47f558c8b7a95d3", "Greg Troutman", "", "Dark Mage (Greg Troutman) (PD) (8K)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "6337927ad909aa739d6d0044699a916d", "Jeffry Johnston", "", "Radial Pong - Version 2 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6339d28c9a7f92054e70029eb0375837", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (1984) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "6342afe9c9ad1b6120b8f6fb040d0926", "", "", "Move a Blue Blob Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6354f9c7588a27109c66905b0405825b", "Thomas Jentzsch", "", "Amidar DS (2003) (TJ) (Hack)", "Hack of Amidar", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6358f7f8bf0483402a080efccf250d61", "CommaVid, John Bronstein", "CM-003", "Cosmic Swarm (1982) (CommaVid) (Prototype)", "AKA Termite", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "635cc7a0db33773959d739d04eff96c2", "", "", "Minesweeper (V.90) (Soren Gust) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6362396c8344eec3e86731a700b13abf", "Panda", "109", "Exocet (1983) (Panda)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "637efac676ff063f2fbb0abff77c4fa5", "", "", "Noize Maker Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "63811ed69bdbc35c69d8aa7806c3d6e9", "Atari", "CX26163P", "Homerun (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "638cc82ea96f67674595ba9ae05da6c6", "Rainbow Vision - Suntek", "SS-011", "Super Ferrari (1983) (Rainbow Vision) (PAL)", "AKA Enduro", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "63a6eda1da30446569ac76211d0f861c", "Activision, David Crane", "AG-001", "Dragster (1980) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "63a7445b1d3046d3cdcdbd488dca38d9", "Rob Kudla", "", "Better Space Invaders (1999) (Rob Kudla) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "63c5fef3208bb1424d26cf1ab984b40c", "", "", "Analog Clock (V0.1) (20-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "63c7395d412a3cd095ccdd9b5711f387", "Eric Ball", "ELB005", "Skeleton+ (PAL)", "Stereo sound", "Homebrew", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "63d6247f35902ba32aa49e7660b0ecaa", "", "", "Space War (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "63e42d576800086488679490a833e097", "Telesys, Jim Rupp", "1004", "Ram It (1983) (Telesys) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "63e783994df824caf289b69a084cbf3e", "David Marli", "", "Fat Albert (David Marli) (Hack)", "Hack of Fast Food", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "63e9e612bbee31045f8d184a4e53f8ec", "ATARITALIA", "", "Moby Blues (2002) (ATARITALIA) (Hack)", "Hack of Mario Bros", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "640a08e9ca019172d612df22a9190afb", "Atari - GCC, Mike Feinstein, Kevin Osborn", "CX2691, CX2691P", "Joust (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "64198bb6470c78ac24fcf13fe76ab28c", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (1982) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "643e6451eb6b8ab793eb60ba9c02e000", "Salu - Avantgarde Software, Michael Buetepage", "460741", "Ghostbusters II (1992) (Salu) (PAL) [different tune]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "645bf7f9146f0e4811ff9c7898f5cd93", "Xonox - K-Tel Software - VSS, Robert Weatherby", "6230, 6250", "Super Kung-Fu (1983) (Xonox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6468d744be9984f2a39ca9285443a2b2", "Atari, Ed Logg, Carol Shaw", "CX26163P", "Reversi (32 in 1) (1988) (Atari) (PAL)", "AKA Othello", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "647162cceb550fd49820e2206d9ee7e8", "", "", "Skeleton (NTSC) (2002) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "64b8e19c767191ccdc97acc6904c397b", "Jeffry Johnston", "", "Radial Pong - Version 6 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "64ca518905311d2d9aeb56273f6caa04", "CCE", "", "Cubo Magico (CCE)", "AKA Cubicolor", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "64d43859258dc8ca54949e9ff4174202", "Thomas Jentzsch", "", "Lilly Adventure (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "64fab9d15df937915b1c392fc119b83b", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX26119", "Saboteur (05-20-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "650df778c6ce22d3fd1a7c33c565bcc3", "Atari - GCC, Betty Ryan Tylko, Douglas B. Macrae", "CX2694", "Pole Position (1983) (Atari)", "Genesis controller (B is high gear, C is low gear, left difficulty switch swaps gear buttons)", "Hack of Pole Position", "", "", "", "", "", "", "", "GENESIS", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "651d2b6743a3a18b426bce2c881af212", "CCE", "C-812", "Pac Man (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6522717cfd75d1dba252cbde76992090", "Home Vision - Gem International Corp. - VDI", "VCS83102", "War 2000 (1983) (Home Vision) (PAL)", "AKA Astrowar", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6538e454b0498ad2befe1ef0f87815c0", "Joe Grand", "", "SCSIcide (v1.2) (2001) (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "", "" },
+  { "65490d61922f3e3883ee1d583ce10855", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692, CX2692P", "Moon Patrol (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "65562f686b267b21b81c4dddc129d724", "", "", "Euchre (28-07-2001) (Eric Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "655c84e5b951258c9d20f0bf2b9d496d", "", "", "2600_2003 Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "656dc247db2871766dffd978c71da80c", "Sears Tele-Games, Jim Huether", "CX2614 - 49-75126", "Steeplechase (1981) (Sears)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "AUTO 60", "", "", "", "" },
+  { "6588d192d9a8afce27b44271a2072325", "Bit Corporation", "R320", "Basketball (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "65917ae29a8c9785bb1f2acb0d6aafd0", "", "", "Junkosoft One Year Demo (1999) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6596b3737ae4b976e4aadb68d836c5c7", "Digivision", "", "Defender (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "659a20019de4a23c748ec2292ea5f221", "Retroactive", "", "Qb (V2.05) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "65a6f1255fe22468a8bf84ff28a4d289", "Akor", "", "Super TV Boy (1995) (Akor)", "Includes 127 games", "", "", "", "", "", "", "", "", "JOYSTICK", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "" },
+  { "65b106eba3e45f3dab72ea907f39f8b4", "Christian Software Development - HomeComputer Software, Dan Schafer, Glenn Stohel, Jon Tedesco - Sparrow", "GCG 1001T", "Music Machine, The (1983) (Sparrow)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" },
+  { "65ba1a4c643d1ab44481bdddeb403827", "Quelle", "876.013 4", "Katastrophen-Einsatz (1983) (Quelle) (PAL)", "AKA M.A.S.H.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "65bd29e8ab1b847309775b0de6b2e4fe", "Coleco, Ed English", "2667", "Roc 'n Rope (1984) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "65c6406f5af934590097c8c032ebb482", "", "", "Three Hugger (Pave Demo) (20-12-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6604f72a966ca6b2df6a94ee4a68eb82", "", "", "MegaMania (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "662eca7e3d89175ba0802e8e3425dedb", "", "", "Hangman Pac-Man Biglist3 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "66362890eb78d6ea65301592cce65f5b", "", "", "Euchre (13-07-2001) (Eric Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "663ef22eb399504d5204c543b8a86bcd", "CBS Electronics - Roklan, Joe Hellesen, Joe Wagner", "4L1720, 4L1721, 4L1722, 4L2276", "Wizard of Wor (1982) (CBS Electronics) (PAL)", "Uses the Joystick Controllers (swapped)", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "664d9bfda6f32511f6b4aa0159fd87f5", "Atari - Roklan, Joe Gaucher", "", "Racer (1982) (Atari) (Prototype) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6651e2791d38edc02c5a5fd7b47a1627", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (04-05-1984) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "665b8f8ead0eef220ed53886fbd61ec9", "Telesys, Don Ruffcorn, Jack Woodman", "1003", "Fast Food (1982) (Telesys)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "66706459e62514d0c39c3797cbf73ff1", "Video Gems", "VG-05", "Treasure Below (1983) (Video Gems) (PAL)", "", "", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6672de8f82c4f7b8f7f1ef8b6b4f614d", "Videospielkassette - Ariola", "PGP237", "Angeln I (Ariola) (PAL)", "AKA Fishing Derby", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "667a70b028f581d87648693b873bc962", "Parker Brothers - Roklan, Joe Gaucher", "PB5370", "Popeye (1983) (Parker Bros) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "668dc528b7ea9345140f4fcfbecf7066", "Gakken", "001", "Pooyan (1983) (Gakken) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6697f177847c70505824422e76aad586", "", "", "Tennis (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "669840b0411bfbab5c05b786947d55d4", "Atari, Andrew Fuchs, Jeffrey Gusman, Dave Jolly, Suki Lee", "CX26117", "Obelix (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "66b89ba44e7ae0b51f9ef000ebba1eb7", "Atari - CCW, Stephan R. Keith, Laura Scholl, Preston Stuart", "CX26106", "Grover's Music Maker (01-18-1983) (Atari) (Prototype)", "Uses Keypad Controller", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "66b92ede655b73b402ecd1f4d8cd9c50", "Activision, John Van Ryzin - Ariola", "EAZ-036-04, EAZ-036-04B, EAZ-036-04I - 711 036-720", "H.E.R.O. (1984) (Activision) (PAL) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "66bc1bef269ea59033928bac2d1d81e6", "Arcadia Corporation, Scott Nelson", "AR-4300", "Fireball (Preview) (1982) (Arcadia)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" },
+  { "66c2380c71709efa7b166621e5bb4558", "Parker Brothers, Dave Engman, Dawn Stockbridge", "931509", "Tutankham (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "66c4e0298d4120df333bc2f3e163657e", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (2 of 3) (1982) (Starpath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "66f49b3248791b9803fa3e2f4165d072", "Bit Corporation", "R320", "Football (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "66fcf7643d554f5e15d4d06bab59fe70", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (09-13-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6706a00f9635508cfeda20639156e66e", "Atari, Jerome Domurat, Michael Sierchio", "CX2667", "RealSports Soccer (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "672012d40336b403edea4a98ce70c76d", "", "", "Spider Kong (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "675ae9c23fa1aae376cea86cad96f9a5", "", "", "Poker Squares (V0.25) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "67631ea5cfe44066a1e76ddcb6bcb512", "", "", "Termool (Unknown) (PAL)", "AKA Turmoil", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "67684a1d18c85ffa5d82dab48fd1cb51", "Tigervision, Warren Schwader - Teldec", "7-003", "Threshold (1982) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "678c1d71a1616d9d022f03d8545b64bb", "", "", "Demo Image Series #11 - Donald And Mario (28-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "67931b0d37dc99af250dd06f1c095e8d", "CommaVid, Irwin Gaines", "CM-004", "Room of Doom (1982) (CommaVid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "679d30c7886b283cbe1db4e7dbe5f2a6", "Colin Hughes", "", "Puzzle (Colin Hughes) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "679e910b27406c6a2072f9569ae35fc8", "Data Age", "DA1002", "Warplock (1982) (Data Age)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 40", "", "", "YES", "" },
+  { "67bd3d4dc5ac6a42a99950b4245bdc81", "Retroactive", "", "Qb (2.11) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "67c05ae94bf8b83a666c3ae2c4bc14de", "Atari", "CX26163P", "NFL Football (32 in 1) (1988) (Atari) (PAL) (4K)", "AKA Football", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "67cdde4176e0447fc45a71e0a1cdd288", "Telegames - VSS, Ed Salvo", "5665 A016", "Glacier Patrol (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "67ce6cdf788d324935fd317d064ed842", "Retroactive", "", "Qb (V2.09) (Stella) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "67cf913d1df0bf2d7ae668060d0b6694", "", "", "Hangman Monkey 4letter (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "67f90d74fd0b72fdc6d9b92436780ea9", "Omegamatrix", "", "SpaceMaster X-7 (Atari Trak-Ball) (PAL60) (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6803fa7c2c094b428b859a58dc1dd06a", "Retroactive", "", "Qb (0.11) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "6805734a0b7bcc8925d9305b071bf147", "Bit Corporation", "PGP229", "Kung Fu (4 Game in One Dark Green) (1983) (BitCorp) (PAL)", "AKA Karate", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "681206a6bde73e71c19743607e96c4bb", "", "", "Casino (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6833c26f385e866f3a0fa0dff311216e", "Thomas Jentzsch", "", "Centipede - Atari Mouse Hack v1.4 (PAL60) (Full-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "683bb0d0f0c5df58557fba9dffc32c40", "Arcadia Corporation, Scott Nelson", "AR-4300", "Fireball (1982) (Arcadia) [a]", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" },
+  { "683dc64ef7316c13ba04ee4398e2b93a", "Ed Federmeyer", "", "Edtris (1995) (Ed Federmeyer)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "68449e4aaba677abcd7cde4264e02168", "", "", "Horizonal Color Bars Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6847ce70819b74febcfd03e99610243b", "", "", "Ruby Runner 4A50", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "68489e60268a5e6e052bad9c62681635", "Bit Corporation", "PG201", "Sea Monster (1982) (BitCorp) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "68597264c8e57ada93be3a5be4565096", "Data Age", "DA1005", "Bugs (1982) (Data Age)", "Uses the Paddle Controllers", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 50", "", "", "", "" },
+  { "685e9668dc270b6deeb9cfbfd4d633c3", "CommaVid, Irwin Gaines - Ariola", "CM-004 - 712 004-720", "Room of Doom (1982) (CommaVid) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "68760b82fc5dcf3fedf84376a4944bf9", "CCE", "C-860", "Laser Gate (1983) (CCE)", "AKA Innerspace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "687c23224e26f81c56e431c24faea36d", "", "", "Qb (Simple Background Animation) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "68878250e106eb6c7754bc2519d780a0", "CCE", "C-809", "Squirrel (1983) (CCE)", "AKA Snail Against Squirrel", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "68ac69b8e1ba83af8792f693f5ae7783", "Digivision", "", "Fathon (Digivision)", "AKA Fathom", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "68c80e7e1d30df98a0cf67ecbf39cc67", "Hozer Video Games", "", "Gunfight 2600 - One Step Forward & Two Steps Back (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "68c938a2a2b45c37db50509f1037fe6e", "Omegamatrix", "", "Star Wars Arcade (Atari Mouse) v4 (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "68cd2adc6b1fc9a1f263ab4561112f30", "Thomas Jentzsch", "", "Boulderdash Demo (09-12-2002) (TJ)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "68feb6d6ff63e80df1302d8547979aec", "", "", "Starfield Demo 2 (20-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "690a6049db78b9400c13521646708e9c", "King Tripod Enterprise Co.", "SS - 007", "Space Raid (King Tripod) (PAL)", "AKA Challenge of.... Nexar, The", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6913c90002636c1487538d4004f7cac2", "Atari - CCW", "CX26131", "Monster Cise (1984) (Atari) (Prototype)", "Uses the Keypad Controllers (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "691d67910b08b63de8631901d1887c1f", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (1983) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "692202772d8b38ccf85a90c8003a1324", "", "", "Zi - The Flie Buster (2002) (Fernando Mora) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "693137592a7f5ccc9baae2d1041b7a85", "", "", "Qb (V2.02) (Stella) (2001) (Retroactive) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "6936aa6763835f62ac13d1aaa79b9f91", "Thomas Jentzsch", "", "Centipede - Atari Trak-Ball Hack v1.4 (NTSC) (Half-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6979f30204149be3e227558cffe21c1d", "Atari", "CX26163P", "Miniaturer Golf (32 in 1) (1988) (Atari) (PAL) (4K)", "AKA Miniature Golf", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6982854657a2cc87d712f718e402bf85", "Zellers", "", "Earth Attack (Zellers)", "AKA Defender", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "69877da5caded48315e3e45882a303d5", "Atari - Roklan, Joe Gaucher, Alex Leavens", "CX2683", "Crazy Climber (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "698f569eab5a9906eec3bc7c6b3e0980", "SpkLeader", "", "Demons! (2003) (SpkLeader) (Hack)", "Hack of Phoenix", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "69974dd5d6420b90898cde50aec5ef39", "Activision, David Crane", "AG-009, AG-009-04", "Freeway (1981) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "69df0411d4d176e558017f961f5c5849", "CCE", "C-831", "Cosmic Ark (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "69e79b1352b9ee1754bbe63b4a7062c3", "Barry Laws Jr.", "", "Pink Floyd - The Wall (2003) (Barry Laws Jr.) (Hack)", "Hack of Berzerk", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "69ebf910ab9b63e5b8345f016095003b", "", "", "Maze Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "69edfb4e1810a523311b3e250fc1e275", "Thomas Jentzsch", "", "Missile Command Atari Trak-Ball Hack v1.3 (PAL) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "69fac82cd2312dd9ce5d90e22e2f070a", "Spectravision - Spectravideo - Quelle", "SA-202 - 412.851 8", "Planet Patrol (1982) (Spectravision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6a03c28d505bab710bf20b954e14d521", "", "", "Pressure Gauge 2 Beta (Hozer Video Games)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6a07836c382195dd5305ce61d992aaa6", "Apollo, Larry Martin", "AP-2008", "Guardian (1982) (Apollo) (Prototype)", "Uses the Paddle Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" },
+  { "6a091b8ffeacd0939850da2094b51564", "", "", "Vertically Scrolling Playfield (02-02-2003) (Aaron Bergstrom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6a222c26bcece3a510ddda21398f72c6", "Bit Corporation", "PG203", "Phantom Tank (1982) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6a2c68f7a77736ba02c0f21a6ba0985b", "Atari, Larry Wagner, Bob Whitehead", "", "Computer Chess (07-07-1978) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6a3b0c33cf74b1e213a629e3c142b73c", "Cody Pittman", "", "Cory The Interviewer (Cody Pittman) (Hack)", "Hack of Ghostbusters", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6a76d5f0ed721639474aa9bbde69ebf0", "", "", "Play Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "6a82b8ecc663f371b19076d99f46c598", "Activision, Larry Miller - Ariola", "EAX-026, EAX-026-04B, EAX-026-04I - 711 026-725", "Enduro (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6a882fb1413912d2ce5cf5fa62cf3875", "Video Game Cartridge - Ariola", "TP-605", "Dragon Defender (Ariola) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "6a8c6940d3be6fd01274363c4d4b298e", "", "", "Spy Hunter (Genesis)", "Genesis controller (C is oil/smoke)", "Hack of Spy Hunter", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6a9b30ca46b0dba9e719f4cbd340e01c", "", "", "Frostbite (Unknown) (PAL) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6a9e0c72fab92df70084eccd9061fdbd", "CCE", "C-835", "Beany Bopper (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6aa66e9c3eea76a0c40ef05513497c40", "", "", "Hangman Ghost Biglist2 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6ac3fd31a51730358708c7fdc62487f8", "Matthias Jaap", "", "PC Invaders (Matthias Jaap) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6aca52e11b597ab84b33d5252e1cd9d1", "Bit Corporation", "R320", "Tac-Scan (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 60", "", "", "", "" },
+  { "6ae4dc6d7351dacd1012749ca82f9a56", "Atari - GCC, Jaques Hugon, Seth Lipkin", "CX26125, CX26127", "Track and Field (1984) (Atari)", "Uses the Track & Field Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6b01a519b413f8cfa2f399f4d2841b42", "", "", "Aphex Invaders (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6b1fc959e28bd71aed7b89014574bdc2", "Bit Corporation", "PG203", "Phantom Tank (1982) (BitCorp) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6b4eb5b3df80995b8d9117cb7e9aeb3c", "Gameworld, J. Ray Dettling", "133-006", "Journey Escape (1983) (Gameworld) (PAL)", "AKA Rock 'n' Roll Escape", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "6b683be69f92958abe0e2a9945157ad5", "U.S. Games Corporation - Western Technologies, Jeff Corsiglia, Paul Allen Newell, Steven B. Sidley, Tom Sloper", "VC2007", "Entombed (1983) (U.S. Games)", "Released as Name That Game for a contest (winning name was Entombed)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "6b6ca32228ae352b4267e4bd2cddf10c", "", "", "Pac-Man 4 (Pac-Man Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6b71f20c857574b732e7a8e840bd3cb2", "", "", "Frostbite (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6b72b691ea86f61438ed0d84c4d711de", "", "", "Fishing Derby (Unknown) (PAL) (4K) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6b75f8fa4fd011a6698c58315f83d2ac", "Thomas Jentzsch", "", "Sprintmaster DC (TJ)", "Uses the Driving Controllers, Hack of Sprintmaster (Atari)", "New Release (Hack)", "", "", "", "", "", "", "", "DRIVING", "", "", "DRIVING", "", "", "", "", "", "45", "", "", "", "" },
+  { "6b7a56b6ac2ca4bf9254474bf6ed7d80", "", "", "Horizonal Color Bars Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6b7e1c11448c4d3f28160d2de884ebc8", "Zirok", "", "Fast Food (Zirok)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6b8fb021bb2e1f1e9bd7ee57f2a8e709", "Paul Slocum", "", "3-D Corridor (29-03-2003) (Paul Slocum) (PD) [a]", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6bb09bc915a7411fe160d0b2e4d66047", "Atari", "CX26163P", "UFO (32 in 1) (1988) (Atari) (PAL)", "AKA Space Jockey", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6bb22efa892b89b69b9bf5ea547e62b8", "Dynacom", "", "Megamania (1982) (Dynacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6bde3f6ac31aceef447ce57d4d2c2ec0", "Piero Cavina", "", "Mondo Pong V1 (Piero Cavina) (PD)", "Uses the Paddle Controllers", "New Release", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "", "", "", "", "01", "", "", "", "" },
+  { "6c128bc950fcbdbcaf0d99935da70156", "Digitel", "", "Volleyball (1983) (Digitel)", "AKA RealSports Volleyball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6c1553ca90b413bf762dfc65f2b881c7", "Quelle", "343.073 3", "Winterjagd (1983) (Quelle) (PAL)", "AKA Ski Hunt", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6c1f3f2e359dbf55df462ccbcdd2f6bf", "Activision, Garry Kitchen - Ariola", "EAX-025, EAX-025-04I - 711 025-725", "Keystone Kapers (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6c25f58fd184632ca76020f589bb3767", "Dynacom", "", "Beat 'Em & Eat 'Em (1983) (Dynacom)", "Uses the Paddle Controller (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" },
+  { "6c449db9bbbd90972ad1932d6af87330", "", "", "20 Sprites at Once Demo 3 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6c658b52d03e01828b9d2d4718a998ac", "", "", "Hangman Invader Biglist2 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6c76fe09aa8b39ee52035e0da6d0808b", "Atari, Brad Stewart", "CX2622, CX2622P", "Breakout (1978) (Atari) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 60", "", "", "", "" },
+  { "6c85098518d3f94f7622c42fd1d819ac", "Suntek", "SS-028", "Firebug (1983) (Suntek) (PAL)", "AKA Spinning Fireball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6c91ac51421cb9fc72c9833c4f440d65", "ITT Family Games", "554-33 375", "Cosmic Town (1983) (ITT Family Games) (PAL)", "AKA Base Attack (Perry Rhodan-Serie)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6c9a32ad83bcfde3774536e52be1cce7", "", "", "Space Treat (NTSC) (13-08-2002) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6cab04277e7cd552a3e40b3c0e6e1e3d", "Telegames - VSS", "7062 A305", "Universal Chaos (1988) (Telegames) (Prototype)", "AKA Targ", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6cbe945e16d9f827d0d295546ac11b22", "", "", "Gunfight 2600 - AI (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6ccd8ca17a0e4429b446cdcb66327bf1", "", "", "RPG Engine (12-05-2003) (Paul Slocum) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "6cd1dc960e3e8d5c5e0fbe67ab49087a", "", "", "Vertical Playfield Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6cd506509e8fd5627f55603780e862a8", "Greg Troutman", "", "Dark Mage (SuperCharger) (Greg Troutman) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "6ce2110ac5dd89ab398d9452891752ab", "Funvision - Fund. International Co.", "", "Persian Gulf War (Funvision)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6cea35ded079863a846159c3a1101cc7", "", "", "Atlantis (208 in 1) (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6ceb7d6a54e9a5e62d26874d1cc88dbc", "Video Soft", "", "Atom Smasher (1984) (Video Soft) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6cf054cd23a02e09298d2c6f787eb21d", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (1984) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "6d218dafbf5a691045cdc1f67ceb6a8f", "Robin Harbron", "", "6 Digit Score Display (1998) (Robin Harbron) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6d475019ea30d0b29f695e9dcfd8f730", "Eric Mooney", "", "Invaders by Erik Mooney (Alpha 2) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6d74ebaba914a5cfc868de9dd1a5c434", "", "", "Fortress (Smooth Version) (20-04-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6d842c96d5a01967be9680080dd5be54", "Activision, Steve Cartwright, David Crane", "AB-035-04", "Pitfall II (1984) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6d8a04ee15951480cb7c466e5951eee0", "Zirok", "", "Kanguru (1983) (Zirok)", "AKA Kangaroo", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6d9afd70e9369c2a6bff96c4964413b7", "", "", "Time Warp (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6dda84fb8e442ecf34241ac0d1d91d69", "Atari - GCC, Douglas B. Macrae", "CX2677", "Dig Dug (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6de924c2297c8733524952448d54a33c", "CCE", "C-1006", "Moon Patrol (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6dfad2dd2c7c16ac0fa257b6ce0be2f0", "Parker Brothers, Larry Gelberg", "PB5065", "Star Wars - Ewok Adventure (1983) (Parker Bros) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6e179eee3d4631a7434d40cf7aeea6e8", "Wizard Video Games - MicroGraphic Image, Robert Barber, Tim Martin", "007", "Halloween (1983) (Wizard Video Games) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6e19428387686a77d8c8d2f731cb09e0", "", "", "Purple Cross Demo (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6e372f076fb9586aff416144f5cfe1cb", "Atari, Tod Frye - Sears", "CX2646 - 49-75185", "Pac-Man (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6e59dd52f88c00d5060eac56c1a0b0d3", "Atari, Bob Smith", "CX2648", "Video Pinball (1981) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6e5d5ba193d2540aec2e847aafb2a5fb", "Retroactive", "", "Qb (2.14) (Retroactive) (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "6e7ed74082f39ad4166c823765a59909", "", "", "Poker Squares (V0.14) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6e7efb0ed13ec28a00d19572de9c9f03", "Apollo - Games by Apollo", "AP-2006", "Infiltrate (1982) (Apollo) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6eb10fd23c7161751d18b9e8484c0004", "Coleco - JWDA, Todd Marshall, Robin McDaniel, Henry Will IV", "2465", "Smurf - Rescue in Gargamel's Castle (1983) (Coleco) (Prototype)", "AKA Smurf, Smurf Action", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6ed5012793f5ddf4353a48c11ea9b8d3", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix - Down on the Line (3 of 3) (1983) (Arcadia)", "Uses Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "01 70", "", "", "", "" },
+  { "6ed6bda5c42b2eb7a21c54e5b3ace3e3", "Canal 3 - Intellivision", "", "Ice Hockey (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6efe876168e2d45d4719b6a61355e5fe", "Bit Corporation", "PG207", "Mission 3,000 A.D. (1983) (BitCorp) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "6f084daf265599f65422ef4173b69bc7", "", "", "Music Kit (V2.0) - Song Player (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "6f2aaffaaf53d23a28bf6677b86ac0e3", "U.S. Games Corporation - Vidtec - JWDA, Garry Kitchen", "VC1001", "Space Jockey (1982) (U.S. Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6f3e3306da2aa6e74a5e046ff43bf028", "", "", "Defender Arcade (Genesis)", "Genesis controller (C is smartbomb)", "Hack of Defender 2", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6f744f14aac04f7e1ea0d3f4bafcb3e4", "Atari - Roklan, Joe Gaucher, Alex Leavens", "CX2683", "Crazy Climber (1983) (Atari) (Prototype) [a3]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6f74ed915ffe73b524ef0f63819e2a1d", "Eckhard Stolberg", "", "An Exercise In Minimalism (V2) (1999) (Eckhard Stolberg)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6fa0ac6943e33637d8e77df14962fbfc", "Imagic, Rob Fulop", "", "Cubicolor (1982) (Imagic) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6fac680fc9a72e0e54255567c72afe34", "", "", "Superman (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6fbd05b0ad65b2a261fa154b34328a7f", "", "", "Boardgame Demo (20-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6fc0176ccf53d7bce249aeb56d59d414", "Rainbow Vision - Suntek", "SS-004", "Pyramid War (1983) (Rainbow Vision) (PAL)", "AKA Chopper Command", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6fc27a9233fc69d28d3f190b4ff80f03", "", "", "UFO #6 (Charles Morgan) (Hack)", "Hack of Pepsi Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6fc394dbf21cf541a60e3b3631b817f1", "Imagic, Bob Smith", "720020-2A, IA3611P", "Dragonfire (1982) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "6fd7c7057eeab273b29c7aafc7429a96", "Activision, David Crane", "AX-018, AX-018-04", "Pitfall! (1982) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6fe67f525c39200a798985e419431805", "Atari - GCC, Kevin Osborn", "CX2689, CX2689P", "Kangaroo (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "6ff4156d10b357f61f09820d03c0f852", "Atari, Larry Kaplan - Sears", "CX2612 - 99804, 49-75103", "Street Racer (1977) (Atari) (4K)", "Uses the Paddle Controllers (swapped)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 60", "", "", "", "" },
+  { "6ffc95108e5add6f9b8abcaf330be835", "Charles Morgan", "", "TP Bug (Charles Morgan) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "700a786471c8a91ec09e2f8e47f14a04", "Activision", "", "Hard-Head (1983) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "703d32062436e4c20c48313dff30e257", "", "", "Moving Maze Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "703f0f7af350b0fa29dfe5fbf45d0d75", "Bit Corporation", "P460", "4 Game in One Dark Green (1983) (BitCorp) (PAL)", "Rodeo Champ, Bobby is Going Home, Open Sesame, Festival", "", "", "", "4IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "705fe719179e65b0af328644f3a04900", "Atari, David Crane - Sears", "CX2653 - 6-99823, 49-75111", "Slot Machine (1979) (Atari) (4K) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "706e3cc4931f984447213b92d1417aff", "", "", "Joustpong (06-07-2002) (Kirk Israel) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "707ecd80030e85751ef311ced66220bc", "", "", "Double-Height 6-Digit Score Display (Background Color Change) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7096a198531d3f16a99d518ac0d7519a", "Telesys, Jim Rupp", "1004", "Ram It (1983) (Telesys)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "709910c2e83361bc4bf8cd0c20c34fbf", "Rainbow Vision - Suntek", "SS-006", "Netmaker (1983) (Rainbow Vision) (PAL)", "AKA Amidar", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "70a43fbdb1c039283ee5048d99842469", "Thomas Jentzsch", "", "Reactor - Atari Mouse Hack v1.3 (PAL) (Half-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "70a8480cfaf08776e5420365732159d2", "Rob Kudla", "", "Horizontally Scrolling Playfield Thing (Rob Kudla) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "70ce036e59be92821c4c7fd735ec6f68", "Activision, Steve Cartwright - Ariola", "EAX-031, EAX-031-04B - 711 031-717", "Frostbite (1983) (Activision) (PAL) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "70d14c66c319683b4c19abbe0e3db57c", "", "", "Oystron (V2.82) (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "710497df2caab69cdcc45e919c69e13f", "Arcadia Corporation, Dennis Caswell", "5 AR-4200", "Labyrinth (Escape from the Mindmaster Beta) (1982) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "713fde2af865b6ec464dfd72e2ebb83e", "", "", "Challenge (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "71464c54da46adae9447926fdbfc1abe", "M Network - INTV - APh Technological Consulting, Bruce Pedersen", "MT5663", "Lock 'n' Chase (1982) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "714e13c08508ee9a7785ceac908ae831", "Home Vision - Gem International Corp. - VDI", "VCS83123", "Parachute (1983) (Home Vision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "715dbf2e39ba8a52c5fe5cdd927b37e0", "Amiga - Video Soft", "3135", "S.A.C. Alert (1983) (Amiga) (Prototype)", "Uses Joyboard", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "715dd9e0240638d441a3add49316c018", "Atari", "", "128-in-1 Junior Console (Chip 2 of 4) (1991) (Atari) (PAL)", "Actually contains only 16 games, not 32", "", "", "", "16IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7187118674ff3c0bb932e049d9dbb379", "Zirok", "", "Keystone Keypers (1983) (Zirok)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "718ae62c70af4e5fd8e932fee216948a", "Data Age, J. Ray Dettling", "112-006", "Journey Escape (1983) (Data Age)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "718ee85ea7ec27d5bea60d11f6d40030", "Thomas Jentzsch", "", "Ghostbusters II (1992) (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "7197b6cbde6ecd10376155e6b848e80d", "Piero Cavina", "", "Multi-Sprite Game V2.1 (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "71b193f46c88fb234329855452dfac5b", "Digitel", "", "Atlantis (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "71d005b60cf6e608d04efb99a37362c3", "Atari, Larry Kaplan", "CX2643", "Codebreaker (1978) (Atari) (PAL) (4K) [a]", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "71f09f128e76eb14e244be8f44848759", "Funvision - Fund. International Co.", "", "Time Race (Funvision) (PAL)", "AKA Time Warp", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "71f8bacfbdca019113f3f0801849057e", "Atari, Dan Hitchens", "CX26126", "Elevator Action (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "72097e9dc366900ba2da73a47e3e80f5", "", "", "Euchre (15-06-2001) (Eric Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "721a5567f76856f6b50a6707aa8f8316", "Activision, David Crane, Dan Kitchen", "EAG-108-04, EAZ-108-04B", "Ghostbusters (1985) (Activision) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "72305c997f2cec414fe6f8c946172f83", "Arcadia Corporation, Dennis Caswell", "AR-4000, AR-4100", "Phaser Patrol (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "724613effaf7743cbcd695fab469c2a8", "", "", "Super-Ferrari (Unknown)", "AKA Enduro", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "728152f5ae6fdd0d3a9b88709bee6c7a", "Spectravideo, Mark Turmell", "SA-217", "Gas Hog (1983) (Spectravideo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "72876fd7c7435f41d571f1101fc456ea", "Quelle", "688.383 9", "Die Ente und der Wolf (1983) (Quelle) (PAL)", "AKA Pooyan", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "72a46e0c21f825518b7261c267ab886e", "Xonox - K-Tel Software - Computer Magic", "99005, 6220, 6250", "Robin Hood (1983) (Xonox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "72a5b5052272ac785fa076709d16cef4", "", "", "KC Munckin (29-01-2003) (J. Parlee)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "72a63bcb5eb31bd0fd5e98ed05125ec1", "Thomas Jentzsch", "", "Missile Control - Atari Trak-Ball Hack v1.15 (PAL60) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "72bda70c75dfa2365b3f8894bace9e6a", "Thomas Jentzsch", "", "Atlantis (TJ) (Hack)", "Hack of Atlantis", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "72d0acb5de0db662de0360a6fc59334d", "", "", "Cosmic Ark (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "72db1194b1cc7d45b242f25eb1c148d3", "", "", "Pac-Man (1981) (Atari) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "72fd08deed1d6195942e0c6f392e9848", "HES", "0701-406", "2 Pak Special - Wall Defender, Planet Patrol (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "72ffbef6504b75e69ee1045af9075f66", "Atari, Richard Maurer - Sears", "CX2632 - 49-75153", "Space Invaders (1980) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "73158ea51d77bf521e1369311d26c27b", "Zellers", "", "Challenge (Zellers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "73521c6b9fed6a243d9b7b161a0fb793", "Atari, Tom Reuterdahl", "CX26163P", "Miniaturer Golf (32 in 1) (1988) (Atari) (PAL)", "AKA Miniature Golf", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "736388d73198552d77d423962000006f", "Dactari", "", "Tennis (Dactari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "73a710e621d44e97039d640071908aef", "", "", "Barber Pole Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "73aa02458b413091ac940c0489301710", "Rainbow Vision - Suntek", "SS-016", "Boom Bang (1983) (Rainbow Vision) (PAL)", "AKA Crackpots", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "73b4e8f8b04515d91937510e680214bc", "", "", "Rubik's Cube Demo 3 (24-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "73c545db2afd5783d37c46004e4024c2", "CBS Electronics - JWDA, Todd Marshall, Robin McDaniel, Henry Will IV", "4L1767, 4L1768, 4L1769, 4L1770", "Smurf - Schtroumpfs (1983) (CBS Electronics) (PAL)", "Pitufo", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "73c839aff6a055643044d2ce16b3aaf7", "Activision, Alan Miller - Ariola", "EAX-016, PAX-016 - 711 016-725", "StarMaster (1982) (Activision) (PAL)", "Use Color/BW switch to change between galactic chart and front views", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "73cb1f1666f3fd30b52b4f3d760c928f", "", "", "Mines of Minos (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "73e66e82ac22b305eb4d9578e866236e", "Jone Yuan Telephonic Enterprise Co", "", "Unknown Datatech Game (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "73efa9f3cbe197f26e0fb87132829232", "CCE", "C-858", "Tennis (1983) (CCE) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "74023e0f2e739fc5a9ba7caaeeee8b6b", "Jone Yuan Telephonic Enterprise Co", "", "Fishing Derby (Jone Yuan) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "740a7fa80f52cc7287ba37677afb6b21", "", "", "Double Dragon (PAL) (Genesis)", "Genesis controller (C is jumpkick)", "Hack of Double Dragon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "740b47df422372fbef700b42cea4e0bf", "", "", "Dizzy Wiz (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "740f39e71104e90416c29a73560b9c6b", "Atari", "TE016643", "Diagnostic Test Cartridge 2.6P (1982) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7412f6788087d7e912c33ba03b36dd1b", "AtariAge, Omegamatrix", "", "Venture Reloaded (2019) (AtariAge) (Hack)", "Transformative hack of Venture", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "742de93b8d849220f266b627fbabba82", "", "", "SCSIcide (25-02-2001) (Chris Wilkson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7450ae4e10ba8380c55b259d7c2b13e8", "", "", "Register Twiddler Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7454786af7126ccc7a0c31fcf5af40f1", "", "", "Phantom Tank (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7465b06b6e25a4a6c6d77d02242af6d6", "Atari", "CX26193", "8 in 1 (01-16-92) (Atari) (Prototype)", "Game 2 is Centipede, but doesn't work", "Prototype", "", "", "8IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7481f0771bff13885b2ff2570cf90d7b", "Arcadia Corporation, Brian McGhie", "AR-4104", "Rabbit Transit (1983) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "749fec9918160921576f850b2375b516", "Spectravision - Spectravideo", "SA-205", "China Syndrome (1982) (Spectravision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "74d072e8a34560c36cacbc57b2462360", "Sancho - Tang's Electronic Co.", "TEC002", "Seahawk (1982) (Sancho) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "74ebaca101cc428cf219f15dda84b6f8", "Activision, Alan Miller", "AG-007, CAG-007", "Tennis (1981) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "74f623833429d35341b7a84bc09793c0", "Zellers", "", "Radar (Zellers)", "AKA Exocet", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "75028162bfc4cc8e74b04e320f9e6a3f", "Atari, Greg Easter, Mimi Nyden", "CX26107", "Snow White (02-09-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7511c34518a9a124ea773f5b0b5c9a48", "", "", "Donkey Kong (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "75169c08b56e4e6c36681e599c4d8cc5", "M Network - INTV - APh Technological Consulting, Hal Finney", "MT5666", "Astroblast (1982) (M Network)", "Can also use left joystick", "Uncommon", "", "", "", "", "", "", "", "PADDLES", "", "", "", "", "", "YES", "", "", "AUTO 55", "", "", "", "" },
+  { "752da1c0acd7d132ccfb0b1067f53cf6", "Thomas Jentzsch", "", "Reactor - Atari Mouse Hack v1.3 (PAL) (Full-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "753375d183c713cfa0aa7298d1f3067b", "Arcadia Corporation, Steve Hales, Stephen Harland Landrum", "AR-4102", "Suicide Mission (1982) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "7550b821ee56fb5833dca2be88622d5a", "", "", "Multiple Moving Objects Demo (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "75511bb694662301c9e71df645f4b5a7", "Activision, Bob Whitehead - Ariola", "EAG-011, PAG-011 - 711 011-715", "Stampede (1981) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "755fed16b48e81de05130708a905d00d", "SnailSoft", "", "Comitoid beta 3 (SnailSoft)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "756ca07a65a4fbbedeb5f0ddfc04d0be", "Atari, Jim Huether", "CX2629, CX2629P", "Sky Diver (1979) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7574480ae2ab0d282c887e9015fdb54c", "Atari, Jerome Domurat, Steve Woita", "CX2699", "Taz (1984) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7576dd46c2f8d8ab159d97e3a3f2052f", "Goliath - Hot Shot", "83-112", "Time Machine (1983) (Goliath) (PAL)", "AKA Asteroid Fire", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "757f529026696e13838364dea382a4ed", "Activision, David Crane - Ariola", "EAX-014, PAX-014, EAX-014-04B, EAX-014-04I - 711 014-720", "Grand Prix (1982) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "75893a9dc5de4b91cc426959b82a1da0", "Champ Games", "CG-02-P", "Conquest Of Mars (2010) (PAL60)", "Rev 2 release", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "75a303fd46ad12457ed8e853016815a0", "ZiMAG - Emag - Vidco", "715-111 - GN-060", "Immies & Aggies (1983) (ZiMAG) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "75b22fdf632d76e246433db1ebccd3c4", "", "", "Skeleton+ (05-05-2003) (Eric Ball) (PAL)", "", "", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "75b557be7f08db84ec5b242207b9f241", "", "", "Space Treat (30-12-2002) (Fabrizio Zavagli) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "75e276ba12dc4504659481c31345703a", "Arcadia Corporation, Kevin Norman", "AR-4103", "Killer Satellites (1983) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "75e8d8b9e9c5c67c2226dbfd77dcfa7d", "", "", "2600 Digital Clock (V b1) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "75ea128ba96ac6db8edf54b071027c4e", "Atari, David Crane", "CX26163P", "Slot Machine (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "75ea60884c05ba496473c23a58edf12f", "Atari, Howard Scott Warshaw - Sears", "CX2655 - 49-75167", "Yars' Revenge (1982) (Atari) (PAL) [a]", "ROM must be started in bank 0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "75ee371ccfc4f43e7d9b8f24e1266b55", "Atari, Greg Easter, Mimi Nyden", "CX26107", "Snow White (11-09-1982) (Atari) (Prototype)", "ROM must be started in bank 0", "Prototype", "", "0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7608abdfd9b26f4a0ecec18b232bea54", "Atari, Bob Whitehead", "CX26163P", "NFL Football (32 in 1) (1988) (Atari) (PAL)", "AKA Football", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7623a639a6fffdb246775fe2eabc8d01", "Activision, Bob Whitehead", "AG-005, CAG-005, AG-005-04", "Skiing (1980) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7628d3cadeee0fd2e41e68b3b8fbe229", "Atari", "CX26163P", "Fishing Derby (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7648e72a5b5899076688df18a1ddcf72", "CBS Electronics, Richard K. Balaska Jr., Andy Frank, Stuart Ross", "4L 2520 5000", "Tunnel Runner (1983) (CBS Electronics) (Prototype)", "Black Box", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "764ce6801f28a9ad36f11de3e57c053b", "Atari, Jim Huether, Alan J. Murphy, Robert C. Polaro", "CX2666", "RealSports Volleyball (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "76809eb1ee0db8a318308a5cdda0f4e2", "Atari, Jerome Domurat, Steve Woita", "CX2699", "Taz (1983) (Atari) (Prototype) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "769ddc995dbb9edb8167efcea9f34a7c", "", "", "H.E.R.O. (Genesis)", "Genesis controller (B is laser, C is dynamite)", "Hack of H.E.R.0.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "76a9bf05a6de8418a3ebc7fc254b71b4", "VideoSoft, Jerry Lawson, Dan McElroy", "VS1008", "Color Bar Generator (1984) (VideoSoft)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "76c685d1a60c0107aa54a772113a2972", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (3 of 3) (1983) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "76c88341017eae660efc6e49c4b6ab40", "", "", "Indiana Pitfall (Hack)", "Hack of Pitfall!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "76ee917d817ef9a654bc4783e0273ac4", "Otto Versand", "311377", "Fox & Goat (Double-Game Package) (1983) (Otto Versand) (PAL)", "AKA Nuts", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "76f53abbbf39a0063f24036d6ee0968a", "M Network, David Akers, Joe 'Ferreira' King, Patricia Lewis Du Long, Jeff Ratcliff - INTV", "MT7045", "Bump 'n' Jump (1983) (M Network)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "76f66ce3b83d7a104a899b4b3354a2f2", "UA Limited", "", "Cat Trax (1983) (UA Limited) (1)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "77057d9d14b99e465ea9e29783af0ae3", "Activision, David Crane", "AG-001", "Dragster (1980) (Activision)", "AKA Drag Strip", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7732e4e4cc2644f163d6650ddcc9d9df", "HES", "771-333", "2 Pak Special - Challenge, Surfing (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7761418d46af069b8cd80c29fe6cd814", "Dion Olsthoorn", "RetroN 77 edition", "Amoeba Jump (R77) (DionoiD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7778ac65d775a079f537e97cbdad541c", "", "", "Spider Fighter (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "777aece98d7373998ffb8bc0b5eff1a2", "", "", "2600 Collison Demo 2 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "77887e4192a6b0a781530e6cf9be7199", "Atari", "CX2604", "Space War (1978) (Atari) [b1]", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "77be57d872e3f5b7ecf8d19d97f73281", "", "", "Basketball (208 in 1) (Unknown) (PAL)", "Console ports are swapped", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "77cd9a9dd810ce8042bdb9d40e256dfe", "Kyle Pittman", "", "Evil Dead (2003) (Kyle Pittman) (Hack)", "Hack of Haunted House", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "77d0a577636e1c9212aeccde9d0baa4b", "Atari, Joe Decuir", "CX2621, CX2621P", "Video Olympics (1977) (Atari) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "PADDLES_IAXDR", "", "", "YES", "", "", "AUTO 60", "", "", "", "" },
+  { "78297db7f416af3052dd793b53ff014e", "", "", "Poker Squares (V0.17) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7836794b79e8060c2b8326a2db74eef0", "", "", "RIOT RAM Test (26-11-2002) (Dennis Debro)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "784176346e9422733d55c427230e5bad", "Activision, Alex DeMeo", "", "Title Match Pro Wrestling (1989) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "784abfdb31d5341e5bd404d8d2a71c3b", "Alessandro Ciceri", "", "MagiCard (TV format conversion) (alex_79) (PAL)", "MagiCard PAL conversion hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7860716fa5dbc0fffab93fb9a4cb4132", "", "", "Hangman Monkey Wordlist (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7867ee819b53d69cfcfe740f7ddca574", "Arcadia Corporation, Dennis Caswell", "1 AR-4000, AR-4100", "Phaser Patrol (1982) (Arcadia) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "787ebc2609a31eb5c57c4a18837d1aee", "Prescott", "", "Vault Assault (19xx) (Prescott)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "78821ef76ebc3934850d1bc1b9e4f4b0", "HES - Activision", "542", "Hot Action Pak - Ghostbusters, Tennis, Plaque Attack (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "78963290052fd17c6c7998305ab3a6a0", "", "", "Push (V0.08) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "78b84cfb1c57b0488d674d2374e656e6", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (1 of 3) (1982) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "78c2de58e42cd1faac2ea7df783eaeb3", "", "", "Fu Kung! (V0.07) (25-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "79004f84bdeee78d142e445057883169", "CCE", "C-830", "Planet Patrol (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "791bc8aceb6b0f4d9990d6062b30adfa", "Activision, David Crane - Ariola", "EAX-018, EAX-018-04B, EAX-018-04I - 711 018-725", "Pitfall! (1982) (Activision) (PAL)", "Abenteuer im Urwald (Jungle Runner)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "791c88eca9836af8c34bf32b07cb58a7", "SpiceWare - Darrell Spice Jr.", "SW-05", "Stay Frosty 2 (PAL60)", "AtariAge Holiday Greetings 2014", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "7926083ad423ed685de3b3a04a914315", "Barry Laws Jr.", "", "Face Invaders 2 (Barry Laws Jr.) (Hack)", "Hack of Astroblast", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "792b1d93eb1d8045260c840b0688ec8f", "Kroko", "", "3E Bankswitch Test (TIA @ $00)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7972e5101fa548b952d852db24ad6060", "Atari - Sears", "CX2627 - 6-99841", "Human Cannonball (1979) (Atari)", "AKA Cannon Man", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "798b8921276eec9e332dfcb47a2dbb17", "Atari - CCW, Gary Stark", "CX26102", "Cookie Monster Munch (1983) (Atari) (PAL) [a]", "Uses Kids/Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" },
+  { "798cc114f1623c14085868cd3494fe8e", "", "", "Pins Revenge (Atari Freak 1)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7991e1797e5e9f311fd957e62d889dff", "Joe Grand", "", "SCSIcide (v1.1) (2001) (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "", "" },
+  { "7996b8d07462a19259baa4c811c2b4b4", "", "", "Math Gran Prix (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "79ab4123a83dc11d468fb2108ea09e2e", "Activision - Cheshire Engineering, David Rolfe, Larry Zwick", "AZ-037-04", "Beamrider (1984) (Activision)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "79b649fb812c50b4347d12e7ddbb8400", "", "", "Red Pong Number 2 Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "79c27f90591e3fdc7d2ed020ecbedeb3", "CCE", "C-815", "Seaquest (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "79d4af56036ec28f298cad964a2e2494", "", "", "Hangman Pac-Man Wordlist (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "79d6f61da3c64688ac8e075667f8a39f", "", "", "Tie-Fighters (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "79e5338dbfa6b64008bb0d72a3179d3c", "M Network - INTV, David Akers, Patricia Lewis Du Long", "MT4313", "Star Strike (1983) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "79fcdee6d71f23f6cf3d01258236c3b9", "Atari - GCC, Mike Feinstein, John Mracek", "CX2673, CX2673P", "Phoenix (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7a09299f473105ae1ef3ad6f9f2cd807", "Atari, Steve Wright", "CX2616P", "Pele's Soccer (1981) (Atari) (PAL)", "AKA Pele's Championship Soccer", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7a2af383014f5d810ad26d322823549d", "", "", "FlickerSort Demo (20-04-2002) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7a5463545dfb2dcfdafa6074b2f2c15e", "20th Century Fox Video Games - Sirius Software, Mark Turmell", "11007", "Turmoil (1982) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7a63d7ea3f2851bcf04f0bb4ba1a3929", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (3 of 4) (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7a64a8b727c8215d945e37d565ca95a5", "Atari, Warren Robinett", "CX2606", "Slot Racers (1978) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7a64b5a6e90619c6aacf244cdd7502f8", "Baroque Gaming (Brian Eno)", "", "Warring Worms (Beta 1) (2002) (Baroque Gaming)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7a7f6ab9215a3a6b5940b8737f116359", "Arcadia Corporation, Kevin Norman", "AR-4103", "Killer Satellites (1983) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7a93d0c029eaa72236523eedc3f19645", "", "", "20 Sprites at Once Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7ab0917107b6ec768a5ebaadf28c497a", "", "", "Santa's Helper (Hack)", "Hack of Kaboom!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
+  { "7ab210f448de518fa61a5924120ba872", "", "", "Fortress (20-04-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7ab2f190d4e59e8742e76a6e870b567e", "Apollo, Larry Martin", "AP-2008", "Guardian (1982) (Apollo)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 65", "", "", "", "" },
+  { "7ac4f4fb425db38288fa07fb8ff4b21d", "Goliath", "83-213", "Space Eagle (1983) (Goliath) (PAL)", "AKA Exocet", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7ad257833190bc60277c1ca475057051", "Atari, Alan J. Murphy, Robert Zdybel", "CX2668", "RealSports Football (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "7ad782952e5147b88b65a25cadcdf9e0", "Imagic, Dave Johnson", "720119-1A, 03211", "Kwibble (1983) (Imagic) (Prototype)", "AKA Quick Step! Beta", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7adbcf78399b19596671edbffc3d34aa", "Atari, Mimi Nyden, Joseph Tung", "CX26152", "Super Baseball (1988) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7af40c1485ce9f29b1a7b069a2eb04a7", "Amiga - Video Soft", "3120", "Mogul Maniac (1983) (Amiga)", "Uses the Amiga Joyboard", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7b24bfe1b61864e758ada1fe9adaa098", "Atari, Chris Crawford", "", "Wizard (1980) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7b33407b2b198af74906b936ce1eecbb", "King Atari", "", "Ghostbuster 2 (King Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "7b3cf0256e1fa0fdc538caf3d5d86337", "CommaVid, Joseph Biel", "CM-009", "Stronghold (1983) (CommaVid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7b43c32e3d4ff5932f39afcb4c551627", "Syncro, Daniel Wolf", "", "Kamikaze Saucers (1983) (Syncro) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7b4be337ac4d73eda75c848355f6f480", "Omegamatrix", "", "Star Wars Arcade (Atari Trak-Ball) (Y Inverted) (PAL60) v4 (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7b5207e68ee85b16998bea861987c690", "Atari, Carol Shaw", "CX26163P", "3-D Tic-Tac-Toe (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7b57318c489ff178f7ff500da1ec9e8c", "Thomas Jentzsch", "", "Reactor - Amiga Mouse Hack v1.3 (PAL) (Full-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7b6f3348dbf71ada88db0fdaf7feefe0", "", "", "3-D Corridor (Pink Spiral) (31-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7b79beb378d1b4471def90ceccf413de", "", "", "Pitfall Cupcake (Hack)", "Hack of Pitfall", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7b7b4ac05232490c28f9b680c72998f9", "Zellers", "", "Freeway (Zellers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7b8a481e0c5aa78150b5555dff01f64e", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692", "Moon Patrol (05-12-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7b938c7ddf18e8362949b62c7eaa660a", "Atari, Bob Whitehead - Sears", "CX2603 - 99803, 49-75601", "Star Ship (1977) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7ba07d4ea18bf3b3245c374d8720ad30", "Starpath Corporation, Stephen H. Landrum", "AR-4101", "Communist Mutants from Space (Preview) (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7bb286cb659d146af3966d699b51f509", "Atari - Axlon, Tod Frye", "CX26178", "Save Mary! (04-03-1989) (Atari) (Prototype)", "AKA Saving Mary", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7bc4fd254ec8c0a25a13f02fd3f762ff", "Retroactive", "", "Qb (V1.00) (Stella) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "7c00e7a205d3fda98eb20da7c9c50a55", "Apollo - Games by Apollo, Larry Minor, Ernie Runyon, Ed Salvo", "AP-2004", "Lost Luggage (1982) (Apollo)", "AKA Airport Mayhem", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7c4a499d343fca0cef2d59dd16af621a", "", "", "Poker Card Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7c757bb151269b2a626c907a22f5dae7", "TNT Games - Sculptured Software, Adam Clayton", "26192", "BMX Air Master (1989) (TNT Games) (PAL)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7c7a4a2d505c2d0c75337c44711d8d54", "Atari, Warren Robinett", "", "Elf Adventure (04-22-83) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7c9b3b8b25acf2fe3b8da834f69629c6", "", "", "I Robot (1984) (Atari) (Prototype) [!]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7ca7a471d70305c673fedd08174a81e8", "Tim Snider", "", "Venture II (2001) (Tim Snider)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "7cc77f6745e1f2b20df4a4327d350545", "Atari, Richard Maurer", "CX2632, CX2632P", "Space Invaders (1980) (Atari) (PAL) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7ccf350354ee15cd9b85564a2014b08c", "", "", "Big Dig (13-04-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7cd379da92c93679f3b6d2548617746a", "", "", "Demo Image Series #5 - Clown (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7cd900e9eccbb240fe9c37fa28f917b5", "Jone Yuan Telephonic Enterprise Co", "", "Bi! Bi! (Jone Yuan) (PAL)", "AKA Skindiver", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7ced6709f091e79a2ab9575d3516a4ac", "Activision, Steve Cartwright - Ariola", "EAX-027 - 711 027-722", "Plaque Attack (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7cedffa0db65d610568b90aeca705ac6", "Atari, Rob Fulop - Sears", "CX2638 - 49-75166", "Missile Command (1981) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7cf3a9267cdb95aba91abc5838d61cc5", "Thomas Jentzsch", "", "Centipede - Atari Mouse Hack v1.4 (PAL60) (Half-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7d0b49ea4fe3a5f1e119a6d14843db17", "Gameworld, J. Ray Dettling", "133-008", "Frankenstein's Monster (1983) (Gameworld) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7d1034bcb38c9b746ea2c0ae37d9dff2", "Atari, Brad Stewart", "", "Morse Code Tutor (1979) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7d3cdde63b16fa637c4484e716839c94", "CCE", "", "Road Runner (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7d483b702c44ee65cd2df22cbcc8b7ed", "Atari, Warren Robinett", "", "Elf Adventure (05-25-83) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7d5c3b7b908752b98e30690e2a3322c2", "Dactari - Milmar", "", "Freeway (Dactari - Milmar)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7d726fa494f706784bafeb1b50d87f23", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (07-27-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7d8287e8423a56d4f8cef10435d97179", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Trak-Ball Hack v1.2 (NTSC) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7d903411807704e725cf3fafbeb97255", "Imagic, Rob Fulop", "720104-1A, 720104-1B, IA3204", "Cosmic Ark (Reaction) (1982) (Imagic) [selectable starfield]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7d93071b3e3616093a6b5a98b0315751", "", "", "Gunfight 2600 - Music & Bugfixes 2 (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7d940d749e55b96b7b746519fa06f2de", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix (Preview) (1983) (Arcadia) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7d9c96b215d1941e87b6fb412eb9204f", "", "", "Othello (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7da9de8d62fcdd3a2c545b2e720c2a61", "CommaVid, John Bronstein", "CM-001", "MagiCard (1981) (CommaVid) (4K)", "Uses the Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7dbc8fa2e488e3f6b87fbe0f76c5b89f", "Ed Federmeyer", "", "Sound X (1996) (Ed Federmeyer)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7dc03a1f56d0e6a8aae3e3e50d654a08", "", "", "Hozer Video Demo (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7dcbfd2acc013e817f011309c7504daa", "Arcadia Corporation, Dennis Caswell", "AR-4000, AR-4100", "Phaser Patrol (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "7dd9c5284422f729066ab22a284c8283", "CCE", "C-833", "Target Practice (1983) (CCE) [a]", "AKA Carnival", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7ded20e88b17c8149b4de0d55c795d37", "Thomas Jentzsch, Paul Slocum", "", "Thrust+ Platinum (v1.26)", "", "New Release, supports BoosterGrip", "", "", "", "", "", "", "", "BOOSTERGRIP", "", "", "DRIVING", "", "", "", "", "", "", "", "", "", "" },
+  { "7dfd100bda9abb0f3744361bc7112681", "Telesys, Don Ruffcorn", "1006", "Demolition Herby (1983) (Telesys) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "7e2fe40a788e56765fe56a3576019968", "Activision - Imagineering, Donald Hahn, Dan Kitchen", "AK-050-04", "Double Dragon (1989) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7e464186ba384069582d9f0c141f7491", "PlayAround - J.H.M.", "206", "General Re-Treat (1982) (PlayAround) (PAL)", "AKA Custer's Revenge", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7e4783a59972ae2cd8384f231757ea0b", "Atari - Imagineering, Dan Kichen", "CX26139P", "Crossbow (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7e51a58de2c0db7d33715f518893b0db", "CBS Electronics, E.F. Dreyer, Ed Salvo", "4L 2738 0000", "Mountain King (1983) (CBS Electronics) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "7e52a95074a66640fcfde124fffd491a", "Atari - GCC, Mike Feinstein, John Mracek", "CX2673", "Phoenix (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7e7c4c59d55494e66eef5e04ec1c6157", "Baroque Gaming (Brian Eno)", "", "Warring Worms (2002) (Baroque Gaming)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7e8aa18bc9502eb57daaf5e7c1e94da7", "CBS Electronics - Roklan, Joe Hellesen, Joe Wagner", "M8774, M8794", "Wizard of Wor (1982) (CBS Electronics)", "Uses the Joystick Controllers (swapped)", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "7e9da5cb84d5bc869854938fe3e85ffa", "Atari, Ian Shepard - Sears", "CX2604 - 6-99812, 49-75106", "Space War (1978) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7e9f088e15b2af9ff3411991393e6b1f", "Atari - Roklan, Joe Gaucher", "CX2679", "RealSports Basketball (12-28-1982) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7eab0284a0cd1043461d446a08d08cec", "Jone Yuan Telephonic Enterprise Co", "", "Basic Math (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7ead257e8b5a44cac538f5f54c7a0023", "Xonox, Anthony R. Henderson", "99006, 6220", "Sir Lancelot (1983) (Xonox) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7eaf009a892f03d90682dc1e67e85f07", "Fabrizio Zavagli", "", "Bounce! (18-03-2003) (Fabrizio Zavagli)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "7eafc9827e8d5b1336905939e097aae7", "Atari, Mark R. Hahn", "", "Elk Attack (1987) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7eba20c2291a982214cc7cbe8d0b47cd", "Imagic, Dave Johnson", "720119-1A, 03211", "Quick Step! (1983) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7ed61a18cebdeca0a93be1f5461731e5", "Dactari", "", "Skiing (Dactari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7ed7130a6e4020161836414332b11983", "", "", "Fu Kung! (V0.05 Cuttle Card Compatible) (13-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7edc8fcb319b3fb61cac87614afd4ffa", "Activision, Alan Miller", "AG-003", "Checkers (1980) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7ef3ca08abde439c6ccca84693839c57", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix (1983) (Arcadia) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" },
+  { "7ef74879d7cb9fa0ef161b91ad55b3bb", "CCE", "", "Vanguard (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7f0209cfcc3d181715463f4d6451cecf", "Atari - GCC, John Allred, Douglas B. Macrae, Betty Ryan Tylko", "CX2694", "Pole Position (05-15-1983) (Atari) (Prototype)", "AKA RealSports Driving", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7f07cd2e89dda5a3a90d3ab064bfd1f6", "Videospielkassette - Ariola", "PGP234", "Boxen (Ariola) (PAL)", "AKA Boxing", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7f430c33044e0354815392b53a9a772d", "HES", "773-891", "2 Pak Special - Cavern Blaster, City War (1992) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7f525b07bc98080cc8950f7284e52ede", "Atari", "", "128-in-1 Junior Console (Chip 4 of 4) (1991) (Atari) (PAL)", "Actually contains only 16 games, not 32", "", "", "", "16IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7f54fa6aa824001af415503c313262f2", "HES", "", "Boom Bang (HES) (PAL)", "AKA Crackpots", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7f6533386644c7d6358f871666c86e79", "CommaVid, Irwin Gaines", "CM-008", "Cakewalk (1983) (CommaVid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7f790939f7eaa8c47a246c4283981f84", "", "", "This Planet Sucks Demo 3 (Greg Troutman) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "7f819454734ddf93f83fefcffcd3e212", "Jone Yuan Telephonic Enterprise Co", "", "Outlaw (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7f9fbe3e00a21ea06e6ae5e0e5db2143", "", "", "Skate Boardin' (2002) (Skyworks)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7fcd1766de75c614a3ccc31b25dd5b7a", "PlayAround - J.H.M.", "203", "Knight on the Town (1982) (PlayAround)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "7fcd5fb59e88fc7b8473c641f44226c3", "CCE", "C-807", "Space Tunnel (1983) (CCE)", "AKA O Tunel Espacial", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7ff53f6922708119e7bf478d7d618c86", "Suntek", "SS-032", "Walker (1983) (Suntek) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "7ffc2d80fd49a124808315306d19868e", "Ishido", "", "Domino (Ishido) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "801ba40f3290fc413e8c816c467c765c", "Hozer Video Games", "", "Gunfight 2600 - Westward Ho! (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "803393ed29a9e9346569dd1bf209907b", "Atari - GCC, Mark Ackerman, Tom Calderwood, Glenn Parker", "CX2684", "Galaxian (02-04-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "804ed85eadf1ce3e93721547cbea7592", "CCE", "", "Fishing Derby (CCE) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8055b9c2622136fd91edfea6df642daf", "Activision", "", "Unknown Activision Game #1 (1983) (Activision) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "805f9a32ef97ac25f999a25014dc5c23", "SnailSoft", "", "Balthazar (SnailSoft)", "AKA Babylon 5", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "8068e07b484dfd661158b3771d6621ca", "Epyx, Steven A. Baker, Peter Engelbrite", "80561-00286", "California Games (1987) (Epyx) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "807841df228ee8aab0a06ee639ce5a8a", "Coleco - Project Guild - GMA, Michael Green, Anthony R. Henderson, Gary Littleton", "2455", "Turbo (1982) (Coleco) (Prototype)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "807a8ff6216b00d52aba2dfea5d8d860", "John Payson", "", "Strat-O-Gems Deluxe (2005) (J. Payson)", "Uses the AtariVox controller", "Homebrew", "", "", "", "", "", "", "", "", "", "", "ATARIVOX", "", "", "", "", "", "", "", "", "", "" },
+  { "808c3b1e60ee0e7c65205fa4bd772221", "CCE", "", "Defender (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "80cd42881e670e4b74a9ccd10d0d7b2e", "20th Century Fox Video Games - Sirius, Ed Hodapp", "11004", "Deadly Duck (1982) (20th Century Fox) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "80cec82239913cb8c4016eb13749de44", "David Marli", "", "Invaders from Space by David Marli (Space Invaders Hack)", "Hack of Space Invaders (Atari)", "New Release (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "80dcbe1b55f12be731a224a53ee4ad5f", "Bit Corporation", "R320", "Amidar (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "80e1410ec98089e0733cc09e584dba4b", "Dynamics", "DY-293005", "Jumping Jack (1983) (Dynamics) (PAL)", "AKA Bobby Is Going Home", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "80e52315919bd8a8b82a407ccd9bb13f", "", "", "Euchre (Jul 28) (2002) (Eric Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "80e5400470ac788143e6db9bc8dd88cf", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (06-XX-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "80f7bf7418a462e8687ecefeaf6eb9c2", "Thomas Jentzsch", "", "Reactor - Atari Trak-Ball Hack v1.3 (NTSC) (Half-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8101efafcf0af32fedda4579c941e6f4", "", "", "Okie Dokie (4K) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "81073d0377a2badef8d5e74fc44fc323", "Thomas Jentzsch", "", "Sadoom (TJ) (PAL60) (Hack)", "Hack of Kaboom!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
+  { "8108162bc88b5a14adc3e031cf4175ad", "Suntek", "SS-030", "Skydiver (1983) (Suntek) (PAL)", "AKA Parachute", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8108ad2679bd055afec0a35a1dca46a4", "", "", "Maze Craze (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "NTSC", "", "", "" },
+  { "810d8952af5a6036fca8d0c4e1b23db6", "Tiger Vision - Eram", "", "Keystone (Tiger Vision)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "81254ebce88fa46c4ff5a2f4d2bad538", "Atari, David Crane - Sears", "CX2653 - 6-99823, 49-75111", "Slot Machine (1979) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "81341f00b61ab37d19d1529f483d496d", "", "", "Fu Kung! (V0.04) (10-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "813985a940aa739cc28df19e0edd4722", "Imagic, Bob Smith", "720000-201, 720102-1B, IA3201", "Star Voyager (1982) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "81414174f1816d5c1e583af427ac89fc", "Thomas Jentzsch", "", "Treasure Below (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "814210c0e121f7dbc25661b93c06311c", "", "", "Joustpong (16-09-2002) (Kirk Israel) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "81591a221419024060b890665beb0fb8", "Atari, Carla Meninsky, Ed Riddle", "CX2611, CX2611P", "Indy 500 (1977) (Atari) (PAL)", "Uses the Driving Controllers", "", "", "", "", "", "", "", "", "DRIVING", "", "", "DRIVING", "", "", "", "", "", "45", "", "", "", "" },
+  { "8190b403d67bf9792fe22fa5d22f3556", "", "", "Sky Diver (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "819aeeb9a2e11deb54e6de334f843894", "Atari, Gary Palmer", "CX2661", "Fun with Numbers (1980) (Atari)", "AKA Basic Math", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "81a010abdba1a640f7adf7f84e13d307", "Telegames - VSS", "7062 A305", "Universal Chaos (1988) (Telegames)", "AKA Targ", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "81b3bf17cf01039d311b4cd738ae608e", "CBS Electronics - Roklan, Joe Gaucher, Alex Leavens", "M8776, M8793", "Gorf (1982) (CBS Electronics)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "81f4f0285f651399a12ff2e2f35bab77", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "822a950f27ff0122870558a89a49cad3", "", "", "Space Jockey (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "82337e5fe0f418ca9484ca851dfc226a", "Thomas Jentzsch", "", "Robot City (V1.0) (Alpha) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "826481f6fc53ea47c9f272f7050eedf7", "Imagic, Dennis Koble", "720103-1A, IA3203", "Atlantis II (1982) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "827a22b9dffee24e93ed0df09ff8414a", "CBS Electronics, Stuart Ross", "", "Wings (10-10-1983) (CBS Electronics) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "8290daea8391f96d7c8e1482e184d19c", "Eckhard Stolberg", "", "Frame Timed Sound Effects (Eckhard Stolberg)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "82bf0dff20cee6a1ed4bb834b00074e6", "Suntek", "SS-035", "Panda (1983) (Quest) (Suntek) (PAL)", "AKA Panda Chase", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "82c25d1c35e6ac6f893d1d7c2fc2f9c8", "Atari, Larry Kaplan", "CX2628, CX2628P", "Bowling (1979) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "82de957d155fc041fc6afb8315a28550", "Coleco, Joseph Biel", "2457", "Venture (1982) (Coleco) (Prototype)", "2K", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "82e7aab602c378cffdd8186a099e807e", "", "", "Space Robot (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "82efe7984783e23a7c55266a5125c68e", "CCE", "C-837", "Pizza Chef (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "834a2273e97aec3181ee127917b4b269", "Quelle", "043.151 0, 874.382 5", "Die hungrigen Froesche (1983) (Quelle) (PAL)", "AKA Frogs and Flies", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "835759ff95c2cdc2324d7c1e7c5fa237", "20th Century Fox Video Games, Frank Cohen, Douglas 'Dallas North' Neubauer", "11011", "M.A.S.H (1983) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8372eec01a08c60dbed063c5524cdfb1", "", "", "Cross Force (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8388d6fe59c38c0b3a6ab2c58420036a", "Atari, Frank Hausman, Mimi Nyden, Steve Woita", "CX2686", "Quadrun (12-06-1982) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "83b8c01c72306d60dd9b753332ebd276", "", "", "Bank Heist (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "83bdc819980db99bf89a7f2ed6a2de59", "Atari, Carla Meninsky - Sears", "CX2637 - 49-75158", "Dodge 'Em (1980) (Atari) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "83d15fb9843d9f84aa3710538403f434", "", "", "Gunfight 2600 - Release Candidate (2001) (MP) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "83e1b9f22f29259679e1018bc04cc018", "Bit Corporation", "R320", "Fast Eddie (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "83f05ececae8be59ba1e51135f4bdcbf", "", "", "Demo Image Series #13 - Mario (4K Interleaved Chronocolour) (05-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "83f50fa0fbae545e4b88bb53b788c341", "Atari, Larry Kaplan - Sears", "CX2643 - 6-99815", "Codebreaker (1978) (Atari) (4K)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "83fafd7bd12e3335166c6314b3bde528", "Epyx, Steven A. Baker, Tod Frye, Peter Engelbrite", "80561-00251", "Winter Games (1987) (Epyx)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "840a5a2eaea24d95d289f514fd12f9bb", "", "", "GBImprov (Hack)", "Hack of Ghostbusters", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "841057f83ce3731e6bbfda1707cbca58", "Champ Games", "CG-04-N", "Super Cobra Arcade (NTSC)", "Compatible with Genesis controller", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "841b7bc1cad05f5408302308777d49dc", "Activision", "", "Unknown Activision Game (10-22-1982) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "84290e333ff7567c2380f179430083b8", "Imagic, Dave Johnson", "13211, EIX-004-04I", "Quick Step! (1983) (Imagic) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "843435eb360ed72085f7ab9374f9749a", "Joe Grand", "", "SCSIcide (1.31) (Joe Grand)", "Uses the Paddle Controllers", "New Release", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "", "" },
+  { "84535afb9a69712ec0af4947329e08b8", "CCE", "C-868", "Bingo (1983) (CCE) (PAL)", "AKA Dice Puzzle", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "8454ed9787c9d8211748ccddb673e920", "Froggo", "FG1002", "Spiderdroid (1987) (Froggo)", "AKA Amidar", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8490e1014c2baa0d3a3a08854e5d68b3", "Xonox, Anthony R. Henderson", "99006, 6220", "Sir Lancelot (1983) (Xonox) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "84db818cd4111542a15c2a795369a256", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (1983) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "850ffd5849c911946b24544ea1e60496", "", "", "Invasion (07-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "851cc1f3c64eaedd10361ea26345acea", "Activision, David Crane", "AG-009, AG-009-04", "Freeway (1981) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "85227160f37aaa29f5e3a6c7a3219f54", "Activision, David Crane", "AG-004", "Fishing Derby (1980) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8530caaaf40acbdcd118c282b5f8a37a", "", "", "This Planet Sucks Demo 2 (Greg Troutman) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8538c5e3ee83267774480649f83fa8d6", "", "", "Escape Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "853c11c4d07050c22ef3e0721533e0c5", "", "", "Oink! (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "85470dcb7989e5e856f36b962d815537", "Atari - Sculptured Software, Inc., Steve Aguirre", "CX26162", "Fatal Run (1989) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "85478bb289dfa5c63726b9153992a920", "", "", "Candi (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "854b68b93e7123a3be42b5a2a41f75d7", "Atari, Carol Shaw", "CX2618, CX2618P", "3-D Tic-Tac-Toe (1980) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "85502d69fe46b7f54ef2598225678b47", "Jone Yuan Telephonic Enterprise Co", "", "Super-Ferrari (Jone Yuan)", "AKA Enduro", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "85564dd0665aa0a1359037aef1a48d58", "ITT Family Games", "554-33 367", "Laser Base (1983) (ITT Family Games) (PAL) [a]", "AKA The End of the World (Perry Rhodan-Serie)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "8556b42aa05f94bc29ff39c39b11bff4", "Atari, Craig Nelson - Sears", "CX2617 - 49-75183", "Backgammon (1979) (Atari)", "Uses the Paddle Controllers", "Extremely Rare", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "", "", "", "", "AUTO 80", "", "", "", "" },
+  { "855a42078b14714bcfd490d2cf57e68d", "Atari, Suki Lee", "CX26113", "Miss Piggy's Wedding (1983) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8597f66dd37d9c855663804669d69d7a", "Tigervision, Warren Schwader", "7-003", "Threshold (1982) (Tigervision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "85a4133f6dcf4180e36e70ad0fca0921", "CCE", "C-827", "Chopper Command (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "85b1bca93e69f13905107cc802a02470", "Atari, Craig Nelson", "CX2617, CX2617P", "Backgammon (1979) (Atari) (PAL)", "Uses the Paddle Controllers", "Extremely Rare", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "", "", "", "", "AUTO 80", "", "", "", "" },
+  { "85bbefb90e16bf386b304c1e9a1f6084", "Champ Games", "CG-02-P", "Conquest Of Mars (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "85e48d68c8d802e3ba9d494a47d6e016", "", "", "Ship Demo (V 15) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "85e564dae5687e431955056fbda10978", "Milton Bradley Company - Renaissance Technology, Ty Roberts", "4362", "Survival Run (1983) (Milton Bradley)", "AKA Cosmic Commander", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "86128001e69ab049937f265911ce7e8a", "Apollo - Games by Apollo, Steve Stringfellow", "AP-2005", "Lochjaw (1982) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8619da7f6796cedff59e5aa20712fb4e", "Thomas Jentzsch", "", "Sadistroids (v1.2) (2003) (Thomas Jentzsch)", "Supports Driving Controller in right port", "", "", "", "", "", "", "", "", "", "", "", "DRIVING", "", "", "", "", "", "", "", "", "YES", "30" },
+  { "862cf669cbced78f9ed31a5d375b2ebe", "", "", "Gunfight 2600 - Flicker acceptance (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8644352b806985efde499ae6fc7b0fec", "CCE", "C-801", "Mr. Postman (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8654d7f0fb351960016e06646f639b02", "Home Vision, R.J.P.G. - Gem International Corp. - VDI", "VCS83106", "Ski Hunt (1983) (Home Vision) (PAL)", "AKA Skiiing Hunt", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "866e5150c995c4ae5172e5207ba948c7", "Canal 3 - Intellivision", "", "Stampede (Canal 3) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "869abe0426e6e9fcb6d75a3c2d6e05d1", "", "", "Stampede (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "86b4aa76bbeb70e1a4f9211a9880ba8e", "", "", "Incoming (1 Player Version) (05-11-2002) (Ben Larson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8712cceec5644aacc2c21203d9ebe2ec", "Retroactive", "", "Qb (V0.10) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "8726c17ee7b559cb7bf2330d20972ad0", "", "", "Cave Demo (21-04-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "873fb75a7788ba0f4ae715229a05545e", "", "", "Euchre (Improved Colors) (PAL) (26-09-2002) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8747ba79cd39fa83a529bb26010db21b", "Atari, Richard Maurer", "CX2632, CX2632P", "Space Invaders (1980) (Atari) (PAL) [different speed and colors]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8749a0d088df25218c149dc325abc7ca", "Commavid, Ben Burch", "CM-010", "Rush Hour (1983) (Commavid) (Prototype) [a5]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "874c76726f68c166fcfac48ce78eef95", "", "", "Red Pong Number 2 Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "8764462d7d19a33b0717af22b99fc88f", "CCE", "", "Sky Jinks (CCE) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "87662815bc4f3c3c86071dc994e3f30e", "Intellivision Productions - M Network, Patricia Lewis Du Long, Stephen Tatsumi", "", "Swordfight (1983) (Intellivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "876a953daae0e946620cf05ed41989f4", "Retroactive", "", "Qb (V2.08) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "877a5397f3f205bf6750398c98f33de1", "Erik Eid", "", "Euchre (Beta) (PAL) (12-09-2002) (Erik Eid)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8786c1e56ef221d946c64f6b65b697e9", "20th Century Fox Video Games, David Lubar", "11015", "AKA Space Adventure", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8786f229b974c393222874f73a9f3206", "Activision, Larry Miller - Ariola", "EAX-021, EAX-021-04I - 711 021-720", "Spider Fighter (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8786f4609a66fbea2cd9aa48ca7aa11c", "Goliath", "5", "Open Sesame (1983) (Goliath) (PAL)", "AKA Open, Sesame!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "87b460df21b7bbcfc57b1c082c6794b0", "Dennis Debro", "", "Climber 5 (20-03-2003) (Dennis Debro)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "87b6a17132fc32f576bc49ea18729506", "Atari, Andrew Fuchs, Courtney Granner, Jeffrey Gusman, Mark R. Hahn", "CX2690", "Pengo (1984) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "87bea777a34278d29b3b6029833c5422", "Thomas Jentzsch", "", "Polaris (1983) (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "87e79cd41ce136fd4f72cc6e2c161bee", "Atari - GCC, Mark Ackerman, Glenn Parker", "CX2675", "Ms. Pac-Man (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "87f020daa98d0132e98e43db7d8fea7e", "20th Century Fox Video Games - Sirius, David Lubar", "11001", "Worm War I (1982) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "883258dcd68cefc6cd4d40b1185116dc", "Activision, David Crane - Ariola", "EAZ-030, EAZ-030-04B, EAZ-030-04I - 711 030-725", "Decathlon (1983) (Activision) (PAL)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8874b68751fd2ba6d3306a263ae57a7d", "Eric Mooney", "", "Invaders by Erik Mooney (Alpha 1) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8885d0ce11c5b40c3a8a8d9ed28cefef", "Atari, Carol Shaw, Nick 'Sandy Maiwald' Turner - Sears", "CX2608 - 49-75165", "Super Breakout (1982 - 1981) (Atari)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 45", "", "", "", "" },
+  { "888debb162d7d1ae71025b4ab794257f", "", "", "Interleaved ChronoColour - Nude Art (17-04-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "88a6c9c88cb329ee5fa7d168bd6c7c63", "CCE", "C-1007", "Jungle Hunt (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "88d300a38bdd7cab9edad271c18cd02b", "Funvision - Fund. Int'l Co.", "", "Pac Kong (Funvision) (PAL)", "AKA Inca Gold", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "88d7b6b3967de0db24cdae1c7f7181bd", "Atari - GCC, Dave Payne", "CX2669", "Vanguard (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "88d8a1accab58cf1abb043613cf185e9", "Ultravison", "", "Sabotage (Ultravison)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "88dce4037471424bb38ab6841aaa8cab", "", "", "Double-Height 6-Digit Score Display (Two Background Color Change) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "88ed87c011f699dd27321dbe404db6c8", "Activision, Dan Kitchen", "AX-029", "Crackpots (1983) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "88f74ec75ef696e7294b7b6ac5ca465f", "Activision, Bob Whitehead", "AG-002, CAG-002, AG-002-04", "Boxing (1980) (Activision) (16K)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8905d54f48b8024fc718ed643e9033f7", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (05-24-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "890c13590e0d8d5d6149737d930e4d95", "Atari, David Crane - Sears", "CX2605 - 6-99822, 49-75109", "Outlaw (1978) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8917f7c1ac5eb05b82331cf01c495af2", "Bit Corporation", "PG202", "Space Tunnel (1982) (BitCorp) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8933976f2029c0d8492ebd8f4eb21492", "", "", "Synthcart Plus (09-02-2003) (Paul Slocum)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8953bc11352d794431d3303e31d3b892", "Tigervision, Robert H. O'Neil", "7-007", "Polaris (02-17-1983) (Tigervision) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "896ec58f26e930e02f5e4f046602c3a1", "", "", "Synthcart (Beta) (2002) (Paul Slocum)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "898143773824663efe88d0a3a0bb1ba4", "Activision - Woodside Design Associates, Steve 'Jessica Stevens' Kitchen", "AZ-033, AZ-033-04", "Space Shuttle (1983) (Activision) [FE]", "A Journey Into Space", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "898748d5eaac3164b0391a64ae1e0e32", "", "", "Hangman Man 4letter (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "898b5467551d32af48a604802407b6e8", "Bit Corporation", "PG208", "Snail Against Squirrel (1983) (BitCorp) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "89a65b83203980d5d4d60f52a584a5b8", "", "", "Marble Craze (PAL) (02-02-2003) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "89a68746eff7f266bbf08de2483abe55", "Atari, Jerome Domurat, Steve Woita", "CX2696", "Asterix (1984) (Atari)", "AKA Taz", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "89afff4a10807093c105740c73e9b544", "", "", "Pooyan (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "89eaba47a59cbfd26e74aad32f553cd7", "Apollo - Games by Apollo, Ed Salvo, Byron Parks", "AP-2001", "Spacechase (1982) (Apollo) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8a159ee58b2f0a54805162984b0f07e5", "Atari - Sculptured Software, Inc., Steve Aguirre", "CX26162", "Fatal Run (1989) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8a183b6357987db5170c5cf9f4a113e5", "Atari - Roklan, Joe Gaucher", "CX2679", "RealSports Basketball (01-11-1983) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8a42e2c7266439d8997a55d0124c912c", "", "", "Hangman Invader Wordlist (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8a49cf1785e3dea2012d331a3ad476e1", "", "", "Boulderdash (10 Blocks Wide) (02-04-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8a6c84f481acf42abcb78ba5064ad755", "128-in-1 Junior Console", "", "Street Racer (128-in-1 Junior Console) (PAL) (4K)", "Uses the Paddle Controllers (swapped)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 75", "", "", "", "" },
+  { "8a8e401369e2b63a13e18a4d685387c6", "Activision, David Crane - Ariola", "EAG-008, PAG-008, EAG-008-04I - 711 008-720", "Laser Blast (1981) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8a9d874a38608964f33ec0c35cab618d", "Chris Cracknell", "", "Rescue Bira Bira (Chris Cracknell)", "Hack of Jungle Fever", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "8a9d953ac3db52a313a90d6a9b139c76", "", "", "Hangman Invader Biglist3 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8aad33da907bed78b76b87fceaa838c1", "Atari, Larry Kaplan", "CX26163P", "Air-Sea Battle (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8ac18076d01a6b63acf6e2cab4968940", "Atari, Dan Hitchens, Mimi Nyden", "CX2685", "Gravitar (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8af58a9b90b25907da0251ec0facf3b8", "Jone Yuan Telephonic Enterprise Co", "", "Cosmic Swarm (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "8b04e9d132b8e30d447acaa6bd049c32", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (1982) (Starpath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8b40a9ca1cfcd14822e2547eaa9df5c1", "Parker Brothers - Western Technologies, Dave Hampton, Tom Sloper", "931517", "Q-bert (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8b504b417c8626167a7e02f44229f0e7", "Retroactive", "", "Qb (V1.00) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "8b556c3d9ca8e5e6e665bd759b93ffae", "", "", "Synthcart (2002) (Paul Slocum) (PAL) [!]", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "8b5b1e3a434ebbdc2c2a49dc68f46360", "CBS Electronics - Woodside Design Associates - Imaginative Systems Software, Garry Kitchen", "4L1700, 4L1701, 4L1702, 4L1802, 4L2274", "Donkey Kong (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8b7ca29a55432f886cee3d452fb00481", "Starpath Corporation, Stephen H. Landrum, Jon Leupp", "11 AR-4201", "Sword of Saros (1983) (Starpath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8b8152d6081f31365406cb716bd95567", "Atari", "CX2626, CX2626P", "Miniature Golf (1979) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8b8789c6669a4cee86c579a65332f852", "Digivision", "", "Plaque Attack (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8bbfd951c89cc09c148bfabdefa08bec", "UA Limited", "", "Pleiades (1983) (UA Limited) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "8bc0d2052b4f259e7a50a7c771b45241", "Xonox - K-Tel Software, Anthony R. Henderson", "99007, 6240", "Tomarc the Barbarian (1983) (Xonox) [a]", "AKA Thundarr the Barbarian", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8bd8f65377023bdb7c5fcf46ddda5d31", "Activision, Bob Whitehead", "AG-019", "Sky Jinks (1982) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8bebac614571135933116045204f0f00", "Thomas Jentzsch", "", "Missile Command (Trakball) (2002) (TJ) (PAL)", "Uses the Trakball Controller", "Homebrew", "", "", "", "", "", "", "", "TRAKBALL", "", "", "TRAKBALL", "", "", "", "", "", "", "", "", "YES", "" },
+  { "8c103a79b007a2fd5af602334937b4e1", "Thomas Jentzsch", "", "Laser Base (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8c136e97c0a4af66da4a249561ed17db", "", "", "Poker Squares (V0.27) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8c146c61817edd376bc1354c7f1ddc63", "Omegamatrix", "", "Star Wars Arcade (Amiga Mouse) (Y Inverted) (PAL60) v4 (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8c1cc284edba691139d6626d062c606f", "Atari, Omegamatrix", "", "Super Breakout Menu (2020) (PAL60) (Hack)", "Hack of Super Breakout", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" },
+  { "8c2fa33048f055f38358d51eefe417db", "Home Vision - Gem International Corp. - VDI", "VCS83137", "Teddy Apple (1983) (Home Vision) (PAL)", "AKA Open, Sesame!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "8c36ed2352801031516695d1eeefe617", "Epyx, Steven A. Baker, Tod Frye, Peter Engelbrite", "80561-00251", "Winter Games (1987) (Epyx) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8c7e5e2329f4f4e06cbcc994a30fd352", "Data Age", "DA1004", "Airlock (1982) (Data Age) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8c8a26ed57870daba8e13162d497bad1", "HES", "", "2 Pak Special - Dolphin, Oink (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8c8b15b3259e60757987ed13cdd74d41", "Supergame", "71", "River Raid (1984) (Supergame)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8c941fa32c7718a10061d8c328909577", "Digivision", "", "River Raid (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8ccaa442d26b09139685f5b22bf189c4", "Retroactive", "", "Qb (V1.01) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "8ccf63141a029603572d1056e772990e", "Thomas Jentzsch", "", "Centipede - Amiga Mouse Hack v1.4 (NTSC) (Full-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8cd26dcf249456fe4aeb8db42d49df74", "Atari - Imagineering, Dan Kichen", "CX26139", "Crossbow (1988) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8ce9126066f2ddd5173e9f1f9ce1494e", "Thomas Jentzsch", "", "Missile Command (Trakball) (2002) (TJ)", "Uses the Trakball Controller", "Homebrew", "", "", "", "", "", "", "", "TRAKBALL", "", "", "TRAKBALL", "", "", "", "", "", "", "", "", "YES", "" },
+  { "8cf0d333bbe85b9549b1e6b1e2390b8d", "Atari, Brad Stewart", "CX2649, CX2649P", "Asteroids (1981) (Atari) (PAL)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "8d00a38f4c8f8800f1c237215ac243fc", "", "", "3-D Corridor (Green) (30-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8d1e2a6d2885966e6d86717180938f87", "Thomas Jentzsch", "", "Missile Command (Amiga Mouse) (2002) (TJ)", "Uses Amiga Mouse Controller", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "8d8b7d7b983f75debbdaac651e814768", "", "", "Demo Image Series #15 - Three Marios (PAL) (06-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8d9a06101ebb0f147936356e645309b8", "", "", "Grid Pattern Demo 2 (20-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8da51e0c4b6b46f7619425119c7d018e", "Atari - Imagineering, David Lubar", "CX26183", "Sentinel (1991) (Atari)", "Uses the Light Gun Controller (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8db152458abaef3cfa7a4e420ddbda59", "", "", "Keystone Kapers (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8df4be9ddc54ac363b13dc57ceaf161a", "Scott Stilphen", "", "Asteroids SS (Scott Stilphen) (Hack)", "Hack of Asteroids", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "8e0ab801b1705a740b476b7f588c6d16", "Activision, David Crane", "AG-009, AG-009-04", "Freeway (1981) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8e42674972d6805068fc653e014370fd", "", "", "Skeleton (PAL) (15-10-2002) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8e48ea6ea53709b98e6f4bd8aa018908", "CBS Electronics, Stuart Ross", "", "Wings (06-03-1983) (CBS Electronics) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "8e4cd60d93fcde8065c1a2b972a26377", "Imagic, Dan Oliver", "720118-2A, 13208, EIX-007-04I", "Laser Gates (1983) (Imagic) (PAL)", "AKA Innerspace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8e4fa8c6ad8d8dce0db8c991c166cdaa", "Atari, Bill Aspromonte, John Russell, Michael Sierchio, Robert Zdybel", "CX26114", "Pigs in Space (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8e512ad4506800458f99dec084fc2c64", "Bob Montgomery, Nathan Strum", "", "Reindeer Rescue (2005)", "2005 AtariAge Holiday Cart", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8e7241bfc8380aac3c0ef1b6881cdded", "Atari, Howard Scott Warshaw - Sears", "CX2655 - 49-75167", "Yars' Revenge (09-01-81) (Atari) (Prototype)", "Time Freeze", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "8e737a88a566cc94bd50174c2d019593", "Quelle", "343.173 1", "Feuerwehr im Einsatz (1983) (Quelle) (PAL)", "AKA Fire Fighter", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8e822b39a71c84ac875f0107fb61d6f0", "", "", "Hangman Ghost Original Words (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8e879aa58db41edb67cbf318b77766c4", "Thomas Jentzsch", "", "Cosmic Commuter (Thomas Jentzsch) (PAL60)", "NTSC Conversion", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8e887d1ba5f3a71ae8a0ea16a4af9fc9", "", "", "Skeleton (V1.1) (PAL) (24-10-2002) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8ed5a746c59571feb255eaa7d6d0cf98", "", "", "Carnival (208 in 1) (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8ed73106e2f42f91447fb90b6f0ea4a4", "Spectravision - Spectravideo", "SA-204", "Tapeworm (1982) (Spectravision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "8ee3f64dc0f349adc893fe93df5245d8", "", "", "Euchre (20-07-2001) (Eric Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8ef96ace4a1d6dfb65926c1e868b0188", "Thomas Jentzsch", "", "Reactor - Amiga Mouse Hack v1.3 (PAL60) (Half-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8f33bce5ba1053dcf4cea9c1c69981e4", "", "", "Jawbreaker (Unknown) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8f53a3b925f0fd961d9b8c4d46ee6755", "", "", "Astrowar (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8f5ac5139419c5d49bacc296e342a247", "Atari - CCW, Michael Callahan, Preston Stuart", "CX26103", "Alpha Beam with Ernie (12-22-1982) (Atari) (Prototype)", "Uses Keypad Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8f60551db6d1535ef0030f155018c738", "", "", "Space War (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8f613ea7c32a587d6741790e32872ddd", "", "", "Troll Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8f88309afad108936ca70f8b2b084718", "Spectravision - Spectravideo - Quelle", "SA-203 - 413.223 9", "Cross Force (1982) (Spectravision) (PAL)", "AKA Kreuzfeuer (Cross Fire)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8f90590dba143d783df5a6cff2000e4d", "", "", "Gopher (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8f98519a91dbbf4864f135a10050d9ed", "Silvio Mogno", "", "Rainbow Invaders (non-playable demo) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8fa47e5242776e841df7e708b12eb998", "", "", "Sea Hawk (Genesis)", "Genesis controller (C drops bomb)", "Hack of Sea Hawk", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8fbabaa87941cdf3a377c15e95bdb0f3", "", "", "Meteor Smasher (SnailSoft)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8fe00172e7fff4c1878dabcf11bb8dce", "Quelle", "689.302 8", "Hili Ball (1983) (Quelle) (PAL)", "AKA Racquetball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "8febdd9142960d084ab6eeb1d3e88969", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX2674", "E.T. - The Extra-Terrestrial (1982) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "8fffc8f15bb2e6d24e211884a5479aa5", "Retroactive", "", "Qb (V1.00) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "9007c3cbb55ce05ad7d1c34d4906750a", "Activision, David Crane", "AX-018, AX-018-04", "Pitfall! (03-18-1983) (Activision) (Prototype)", "Pitfall Harry's Jungle Adventure (Jungle Runner)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9048ccb7e0802cd8fa5bfc2609f292d8", "Tigervision, Robert H. O'Neil", "7-007", "Polaris (1983) (Tigervision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9057694dce8449521e6164d263702185", "Activision, Bob Whitehead", "AG-011", "Stampede (1981) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "90578a63441de4520be5324e8f015352", "Bit Corporation", "PGP204", "Open Sesame (4 Game in One) (1983) (BitCorp) (PAL)", "AKA Open, Sesame!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "9072c142728a3a3d994956d03bfacba2", "Fabrizio Zavagli", "", "Crash Dive (Fabrizio Zavagli) (PAL60)", "NTSC Conversion", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "90a3c3255f2a54225cdcb50831f8793a", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Trak-Ball Hack v1.1 (PAL) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "90b1799dddb8bf748ee286d22e609480", "", "", "Ship Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "90b647bfb6b18af35fcf613573ad2eec", "AtariAge (Chris Walton)", "", "Juno First (2009)", "AtariVox supported", "Homebrew", "", "", "", "", "", "", "", "", "", "", "ATARIVOX", "", "", "", "", "", "", "", "", "YES", "" },
+  { "90ccf4f30a5ad8c801090b388ddd5613", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (1982) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "90d77e966793754ab4312c47b42900b1", "Imagic, Brad Stewart", "720105-2A, IA3400P, EIX-005-04I", "Fire Fighter (1982) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "90f502cbf4438a95f69f848cef36eb64", "Digitel", "", "River Raid II (1985) (Digitel)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "910dd9bf98cc5bc080943e5128b15bf5", "", "", "Gunfight 2600 - Improved AI (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "911d385ee0805ff5b8f96c5a63da7de5", "Thomas Jentzsch", "", "Jammed (V0.1) (Demo) (2001) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "913d5d959b5021f879033c89797bab5e", "", "", "Robot Player Graphic (1996) (J.V. Matthews) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "914a8feaf6d0a1bbed9eb61d33817679", "Atari", "CX26163P", "Freeway Chicken (32 in 1) (1988) (Atari) (PAL)", "AKA Freeway", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "91925abce3a29e33b6a8b81482f4f5af", "Activision, Garry Kitchen - Ariola", "EAX-025, EAX-025-04I - 711 025-725", "Keystone Kapers (1983) (Activision) (PAL) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9193b6fff6897d43274741d4f9855b6d", "", "", "M.A.S.H (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "91a3749ff7b7e72b7fa09e05396a0e7b", "", "", "Gunfight 2600 - Final Run Part 2 (2002) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "91b007f33f9b790be64f57220ec52e80", "Jone Yuan Telephonic Enterprise", "", "Laser Blast (Jone Yuan) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "91c2098e88a6b13f977af8c003e0bca5", "Atari - GCC", "CX2676", "Centipede (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "91d1c82ceaf8af2add3973a3c34bc0cb", "", "", "Starfield Demo 1 (20-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "91f0a708eeb93c133e9672ad2c8e0429", "", "", "Oystron (V2.9) (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "91fdb6541f70c40b16aabf8308123be8", "", "", "Interlacing Game (19-08-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9222b25a0875022b412e8da37e7f6887", "Panda", "106", "Dice Puzzle (1983) (Panda)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "9245a84e9851565d565cb6c9fac5802b", "Bomb - Onbase", "CA282", "Great Escape (1983) (Bomb)", "AKA Asteroid Fire", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "927d422d6335018da469a9a07cd80390", "Activision, Carol Shaw - Ariola", "EAX-020, EAX-020-04B, EAX-020-04I - 711 020-720", "River Raid (1982) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9281eccd7f6ef4b3ebdcfd2204c9763a", "Retroactive", "", "Qb (2.15) (Retroactive) (PAL)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "9295570a141cdec18074c55dc7229d08", "Telegames", "7045 A015", "Bump 'n' Jump (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "929e8a84ed50601d9af8c49b0425c7ea", "Bit Corporation", "PG205", "Dancing Plate (1982) (BitCorp) (PAL)", "AKA Dishaster, Dancing Plates, Tanzende Teller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "92a1a605b7ad56d863a56373a866761b", "U.S. Games Corporation - Western Technologies, Dave Hampton", "VC2006", "Raft Rider (1983) (U.S. Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "92d1b6cb8a1b615266c4088a58464779", "Bit Corporation", "R320", "Fishing Derby (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "92d1f6ac179ebe5963868d6bc1bdda8d", "HES", "498", "Smash Hit Pak - Frogger, Boxing, Seaquest, Skiing, Stampede (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "92e72f7cc569584c44c9530d645ae04e", "Canal 3 - Intellivision", "", "Spider Fighter (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "931b91a8ea2d39fe4dca1a23832b591a", "Activision, David Crane", "AG-008", "Laser Blast (1981) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9333172e3c4992ecf548d3ac1f2553eb", "Konami", "RC 101-X 02", "Strategy X (1983) (Konami)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "93420cc4cb1af1f2175c63e52ec18332", "Tim Snider", "", "Blair Witch Project (Tim Snider) (Hack)", "Hack of Haunted House", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9364ad51c321e0f15c96a8c0aff47ceb", "Atari, Rob Fulop", "CX2638", "Missile Command (1981) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "936ef1d6f8a57b9ff575dc195ee36b80", "", "", "Pac Kong (Unknown)", "AKA Inca Gold", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "936f555b4b1a2cd061b659ff63f4f5f2", "HES, David Lubar", "535", "My Golf (1990) (HES) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "937736d899337036de818391a87271e0", "Atari, Peter C. Niday", "CX26108", "Donald Duck's Speedboat (04-12-1983) (Atari) (Prototype)", "AKA Donald Duck's Regatta", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "939ce554f5c0e74cc6e4e62810ec2111", "ZiMAG - Emag - Vidco", "711-111 - GN-020", "Dishaster (1983) (ZiMAG)", "AKA Dancing Plate", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "93acd5020ae8eb5673601e2edecbc158", "Chris Cracknell", "", "Video Time Machine (Chris Cracknell)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "93b9229fc0ea4fb959d604f83f8f603c", "Thomas Jentzsch", "", "Amidar DS (Fast Enemies) (2003) (TJ) (Hack)", "Hack of Amidar", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "93c4b910f7649b3e998bb6d8527c6f4a", "Sparrow - Enter-Tech, Paul Walters, Rick Harris, George Hefner, Barbara Ultis", "", "Arkyology (1983) (Sparrow) (Prototype) [fixed]", "Fix for un-initialized 'X' register", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "93c52141d3c4e1b5574d072f1afde6cd", "Imagic, Mark Klein", "720112-1A, 03213", "Subterranea (1983) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "93c8d9d24f9c5f1f570694848d087df7", "Digivision", "", "Galaxian (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "93c9f9239a4e5c956663dd7affa70da2", "Quelle", "626.610 0", "Billard (1983) (Quelle) (PAL)", "AKA Trick Shot", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "93db185c3b3dc382f3aecd6a2fea7fd9", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Trak-Ball Hack v1.1 (PAL60) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "93dc15d15e77a7b23162467f95a5f22d", "CCE", "", "Sky Jinks (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "93e276172b521c4491097f8b1393eea7", "Atari", "", "Diagnostic Test Cartridge 4.2 (06-01-1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "93eb1795c8b1065b1b3d62bb9ec0ccdc", "JSK", "", "Custer's Viagra (JSK) (Hack)", "Hack of Custer's Revenge", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "94102febc53b4a78342d11b645342ed4", "", "", "Joustpong (14-07-2002) (Kirk Israel) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9433770890f087bfcf3e50122694d8c0", "Omegamatrix", "", "Star Wars Arcade (Amiga Mouse) (Y Inverted) v4 (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9436b7ad131b5a1f7753ce4309ba3dee", "Kyle Pittman", "", "War of The Worlds (Kyle Pittman) (Hack)", "Hack of Defender", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "943798452ceba9357e2c56303cadb4f7", "Thomas Jentzsch, Paul Slocum", "", "Thrust+ Platinum (v1.28)", "", "New Release, supports BoosterGrip and Genesis (switched by Color/B+W)", "", "", "", "", "", "", "", "JOYSTICK", "", "", "DRIVING", "", "", "", "", "", "", "", "", "", "" },
+  { "9446940866c9417f210f8552cf6c3078", "Thomas Jentzsch", "", "Marble Craze - Amiga Mouse Hack v1.0 (PAL60) (TJ)", "Uses Amiga Mouse Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "94507dee401b0a072a481c00d7699ffe", "Thomas Jentzsch", "", "Missile Control - Atari Trak-Ball Hack v1.15 (PAL) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9469d18238345d87768e8965f9f4a6b2", "CCE", "", "Ms. Pac-Man (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "947317a89af38a49c4864d6bdd6a91fb", "CBS Electronics, Bob Curtiss", "4L 2487 5000", "Solar Fox (1983) (CBS Electronics)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "94b92a882f6dbaa6993a46e2dcc58402", "Activision, Larry Miller", "AX-026, AX-026-04", "Enduro (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "94d90f63678e086f6b6d5e1bc6c4c8c2", "Digivision", "", "Seaquest (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "94e3fbc19107a169909e274187247a9d", "", "2402-044-01", "2-in-1 Freeway and Tennis (Unknown)", "", "", "", "", "2IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "94e4c9b924286038527f49cdc20fda69", "Retroactive", "", "Qb (V2.12) (Stella) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "94e7cc6342d11e508e7e8b2ddf53c255", "", "", "Missile Command (208 in 1) (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "94ff6b7489ed401dcaaf952fece10f67", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692", "Moon Patrol (07-31-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "951e8cec7a1a1d6c01fd649e7ff7743a", "Atari - Sculptured Software, Adam Clayton", "CX26151, CX26151P", "Dark Chambers (1988) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9526e3db3bdfbc27989a9cbfd0ee34bf", "", "", "Atari Logo Demo 6 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "95351b46fa9c45471d852d28b9b4e00b", "Atari, Tom Rudadahl", "CX26163P", "Golf (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "955c408265ad6994f61f9b66657bbae9", "", "", "Quadrun (Video Conversion) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "956496f81775de0b69a116a0d1ad41cc", "CCE", "", "Alien (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "956b99511c0f47b3a11d18e8b7ac8d47", "", "", "Bones (Arcade Golf Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "95956108289a917f80667eccd3ce98a9", "Atari, Ed Logg, Carol Shaw", "CX2639, CX2639P", "Othello (1981) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "95a69cf8c08ef1522b050529464f0bca", "", "", "Grid Pattern Demo 1 (20-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "95a89d1bf767d7cc9d0d5093d579ba61", "PlayAround - J.H.M.", "204", "Lady in Wading (1982) (PlayAround)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "95e1d834c57cdd525dd0bd6048a57f7b", "Atari, Bill Aspromonte, John Russell, Michael Sierchio, Robert Zdybel", "CX26114", "Pigs in Space (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "95e542a7467c94b1e4ab24a3ebe907f1", "Suntek", "SS-021", "Dragon Defender (1983) (Suntek) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "95fd6097dc27c20666f039cfe34f7c69", "", "", "Oh No! (Version 1) (17-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "961112b74a920a5242e233480326c356", "Activision, Alan Miller", "AG-007, CAG-007", "Tennis (1981) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "962ffd3eaf865230a7a312b80e6c5cfd", "Imagic, Wilfredo 'Willy' Aguilar, Michael Becker, Rob Fulop", "13205", "Fathom (1983) (Imagic) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "96662271ae50b6859017bffbdda75525", "Andrew Davie & Thomas Jentzsch", "", "Boulder Dash - Demo (2011)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "96670d0bf3610da2afcabd8e21d8eabf", "", "", "Boring Pitfall (Hack)", "Hack of Pitfall!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "966b11d3c147d894dd9e4ebb971ea309", "", "", "Marble Craze Song (Paul Slocum) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "966c955e4aaca7082d9ffb9a68e3f3ed", "Thomas Jentzsch", "", "Centipede - Atari Mouse Hack v1.4 (PAL) (Full-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9671b658286e276cc4a3d02aa25931d2", "", "", "Hangman Ghost Wordlist (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "968efc79d500dce52a906870a97358ab", "TNT Games - Sculptured Software, Adam Clayton", "26192", "BMX Air Master (1989) (TNT Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "969b968383d9f0e9d8ffd1056bcaef49", "Atari, Larry Kaplan", "CX2628, CX2628P", "Bowling (1979) (Atari) (PAL)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "96bcb3d97ce4ff7586326d183ac338a2", "", "", "Revenge of the Apes (Hack) [h2]", "Hack of Planet of the Apes", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "96e798995af6ed9d8601166d4350f276", "20th Century Fox Video Games - Videa, David Ross", "11029", "Meltdown (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "96eccc2277043508a6c481ea432d7dd9", "Thomas Jentzsch", "", "Missile Command (Atari Mouse) (2002) (TJ) (PAL)", "Uses Atari ST Mouse Controller", "Homebrew", "", "", "", "", "", "", "", "ATARIMOUSE", "", "", "ATARIMOUSE", "", "", "", "", "", "", "", "", "YES", "" },
+  { "96f806fc62005205d851e758d050dfca", "", "", "Push (V0.05) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "97184b263722748757cfdc41107ca5c0", "Parker Brothers", "PB5820", "Mr. Do!'s Castle (1984) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "9718b85ac5a55cbc7348963c63ffa35a", "Robby", "", "Demon Attack (Robby)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "972486110933623039a3581db308fda6", "", "", "Xeno Plus (Hack)", "Hack of Xenophobe", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "97327d6962f8c64e6f926f79cd01c6b9", "", "", "Jawbreaker (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "977294ae6526c31c7f9a166ee00964ad", "Atari - GCC, Douglas B. Macrae", "CX2677, CX2677P", "Dig Dug (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9784290f422e7aeeab4d542318bd9a1f", "AtariAge, Chris Walton", "1.0 (Release)", "Chetiry (2011) (AtariAge) (60k)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "50" },
+  { "97842fe847e8eb71263d6f92f7e122bd", "Imagic, Wilfredo Aguilar, Michael Becker, Dennis Koble", "720113-1A, 03206", "Solar Storm (1983) (Imagic)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 45", "", "", "", "" },
+  { "97933c9f20873446e4c1f8a4da21575f", "", "", "Racquetball (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "97a9bb5c3679d67f5c2cd17f30b85d95", "Atari", "", "Colors (1980) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "97cd63c483fe3c68b7ce939ab8f7a318", "Thomas Jentzsch", "", "Robot City (V0.21) (15-09-2002) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "97d0151beb84acbe82aa6db18cd91b98", "Steve Engelhardt", "", "Lunar Attack (2002) (Steve Engelhardt) (Hack)", "Hack of Z-Tack", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "97d079315c09796ff6d95a06e4b70171", "Activision, Garry Kitchen", "AZ-032", "Pressure Cooker (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "97e47512f89e79818d988d078dc90410", "Thomas Jentzsch", "", "Missile Control - Amiga Mouse Hack v1.15 (NTSC) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "97f4da9f1031486f4e588f1e53572e53", "SpiceWare - Darrell Spice Jr.", "", "Draconian", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "9813b9e4b8a6fd919c86a40c6bda8c93", "Atari", "CX26177", "Ikari Warriors (1989) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9831efc7f4cb8ffb4df0082bab2f07a3", "Activision, Steve Cartwright - Ariola", "EAX-031, EAX-031-04B - 711 031-717", "Frostbite (1983) (Activision) (PAL) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9848b5ef7a0c02fe808b920a2ac566d2", "Skyworks Technology Inc.", "", "Baseball (2002) (Skyworks)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9853089672116117258097dbbdb939b7", "Hozer Video Games", "", "Gunfight 2600 - Cowboy Hair (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "98555b95cb38e0e0b22b482b2b60a5b6", "", "", "Spinning Fireball (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "98ba601a60172cb46c5bf9a962fd5b1f", "", "", "Gorilla Kong (Hack)", "Hack of Donkey Kong", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "98ccd15345b1aee6caf51e05955f0261", "Retroactive", "", "Qb (V2.03) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "98e5e4d5c4dd9a986d30fd62bd2f75ae", "", "", "Air-Sea Battle (Unknown) (Hack) (4K)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "98e6e34af45a0664597972c3bb31180f", "", "", "Space Instigators (V1.7) (17-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "98e7caaab8ec237558378d2776c66616", "Bradford W. Mott", "", "HMOVE Test (Bradford W. Mott) (1998) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "98ea10c47c13f1b3306c7b13db304865", "", "", "Jam Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "98ec0fa4199b9c01f7b8fa3732e43372", "Activision, David Crane", "AX-018, AX-018-04", "Pitfall! (1982) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "98ef1593624b409b9fb83a1c272a0aa7", "CCE", "C-831", "Cosmic Ark (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "98f63949e656ff309cefa672146dc1b8", "Atari - Axlon, John Vifian", "CX26168", "Off the Wall (1989) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "98fa3ad778a668a79449350de4b3b95b", "Thomas Jentzsch", "", "Thrust (V1.1) (2000) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9905f9f4706223dadee84f6867ede8e3", "HES", "", "Challenge (HES) (PAL)", "Surfer's Paradise if right difficulty = 'A'", "", "", "0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9912d06eea42200a198dd3e2be18c601", "Imagic, Michael Greene", "IA3312", "No Escape! (1982) (Imagic) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "991d57bbcd529ad62925098e0aec1241", "", "", "Gunfight 2600 - The Final Kernel (MP) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9945a22f60bbaf6d04a8d73b3cf3db75", "Activision, Dan Kitchen", "EAX-039-04B, EAX-039-04I", "Kung-Fu Master (1987) (Activision) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9947f1ebabb56fd075a96c6d37351efa", "CBS Electronics", "4L 2737 0000", "Omega Race (1983) (CBS Electronics)", "Set right difficulty to 'A' for BoosterGrip in both ports", "", "", "", "", "", "A", "", "", "BOOSTERGRIP", "", "", "BOOSTERGRIP", "", "", "", "", "", "", "", "", "", "" },
+  { "9962034ea7b3d4a905d0991804670087", "", "", "Grid Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9989f974c3cf9c641db6c8a70a2a2267", "Eckhard Stolberg", "", "Colours Selector (Eckhard Stolberg)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "99a24d7bb31d49b720b422550b32c35f", "", "", "Hangman Ghost Biglist1 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "99ac89241365b692255ba95d745edd91", "Atari, Frank Hausman, Mimi Nyden, Steve Woita", "CX2686", "Quadrun (18-03-1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "99f7c6c26046bbe95f1c604b25da8360", "SnailSoft", "", "Comitoid beta 2 (SnailSoft)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9a01115206f32eb0b539c7e5a47ccafa", "Atari, Jerome Domurat, Steve Woita", "CX2699", "Taz (07-15-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9a165c39af3f050fdee6583fdfcdc9be", "Zirok", "", "Mario Bros. (Zirok)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9a21fba9ee9794e0fadd7c7eb6be4e12", "Atari - Imagineering, Dan Kitchen", "CX26177", "Ikari Warriors (1991) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9a25b3cfe2bbb847b66a97282200cca2", "Atari, Brad Stewart - Sears", "CX2622 - 6-99813, 49-75107", "Breakout (1978) (Atari) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 60", "", "", "", "" },
+  { "9a4274409216ff09ecde799f2a56ac73", "CCE", "C-801", "Mr. Postman (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9ab72d3fd2cc1a0c9adb504502579037", "Epyx, Steven A. Baker, Peter Engelbrite", "80561-00286", "California Games (1987) (Epyx)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9ad362179c2eea4ea115c7640b4b003e", "", "", "Barnstorming (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "NTSC50", "", "", "" },
+  { "9ad36e699ef6f45d9eb6c4cf90475c9f", "Imagic, Dennis Koble", "720103-1A, 720103-1B, IA3203, IX-010-04", "Atlantis (1982) (Imagic)", "AKA Lost City of Atlantis", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9aeb5206c5bf974892a9cc59f1478db3", "Activision, Steve Cartwright", "AX-013", "Barnstorming (1982) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9af615951e9719df2244bc77fc50cb95", "Dactari - Milmar", "", "Defender (Dactari - Milmar)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9afdfe1cff7f37f1c971fe3f0c900606", "Funvision - Fund. International Co.", "", "Plug Attack (Funvision)", "AKA Plaque Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9b150a42fc788960fbb4cbe250259ee2", "Kroko", "", "3E Bankswitch Test (TIA @ $40)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9b21d8fc78cc4308990d99a4d906ec52", "CCE", "C-838", "Immies & Aggies (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9b246683f44c963a50e41d6b485bee77", "", "", "Boring (PAL) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9bb136b62521c67ac893213e01dd338f", "Xonox - Beck-Tech", "6210, 7210, 06003. 99001", "Spike's Peak (1983) (Xonox) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9bd4e0d5f28ba6da417c26649171f8e4", "", "", "Hangman Pac-Man Original Words (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9be58a14e055b0e7581fc4d6c2f6b31d", "", "", "Adventure (Color Scrolling) (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9c27ef3bd01c611cdb80182a59463a82", "Arcadia Corporation, Kevin Norman", "AR-4103", "Killer Satellites (1983) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9c40bf810f761ffc9c1b69c4647a8b84", "", "", "2 in 1 - Frostbite, River Raid (Unknown)", "", "", "", "", "2IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9c6d65bd3b477aace0376f705b354d68", "", "", "RPG Kernal (18-04-2003) (Paul Slocum) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "9c6faa4ff7f2ae549bbcb14f582b70e4", "U.S. Games Corporation, Garry Kitchen, Paul Willson - Vidtec", "VC1002", "Sneak 'n Peek (1982) (U.S. Games)", "AKA Hide 'n Seek", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9c6fd6ed3599978ab7b6f900484b9be6", "Andrew Wallace", "", "Laseresal 2002 (PAL60) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9c729017dd2f9ccbadcb511187f80e6b", "", "", "J-Pac (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9c7fa3cfcaaafb4e6daf1e2517d43d88", "", "", "PIEROXM Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9ca2deb61318eba4fb784d4bf7441d8b", "", "", "Purple Bar Demo 2 (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9cbb07f1993a027bc2f87d5205457ec9", "", "", "Eckhard Stolberg's Scrolling Text Demo 1 (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9d0befa555f003069a21d2f6847ad962", "Atari - GCC, Dave Payne", "CX2669", "Vanguard (1982) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9d1556ae5890398be7e3d57449774b40", "Activision, David Crane", "AG-001", "Dragster (1980) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9d2938eb2b17bb73e9a79bbc06053506", "Imagic, Michael Greene", "EIZ-002-04I", "Wing War (1983) (Imagic) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9d2f05d0fe8b2dfcf770b02eda066fc1", "", "", "Push (V0.06) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9d33d31fb1de58c5460d8a67b57b36da", "", "", "Star Voyager (Genesis)", "Genesis controller (C is secondary lasers)", "Hack of Star Voyager", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9d37a1be4a6e898026414b8fee2fc826", "M Network - INTV - APh Technological Consulting, David Rolfe", "MT5665", "Super Challenge Baseball (1982) (M Network)", "AKA Big League Baseball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9d4bc7c6fe9a7c8c4aa24a237c340adb", "Dennis Debro", "", "Climber 5 (16-04-2003) (Dennis Debro)", "For Philly Classic 4", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9d522a3759aa855668e75962c84546f7", "Atari, Tom Rudadahl", "CX2634, CX2634P", "Golf (1980) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9d7f04618bb4043f531d087e3aaa7ac8", "Parker Brothers, Larry Gelberg, Gary Goltz", "PB5065", "Star Wars - Ewok Adventure (1983) (Parker Bros) (Prototype) (PAL) (16K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9de0d45731f90a0a922ab09228510393", "20th Century Fox Video Games - Sirius, Mark Turmell", "11003", "Fast Eddie (1982) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9dec0be14d899e1aac4337acef5ab94a", "CommaVid, John Bronstein", "CM-003", "Cosmic Swarm (1982) (CommaVid) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "9e01f7f95cb8596765e03b9a36e8e33c", "Atari - CCW, Michael Callahan, Preston Stuart", "CX26103", "Alpha Beam with Ernie (1983) (Atari)", "Uses Keypad Controllers", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9e135f5dce61e3435314f5cddb33752f", "Fabrizio Zavagli", "", "Space Treat Deluxe (2003)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9e192601829f5f5c2d3b51f8ae25dbe5", "PlayAround - J.H.M.", "201", "Cathouse Blues (1982) (PlayAround)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "9e2c7299c69b602443d327c7dad51cbf", "Charles Morgan", "", "Xaxyrax Road (Charles Morgan) (Hack)", "Hack of Freeway", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9e437229136f1c5e6ef4c5f36178ed18", "Funvision - Fund. International Co.", "", "Grand Prize (Funvision)", "AKA Enduro", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9e5007131695621d06902ab3c960622a", "Sega", "", "Tac Scan (1983) (Sega) [h1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 60", "", "", "YES", "" },
+  { "9e792a59f8795664cbaaff1ba152d731", "", "", "Bullet Demo (20-12-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9e904e2eaa471c050c491289b8b80f60", "", "", "How to Draw a Playfield II (1997) (Erik Mooney) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9ea8ed9dec03082973244a080941e58a", "Eric Mooney, Piero Cavina", "", "INV+", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9ec1b259a1bcffa63042a3c2b3b90f0a", "Activision, David Crane", "AG-008", "Laser Blast (1981) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9eca521db1959156a115dee85a405194", "", "", "Fu Kung! (V0.08) (2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9ed0f2aa226c34d4f55f661442e8f22a", "", "", "Nuts (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9eeb40f04a27efb1c68ba1d25e606607", "Kyle Pittman", "", "Rambo II (2003) (Kyle Pittman) (Hack)", "Hack of Double Dragon", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9efa877a98dd5a075e058214da428abb", "Hozer Video Games", "", "SCSIcide (1.32) (Hozer Video Games)", "Uses the Paddle Controllers", "New Release", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "", "" },
+  { "9efb4e1a15a6cdd286e4bcd7cd94b7b8", "20th Century Fox Video Games, John W.S. Marvin", "", "Planet of the Apes (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9f2d58dce1b81c6ba201ed103507c025", "", "", "Fu Kung! (V0.02) (2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9f48eeb47836cf145a15771775f0767a", "Atari, Warren Robinett", "CX2620", "Basic Programming (1979) (Atari)", "Uses Keypad Controllers", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "9f5096a6f1a5049df87798eb59707583", "20th Century Fox Video Games, Mark Klein", "11036", "Entity, The (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9f52271759f8a2004d207b2247ae0bb3", "Parker Brothers", "PB5820", "Mr. Do!'s Castle (03-12-84) (Parker Bros) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "9f59eddf9ba91a7d93bce7ee4b7693bc", "Thomas Jentzsch", "", "Montezuma's Revenge (Thomas Jentzsch) (PAL60)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9f8fad4badcd7be61bbd2bcaeef3c58f", "Parker Brothers, Charlie Heath", "PB5330", "Reactor (1983) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "9f901509f0474bf9760e6ebd80e629cd", "Atari, Bob Whitehead - Sears", "CX2623 - 6-99819, 49-75108, 49-75125", "Home Run (1978) (Atari) (4K)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9f93734c68f6479eb022cab40814142e", "", "", "Push (V0.07) (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9f982421b9b4320ede00fe4aa2e812f4", "Atari, Omegamatrix", "", "Super Breakout Menu (2020) (Hack)", "Hack of Super Breakout", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" },
+  { "9f9ee0f60c119c831e80694b6678ca1a", "Jeffry Johnston", "", "Radial Pong - Version 8 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9fa0c664b157a0c27d10319dbbca812c", "Chris Walton, Justin Hairgrove, Tony Morse", "", "Hunchy II (2005)", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "9fc2d1627dcdd8925f4c042e38eb0bc9", "Atari - GCC, John Allred, Mike Feinstein", "CX2688, CX2688P", "Jungle Hunt (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "E68E28752D3C54EDD3CCDA42C27E320C", "Xonox - K-Tel Software, Anthony R. Henderson", "99007, 6240", "Tomarc the Barbarian (1983) (Xonox)", "Genesis controller (B is jump and throw, C switches between players)", "Hack of Tomarc the Barbarian", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a0028f057d496f22b549fd8deecc6f78", "Joe Grand", "", "SCSIcide Pre-release 6 (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a00ec89d22fcc0c1a85bb542ddcb1178", "CCE", "C-1012", "Phoenix (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a00ee0aed5c8979add4c170f5322c706", "Barry Laws Jr.", "", "Egghead (Barry Laws Jr.) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a0185c06297b2818f786d11a3f9e42c3", "", "", "International Soccer (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a025a8f83a42a4d6d46c4887e799bfac", "Hozer Video Games", "", "Gunfight 2600 - Descissions had to be made (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a0297c4788f9e91d43e522f4c561b4ad", "Atari - CCW, Gary Stark", "CX26102", "Cookie Monster Munch (1983) (Atari) (PAL)", "Uses Kids/Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" },
+  { "a0563dd6d8215c38c488fbbd61435626", "", "", "Ship Demo (V 1501) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a0675883f9b09a3595ddd66a6f5d3498", "Telegames - VSS", "6057 A227", "Quest for Quintana Roo (1988) (Telegames)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a075ad332942740c386f4c3814925ece", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (2 of 4) (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a0d502dc8b90b1d7daa5f6effb10d349", "", "", "Demo Image Series #5 - Sam (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a0e2d310e3e98646268200c8f0f08f46", "Atari, Ed Logg, Carol Shaw", "CX2639, CX2639P", "Othello (1981) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a100eff2d7ae61ca2b8e65baf7e2aae8", "David Marli", "", "Muncher (David Marli) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a11099b6ec24e4b00b8795744fb12005", "Activision - Bobco, Robert C. Polaro", "EAK-049-04B", "Rampage! (1989) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a1403fef01641dcd3980cac9f24d63f9", "Dactari - Milmar", "", "Atlantis (Dactari - Milmar)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a14d8a388083c60283e00592b18d4c6c", "", "", "Tunnel Demo (28-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a15b5831a1fab52e4c416068c85ec011", "Hozer Video Games", "", "Gunfight 2600 - The Good, The Bad, The Ugly (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a174cece06b3abc0aec3516913cdf9cc", "Sears Tele-Games, Jim Huether", "CX2614 - 49-75126", "Steeplechase (1980) (Sears) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a1770ef47146ab7b12e2c4beccd68806", "Digitel", "", "Kaystone Kapers (1983) (Digitel)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a184846d8904396830951217b47d13d9", "Activision, Dan Kitchen", "AX-029", "Crackpots (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a189f280521f4e5224d345efb4e75506", "Atari - Thomas Jentzsch", "", "Obelix (1983) (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a1bcbe0bfe6570da2661fc4de2f74e8a", "Imagic - Advanced Program Technology, Rob Fulop", "", "Actionauts (Microbots) (1984-2008) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a1ca372388b6465a693e4626cc98b865", "Quelle", "176.543 7", "Der Vielfrass (1983) (Quelle) (PAL)", "AKA Fast Food", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a1ead9c181d67859aa93c44e40f1709c", "American Videogame - Dunhill Electronics, Darrell Wagner, Todd Clark Holm, John Simonds", "", "Tax Avoiders (1986) (American Videogame)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a1f9159121142d42e63e6fb807d337aa", "Quelle - Otto Versand", "700.223 1 - 781627", "Der moderne Ritter (1983) (Quelle) (PAL)", "AKA Fast Eddie", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a204cd4fb1944c86e800120706512a64", "Coleco, Rob Harris", "2511", "Smurfs Save the Day (1983) (Coleco)", "Uses the Kid Vid Controller", "", "", "", "", "", "", "", "", "", "", "", "KIDVID", "", "", "", "", "", "", "", "", "", "" },
+  { "a20b7abbcdf90fbc29ac0fafa195bd12", "Quelle - Otto Versand", "719.383 2 - 649635, 781393, 781784, 986404", "Motocross (1983) (Quelle) (PAL)", "AKA Motorcross", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a20d931a8fddcd6f6116ed21ff5c4832", "Apollo - Games by Apollo, Ed Salvo, Byron Parks", "AP-2003", "Racquetball (1982) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "a2170318a8ef4b50a1b1d38567c220d6", "Amiga - Video Soft", "3125", "Surf's Up (1983) (Amiga) (Prototype) [a1]", "Uses the Joyboard controller", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a2276822c772f72073a8a40a72a1ca52", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Mouse Hack v1.1 (NTSC) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a2424c1a0c783d7585d701b1c71b5fdc", "", "", "Video Pinball (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a25bb76e9e773117e567fd4300b1bb23", "", "", "Interleaved ChronoColour Demo (NTSC) (05-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a28d872fc50fa6b64eb35981d0f4bb8d", "Atari, Larry Kaplan - Sears", "CX2628 - 6-99842, 49-75117", "Bowling (1979) (Atari) (4K)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a29df35557f31dfea2e2ae4609c6ebb7", "Atari", "", "Circus Atari (1980) (Atari) (Joystick)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a29fc854838e08c247553a7d883dd65b", "Activision, Steve Cartwright", "AX-013", "Barnstorming (1982) (Activision) (16K)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a2a384d3a16d5be50afd12906f146827", "Bit Corporation", "R320", "Flash Gordon (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a2aae759e4e76f85c8afec3b86529317", "", "", "Boom Bang (Unknown)", "AKA Crackpots", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a2d7cc2e5419a9e4ab91fdb26339b726", "Omegamatrix", "", "Star Wars Arcade (Atari Mouse) (Y Inverted) (PAL60) v4 (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a2de0fc85548871279ed2a3c1325c13e", "George Veeder", "", "Cat and Mouse (George Veeder) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a2eb84cfeed55acd7fece7fefdc83fbb", "", "", "Kool Aid Man (Fixed) (15-11-2002) (CT)", "HMOVE handling fixed in this version", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a2f296ea2d6d4b59979bac5dfbf4edf0", "", "", "Warring Worms (28-01-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a2f9e3b6aaa23b6dc06099cdd5b51b31", "Nukey Shay", "", "Montezuma's Revenge (Genesis) (PAL60) (F6_Conversion)", "Genesis controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a302b922a8dbec47743f28b7f91d4cd8", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (Preview) (1982) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a30ece6dc4787e474fbc4090512838dc", "Zellers", "", "Circus (Zellers)", "AKA Circus Atari", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a310494ad5ba2b5b221a30d7180a0336", "", "", "Demo Image Series #6 - Mario (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a336beac1f0a835614200ecd9c41fd70", "Atari, Christopher H. Omarzu, Robert Vieira", "CX26121", "Zoo Keeper Sounds (1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a34560841e0878c7b14cc65f79f6967d", "Multivision, Michael Case", "", "Harem (1982) (Multivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a3486c0b8110d9d4b1db5d8a280723c6", "Atari, Alan J. Murphy, Robert C. Polaro", "CX26100", "Bugs Bunny (08-04-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a35d47898b2b16ec641d1dfa8a45c2b7", "Activision, Steve Cartwright", "AX-017, AX-017-04", "MegaMania (1982) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a3873d7c544af459f40d58dfcfb78887", "", "", "Tennis (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a3b9d2be822eab07e7f4b10593fb5eaa", "", "", "GREGXM Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a3c1c70024d7aabb41381adbfb6d3b25", "Telesys, Alex Leavens", "1005", "Stargunner (1983) (Telesys)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a3d7c299fbcd7b637898ee0fdcfc47fc", "Arcadia Corporation, Scott Nelson", "AR-4300", "Fireball (Preview) (1982) (Arcadia) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" },
+  { "a3f2a0fcf74bbc5fa763b0ee979b05b1", "Quelle", "873.790 0", "Eishockey-Fieber (1983) (Quelle) (PAL)", "AKA Ice Hockey", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a3f8aebb38182749cb8da85cfbc63d7c", "", "", "Tennis (208 in 1) (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a3fee8ce15525ea00d45a06f04c215d1", "Aaron Curtis", "", "AStar (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a406d2f6d84e61d842f4cb13b2b1cfa7", "Tigervision, John Harris - Teldec", "7-002", "Jawbreaker (1982) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a412c8577b2d57b09185ae51739ac54f", "Arcadia Corporation, Dennis Caswell", "AR-4000", "Phaser Patrol (1982) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "a41450333f8dd0e96e5e9f0af3770ae9", "", "", "Basic Math (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a422194290c64ef9d444da9d6a207807", "M Network - APh Technological Consulting, Hal Finney", "MT5667", "Dark Cavern (1982) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a428068d3e51498907d97cec40000515", "Bit Corporation", "R320", "Sky Alien (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a47878a760f5fa3aa99f95c3fdc70a0b", "", "", "Demo Image Series #5 - Baboon (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a4790224bd5afabd53cbe93e46a7f241", "Activision, Bob Whitehead", "AG-019", "Sky Jinks (1982) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a47e26096de6f6487bf5dd2d1cced294", "Atari", "CX2643", "Codebreaker (1978) (Atari) (PAL)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a484638990de7b12c62947c79dafa4c6", "Thomas Jentzsch", "", "Marble Craze - Atari Mouse Hack v1.0 (PAL60) (TJ)", "Uses Atari Mouse Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a499d720e7ee35c62424de882a3351b6", "SEGA - Beck-Tech, Steve Beck, Phat Ho", "009-01", "Up 'n Down (1984) (SEGA)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a4aa7630e4c0ad7ebb9837d2d81de801", "", "", "Atari 2600 Invaders (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a4ab331e8768eafdc20ce8b0411ff77a", "", "", "Demo Image Series #1 - Sam (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a4b9423877a0b86ca35b52ca3c994ac5", "CCE", "C-805", "Sea Monster (1983) (CCE)", "O Monstro Marinho", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a4b99aa5ed85cfdb7d101923147de035", "Jim Goebel", "", "Pac-Law (Jim Goebel) (Hack)", "Hack of Outlaw", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a4c08c4994eb9d24fb78be1793e82e26", "Activision, Alan Miller", "AX-012, CAX-012, AX-012-04", "Ice Hockey (1981) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a4d026a5c200ef98518ebb77719fe8dc", "Kyle Pittman", "", "SpongeBob SquarePants (2003) (Kyle Pittman) (Hack)", "Hack of Revenge of the Beefsteak Tomatoes", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a4e885726af9d97b12bb5a36792eab63", "Xonox - K-Tel Software - Beck-Tech, Steve Beck", "6210, 7210, 06003. 99001", "Spike's Peak (1983) (Xonox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a4ecb54f877cd94515527b11e698608c", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX26119", "Saboteur (12-20-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a4f1cea2c8479284e2a2292f8d51b5fa", "", "", "Gunfight 2600 - The Final Kernel Part 2 (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a4ff39d513b993159911efe01ac12eba", "Atari - GCC, John Allred, Douglas B. Macrae, Betty Ryan Tylko", "CX2694", "Pole Position (1983) (Atari)", "AKA RealSports Driving", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a511f7ee13e4b35512f9217a677b4028", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX2674", "E.T. - The Extra-Terrestrial (1982) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a5262fe6d01d6a1253692682a47f79dd", "", "", "JKH Text Scrolling Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a537879d8e82e1061d3ad800479d3b84", "Andrew Wallace", "", "Brooni (2001) (Andrew Wallace) (PD) (PAL)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a539b9fd1ba57e46442b3e9351e6383b", "", "", "River Raid (208 in 1) (Unknown) (PAL) (Hack) [a]", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a56b642a3d3ab9bbeee63cd44eb73216", "Carrere Video - JWDA, Sylvia Day, Todd Marshall, Robin McDaniel, Henry Will IV - Teldec - Prism", "USC2001", "Gopher (1983) (Carrere Video) (PAL)", "AKA Vossicht Whlmaus!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a5855d73d304d83ef07dde03e379619f", "Atari, David Crane", "", "Boggle (08-07-1978) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "a58b11148c18d85e4c2aef4ff46ade67", "", "", "Video Chess (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a591b5e8587aae0d984a0f6fe2cc7d1c", "", "", "Globe Trotter Demo (24-03-2003) (Weston)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a5b7f420ca6cc1384da0fed523920d8e", "", "", "Adventure (New Graphics) (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a5c96b046d5f8b7c96daaa12f925bef8", "Activision, Alan Miller - Ariola", "EAG-007, EAG-007-04I, PAG-007 - 711 007-720", "Tennis (1981) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a5e9ed3033fb2836e80aa7a420376788", "Atari, Carla Meninsky", "CX2637, CX2637P", "Dodge 'Em (1980) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a60598ad7ee9c5ccad42d5b0df1570a1", "Atari, Alan Miller", "CX26163P", "Surround (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a6127f470306eed359d85eb4a9cf3c96", "Atari, Michael Kosaka, Peter C. Niday, Robert Vieira", "CX26110", "Crystal Castles (1984) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a6239810564638de7e4c54e66b3014e4", "Personal Games Company, Robert Anthony Tokar", "", "Birthday Mania (1984) (Personal Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a62e3e19280ff958407e05ca0a2d5ec7", "", "", "Hangman Ghost Biglist3 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a6737c81542a99ee71cb5f5ff14703d9", "", "", "Scrolling Playfield 3 (Junkosoft) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a69f5b1761a8a11c98e706ec7204937f", "", "", "Pharaoh's Curse (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "a6ed8d72ed691fd3aad5b6974fa17978", "Bit Corporation", "R320", "Bank Heist (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a74689a08746a667a299b0507e1e6dd9", "Starpath Corporation, Stephen H. Landrum", "9 AR-4105", "Official Frogger, The (1983) (Starpath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a7523db9a33e9417637be0e71fa4377c", "Videospielkassette - Ariola", "PGP238", "Gangster (Ariola) (PAL)", "AKA Outlaw", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a7673809068062106db8e9d10b56a5b3", "Atari, Jerome Domurat, Andrew Fuchs, Dave Staugas, Robert Vieira", "CX26118, CX26118P", "Millipede (1984) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a779b9fa02c62d00d7c31ed51268f18a", "Arcadia Corporation, Brian McGhie", "AR-4104", "Rabbit Transit (1983) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a7a58e9291aefa1064e933071f60d4ef", "Arcadia Corporation, Dennis Caswell", "1 AR-4000, AR-4100", "Phaser Patrol (1982) (Arcadia) (Prototype) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "a7b584937911d60c120677fe0d47f36f", "M Network - INTV - APh Technological Consulting, Hal Finney", "MT5661", "Armor Ambush (1982) (M Network)", "AKA Tank Battle", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a7b96a8150600b3e800a4689c3ec60a2", "Atari, Mike Lorenzen - Sears", "CX2630 - 49-75122", "Circus Atari (1980) (Atari)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 55", "", "", "", "" },
+  { "a7bf8353f77caca407ef85c2698fdff2", "Atari, Suki Lee - Sears", "CX2658 - 49-75128", "Math Gran Prix (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a7cf2b9afdbb3a161bf418dbcf0321dc", "Barry Laws Jr.", "", "Attack Of The Mutant Space Urchins (2002) (Barry Laws Jr.) (Hack)", "Hack of Alien", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "a7d2e9408bb7cd70139ecced407ff238", "Atari - Roklan, Joe Gaucher, Alex Leavens", "CX2683", "Crazy Climber (1983) (Atari) (Prototype) [a1]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a7ed7dc5cbc901388afa59030fb11d26", "Atari, Warren Robinett", "CX2606, CX2606P", "Slot Racers (1978) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a7ef44ccb5b9000caf02df3e6da71a92", "Atari, Ian Shepard - Sears", "CX2604 - 6-99812, 49-75106", "Space War (1978) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a8101cb667e50a46165c6fb48c608b6b", "", "", "Kung Fu Sprite Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "a81697b0c8bbc338ae4d0046ede0646b", "CCE", "", "Gravitar (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a81b29177f258494b499fbac69789cef", "Greg Thompson", "", "Console Wars (Greg Thompson) (Hack)", "Hack of Space Jockey", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a83b070b485cf1fb4d5a48da153fdf1a", "Apollo", "AP-2011", "Pompeii (1983) (Apollo) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a8435ec570141de5d833c4abec499e55", "", "", "Happy Birthday Demo (2001) (Dennis Debro) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a8633050a686270fcf6c0cc4dcbad630", "Zirok", "", "Phoenix (Zirok)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a867b76098786c4091dba2fcee5084c3", "", "", "Dragrace (Hack)", "Hack of Dragster", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a875f0a919129b4f1b5103ddd200d2fe", "Atari, Dan Hitchens. Mimi Nyden", "CX2656", "SwordQuest - EarthWorld (1982) (Atari) (PAL)", "AKA Adventure I, SwordQuest I - EarthWorld", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a8916734ff8c64ec3342f4c73fd5b57d", "Atari", "", "Stand Alone Test Cart (1982) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a89a3e0547d6887279c34aba4b17a560", "M Network, Steve Crandall, Patricia Lewis Du Long", "MT4646", "Rocky & Bullwinkle (1983) (Mattel) (Prototype)", "", "Prototype", "", "", "4K", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a8a703e073183a89c94d4d99b9661b7f", "Franklin Cruz", "", "Spice Invaders (Franklin Cruz) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a8b3ea6836b99bea77c8f603cf1ea187", "CCE", "C-861", "Boxing (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a8c447efbec3a2b5d08b05a09999bd92", "", "", "MegaCart Menu", "", "", "", "", "", "", "", "", "", "JOYSTICK", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "" },
+  { "a8c48b4e0bf35fe97cc84fdd2c507f78", "Puzzy - Bit Corporation", "PG201", "Seamonster (1982) (Puzzy)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a8d0a4a77cd71ac601bd71df5a060e4c", "", "", "Space Shuttle (1983) (Activision) [t2] (Fuel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a8d4a9500b18b0a067a1f272f869e094", "", "", "Red And White Checkerboard Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a8e49d7e24ce293629ca29614862821b", "", "", "Enduro (Genesis)", "Genesis controller (B is acceleration, C is brakes)", "Hack of Enduro", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a91d0858a52de3a2e6468437212d93e8", "", "", "Q-bert (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a936d80083e99d48752ad15c2b5f7c96", "", "", "Room of Doom (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "a93e8ea1f565c3c1e86b708cf0dc2fa9", "Jess Ragan", "", "Kabul! (Jess Ragan) (Hack)", "Hack of Kaboom!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
+  { "a94528ae05dd051894e945d4d2349b3b", "Genus", "", "River Raid (Genus)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a94b8ca630f467b574b614808d813919", "HES", "773-883", "2 Pak Special - Space Voyage, Fire Alert (1992) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a9531c763077464307086ec9a1fd057d", "Atari, John Dunn - Sears", "CX2631 - 49-75152", "Superman (1979) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a957dbe7d85ea89133346ad56fbda03f", "Atari, Brad Stewart", "CX2649, CX2649P", "Asteroids (1981) (Atari) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "a97733b0852ee3096300102cb0689175", "CCE", "C-834", "Fast Eddie (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a9784c24cddb33bd0d14442b97784f3d", "Thomas Jentzsch", "", "Omega Race DC (2003) (TJ) (Omega Race Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a98b649912b6ca19eaf5c2d2faf38562", "", "", "This Planet Sucks (Greg Troutman) (PAL) [!]", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a995b6cbdb1f0433abc74050808590e6", "Imagic, Rob Fulop, Bob Smith", "720106-1A, IA3600", "Riddle of the Sphinx (1982) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a9cb638cd2cb2e8e0643d7a67db4281c", "M Network - INTV - APh Technological Consulting, Larry Zwick", "MT5861", "Air Raiders (1983) (M Network)", "AKA Air Battle", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a9d9e19d0c89fb31780b5d63e1f8c6a4", "AtariAge, Chris Spry", "CX26201", "Zippy the Porcupine (2014) (Sprybug) (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "a9e3c23599c0d77151602f8e31daf879", "", "", "Kung Fu Master (Genesis)", "Genesis controller (C is extra kick modes)", "Hack of Kung Fu Master", "", "", "", "", "", "", "", "GENESIS", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "aa1c41f86ec44c0a44eb64c332ce08af", "Spectravideo, David Lubar", "SA-218", "Bumper Bash (1983) (Spectravideo)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "PADDLES", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "aa2c4b32656bde9a75042a4d158583e1", "", "", "Oystron X (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "aa5cfe3b20395aba1d479135943ad85c", "", "", "Defender (Hack) (Unknown)", "", "Hack of Defender", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "aa7bb54d2c189a31bb1fa20099e42859", "CBS Electronics, Ed English", "4L4478", "Mr. Do! (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "aa8c75d6f99548309949916ad6cf33bc", "Bob Montgomery (aka vdub_bobby)", "", "Squish 'Em (2007)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "aa8e4b2cb8a78ffe6b20580033f4dec9", "", "", "Bitmap Demo (13-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "aaac0d277eda054861e613c59c2e4ff2", "JWDA, Todd Marshall", "", "Music Demo (JWDA)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "aab840db22075aa0f6a6b83a597f8890", "Home Vision, R.J.P.G. - Gem International Corp. - VDI", "VCS83124", "Racing Car (1983) (Home Vision) (PAL)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "aad61898633f470ce528e3d7ef3d0adb", "Commavid, Ben Burch", "CM-010", "Rush Hour (1983) (Commavid) (Prototype) [a1]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "aad91be0bf78d33d29758876d999848a", "Activision, David Crane", "AX-018, AX-018-04", "Pitfall! (1981) (Activision) (Prototype)", "Pitfall Harry's Jungle Adventure (Jungle Runner)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "aaea37b65db9e492798f0105a6915e96", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix - Tug of War (2 of 3) (1983) (Arcadia)", "Uses Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "02", "", "", "", "" },
+  { "aafc79ffc32c4c9b2d73c8ada7602cfe", "", "", "Planet Patrol (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ab10f2974dee73dab4579f0cab35fca6", "ITT Family Games", "", "Wilma Wanderer (1983) (ITT Family Games) (PAL)", "AKA Lilly Adventure", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ab2cfcaad3daaf673b2b14fdbb8dac33", "M Network - INTV, David Akers, Joe King, Patricia Lewis Du Long, Jeff Ratcliff", "MT7045", "Bump 'n' Jump (1983) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ab2ea35dcc1098c87455bb8210b018cf", "", "", "Fu Kung! (V0.04 Single Line Resolution) (10-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ab301d3d7f2f4fe3fdd8a3540b7a74f5", "Jone Yuan Telephonic Enterprise Co", "", "IQ 180 (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ab434f4c942d6472e75d5490cc4dd128", "HES", "773-875", "2 Pak Special - Hoppy, Alien Force (1992) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ab48c4af46c8b34c3613d210e1206132", "Andrew Davie & Thomas Jentzsch", "", "Boulder Dash - Demo V2 (2014)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ab4ac994865fb16ebb85738316309457", "Atari, Alan Miller - Sears", "CX2624 - 6-99826, 49-75113", "Basketball (1978) (Atari)", "Console ports are swapped", "Common", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ab56f1b2542a05bebc4fbccfc4803a38", "Activision - Imagineering, Dan Kitchen, David Lubar", "AK-048-04", "River Raid II (1988) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ab5bf1ef5e463ad1cbb11b6a33797228", "Imagic, Rob Fulop", "720104-1A, 720104-1B, IA3204", "Cosmic Ark (1982) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ab60ea7b707c58d356cad858eb18db43", "", "", "Tazer (John K. Harvey)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ab8d318da4addd39c65b7f9c408df2a6", "", "", "Star Trek (Genesis)", "Genesis controller (B is phaser, C is warp)", "Hack of Star Trek", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "abb740bea0a6842831b4f53112fb8145", "", "", "Qb (V1.01) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "abb741c83f665d73c86d90a7d9292a9b", "Telegames", "", "Space Attack (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "abc64037ca5d5b04ae8a7eedbca3ed74", "", "", "Green and Yellow Number 1 Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "abe40542e4ff2d1c51aa2bb033f09984", "Absolute Entertainment, David Crane", "EAZ-042-04B, EAZ-042-04I", "Skate Boardin' (1987) (Absolute) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ac05c0e53a5e7009ddd75ed4b99949fc", "Atari, Joe Decuir, Steve Mayer, Larry Wagner - Sears", "CX2601 - 99801, 6-99801, 49-75124", "Combat (1977) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ac0ddbcff34d064009591607746e33b8", "Thomas Jentzsch", "", "Atlantis FH (2003) (TJ) (Hack)", "Hack of Atlantis", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ac26d7d37248d1d8eac5eccacdbef8db", "", "", "Snail Against Squirrel (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ac3dd22dd945724be705ddd2785487c2", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692", "Moon Patrol (06-15-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ac53b83e1b57a601eeae9d3ce1b4a458", "Retroactive", "", "Qb (2.15) (Retroactive) (NTSC)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "ac5f78bae0638cf3f2a0c8d07eb4df69", "", "", "Minesweeper (V.99) (Soren Gust) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ac7c2260378975614192ca2bc3d20e0b", "Activision, David Crane", "AG-930-04, AZ-030", "Decathlon (1983) (Activision)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ac9adbd6de786a242e19d4bec527982b", "Activision, Alan Miller - Ariola", "EAG-012-04I, EAX-012, EAX-012-04B - 711 012-720", "Ice Hockey (1981) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "aca09ffea77174b148b96b205109db4d", "Activision, Alan Miller", "AG-007, CAG-007", "Tennis (1981) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "acaa27d214039d89d7031609aafa55c3", "", "", "Sprite Demo 6 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "acb6787b938079f4e74313a905ec3ceb", "", "", "Chronocolor Donkey Kong (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "acb7750b4d0c4bd34969802a7deb2990", "Parker Brothers, Ed Temple", "PB5310", "Amidar (1982) (Parker Bros)", "", "Uncommon", "", "", "", "A", "A", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "acb962473185d7a652f90ed6591ae13b", "Imagic, Dennis Koble", "IA3203, IX-010-04", "Atlantis (1982) (Imagic) (16K)", "AKA Lost City of Atlantis", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ace319dc4f76548659876741a6690d57", "Atari, Steve Wright", "CX2616", "Pele's Soccer (1981) (Atari)", "AKA Pele's Championship Soccer", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ad2e6bfb3b9b9b36ba8bf493ce764c49", "", "", "2600 Collison Demo 1 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ad42e3ca3144e2159e26be123471bffc", "Atari", "CX26163P", "Human Cannonball (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ad72d616030a17634ff29ce8680d3c4c", "Thomas Jentzsch", "", "Reactor - Atari Trak-Ball Hack v1.3 (PAL60) (Full-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ad7e97c19bd25d5aa3999430845c755b", "", "", "Sprite Demo 5 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ad8072675109d13fdd31a2e0403d5cff", "Funvision - Fund. International Co.", "", "Tank City (Funvision)", "AKA Thunderground", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "adb770ff70e9adf08bbb907a7eccd240", "", "", "Inv Demo 3 (2001) (Erik Mooney) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "adb79f9ac1a633cdd44954e2eac14774", "Digivision", "", "Frostbite (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "adf1afac3bdd7b36d2eda5949f1a0fa3", "Quelle - Otto Versand", "495.463 2 - 746381", "Angriff der Luftflotten (1983) (Quelle) (PAL)", "AKA Paris Attack, M.A.D.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "adfbd2e8a38f96e03751717f7422851d", "Champ Games", "CG-01-N", "Lady Bug (NTSC)", "", "Homebrew", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "ae047e9468bda961d8e9e9d8ff52980f", "", "", "Tunnel Demo (Red Spiral) (30-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ae0d4f3396cb49de0fabdff03cb2756f", "Retroactive", "", "Qb (V2.02) (PAL) (2001) (Retroactive)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "ae10527840a1ac24de43730645ed508d", "Charles Morgan", "", "Planet Invaders (Charles Morgan) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ae18c11e4d7ed2437f0bf5d167c0e96c", "", "", "Multi-Color Demo 3 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ae2f1f69bb38355395c1c75c81acc644", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (12-23-1983) (Parker Bros) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "ae465044dfba287d344ba468820995d7", "", "", "Inca Gold (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ae4be3a36b285c1a1dff202157e2155d", "Spectravideo", "SA-210", "Master Builder (1983) (Spectravideo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ae682886058cd6981c4b8e93e7b019cf", "Retroactive", "", "Qb (V0.12) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "ae6cb335470788b94beb5787976e8818", "", "", "Mortal Kurling (02-01-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ae83541cf4a4c0bce0adccd2c1bf6288", "", "", "Maze 003 Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ae97cf8ed21f4154b4360a3cf6c95c5e", "", "", "Teleterm 2600 (John K. Harvey) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "aeb104f1e7b166bc0cbaca0a968fde51", "", "", "Ms. Pac-Man (1999) (Hack)", "Hack of Ms. Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "aec9b885d0e8b24e871925630884095c", "Amiga - Video Soft", "3125", "Surf's Up (1983) (Amiga) (Prototype)", "Uses the Joyboard controller", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "aed0b7bd64cc384f85fdea33e28daf3b", "Atari, Jim Huether, Alan J. Murphy, Robert C. Polaro", "CX2666", "RealSports Volleyball (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "aed82052f7589df05a3f417bb4e45f0c", "Atari, Warren Robinett - Sears", "CX2606 - 6-99825, 49-75112", "Slot Racers (1978) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "af6ab88d3d7c7417db2b3b3c70b0da0a", "Activision, Larry Kaplan, David Crane", "AG-010, AG-010-04", "Kaboom! (1981) (Activision) (4K)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
+  { "af6f3e9718bccfcd8afb421f96561a34", "Atari, Tod Frye", "CX2695", "Xevious (01-18-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "afb3bc45c6a82739cc82582127cd96e6", "Atari - Sculptured Software, Adam Clayton", "CX26151, CX26151P", "Dungeon (11-22-1985) (Atari) (Prototype)", "Dark Chambers Beta", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "afc194534c1b346609ef05eff6d3cef6", "Jone Yuan Telephonic Enterprise Co", "", "Boxing (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "afd2cf258d51ae4965ee21abba3627ab", "Atari - CCW, Christopher H. Omarzu", "CX26104", "Big Bird's Egg Catch (12-08-1982) (Atari) (Prototype)", "Uses the Keypad Controller", "Prototype", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "afe4eefc7d885c277fc0649507fbcd84", "Atari", "CX26163P", "Ant Party (32 in 1) (1988) (Atari) (PAL)", "AKA Cosmic Swarm", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "afe776db50e3378cd6f29c7cdd79104a", "Thomas Jentzsch", "", "Bobby is Going Home (TJ)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "afe88aae81d99e0947c0cfb687b16251", "Apollo - Games by Apollo", "AP-2006", "Infiltrate (1982) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "aff8cba0f2d2eb239953dd7116894a08", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (3 of 3) (1982) (Starpath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b00088418fc891f3faa3d4ddde6ace94", "", "", "Unknown Title (bin00007 (200102)) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b00a8bc9d7fe7080980a514005cbad13", "K-Tel Vision", "", "Vulture Attack (1982) (K-Tel Vision) (PAL)", "AKA Condor Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b00e8217633e870bf39d948662a52aac", "Konami", "RC 102-X 02", "Marine Wars (1983) (Konami)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b011d8fdc450597c0762c2c0010a9b17", "Thomas Jentzsch", "", "Reactor - Amiga Mouse Hack v1.3 (NTSC) (Half-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b049fc8ac50be7c2f28418817979c637", "Activision - Imagineering, Dan Kitchen, David Lubar", "EAK-048-04, EAK-048-04B", "River Raid II (1988) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b06050f686c6b857d0df1b79fea47bb4", "Activision", "AIZ-001", "Moonsweeper (1988) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "b061e98a4c854a672aadefa233236e51", "Atari, Warren Robinett", "CX2620, CX2620P", "Basic Programming (1979) (Atari) (PAL)", "Uses Keypad Controllers", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "b095009004df341386d22b2a3fae3c81", "", "", "Sub-Scan (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b09b79c9628878be051e89f7f1e77378", "Activision, Larry Kaplan, David Crane - Ariola", "EAG-010, PAG-010 - 711 010-720", "Kaboom! (1981) (Activision) (PAL) (4K)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
+  { "b0a9c6f6c8014c4023e0341ba11ca35e", "The Atari 2600 Connection - John K. Harvey, Tim Duarte", "v75", "Mean Santa (2009) (PAL)", "Released in 2019", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b0ba51723b9330797985808db598fc31", "Atari, Michael Callahan, Preston Stuart", "CX26103", "Alpha Beam with Ernie (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b0c47e426c7f799aee2c40422df8f56a", "", "", "Space Treat (PAL) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b0c9cf89a6d4e612524f4fd48b5bb562", "Atari - GCC", "CX2663", "Combat Two (1982) (Atari) (Prototype)", "AKA Super Combat", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b0e1ee07fbc73493eac5651a52f90f00", "Colin Hughes", "", "Tetris 2600 (Colin Hughes)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "b1276417fb0f79bc52e741bb8f4d8360", "Thomas Jentzsch", "", "Marble Craze - Amiga Mouse Hack v1.0 (NTSC) (TJ)", "Uses Amiga Mouse Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b129d7541cff79ebe33852a83057c524", "Thomas Jentzsch", "", "Marble Craze - Atari Trak-Ball Hack v1.0 (NTSC) (TJ)", "Uses Atari Trak-Ball Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b12a7f63787a6bb08e683837a8ed3f18", "Imagic, Rob Fulop", "720000-200, 720101-1B, 720101-1C, IA3200, IA3200C, IX-006-04", "Demon Attack (1982) (Imagic) [fixed]", "AKA Death from Above", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b1339c56a9ea63122232fe4328373ac5", "Goliath - Hot Shot", "83-215", "Dream Flight (1983) (Goliath) (PAL)", "AKA Nightmare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b1486e12de717013376447ac6f7f3a80", "Spectravideo, Mark Turmell, Quelle", "SA-217, SA-217C - 413.723 8", "Gas Hog - Piraten Schiff (1983) (Spectravideo) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b15026b43c6758609667468434766dd8", "Retroactive", "", "Qb (0.06) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "b16cd9784589219391c839cb68c47b9c", "Video Soft, Jerry Lawson, Dan McElroy", "", "Golf Diagnostic (1983) (Video Soft) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b17b9cc4103844dcda54f77f44acc93a", "Quelle", "377.943 6", "Stopp die Gangster (1983) (Quelle) (PAL)", "AKA Gangster Alley", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b182d9708e00709830caab9cf8205ca0", "Thomas Jentzsch", "", "Reactor - Atari Mouse Hack v1.3 (PAL60) (Half-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b1a6c96e9093352106bc335e96caa154", "Joe Grand", "", "SCSIcide Pre-release 1 (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b1b20536aef4eed9c79dc5804f077862", "", "", "Euchre (NTSC) (09-11-2001) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b1c14b5ac896400cc91c8e5dd67acb59", "", "", "River Raid (208 in 1) (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b1d1e083dc9e7d9a5dc1627869d2ade7", "CCE", "C-1004", "Mario's Bros. (1983) (CCE)", "AKA Mario Bros.", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b1e2d5dc1353af6d56cd2fe7cfe75254", "Atari - Axlon, Steve DeFrisco", "CX26171", "MotoRodeo (1991) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "b1fd0b71de9f6eeb5143a97963674cb6", "", "", "Multi-Color Demo 7 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b227175699e372b8fe10ce243ad6dda5", "Atari, Brad Stewart - Sears", "CX2649, 49-75163", "Asteroids (1981) (Atari) [a1]", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "b23ebf427713dd0198b7ef47dbd07ef4", "Jone Yuan Telephonic Enterprise Co", "", "Sky Diver (Jone Yuan) (4K) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b24f6a5820a4b7763a3d547e3e07441d", "CCE", "C-823", "Demon Attack (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b25841173f058380b1771aacd5e7cdf3", "Bit Corporation", "PG205", "Dancing Plate (1982) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b26506fbf411009e5e3f7365f442960e", "Atari, Alan Miller", "CX2642", "Hunt & Score (1978) (Atari) (PAL) (4K)", "Uses the Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b2737034f974535f5c0c6431ab8caf73", "CBS Electronics, Richard K. Balaska Jr., Andy Frank, Stuart Ross", "4L 2520 5000", "Tunnel Runner (1983) (CBS Electronics)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b2761efb8a11fc59b00a3b9d78022ad6", "Atari, Bob Whitehead - Sears", "CX2651 - 99805, 49-75602", "Blackjack (1977) (Atari) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b290c2b139344fcff5b312c71b9ac3b2", "Atari", "CX26163P", "UFO (32 in 1) (1988) (Atari) (PAL) (4K)", "AKA Space Jockey", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b29359f7de62fed6e6ad4c948f699df8", "Goliath", "3", "Phantom Tank (1983) (Goliath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b2a6f31636b699aeda900f07152bab6e", "", "", "Space Instigators (Public Release 2) (06-01-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b2ab209976354ad4a0e1676fc1fe5a82", "Atari - Axlon, Tod Frye - Heuristica, Agustin Ortiz", "CX26169", "Shooting Arcade (03-07-1989) (Atari) (Prototype) [a3]", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b2d1e63f7f22864096b7b6c154151d55", "Fabrizio Zavagli", "", "Bounce! (17-03-2003) (Fabrizio Zavagli)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "b2d3bcee001cff2bd2d8a21b2cb55109", "Atari - GCC, Mike Feinstein, Kevin Osborn", "CX2691", "Joust (08-09-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "b2d5d200f0af8485413fad957828582a", "Atari - Bobco, Robert C. Polaro", "CX26155P", "Sprint Master (1988) (Atari) (PAL)", "AKA Sprint 88, Sprint 2000", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b2f0d7217147160b2f481954cedf814b", "", "", "Marquee Drawer (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "b3017e397f74efd53caf8fae0a38e3fe", "Retroactive", "", "Qb (2.12) (Retroactive) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "b311ab95e85bc0162308390728a7361d", "Parker Brothers - Roklan, Joe Gaucher", "PB5080", "Gyruss (1984) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "b31dc989f594764eacfa7931cead0050", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (2 of 3) (1983) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b31e9487efc06f18dfc3d7ebadf54416", "Omegamatrix", "", "Star Wars Arcade (Atari Mouse) v4 (PAL60) (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b31f178aa0d569cccac7959f84e0a724", "Atari, Jerome Domurat, Steve Woita", "CX2699", "Taz (07-13-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b3203e383b435f7e43f9492893c7469f", "Gameworld", "133-003", "Sssnake (1983) (Gameworld) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b36040a2f9ecafa73d835d804a572dbf", "Digitel", "", "Pac Man (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b37f0fe822b92ca8f5e330bf62d56ea9", "Xonox - K-Tel Software - Beck-Tech, Steve Beck", "6210, 7210, 06003. 99001", "Spike's Peak (1983) (Xonox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b392964e8b1c9c2bed12246f228011b2", "", "", "Name This Game (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b4030c38a720dd84b84178b6ce1fc749", "M Network - APh Technological Consulting, Kevin Miller", "MT5687", "International Soccer (1982) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b40dea357d41c5408546e4e4d5f27779", "Digivision", "", "Spider Fighter (Digivision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b41fdd4a522e1d5a2721840028684ac2", "", "", "Green and Yellow Number 1 Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "b42df8d92e3118dc594cecd575f515d7", "Mystique - American Multiple Industries", "1003", "Burning Desire (1982) (Mystique) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "b438a6aa9d4b9b8f0b2ddb51323b21e4", "Telegames", "5861 A030", "Bogey Blaster (1988) (Telegames) (PAL)", "AKA Air Raiders", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b451307b8b5e29f1c5f2cf064f6c7227", "", "", "Demo Image Series #6 - Mario (Fixed) (26-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b49331b237c8f11d5f36fe2054a7b92b", "", "", "Condor Attack (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b4a4c87840613f102acb5b3a647d0a67", "", "", "Mobile 48 Sprite Kernel (04-01-2003) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b4daedb43511521db9036d503b3c1b69", "", "", "Sokoban (01-01-2003) (Adam Wozniak) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b4e2fd27d3180f0f4eb1065afc0d7fc9", "Avalon Hill, Jean Baer, Bill 'Rebecca Ann' Heineman, William O. Sheppard", "5002002", "London Blitz (1983) (Avalon Hill)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b4f05e544834d0238a0c263491775edf", "Starpath Corporation, Steve Hales, Stephen H. Landrum", "4 AR-4102", "Suicide Mission (Preview) (1982) (Starpath) (PAL)", "AKA Meteoroids", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "b4f31ea8a6cc9f1fd4d5585a87c3b487", "Mystique - American Multiple Industries, Joel H. Martin", "", "Beat 'Em & Eat 'Em (1982) (Mystique) (PAL)", "Uses the Paddle Controller (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" },
+  { "b4f87ce75f7329c18301a2505fe59cd3", "Videospielkassett - Ariola", "PGP232", "Autorennen (Ariola) (PAL)", "AKA Grand Prix", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b50ae55aac93fbed258bc5a873edd2cb", "Recompile", "", "E.T. The Extra-Terrestrial (Recompile) (Hack)", "www.neocomputer.org/projects/et", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b5110f55ed99d5279f18266d001a8cd5", "Eckhard Stolberg", "", "Auto-mobile Demo (2001) (Eckhard Stolberg)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b56264f738b2eb2c8f7cf5a2a75e5fdc", "Atari - GCC, John Allred, Douglas B. Macrae, Betty Ryan Tylko", "CX2694, CX2694P", "Pole Position (1983) (Atari) (PAL)", "AKA RealSports Driving", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b5657d4c1c732fbb6af150668464247f", "Arcadia Corporation, Stephen H. Landrum", "AR-4400", "Excalibur (Dragonstomper Beta) (1982) (Arcadia) (Prototype)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b59417d083b0be2d49a7d93769880a4b", "Pet Boat", "", "Donkey Kong (1983) (Pet Boat) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b59fd465abf76f64c85652ff29d5952d", "VentureVision, Dan Oliver", "", "Innerspace (1983) (VentureVision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b5a1a189601a785bdb2f02a424080412", "Imagic, Dennis Koble", "720021-1A, IA3410", "Shootin' Gallery (1983) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b5cb9cf6e668ea3f4cc2be00ea70ec3c", "CommaVid, Irwin Gaines - Ariola", "CM-005 - 712 005-720", "Mines of Minos (1982) (CommaVid) (PAL)", "AKA Im Labyrinth des Roboters", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "b5cdbab514ea726a14383cff6db40e26", "Video Gems", "VG-04", "Mission Survive (1983) (Video Gems) (PAL) [a]", "", "", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "b5efe0271d2214e4d5dc798881486884", "Atari - Axlon, Steve DeFrisco", "CX26192", "Klax (06-14-1990) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b6166f15720fdf192932f1f76df5b65d", "Amiga - Video Soft", "3130", "Off Your Rocker (1983) (Amiga) (Prototype)", "Uses the Amiga Joyboard", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b64426e787f04ff23ee629182c168603", "Dynacom", "", "Plaque Attack (1983) (Dynacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b65d4a38d6047735824ee99684f3515e", "Dynacom", "", "MegaBoy (Dynacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b676a9b7094e0345a76ef027091d916b", "Thomas Jentzsch", "", "Mission Survive (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "b6812eaf87127f043e78f91f2028f9f4", "Simage", "", "Eli's Ladder (1984) (Simage)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b6821ac51c4c1dcb283f01be2f047dc1", "Thomas Jentzsch", "", "Rubik's Cube 3D Demo (25-11-2002) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b6960be26bee87d53ba4e2e71cfe772f", "", "", "3-D Corridor (Spiral Words) (31-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b6d52a0cf53ad4216feb04147301f87d", "Imagic, Michael Greene", "720055-1A, IA3312", "No Escape! (1983) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b6e40bce550672e5495a8cdde7075b8b", "Arcadia Corporation, Steve Mundry, Scott Nelson", "AR-4401", "Survival Island (1 of 3) (1983) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b702641d698c60bcdc922dbd8c9dd49c", "Atari, Ian Shepard", "CX26163P", "Space War (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b719ada17771a8d206c7976553825139", "Ron Corcoran", "", "DUP Space Invaders (Ron Corcoran) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b731d35e4ac6b3b47eba5dd0991f452f", "Thomas Jentzsch", "", "Rubik's Cube 3D Demo (Final) (08-01-2003) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b7345220a0c587f3b0c47af33ebe533c", "Quelle", "176.433 1", "Landungskommando (1983) (Quelle) (PAL)", "AKA Strategy X", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b76fbadc8ffb1f83e2ca08b6fb4d6c9f", "Activision, Bob Whitehead", "AG-005, CAG-005, AG-005-04", "Skiing (1980) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b77468d586957d1b7fb4cccda2684f47", "Atari", "CX26163P", "Boxing (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b7903268e235310dc346a164af4c7022", "Thomas Jentzsch", "", "Cat Trax (Thomas Jentzsch) (PAL60)", "NTSC Conversion", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "b79fe32320388a197ac3a0b932cc2189", "Imagic, Bob Smith", "13207, EIZ-001-04I", "Moonsweeper (1983) (Imagic) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "b7a7e34e304e4b7bc565ec01ba33ea27", "Parker Brothers", "PB5820", "Mr. Do!'s Castle (1984) (Parker Bros) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "b7b1d3ce07e75976c43a2dca3866237e", "Atari", "CX26163P", "Freeway Chicken (32 in 1) (1988) (Atari) (PAL) (4K)", "AKA Freeway", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b7d0aae399781b3c18679debda6d32b1", "Thomas Jentzsch", "", "Three.s (v1.02)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b7d7c76e37f372f4e4979b380ed95a58", "AtariAge - Michael Haas", "RC2", "Flappy (2014) (AtariAge) (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b7e459d5416eeb196aaa8e092db14463", "", "", "Push (V0.02) (1998) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b7f184013991823fc02a6557341d2a7a", "", "", "Blue Rod Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b80d50ecee73919a507498d0a4d922ae", "20th Century Fox Video Games - Sirius Software, David Lubar", "11008", "Fantastic Voyage (1982) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b816296311019ab69a21cb9e9e235d12", "Atari, Bob Whitehead - Sears", "CX2652 - 6-99816, 49-75151", "Casino (1979) (Atari)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b822fba8b7c8a97ea4e92aeb2c455ef9", "Dactari", "", "Freeway (Dactari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b83579c4450fcbdf2b108903731fa734", "", "", "Mission 3,000 A.D. (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "b83df1f32b4539c324bdf94851b4db55", "Angelino", "", "One On One by Angelino (Basketball Hack)", "Hack of Basketball (1978) (Atari)", "New Release (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b86552198f52cfce721bafb496363099", "Apollo, Tim Martin", "AP-2007", "Kyphus (1982) (Apollo) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b86a12e53ab107b6caedd4e0272aa034", "Funvision - Fund. International Co.", "", "Treasure Hunting (Funvision)", "AKA Pitfall!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b879e13fd99382e09bcaf1d87ad84add", "Zellers", "", "Time Warp (Zellers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b8865f05676e64f3bec72b9defdacfa7", "Activision, David Crane", "AG-004", "Fishing Derby (1980) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b897f9e3f939b9f21566d56db812a84e", "Atari, Jim Huether", "CX26163P", "Flag Capture (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b8e715223ba65cf716b3620a90ca3ec1", "Parker Brothers", "PB5820", "Mr. Do!'s Castle (1984) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "b8ed78afdb1e6cfe44ef6e3428789d5f", "Data Age, J. Ray Dettling", "112-007", "Bermuda Triangle (1983) (Data Age)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b9232c1de494875efe1858fc8390616d", "Panda", "110", "Harbor Escape (1983) (Panda)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b9336ed6d94a5cc81a16483b0a946a73", "Atari, Jerome Domurat, Michael Sierchio", "CX2667, CX2667P", "RealSports Soccer (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "b955eb0e2baf7a437c186bddd4c49958", "Atari, Omegamatrix", "", "Space Invaders Menu (2020) (PAL60) (Hack)", "Hack of Space Invaders", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b958d5fd9574c5cf9ece4b9421c28ecd", "Piero Cavina", "", "Multi-Sprite Game V1.0 (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b95a6274ca0e0c773bfdc06b4c3daa42", "Paul Slocum", "", "3-D Corridor (29-03-2003) (Paul Slocum)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b98cc2c6f7a0f05176f74f0f62c45488", "Spectravideo", "SV-010", "CompuMate (1983) (Spectravideo)", "", "", "", "", "CM", "", "", "", "", "COMPUMATE", "", "", "COMPUMATE", "", "", "", "", "", "", "", "", "YES", "" },
+  { "b9b4612358a0b2c1b4d66bb146767306", "Commavid, Ben Burch", "CM-010", "Rush Hour (1983) (Commavid) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b9d1e3be30b131324482345959aed5e5", "Activision - Boston Design Center, Rex Bradford", "", "Kabobber (07-25-1983) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "b9f6fa399b8cd386c235983ec45e4355", "Parker Brothers, John Emerson", "931511", "Action Force (1983) (Parker Bros) (PAL)", "AKA G.I. Joe - Cobra Strike", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 55", "", "", "", "" },
+  { "b9f9c0fed0db08c34346317f3957a945", "SuperVision", "405, 427, 806, 808, 813, 816", "Chopper Command (SuperVision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ba257438f8a78862a9e014d831143690", "U.S. Games Corporation - JWDA, Todd Marshall, Robin McDaniel, Henry Will IV", "VC2002", "Squeeze Box (1983) (U.S. Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ba317f83cdfcd58cbc65aac1ccb87bc5", "Thomas Jentzsch", "", "Jammed (2001) (XYPE) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ba3a17efd26db8b4f09c0cf7afdf84d1", "Activision, Larry Miller", "AX-021", "Spider Fighter (1983) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ba3b0eebccc7b791107de5b4abb671b4", "Thomas Jentzsch", "", "Thrust (V0.9) (2000) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ba657d940a11e807ff314bba2c8b389b", "Activision, John Van Ryzin", "AG-038-04", "Cosmic Commuter (1984) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bac28d06dfc03d3d2f4a7c13383e84ee", "Supergame", "", "Demon Attack (Supergame)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bae1a23f9b6acdadf465cfb330ba0acb", "Atari - GCC, Doug Macrae", "CX2677", "Dig Dug (1983) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bae66907c3200bc63592efe5a9a69dbb", "Spectravision - Spectravideo - Quelle", "SA-201 - 412.783 3", "Gangster Alley (1982) (Spectravision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "baf4ce885aa281fd31711da9b9795485", "Atari, Douglas Neubauer", "CX26176", "Radar Lock (1989) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bb18189021d58362d9e4d317cd2e28b7", "Activision, David Crane - Ariola", "EAG-001, PAG-001, EAG-001-04B, EAG-001-04I - 711 001-715", "Dragster (1980) (Activision) (PAL) (4K)", "AKA Dragster Rennen", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bb2b83fff97604f74ada565e0b5bae94", "Thomas Jentzsch", "", "Missile Control - Atari Mouse Hack v1.15 (PAL60) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bb5049e4558daade0f87fed69a244c59", "Atari, Brad Stewart", "CX2649, CX2649P", "Asteroids (1981) (Atari) (PAL) [no copyright]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "bb579404924c40ca378b4aff6ccf302d", "", "", "Lightbulb Lightens, The (PD) (Non Functional)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bb6a5a2f7b67bee5d1f237f62f1e643f", "", "", "Demo Image Series #5 - Animegirl (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bb745c893999b0efc96ea9029e3c62ca", "Play Video", "", "Planet Patrol (1982) (Play Video) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bb756aa98b847dddc8fc170bc79f92b2", "", "", "Golf (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bb9112d478a1a922d2c289a752bba695", "Omegamatrix", "", "SpaceMaster X-7 (Amiga Mouse) (Omegamatrix)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bbf8c7c9ed280151934aabe138e41ba7", "Amiga", "1130", "Power Play Arcade Video Game Album V (1984) (Amiga) (Prototype)", "Mogul Maniac, Surf's Up, Off Your Rocker, S.A.C. Alert", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bc24440b59092559a1ec26055fd1270e", "", "", "Private Eye (1984) (Activision) [a]", "", "", "", "0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bc3057a35319aae3a5cd87a203736abe", "CCE", "C-845", "Time Warp (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bc33c685e6ffced83abe7a43f30df7f9", "Dynacom", "", "Seaquest (1983) (Dynacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bc4cf38a4bee45752dc466c98ed7ad09", "Atari, Douglas Neubauer, Mimi Nyden", "CX26136", "Solaris (1986) (Atari) (PAL)", "AKA Universe, Star Raiders II, The Last Starfighter", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bc526185ad324241782dc68ba5d0540b", "", "", "Dodge Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bc5389839857612cfabeb810ba7effdc", "Atari, Tod Frye", "CX2671", "SwordQuest - WaterWorld (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bc703ea6afb20bc089f04d8c9d79a2bd", "", "", "Gunfight 2600 - Not mergeable with Colbert wizardry... (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bc97d544f1d4834cc72bcc92a37b8c1b", "", "", "Sky Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bcb31f22856b0028c00d12f0e4c0a952", "Canal 3 - Intellivision", "", "Thunderground (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bcb73b534ed7c613ac379ecd726effb5", "Bob Montgomery (aka vdub_bobby)", "", "Squish 'Em (2007) (PAL60)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bccb4e2cfad5efc93f6d55dc992118ce", "Activision, Carol Shaw", "AX-020, AX-020-04", "River Raid (1982) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bce4c291d0007f16997faa5c4db0a6b8", "Quelle", "292.651 7", "Weltraumtunnel (1983) (Quelle) (PAL)", "AKA Innerspace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bce93984b920e9b56cf24064f740fe78", "Atari", "CX26163P", "Checkers (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bcef7880828a391cf6b50d5a6dcef719", "Rainbow Vision - Suntek", "SS-009", "Bermuda, The (1983) (Rainbow Vision) (PAL)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bd1bd6f6b928df17a702def0302f46f4", "", "", "Binary To Decimal Routine (2001) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bd39598f067a1193ae81bd6182e756d1", "Telegames", "", "Night Stalker (1988) (Telegames) (PAL)", "AKA Dark Cavern", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bd430c2193045c68d1a20a018a976248", "", "", "Pac Ghost Sprite Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bd551ff1264f5c367a3ad7cf0d2f266c", "Bit Corporation", "R320", "SpaceMaster X-7 (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bda1463e02ae3a6e1107ffe1b572efd2", "Atari, Nick 'Sandy Maiwald' Turner", "CX26111", "Snoopy and the Red Baron (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bdb4b584ddc90c9d2ec7e21632a236b6", "Atari Freak 1", "", "Nitemare at Sunshine Bowl-a-Rama (Atari Freak 1) (Hack)", "Hack of Pac-Man Jr.", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bdbaeff1f7132358ea64c7be9e46c1ac", "20th Century Fox Video Games, Douglas 'Dallas North' Neubauer", "11105", "Mega Force (1982) (20th Century Fox) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bdc381baf7c252c63739c5e9ed087a5c", "", "", "Vertical Ship Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bdecc81f740200780db04a107c3a1eba", "Quelle", "874.254 6", "Super-Cowboy beim Rodeo (1983) (Quelle) (PAL)", "AKA Stampede", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bdf1996e2dd64baf8eff5511811ca6ca", "Tron", "", "H.E.R.O. (Tron)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "be060a704803446c02e6f039ab12eb91", "Parker Brothers, Rex Bradford, Sam Kjellman", "931501", "Star Wars - The Empire Strikes Back (1982) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "be1922bd8e09d74da471287e1e968653", "Cropsy", "", "Hangman Pacman Demo (Cropsy) (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "be2870a0120fd28d25284e9ccdcbdc99", "", "", "Tomb Raider 2600 [REV 01] (Montezuma's Revenge Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "be35d8b37bbc03848a5f020662a99909", "Atari, Joe Decuir, Steve Mayer, Larry Wagner - Sears", "CX2601 - 99801, 6-99801, 49-75124", "Combat (1977) (Atari) (4K) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "be3f0e827e2f748819dac2a22d6ac823", "Puzzy - Bit Corporation", "PG202", "Space Tunnel (1982) (Puzzy)", "AKA Le Tunnel de L'Estace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "be41463cd918daef107d249f8cde3409", "", "", "Berzerk (Voice Enhanced) (Hack)", "Hack of Berzerk", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "be561b286b6432cac71bccbae68002f7", "", "", "Counter Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "be929419902e21bd7830a7a7d746195d", "Activision, Garry Kitchen", "AX-025, AX-025-04", "Keystone Kapers (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "becd908f9d7bb361982c3dc02d6475c6", "Kyle Pittman", "", "THX-1138 (Kyle Pittman) (Hack)", "Hack of Berserk", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bedfbde71fb606601f936b5b057f26f7", "Activision, Garry Kitchen - Ariola", "EAX-025, EAX-025-04I - 711 025-725", "Keystone Kapers (1983) (Activision) (PAL) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "befce0de2012b24fd6cb8b53c17c8271", "", "", "Push (V0.03) (No Illegal Opcodes) (1998) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bf1970b692275b42c4ec0683588eb062", "Thomas Jentzsch", "", "Reactor - Amiga Mouse Hack v1.3 (NTSC) (Full-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bf52327c2197d9d2c4544be053caded1", "HES - Activision", "AG-930-04, AZ-030", "Decathlon (HES) (PAL) (16K)", "AKA Activision Decathlon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bf84f528de44225dd733c0e6a8e400a0", "CCE", "", "Demons to Diamonds (CCE)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 57", "", "", "", "" },
+  { "bf976cf80bcf52c5f164c1d45f2b316b", "Atari, Tod Frye, Mimi Nyden", "CX2657", "SwordQuest - FireWorld (1982) (Atari) (PAL)", "AKA Adventure II, SwordQuest II - FireWorld", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bfa58198c6b9cd8062ee76a2b38e9b33", "", "", "20 Sprites at Once Demo 4 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bfb73aabb2489316cd5882c3cd11d9f9", "AtariAge, Chris Walton & Thomas Jentzsch", "165", "Star Castle Arcade (2014) (AtariAge)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "bff8f8f53a8aeb1ee804004ccbb08313", "", "", "Droid Demo 22 (David Conrad Schweinsberg) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "bffe34516aaa3cbf5d307eab382a7e95", "", "", "Euchre (Release Candidate) (PAL) (28-09-2002) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c00734a2233ef683d9b6e622ac97a5c8", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX26133", "A-Team, The (03-30-1984) (Atari) (Prototype)", "AKA Saboteur", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c00b65d1bae0aef6a1b5652c9c2156a1", "Atari, Joe Decuir - Sears", "CX2621 - 99806, 6-99806, 49-75104", "Video Olympics (1977) (Atari) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "", "YES", "", "", "AUTO 60", "", "", "", "" },
+  { "c02e1afa0671e438fd526055c556d231", "Atari", "", "A-Team (Atari) (Prototype) (PAL60)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c032c2bd7017fdfbba9a105ec50f800e", "Activision, Charlie Heath", "", "Thwocker (04-09-1984) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c033dc1d7b6fde41b9cadce9638909bb", "", "", "Skeleton (V1.1) (06-09-2002) (Eric Ball)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c0589bb73858924389077fa3c2e9441a", "SOLID Corp. (D. Scott Williamson)", "CX2655-014", "Star Castle 2600 (SolidCorp) [014]", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "c05f367fa4767ceb27abadf0066df7f4", "Thomas Jentzsch", "", "TomInv (31-07-2001) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c08d0cee43077d3055febb00e5745c1d", "HES - Activision", "", "Super Hit Pak - River Raid, Sky Jinks, Grand Prix, Fishing Derby, Checkers (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c0a68837c60e15d1fc5a40c9a62894bc", "Arcadia Corporation, Kevin Norman", "7 AR-4103", "Killer Satellites (1983) (Arcadia) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c0c7eddefce9015346db88ade3e1e096", "CBS Electronics, Bob Curtiss", "4L 2487 5000", "Solar Fox (1983) (CBS Electronics) (Prototype) (4K)", "RAM must be zero'ed to start correctly", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "c0d2434348de72fa6edcc6d8e40f28d7", "SEGA - Beck-Tech, Steve Beck", "010-01", "Tapper (1984) (SEGA)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c1034a5bfb0bb13cc5bdf86cc58989a7", "Atari, Nick 'Sandy Maiwald' Turner", "CX2665", "Frog Pond (1982) (Atari) (Prototype) (4K) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c118854d670289a8b5d5156aa74b0c49", "Jone Yuan Telephonic Enterprise Co", "", "Skiing (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c11e8473c652619ac6166900150ce215", "AtariAge, Chris Walton", "1.0 (Release)", "Chetiry (2011) (AtariAge) (60k) (PAL)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "50" },
+  { "c126656df6badfa519cc63e681fb3596", "Ron Corcoran", "", "Space Invaders (2002) (Ron Corcoran) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c15042e54c7408498f051d782aaa8945", "Omegamatrix", "", "Millipede (Atari Trak-Ball) v6.5 (Omegamatrix)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c150c76cbde2c9b5a97eb5399d46c64f", "", "", "Unknown Title (xxx00000 (200203)) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c16c79aad6272baffb8aae9a7fff0864", "U.S. Games Corporation - JWDA, Sylvia Day, Todd Marshall, Robin McDaniel, Henry Will IV", "VC2001", "Gopher (1982) (U.S. Games)", "AKA Gopher Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c16fbfdbfdf5590cc8179e4b0f5f5aeb", "", "", "Wall Break (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c17bdc7d14a36e10837d039f43ee5fa3", "Spectravision - Spectravideo", "SA-203", "Cross Force (1982) (Spectravision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c1a83f44137ea914b495fc6ac036c493", "Atari, Carla Meninsky", "CX2660", "Star Raiders (1982) (Atari) (PAL)", "Uses Joystick (left) and Keypad (right) Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c1b038ce5cb6d85e956c5509b0e0d0d8", "", "", "Rotating Colors Demo 2 (Junkosoft) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c1b1049b88bcd98437d8872d1d62ba31", "", "", "Demo Image Series #4 - Donald (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c1b7aeabc3ec41556d924c8372a9ba5b", "Atari, Robert C. Polaro", "", "Dukes of Hazard (1980) (Atari) (Prototype)", "AKA Stunt Cycle", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c1cb228470a87beb5f36e90ac745da26", "Activision, Bob Whitehead", "AX-015, AX-015-04", "Chopper Command (1982) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c1e6e4e7ef5f146388a090f1c469a2fa", "Bomb - Onbase", "CA283", "Z-Tack (1983) (Bomb)", "AKA Base Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c1f209d80f0624dada5866ce05dd3399", "Telegames", "", "Deadly Discs (1988) (Telegames) (PAL)", "AKA TRON - Deadly Discs", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c1fdd44efda916414be3527a47752c75", "Parker Brothers, John Emerson", "PB5920", "G.I. Joe - Cobra Strike (1983) (Parker Bros)", "Uses the Paddle (left) and Joystick (right) Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c20f15282a1aa8724d70c117e5c9709e", "Video Gems", "VG-02", "Surfer's Paradise (1983) (Video Gems) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c21450c21efb7715746e9fa87ad6f145", "Hozer Video Games", "", "Gunfight 2600 - It could've been soooo cool, but... (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c216b91f5db21a093ded6a5aaec85709", "Jone Yuan Telephonic Enterprise Co", "", "Dragster (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c221607529cabc93450ef25dbac6e8d2", "Eckhard Stolberg", "", "Color Test (26-09-2002) (Eckhard Stolberg)", "", "Homebrew", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c225379e7c4fb6f886ef9c8c522275b4", "Video Mania", "", "Frostbite (1983) (Video Mania)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c225abfb584960efe1f359fc94b73379", "", "", "Joustpong (21-09-2002) (Kirk Israel) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c2410d03820e0ff0a449fa6170f51211", "", "", "Pac-Man (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c246e05b52f68ab2e9aee40f278cd158", "Thomas Jentzsch", "", "Star Wars - Ewok Adventure (Thomas Jentzsch) (Prototype)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c2778507b83d9540e9be5713758ff945", "", "", "Island Flyer Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c28b29764c2338b0cf95537cc9aad8c9", "", "", "Multi-Color Demo 4 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c29d17eef6b0784db4586c12cb5fd454", "Jone Yuan Telephonic Enterprise Co", "", "River Raid (Jone Yuan) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c29f8db680990cb45ef7fef6ab57a2c2", "Parker Brothers - Roklan, Paul Crowley, Bob Curtiss", "931505", "Super Cobra (1983) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c2a37f1c7603c5fd97df47d6c562abfa", "Roger Williams", "", "Bar-Score Demo (2001) (Roger Williams)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c2b5c50ccb59816867036d7cf730bf75", "Salu - Avantgarde Software, Michael Buetepage", "460741", "Ghostbusters II (1992) (Salu) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "c2bcd8f2378c3779067f3a551f662bb7", "Activision, Bob Whitehead - Ariola", "EAG-002, EAG-002-04I, PAG-002 - 711 002-715", "Boxing (1980) (Activision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c2c7a11717e255593e54d0acaf653ee5", "", "", "Chopper Command (208 in 1) (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c2c8eb642765137bb82b83a65232961f", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Mouse Hack v1.1 (PAL) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c2dea467f4a02fa1f06d66f52bc12e6e", "Thomas Jentzsch", "", "Missile Command Atari Trak-Ball Hack v1.3 (NTSC) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c2fbef02b6eea37d8df3e91107f89950", "Champ Games", "CG-02-N", "Conquest Of Mars (NTSC)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c31a17942d162b80962cb1f7571cd1d5", "Home Vision - Gem International Corp. - VDI", "VCS83112", "Sky Alien (1983) (Home Vision) (PAL)", "AKA Sky Aliem", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c3205e3707f646e1a106e09c5c49c1bf", "", "", "Unknown Title (bin00003 (200206)) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c3472fa98c3b452fa2fd37d1c219fb6f", "Atari, Carla Meninsky - Sears", "CX2637 - 49-75158", "Dodge 'Em (1980) (Atari) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c370c3268ad95b3266d6e36ff23d1f0c", "Atari, Alan Miller", "CX2641, CX2641P", "Surround (1977) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c3a9550f6345f4c25b372c42dc865703", "Atari - Bobco, Robert C. Polaro", "CX2663", "Road Runner (1989) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c3aeb796fdaf9429e8cd6af6346f337e", "", "", "If It's Not One Thing It's Another (1997) (Chris Cracknell)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c3bbc673acf2701b5275e85d9372facf", "Atari, Robert C. Polaro", "CX26157", "Stunt Cycle (07-21-1980) (Atari) (Prototype)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c3e4aa718f46291311f1cce53e6ccd79", "", "", "Hangman Ghost 4letter (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c3ef5c4653212088eda54dc91d787870", "Activision, Bob Whitehead", "AG-002, CAG-002, AG-002-04", "Boxing (1980) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c3f53993ade534b0982ca3a286c85bb5", "", "", "Full Screen Bitmap Drawing System (12-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c4060a31d61ba857e756430a0a15ed2e", "Thomas Jentzsch", "", "Pick 'n Pile (2003) (TJ)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "c41e7735f6701dd50e84ee71d3ed1d8f", "Dynacom", "", "Spider Fighter (1983) (Dynacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c43bd363e1f128e73ba5f0380b6fd7e3", "Atari, Chris Crawford", "", "Wizard (1980) (Atari) (Prototype) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c446288fe62c0c2737639fd788ae4a21", "", "", "Mark's Sound Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "c450a285daa7a3b65188c2c3cf04fb3e", "Wizard Video Games", "007", "Halloween (1983) (Wizard Video Games) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c469151655e333793472777052013f4f", "", "", "Base Attack (Unknown) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c471b97446a85304bbac021c57c2cb49", "First Star Software, Alex Leavens, Shirley Ann Russell", "", "Boing! (1983) (First Star Software) (PAL)", "AKA Bubbles, Soap Suds, The Emphysema Game", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "c47244f5557ae12c61e8e01c140e2173", "Atari - GCC, Mike Feinstein, John Allred", "CX2688, CX2688P", "Jungle Hunt (1983) (Atari) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c47b7389e76974fd0de3f088fea35576", "Funvision - Fund. International Co.", "", "Mighty Mouse (Funvision)", "AKA Gopher", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c482f8eebd45e0b8d479d9b71dd72bb8", "Retroactive", "", "Push (V0.03) (1998) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "c49fe437800ad7fd9302f3a90a38fb7d", "Atari, Dan Hitchens, Mimi Nyden", "CX2697, CX2697P", "Mario Bros. (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c4b73c35bc2f54b66cd786f55b668a82", "Arcadia Corporation, Stephen Harland Landrum", "AR-4101", "Communist Mutants from Space (1982) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c4bbbb0c8fe203cbd3be2e318e55bcc0", "", "", "Atlantis (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c4bc8c2e130d76346ebf8eb544991b46", "Imagic", "", "Imagic Selector ROM (1982) (Imagic) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c4d888bcf532e7c9c5fdeafbb145266a", "", "", "Space Robot (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "c504a71c411a601d1fc3173369cfdca4", "Retroactive", "", "Qb (V2.02) (Stella) (2001) (Retroactive)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "c5124e7d7a8c768e5a18bde8b54aeb1d", "Imagic, Rob Fulop", "720104-2A, IA3204P, EIX-008-04I", "Cosmic Ark (1982) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c517144e3d3ac5c06f2f682ebf212dd7", "Tigervision - Teldec", "7-008 - 3.60006 VG", "Miner 2049er (1983) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c529e63013698064149b9e0468afd941", "", "", "S.I.PLIX 2 (Hack)", "Hack of Kaboom!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
+  { "c52d9bbdc5530e1ef8e8ba7be692b01e", "Atari, Robert C. Polaro", "CX26130", "Holey Moley (02-29-1984) (Atari) (Prototype)", "Uses Keypad Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c5301f549d0722049bb0add6b10d1e09", "Atari, Carla Meninsky, Ed Riddle - Sears", "CX2611 - 99821, 49-75149", "Indy 500 (1977) (Atari)", "Uses the Driving Controllers", "", "", "", "", "", "", "", "", "DRIVING", "", "", "DRIVING", "", "", "", "", "", "45", "", "", "", "" },
+  { "c5387fc1aa71f11d2fa82459e189a5f0", "Bit Corporation", "PG202", "Space Tunnel (1982) (BitCorp) (PAL)", "AKA Weltraum-Tunnel", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c53c0d10c74325deae9ba84074281983", "The Atari 2600 Connection - John K. Harvey, Tim Duarte", "v75", "Mean Santa (2009)", "Released in 2019", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c541a5f6fc23b40a211196dd78233780", "Atari, Carla Meninsky - Sears", "CX2660 - 49-75187", "Star Raiders (1981) (Atari) (Prototype) (4K)", "Uses Joystick (left) and Keypad (right) Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" },
+  { "c54b4207ce1d4bf72fadbb1a805d4a39", "Billy Eno", "", "Sniper (Feb 30) (2001) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c560a3ecb7b751021953819efcfe5b41", "Omegamatrix", "", "Ghostbusters (Genesis)", "Genesis controller", "", "", "", "", "", "", "", "", "GENESIS", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c569e57dca93d3bee115a49923057fd7", "", "", "Pac-Space (Pac-Man Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c58708c09ccb61625cda9d15ddcd8be6", "SPIKE the Percussionist", "", "NOIZ Invaders (SPIKE) (2002) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c5930d0e8cdae3e037349bfa08e871be", "Atari, Howard Scott Warshaw - Sears", "CX2655 - 49-75167", "Yars' Revenge (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "c59633dbebd926c150fb6d30b0576405", "Telegames", "5861 A030", "Bogey Blaster (1988) (Telegames)", "AKA Air Raiders", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c5a76bafc4676edb76e0126fb9f0fb2d", "Charles Morgan", "", "Zero Patrol (Charles Morgan) (Hack)", "Hack of Moon Patrol", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c5bab953ac13dbb2cba03cd0684fb125", "SpiceWare - Darrell Spice Jr.", "", "Stay Frosty (SpiceWare)", "Part of Stella's Stocking 2007 Xmas compilation", "Homebrew", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "c5bf03028b2e8f4950ec8835c6811d47", "Atari - Axlon, Tod Frye - Heuristica, Agustin Ortiz", "CX26169", "Shooting Arcade (03-07-1989) (Atari) (Prototype) [a2]", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c5c7cc66febf2d4e743b4459de7ed868", "Atari, Jerome Domurat, Steve Woita", "CX2696", "Asterix (1983) (Atari) (PAL) [a]", "AKA Taz", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c5d2834bf98e90245e545573eb7e6bbc", "CCE", "", "Snoopy and the Red Baron (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c5dd8399257d8862f3952be75c23e0eb", "Atari - GCC", "CX2680", "RealSports Tennis (1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c5f71dfbdca9cc96b28643ff4d06aa6f", "Thomas Jentzsch", "", "Centipede - Atari Trak-Ball Hack v1.4 (PAL) (Full-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c5fe45f2734afd47e27ca3b04a90213c", "Atari, Brad Stewart", "CX2622, CX2622P", "Breakout (1978) (Atari) (PAL) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" },
+  { "c63a98ca404aa5ee9fcff1de488c3f43", "Atari", "CX26145", "Venture (1987) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "c6556e082aac04260596b4045bc122de", "Atari - GCC, Dave Payne", "CX2669", "Vanguard (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c6688781f4ab844852f4e3352772289b", "Atari, Tod Frye", "CX2695", "Xevious (08-02-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "c67ff409f28f44883bd5251cea79727d", "", "", "Gunfight 2600 - Music & Bugfixes 1 (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c689148ad9275667924ab334107b517e", "Jone Yuan Telephonic Enterprise Co", "", "Space Raid (Jone Yuan)", "AKA MegaMania", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c68a6bafb667bad2f6d020f879be1d11", "Atari, Michael Kosaka, Peter C. Niday, Robert Vieira", "CX26110", "Crystal Castles (1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c6ae21caceaad734987cb24243793bd5", "CCE", "", "Frostbite (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c6c63da3bc2e47291f63280e057061d0", "128-in-1 Junior Console", "", "Human Cannonball (128-in-1 Junior Console) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c6d48c6ae6461e0e82753540a985ac9e", "Ed Federmeyer", "", "Edtris (1994) (Ed Federmeyer)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c6d7fe7a46dc46f962fe8413c6f53fc9", "Parker Brothers, Mark Lesser", "PB5950", "Lord of the Rings (1983) (Parker Bros) (Prototype) [a]", "Journey to Rivendell (The Lord of the Rings I)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c6db733e0b108c2580a1d65211f06dbf", "Atari, Eric Manghise, Mimi Nyden, Joseph Tung", "CX2640", "RealSports Baseball (07-09-1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c738fc3f5aae1e8f86f7249f6c82ac81", "Atari, Brad Stewart - Sears", "CX2622 - 6-99813, 49-75107", "Breakout (1978) (Atari) (16K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 60", "", "", "", "" },
+  { "c73ae5ba5a0a3f3ac77f0a9e14770e73", "Starpath Corporation, Stephen H. Landrum", "9 AR-4105", "Official Frogger, The (1983) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c745487828a1a6a743488ecebc55ad44", "Rainbow Vision - Suntek", "SS-002", "Galactic (1983) (Rainbow Vision) (PAL)", "AKA The Challenge of.... Nexar", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c74bfd02c7f1877bbe712c1da5c4c194", "Thomas Jentzsch", "", "River Raid Tanks (Thomas Jentzsch) (Hack)", "Hack of River Raid", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c7600d72247c5dfa1ec1a88d23e6c85e", "Arcadia Corporation, Scott Nelson", "13", "Sweat! - The Decathlon Game (1 of 3) (1983) (Arcadia) (Prototype)", "Uses the Paddle Controllers (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c77c35a6fc3c0f12bf9e8bae48cba54b", "Xonox - K-Tel Software - Action Graphics, Michael Schwartz, David Thiel", "6230, 7210, 06004, 99004", "Artillery Duel (1983) (Xonox)", "", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c77d3b47f2293e69419b92522c6f6647", "Panda", "101", "Tank Brigade (1983) (Panda)", "AKA Phantom Tank", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c7900a7fe95a47eef3b325072ad2c232", "Larry Petit", "", "Super Congo Bongo (2003) (Larry Petit) (Hack)", "Hack of Bongo", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c7d5819b26b480a49eb26aeb63cc831e", "Bit Corporation", "PGP210", "Ice Hockey (4 Game in One Light Green) (1983) (BitCorp) (PAL)", "AKA Hockey, Hockey", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c7e43ad79c5e5c029d9f5ffde23e32cf", "", "", "PAL-NTSC Detector (15-11-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c7eab66576696e11e3c11ffff92e13cc", "Atari - GCC", "CX2680, CX2680P", "RealSports Tennis (1983) (Atari) (PAL) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c7f13ef38f61ee2367ada94fdcc6d206", "Parker Brothers - Roklan, Joe Gaucher", "PB5370", "Popeye (1983) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "c82ec00335cbb4b74494aecf31608fa1", "CCE", "", "E.T. - The Extra-Terrestrial (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c830f6ae7ee58bcc2a6712fb33e92d55", "Atari, Michael Kosaka", "CX2687", "Tempest (01-05-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c866c995c0d2ca7d017fef0fc0c2e268", "Retroactive", "", "Qb (2.00) (Retroactive) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "c880c659cdc0f84c4a66bc818f89618e", "Thomas Jentzsch", "", "Open Sesame (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "c89c3138a99fd1fd54367d65f75b0244", "Atari, Omegamatrix", "", "Space Invaders Menu (2020) (PAL) (Hack)", "Hack of Space Invaders", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c8c7da12f087e8d16d3e6a21b371a5d3", "", "", "Demo Image Series #9 - Genius (28-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c8e90fc944596718c84c82b55139b065", "Atari - Roklan, Bob Curtiss", "", "Firefox (1983) (Atari) (Prototype) [a]", "AKA Combat II, Fighter Command", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c8fa5d69d9e555eb16068ef87b1c9c45", "Atari", "CX26144", "Donkey Kong Junior (1987) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c90788d9aa71a78bcc78c015edb22c54", "Thomas Jentzsch", "", "Marble Craze - Atari Trak-Ball Hack v1.0 (PAL60) (TJ)", "Uses Atari Trak-Ball Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c9196e28367e46f8a55e04c27743148f", "Atari", "CX26163P", "Stampede (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c92cfa54b5d022637fdcbdc1ef640d82", "Retroactive", "", "Qb (V2.05) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "c98e8c918a40b4d3a243dd6c49196330", "AtariAge, Omegamatrix", "", "Venture Reloaded (2019) (AtariAge) (PAL60) (Hack)", "Transformative hack of Venture", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "c9b7afad3bfd922e006a6bfc1d4f3fe7", "Atari, Larry Kaplan - Sears", "CX2628 - 6-99842, 49-75117", "Bowling (1979) (Atari)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c9c25fc536de9a7cdc5b9a916c459110", "Activision, Mike Lorenzen", "AX-023", "Oink! (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c9d02d3cfeef8b48fb71cb4520a4aa84", "", "", "Euchre (More for less) (PAL) (22-08-2002) (Erik Eid)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c9e721eb29c940c2e743485b044c0a3f", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "c9f6e521a49a2d15dac56b6ddb3fb4c7", "Parker Brothers, Rex Bradford", "PB5000", "Star Wars - Jedi Arena (1983) (Parker Bros)", "Uses the Paddle Controllers (swapped)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 50", "", "", "", "" },
+  { "ca09fa7406b7d2aea10d969b6fc90195", "Activision, Matthew L. Hubbard, Bob Whitehead", "AX-024", "Dolphin (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ca4f8c5b4d6fb9d608bb96bc7ebd26c7", "M Network - INTV - APh Technological Consulting, Hal Finney, Glenn Hightower, Peter Kaminski", "MT4317", "Adventures of TRON (1983) (M Network)", "AKA Tron Joystick", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ca50cc4b21b0155255e066fcd6396331", "Suntek", "SS-031", "UFO Patrol (1983) (Suntek) (PAL)", "AKA X'Mission", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "ca53fc8fd8b3c4a7df89ac86b222eba0", "CCE", "C-812", "Pac Man (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ca54de69f7cdf4d7996e86f347129892", "PlayAround - J.H.M.", "201", "Philly Flasher (1982) (PlayAround)", "Uses the Paddle Controllers, AKA Beat 'Em & Eat 'Em", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 45", "", "", "", "" },
+  { "ca7aaebd861a9ef47967d31c5a6c4555", "Atari, Bob Whitehead", "CX26163P", "Homerun (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ca7abc774a2fa95014688bc0849eee47", "Atari, Michael Kosaka, Peter C. Niday, Robert Vieira", "CX26110", "Crystal Castles (1984) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ca7f166a94eed1a349dec6d6a358bcad", "Activision, Alan Miller - Ariola", "EAG-007, EAG-007-04I, PAG-007 - 711 007-720", "Tennis (1981) (Activision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cac9928a84e1001817b223f0cecaa3f2", "Amiga - Video Soft, Jerry Lawson, Dan McElroy", "", "3-D Genesis (1983) (Amiga) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "cad982c9b45bc5eff34e4ea982d5f1ca", "", "", "Song (17-02-2003) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "cade123747426df69570a2bc871d3baf", "Gakken", "011", "Marine Wars (1983) (Gakken) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cae8f83c06831ec7bb6a3c07e98e9342", "Colin Hughes", "", "Tetris 2600 (Colin Hughes) [o1]", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "cb18d8d5fbdcb1cd7bd36c5423348859", "", "", "RAM-Pong (NTSC) v1.0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cb24210dc86d92df97b38cf2a51782da", "Video Gems", "VG-01", "Missile Control (1983) (Video Gems) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cb4a7b507372c24f8b9390d22d54a918", "ITT Family Games", "554-37 338", "Peter Penguin (1983) (ITT Family Games) (PAL)", "AKA Frisco (Pumuckl-Serie)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cb8399dc0d409ff1f531ef86b3b34953", "", "", "Demo Image Series #12 - Luigi And Mario (01-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cb9626517b440f099c0b6b27ca65142c", "Atari, Larry Kaplan - Sears", "CX2664 - 6-99818", "Brain Games (1978) (Atari) (4K)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" },
+  { "cb96b0cf90ab7777a2f6f05e8ad3f694", "Silvio Mogno", "", "Rainbow Invaders", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cb9b2e9806a7fbab3d819cfe15f0f05a", "Parker Brothers - JWDA, Todd Marshall, Robin McDaniel, Ray Miller", "931513", "Star Wars - Death Star Battle (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cba56e939252b05df7b7de87307d12ca", "", "", "Playfield Text Demo (2001) (Roger Williams)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cbad928e10aeee848786cc55394fb692", "", "", "Fu Kung! (V0.06a Cuttle Cart Compatible) (15-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cbb0ee17c1308148823cc6da85bff25c", "", "", "Rotating Colors Demo 1 (Junkosoft) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cbc373fbcb1653b4c56bfabba33ea50d", "CCE", "", "Super Voleyball (CCE)", "AKA RealSports Volleyball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cbced209dd0575a27212d3eee6aee3bc", "Apollo - Games by Apollo, Ed Salvo, Byron Parks", "AP-2003", "Racquetball (1982) (Apollo) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "cbd981a23c592fb9ab979223bb368cd5", "Atari, Carla Meninsky - Sears", "CX2660 - 49-75187", "Star Raiders (1982) (Atari)", "Uses Joystick (left) and Keypad (right) Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cbe5a166550a8129a5e6d374901dffad", "Atari, Carla Meninsky - Sears", "CX2610 - 49-75127", "Warlords (1981) (Atari)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 50", "", "", "", "" },
+  { "cbeafd37f15e0dddb0540dbe15c545a4", "", "", "Black and White Fast Scolling Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cc03c68b8348b62331964d7a3dbec381", "Jone Yuan Telephonic Enterprise Co", "", "Marauder (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cc12581e079cd18330a89902625b8347", "Dave Neuman", "", "Space Battle (PAL)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cc1939e4769d0c157ace326efcfdcf80", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (3 of 4) (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cc2973680c150886cce1ed8693c3aca2", "Quelle", "874.254 6", "Super-Cowboy beim Rodeo (1983) (Quelle) (PAL) (4K)", "AKA Stampede", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cc3d942c6958bd16b1c602623f59e6e1", "Atari, Bill Aspromonte, John Russell, Michael Sierchio, Robert Zdybel", "CX26114", "Pigs in Space (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cc7138202cd8f6776212ebfc3a820ecc", "Atari - CCW, Christopher H. Omarzu, Preston Stuart, Bruce Williams", "CX26101", "Oscar's Trash Race (03-30-1983) (Atari) (Prototype)", "Uses the Keypad Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" },
+  { "cc724ebe74a109e39c0b2784ddc980ca", "Atari, Jerome Domurat, Dave Staugas", "CX2682", "Krull (05-27-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cc74ddb45d7bc4d04c2e6f1907416699", "", "", "Colour Display Programme (1997) (Chris Cracknell)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cca33ae30a58f39e3fc5d80f94dc0362", "", "", "Okie Dokie (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ccb56107ff0492232065b85493daa635", "Bit Corporation", "PG206 [demonstration cartridge]", "Bobby Is Going Home (1983) (BitCorp) (PAL) [demo cart]", "AKA Bobby geht Heim", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ccb5fa954fb76f09caae9a8c66462190", "Answer Software Corporation - TY Associates, Mike Wentz", "ASC1001", "Malagai (1983) (Answer Software)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "ccb807eb79b0ed0f5fdc460445ef703a", "", "", "Superman (Stunt_Cycle_Rules!) (Hack)", "Hack of Superman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ccbd36746ed4525821a8083b0d6d2c2c", "Atari, Brad Stewart - Sears", "CX2649, 49-75163", "Asteroids (1981) (Atari) [no copyright]", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "cccfe9e9a11b1dad04beba46eefb7351", "", "", "Poker Squares (V0.25) (PAL) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ccd6ce508eee4b3fca67212833edcd85", "Otto Versand", "746422", "Hot Wave (Double-Game Package) (1983) (Otto Versand) (PAL)", "AKA Ram It", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ccd92a269a4c2bd64d58cf2c0114423c", "Atari - GCC, Mark Ackerman, Glenn Parker", "CX2675", "Ms. Pac-Man (09-20-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cd032ab6764b55438a7b0bfb5e78595a", "", "", "Hangman Pac-Man 4letter (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cd139ae6d09f3665ad09eb79da3f9e49", "Eric Mooney", "", "Invaders by Erik Mooney (4-24-97) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cd34b3b3ef9e485201e841ba71beb253", "Bradford W. Mott", "", "Hit HMOVE At Various Cycles After WSYNC Test (Bradford W. Mott) (1998) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cd38ad19f51b1048d8e5e99c86a2a655", "", "", "Demo Image Series #5 - Flag (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cd399bc422992a361ba932cc50f48b65", "Arcadia Corporation, Brian McGhie", "AR-4104", "Rabbit Transit (Preview) (1983) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cd3e26786136a4692fd2cb2dfbc1927e", "", "", "Multiple Moving Objects Demo 2 (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cd4423bd9f0763409bae9111f888f7c2", "Jone Yuan Telephonic Enterprise Co", "", "River Raid (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cd4ded1ede63c4dd09f3dd01bda7458c", "Future Video Games", "", "Laser Gate (Future Video Games) (PAL)", "AKA Innerspace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cd568d6acb2f14477ebf7e59fb382292", "Videospielkassette - Ariola", "PGP235", "Fussball (Ariola) (PAL)", "AKA International Soccer", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cd5af682685cfecbc25a983e16b9d833", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX26133", "A-Team, The (05-08-1984) (Atari) (Prototype)", "AKA Saboteur", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cd88ef1736497288c4533bcca339f881", "SEGA - Teldec", "005-10", "Buck Rogers - Planet of Zoom (1983) (SEGA) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "cd8fa2e9f6255ef3d3b9b5a4f24a54f7", "", "", "Daredevil (V2) (Stunt_Cycle_Rules!) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cd98be8a48ebf610c9609a688b9c57f2", "Arcadia Corporation, Steve Hales, Stephen H. Landrum", "4 AR-4102", "Suicide Mission (1982) (Arcadia) (Prototype)", "AKA Meteoroids", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "cd9fea12051e414a6dfe17052067da8e", "Paul Slocum", "", "Marble Craze Demo (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cda38714267978b9a8b0b24bee3529ae", "", "", "Space Instigators (V1.6) (17-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cdadb57b34438805ee322ff05bd3d43e", "Thomas Jentzsch", "", "Centipede - Amiga Mouse Hack v1.4 (PAL60) (Full-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cdb81bf33d830ee4ee0606ee99e84dba", "Arcadia Corporation, Scott Nelson", "AR-4300", "Fireball (1982) (Arcadia) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" },
+  { "cdc1a5c61d7488eadc9aba36166b253d", "Retroactive", "", "Qb (V0.12) (Stella) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "cddabfd68363a76cd30bee4e8094c646", "Computer Magic - CommaVid, John Bronstein", "CM-001", "MagiCard (1981) (CommaVid)", "Uses the Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ce17325834bf8b0a0d0d8de08478d436", "", "", "Boring Freeway (Hack)", "Hack of Freeway", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ce1cbe159b9ae5992dacf09371de5e13", "Atari - GCC, Kevin Osborn", "CX2689", "Kangaroo (01-19-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ce243747bf34a2de366f846b3f4ca772", "Home Vision - Gem International Corp. - VDI", "", "Jacky Jump (1983) (Home Vision) (PAL)", "AKA Bobby Is Going Home", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ce4bbe11d682c15a490ae15a4a8716cf", "", "", "Okie Dokie (Older) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ce5524bb18e3bd8e092273ef22d36cb9", "Carrere Video - JWDA, Todd Marshall, Wes Trager, Henry Will IV - Teldec - Prism", "USC1004", "Commando Raid (1983) (Carrere Video) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ce5cc62608be2cd3ed8abd844efb8919", "Atari - Bobco, Robert C. Polaro", "CX2663", "Road Runner (1989) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ce64812eb83c95723b04fb56d816910b", "Retroactive", "", "Qb (V2.04) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "ce6c4270f605ad3ce5e82678b0fc71f8", "", "", "Vertical Rainbow Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ce82a675c773ff21e0ffc0a4d1c90a71", "", "", "Defender 2 (Genesis)", "Genesis controller (C is smartbomb)", "Hack of Defender 2", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ce8467ae2a3a5bc88ca72a2ce44ce28c", "SOLID Corp. (D. Scott Williamson)", "CX2655-015", "Star Castle 2600 (SolidCorp) (PAL) [015]", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "ce89529d6e98a13ddf3d84827bbdfe68", "", "", "Kung Fu Sprite Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "ce904c0ae58d36d085cd506989116b0b", "Telegames", "5687 A279", "International Soccer (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cea9f72036dc6f7af5eff52459066290", "Retroactive", "", "Qb (2.07) (Retroactive) (Stella)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "ceba7965a93c689bdecdb46a5b2ac0c1", "Thomas Jentzsch", "", "Reactor - Atari Trak-Ball Hack v1.3 (PAL60) (Half-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cedbd67d1ff321c996051eec843f8716", "Ultravision", "1044", "Karate (1982) (Ultravision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cef01595000627ee50863d4290372c27", "", "", "Many Blue Bars and Text Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cef2287d5fd80216b2200fb2ef1adfa8", "Milton Bradley Company", "4363", "Spitfire Attack (1983) (Milton Bradley)", "AKA Flight Commander)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cf0c593c563c84fdaf0f741adb367445", "Retroactive", "", "Qb (V0.05) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "cf3a9ada2692bb42f81192897752b912", "", "", "Air Raiders (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cf3c2725f736d4bcb84ad6f42de62a41", "Rainbow Vision - Suntek", "SS-009", "Bermuda, The (1983) (Rainbow Vision) (PAL) [a]", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cf507910d6e74568a68ac949537bccf9", "SEGA, Jeff Lorenz", "003-01", "Thunderground (1983) (SEGA)", "AKA Underground", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "cf63ffac9da89ef09c6c973083061a47", "CCE", "C-859", "MASH (1983) (CCE)", "AKA M.A.S.H", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cf9069f92a43f719974ee712c50cd932", "Video Gems", "VG-04", "Mission Survive (1983) (Video Gems) (PAL)", "", "", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "cfad2b9ca8b8fec7fb1611d656cc765b", "Bit Corporation", "PG207", "Mission 3,000 A.D. (1983) (BitCorp) (PAL) [demo cart]", "demonstration cartridge", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "cfb3260c603b0341d49ddfc94051ec10", "Dactari - Milmar", "", "Boxing (Dactari - Milmar)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cfb83a3b0513acaf8be4cae1512281dc", "Starpath Corporation", "", "Going-Up (1983) (Starpath) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cfc226d04d7490b69e155abd7741e98c", "Atari, Matthew L. Hubbard", "CX26159", "Double Dunk (1989) (Atari) (PAL)", "AKA Super Basketball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cfce5596a7e8ca13529e9804cad693ef", "Canal 3 - Intellivision", "", "Tennis (Canal 3) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cfd5518c71552b8bb853b0e461e328d7", "Bit Corporation", "R320", "Spider Fighter (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cfd6a8b23d12b0462baf6a05ef347cd8", "Activision, Larry Kaplan", "AX-006", "Bridge (1980) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cfdb4d0427a1ea8085c6bc6eb90259d8", "", "", "Gunfight 2600 - Release Candidate (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cfe2185f84ce8501933beb5c5e1fd053", "", "", "Football (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cfe62ed7125ff9fae99b4c8a367c0399", "Activision, Larry Miller", "AX-026, AX-026-04", "Enduro (1983) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cfee10bd7119f10b136921ced2ee8972", "", "", "Space Instigators (V1.8) (19-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cfef1a2d1f6a5ee7a5e1f43f3056f112", "", "", "Skeleton+ (05-05-2003) (Eric Ball) (NTSC)", "", "", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cff1e9170bdbc29859b815203edf18fa", "Retroactive", "", "Push (V0.01) (1998) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "cff578e5c60de8caecbee7f2c9bbb57b", "George Veeder", "", "Suicide Adventure (George Veeder) (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "cff9950d4e650094f65f40d179a9882d", "Paul Slocum", "", "Mr. Roboto (Paul Slocum) (Hack)", "Hack of Berzerk", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "cfffc4b97d01cc3e7b9f47575f7b11ec", "Xonox - K-Tel Software, Anthony R. Henderson", "99007, 6240", "Tomarc the Barbarian (1983) (Xonox) (PAL60)", "Genesis controller (B is jump and throw, C switches between players)", "Hack of Tomarc the Barbarian", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d00f6f8ba89559e4b20972a478fc0370", "Spiceware", "SW-01", "Medieval Mayhem (PAL)", "", "Homebrew", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 55", "", "", "", "" },
+  { "d010e3dfe7366e47561c088079a59439", "Retroactive", "", "Qb (V0.10) (Stella) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "d026716b3c5be2c951cc4c064317c524", "", "", "Fu Kung! (V0.06) (14-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d0498baca989e792db4b8270a02b9624", "", "", "Pac Ghost Sprite Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d071d2ec86b9d52b585cc0382480b351", "UA Limited", "", "Cat Trax (1983) (UA Limited) (1) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "d078674afdf24a4547b4b32890fdc614", "Jone Yuan Telephonic Enterprise Co", "", "Laser Blast (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d078d25873c5b99f78fa267245a2af02", "SEGA - Beck-Tech, Steve Beck, Phat Ho", "006-01", "Congo Bongo (1983) (SEGA) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d0796a0317abf9018d6745086bef411f", "Edward Smith", "", "Alien Attack (2018)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d08fccfbebaa531c4a4fa7359393a0a9", "Activision, David Crane, Bob Whitehead", "", "Venetian Blinds Demo (1981) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d090836f0a4ea8db9ac7abb7d6adf61e", "Hozer Video Games", "", "Yahtzee (Hozer Video Games)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "d09935802d6760ae58253685ff649268", "Telesys, Don Ruffcorn", "1006", "Demolition Herby (1983) (Telesys)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "d09a7504ee8c8717ac3e24d263e7814d", "Activision, Matthew L. Hubbard, Bob Whitehead", "AX-024", "Dolphin (1983) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d09f1830fb316515b90694c45728d702", "Imagic, Brad Stewart", "720105-1A, IA3400", "Fire Fighter (1982) (Imagic)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d0a379946ed77b1b126230ca68461333", "Ataripoll", "", "Atari Invaders (Ataripoll) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d0af33865512e9b6900714c26db5fa23", "Telegames", "", "Armor Ambush (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d0b26e908370683ad99bc6b52137a784", "Apollo - Games by Apollo, Larry Minor, Ernie Runyon, Ed Salvo - RCA Video Jeux", "AP-2004", "Lost Luggage (1982) (Apollo) (PAL)", "AKA La valise piegee", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d0b9df57bfea66378c0418ec68cfe37f", "20th Century Fox Video Games - Sirius, Grady Ward", "11002", "Beany Bopper (1982) (20th Century Fox)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d0b9f705aa5f61f47a748a66009ae2d2", "", "", "Synthcart (14-01-2002) (Paul Slocum)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "d0cb28e1b7bd6c7f683a0917b59f707e", "Atari, Gary Palmer", "CX2661P", "Fun with Numbers (1980) (Atari) (PAL) (4K)", "AKA Basic Math", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d0cdafcb000b9ae04ac465f17788ad11", "Quelle - Otto Versand", "732.273 8 - 600273, 781644", "Lilly Adventure (1983) (Quelle) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d0e05ba5f10e3df3023c5ee787f760ef", "Thomas Jentzsch", "", "Centipede - Atari Mouse Hack v1.4 (PAL) (Half-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d0e15a3ce322c5af60f07343594392af", "Amiga - Video Soft", "3125", "Surf's Up (1983) (Amiga) (Prototype) (4K)", "Uses the Joyboard controller", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d0e9beb2347595c6c7d158e9d83d2da8", "Retroactive", "", "Qb (2.00) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "d100b11be34a1e5b7832b1b53f711497", "", "", "Robotfindskitten2600 (26-04-2003) (Jeremy Penner) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d15655fe355fa57dd541487dc5725145", "Rentacom", "", "Vanguard (Rentacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d170317ae4c7d997a989c7d6567c2840", "Jone Yuan Telephonic Enterprise Co", "", "Stampede (Jone Yuan) (4K) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d175258b2973b917a05b46df4e1cf15d", "Suntek", "SS-032", "Walker (1983) (Suntek) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d17a671029b1532b197defca5f3649a7", "Hozer Video Games", "", "Gunfight 2600 - Limit broken again! (2001) (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d17a8c440d6be79fae393a4b46661164", "", "", "Warring Worms (Beta 3) (2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d1a1841b7f2007a24439ac248374630a", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (1 of 4) (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d1a9478b99d6a55e13a9fd4262da7cd4", "U.S. Games Corporation, Garry Kitchen - Vidtec", "VC1001", "Space Jockey (1982) (U.S. Games) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d1b4075925e8d3031a7616d2f02fdd1f", "", "", "Demo Image Series #7 - Two Marios (27-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d1c3520b57c348bc21d543699bc88e7e", "Gameworld", "133-002", "Warplock (1983) (Gameworld) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01", "", "", "YES", "" },
+  { "d1ca47b262f952413c1234117c4e4e21", "Bit Corporation", "R320", "Missile Command (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d1d704a7146e95709b57b6d4cac3f788", "Atari, Warren Robinett", "CX26163P", "Slot Racers (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d20e61c86ed729780feca162166912ca", "Supergame", "32", "Pitfall (1984) (Supergame)", "AKA Pitfall!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d214c7a734e133a5c18e93229435b57a", "Digivision", "", "Mickey (Digivision)", "AKA Sorcerer's Apprentice", "", "", "", "UASW", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d223bc6f13358642f02ddacfaf4a90c9", "Rainbow Vision - Suntek", "SS-003", "Pac-Kong (1983) (Rainbow Vision) (PAL)", "AKA Inca Gold", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d245e2f27c84016041e9496b66b722fe", "", "", "Gunfight 2600 - The Final Kernel (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d25018349c544320bf3fd5092ee072bc", "Activision, Larry Miller", "AX-021", "Spider Fighter (1983) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d28afe0517a046265c418181fa9dd9a1", "", "", "Dodge 'Em (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d2901c34bb6496bb96c7bc78a9e6142a", "Greg Zumwalt", "", "Fish Revenge (2003) (Greg Zumwalt) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d2c4f8a4a98a905a9deef3ba7380ed64", "Mythicon, Bill Bryner, Bruce de Graaf", "MA1001", "Sorcerer (1983) (Mythicon)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d2c8e6aa8172b16c8aa9aae739ac9c5e", "Activision, David Crane", "08-08-1980", "Laser Blast (08-08-1980) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d2c957dd7746521b51bb09fde25c5774", "Eckhard Stolberg", "", "Cubis (6K) (1997) (Eckhard Stolberg)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d2d8c4f1ea7f347c8bcc7d24f45aa338", "", "", "20 Sprites at Once Demo 5 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d2deddb77c8b823e4be9c57cb3c69adc", "Canal 3 - Intellivision", "C 3007", "Snoopy and the Red Baron (Canal 3)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d2f713c78a9ebba9da6d10aeefc6f20f", "Digivision", "", "Enduro (Digivision) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d3171407c3a8bb401a3a62eb578f48fb", "ZiMAG - Emag - Vidco", "GN-080", "Spinning Fireball (1983) (ZiMAG) (Prototype) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "d326db524d93fa2897ab69c42d6fb698", "Parker Brothers - Roklan, Paul Crowley, Bob Curtiss", "931505", "Super Cobra (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d339b95f273f8c3550dc4daa67a4aa94", "", "", "Laser Blast (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d341d39774277cee6a1d378a013f92ac", "Xonox, John Perkins", "6230, 7210, 06004, 99004", "Artillery Duel (1983) (Xonox) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d3423d7600879174c038f53e5ebbf9d3", "U.S. Games Corporation - Western Technologies", "VC2005", "Piece o' Cake (1983) (U.S. Games)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 60", "", "", "", "" },
+  { "d3456b4cf1bd1a7b8fb907af1a80ee15", "Avalon Hill, Duncan Scott", "5003002", "Wall Ball (1983) (Avalon Hill)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "d34b933660e29c0a0a04004f15d7e160", "", "", "Multi-Color Demo 5 (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d36308387241e98f813646f346e7f9f7", "King Atari", "", "Ghostbuster 2 (King Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "d39e29b03af3c28641084dd1528aae05", "Funvision - Fund. Int'l Co.", "", "Spider Monster (1982) (Funvision) (PAL)", "AKA Spider Kong", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d3bb42228a6cd452c111c1932503cc03", "UA Limited", "", "Funky Fish (1983) (UA Limited) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "d44d90e7c389165f5034b5844077777f", "Parker Brothers, Larry Gelberg", "PB5065", "Star Wars - Ewok Adventure (1983) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d45bf71871b196022829aa3b96bfcfd4", "Activision, Steve Cartwright", "AX-017, AX-017-04", "MegaMania (1982) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d45ebf130ed9070ea8ebd56176e48a38", "SEGA, Jeff Lorenz", "001-01", "Tac-Scan (1983) (SEGA)", "Uses the Paddle Controllers (right only)", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "YES", "", "", "AUTO 60", "", "", "YES", "" },
+  { "d47387658ed450db77c3f189b969cc00", "PlayAround - J.H.M.", "206", "Westward Ho (1982) (PlayAround) (PAL)", "AKA Custer's Revenge", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d4806775693fcaaa24cf00fc00edcdf3", "Atari - Bobco, Robert C. Polaro", "CX26140, CX26140P", "Desert Falcon (1987) (Atari) (PAL)", "AKA Nile Flyer, Sphinx", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d483f65468d9a265661917bae1a54f3e", "Joe Grand", "", "SCSIcide Pre-release 3 (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d4942f4b55313ff269488527d84ce35c", "Atari - GCC, Mark Ackerman, Glenn Parker", "CX2675, CX2675P", "Ms. Pac-Man (1982) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d49aff83f77a1b9041ad7185df3c2277", "", "", "Space Treat (60% complete) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d4aa89e96d2902692f5c45f36903d336", "", "", "Euchre (NTSC) (Erik Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d4c590ccfb611a73b3331359700c01a3", "", "", "Sprite Movement Demo 2 (2001) (Roger Williams)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d541b20eae221a8ee321375e5971e766", "Arcadia Corporation, Stephen H. Landrum", "AR-4101", "Communist Mutants from Space (Preview) (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d54cd41ecfd59e4b72d2c086152b9a75", "Amiga - Video Soft - Michael K. Glass, Jerry Lawson", "1110", "Power Play Arcade Video Game Album (1983) (Amiga) (Prototype)", "3-D Ghost Attack only (3-D Genesis & 3-D Havoc missing in ROM)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "d5618464dbdc2981f6aa8b955828eeb4", "CCE", "C-829", "Megamania (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d563ba38151b8204c9f5c9f58e781455", "Atari, Brad Stewart - Sears", "CX2649, 49-75163", "Asteroids (1981) (Atari) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "d573089534ca596e64efef474be7b6bc", "Parker Brothers, John Emerson", "931511", "Action Force (1983) (Parker Bros) (PAL) [a]", "AKA G.I. Joe - Cobra Strike", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 55", "", "", "", "" },
+  { "d57913088e0c49ac3a716bf9837b284f", "Activision, Garry Kitchen", "EAZ-032", "Pressure Cooker (1983) (Activision) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d57eb282d7540051bc9b5427cf966f03", "Atari Troll", "", "Custer's Viagra (Atari Troll) (Hack)", "Hack of Custer's Revenge", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d597d35c6022c590d6e75e865738558a", "", "", "Sprite Color Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d5aa7472e7f2cc17e893a1a36f8dadf0", "", "", "Overhead Adventure Demo 5 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d5c6b81212ad86fd9542a1fedaf57cae", "", "", "Sprite Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d5d2d44fb73785996ccc24ae3a0f5cef", "Robby", "", "Grand Prix (Robby)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d5e17022d1ecc20fd9b53dc464c302f1", "Activision, Carol Shaw", "EAX-020", "River Raid (1982) (Activision) (SECAM)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d5e27051512c1e7445a9bf91501bda09", "Activision, David Crane", "AG-008", "Laser Blast (1981) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d5e5b3ec074fff8976017ef121d26129", "Star Game", "003", "River Raid (Star Game)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d5f965c159e26a1fb49a22a47fbd1dd0", "Supergame", "", "River Raid II (Supergame)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d605ed12f4eaaaec3dcd5aa909a4bad7", "", "", "Chronocolor Frame Demo (10-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d61629bbbe035f45552e31cef7d591b2", "", "", "Atari Logo Demo (PD) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d62283aed0f4199adb2333de4c263e9c", "Atari, Alan J. Murphy, Nick 'Sandy Maiwald' Turner", "CX2615", "Demons to Diamonds (1982) (Atari) (PAL)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 57", "", "", "", "" },
+  { "d62d7d1a974c31c5803f96a8c1552510", "", "", "StarMaster (Unknown) (PAL)", "Use Color/BW switch to change between galactic chart and front views", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d632b74fea533d593af82cf16e7c5e4a", "", "", "Fu Kung! (V0.13) (01-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "d65028524761ef52fbbdebab46f79d0f", "CCE", "", "Galaxian (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d65900fefa7dc18ac3ad99c213e2fa4e", "", "", "Guntest (2000) (Eckhard Stolberg)", "Light Gun Test (based on Sentinel code)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d69559f9c9dc6ef528d841bf9d91b275", "Activision, Alan Miller", "AX-016", "StarMaster (1982) (Activision)", "Use Color/BW switch to change between galactic chart and front views", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d6a44277c3eb4f9d039185e0ecf7bfa6", "", "", "Trick (1997) (Eckhard Stolberg)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d6acff6aed0f04690fe4024d58ff4ce3", "Spectravision - Spectravideo - Quelle", "SA-202 - 412.851 8", "Planet Patrol (1982) (Spectravision) (PAL) [different spaceship]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d6b8beeb05e5b730084d4b8f381bbf8d", "", "", "208 in 1 Game Select ROM (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d6d1ddd21e9d17ea5f325fa09305069c", "Funvision - Fund. International Co.", "", "Time Warp (1982) (Funvision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d6d5dd8fd322d3cf874e651e7b6c1657", "", "", "How to Draw a Playfield (1997) (Nick Bensema) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d6dc9b4508da407e2437bfa4de53d1b2", "Bomb - Onbase", "CA283", "Z-Tack (1983) (Bomb) (PAL)", "AKA Base Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d726621c676552afa503b7942af5afa2", "Atari, Bob Whitehead", "CX26163P", "Blackjack (32 in 1) (1988) (Atari) (PAL) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d73ad614f1c2357997c88f37e75b18fe", "Goliath", "7", "Space Tunnel (1983) (Goliath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d74a81fcd89c5cf0bd4c88eb207ebd62", "", "", "Poker Squares (V0.00a) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d763e3a9cdcdd56c715ec826106fab6a", "Activision, David Crane", "AG-001", "Dragster (1980) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d7759fa91902edd93f1568a37dc70cdb", "Atari, Robert C. Polaro", "CX26157", "Stunt Cycle (1980) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d782543818b6320e4f60d77da2b596de", "Atari", "CX26163P", "Fishing Derby (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d787ec6785b0ccfbd844c7866db9667d", "Retroactive", "", "Qb (V0.04) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "d7891b0faa4c7f764482762d0ed427a5", "", "", "Bars and Text Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d7b2259f6bb57bf37eac82365c1f8ad6", "Parker Brothers, Mike Brodie", "PB5320", "Super Cobra (1983) (Parker Bros) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d7b58303ec8d8c4dbcbf54d3b9734c7e", "", "", "Paddle Demo (Joe Grand) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d7dd56677e4ec1e6627419478a4a9668", "", "", "Shadow Keep (Fixed) (04-03-2003) (Andrew Towers)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d7f5bf138cfc7feab7b8ef1534c8b477", "", "", "Eric Bergstrom's KC-135 (Radar Map) (Aaron Bergstrom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d816fea559b47f9a672604df06f9d2e3", "Atari, Gary Palmer", "CX26163P", "Fun with Numbers (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d81bb6965e6c99b3be99ffd8978740e4", "", "", "Gunfight 2600 - The Final Kernel Part 3 (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d82675ce67caf16afe5ed6b6fac8aa37", "Thomas Jentzsch", "", "Robot City (V0.23) (13-11-2002) (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d8295eff5dcc43360afa87221ea6021f", "Spectravideo", "SA-212", "Mangia' (1983) (Spectravideo) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d82c8a58098a6b46c5b81c16180354d1", "Dennis Debro", "", "Climber 5 (30-10-2002) (Dennis Debro) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d85f1e35c5445ac898746719a3d93f09", "Suntek", "SS-034", "Farmyard Fun (1983) (Suntek) (PAL)", "AKA Play Farm", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d86deb100c6abed1588aa84b2f7b3a98", "Atari, Bob Whitehead - Sears", "CX2625 - 6-99827, 49-75114", "Football (1979) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d88691c995008b9ab61a44bb686b32e4", "", "", "Warring Worms (07-02-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d89262907e70c13dff23356c4a9055d0", "Bit Corporation", "R320", "Video Pinball (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d89fedded0436fdeda7c3c37e2fb7cf1", "", "", "Surround (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d8acaa980cda94b65066568dd04d9eb0", "CCE", "", "Sea Hunt (CCE)", "AKA Skindiver", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d8b2c81cea5af04f795eb3dc6573d72b", "", "", "Tunnel Demo 2 (27-03-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d8df256c0d89e494a9fb3e9abb8e44ac", "Imagic, Michael Greene", "IA3312P", "No Escape! (1982) (Imagic) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d8e4c8e2d210270cd1e0f6d1b4582b91", "Imagic, Mark Klein", "EIZ-003-04I", "Subterranea (1983) (Imagic) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d90205e29bb73a4cdf28ea7662ba0c3c", "Thomas Jentzsch", "", "Boulderdash Demo (Brighter Version) (09-12-2002) (TJ)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "d912312349d90e9d41a9db0d5cd3db70", "CCE", "C-818", "Star Voyager (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d9548ad44e67edec202d1b8b325e5adf", "Apollo - Games by Apollo, Dan Oliver - RCA Video Jeux", "AP-2002", "Space Cavern (1982) (Apollo) (PAL)", "AKA Les guerriers de l'espace", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d968de2b4ff18bfe4a95066cde310578", "Thomas Jentzsch", "", "Centipede - Amiga Mouse Hack v1.4 (PAL) (Half-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d97e3d0b4575ce0b9a6132e19cfeac6e", "Fabrizio Zavagli", "", "Space Treat (061002) (PD)", "Won't work with Stella < V1.2", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d97fd5e6e1daacd909559a71f189f14b", "M Network, Steve Crandall, Patricia Lewis Du Long", "MT4646", "Rocky & Bullwinkle (04-20-1983) (M Network) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d9ab6b67a17da51e5ad13717e93fa2e2", "Thomas Jentzsch", "", "Turbo (Coleco) Prototype Fake v0.1 (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d9b49f0678776e04916fa5478685a819", "Activision, John Van Ryzin - Ariola", "EAZ-036-04, EAZ-036-04B, EAZ-036-04I - 711 036-720", "H.E.R.O. (1984) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d9bd343533b61389b270c0787210943b", "Atari, Douglas 'Solaris' Neubauer", "CX26134", "Last Starfighter (1984) (Atari) (Prototype)", "Genesis controller (C switches to map mode)", "Hack of Last Starfighter (Solaris prototype)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "d9c9cece2e769c7985494b1403a25721", "SOLID Corp. (D. Scott Williamson)", "CX2655*", "Star Castle 2600 (SolidCorp)", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "d9da2ae7c7894a29b43b3c6b79f3b7a2", "Atari, Rob Fulop", "CX2633, CX2633P", "Night Driver (1980) (Atari) (PAL) (4K)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "YES", "" },
+  { "d9fbf1113114fb3a3c97550a0689f10f", "ZiMAG - Emag - Vidco", "713-111 - GN-050", "Pizza Chef (1983) (ZiMAG) (Prototype)", "AKA Pizza Time", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "da0fb2a484d0d2d8f79d6e063c94063d", "", "", "Air Raiders (1982) (Unknown) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "da4e3396aa2db3bd667f83a1cb9e4a36", "Activision, Steve Cartwright", "AX-027", "Plaque Attack (1983) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "da5096000db5fdaa8d02db57d9367998", "Digitel", "", "River Raid (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "da6465a34d2e44d26aa9a2a0cd1bce4d", "Absolute Entertainment, Alex DeMeo", "AG-041-04", "Title Match Pro Wrestling (1987) (Absolute) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "da66d75e4b47fab99733529743f86f4f", "Digitel", "", "Chopper Command (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "da732c57697ad7d7af414998fa527e75", "Atari - Glenn Axworthy", "CX26129", "Midnight Magic (1986) (Atari) (PAL)", "AKA Pinball Wizard", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "da79aad11572c80a96e261e4ac6392d0", "Salu - Ubi Soft, Dennis M. Kiss", "460673", "Pick 'n' Pile (1990) (Salu) (PAL)", "", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "da7a17dcdaa62d6971393c0a6faf202a", "", "", "Flag Capture (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dab844deed4c752632b5e786b0f47999", "", "", "Super Challenge Baseball (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dac38b4dd3da73bb7b2e9d70c61d2b7c", "", "", "Hangman Monkey Biglist3 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dac5c0fe74531f077c105b396874a9f1", "Atari - GCC", "CX2680", "RealSports Tennis (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dac762e4d01d445bdef20b7771f6570e", "Atari, Carla Meninsky, Ed Riddle - Sears", "CX2611 - 99821, 49-75149", "Indy 500 (1977) (Atari) (4K) [a]", "Uses the Driving Controllers", "", "", "", "", "", "", "", "", "DRIVING", "", "", "DRIVING", "", "", "", "", "", "45", "", "", "", "" },
+  { "dad2ab5f66f98674f12c92abcfbf3a20", "", "", "Blue and White Sprite Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "daeb54957875c50198a7e616f9cc8144", "20th Century Fox Video Games, Douglas 'Dallas North' Neubauer", "11005", "Mega Force (1982) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "daef7d8e5a09981c4aa81573d4dbb380", "Adam Thornton", "", "Lord of the Rings (Adam Thornton) (Hack)", "Hack of Dark Mage", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "dafc3945677ccc322ce323d1e9930beb", "Atari", "", "A-Team (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "db1753cc702c18d3917ec7f3b0e8659f", "", "", "Frame Counter 2 (2001) (Jake Patterson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "db339aea2b65b84c7cfe0eeab11e110a", "", "", "Chronocolor Frame Demo 2 (10-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "db4eb44bc5d652d9192451383d3249fc", "CBS Electronics - E.F. Dreyer - VSS, Ed Salvo", "4L 2738 0000", "Mountain King (1983) (CBS Electronics)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "db5073bd75eb05f7d62a7268396d1e77", "Atari", "CX26163P", "Golf (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "db76f7a0819659d9e585f2cdde9175c7", "Xonox", "99005, 6220, 6250", "Robin Hood (1983) (Xonox) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "db80d8ef9087af4764236f7b5649fa12", "M Network, Steve Crandall, Patricia Lewis Du Long", "MT4646", "Rocky & Bullwinkle (1983) (Mattel) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "db971b6afc9d243f614ebf380af0ac60", "Gammation, Robert L. Esken Jr.", "", "Gamma-Attack (1983) (Gammation)", "Uses right joystick controller", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dba270850ae997969a18ee0001675821", "Greg Troutman", "", "Dark Mage (Greg Troutman) (PD) (4K)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "dbabb80e92ff18d8eecf615c0539151e", "", "", "Sprite Demo 3 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dbb10b904242fcfb8428f372e00c01af", "Atari, John Dunn", "CX2631, CX2631P", "Superman (1979) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dbba14a0f69f0e13fdccb3fde3baedca", "Thomas Jentzsch", "", "Reactor - Atari Trak-Ball Hack v1.3 (NTSC) (Full-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dbc7485ad5814d466de780a3e7ed3b46", "Kyle Pittman", "", "Pink Floyd (Kyle Pittman) (PD)", "Hack of Adventures of Tron (Mattel)", "New Release (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dbc8829ef6f12db8f463e30f60af209f", "Data Age", "DA1001", "Encounter at L-5 (1982) (Data Age)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 50", "", "", "", "" },
+  { "dbdaf82f4f0c415a94d1030271a9ef44", "CCE", "", "Kaboom! (CCE)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
+  { "dbdd21e1ee3d72119e8cd14d943c585b", "", "", "Slot Machine (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dc13df8420ec69841a7c51e41b9fbba5", "Atari, Mimi Nyden, Steve Woita", "CX26132", "Garfield (06-21-1984) (Atari) (Prototype)", "AKA Garfield on the Run", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dc33479d66615a3b09670775de4c2a38", "Suntek", "SS-033", "I.Q. Memory Teaser (1983) (Suntek) (PAL)", "AKA IQ 180", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dc81c4805bf23959fcf2c649700b82bf", "Imagic, Michael Greene", "720055-2A, IA3312P", "No Escape! (1983) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dc905b22de0f191a029df13eddfcabc4", "Atari, Warren Robinett", "", "Elf Adventure (05-02-83) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dc97cbcf091a5ef4ca7fe95dc0848036", "Atari - Roklan, Joe Gaucher, Alex Leavens", "CX2683", "Crazy Climber (1983) (Atari) (Prototype) [a2]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dca90ea1084a2fdbe300d7178ca1a138", "Imagic, Dennis Koble", "IA3000P", "Trick Shot (1982) (Imagic) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "dca941dab5c6f859b71883b13ade9744", "", "", "Hangman Pac-Man Biglist2 (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dcba0e33aa4aed67630a4b292386f405", "Retroactive", "", "Qb (V2.08) (Half Speed Version) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "dcc2956c7a39fdbf1e861fc5c595da0d", "M Network - INTV - APh Technological Consulting, David Rolfe", "MT5664", "Frogs and Flies (1982) (M Network)", "AKA Frogs 'n' Flies", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dcec46a98f45b193f07239611eb878c2", "", "", "Bars and Text Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dd08e18cfee87a0e7fc19a684b36e124", "Atari - GCC, Kevin Osborn", "CX2689, CX2689P", "Kangaroo (1983) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dd0cbe5351551a538414fb9e37fc56e8", "Xonox - K-Tel Software - Product Guild, Anthony R. Henderson", "99006, 6220", "Sir Lancelot (1983) (Xonox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dd0de0f61af2a2a4878e377b880a3933", "SOLID Corp. (D. Scott Williamson)", "CX2655-013", "Star Castle 2600 (SolidCorp) [013]", "http://starcastle2600.blogspot.com/p/star-castle-2600-story.html", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "dd10b5ee37fdbf909423f2998a1f3179", "", "", "Space Instigators (V1.9) (21-10-2002) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dd13a16d14100819f79b1ce3a5bf499c", "Thomas Jentzsch", "", "Missile Control - Atari Mouse Hack v1.15 (PAL) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dd1422ffd538e2e33b339ebeef4f259d", "Atari, Michael Sierchio", "", "Football Demo (1982) (Atari)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dd17711a30ad60109c8beace0d4a76e8", "", "", "Karate (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dd1842ba0f3f9d94dccb21eaa0f069b7", "Bit Corporation", "R320", "Defender (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dd45e370aceff765f1e72c619efd4399", "Bit Corporation", "PG201", "Sea Monster (1982) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dd4f4e0fbd81762533e39e6f5b55bb3a", "Thomas Jentzsch", "", "Turbo WIP (TJ)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dd7598b8bcb81590428900f71b720efb", "Xonox - K-Tel Software - Computer Magic", "99005, 6220, 6250", "Robin Hood (1983) (Xonox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dd7884b4f93cab423ac471aa1935e3df", "Atari, Brad Stewart - Sears", "CX2649, 49-75163", "Asteroids (1981) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "dd8a2124d4eda200df715c698a6ea887", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (3 of 3) (1982) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dd92d6ad50976f881d86b52d38616118", "SpkSoft", "", "River Raid (SpkSoft) [h1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dda23757407c4e217f64962c87ad0c82", "Atari Freak 1", "", "Nitemare at Sunshine Bowl-a-Rama (Atari Freak 1) (Hack) [a]", "Hack of Pac-Man Jr.", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ddd1efc1862cd3eb3baf4cba81ff5050", "", "", "Max3 (2001) (Maxime Beauvais) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "de0173ed6be9de6fd049803811e5f1a8", "Xonox - K-Tel Software - Product Guild, Anthony R. Henderson", "99008, 6240", "Motocross Racer (1983) (Xonox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "de07e9cb43ad8d06a35f6506e22c62e9", "", "", "Oh No! (Version 4) (22-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "de1a636d098349be11bbc2d090f4e9cf", "", "", "Pressure Gauge (Hozer Video Games)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "de1e9fb700baf8d2e5ae242bffe2dbda", "Activision - Imagineering, Mike Reidel", "EAK-043-04I", "Commando (1988) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "de24f700fd28d5b8381de13abd091db9", "CCE", "", "Plaque Attack (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "de29e46dbea003c3c09c892d668b9413", "Coleco - Woodside Design Associates, Steve 'Jessica Stevens' Kitchen", "4L1717, 4L1718, 4L1719, 4L2277", "Carnival (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "de3d0e37729d85afcb25a8d052a6e236", "Spectravision - Spectravideo", "SA-204", "Tapeworm (1982) (Spectravision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "de4436eaa41e5d7b7609512632b90078", "Activision, David Crane", "AX-014, AX-014-04", "Grand Prix (1982) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "de5aab22e5aba5edcb29a3e7491ff319", "Star Game", "001", "Donkey Kong (Star Game)", "AKA Inca Gold", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "de61a0b171e909a5a4cfcf81d146dbcb", "Rainbow Vision - Suntek", "SS-005", "Tom Boy (1983) (Rainbow Vision) (PAL)", "AKA Pitfall!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "de62f8a30298e2325249fe112ecb5c10", "CCE", "C-810", "Enduro (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "de78b3a064d374390ac0710f95edde92", "Bomb - Onbase", "CA281", "Assault (1983) (Bomb)", "AKA Sky Alien", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "de7a64108074098ba333cc0c70eef18a", "", "", "Nuts (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "de7bca4e569ad9d3fd08ff1395e53d2d", "Thomas Jentzsch", "", "Thrust (V1.22) (2000) (TJ)", "Supports BoosterGrip", "New Release", "", "", "", "", "", "", "", "BOOSTERGRIP", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "de8443ff47283e7b274a7838cb071fb6", "Atari, Lou Harp", "CX26122", "Sinistar (01-04-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dea0ade296f7093e71185e802b500db8", "CCE", "", "Fishing Derby (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "deb39482e77f984d4ce73be9fd8adabd", "Activision, David Lubar", "AK-048-04", "River Raid II (1988) (Activision) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ded26e1cb17f875a9c17515c900f9933", "", "", "Space Treat (29-12-2002) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "df12953b919844dad2070ed2e70c9fa2", "Amiga - Video Soft", "3135", "S.A.C. Alert (1983) (Amiga) (Prototype) (PAL)", "Uses Joyboard", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "df2745d585238780101df812d00b49f4", "Bit Corporation", "PG202", "Space Tunnel (1982) (BitCorp)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "df3e6a9b6927cf59b7afb626f6fd7eea", "", "", "Tuby Bird (208 in 1) (Unknown) (PAL)", "AKA Dolphin", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "df40af244a8d68b492bfba9e97dea4d6", "Franklin Cruz", "", "Asteroids 2 (Franlin Cruz) (Hack)", "Hack of Asteroids", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "df5cc5cccdc140eb7107f5b8adfacda1", "Cracker Jack Productions", "", "Lumberman (Cracker Jack) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "df62a658496ac98a3aa4a6ee5719c251", "Atari, Tom Reuterdahl - Sears", "CX2626 - 6-99829, 49-75116", "Miniature Golf (1979) (Atari)", "AKA Arcade Golf", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "df6a28a89600affe36d94394ef597214", "Apollo - Games by Apollo, Dan Oliver", "AP-2002", "Space Cavern (1982) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "df6a46714960a3e39b57b3c3983801b5", "Puzzy - Bit Corporation", "PG201", "Sea Monster (1982) (Puzzy) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "df753cb87d3af4d03f694ab848638108", "CBS Electronics, Bob Curtiss", "4L1845, 4L1852, 4L1853, 4L1854", "Solar Fox (1983) (CBS Electronics) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "df91277a3569344b89e6e8bd5bebc8d1", "Thomas Jentzsch", "", "Marble Craze - Amiga Mouse Hack v1.0 (PAL) (TJ)", "Uses Amiga Mouse Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "df95e4af466c809619299f49ece92365", "Atari - CCW, Michael Callahan, Preston Stuart", "CX26103", "Alpha Beam with Ernie (06-03-1983) (Atari) (Prototype) (PAL)", "Uses Keypad Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dfad86dd85a11c80259f3ddb6151f48f", "HES - Imagineering, David Lubar", "535", "My Golf (1990) (HES) (PAL) [fixed]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dfafa3fa58f5cc3f0342cca475df6095", "", "", "Space Treat (V1.1 Beta) (24-12-2002) (Fabrizio Zavagli)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dfc03ef371cf5163f54c50d8ee73c8cf", "Atari, Gary Palmer", "CX2661", "Fun with Numbers (1980) (Atari) (4K)", "AKA Basic Math", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dfc3dbbb39f05d7dd8ee3ac987478970", "", "", "Imagic Selector ROM (1982) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dfcdd6f593bb7b05dbc2e8e1fc6ee0de", "", "", "Gunfight 2600 - Scenarios complete (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dfe034297200dff672df9533ed1449a9", "", "", "Sprite Movement Demo 1 (2001) (Roger Williams)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dfe6aa7443bb813cefa35a4cf4887422", "", "", "This Planet Sucks (Greg Troutman) [a1]", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "dff33523ccd2fdc8912e84cab8e0d982", "", "", "Fu Kung! (V0.03) (10-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e01e00504e6d4b88fa743c0bbe8a96e5", "", "", "Qb (Special Edition, some bugfixes) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "e020f612255e266a8a6a9795a4df0c0f", "Telegames - VSS", "7062 A305", "Universal Chaos (1988) (Telegames) (PAL)", "AKA Targ", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e02156294393818ff872d4314fc2f38e", "Sancho - Tang's Electronic Co.", "TEC005", "Dice Puzzle (1983) (Sancho) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "e0221c95aa657f5764eeeb64c8429258", "", "", "Tomb Raider 2600 [REV 02] (Montezuma's Revenge Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e03b0b091bea5bc9d3f14ee0221e714d", "CBS Electronics, Bob Curtiss", "4L1852, 4L1853, 4L1854, 4L1855", "Solar Fox (1983) (CBS Electronics) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e040df95a055b18ebdb094e904cb71b2", "", "", "Score Demo (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e04f1c1e4401d584d3f4343410a5bcc4", "Wizard Video Games - MicroGraphic Image, Robert Barber, Tim Martin", "007", "Halloween (1983) (Wizard Video Games) (Prototype) [a]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e0b24c3f40a46cda52e29835ab7ad660", "Quelle - Otto Versand", "626.502 9 - 746381", "Top Gun (1983) (Quelle) (PAL)", "AKA Air Raiders", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e0cf2dcc4c1348c468f5bb1e421c9164", "", "", "Invader Sprites in a Line Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e0de3773f5b867795db557be7b8a703e", "", "", "Boulderdash (13 Blocks Wide) (02-04-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e0eff071f578ecf19edc2ab276644e46", "", "", "Gas Gauge Demo (2001) (Joe Grand) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e1029676edb3d35b76ca943da7434da8", "Atari, Robert C. Polaro, Alan J. Murphy - Sears", "CX2609 - 49-75186", "Defender (10-30-1981) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e10bf1af6bf3b4a253c5bef6577fe923", "Rob Kudla", "", "Space Invaders (1978) (Atari) [h1]", "Hack of Space Invaders (Atari)", "New Release (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e10d2c785aadb42c06390fae0d92f282", "Parker Brothers, Dawn Stockbridge", "PB5910", "Strawberry Shortcake - Musical Match-Ups (1983) (Parker Bros)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e1143b72a30d4d3fee385eec38b4aa4d", "", "", "Word Zapper (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e12e32dee68201b6765fcd0ed54d6646", "Atari, Larry Kaplan", "CX2612, CX2612P", "Street Racer (1977) (Atari) (PAL)", "Uses the Paddle Controllers (swapped)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "AUTO 75", "", "", "", "" },
+  { "e13818a5c0cb2f84dd84368070e9f099", "CCE", "C-839", "Misterious Thief, A (1983) (CCE)", "AKA A Mysterious Thief", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "e13c7627b2e136b9c449d9e8925b4547", "Atari, Alan Miller - Sears", "CX2624 - 6-99826, 49-75113", "Basketball (1978) (Atari) (4K)", "", "Common", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e1486c7822c07117b4f94a32e5ed68c1", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (06-14-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e14dc36b24fe22c04fa076e298f2e15f", "Activision, Larry Kaplan, David Crane", "AG-010, AG-010-04", "Kaboom! (1981) (Activision) (16K)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
+  { "e14feddeb82f5160ed5cf9ca4078e58d", "", "", "SpaceMaster X-7 (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e150f0d14f013a104b032305c0ce23ef", "Spectravision - Spectravideo", "SA-205", "China Syndrome (1982) (Spectravision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "e15b5525cf8f77297b322838df8d999c", "", "", "Sprite Demo 0 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e171558c51bb3bac97bfa79fa2c1a19c", "", "", "Warring Worms (Tim Strauss Edition) (20-12-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e17699a54c90f3a56ae4820f779f72c4", "Rainbow Vision - Suntek", "SS-020", "Tuby Bird (1983) (Rainbow Vision) (PAL)", "AKA Dolphin", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e18abe87035379c56b435bfe8175077b", "Grimlock", "", "Rumble 2600 (Grimlock) (Hack)", "Hack of Mario Bros.", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e1a51690792838c5c687da80cd764d78", "20th Century Fox, John Russell", "", "Alligator People (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e1b90f1e01b1a316d7bbf141525cc00e", "", "", "Sky Jinks (Unknown) (PAL) (4K) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e1d5c8213e82820128fa9c4775f1e166", "Jess Ragan", "", "Jungle King (2003) (Jess Ragan) (Hack)", "Hack of Jungle Hunt", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e1d79e4e7c150f3861256c541ec715a1", "", "", "Space Jockey (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e1e09e2f280e8e142121a377d0dc1b46", "Thomas Jentzsch", "", "Thrust (V1.21) (2000) (TJ)", "Bugfixed", "New Release", "", "", "", "", "", "", "", "BOOSTERGRIP", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e1efe2ef7664bb6758b1a22ff8ea16a1", "Dynacom", "", "Enduro (1983) (Dynacom)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e1f88da6da8a7d521ca1dcbf2bc6978b", "Activision, Bob Whitehead - Ariola", "EAG-005, PAG-005, EAG-005-04B - 711 005-715", "Skiing (1980) (Activision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e21ee3541ebd2c23e817ffb449939c37", "Tigervision - Software Electronics Corp., Karl T. Olinger - Teldec", "7-001", "King Kong (1982) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e227be19f572f6900e314213ae9a4deb", "Atari, Dan Hitchens, Mimi Nyden", "CX2656", "SwordQuest - EarthWorld (1982) (Atari) (Prototype)", "AKA Adventure I, SwordQuest I - EarthWorld", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e237ee91514d5ed535c95a14fc608c11", "Activision, Matthew L. Hubbard, Bob Whitehead", "AX-024", "Dolphin (1983) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e2389c0be5b5b84e0d3ca36ec7e67514", "Retroactive", "", "Qb (V2.09) (NTSC) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "e24d7d879281ffec0641e9c3f52e505a", "Parker Brothers, Mark Lesser", "PB5950", "Lord of the Rings (1983) (Parker Bros) (Prototype)", "Journey to Rivendell (The Lord of the Rings I)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e25e173740f7ecc0e23025445c4591f3", "Greg Zumwalt", "", "Comitoid (Greg Zumwalt)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e275cbe7d4e11e62c3bfcfb38fca3d49", "M Network - INTV - APh Technological Consulting, Ken Smith", "MT5658", "Super Challenge Football (1982) (M Network)", "AKA Pro Football", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e27d518993b0a010f16e92b971ecdcdd", "Manuel Polik", "", "Star Fire (2003) (XYPE) (PAL)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e28113d10c0c14cc3b5f430b0d142fcb", "CCE", "C-816", "Keystone Kappers (1983) (CCE) [a]", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e2846af3e4d172b251ab77cbdd01761e", "Steve Engelhardt", "", "Adventure Plus (2003) (Steve Engelhardt) (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e2904748da63dfefc8816652b924b642", "Jone Yuan Telephonic Enterprise Co", "", "Catch Time (Jone Yuan)", "AKA Plaque Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e2b682f6e6d76b35c180c7d847e93b4f", "", "", "Dodge Demo 4 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e2c1b60eaa8eda131632d73e4e0c146b", "Atari - GCC, Mark Ackerman, Noellie Alito", "CX2692", "Moon Patrol (07-04-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e2c89f270f72cd256ed667507fa038a2", "Starpath Corporation, Stephen H. Landrum", "AR-4101", "Communist Mutants from Space (1982) (Arcadia) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e2ca84a2bb63d1a210ebb659929747a9", "Telesys, Don 'Donyo' Ruffcorn", "1002", "Cosmic Creeps (1982) (Telesys) (PAL)", "AKA Space Maze, Spaze Maze", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "e2eccbbe963f80f291cb1f18803bf557", "Atari, Joe Decuir, Steve Mayer, Larry Wagner", "CX26163P", "Combat (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e30f3a37032da52d7815b5a409f6d4b4", "SEGA, Fred Mack", "", "Bear Game Demo (1983) (SEGA)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e314b42761cd13c03def744b4afc7b1b", "Activision, David Crane, Dan Kitchen", "AZ-108-04", "Ghostbusters (1985) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e34c236630c945089fcdef088c4b6e06", "Activision, Steve Cartwright, David Crane - Ariola", "EAB-035-04 - 711 035-721", "Pitfall II (1984) (Activision) (PAL)", "Lost Caverns", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e3533684a7ef930a7fbd0c4dd8ec4847", "CCE", "C-856", "Pimball (1983) (CCE)", "AKA Video Pinball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e3600be9eb98146adafdc12d91323d0f", "Atari, Carol Shaw", "CX2618, CX2618P", "3-D Tic-Tac-Toe (1980) (Atari) (PAL)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e363e467f605537f3777ad33e74e113a", "Atari, Bob Whitehead - Sears", "CX2603 - 99803, 49-75601", "Star Ship (1977) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e377c3af4f54a51b85efe37d4b7029e6", "20th Century Fox Video Games, Beck-Tech, Steve Beck", "11035", "Save the Whales (1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e37c8055d70979af354251ebe9f1b7dd", "HES", "", "Mega Funpak - Gorf, P. Patrol, Pacman, Skeet Shoot (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e38dc1f81a02e325562cd285123f579b", "Atari - GCC, Mike Feinstein", "CX2681, CX2681P", "Battlezone (1983) (Atari) (PAL) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e39843c56b7a4a08b18fa7949ec3ee6b", "", "", "Joshua Invaders (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e39a13b13dc82c5fdbfbbfd55ba1230e", "", "", "Analog Clock (Additional Frame Info) (V0.0) (20-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e3c0451d29dad724231bc5818ec4bae0", "", "", "Single-Scanline Positioning Demo 1 (2001) (Roger Williams)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e3c35eac234537396a865d23bafb1c84", "TechnoVision - Video Technology", "TVS1001", "Nuts (1983) (TechnoVision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e3ed4ba3361756970f076e46e9cad1d2", "", "", "Tennis (Unknown) (PAL) (4K) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e40a818dac4dd851f3b4aafbe2f1e0c1", "Atari, Bill Aspromonte, Dr. Lee Salk", "CX26135", "Peek-A-Boo (1984) (Atari) (Prototype)", "Uses the Keypad Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e42b937c30c617241ca9e01e4510c3f6", "", "", "Pitfall! (No Walls Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e434c0e161dd3c3fb435eb6bad2e182c", "Atari - GCC, Mike Feinstein, Brad Rice", "CX2681", "Battlezone (05-02-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e48d3a4056ede9393586421996db1ae8", "Thomas Jentzsch", "", "Centipede - Atari Trak-Ball Hack v1.4 (PAL60) (Full-Speed) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e49ac0ec879a0d7820bc2598fc2cfcd4", "CCE", "", "Kaboom! (CCE) (4K)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
+  { "e4a0b28befaaa2915df1fa01238b1e29", "", "", "Gunfight 2600 - Red River (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e4afe157c09962cf39cdb25845d83d47", "Activision, David Crane - Ariola", "EAG-009, PAG-009 - 711 009-720", "Freeway (1981) (Activision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e4b12deaafd1dbf5ac31afe4b8e9c233", "Adam Thornton", "", "Lord of the Rings (Adam Thornton) (Hack) [a]", "Hack of Dark Mage", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "e4bff1d5df70163c0428a1ead309c22d", "Atari, Robert C. Polaro, Alan J. Murphy", "CX2609, CX2609P", "Defender (1982) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e4c00beb17fdc5881757855f2838c816", "20th Century Fox Video Games - Sirius, Ed Hodapp", "11004", "Deadly Duck (1982) (20th Century Fox)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e4c2077a18e3c27f4819aa7757903aa0", "", "", "Many Blue Bars Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e4c666ca0c36928b95b13d33474dbb44", "Arcadia Corporation, Steve Hales, Stephen H. Landrum", "4 AR-4102", "Suicide Mission (1982) (Arcadia)", "AKA Meteoroids", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "e4d41f2d59a56a9d917038682b8e0b8c", "Cody Pittman", "", "Kiss Meets Pacman (Cody Pittman) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e4e9125a8741977583776729359614e1", "SnailSoft", "", "Comitoid beta 4 (SnailSoft)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e4fa739c81b003c92bea7da5e84c7feb", "Akor", "", "TV Boy (1992) (Akor) (NTSC) [bad dump]", "Includes 127 games", "", "", "", "", "", "", "", "", "JOYSTICK", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "" },
+  { "e505bd8e59e31aaed20718d47b15c61b", "Funvision - Fund. Int'l Co.", "", "Space War (1982) (Funvision) (PAL)", "AKA Condor Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e51030251e440cffaab1ac63438b44ae", "Parker Brothers - On-Time Software, Joe Gaucher, Louis Marbel", "PB5110", "James Bond 007 (1984) (Parker Bros)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "e51c23389e43ab328ccfb05be7d451da", "Arcadia Corporation, Scott Nelson", "13", "Sweat! - The Decathlon Game (1983) (Arcadia) (Prototype)", "Uses the Paddle Controllers (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e5359cbbbff9c6d7fe8aeff5fb471b46", "CCE", "C-849", "Boom Bang (1983) (CCE)", "AKA Crackpots", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e549f1178e038fa88dc6d657dc441146", "Atari, Bob Whitehead - Sears", "CX2625 - 6-99827, 49-75114", "Football (1979) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e556e07cc06c803f2955986f53ef63ed", "Coleco - Individeo, Ed Temple", "2665", "Front Line (1984) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e558be88eef569f33716e8e330d2f5bc", "Shock Vision", "", "Keystone Kapers (Shock Vision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e56da674188ba2f02c7a0a343a01236f", "", "", "This Planet Sucks Demo 4 (Greg Troutman) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e59d022d524d05acc19515598c831e4d", "Alessandro Ciceri", "", "MagiCard+ (alex_79) WIP_20150118 (PAL)", "MagiCard hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e5a6e0bb7d56e2f08b237e15076e5699", "", "", "Color Table Display Helper (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e5bacf526036d3c8c99db5b030cf00e7", "", "", "Starmaster (Genesis)", "Genesis controller (C switches to map mode)", "Hack of Starmaster", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e5d5085123a98c1e61818caa2971e999", "", "", "Euchre (PAL) (Erik Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e5d72ff8bab4450be57785cc9e83f3c0", "Telegames", "6082 A145", "Kung Fu Superkicks (1988) (Telegames) (PAL)", "AKA Chuck Norris Superkicks", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e5ecd78edd24326a968809decbc7b916", "Imagic, Bob Smith", "720020-1A, IA3611", "Cheese (Dragonfire Beta) (05-21-1982) (Imagic) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "e5f17b3e62a21d0df1ca9aee1aa8c7c5", "CommaVid, John Bronstein", "CM-003", "Cosmic Swarm (1982) (CommaVid)", "AKA Termite", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "e5f360226dc552aba3e7e9b202330f48", "Supercat", "", "Mega Bitmap Demo (2007) (Supercat)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "e5f84930aa468db33c0d0f7b26dd8293", "CCE", "C-826", "Grand Prix (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e5fcc62e1d73706be7b895e887e90f84", "", "", "Air-Sea Battle (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e600f5e98a20fafa47676198efe6834d", "Parker Brothers - Roklan, Joe Gaucher", "PB5080", "Gyruss (1984) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "e609e8a007127b8fcff79ffc380da6b1", "", "", "Multi-Sprite Game V2.3 (Piero Cavina) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e61210293b14c9c4ecc91705072c6a7e", "Gameworld", "133-005", "Bugs (1983) (Gameworld) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 50", "", "", "", "" },
+  { "e62e60a3e6cb5563f72982fcd83de25a", "Jone Yuan Telephonic Enterprise Co", "", "End of the World (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e63a87c231ee9a506f9599aa4ef7dfb9", "Tigervision, Warren Schwader", "7-003", "Threshold (1982) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e63efdfda9a4003dcd77a854a781a06a", "Paul Slocum", "", "Combat Rock (PD) (Hack) [a]", "Hack of Combat", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e643aaec9a9e1c8ab7fe1eae90bc77d7", "Roger Williams", "", "Asymmetric Playfield (Roger Williams)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e64a8008812327853877a37befeb6465", "Answer Software Corporation - TY Associates, Mike Wentz", "ASC1002", "Gauntlet (1983) (Answer Software)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e6508b878145187b87b9cded097293e7", "", "", "Oystron (V2.8) (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e66e5af5dea661d58420088368e4ef0d", "Activision, Bob Whitehead", "AG-011", "Stampede (1981) (Activision) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e67b0ed32fd9d28d12ab3775d52e8c3a", "Atari, Omegamatrix", "", "Video Olympics Menu (2020) (Hack)", "Hack of Video Olympics", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "AUTO 60", "", "", "", "" },
+  { "e6d5948f451a24994dfaaca51dfdb4e1", "Jone Yuan Telephonic Enterprise Co", "", "Football (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e6de4ef9ab62e2196962aa6b0dedac59", "Imagic, Wilfredo Aguilar, Michael Becker, Dennis Koble", "720113-2A, 13206", "Solar Storm (1983) (Imagic) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 45", "", "", "", "" },
+  { "e6e5bb0e4f4350da573023256268313d", "Thomas Jentzsch", "", "Missile Control (Thomas Jentzsch)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e6f49a1053c79211f82be4d90dc9fe3d", "", "", "Gunfight 2600 - Little progress... (2001) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e723ad8f406cb258b89681ef4cef0eff", "Thomas Jentzsch", "", "Sadoom (TJ) (PAL) (Hack)", "Hack of Kaboom!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
+  { "e72eb8d4410152bdcb69e7fba327b420", "Atari, Douglas Neubauer, Mimi Nyden", "CX26136", "Solaris (1986) (Atari)", "AKA Universe, Star Raiders II, The Last Starfighter", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e72ee2d6e501f07ec5e8a0efbe520bee", "Imagic, Dave Johnson", "720119-2A, 13211, EIX-004-04I", "Quick Step! (1983) (Imagic) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e73838c43040bcbc83e4204a3e72eef4", "CCE", "", "Apples and Dolls (CCE)", "AKA Open, Sesame!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "e74022cfe31ec8908844718dfbdedf7a", "", "", "Space Treat (30-12-2002) (Fabrizio Zavagli) [a2]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e77ec259e1387bc308b0534647a89198", "Parker Brothers, David Lamkins, Laura Nikolich", "931503", "Spider-Man (1982) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e77f332b71f13884c84771e7a121182d", "Jone Yuan Telephonic Enterprise Co", "", "Hey! Stop! (Jone Yuan)", "AKA Keystone Kapers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e784a9d26707cfcd170a4c1c60422a72", "Quelle", "147.443 6", "Gefecht im All (1983) (Quelle) (PAL)", "AKA Space Jockey", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e7864caaf9ec49ed67b1904ce8602690", "", "", "Donkey Kong 2K3 Pic (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e7a758bb0b43d0f7004e92b9abf4bc83", "", "", "Troll's Adventure (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e7dd8c2e6c100044002c1086d02b366e", "Activision, Steve Cartwright - Ariola", "EAX-013, PAX-013, 711 013-720", "Barnstorming (1982) (Activision) (PAL)", "AKA Die tollkeuhnen Flieger", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e7f005ddb6902c648de098511f6ae2e5", "Spectravideo - Universum", "SV-010", "CompuMate (1983) (Spectravideo) (PAL)", "", "", "", "", "CM", "", "", "", "", "COMPUMATE", "", "", "COMPUMATE", "", "", "", "", "", "", "", "", "YES", "80" },
+  { "e800e4aec7c6c54c9cf3db0d1d030058", "", "", "Qb (2.06) (Retroactive) (Stella)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "e80a4026d29777c3c7993fbfaee8920f", "", "", "Frisco (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e823b13751e4388f1f2a375d3560a8d7", "Arcadia Corporation, Stephen Harland Landrum", "AR-4105", "Official Frogger (Preview) (1983) (Arcadia) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e879b7093ac4cfad74c88d636ca97d00", "", "", "Poker Squares (V0.0f) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e88340f5bd2f03e2e9ce5ecfa9c644f5", "", "", "Lock 'n' Chase (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e8a3473bf786cf796d1336d2d03a0008", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (12-05-1983) (Parker Bros) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "e8aa36e3d49e9bfa654c25dcc19c74e6", "Atari, Joe Decuir, Larry Caplan, Steve Mayer, Larry Wagner", "CX2601, CX2601P", "Combat (1977) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e8e7b9bdf4bf04930c2bcaa0278ee637", "", "", "Boring Taz (Hack)", "Hack of Taz", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e8f7679359c4f532f5d5e93af7d8a985", "", "", "Hangman Invader Original Words (Hack)", "Hack of Hangman", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e9034b41741dcee64ab6605aba9de455", "Digivision", "", "Phanton Tank (Digivision)", "AKA Phantom Tank", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e908611d99890733be31733a979c62d8", "Atari, Dan Hitchens, Mimi Nyden", "CX2697", "Mario Bros. (1983) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e91d2ecf8803ae52b55bbf105af04d4b", "Atari, Howard Scott Warshaw", "CX2655, CX2655P", "Yars' Revenge (1982) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "e923001015bedd7901569f035d9c592c", "", "", "Adventure II (Hack)", "Hack of Adventure", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e927ecf80f3784d745abd8368d78f2f3", "", "", "Space Instigators (V1.8) (19-10-2002) (CT) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e932f44fad2a66b6d5faec9addec208e", "", "", "Atari Logo Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e94632b0d863dd76459d689a9865bb33", "Jone Yuan Telephonic Enterprise Co", "", "Combat (Jone Yuan) (4K)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e957eb4612d6bd5940d3492dfa749668", "", "", "Tunnel Demo (27-03-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e959b5a2c882ccaacb43c32790957c2d", "", "", "Phantom II & Pirate (NTSC)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e97eafd0635651d3999cece953c06bd5", "", "", "M.A.S.H (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e9be3e8e4a7e73dd63ed4235a3a1a25f", "", "", "MMetall (Hack)", "Hack of Miniature Golf", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e9c5d04643855949a23ff29349af74ea", "", "", "SCSIcide (Score Hack 2) (24-02-2001) (Joe Grand) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e9c71f8cdba6037521c9a3c70819d171", "Action Hi Tech - Hi-Score", "", "Bank Heist (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e9cb18770a41a16de63b124c1e8bd493", "Parker Brothers - Roklan, Joe Gaucher", "931519", "Popeye (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "e9db2f91efe6ff7ea3546e2c2578fb09", "Omegamatrix", "", "Millipede (Atari Mouse) v6.5 (Omegamatrix)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "PAL60", "", "", "" },
+  { "e9e646f730b8400cd5da08c849ef3e3b", "Tron", "", "Enduro (Tron)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e9e6ad30549a6e2cd89fe93b7691d447", "Atari - Bobco, Robert C. Polaro", "CX26140, CX26140P", "Desert Falcon (05-27-1987) (Atari) (Prototype) (PAL)", "AKA Nile Flyer, Sphinx", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "e9f25c7af4f27c9e1b5b8f6fe6141e8c", "Champ Games", "CG-03-N", "Scramble (NTSC)", "Compatible with Genesis controller", "Homebrew", "", "", "", "", "", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "ea38fcfc06ad87a0aed1a3d1588744e4", "Atari, Lou Harp", "CX26122", "Sinistar (01-XX-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ea6d40db5498d6386571a76df448aa4c", "", "", "Vertical Playfield Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ea7e25ade3fe68f5b786ee0aa82b1fe5", "", "", "Galatic (208 in 1) (Unknown) (PAL)", "AKA Challenge of.... Nexar, The", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ea832e2cb6aae6f525f07452c381fa48", "", "", "Polar to Cartesian and VV (2001) (Roger Williams)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ea86176b27ab0da8cce8f0179884bfaa", "", "", "Demo Image Series #10 - It's Art (28-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "eaacfcdc1d4ee1258429b7ae7f084125", "Telegames", "6057 A227", "Quest for Quintana Roo (1989) (Telegames)", "Genesis controller (B is action button, C chooses tool or weapon)", "Hack of Quest for Quintana Roo", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ead60451c28635b55ca8fea198444e16", "Sancho - Tang's Electronic Co.", "TEC004", "Nightmare (1983) (Sancho) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "eada0dd61ce13f8317de774dc1e68604", "", "", "2600 Digital Clock (Demo 1) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "eae0c06ee61c63b81cd016096fc901b0", "Joe Grand", "", "SCSIcide (v1.0) (2001) (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "eae6a5510055341d3abeb45667bb3e9b", "HES", "", "Wall Defender (HES) (PAL)", "AKA Wall Break (Planet Patrol if right difficulty = 'A')", "", "", "0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "eaf744185d5e8def899950ba7c6e7bb5", "Atari", "CX26172", "Xenophobe (1991) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "eafe8b40313a65792e88ff9f2fe2655c", "Eric Ball", "ELB004", "Skeleton+ (NTSC)", "Stereo sound", "Homebrew", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "eb3d680699f8762f71f38e28e321234d", "", "", "Fu Kung! (V0.01) (08-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "eb4252faff7a4f2ba5284a98b8f78d1a", "", "", "John K Harvey's Equalizer (NTSC) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "eb46e99ec15858f8cd8c91cef384ce09", "Goliath - Hot Shot", "83-113", "Ground Zero (1983) (Goliath) (PAL)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "eb503cc64c3560cd78b7051188b7ba56", "Star Game", "043", "Moto Laser (Star Game)", "AKA Mega Force", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "eb634650c3912132092b7aee540bbce3", "Atari, Eric Manghise, Mimi Nyden, Joseph Tung", "CX2640", "RealSports Baseball (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "eb6d6e22a16f30687ade526d7a6f05c5", "Atari", "CX26150P", "Q-bert (1987) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "eb71743c6c7ccce5b108fad70a326ad9", "", "", "Euchre (25-11-2001) (Erik Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "eb7934360658a29c50aeaff20bfda23b", "Activision, John Van Ryzin", "EAZ-036-04", "H.E.R.O. (1984) (Activision) (SECAM)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "eb92193f06b645df0b2a15d077ce435f", "Starpath Corporation, Steve Hales, Stephen H. Landrum", "4 AR-4102", "Suicide Mission (1982) (Starpath) (PAL)", "AKA Meteoroids", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "eb9712e423b57f0b07ccd315bb9abf61", "Retroactive", "", "Qb (V2.04) (PAL) (2001) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "eb9f8b84c193d9d93a58fca112aa39ed", "", "", "Register Twiddler Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ebcb084a91d41865b2c1915779001ca7", "JVP", "", "Bob Is Going Home (JVP)", "AKA Bobby Is Going Home", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ebcbc8a181a738e13df6216e5c329230", "Activision, Steve Cartwright", "AX-022", "Seaquest (1983) (Activision) (16K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ebd2488dcace40474c1a78fa53ebfadf", "Skill Screen Games, Herman Quast", "SSG001", "Extra Terrestrials (1984) (SSG)", "The only Canadian-designed and manufactured Atari 2600 game from the 1980's", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ebdc5716b85c4ff44fa357cb697d6cef", "Thomas Jentzsch", "", "Centipede - Amiga Mouse Hack v1.4 (NTSC) (Half-Speed) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ebf2dff78a08733251bf3838f02f7938", "Commavid, Ben Burch", "CM-010", "Rush Hour (1983) (Commavid) (Prototype) [a2]", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ebf9038e927e6a0db3e0d170c59911e6", "", "", "Pac-2600 (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ec3beb6d8b5689e867bafb5d5f507491", "U.S. Games Corporation - Vidtec - JWDA, Todd Marshall, Henry Will IV", "VC1003", "Word Zapper (1982) (U.S. Games)", "AKA Word Grabber", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ec407a206b718a0a9f69b03e920a0185", "Quelle", "876.482 1", "Landung in der Normandie (1983) (Quelle) (PAL)", "AKA Commando Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ec5c861b487a5075876ab01155e74c6c", "Apollo - Games by Apollo, Ed Salvo, Byron Parks", "AP-2001", "Spacechase (1982) (Apollo)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ece463abde92e8b89bcd867ec71751b8", "Puzzy - Bit Corporation", "PG205", "Dancing Plate (1982) (Puzzy) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "ece908d77ab944f7bac84322b9973549", "", "", "Tom Boy (Unknown) (PAL60)", "AKA Pitfall!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ecf51385384b468834611d44a8429c03", "20th Century Fox Video Games, Douglas 'Dallas North' Neubauer", "11105", "Mega Force (1982) (20th Century Fox) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ecfa04523dde82fe42cdc7315a8f61b6", "Activision, David Crane - Ariola", "EAG-004, PAG-004 - 711 004-715", "Fishing Derby (1980) (Activision) (PAL) (4K)", "AKA Schneller als der Hai", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ed014beeeb77dbb2bbcf9b5f6850b2f4", "", "", "Green Bar Text Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ed0451010d022b96a464febcba70b9c4", "PlayAround - J.H.M.", "203", "Knight on the Town (1982) (PlayAround) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "ed0ab909cf7b30aff6fc28c3a4660b8e", "Panda", "105", "Stunt Man (1983) (Panda)", "AKA Nightmare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ed1306436ce237afc5a7ed3f77134202", "HES", "771-341", "2 Pak Special - Dolphin, Pigs n' Wolf (1990) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ed1492d4cafd7ebf064f0c933249f5b0", "CCE", "", "Video Cube (CCE)", "AKA Atari Video Cube", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ed1a784875538c7871d035b7a98c2433", "Bit Corporation", "R320", "Save Our Ship (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ed2218b3075d15eaa34e3356025ccca3", "Atari, Richard Maurer", "CX2635, CX2635P", "Maze Craze (1980) (Atari) (PAL)", "AKA A Game of Cops 'n Robbers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ed5ccfc93ad4561075436ee42a15438a", "Atari, Tom Reuterdahl", "CX2626, CX2626P", "Miniature Golf (1979) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ed8f319e82d355832195eb7715644795", "Activision, Larry Kaplan, David Crane", "AG-010, AG-010-04", "Kaboom! (1981) (Activision) (8K)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
+  { "eddef10fdc0029301064115ae0cd41d4", "CCE", "", "Freeway (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ede4ab11ca346bd023b2c21d941e0c50", "Activision, David Crane", "EAZ-030", "Decathlon (1983) (Activision) (SECAM)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ede7e8bf865b0afb4744f86d13624f9a", "", "", "Demo Image Series #2 - Clown (19-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "edf69b123e06eaf8663cc78d8aeba06e", "SpkSoft 98", "", "River Raid (SpkSoft 98) [h1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ee28424af389a7f3672182009472500c", "Atari, Carol Shaw - Ralph Lauren", "", "Polo (1978) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ee456542b93fa8d7e6a8c689b5a0413c", "", "", "Chronocolor Donkey Kong Clean (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ee4c186123d31a279ed7a84d3578df23", "Atari, Carol Shaw, Nick 'Sandy Maiwald' Turner", "CX2608", "Super Breakout (1982 - 1981) (Atari) (PAL)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 45", "", "", "", "" },
+  { "ee659ae50e9df886ac4f8d7ad10d046a", "Exus Corporation", "", "Video Reflex (1983) (Exus)", "AKA Foot Craz", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ee6665683ebdb539e89ba620981cb0f6", "Coleco", "2658", "Berenstain Bears (1983) (Coleco)", "Uses the KidVid Controller", "Unbelievably Rare", "", "", "", "A", "", "", "", "", "", "", "KIDVID", "", "", "", "", "", "", "", "", "", "" },
+  { "ee67dc0b01746372d2b983d88f48e24f", "", "", "Scroller Demo (02-01-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ee681f566aad6c07c61bbbfc66d74a27", "Activision", "", "Unknown Activision Game (10-29-1982) (Activision) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ee6cbedf6c0aac90faa0a8dbc093ffbe", "CCE", "", "My Golf (CCE) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ee8027d554d14c8d0b86f94737d2fdcc", "Canal 3 - Intellivision", "", "Yars' Revenge (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "ee84bdc5dae268e227e407c7b5e6b6b7", "", "", "Marilyn Monroe Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ee9caee4eb958284fb10c277b14537f1", "Carrere Video, Garry Kitchen - Teldec", "USC1001", "Space Jockey (1983) (Carrere Video) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "eea0da9b987d661264cce69a7c13c3bd", "Coleco", "2454", "Zaxxon (1983) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "eeb92f3f46df841487d1504f2896d61a", "Cody Pittman", "", "Corys Adventure (Cody Pittman) (Hack)", "Hack of Pac-Man", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "eec61cc4250df70939d48fe02d7122ac", "Activision, Bob Whitehead - Ariola", "EAG-005, PAG-005, EAG-005-04B - 711 005-715", "Skiing (1980) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "eed9eaf1a0b6a2b9bc4c8032cb43e3fb", "Atari - Axlon, Steve DeFrisco", "CX26192", "Klax (1991) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "eee7695ae3eea7818321df0b790b31f3", "", "", "Sound Paddle V2 (Dennis Caswell & Jim Nitchals) (PD)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" },
+  { "ef263d40a23483ab339cac44d9515a56", "Thomas Jentzsch", "", "Fatal Run (TJ)", "NTSC Conversion", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ef3a4f64b6494ba770862768caf04b86", "Activision, Bob Whitehead", "AG-034-04", "Private Eye (1984) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ef60b06fddb675b0d783afbfa5fc5232", "", "", "Many Blue Bars and Text Demo 4 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ef66af190840871409fe1702d2483554", "Andrew Davie, Paul Slocum, Christopher Tumber", "", "DiscoTech (12-02-2003) (Andrew Davie)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ef71e9fb0d8d477226d8d42261fbf0a7", "Piero Cavina", "", "Multi-Sprite Demo V2.0 (Piero Cavina) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ef76ea05655a0b62cb1018c92b9b4b7d", "Gakken", "010", "Strategy X (1983) (Gakken) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "efa1098c7d091b940c2543abe372f036", "Scott Stilphen", "", "E.T. The Extra-Terrestrial (Scott Stilphen) (Hack)", "Hack of E.T. The Extra-Terrestrial", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "efb47d70b2965ce689e2c5757616b286", "", "", "Time Test Demo (Eckhard Stolberg) (PAL) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "efd387430a35a659ff569a9a0ec22209", "Atari - GCC", "CX26118", "Millipede (1984) (Atari) (Prototype) (PAL)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "efefc02bbc5258815457f7a5b8d8750a", "CBS Electronics, Richard K. Balaska Jr.", "4L 2520 5000", "Tunnel Runner (1983) (CBS Electronics) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "effa3a7ce078c6d83bf43174a7bfdb1f", "Thomas Jentzsch", "", "Centipede - Atari Mouse Hack v1.4 (NTSC) (Half-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "efffafc17b7cb01b9ca35324aa767364", "", "", "Circus Atari (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f02ba8b5292bf3017d10553c9b7b2861", "Atari", "CX26172", "Xenophobe (1991) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f032b2f2d8323404a6b4541f92dd1825", "", "", "Many Blue Bars and Text Demo 3 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f047df70d3d08e331122cd2de61d6af8", "Dave Neuman", "", "Space Battle (NTSC)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f04ee80011d95798006378643650aaa7", "Atari, Bill Aspromonte, John Russell, Michael Sierchio, Robert Zdybel", "CX26114", "Pigs in Space (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f0510abbfbe24ead552e92e3841f63f3", "Thomas Jentzsch", "", "Reactor - Atari Mouse Hack v1.3 (NTSC) (Full-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f0536303f49006806bac3aec15738336", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (4 of 4) (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f0541d2f7cda5ec7bab6d62b6128b823", "Atari, Paul Donaldson", "", "Bionic Breakthrough (1984) (Atari) (Prototype)", "Uses Mindlink Controller (left only)", "Prototype", "", "", "", "", "", "", "", "MINDLINK", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f060826626aac9e0d8cda0282f4b7fc3", "Atari, David Crane - Sears", "CX2605 - 6-99822, 49-75109", "Outlaw (1978) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f0631c6675033428238408885d7e4fde", "Paul Slocum", "", "Test Cart (2002) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "f066bea7ab0a37b83c83c924a87c5b67", "", "", "Air Raiders (1982) (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f0a6e99f5875891246c3dbecbf2d2cea", "Atari, James Andreasen - Sears", "CX2654 - 49-75141", "Haunted House (1982) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f0b7db930ca0e548c41a97160b9f6275", "Atari, Larry Wagner, Bob Whitehead - Sears", "CX2645 - 49-75181", "Video Chess (1979) (Atari)", "AKA Computer Chess", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f0cacae1d1b79ee92f0dc035f42e0560", "", "", "Boring Donkey Kong (Hack)", "Hack of Donkey Kong", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f0d393dbf4164a688b2346770c9bbd12", "", "", "Racquetball (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "f0daaa966199ef2b49403e9a29d12c50", "", "", "Mr. Postman (Unknown)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f0de4f49e95d529569e8788d5a7b4d30", "Thomas Jentzsch", "", "Reactor - Atari Mouse Hack v1.3 (PAL60) (Full-Speed) (TJ)", "Uses Atari Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f0e0addc07971561ab80d9abe1b8d333", "Imagic, Rob Fulop", "720000-200, 720101-1B, 720101-1C, IA3200, IA3200C, IX-006-04", "Demon Attack (1982) (Imagic)", "AKA Death from Above", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f0ef9a1e5d4027a157636d7f19952bb5", "Atari - Axlon, Tod Frye - Heuristica, Agustin Ortiz", "CX26169", "Shooting Arcade (03-07-1989) (Atari) (Prototype) [a5]", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f10e3f45fb01416c87e5835ab270b53a", "Suntek", "SS-024", "Ski Run (1983) (Suntek) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f1127ade54037236e75a133b1dfc389d", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (Preview) (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f11cfab087fcbd930ab8b0becc5b2e5a", "Canal 3 - Intellivision", "", "River Raid (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f12afbffa080dd3b2801dd14d4837cf6", "Atari, Michael Kosaka, Peter C. Niday, Robert Vieira", "CX26110", "Crystal Castles (01-04-1984) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "f137211537438b1fce3d811baef25457", "", "", "Incoming (02-10-2002) (Ben Larson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f1489e27a4539a0c6c8529262f9f7e18", "Champ Games", "CG-01-P", "Lady Bug (PAL60)", "", "Homebrew", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "f14d5e96ec3380aef57a4b70132c6677", "Goliath - Hot Shot", "83-414", "Pac Kong (1983) (Goliath) (PAL)", "AKA Inca Gold", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f1554569321dc933c87981cf5c239c43", "Atari - Glenn Axworthy", "CX26129", "Midnight Magic (1986) (Atari)", "AKA Pinball Wizard", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "f16c709df0a6c52f47ff52b9d95b7d8d", "Atari, Alan Miller - Sears", "CX2662 - 6-99811", "Hangman (1978) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f16ef574d2042ed8fe877d6541f4dba4", "Spectravision - Spectravideo", "SA-201", "Gangster Alley (1982) (Spectravision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f1929bb9b5db22d98dd992aa3fe72920", "", "", "Cube Conquest (Improved Interlace) (Billy Eno) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "f19aba18f86e415812480ad2be221425", "Chris Larkin", "", "Solaris Trainer (2002) (Chris Larkin) (Hack)", "Hack of Solaris", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f1a0a23e6464d954e3a9579c4ccd01c8", "20th Century Fox, Douglas 'Dallas North' Neubauer", "11006", "Alien (1982) (20th Century Fox)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "f1ae6305fa33a948e36deb0ef12af852", "Andreas Dietrich", "", "Donkey Kong VCS (2017) (1.0)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "f1b2ea568b3e156e3f2849dac83591f6", "", "", "Sprite Demo (1997) (Bob Colbert) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f1b7edff81ceef5af7ae1fa76c8590fc", "Atari, Richard Maurer", "CX2632, CX2632P", "Space Invaders (1980) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f1beca5a198cf08190487e5c27b8e540", "", "", "Fu Kung! (V0.16) (2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f1e375d921858467166e53bcec05803f", "Jeffry Johnston", "", "Radial Pong - Version 3 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f1eeeccc4bba6999345a2575ae96508e", "Video Gems", "VG-03", "Steeplechase (1983) (Video Gems) (PAL)", "", "", "", "", "", "", "A", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "f1fe06ebe2900eac4cdd17799389a102", "Atari, Jim Huether", "CX26163P", "Sky Diver (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f20675c8b98518367b9f5b8ee6f7c8ea", "Atari", "CX26163P", "Stampede (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f20bd756f3990e06c492f53cd0168e68", "", "", "Skeleton+ (03-05-2003) (Eric Ball) (NTSC)", "", "", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f21813aa050437f0dbc8479864acec6d", "", "", "Sneak 'n Peek (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f23d19b73dac50cc6149316912b8ee53", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Amiga Mouse Hack v1.1 (PAL) (TJ)", "Uses Amiga Mouse Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f240ba9f8092d2e8a4c7d82c554bf509", "Quelle", "463.860 7", "Strahlen der Teufelsvoegel (1983) (Quelle) (PAL)", "AKA Atlantis", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f280976d69d6e27a48506bd6bad11dcd", "Atari, Larry Kaplan", "CX2664, CX2664P", "Brain Games (1978) (Atari) (PAL)", "Uses Keypad Controllers", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" },
+  { "f283cc294ece520c2badf9da20cfc025", "Atari - CCW, Christopher H. Omarzu", "CX26104", "Big Bird's Egg Catch (1983) (Atari) (PAL)", "Uses Kids/Keypad Controllers", "Rare", "", "", "", "", "", "", "", "KEYBOARD", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" },
+  { "f28c07767b3e90a2689ade5b5e305874", "Canal 3 - Intellivision", "C 3014", "Keystone Kapers (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f2d40c70cf3e1d03bc112796315888d9", "Atari - CCW, Michael Callahan, Preston Stuart", "CX26103", "Alpha Beam with Ernie (1983) (Atari) (PAL)", "Uses Keypad Controllers", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f2d4d6187903cac2d5ea8ed90dad120d", "Digimax", "", "River Raid II (Digimax)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f2e4fb2d3600c0f76d05864e658cc57b", "", "", "Marble Craze (Kernel) (17-02-2002) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f2f2cb35fdef063c966c1f5481050ea2", "", "", "Ram It (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f2f59629d7341c97644405daeac08845", "Jone Yuan Telephonic Enterprise Co", "", "Bobby Is Going Home (Jone Yuan)", "2600 Screen Search Console", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f303630a2d7316787aecd67fff6b2e33", "AtariAge - Fred Quimby", "", "Gingerbread Man (Fred Quimby)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f3213a8a702b0646d2eaf9ee0722b51c", "Atari, Carol Shaw - Sears", "CX2618 - 49-75123", "3-D Tic-Tac-Toe (1980) (Atari) (4K)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f33f1d0f7819c74148dacb48cbf1c597", "Retroactive", "", "Qb (2.00) (Retroactive) (Stella)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "f344ac1279152157d63e64aa39479599", "Tigervision", "7-012", "Espial (1984) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f34dd3b8156aaf113cb621b2e51d90b8", "Joe Grand", "", "SCSIcide Pre-release 5 (Joe Grand)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f34f08e5eb96e500e851a80be3277a56", "Atari, Brad Stewart - Sears", "CX2622 - 6-99813, 49-75107", "Breakout (1978) (Atari)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 60", "", "", "", "" },
+  { "f367e58667a30e7482175809e3cec4d4", "ZiMAG - Emag - Vidco", "708-111 - GN-040", "Cosmic Corridor (1983) (ZiMAG)", "AKA Space Tunnel", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f38358cd8f5ecfedffd5aca1aa939f18", "Universal Gamex Corporation, Alan Roberts", "1005", "X-Man (1983) (Universal) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f39e4bc99845edd8621b0f3c7b8c4fd9", "AtariAge", "", "Toyshop Trouble (AtariAge)", "F8 Emulator Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f3c431930e035a457fe370ed4d230659", "", "", "Crackpots (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f3cd0f886201d1376f3abab2df53b1b9", "Commavid, Ben Burch", "CM-010", "Rush Hour (1983) (Commavid) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f3dfae774f3bd005a026e29894db40d3", "Otto Versand", "649635", "See Saw (Double-Game Package) (1983) (Otto Versand) (PAL)", "AKA Circus Atari", "", "", "", "", "", "", "", "", "JOYSTICK", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "" },
+  { "f3f5f72bfdd67f3d0e45d097e11b8091", "Sears Tele-Games, Marilyn Churchill, Matthew L. Hubbard", "CX2647 - 49-75142", "Submarine Commander (1982) (Sears)", "AKA Seawolf 3", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f3f92aad3a335f0a1ead24a0214ff446", "", "", "Spectrum Color Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f40e437a9ebf0bdfe26204152f74f868", "Bit Corporation", "R320", "Jawbreaker (32 in 1) (BitCorp) (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f4204fc92d17ed4cb567c40361ad58f1", "Inky", "", "Beanie Baby Bash (Inky) (Hack)", "Hack of Beany Bopper", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f4469178cd8998cb437fa110a228eaca", "Digitel", "", "Frostbite (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f45644ff82b533a781a1ee50f2e95f3c", "", "", "Overhead Adventure Demo 6 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f457674cef449cfd85f21db2b4f631a7", "U.S. Games Corporation - JWDA, Todd Marshall, Wes Trager, Henry Will IV", "VC1004", "Commando Raid (1982) (U.S. Games)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f473f99e47d4026a7a571184922ebf04", "Philip R. Frey", "", "Donkey Claus (Philip R. Frey) (Hack)", "Hack of Donkey Kong", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f48022230bb774a7f22184b48a3385af", "Atari, Rob Fulop - Sears", "CX2633 - 49-75119", "Night Driver (1980) (Atari) (4K)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "YES", "" },
+  { "f48735115ec302ba8bb2d2f3a442e814", "", "", "Dancing Plate (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "f49a34f1fdd7dc147cbf96ce2ce71b76", "", "", "Qb (Special Edition) (PAL) (Retroactive)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "f4a09f906cc37be31224433f576d77d3", "Thomas Jentzsch", "", "Challenge of... Nexar, The - Atari Trak-Ball Hack v1.2 (PAL) (TJ)", "Uses Atari Trak-Ball Controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f4ab6bd5f80d8988141edde4c84b23b5", "Atari, Alan Miller", "CX2624, CX2624P", "Basketball (1978) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f4b8a47a95b61895e671c3ec86ffd461", "Parker Brothers, Wilfredo Aguilar, Michael Becker, Neil McKenzie, Bob Smith, Brad Stewart", "PB5540", "Star Wars - The Arcade Game (01-03-1984) (Parker Bros) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "f4c2e50b01dff99bddbe037b3489511c", "", "", "Hypnotic (V0.04) (2001) (Inkling) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f4c6621f1a0b4d27081123c08d7d1497", "CCE", "C-838", "Immies & Aggies (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f4cf6881b65c424095dc25dc987f151f", "", "", "128 in 1 Game Select ROM (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f4dabd5bcc603e8464a478208037d423", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (08-21-1984) (Coleco) (Prototype)", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f526d0c519f5001adb1fc7948bfbb3ce", "Mythicon, Bill Bryner, Bruce de Graaf", "MA1003", "Star Fox (1983) (Mythicon)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f52f40299fd238c6ffd9e6107050dc76", "Activision, Bob Whitehead - Ariola", "EAG-011, PAG-011 - 711 011-715", "Stampede (1981) (Activision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f539e32bf6ce39c8ca47cb0cdd2c5cb8", "Control Video Corporation", "", "GameLine Master Module ROM (1983) (Control Video)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f542b5d0193a3959b54f3c4c803ba242", "Atari, Tom Rudadahl - Sears", "CX2634 - 49-75121", "Golf (1980) (Atari) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f5445b52999e229e3789c39e7ee99947", "Atari, Jim Huether", "CX26163P", "Flag Capture (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f5a2f6efa33a3e5541bc680e9dc31d5b", "Suntek", "SS-022", "Motocross (1983) (Suntek) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f5a3e051730d45fea518f2e8b926565b", "Robby", "", "Keystone Kapers (Robby)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f5aa6bd10f662199c42e43863a30106c", "", "", "Music Kit (V1.0) - Song Player (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "f5d103a9ae36d1d4ee7eef657b75d2b3", "Starpath Corporation, Stephen H. Landrum", "9 AR-4105", "Official Frogger, The (Preview) (1983) (Starpath)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f613aad84d2163d6b197b220bfec1b7e", "", "", "X-Doom V.27 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f661f129644f338b13d9f4510d816c03", "Atari, David Crane", "CX26163P", "Outlaw (32 in 1) (1988) (Atari) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f6676e3fe901eb8515fc7ae310302c3c", "Activision, David Crane", "AG-008", "Laser Blast (1981) (Activision) (8K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f67181b3a01b9c9159840b15449b87b0", "Atari, Nick 'Sandy Maiwald' Turner", "CX2665", "Frog Pond (08-27-1982) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f687ec4b69611a7f78bd69b8a567937a", "Activision, Alan Miller - Ariola", "EAZ-028 - 711 028-725", "Robot Tank (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f69a39b215852a0c2764d2a923c1e463", "", "", "Move a Blue Blob Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f69bb58b815a6bdca548fa4d5e0d5a75", "Atari, Larry Kaplan", "CX26163P", "Bowling (32 in 1) (1988) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f69d4fcf76942fcd9bdf3fd8fde790fb", "CCE", "", "Aquaventure (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f6a282374441012b01714e19699fc62a", "ZiMAG - Emag - Vidco", "710-111 - GN-010", "I Want My Mommy (1983) (ZiMAG)", "AKA Open, Sesame!", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "f6a9ea814d15b85bffe980c927df606b", "", "", "Missile Command (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "f6b5ebb65cbb2981af4d546c470629d7", "Coleco - Individeo, Ed Temple", "", "Cabbage Patch Kids (09-13-1984) (Coleco) (Prototype) [a]", "Adventures in the Park", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f6c13e816e58c8c62f82b2c8b91a2d67", "", "", "Scrolling Playfield 2 (Junkosoft) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f6d512bef1bf253dc935d0e13c3d1462", "", "", "Slot Racers (Unknown) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f6daebc0424fa0f8d9aaf26c86df50f4", "Brian Watson", "", "Color Tweaker (V1.0) (2001) (B. Watson)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f6efa00ae99aaf33e427b674bcfd834d", "", "", "2600 Digital Clock (Demo 3) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f6f1b27efc247a0e8d473ddb4269ff9e", "Rainbow Vision - Suntek", "SS-015", "Catch Time (1983) (Rainbow Vision) (PAL)", "AKA Plaque Attack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f70e3f3bb2d19ec2aaec8f78dc43744f", "Jone Yuan Telephonic Enterprise Co", "", "Pooyan (Jone Yuan) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f714a223954c28eccf459295517dcae6", "", "", "Big - Move This Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f7154add27b95cd90464dbed8cfd7557", "Fabrizio Zavagli", "", "Space Treat Deluxe (2003) (PAL)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f724d3dd2471ed4cf5f191dbb724b69f", "Atari, Jerome Domurat, Howard Scott Warshaw", "CX2659", "Raiders of the Lost Ark (1982) (Atari)", "Console ports are swapped", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f736864442164b29235e8872013180cd", "Telegames - VSS", "6057 A227", "Quest for Quintana Roo (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f73d2d0eff548e8fc66996f27acf2b4b", "CCE", "C-813", "Pitfall (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f7424985bac41067502b4a05b64cb75a", "Activision, Steve Cartwright", "AX-027", "Plaque Attack (1983) (Activision)", "Genesis controller (B is fire up, C is fire down)", "Hack of Plaque Attack", "", "", "", "", "", "", "", "GENESIS", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f74ad642552385c3daa203a2a6fc2291", "Eckhard Stolberg", "", "Cubis (1997) (Eckhard Stolberg)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f750b5d613796963acecab1690f554ae", "Manuel Polik", "", "Gunfight 2600 (MP)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f75872946e82ad74d48eae5bc28f5f0e", "Sears Tele-Games, Jim Huether", "CX2614 - 49-75126", "Steeplechase (04-15-1980) (Sears) (Prototype)", "Uses the Paddle Controllers", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f777444fc21a5925e066b68b1d350575", "", "", "Marble Craze (Kernel Works) (Paul Slocum)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f77f5fc3893da5d00198e4cd96544aad", "Canal 3 - Intellivision", "", "Stampede (Canal 3)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f7856e324bc56f45b9c8e6ff062ec033", "Atari, Jerome Domurat, Michael Sierchio", "CX2667", "RealSports Soccer (1983) (Atari) [no opening tune]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "f78c125b5da483c41e51522947d6c4ce", "", "", "Sound Paddle V1 (Dennis Caswell & Jim Nitchals) (PD)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "YES", "", "", "", "", "", "", "", "", "", "01", "", "", "", "" },
+  { "f7a138eed69665b5cd1bfa796a550b01", "Tigervision - Teldec", "7-012 - 3.60016 VC", "Espial (1984) (Tigervision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f7a651972d78f9ba485b14690452d4be", "Paul Slocum", "", "Homestar Runner Demo #2 (2004-03-29)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "f7af41a87533524d9a478575b0d873d0", "Quelle", "495.663 7", "Spiderman (1983) (Quelle) (PAL)", "AKA Spider-Man", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f7d6592dcb773c81c278140ed4d01669", "Activision, David Crane, Dan Kitchen", "EAG-108-04, EAZ-108-04B", "Ghostbusters (1985) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f7e07080ed8396b68f2e5788a5c245e2", "Video Game Cartridge - Ariola", "TP-617", "Farmyard Fun (Ariola)", "AKA Play Farm", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f7ec2f2bdbe8fbea048c0d5fa6503b0b", "Akor", "", "TV Boy (1992) (Akor) (PAL)", "Includes 127 games", "", "", "", "", "", "", "", "", "JOYSTICK", "", "", "JOYSTICK", "", "", "", "", "", "", "", "", "", "" },
+  { "f7f50d9c9d28bcc9f7d3075668b7ac89", "Activision, David Crane - Ariola", "EAG-008, PAG-008, EAG-008-04I - 711 008-720", "Laser Blast (1981) (Activision) (PAL) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f7fac15cf54b55c5597718b6742dbec2", "Spiceware", "SW-01", "Medieval Mayhem (NTSC)", "", "Homebrew", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 55", "", "", "", "" },
+  { "f802fa61011dd9eb6f80b271bac479d0", "Suntek", "SS-023", "Mole Hunter (1983) (Suntek) (PAL)", "AKA Topy", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f80cf77164079d774b9b0fae33dffca9", "", "", "Fu Kung! (V0.15) (Negative Version) (05-02-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f8240e62d8c0a64a61e19388414e3104", "Activision, Steve Cartwright", "AX-013", "Barnstorming (1982) (Activision)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f825c538481f9a7a46d1e9bc06200aaf", "Atari, Richard Maurer - Sears", "CX2635 - 49-75157", "Maze Craze (1980) (Atari)", "AKA A Game of Cops 'n Robbers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "NTSC", "", "", "" },
+  { "f844f4c6f3baaaf5322657442d6f29eb", "Atari, Sam Comstock, Richard Dobbis, Nick 'Sandy Maiwald' Turner", "CX26111", "Snoopy and the Red Baron (1983) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f847fb8dba6c6d66d13724dbe5d95c4d", "Absolute Entertainment, David Crane", "AG-042-02, AG-042-04", "Skate Boardin' (1987) (Absolute)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f8582bc6ca7046adb8e18164e8cecdbc", "", "", "Panda Chase (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f8648d0c6ad1266434f6c485ff69ec40", "CCE", "", "Oink! (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f8811d45a9935cca90c62f924712f8e6", "Jone Yuan Telephonic Enterprise Co", "", "Chopper Command (Jone Yuan) (Hack)", "2600 Screen Search Console", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f8b2a6a4d73ebff10d805a9b59041986", "Activision, Larry Kaplan - Ariola", "EAX-006, PAX-006 - 771 006-720", "Bridge (1980) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f8bfd99163d2c4ec688357786e6fba28", "", "", "Eckhard Stolberg's Scrolling Text Demo 2 (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f8c1c4a41303bd40b0d6c81bfaf8573b", "HES", "773-891", "2 Pak Special - Dungeon Master, Creature Strike (1992) (HES) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f8fbe2b07345086fc867bceeaf38dc48", "Atari, Eric Manghise, Mimi Nyden, Joseph Tung", "CX2640", "RealSports Baseball (1982) (Atari) (Prototype) (4K)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f8ff34b53d86f55bd52d7a520af6d1dc", "", "", "Big Dig (04-04-2003) (CT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f90b5da189f24d7e1a2117d8c8abc952", "Atari, David Crane - Sears", "CX2653 - 6-99823, 49-75111", "Slot Machine (1979) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f91fb8da3223b79f1c9a07b77ebfa0b2", "Atari, Alan J. Murphy, Nick 'Sandy Maiwald' Turner - Sears", "CX2615 - 49-75140", "Demons to Diamonds (1982) (Atari)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "", "", "10 57", "", "", "", "" },
+  { "f93d7fee92717e161e6763a88a293ffa", "20th Century Fox Video Games - Lazer Micro Systems - Dunhill Electronics, B. Winston Hendrickson, Randall Hyde, Mark V. Rhoads, John Simonds", "11013", "Porky's (1983) (20th Century Fox)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f9420173efcb4b9f2b01c2a7b595cca7", "CCE", "", "Laser Blast (CCE) (4K)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f954381f9e0f2009d1ac40dedd777b1a", "Thomas Jentzsch", "", "Robot City (V0.18) (01-09-2002) (TJ)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f9655ed51462ecfc690c7b97cec649f9", "Andrew Wallace", "", "Laseresal 2002 (PAL) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f965cc981cbb0822f955641f8d84e774", "Answer Software Corporation - TY Associates, Kim Ellis", "ASC2001", "Confrontation (1983) (Answer) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "f9660ebed66fee8bdfdf07b4faa22941", "VGS", "", "Vanguard (VGS)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f9677b2ec8728a703eb710274474613d", "Atari, Ian Shepard", "CX2604, CX2604P", "Space War (1978) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f97dee1aa2629911f30f225ca31789d4", "Avalon Hill, Jean Baer, Bill 'Rebecca Ann' Heineman, Jim Jacob", "5005002", "Out of Control (1983) (Avalon Hill)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f98d2276d4a25b286135566255aea9d0", "Digitel", "", "Name This Game (1983) (Digitel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f98d869f287d2ce4f8fb36e0686929d9", "", "", "Skeleton+ (17-04-2003) (Eric Ball) (NTSC)", "", "", "STEREO", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f991e0670b5f67faa6b6211e9bd81b91", "Nukey Shay, Omegamatrix", "", "Double Dragon (Genesis) (PAL) V2", "Genesis controller", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f992a39b46aa48188fab12ad3809ae4a", "", "", "Sky Jinks (Unknown) (PAL) (Hack)", "", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f9967369943209b4788d4e92cefc0795", "Atari", "CX26163P", "Fishing (32 in 1) (1988) (Atari) (PAL) (4K)", "AKA Fishing Derby", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f9cef637ea8e905a10e324e582dd39c2", "CCE", "", "Private Eye (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f9d51a4e5f8b48f68770c89ffd495ed1", "Atari, Tod Frye, Mimi Nyden", "CX2657", "SwordQuest - FireWorld (1982) (Atari)", "AKA Adventure II, SwordQuest II - FireWorld", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f9da42f91a1c5cfa344d2ff440c6f8d4", "ZUT", "", "Pac Invaders (ZUT)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f9de91d868d6ebfb0076af9063d7195e", "", "", "Maze Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "f9e99596345a84358bc5d1fbe877134b", "Activision, Larry Kaplan, David Crane - Ariola", "EAG-010, PAG-010 - 711 010-720", "Kaboom! (1981) (Activision) (PAL)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 50", "", "", "", "" },
+  { "fa0570561aa80896f0ead05c46351389", "Tigervision", "7-008", "Miner 2049er (1983) (Tigervision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fa1b060fd8e0bca0c2a097dcffce93d3", "Atari - CCW, Christopher H. Omarzu, Preston Stuart, Bruce Williams", "CX26101", "Oscar's Trash Race (1984) (Atari)", "Uses the Keypad Controllers", "", "", "", "", "", "", "", "", "KEYBOARD", "", "", "KEYBOARD", "", "", "", "", "", "", "", "", "", "" },
+  { "fa2be8125c3c60ab83e1c0fe56922fcb", "Camelot - DSD, Michael Doherty, Clyde Hager - Johnson & Johnson", "", "Tooth Protectors (1983) (Camelot)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "fa3de71841c0841db6a741884a6b6b2f", "", "", "Warring Worms (17-02-2002) (Billy Eno)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fa4404fabc094e3a31fcd7b559cdd029", "Atari, Alan J. Murphy, Robert C. Polaro", "CX26100", "Bugs Bunny (1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fa529ec88eca679f6d5fd0ccb2120e46", "", "", "20 Sprites at Once Demo 1 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fa6fe97a10efb9e74c0b5a816e6e1958", "ZiMAG - Emag - Vidco", "707-111 - GN-030", "Tanks But No Tanks (1983) (ZiMAG)", "AKA Phantom Tank", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fa7ce62e7fd77e02b3e2198d70742f80", "Atari, Peter C. Niday", "CX26108", "Donald Duck's Speedboat (04-18-1983) (Atari) (Prototype) (PAL)", "AKA Donald Duck's Regatta", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fa7e11a3dbea4365975cd2f094e61d25", "Tim Snider", "", "Mystery Science Theater 2600 (1999) (Tim Snider) (Hack)", "Hack of Megamania", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fa98d48cd609c9babc819e0a1bd8d598", "AtariAge (Chris Walton)", "", "Juno First (2009) (PAL60)", "AtariVox supported", "Homebrew", "", "", "", "", "", "", "", "", "", "", "ATARIVOX", "", "", "", "", "", "", "", "", "YES", "" },
+  { "fab7b04b9f42df761eb6f2bc445eaa99", "20th Century Fox Video Games - Sirius Software, David Lubar", "11008", "Fantastic Voyage (11-04-1982) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fabca526d57de46768b392f758f1a008", "", "", "Laseresal 2600 (16-12-2001) (Andrew Wallace) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fac28963307b6e85082ccd77c88325e7", "CCE", "", "Berzerk (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fadb89f9b23beb4d43a7895c532757e2", "Galaga Games", "", "River Raid (1984) (Galaga Games) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fae0b86934a7c5a362281dffebdb43a0", "Retroactive", "", "Qb (2.07) (Retroactive) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "faebcb2ef1f3831b2fc1dbd39d36517c", "Atari, Jerome Domurat, Steve Woita", "CX2696", "Asterix (1984) (Atari) (PAL)", "AKA Taz", "Extremely Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "faed2ef6b44894f8c83f2b50891c35c6", "CCE", "", "Super Baseball (CCE)", "AKA RealSports Baseball", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "faffd84f3a8eceee2fa5ea5b0a3e6678", "Suntek", "SS-025", "Spectracube Invasion (1983) (Suntek) (PAL)", "AKA Immies & Aggies", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fb09ee4ccd47ae74a3c314f0d8a40344", "", "", "Titans (SnailSoft)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fb0c32ef7af5b45486db663510094be8", "", "", "Demo Image Series #15 - Three Marios (NTSC) (Non-Interleave) (06-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fb0e84cee4c108d24253bcb7e382cffd", "", "", "Interleaved ChronoColour Demo (SECAM) (05-03-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fb27afe896e7c928089307b32e5642ee", "M Network - INTV - APh Technological Consulting, Jeff Ronne, Brett Stutz", "MT5662", "TRON - Deadly Discs (1983) (M Network)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fb4ca865abc02d66e39651bd9ade140a", "Arcadia Corporation, Brian McGhie", "AR-4104", "Rabbit Transit (1983) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fb531febf8e155328ec0cd39ef77a122", "", "", "Worm War I (208 in 1) (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "fb5c8af97bd8ffe88323656f462645a7", "", "", "Interlace Demo (Glenn Saunders)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "fb833ed50c865a9a505a125fc9d79a7e", "ITT Family Games", "", "Pumuckl I (1983) (ITT Family Games) (PAL)", "AKA Panda Chase", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fb884ffd89013331a6f01ae3f6abd214", "Activision, David Crane", "", "Venetian Blinds Demo (1982) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fb88baa01afd34e0e4b601e1d29bc806", "Manuel Polik", "", "Star Fire (2003) (XYPE)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fb88c400d602fe759ae74ef1716ee84e", "20th Century Fox Video Games, Bill Aspromonte", "11031", "Crash Dive (1983) (20th Century Fox)", "AKA Voyage to the Bottom of the Sea", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fb91da78455d9b1606913fbf8c859772", "", "", "Split Screen (Ballblazer) Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fb91dfc36cddaa54b09924ae8fd96199", "Parker Brothers, Mark Lesser", "PB5590", "Frogger II (1984) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "fb978f1c053e8061cc37a726639f43f7", "Atari - Axlon, Tod Frye - Heuristica, Agustin Ortiz", "CX26169", "Shooting Arcade (03-07-1989) (Atari) (Prototype)", "Uses the Light Gun Controller (left only)", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fbac6476e7b2b20d246202af81662c88", "Starpath Corporation, Stephen H. Landrum", "AR-4400", "Dragonstomper (Preview) (1982) (Starpath) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fbb0151ea2108e33b2dbaae14a1831dd", "Thomas Jentzsch", "", "Robot Tank TV (Thomas Jentzsch) (Hack)", "Uses two simultaneous Joystick Controllers, Hack of Robot Tank", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fbb4f3debf48dc961b559384467f2057", "Digitel", "", "River Raid III (1985) (Digitel)", "AKA River Raid", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fbe554aa8f759226d251ba6b64a9cce4", "Atari - GCC, Mike Feinstein, Brad Rice", "CX2681, CX2681P", "Battlezone (1983) (Atari) (PAL)", "", "Uncommon", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fbfebee9c14694719e3eda4854dc42ee", "Jake Patterson", "", "Baubles 3 (Jake Patterson) (PD)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fc2104dd2dadf9a6176c1c1c8f87ced9", "Coleco - Woodside Design Associates, Harley H. Puthuff Jr.", "2663", "Time Pilot (1983) (Coleco)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fc2233fc116faef0d3c31541717ca2db", "Atari, Tod Frye", "CX2646", "Pac-Man (1982) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fc24a94d4371c69bc58f5245ada43c44", "Atari - Axlon, Steve DeFrisco", "CX26170", "Secret Quest (1989) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fc6052438f339aea373bbc999433388a", "Atari, David Crane", "CX2653P", "Slot Machine (1979) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fc668a2251dd79cbd903d4fa0e558f96", "Thomas Jentzsch", "", "Thrust (V1.1) (2000) (TJ) [a1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fc92d74f073a44bc6e46a3b3fa8256a2", "", "", "Megademo (19xx) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fc9c1652fe3a2cade6188f4d3692481f", "Andrew Davies", "", "Andrew Davies early notBoulderDash demo (NTSC)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "fca4a5be1251927027f2c24774a02160", "Activision, John Van Ryzin", "AZ-036-04", "H.E.R.O. (1984) (Activision)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fcbbd0a407d3ff7bf857b8a399280ea1", "ZiMAG - Emag - Vidco", "GN-070", "Mysterious Thief, A (1983) (ZiMAG) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "fcbdf405f0fc2027b0ea45bb5af94c1a", "Amiga - Video Soft, Michael K. Glass, Jerry Lawson", "", "3-D Ghost Attack (1983) (Amiga) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "fcea12625c071ddc49f4e409f4038c60", "Fabrizio Zavagli", "", "Balls! (16-09-2002) (Fabrizio Zavagli)", "", "Homebrew", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" },
+  { "fcf8e306f6615f74feba5cb25550038c", "", "", "Blue Dot Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fd0e5148162e8ec6719445d559f018a9", "Activision, Steve Cartwright - Ariola", "EAX-022, EAX-022-04I - 711 022-720", "Seaquest (1983) (Activision) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fd10915633aea4f9cd8b518a25d62b55", "Atari, John Dunn", "CX2631, CX2631P", "Superman (1979) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fd16949913aaab5beaefed73bf2ca67c", "Atari - GCC, John Allred, Mike Feinstein", "CX2688", "Jungle Hunt (02-03-1983) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fd4f5536fd80f35c64d365df85873418", "Atari - Bobco, Robert C. Polaro", "CX26140", "Desert Falcon (1987) (Atari)", "AKA Nile Flyer, Sphinx", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fd6e507b5df68beeeddeaf696b6828fa", "", "", "Boxing (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fd7464edaa8cc264b97ba0d13e7f0678", "HES", "771-333", "2 Pak Special - Challenge, Surfing (1990) (HES) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fd78f186bdff83fbad7f97cb583812fe", "Amiga - Video Soft", "3125", "Surf's Up (1983) (Amiga) (Prototype) [a2]", "Uses the Joyboard controller", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fd8b4ee0d57605b35e236e814f706ff1", "Atari - GCC, Mike Feinstein, John Mracek", "CX2673, CX2673P", "Phoenix (1982) (Atari) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fd9b321cee5fbb32c39ba3ca5d9ec7cf", "Jeffry Johnston", "", "Radial Pong - Version 5 (Jeffry Johnston) (PD)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fdd4995a50395db14f518f63c2d63438", "", "", "Oh No! (Version 3) (18-01-2003) (AD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fde42e39710e75e9e4d4d75440f8e4e5", "Thomas Jentzsch", "", "Coke Zero (v1.0) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fdf0de38517e0cf7f0885f98ccc95836", "Arcadia Corporation, Dennis Caswell", "AR-4200", "Escape from the Mindmaster (2 of 4) (1982) (Arcadia)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fdf6680b2b1e8054293a39700a765692", "", "", "Alpha Demo - The Beta Demo 2 (2000) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fe0b7f27e3ad50bbf9ff468ee56d553d", "", "", "Lines Demo (Eckhard Stolberg) (PAL) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fe0bc4bb92c1c4de7d5706aaa8d8c10d", "", "", "Sprite Demo 2 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fe3b461d4c8b179fe68bc77760294c25", "Atari, Joe Decuir", "CX2621, CX2621P", "Video Olympics (1977) (Atari) (PAL) (4K)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "", "YES", "", "", "", "", "", "", "" },
+  { "fe641247a4ab9bee970e19ab55f23b25", "20th Century Fox Video Games, Beck-Tech, Steve Beck", "11035", "Save the Whales (02-07-1983) (20th Century Fox) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fe67087f9c22655ce519616fc6c6ef4d", "Atari - Zip Technology, Randy Bowker, Bruce Williams", "CX26142", "Crack'ed (11-28-1988) (Atari) (Prototype)", "", "Prototype", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fe6abc0f63e31e2646c9c600926b5b7f", "Atari", "CX26137", "4 in 1 (02-19-1987) (Atari) (Prototype)", "Home Run, Canyon Bomber, Sky Diver, Night Driver", "Prototype", "", "", "4IN1", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fe870018332a0221eb59fb18b0c6bccc", "", "", "Incoming (08-11-2002) (Ben Larson) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fe9ae625d924b54c9f8a14ac9a0f6c6d", "BG Dodson", "", "High Bid! (BG Dodson) (Hack)", "Hack of Pepsi Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "feba8686fd0376015258d1152923958a", "", "", "Super Circus (Unknown) (PAL)", "AKA Circus Atari", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fec0c2e2ab0588ed20c750b58cf3baa3", "Activision - Cheshire Engineering, David Rolfe, Larry Zwick", "EAZ-037-04, EAZ-037-04I", "Beamrider (1984) (Activision) (PAL)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "fece458a8023a809a5006867feca40e8", "", "", "SCSIcide (24-02-2001) (Joe Grand) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "feec54aac911887940b47fe8c9f80b11", "Atari, Rob Fulop", "CX2633, CX2633P", "Night Driver (1980) (Atari) (PAL)", "Uses the Paddle Controllers (left only)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AUTO 65", "", "", "YES", "" },
+  { "feedcc20bc3ca34851cd5d9e38aa2ca6", "Atari, David Crane - Sears", "CX2607 - 6-99828, 49-75115", "Canyon Bomber (1979) (Atari)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXDR", "", "", "", "", "", "YES", "", "", "10", "", "", "", "" },
+  { "ff1523783e0e76a3b0d1f7f0d1cb3050", "Thomas Jentzsch", "", "Marble Craze - Atari Trak-Ball Hack v1.0 (PAL) (TJ)", "Uses Atari Trak-Ball Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ff3bd0c684f7144aeaa18758d8281a78", "Atari, Bob Whitehead", "CX2651", "Blackjack (1977) (Atari) (PAL)", "Uses the Paddle Controllers", "Rare", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ff5a9e340d96df6f5a5b6eb038e923bd", "", "", "Space Shuttle (1983) (Activision) [t1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ff7627207e8aa03730c35c735a82c26c", "Atari, Bob Whitehead", "CX26163P", "Blackjack (32 in 1) (1988) (Atari) (PAL)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "", "PADDLES_IAXIS", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ff86fc8ffa717bb095e8471638c1c31c", "Arcadia Corporation, Dennis Caswell", "AR-4302", "Party Mix - Bop a Buggy (1 of 3) (1983) (Arcadia) (PAL)", "Uses Paddle Controllers", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "01 56", "", "", "", "" },
+  { "ff87d58125ae517eb7b09a0475a1ccdc", "", "", "SCSIcide (Score Hack 1) (24-02-2001) (Joe Grand) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ffb1cd548563158ce33f9d10268187e7", "Erik Eid", "", "Euchre (Beta) (NTSC) (12-09-2002) (Erik Eid)", "", "New Release", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ffc0ff4305dd46b4b459885bd1818e2e", "Barry Laws Jr.", "", "Star Wars - The Battle of Alderaan (Star Strike Hack)", "Hack of Star Strike (Mattel)", "New Release (Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ffdc0eb3543404eb4c353fbdddfa33b6", "CCE", "C-827", "Chopper Command (1983) (CCE) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ffe51989ba6da2c6ae5a12d277862e16", "Atari - Sears", "CX2627 - 6-99841", "Human Cannonball (1979) (Atari) (4K)", "AKA Cannon Man", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
+  { "ffebb0070689b9d322687edd9c0a2bae", "", "", "Spitfire Attack (1983) (Milton Bradley) [h1]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }
 }};
 
 #endif
diff --git a/src/emucore/DispatchResult.cxx b/src/emucore/DispatchResult.cxx
index 20a208a56..9ba5326ca 100644
--- a/src/emucore/DispatchResult.cxx
+++ b/src/emucore/DispatchResult.cxx
@@ -31,11 +31,13 @@ void DispatchResult::setOk(uInt64 cycles)
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void DispatchResult::setDebugger(uInt64 cycles, const string& message, int address, bool wasReadTrap)
+void DispatchResult::setDebugger(uInt64 cycles, const string& message,
+                                 const string& tooltip, int address, bool wasReadTrap)
 {
   myStatus = Status::debugger;
   myCycles = cycles;
   myMessage = message;
+  myToolTip = tooltip;
   myAddress = address;
   myWasReadTrap = wasReadTrap;
 }
diff --git a/src/emucore/DispatchResult.hxx b/src/emucore/DispatchResult.hxx
index 6d76cf5ce..38e80a9c5 100644
--- a/src/emucore/DispatchResult.hxx
+++ b/src/emucore/DispatchResult.hxx
@@ -37,12 +37,14 @@ class DispatchResult
 
     bool wasReadTrap() const { assertStatus(Status::debugger); return myWasReadTrap; }
 
+    const string& getToolTip() const { assertStatus(Status::debugger, Status::fatal); return myToolTip; }
+
     bool isSuccess() const;
 
     void setOk(uInt64 cycles);
 
-    void setDebugger(uInt64 cycles, const string& message = "", int address = -1,
-                     bool wasReadTrap = true);
+    void setDebugger(uInt64 cycles, const string& message = "",
+                     const string& tooltip = "", int address = -1, bool wasReadTrap = true);
 
     void setFatal(uInt64 cycles);
 
@@ -73,6 +75,8 @@ class DispatchResult
     int myAddress{0};
 
     bool myWasReadTrap{false};
+
+    string myToolTip;
 };
 
 #endif // DISPATCH_RESULT_HXX
diff --git a/src/emucore/Driving.cxx b/src/emucore/Driving.cxx
index bd08a03e0..490759e63 100644
--- a/src/emucore/Driving.cxx
+++ b/src/emucore/Driving.cxx
@@ -21,22 +21,40 @@
 #include "Driving.hxx"
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Driving::Driving(Jack jack, const Event& event, const System& system)
+Driving::Driving(Jack jack, const Event& event, const System& system, bool altmap)
   : Controller(jack, event, system, Controller::Type::Driving)
 {
   if(myJack == Jack::Left)
   {
-    myCCWEvent   = Event::JoystickZeroLeft;
-    myCWEvent    = Event::JoystickZeroRight;
-    myFireEvent  = Event::JoystickZeroFire;
+    if(!altmap)
+    {
+      myCCWEvent  = Event::JoystickZeroLeft;
+      myCWEvent   = Event::JoystickZeroRight;
+      myFireEvent = Event::JoystickZeroFire;
+    }
+    else
+    {
+      myCCWEvent  = Event::JoystickTwoLeft;
+      myCWEvent   = Event::JoystickTwoRight;
+      myFireEvent = Event::JoystickTwoFire;
+    }
     myXAxisValue = Event::PaddleZeroAnalog;
     myYAxisValue = Event::PaddleOneAnalog;
   }
   else
   {
-    myCCWEvent   = Event::JoystickOneLeft;
-    myCWEvent    = Event::JoystickOneRight;
-    myFireEvent  = Event::JoystickOneFire;
+    if(!altmap)
+    {
+      myCCWEvent  = Event::JoystickOneLeft;
+      myCWEvent   = Event::JoystickOneRight;
+      myFireEvent = Event::JoystickOneFire;
+    }
+    else
+    {
+      myCCWEvent  = Event::JoystickThreeLeft;
+      myCWEvent   = Event::JoystickThreeRight;
+      myFireEvent = Event::JoystickThreeFire;
+    }
     myXAxisValue = Event::PaddleTwoAnalog;
     myYAxisValue = Event::PaddleThreeAnalog;
   }
diff --git a/src/emucore/Driving.hxx b/src/emucore/Driving.hxx
index 35a02b2c1..863132890 100644
--- a/src/emucore/Driving.hxx
+++ b/src/emucore/Driving.hxx
@@ -33,11 +33,12 @@ class Driving : public Controller
       Create a new Indy 500 driving controller plugged into
       the specified jack
 
-      @param jack   The jack the controller is plugged into
-      @param event  The event object to use for events
-      @param system The system using this controller
+      @param jack    The jack the controller is plugged into
+      @param event   The event object to use for events
+      @param system  The system using this controller
+      @param altmap  If true, use alternative mapping
     */
-    Driving(Jack jack, const Event& event, const System& system);
+    Driving(Jack jack, const Event& event, const System& system, bool altmap = false);
     ~Driving() override = default;
 
   public:
diff --git a/src/emucore/Event.hxx b/src/emucore/Event.hxx
index 197f7569f..f348fbeff 100644
--- a/src/emucore/Event.hxx
+++ b/src/emucore/Event.hxx
@@ -123,12 +123,27 @@ class Event
       ToggleFrameStats, ToggleSAPortOrder, ExitGame,
       SettingDecrease, SettingIncrease, PreviousSetting, NextSetting,
       ToggleAdaptRefresh, PreviousMultiCartRom,
-      // add new events from here to avoid that user remapped events get overwritten
+      // add new (after Version 4) events from here to avoid that user remapped events get overwritten
       PreviousSettingGroup, NextSettingGroup,
       TogglePlayBackMode,
       DecreaseAutoFire, IncreaseAutoFire,
       DecreaseSpeed, IncreaseSpeed,
 
+      JoystickTwoUp, JoystickTwoDown, JoystickTwoLeft, JoystickTwoRight,
+      JoystickTwoFire,
+      JoystickThreeUp, JoystickThreeDown, JoystickThreeLeft, JoystickThreeRight,
+      JoystickThreeFire,
+
+      ToggleCorrectAspectRatio,
+
+      MoveLeftChar, MoveRightChar, MoveLeftWord, MoveRightWord,
+      MoveHome, MoveEnd,
+      SelectLeftChar, SelectRightChar, SelectLeftWord, SelectRightWord,
+      SelectHome, SelectEnd, SelectAll,
+      Delete, DeleteLeftWord, DeleteRightWord, DeleteHome, DeleteEnd, Backspace,
+      Cut, Copy, Paste, Undo, Redo,
+      AbortEdit, EndEdit,
+
       LastType
     };
 
@@ -217,11 +232,15 @@ class Event
 static const Event::EventSet LeftJoystickEvents = {
   Event::JoystickZeroUp, Event::JoystickZeroDown, Event::JoystickZeroLeft, Event::JoystickZeroRight,
   Event::JoystickZeroFire, Event::JoystickZeroFire5, Event::JoystickZeroFire9,
+  Event::JoystickTwoUp, Event::JoystickTwoDown, Event::JoystickTwoLeft, Event::JoystickTwoRight,
+  Event::JoystickTwoFire
 };
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 static const Event::EventSet RightJoystickEvents = {
   Event::JoystickOneUp, Event::JoystickOneDown, Event::JoystickOneLeft, Event::JoystickOneRight,
-  Event::JoystickOneFire, Event::JoystickOneFire5, Event::JoystickOneFire9
+  Event::JoystickOneFire, Event::JoystickOneFire5, Event::JoystickOneFire9,
+  Event::JoystickThreeUp, Event::JoystickThreeDown, Event::JoystickThreeLeft, Event::JoystickThreeRight,
+  Event::JoystickThreeFire
 };
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx
index ed72579a6..5eced0d94 100644
--- a/src/emucore/EventHandler.cxx
+++ b/src/emucore/EventHandler.cxx
@@ -69,16 +69,6 @@ using namespace std::placeholders;
 EventHandler::EventHandler(OSystem& osystem)
   : myOSystem(osystem)
 {
-  // Create keyboard handler (to handle all physical keyboard functionality)
-  myPKeyHandler = make_unique<PhysicalKeyboardHandler>(osystem, *this);
-
-  // Create joystick handler (to handle all physical joystick functionality)
-  myPJoyHandler = make_unique<PhysicalJoystickHandler>(osystem, *this);
-
-  // Erase the 'combo' array
-  for(int i = 0; i < COMBO_SIZE; ++i)
-    for(int j = 0; j < EVENTS_PER_COMBO; ++j)
-      myComboTable[i][j] = Event::NoType;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -89,6 +79,17 @@ EventHandler::~EventHandler()
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void EventHandler::initialize()
 {
+  // Create keyboard handler (to handle all physical keyboard functionality)
+  myPKeyHandler = make_unique<PhysicalKeyboardHandler>(myOSystem, *this);
+
+  // Create joystick handler (to handle all physical joystick functionality)
+  myPJoyHandler = make_unique<PhysicalJoystickHandler>(myOSystem, *this);
+
+  // Erase the 'combo' array
+  for(int i = 0; i < COMBO_SIZE; ++i)
+    for(int j = 0; j < EVENTS_PER_COMBO; ++j)
+      myComboTable[i][j] = Event::NoType;
+
   // Make sure the event/action mappings are correctly set,
   // and fill the ActionList structure with valid values
   setComboMap();
@@ -190,12 +191,12 @@ void EventHandler::toggleSAPortOrder()
   if(saport == "lr")
   {
     mapStelladaptors("rl");
-    myOSystem.frameBuffer().showMessage("Stelladaptor ports right/left");
+    myOSystem.frameBuffer().showTextMessage("Stelladaptor ports right/left");
   }
   else
   {
     mapStelladaptors("lr");
-    myOSystem.frameBuffer().showMessage("Stelladaptor ports left/right");
+    myOSystem.frameBuffer().showTextMessage("Stelladaptor ports left/right");
   }
 #endif
 }
@@ -213,7 +214,7 @@ void EventHandler::set7800Mode()
 void EventHandler::handleMouseControl()
 {
   if(myMouseControl)
-    myOSystem.frameBuffer().showMessage(myMouseControl->next());
+    myOSystem.frameBuffer().showTextMessage(myMouseControl->next());
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -322,7 +323,8 @@ void EventHandler::handleSystemEvent(SystemEvent e, int, int)
   {
     case SystemEvent::WINDOW_EXPOSED:
     case SystemEvent::WINDOW_RESIZED:
-      myOSystem.frameBuffer().update(true); // force full update
+      // Force full render update
+      myOSystem.frameBuffer().update(FrameBuffer::UpdateMode::RERENDER);
       break;
 #ifdef BSPF_UNIX
     case SystemEvent::WINDOW_FOCUS_GAINED:
@@ -377,7 +379,9 @@ AdjustFunction EventHandler::cycleAdjustSetting(int direction)
         #ifdef ADAPTABLE_REFRESH_SUPPORT
           || (myAdjustSetting == AdjustSetting::ADAPT_REFRESH && !isFullScreen)
         #endif
-          || (myAdjustSetting == AdjustSetting::PALETTE_PHASE && !isCustomPalette)
+          || (myAdjustSetting >= AdjustSetting::PALETTE_PHASE
+              && myAdjustSetting <= AdjustSetting::PALETTE_BLUE_SHIFT
+              && !isCustomPalette)
           || (myAdjustSetting >= AdjustSetting::NTSC_SHARPNESS
               && myAdjustSetting <= AdjustSetting::NTSC_BLEEDING
               && !isCustomFilter);
@@ -411,7 +415,7 @@ AdjustFunction EventHandler::getAdjustSetting(AdjustSetting setting)
   {
     // Audio & Video settings
     std::bind(&Sound::adjustVolume, &myOSystem.sound(), _1),
-    std::bind(&FrameBuffer::selectVidMode, &myOSystem.frameBuffer(), _1),
+    std::bind(&FrameBuffer::switchVideoMode, &myOSystem.frameBuffer(), _1),
     std::bind(&FrameBuffer::toggleFullscreen, &myOSystem.frameBuffer(), _1),
   #ifdef ADAPTABLE_REFRESH_SUPPORT
     std::bind(&FrameBuffer::toggleAdaptRefresh, &myOSystem.frameBuffer(), _1),
@@ -419,11 +423,24 @@ AdjustFunction EventHandler::getAdjustSetting(AdjustSetting setting)
     std::bind(&FrameBuffer::changeOverscan, &myOSystem.frameBuffer(), _1),
     std::bind(&Console::selectFormat, &myOSystem.console(), _1),
     std::bind(&Console::changeVerticalCenter, &myOSystem.console(), _1),
+    std::bind(&Console::toggleCorrectAspectRatio, &myOSystem.console(), _1),
     std::bind(&Console::changeVSizeAdjust, &myOSystem.console(), _1),
     // Palette adjustables
     std::bind(&PaletteHandler::cyclePalette, &myOSystem.frameBuffer().tiaSurface().paletteHandler(), _1),
     std::bind(&PaletteHandler::changeAdjustable, &myOSystem.frameBuffer().tiaSurface().paletteHandler(),
       PaletteHandler::PHASE_SHIFT, _1),
+    std::bind(&PaletteHandler::changeAdjustable, &myOSystem.frameBuffer().tiaSurface().paletteHandler(),
+      PaletteHandler::RED_SCALE, _1),
+    std::bind(&PaletteHandler::changeAdjustable, &myOSystem.frameBuffer().tiaSurface().paletteHandler(),
+      PaletteHandler::RED_SHIFT, _1),
+    std::bind(&PaletteHandler::changeAdjustable, &myOSystem.frameBuffer().tiaSurface().paletteHandler(),
+      PaletteHandler::GREEN_SCALE, _1),
+    std::bind(&PaletteHandler::changeAdjustable, &myOSystem.frameBuffer().tiaSurface().paletteHandler(),
+      PaletteHandler::GREEN_SHIFT, _1),
+    std::bind(&PaletteHandler::changeAdjustable, &myOSystem.frameBuffer().tiaSurface().paletteHandler(),
+      PaletteHandler::BLUE_SCALE, _1),
+    std::bind(&PaletteHandler::changeAdjustable, &myOSystem.frameBuffer().tiaSurface().paletteHandler(),
+      PaletteHandler::BLUE_SHIFT, _1),
     std::bind(&PaletteHandler::changeAdjustable, &myOSystem.frameBuffer().tiaSurface().paletteHandler(),
       PaletteHandler::HUE, _1),
     std::bind(&PaletteHandler::changeAdjustable, &myOSystem.frameBuffer().tiaSurface().paletteHandler(),
@@ -534,7 +551,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
           default:
             break;
         }
-        myOSystem.frameBuffer().showMessage(msg + " settings");
+        myOSystem.frameBuffer().showTextMessage(msg + " settings");
         myAdjustActive = false;
       }
       break;
@@ -620,6 +637,46 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
         myEvent.set(Event::JoystickOneLeft, 0);
       break;
 
+    case Event::JoystickTwoUp:
+      if(!myAllowAllDirectionsFlag && pressed)
+        myEvent.set(Event::JoystickTwoDown, 0);
+      break;
+
+    case Event::JoystickTwoDown:
+      if(!myAllowAllDirectionsFlag && pressed)
+        myEvent.set(Event::JoystickTwoUp, 0);
+      break;
+
+    case Event::JoystickTwoLeft:
+      if(!myAllowAllDirectionsFlag && pressed)
+        myEvent.set(Event::JoystickTwoRight, 0);
+      break;
+
+    case Event::JoystickTwoRight:
+      if(!myAllowAllDirectionsFlag && pressed)
+        myEvent.set(Event::JoystickTwoLeft, 0);
+      break;
+
+    case Event::JoystickThreeUp:
+      if(!myAllowAllDirectionsFlag && pressed)
+        myEvent.set(Event::JoystickThreeDown, 0);
+      break;
+
+    case Event::JoystickThreeDown:
+      if(!myAllowAllDirectionsFlag && pressed)
+        myEvent.set(Event::JoystickThreeUp, 0);
+      break;
+
+    case Event::JoystickThreeLeft:
+      if(!myAllowAllDirectionsFlag && pressed)
+        myEvent.set(Event::JoystickThreeRight, 0);
+      break;
+
+    case Event::JoystickThreeRight:
+      if(!myAllowAllDirectionsFlag && pressed)
+        myEvent.set(Event::JoystickThreeLeft, 0);
+      break;
+
     ///////////////////////////////////////////////////////////////////////////
     // Audio & Video events (with global hotkeys)
     case Event::VolumeDecrease:
@@ -652,7 +709,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
     case Event::VidmodeDecrease:
       if(pressed)
       {
-        myOSystem.frameBuffer().selectVidMode(-1);
+        myOSystem.frameBuffer().switchVideoMode(-1);
         myAdjustSetting = AdjustSetting::ZOOM;
         myAdjustActive = true;
       }
@@ -661,7 +718,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
     case Event::VidmodeIncrease:
       if(pressed)
       {
-        myOSystem.frameBuffer().selectVidMode(+1);
+        myOSystem.frameBuffer().switchVideoMode(+1);
         myAdjustSetting = AdjustSetting::ZOOM;
         myAdjustActive = true;
       }
@@ -740,7 +797,6 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
         myAdjustActive = true;
       }
       return;
-
     case Event::VSizeAdjustDecrease:
       if(pressed)
       {
@@ -759,6 +815,15 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
       }
       return;
 
+    case Event::ToggleCorrectAspectRatio:
+      if(pressed && !repeated)
+      {
+        myOSystem.console().toggleCorrectAspectRatio();
+        myAdjustSetting = AdjustSetting::ASPECT_RATIO;
+        myAdjustActive = true;
+      }
+      break;
+
     case Event::PaletteDecrease:
       if (pressed && !repeated)
       {
@@ -1146,7 +1211,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
 
     case Event::SaveAllStates:
       if (pressed && !repeated)
-        myOSystem.frameBuffer().showMessage(myOSystem.state().rewindManager().saveAllStates());
+        myOSystem.frameBuffer().showTextMessage(myOSystem.state().rewindManager().saveAllStates());
       return;
 
     case Event::PreviousState:
@@ -1179,7 +1244,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
 
     case Event::LoadAllStates:
       if (pressed && !repeated)
-        myOSystem.frameBuffer().showMessage(myOSystem.state().rewindManager().loadAllStates());
+        myOSystem.frameBuffer().showTextMessage(myOSystem.state().rewindManager().loadAllStates());
       return;
 
     case Event::RewindPause:
@@ -1412,7 +1477,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
       {
         myEvent.set(Event::ConsoleBlackWhite, 0);
         myEvent.set(Event::ConsoleColor, 1);
-        myOSystem.frameBuffer().showMessage(myIs7800 ? "Pause released" : "Color Mode");
+        myOSystem.frameBuffer().showTextMessage(myIs7800 ? "Pause released" : "Color Mode");
         myOSystem.console().switches().update();
       }
       return;
@@ -1421,7 +1486,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
       {
         myEvent.set(Event::ConsoleBlackWhite, 1);
         myEvent.set(Event::ConsoleColor, 0);
-        myOSystem.frameBuffer().showMessage(myIs7800 ? "Pause pushed" : "B/W Mode");
+        myOSystem.frameBuffer().showTextMessage(myIs7800 ? "Pause pushed" : "B/W Mode");
         myOSystem.console().switches().update();
       }
       return;
@@ -1432,13 +1497,13 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
         {
           myEvent.set(Event::ConsoleBlackWhite, 1);
           myEvent.set(Event::ConsoleColor, 0);
-          myOSystem.frameBuffer().showMessage(myIs7800 ? "Pause pushed" : "B/W Mode");
+          myOSystem.frameBuffer().showTextMessage(myIs7800 ? "Pause pushed" : "B/W Mode");
         }
         else
         {
           myEvent.set(Event::ConsoleBlackWhite, 0);
           myEvent.set(Event::ConsoleColor, 1);
-          myOSystem.frameBuffer().showMessage(myIs7800 ? "Pause released" : "Color Mode");
+          myOSystem.frameBuffer().showTextMessage(myIs7800 ? "Pause released" : "Color Mode");
         }
         myOSystem.console().switches().update();
       }
@@ -1450,7 +1515,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
         myEvent.set(Event::ConsoleBlackWhite, 0);
         myEvent.set(Event::ConsoleColor, 0);
         if (myIs7800)
-          myOSystem.frameBuffer().showMessage("Pause pressed");
+          myOSystem.frameBuffer().showTextMessage("Pause pressed");
         myOSystem.console().switches().update();
       }
       return;
@@ -1460,7 +1525,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
       {
         myEvent.set(Event::ConsoleLeftDiffA, 1);
         myEvent.set(Event::ConsoleLeftDiffB, 0);
-        myOSystem.frameBuffer().showMessage(GUI::LEFT_DIFFICULTY + " A");
+        myOSystem.frameBuffer().showTextMessage(GUI::LEFT_DIFFICULTY + " A");
         myOSystem.console().switches().update();
       }
       return;
@@ -1469,7 +1534,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
       {
         myEvent.set(Event::ConsoleLeftDiffA, 0);
         myEvent.set(Event::ConsoleLeftDiffB, 1);
-        myOSystem.frameBuffer().showMessage(GUI::LEFT_DIFFICULTY + " B");
+        myOSystem.frameBuffer().showTextMessage(GUI::LEFT_DIFFICULTY + " B");
         myOSystem.console().switches().update();
       }
       return;
@@ -1480,13 +1545,13 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
         {
           myEvent.set(Event::ConsoleLeftDiffA, 0);
           myEvent.set(Event::ConsoleLeftDiffB, 1);
-          myOSystem.frameBuffer().showMessage(GUI::LEFT_DIFFICULTY + " B");
+          myOSystem.frameBuffer().showTextMessage(GUI::LEFT_DIFFICULTY + " B");
         }
         else
         {
           myEvent.set(Event::ConsoleLeftDiffA, 1);
           myEvent.set(Event::ConsoleLeftDiffB, 0);
-          myOSystem.frameBuffer().showMessage(GUI::LEFT_DIFFICULTY + " A");
+          myOSystem.frameBuffer().showTextMessage(GUI::LEFT_DIFFICULTY + " A");
         }
         myOSystem.console().switches().update();
       }
@@ -1497,7 +1562,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
       {
         myEvent.set(Event::ConsoleRightDiffA, 1);
         myEvent.set(Event::ConsoleRightDiffB, 0);
-        myOSystem.frameBuffer().showMessage(GUI::RIGHT_DIFFICULTY + " A");
+        myOSystem.frameBuffer().showTextMessage(GUI::RIGHT_DIFFICULTY + " A");
         myOSystem.console().switches().update();
       }
       return;
@@ -1506,7 +1571,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
       {
         myEvent.set(Event::ConsoleRightDiffA, 0);
         myEvent.set(Event::ConsoleRightDiffB, 1);
-        myOSystem.frameBuffer().showMessage(GUI::RIGHT_DIFFICULTY + " B");
+        myOSystem.frameBuffer().showTextMessage(GUI::RIGHT_DIFFICULTY + " B");
         myOSystem.console().switches().update();
       }
       return;
@@ -1517,13 +1582,13 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
         {
           myEvent.set(Event::ConsoleRightDiffA, 0);
           myEvent.set(Event::ConsoleRightDiffB, 1);
-          myOSystem.frameBuffer().showMessage(GUI::RIGHT_DIFFICULTY + " B");
+          myOSystem.frameBuffer().showTextMessage(GUI::RIGHT_DIFFICULTY + " B");
         }
         else
         {
           myEvent.set(Event::ConsoleRightDiffA, 1);
           myEvent.set(Event::ConsoleRightDiffB, 0);
-          myOSystem.frameBuffer().showMessage(GUI::RIGHT_DIFFICULTY + " A");
+          myOSystem.frameBuffer().showTextMessage(GUI::RIGHT_DIFFICULTY + " A");
         }
         myOSystem.console().switches().update();
       }
@@ -2223,6 +2288,7 @@ void EventHandler::enterMenuMode(EventHandlerState state)
 void EventHandler::leaveMenuMode()
 {
 #ifdef GUI_SUPPORT
+  myOverlay->removeDialog(); // remove the base dialog from dialog stack
   setState(EventHandlerState::EMULATION);
   myOSystem.sound().mute(false);
 #endif
@@ -2248,15 +2314,16 @@ bool EventHandler::enterDebugMode()
     myOSystem.debugger().setQuitState();
     setState(EventHandlerState::EMULATION);
     if(fbstatus == FBInitStatus::FailTooLarge)
-      myOSystem.frameBuffer().showMessage("Debugger window too large for screen",
-                                          MessagePosition::BottomCenter, true);
+      myOSystem.frameBuffer().showTextMessage("Debugger window too large for screen",
+                                              MessagePosition::BottomCenter, true);
     return false;
   }
   myOverlay->reStack();
   myOSystem.sound().mute(true);
+
 #else
-  myOSystem.frameBuffer().showMessage("Debugger support not included",
-                                      MessagePosition::BottomCenter, true);
+  myOSystem.frameBuffer().showTextMessage("Debugger support not included",
+                                          MessagePosition::BottomCenter, true);
 #endif
 
   return true;
@@ -2467,6 +2534,18 @@ EventHandler::EmulActionList EventHandler::ourEmulActionList = { {
   { Event::JoystickOneFire5,        "P1 Booster Top Booster Button",         "" },
   { Event::JoystickOneFire9,        "P1 Booster Handle Grip Trigger",        "" },
 
+  { Event::JoystickTwoUp,           "P2 Joystick Up",                        "" },
+  { Event::JoystickTwoDown,         "P2 Joystick Down",                      "" },
+  { Event::JoystickTwoLeft,         "P2 Joystick Left",                      "" },
+  { Event::JoystickTwoRight,        "P2 Joystick Right",                     "" },
+  { Event::JoystickTwoFire,         "P2 Joystick Fire",                      "" },
+
+  { Event::JoystickThreeUp,         "P3 Joystick Up",                        "" },
+  { Event::JoystickThreeDown,       "P3 Joystick Down",                      "" },
+  { Event::JoystickThreeLeft,       "P3 Joystick Left",                      "" },
+  { Event::JoystickThreeRight,      "P3 Joystick Right",                     "" },
+  { Event::JoystickThreeFire,       "P3 Joystick Fire",                      "" },
+
   { Event::PaddleZeroAnalog,        "Paddle 0 Analog",                       "" },
   { Event::PaddleZeroIncrease,      "Paddle 0 Turn Left",                    "" },
   { Event::PaddleZeroDecrease,      "Paddle 0 Turn Right",                   "" },
@@ -2521,6 +2600,7 @@ EventHandler::EmulActionList EventHandler::ourEmulActionList = { {
   { Event::OverscanIncrease,        "Increase overscan in fullscreen mode",  "" },
   { Event::VidmodeDecrease,         "Previous zoom level",                   "" },
   { Event::VidmodeIncrease,         "Next zoom level",                       "" },
+  { Event::ToggleCorrectAspectRatio,"Toggle aspect ratio correct scaling",   "" },
   { Event::VSizeAdjustDecrease,     "Decrease vertical display size",        "" },
   { Event::VSizeAdjustIncrease,     "Increase vertical display size",        "" },
   { Event::VCenterDecrease,         "Move display up",                       "" },
@@ -2673,7 +2753,7 @@ const Event::EventSet EventHandler::AudioVideoEvents = {
   Event::OverscanDecrease, Event::OverscanIncrease,
   Event::FormatDecrease, Event::FormatIncrease,
   Event::VCenterDecrease, Event::VCenterIncrease,
-  Event::VSizeAdjustDecrease, Event::VSizeAdjustIncrease,
+  Event::VSizeAdjustDecrease, Event::VSizeAdjustIncrease, Event::ToggleCorrectAspectRatio,
   Event::PaletteDecrease, Event::PaletteIncrease,
   Event::PreviousPaletteAttribute, Event::NextPaletteAttribute,
   Event::PaletteAttributeDecrease, Event::PaletteAttributeIncrease,
@@ -2711,6 +2791,10 @@ const Event::EventSet EventHandler::JoystickEvents = {
   Event::JoystickZeroFire, Event::JoystickZeroFire5, Event::JoystickZeroFire9,
   Event::JoystickOneUp, Event::JoystickOneDown, Event::JoystickOneLeft, Event::JoystickOneRight,
   Event::JoystickOneFire, Event::JoystickOneFire5, Event::JoystickOneFire9,
+  Event::JoystickTwoUp, Event::JoystickTwoDown, Event::JoystickTwoLeft, Event::JoystickTwoRight,
+  Event::JoystickTwoFire,
+  Event::JoystickThreeUp, Event::JoystickThreeDown, Event::JoystickThreeLeft, Event::JoystickThreeRight,
+  Event::JoystickThreeFire,
 };
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -2750,3 +2834,8 @@ const Event::EventSet EventHandler::DebugEvents = {
   Event::ToggleColorLoss,
   Event::ToggleJitter,
 };
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+const Event::EventSet EventHandler::EditEvents = {
+
+};
diff --git a/src/emucore/EventHandler.hxx b/src/emucore/EventHandler.hxx
index 4c7954c40..5671e1291 100644
--- a/src/emucore/EventHandler.hxx
+++ b/src/emucore/EventHandler.hxx
@@ -102,7 +102,7 @@ class EventHandler
     void poll(uInt64 time);
 
     /**
-      Get/set the current state of the EventHandler
+      Get/set the current state of the EventHandler.
 
       @return The EventHandlerState type
     */
@@ -110,7 +110,18 @@ class EventHandler
     void setState(EventHandlerState state);
 
     /**
-      Resets the state machine of the EventHandler to the defaults
+      Convenience method that checks if we're in TIA mode.
+
+      @return Whether TIA mode is active
+    */
+    bool inTIAMode() const {
+      return !(myState == EventHandlerState::DEBUGGER ||
+               myState == EventHandlerState::LAUNCHER ||
+               myState == EventHandlerState::NONE);
+    }
+
+    /**
+      Resets the state machine of the EventHandler to the defaults.
 
       @param state  The current state to set
     */
@@ -326,6 +337,19 @@ class EventHandler
     */
     virtual void enableTextEvents(bool enable) = 0;
 
+  #ifdef GUI_SUPPORT
+    /**
+      Check for QWERTZ keyboard layout
+    */
+    bool isQwertz() { return myQwertz; }
+
+    /**
+      Clipboard methods.
+    */
+    virtual void copyText(const string& text) const = 0;
+    virtual string pasteText(string& text) const = 0;
+  #endif
+
     /**
       Handle changing mouse modes.
     */
@@ -340,6 +364,11 @@ class EventHandler
     // Global OSystem object
     OSystem& myOSystem;
 
+  #ifdef GUI_SUPPORT
+    // Keyboard layout
+    bool myQwertz{false};
+  #endif
+
     /**
       Methods which are called by derived classes to handle specific types
       of input.
@@ -406,10 +435,17 @@ class EventHandler
       OVERSCAN,
       TVFORMAT,
       VCENTER,
+      ASPECT_RATIO,
       VSIZE,
       // Palette adjustables
       PALETTE,
       PALETTE_PHASE,
+      PALETTE_RED_SCALE,
+      PALETTE_RED_SHIFT,
+      PALETTE_GREEN_SCALE,
+      PALETTE_GREEN_SHIFT,
+      PALETTE_BLUE_SCALE,
+      PALETTE_BLUE_SHIFT,
       PALETTE_HUE,
       PALETTE_SATURATION,
       PALETTE_CONTRAST,
@@ -475,6 +511,7 @@ class EventHandler
     static const Event::EventSet KeyboardEvents;
     static const Event::EventSet ComboEvents;
     static const Event::EventSet DebugEvents;
+    static const Event::EventSet EditEvents;
 
     /**
       The following methods take care of assigning action mappings.
@@ -559,7 +596,7 @@ class EventHandler
     #else
       REFRESH_SIZE         = 0,
     #endif
-      EMUL_ACTIONLIST_SIZE = 164 + PNG_SIZE + COMBO_SIZE + REFRESH_SIZE,
+      EMUL_ACTIONLIST_SIZE = 175 + PNG_SIZE + COMBO_SIZE + REFRESH_SIZE,
       MENU_ACTIONLIST_SIZE = 18
     ;
 
diff --git a/src/emucore/EventHandlerConstants.hxx b/src/emucore/EventHandlerConstants.hxx
index 0009af3d3..b67df420f 100644
--- a/src/emucore/EventHandlerConstants.hxx
+++ b/src/emucore/EventHandlerConstants.hxx
@@ -79,6 +79,7 @@ static const int NUM_PORTS = 2;
 enum class EventMode {
   kEmulationMode, // active mapping used for emulation
   kMenuMode,      // mapping used for dialogs
+  kEditMode,      // mapping used in editable widgets
   kJoystickMode,  // 4 extra modes for mapping controller keys separately for emulation mode
   kPaddlesMode,
   kKeypadMode,
diff --git a/src/emucore/FBBackend.hxx b/src/emucore/FBBackend.hxx
new file mode 100644
index 000000000..ffbb5043a
--- /dev/null
+++ b/src/emucore/FBBackend.hxx
@@ -0,0 +1,207 @@
+//============================================================================
+//
+//   SSSS    tt          lll  lll
+//  SS  SS   tt           ll   ll
+//  SS     tttttt  eeee   ll   ll   aaaa
+//   SSSS    tt   ee  ee  ll   ll      aa
+//      SS   tt   eeeeee  ll   ll   aaaaa  --  "An Atari 2600 VCS Emulator"
+//  SS  SS   tt   ee      ll   ll  aa  aa
+//   SSSS     ttt  eeeee llll llll  aaaaa
+//
+// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
+// and the Stella Team
+//
+// See the file "License.txt" for information on usage and redistribution of
+// this file, and for a DISCLAIMER OF ALL WARRANTIES.
+//============================================================================
+
+#ifndef FB_BACKEND_HXX
+#define FB_BACKEND_HXX
+
+class FBSurface;
+
+#include "Rect.hxx"
+#include "Variant.hxx"
+#include "FrameBufferConstants.hxx"
+#include "VideoModeHandler.hxx"
+#include "bspf.hxx"
+
+/**
+  This class provides an interface/abstraction for platform-specific,
+  framebuffer-related rendering operations.  Different graphical
+  platforms will inherit from this.  For most ports that means SDL2,
+  but some (such as libretro) use their own graphical subsystem.
+
+  @author  Stephen Anthony
+*/
+class FBBackend
+{
+  friend class FrameBuffer;
+
+  public:
+    FBBackend() = default;
+    virtual ~FBBackend() = default;
+
+  protected:
+    /**
+      This method is called to query and initialize the video hardware
+      for desktop and fullscreen resolution information.  Since several
+      monitors may be attached, we need the resolution for all of them.
+
+      @param fullscreenRes  Maximum resolution supported in fullscreen mode
+      @param windowedRes    Maximum resolution supported in windowed mode
+      @param renderers      List of renderer names (internal name -> end-user name)
+    */
+    virtual void queryHardware(vector<Common::Size>& fullscreenRes,
+                               vector<Common::Size>& windowedRes,
+                               VariantList& renderers) = 0;
+
+    /**
+      This method is called to change to the given video mode.
+
+      @param mode   The video mode to use
+      @param winIdx The display/monitor that the window last opened on
+      @param winPos The position that the window last opened at
+
+      @return  False on any errors, else true
+    */
+    virtual bool setVideoMode(const VideoModeHandler::Mode& mode,
+                              int winIdx, const Common::Point& winPos) = 0;
+
+    /**
+      Clear the framebuffer.
+    */
+    virtual void clear() = 0;
+
+    /**
+      Transform from window to renderer coordinates, x direction
+     */
+    virtual int scaleX(int x) const = 0;
+
+    /**
+      Transform from window to renderer coordinates, y direction
+     */
+    virtual int scaleY(int y) const = 0;
+
+    /**
+      Updates window title.
+
+      @param title   The title of the application / window
+    */
+    virtual void setTitle(const string& title) = 0;
+
+    /**
+      Shows or hides the cursor based on the given boolean value.
+    */
+    virtual void showCursor(bool show) = 0;
+
+    /**
+      Grabs or ungrabs the mouse based on the given boolean value.
+    */
+    virtual void grabMouse(bool grab) = 0;
+
+    /**
+      This method must be called after all drawing is done, and indicates
+      that the buffers should be pushed to the physical screen.
+    */
+    virtual void renderToScreen() = 0;
+
+    /**
+      Answers if the display is currently in fullscreen mode.
+
+      @return  Whether the display is actually in fullscreen mode
+    */
+    virtual bool fullScreen() const = 0;
+
+    /**
+      Retrieve the current display's refresh rate.
+    */
+    virtual int refreshRate() const = 0;
+
+    /**
+      This method is called to retrieve the R/G/B data from the given pixel.
+
+      @param pixel  The pixel containing R/G/B data
+      @param r      The red component of the color
+      @param g      The green component of the color
+      @param b      The blue component of the color
+    */
+    virtual void getRGB(uInt32 pixel, uInt8* r, uInt8* g, uInt8* b) const = 0;
+
+    /**
+      This method is called to map a given R/G/B triple to the screen palette.
+
+      @param r  The red component of the color.
+      @param g  The green component of the color.
+      @param b  The blue component of the color.
+    */
+    virtual uInt32 mapRGB(uInt8 r, uInt8 g, uInt8 b) const = 0;
+
+    /**
+      This method is called to get the specified ARGB data from the viewable
+      FrameBuffer area.  Note that this isn't the same as any internal
+      surfaces that may be in use; it should return the actual data as it
+      is currently seen onscreen.
+
+      @param buffer  The actual pixel data in ARGB8888 format
+      @param pitch   The pitch (in bytes) for the pixel data
+      @param rect    The bounding rectangle for the buffer
+    */
+    virtual void readPixels(uInt8* buffer, uInt32 pitch,
+                            const Common::Rect& rect) const = 0;
+
+    /**
+      This method is called to query if the current window is not
+      centered or fullscreen.
+
+      @return  True, if the current window is positioned
+    */
+    virtual bool isCurrentWindowPositioned() const = 0;
+
+    /**
+      This method is called to query the video hardware for position of
+      the current window.
+
+      @return  The position of the currently displayed window
+    */
+    virtual Common::Point getCurrentWindowPos() const = 0;
+
+    /**
+      This method is called to query the video hardware for the index
+      of the display the current window is displayed on.
+
+      @return  The current display index or a negative value if no
+               window is displayed
+    */
+    virtual Int32 getCurrentDisplayIndex() const = 0;
+
+    /**
+      This method is called to create a surface with the given attributes.
+
+      @param w      The requested width of the new surface.
+      @param h      The requested height of the new surface.
+      @param inter  Interpolation mode
+      @param data   If non-null, use the given data values as a static surface
+    */
+    virtual unique_ptr<FBSurface>
+        createSurface(
+          uInt32 w,
+          uInt32 h,
+          ScalingInterpolation inter = ScalingInterpolation::none,
+          const uInt32* data = nullptr
+    ) const = 0;
+
+    /**
+      This method is called to provide information about the backend.
+    */
+    virtual string about() const = 0;
+
+  private:
+    // Following constructors and assignment operators not supported
+    FBBackend(const FBBackend&) = delete;
+    FBBackend(FBBackend&&) = delete;
+    FBBackend& operator=(const FBBackend&) = delete;
+    FBBackend& operator=(FBBackend&&) = delete;
+};
+
+#endif
diff --git a/src/emucore/FBSurface.cxx b/src/emucore/FBSurface.cxx
index c489fc703..16030b579 100644
--- a/src/emucore/FBSurface.cxx
+++ b/src/emucore/FBSurface.cxx
@@ -296,27 +296,47 @@ void FBSurface::frameRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void FBSurface::wrapString(const string& inStr, int pos, string& leftStr, string& rightStr) const
+void FBSurface::splitString(const GUI::Font& font, const string& s, int w,
+                            string& left, string& right) const
 {
-  for(int i = pos; i > 0; --i)
+#ifdef GUI_SUPPORT
+  uInt32 pos;
+  int w2 = 0;
+  bool split = false;
+
+  // SLOW algorithm to find the acceptable length. But it is good enough for now.
+  for(pos = 0; pos < s.size(); ++pos)
   {
-    if(isWhiteSpace(inStr[i]))
+    int charWidth = font.getCharWidth(s[pos]);
+    if(w2 + charWidth > w || s[pos] == '\n')
     {
-      leftStr = inStr.substr(0, i);
-      if(inStr[i] == ' ') // skip leading space after line break
-        i++;
-      rightStr = inStr.substr(i);
-      return;
+      split = true;
+      break;
     }
+    w2 += charWidth;
   }
-  leftStr = inStr.substr(0, pos);
-  rightStr = inStr.substr(pos);
+
+  if(split)
+    for(int i = pos; i > 0; --i)
+    {
+      if(isWhiteSpace(s[i]))
+      {
+        left = s.substr(0, i);
+        if(s[i] == ' ' || s[pos] == '\n') // skip leading space after line break
+          i++;
+        right = s.substr(i);
+        return;
+      }
+    }
+  left = s.substr(0, pos);
+  right = s.substr(pos);
+#endif
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 bool FBSurface::isWhiteSpace(const char s) const
 {
-  const string WHITESPACES = " ,.;:+-";
+  const string WHITESPACES = " ,.;:+-*/\\'([\n";
 
   for(size_t i = 0; i < WHITESPACES.length(); ++i)
     if(s == WHITESPACES[i])
@@ -331,37 +351,30 @@ int FBSurface::drawString(const GUI::Font& font, const string& s,
   ColorId color, TextAlign align,
   int deltax, bool useEllipsis, ColorId shadowColor)
 {
-  int lines = 1;
+  int lines = 0;
 
 #ifdef GUI_SUPPORT
   string inStr = s;
 
   // draw multiline string
-  while (font.getStringWidth(inStr) > w && h >= font.getFontHeight() * 2)
+  //while (font.getStringWidth(inStr) > w && h >= font.getFontHeight() * 2)
+  while(inStr.length() && h >= font.getFontHeight() * 2)
   {
     // String is too wide.
-    uInt32 i;
     string leftStr, rightStr;
-    int w2 = 0;
 
-    // SLOW algorithm to find the acceptable length. But it is good enough for now.
-    for(i = 0; i < inStr.size(); ++i)
-    {
-      int charWidth = font.getCharWidth(inStr[i]);
-      if(w2 + charWidth > w)
-        break;
-
-      w2 += charWidth;
-      //str += inStr[i];
-    }
-    wrapString(inStr, i, leftStr, rightStr);
+    splitString(font, inStr, w, leftStr, rightStr);
     drawString(font, leftStr, x, y, w, color, align, deltax, false, shadowColor);
     h -= font.getFontHeight();
     y += font.getFontHeight();
     inStr = rightStr;
     lines++;
   }
-  drawString(font, inStr, x, y, w, color, align, deltax, useEllipsis, shadowColor);
+  if(inStr.length())
+  {
+    drawString(font, inStr, x, y, w, color, align, deltax, useEllipsis, shadowColor);
+    lines++;
+  }
 #endif
   return lines;
 }
diff --git a/src/emucore/FBSurface.hxx b/src/emucore/FBSurface.hxx
index 48632404d..de19fca28 100644
--- a/src/emucore/FBSurface.hxx
+++ b/src/emucore/FBSurface.hxx
@@ -177,7 +177,8 @@ class FBSurface
       @param y         The destination y-location to start drawing pixels
       @param numpixels The number of pixels to draw
     */
-    virtual void drawPixels(const uInt32* data, uInt32 x, uInt32 y, uInt32 numpixels);
+    virtual void drawPixels(const uInt32* data, uInt32 x, uInt32 y,
+                            uInt32 numpixels);
 
     /**
       This method should be called to draw a rectangular box with sides
@@ -246,6 +247,37 @@ class FBSurface
         ColorId color, TextAlign align = TextAlign::Left,
         int deltax = 0, bool useEllipsis = true, ColorId shadowColor = kNone);
 
+    /**
+      Splits a given string to a given width considering whitespaces.
+
+      @param font   The font to draw the string with
+      @param s      The string to split
+      @param w      The width of the string area
+      @param left   The left part of the split string
+      @param right  The right part of the split string
+    */
+    void splitString(const GUI::Font& font, const string& s, int w,
+                     string& left, string& right) const;
+
+    /**
+      The rendering attributes that can be modified for this texture.
+      These probably can only be implemented in child FBSurfaces where
+      the specific functionality actually exists.
+    */
+    struct Attributes {
+      bool blending{false};    // Blending is enabled
+      uInt32 blendalpha{100};  // Alpha to use in blending mode (0-100%)
+
+      bool operator==(const Attributes& other) const {
+        return blendalpha == other.blendalpha && blending == other.blending;
+      }
+    };
+
+    /**
+      Get the currently applied attributes.
+    */
+    Attributes& attributes() { return myAttributes; }
+
     //////////////////////////////////////////////////////////////////////////
     // Note:  The following methods are FBSurface-specific, and must be
     //        implemented in child classes.
@@ -272,11 +304,14 @@ class FBSurface
       These methods set the origin point and width/height for the
       specified service.  They are defined as separate x/y and w/h
       methods since these items are sometimes set separately.
+      Other times they are set together, so we can use a Rect instead.
     */
     virtual void setSrcPos(uInt32 x, uInt32 y)  = 0;
     virtual void setSrcSize(uInt32 w, uInt32 h) = 0;
+    virtual void setSrcRect(const Common::Rect& r) = 0;
     virtual void setDstPos(uInt32 x, uInt32 y)  = 0;
     virtual void setDstSize(uInt32 w, uInt32 h) = 0;
+    virtual void setDstRect(const Common::Rect& r) = 0;
 
     /**
       This method should be called to enable/disable showing the surface
@@ -303,7 +338,18 @@ class FBSurface
       This method should be called to reset the surface to empty
       pixels / colour black.
     */
-    virtual void invalidate() = 0;
+    virtual void invalidate() {}
+
+    /**
+      This method should be called to reset a surface area to empty
+
+      @param x      The x coordinate
+      @param y      The y coordinate
+      @param w      The width of the area
+      @param h      The height of the area
+    */
+    virtual void invalidateRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h) = 0;
+
 
     /**
       This method should be called to free any resources being used by
@@ -324,35 +370,17 @@ class FBSurface
     */
     virtual void resize(uInt32 width, uInt32 height) = 0;
 
-    /**
-      The rendering attributes that can be modified for this texture.
-      These probably can only be implemented in child FBSurfaces where
-      the specific functionality actually exists.
-    */
-    struct Attributes {
-      bool blending{false};    // Blending is enabled
-      uInt32 blendalpha{100};  // Alpha to use in blending mode (0-100%)
-
-      bool operator==(const Attributes& other) const {
-        return blendalpha == other.blendalpha && blending == other.blending;
-      }
-    };
-
-    /**
-      Get the currently applied attributes.
-    */
-    Attributes& attributes() { return myAttributes; }
-
     /**
       Configure scaling interpolation.
      */
-    virtual void setScalingInterpolation(FrameBuffer::ScalingInterpolation) = 0;
+    virtual void setScalingInterpolation(ScalingInterpolation) = 0;
 
     /**
       The child class chooses which (if any) of the actual attributes
       can be applied.
     */
     virtual void applyAttributes() = 0;
+    //////////////////////////////////////////////////////////////////////////
 
     static void setPalette(const FullPaletteArray& palette) { myPalette = palette; }
 
@@ -367,8 +395,6 @@ class FBSurface
     */
     bool checkBounds(const uInt32 x, const uInt32 y) const;
 
-    void wrapString(const string& inStr, int pos, string& leftStr, string& rightStr) const;
-
     /**
       Check if the given character is a whitespace.
       @param s      Character to check
diff --git a/src/emucore/FSNode.cxx b/src/emucore/FSNode.cxx
index f2e5e477a..6ff0b6482 100644
--- a/src/emucore/FSNode.cxx
+++ b/src/emucore/FSNode.cxx
@@ -76,10 +76,64 @@ bool FilesystemNode::exists() const
   return _realNode ? _realNode->exists() : false;
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool FilesystemNode::getAllChildren(FSList& fslist, ListMode mode,
+                                    const NameFilter& filter,
+                                    bool includeParentDirectory,
+                                    const CancelCheck& isCancelled) const
+{
+  if(getChildren(fslist, mode, filter, includeParentDirectory, true, isCancelled))
+  {
+    // Sort only once at the end
+  #if defined(ZIP_SUPPORT)
+    // before sorting, replace single file ZIP archive names with contained file names
+    //  because they are displayed using their contained file names
+    for(auto& i : fslist)
+    {
+      if(BSPF::endsWithIgnoreCase(i.getPath(), ".zip"))
+      {
+        FilesystemNodeZIP zipNode(i.getPath());
+
+        i.setName(zipNode.getName());
+      }
+    }
+  #endif
+
+    std::sort(fslist.begin(), fslist.end(),
+              [](const FilesystemNode& node1, const FilesystemNode& node2)
+    {
+      if(node1.isDirectory() != node2.isDirectory())
+        return node1.isDirectory();
+      else
+        return BSPF::compareIgnoreCase(node1.getName(), node2.getName()) < 0;
+    }
+    );
+
+  #if defined(ZIP_SUPPORT)
+    // After sorting replace zip files with zip nodes
+    for(auto& i : fslist)
+    {
+      if(BSPF::endsWithIgnoreCase(i.getPath(), ".zip"))
+      {
+        // Force ZIP c'tor to be called
+        AbstractFSNodePtr ptr = FilesystemNodeFactory::create(i.getPath(),
+                                                              FilesystemNodeFactory::Type::ZIP);
+        FilesystemNode zipNode(ptr);
+        i = zipNode;
+      }
+    }
+  #endif
+    return true;
+  }
+  return false;
+}
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 bool FilesystemNode::getChildren(FSList& fslist, ListMode mode,
                                  const NameFilter& filter,
-                                 bool includeParentDirectory) const
+                                 bool includeChildDirectories,
+                                 bool includeParentDirectory,
+                                 const CancelCheck& isCancelled) const
 {
   if (!_realNode || !_realNode->isDirectory())
     return false;
@@ -90,12 +144,18 @@ bool FilesystemNode::getChildren(FSList& fslist, ListMode mode,
   if (!_realNode->getChildren(tmp, mode))
     return false;
 
+  // when incuding child directories, everything must be sorted once at the end
+  if(!includeChildDirectories)
+  {
+    if(isCancelled())
+      return false;
+
   #if defined(ZIP_SUPPORT)
     // before sorting, replace single file ZIP archive names with contained file names
     //  because they are displayed using their contained file names
-    for (auto& i : tmp)
+    for(auto& i : tmp)
     {
-      if (BSPF::endsWithIgnoreCase(i->getPath(), ".zip"))
+      if(BSPF::endsWithIgnoreCase(i->getPath(), ".zip"))
       {
         FilesystemNodeZIP node(i->getPath());
 
@@ -104,15 +164,16 @@ bool FilesystemNode::getChildren(FSList& fslist, ListMode mode,
     }
   #endif
 
-  std::sort(tmp.begin(), tmp.end(),
-    [](const AbstractFSNodePtr& node1, const AbstractFSNodePtr& node2)
+    std::sort(tmp.begin(), tmp.end(),
+              [](const AbstractFSNodePtr& node1, const AbstractFSNodePtr& node2)
     {
-      if (node1->isDirectory() != node2->isDirectory())
+      if(node1->isDirectory() != node2->isDirectory())
         return node1->isDirectory();
       else
         return BSPF::compareIgnoreCase(node1->getName(), node2->getName()) < 0;
     }
-  );
+    );
+  }
 
   // Add parent node, if it is valid to do so
   if (includeParentDirectory && hasParent())
@@ -125,29 +186,54 @@ bool FilesystemNode::getChildren(FSList& fslist, ListMode mode,
   // And now add the rest of the entries
   for (const auto& i: tmp)
   {
+    if(isCancelled())
+      return false;
+
   #if defined(ZIP_SUPPORT)
     if (BSPF::endsWithIgnoreCase(i->getPath(), ".zip"))
     {
       // Force ZIP c'tor to be called
       AbstractFSNodePtr ptr = FilesystemNodeFactory::create(i->getPath(),
-          FilesystemNodeFactory::Type::ZIP);
-      FilesystemNode node(ptr);
-      if (filter(node))
-        fslist.emplace_back(node);
+                                                            FilesystemNodeFactory::Type::ZIP);
+      FilesystemNode zipNode(ptr);
+
+      if(filter(zipNode))
+      {
+        if(!includeChildDirectories)
+          fslist.emplace_back(zipNode);
+        else
+        {
+          // filter by zip node but add file node
+          FilesystemNode node(i);
+          fslist.emplace_back(node);
+        }
+      }
     }
     else
   #endif
     {
       // Make directories stand out
-      if (i->isDirectory())
+      if(i->isDirectory())
         i->setName(" [" + i->getName() + "]");
 
       FilesystemNode node(i);
-      if (filter(node))
-        fslist.emplace_back(node);
+
+      if(includeChildDirectories)
+      {
+        if(i->isDirectory())
+          node.getChildren(fslist, mode, filter, includeChildDirectories, false, isCancelled);
+        else
+          // do not add directories in this mode
+          if(filter(node))
+            fslist.emplace_back(node);
+      }
+      else
+      {
+        if(filter(node))
+          fslist.emplace_back(node);
+      }
     }
   }
-
   return true;
 }
 
diff --git a/src/emucore/FSNode.hxx b/src/emucore/FSNode.hxx
index cf76f9ac1..05378d185 100644
--- a/src/emucore/FSNode.hxx
+++ b/src/emucore/FSNode.hxx
@@ -57,6 +57,7 @@ class FilesystemNode
     /** Function used to filter the file listing.  Returns true if the filename
         should be included, else false.*/
     using NameFilter = std::function<bool(const FilesystemNode& node)>;
+    using CancelCheck = std::function<bool()> const;
 
     /**
      * Create a new pathless FilesystemNode. Since there's no path associated
@@ -114,6 +115,18 @@ class FilesystemNode
      */
     bool exists() const;
 
+    /**
+     * Return a list of child nodes of this and all sub-directories. If called on a node
+     * that does not represent a directory, false is returned.
+     *
+     * @return true if successful, false otherwise (e.g. when the directory
+     *         does not exist).
+     */
+    bool getAllChildren(FSList& fslist, ListMode mode = ListMode::DirectoriesOnly,
+                        const NameFilter& filter = [](const FilesystemNode&) { return true; },
+                        bool includeParentDirectory = true,
+                        const CancelCheck& isCancelled = []() { return false; }) const;
+
     /**
      * Return a list of child nodes of this directory node. If called on a node
      * that does not represent a directory, false is returned.
@@ -123,7 +136,9 @@ class FilesystemNode
      */
     bool getChildren(FSList& fslist, ListMode mode = ListMode::DirectoriesOnly,
                      const NameFilter& filter = [](const FilesystemNode&){ return true; },
-                     bool includeParentDirectory = true) const;
+                     bool includeChildDirectories = false,
+                     bool includeParentDirectory = true,
+                     const CancelCheck& isCancelled = []() { return false; }) const;
 
     /**
      * Set/get a string representation of the name of the file. This is can be
@@ -273,8 +288,8 @@ class FilesystemNode
     string getPathWithExt(const string& ext) const;
 
   private:
-    AbstractFSNodePtr _realNode;
     explicit FilesystemNode(const AbstractFSNodePtr& realNode);
+    AbstractFSNodePtr _realNode;
     void setPath(const string& path);
 };
 
diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx
index 80b1d67e1..2171382c5 100644
--- a/src/emucore/FrameBuffer.cxx
+++ b/src/emucore/FrameBuffer.cxx
@@ -25,6 +25,7 @@
 #include "Settings.hxx"
 #include "TIA.hxx"
 #include "Sound.hxx"
+#include "MediaFactory.hxx"
 
 #include "FBSurface.hxx"
 #include "TIASurface.hxx"
@@ -63,14 +64,24 @@ FrameBuffer::FrameBuffer(OSystem& osystem)
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 FrameBuffer::~FrameBuffer()
 {
+  // Make sure to free surfaces/textures before destroying the backend itself
+  // Most platforms are fine with doing this in either order, but it seems
+  // that OpenBSD in particular crashes when attempting to destroy textures
+  // *after* the renderer is already destroyed
+  freeSurfaces();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-bool FrameBuffer::initialize()
+void FrameBuffer::initialize()
 {
+  // First create the platform-specific backend; it is needed before anything
+  // else can be used
+  try { myBackend = MediaFactory::createVideoBackend(myOSystem); }
+  catch(const runtime_error& e) { throw e; }
+
   // Get desktop resolution and supported renderers
   vector<Common::Size> windowedDisplays;
-  queryHardware(myFullscreenDisplays, windowedDisplays, myRenderers);
+  myBackend->queryHardware(myFullscreenDisplays, windowedDisplays, myRenderers);
   uInt32 query_w = windowedDisplays[0].w, query_h = windowedDisplays[0].h;
 
   // Check the 'maxres' setting, which is an undocumented developer feature
@@ -104,9 +115,11 @@ bool FrameBuffer::initialize()
 #endif
 
   // Determine possible TIA windowed zoom levels
-  myTIAMaxZoom = maxZoomForScreen(
-      TIAConstants::viewableWidth, TIAConstants::viewableHeight,
-      myAbsDesktopSize.w, myAbsDesktopSize.h);
+  myTIAMaxZoom = maxWindowZoom(TIAConstants::viewableWidth,
+                               TIAConstants::viewableHeight);
+  float currentTIAZoom = myOSystem.settings().getFloat("tia.zoom");
+  myOSystem.settings().setValue("tia.zoom",
+      BSPF::clampw(currentTIAZoom, supportedTIAMinZoom(), myTIAMaxZoom));
 
   setUIPalette();
 
@@ -114,8 +127,6 @@ bool FrameBuffer::initialize()
 
   // Create a TIA surface; we need it for rendering TIA images
   myTIASurface = make_unique<TIASurface>(myOSystem);
-
-  return true;
 }
 
 #ifdef GUI_SUPPORT
@@ -173,13 +184,13 @@ void FrameBuffer::setupFonts()
     //  However, we have to make sure all Dialogs are sized using the fontsize.
     int zoom_h = (fd.height * 4 * 2) / GUI::stellaMediumDesc.height;
     int zoom_w = (fd.maxwidth * 4 * 2) / GUI::stellaMediumDesc.maxwidth;
-    myTIAMinZoom = std::max(std::max(zoom_w, zoom_h) / 4.F, 2.F); // round to 25% steps, >= 200%
+    // round to 25% steps, >= 200%
+    myTIAMinZoom = std::max(std::max(zoom_w, zoom_h) / 4.F, 2.F);
   }
 
   // The font used by the ROM launcher
   const string& lf = myOSystem.settings().getString("launcherfont");
 
-
   myLauncherFont = make_unique<GUI::Font>(getFontDesc(lf));       //  8x13
 }
 
@@ -187,7 +198,7 @@ void FrameBuffer::setupFonts()
 FontDesc FrameBuffer::getFontDesc(const string& name) const
 {
   if(name == "small")
-    return GUI::consoleBDesc;       //  8x13
+    return GUI::consoleDesc;        //  8x13
   else if(name == "low_medium")
     return GUI::consoleMediumBDesc; //  9x15
   else if(name == "medium")
@@ -205,21 +216,16 @@ FontDesc FrameBuffer::getFontDesc(const string& name) const
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 FBInitStatus FrameBuffer::createDisplay(const string& title, BufferType type,
-                                        uInt32 width, uInt32 height,
-                                        bool honourHiDPI)
+                                        Common::Size size, bool honourHiDPI)
 {
-  // always save, maybe only the mode of the window has changed
-  saveCurrentWindowPosition();
-  myBufferType = type;
-
   ++myInitializedCount;
-  myScreenTitle = title;
+  myBackend->setTitle(title);
 
-  // In HiDPI mode, all created displays must be scaled by 2x
+  // In HiDPI mode, all created displays must be scaled appropriately
   if(honourHiDPI && hidpiEnabled())
   {
-    width  *= hidpiScaleFactor();
-    height *= hidpiScaleFactor();
+    size.w *= hidpiScaleFactor();
+    size.h *= hidpiScaleFactor();
   }
 
   // A 'windowed' system is defined as one where the window size can be
@@ -232,69 +238,39 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, BufferType type,
   // If the WINDOWED_SUPPORT macro is defined, we treat the system as the
   // former type; if not, as the latter type
 
-  bool useFullscreen = false;
 #ifdef WINDOWED_SUPPORT
   // We assume that a desktop of at least minimum acceptable size means that
   // we're running on a 'large' system, and the window size requirements
   // can be relaxed
   // Otherwise, we treat the system as if WINDOWED_SUPPORT is not defined
   if(myDesktopSize.w < FBMinimum::Width && myDesktopSize.h < FBMinimum::Height &&
-    (myDesktopSize.w < width || myDesktopSize.h < height))
+     size > myDesktopSize)
     return FBInitStatus::FailTooLarge;
-
-  useFullscreen = myOSystem.settings().getBool("fullscreen");
 #else
   // Make sure this mode is even possible
   // We only really need to worry about it in non-windowed environments,
   // where requesting a window that's too large will probably cause a crash
-  if(myDesktopSize.w < width || myDesktopSize.h < height)
+  if(size > myDesktopSize)
     return FBInitStatus::FailTooLarge;
-
-  useFullscreen = true;
 #endif
 
-  // Set the available video modes for this framebuffer
-  setAvailableVidModes(width, height);
+  // Initialize video mode handler, so it can know what video modes are
+  // appropriate for the requested image size
+  myVidModeHandler.setImageSize(size);
 
-  // Initialize video subsystem (make sure we get a valid mode)
-  string pre_about = about();
-  const FrameBuffer::VideoMode& mode = getSavedVidMode(useFullscreen);
-  if(width <= mode.screen.w && height <= mode.screen.h)
-  {
-    // Changing the video mode can take some time, during which the last
-    // sound played may get 'stuck'
-    // So we mute the sound until the operation completes
-    bool oldMuteState = myOSystem.sound().mute(true);
-    if(setVideoMode(myScreenTitle, mode))
-    {
-      myImageRect = mode.image;
-      myScreenSize = mode.screen;
-      myScreenRect = Common::Rect(mode.screen);
+  // Always save, maybe only the mode of the window has changed
+  saveCurrentWindowPosition();
+  myBufferType = type;
 
-      // Inform TIA surface about new mode
-      if(myOSystem.eventHandler().state() != EventHandlerState::LAUNCHER &&
-         myOSystem.eventHandler().state() != EventHandlerState::DEBUGGER)
-        myTIASurface->initialize(myOSystem.console(), mode);
-
-      // Did we get the requested fullscreen state?
-      myOSystem.settings().setValue("fullscreen", fullScreen());
-      resetSurfaces();
-      setCursorState();
-
-      myOSystem.sound().mute(oldMuteState);
-    }
-    else
-    {
-      Logger::error("ERROR: Couldn't initialize video subsystem");
-      return FBInitStatus::FailNotSupported;
-    }
-  }
-  else
-    return FBInitStatus::FailTooLarge;
+  // Initialize video subsystem
+  string pre_about = myBackend->about();
+  FBInitStatus status = applyVideoMode();
+  if(status != FBInitStatus::Success)
+    return status;
 
 #ifdef GUI_SUPPORT
   // Erase any messages from a previous run
-  myMsg.counter = 0;
+  myMsg.enabled = false;
 
   // Create surfaces for TIA statistics and general messages
   const GUI::Font& f = hidpiEnabled() ? infoFont() : font();
@@ -322,20 +298,20 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, BufferType type,
   // Print initial usage message, but only print it later if the status has changed
   if(myInitializedCount == 1)
   {
-    Logger::info(about());
+    Logger::info(myBackend->about());
   }
   else
   {
-    string post_about = about();
+    string post_about = myBackend->about();
     if(post_about != pre_about)
       Logger::info(post_about);
   }
 
-  return FBInitStatus::Success;
+  return status;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void FrameBuffer::update(bool force)
+void FrameBuffer::update(UpdateMode mode)
 {
   // Onscreen messages are a special case and require different handling than
   // other objects; they aren't UI dialogs in the normal sense nor are they
@@ -346,13 +322,14 @@ void FrameBuffer::update(bool force)
   //  - at the bottom of ::update(), to actually draw them (this must come
   //    last, since they are always drawn on top of everything else).
 
-  // Full rendering is required when messages are enabled
-  force = force || myMsg.counter >= 0;
+  bool forceRedraw = mode & UpdateMode::REDRAW;
+  bool redraw = forceRedraw;
 
-  // Detect when a message has been turned off; one last redraw is required
-  // in this case, to draw over the area that the message occupied
-  if(myMsg.counter == 0)
-    myMsg.counter = -1;
+  // Forced render without draw required if messages or dialogs were closed
+  // Note: For dialogs only relevant when two or more dialogs were stacked
+  bool rerender = (mode & (UpdateMode::REDRAW | UpdateMode::RERENDER))
+    || myPendingRender;
+  myPendingRender = false;
 
   switch(myOSystem.eventHandler().state())
   {
@@ -367,59 +344,69 @@ void FrameBuffer::update(bool force)
       if(myPausedCount-- <= 0)
       {
         myPausedCount = uInt32(7 * myOSystem.frameRate());
-        showMessage("Paused", MessagePosition::MiddleCenter);
-      }
-      if(force)
+        showTextMessage("Paused", MessagePosition::MiddleCenter);
+        myTIASurface->render();
+      }
+      if(rerender)
         myTIASurface->render();
-
       break;  // EventHandlerState::PAUSE
     }
 
   #ifdef GUI_SUPPORT
     case EventHandlerState::OPTIONSMENU:
     {
-      force = force || myOSystem.menu().needsRedraw();
-      if(force)
+      myOSystem.menu().tick();
+      redraw |= myOSystem.menu().needsRedraw();
+      if(redraw)
       {
         clear();
         myTIASurface->render();
-        myOSystem.menu().draw(force);
+        myOSystem.menu().draw(forceRedraw);
+      }
+      else if(rerender)
+      {
+        clear();
+        myTIASurface->render();
+        myOSystem.menu().render();
       }
       break;  // EventHandlerState::OPTIONSMENU
     }
 
     case EventHandlerState::CMDMENU:
     {
-      force = force || myOSystem.commandMenu().needsRedraw();
-      if(force)
+      myOSystem.commandMenu().tick();
+      redraw |= myOSystem.commandMenu().needsRedraw();
+      if(redraw)
       {
         clear();
         myTIASurface->render();
-        myOSystem.commandMenu().draw(force);
+        myOSystem.commandMenu().draw(forceRedraw);
       }
       break;  // EventHandlerState::CMDMENU
     }
 
     case EventHandlerState::MESSAGEMENU:
     {
-      force = force || myOSystem.messageMenu().needsRedraw();
-      if (force)
+      myOSystem.messageMenu().tick();
+      redraw |= myOSystem.messageMenu().needsRedraw();
+      if(redraw)
       {
         clear();
         myTIASurface->render();
-        myOSystem.messageMenu().draw(force);
+        myOSystem.messageMenu().draw(forceRedraw);
       }
       break;  // EventHandlerState::MESSAGEMENU
     }
 
     case EventHandlerState::TIMEMACHINE:
     {
-      force = force || myOSystem.timeMachine().needsRedraw();
-      if(force)
+      myOSystem.timeMachine().tick();
+      redraw |= myOSystem.timeMachine().needsRedraw();
+      if(redraw)
       {
         clear();
         myTIASurface->render();
-        myOSystem.timeMachine().draw(force);
+        myOSystem.timeMachine().draw(forceRedraw);
       }
       break;  // EventHandlerState::TIMEMACHINE
     }
@@ -444,32 +431,28 @@ void FrameBuffer::update(bool force)
           r.rewindStates(1);
       }
 
-      force = force || success;
-      if (force)
+      redraw |= success;
+      if(redraw)
         myTIASurface->render();
 
       // Stop playback mode at the end of the state buffer
       // and switch to Time Machine or Pause mode
-      if (!success)
+      if(!success)
       {
         frames = 0;
-      #ifdef GUI_SUPPORT
         myOSystem.eventHandler().enterMenuMode(EventHandlerState::TIMEMACHINE);
-      #else
-        myOSystem.eventHandler().changeStateByEvent(Event::TogglePauseMode);
-      #endif
       }
       break;  // EventHandlerState::PLAYBACK
     }
 
     case EventHandlerState::LAUNCHER:
     {
-      force = force || myOSystem.launcher().needsRedraw();
-      if(force)
-      {
-        clear();
-        myOSystem.launcher().draw(force);
-      }
+      myOSystem.launcher().tick();
+      redraw |= myOSystem.launcher().needsRedraw();
+      if(redraw)
+        myOSystem.launcher().draw(forceRedraw);
+      else if(rerender)
+        myOSystem.launcher().render();
       break;  // EventHandlerState::LAUNCHER
     }
   #endif
@@ -477,12 +460,12 @@ void FrameBuffer::update(bool force)
   #ifdef DEBUGGER_SUPPORT
     case EventHandlerState::DEBUGGER:
     {
-      force = force || myOSystem.debugger().needsRedraw();
-      if(force)
-      {
-        clear();
-        myOSystem.debugger().draw(force);
-      }
+      myOSystem.debugger().tick();
+      redraw |= myOSystem.debugger().needsRedraw();
+      if(redraw)
+        myOSystem.debugger().draw(forceRedraw);
+      else if(rerender)
+        myOSystem.debugger().render();
       break;  // EventHandlerState::DEBUGGER
     }
   #endif
@@ -496,11 +479,11 @@ void FrameBuffer::update(bool force)
   // indicates that, and then the code at the top of this method sees
   // the change and redraws everything
   if(myMsg.enabled)
-    drawMessage();
+    redraw |= drawMessage();
 
   // Push buffers to screen only when necessary
-  if(force)
-    renderToScreen();
+  if(redraw || rerender)
+    myBackend->renderToScreen();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -526,22 +509,18 @@ void FrameBuffer::updateInEmulationMode(float framesPerSecond)
     drawMessage();
 
   // Push buffers to screen
-  renderToScreen();
+  myBackend->renderToScreen();
 }
 
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void FrameBuffer::showMessage(const string& message, MessagePosition position,
-                              bool force)
-{
 #ifdef GUI_SUPPORT
+void FrameBuffer::createMessage(const string& message, MessagePosition position, bool force)
+{
   // Only show messages if they've been enabled
   if(myMsg.surface == nullptr || !(force || myOSystem.settings().getBool("uimessages")))
     return;
 
-  const int fontWidth  = font().getMaxCharWidth(),
-            fontHeight = font().getFontHeight();
+  const int fontHeight = font().getFontHeight();
   const int VBORDER = fontHeight / 4;
-  const int HBORDER = fontWidth * 1.25 / 2.0;
 
   myMsg.counter = uInt32(myOSystem.frameRate()) * 2; // Show message for 2 seconds
   if(myMsg.counter == 0)
@@ -550,39 +529,40 @@ void FrameBuffer::showMessage(const string& message, MessagePosition position,
   // Precompute the message coordinates
   myMsg.text      = message;
   myMsg.color     = kBtnTextColor;
-  myMsg.showGauge = false;
-  myMsg.w         = std::min(fontWidth * (MESSAGE_WIDTH) - HBORDER * 2,
-                             font().getStringWidth(myMsg.text) + HBORDER * 2);
   myMsg.h         = fontHeight + VBORDER * 2;
   myMsg.position  = position;
   myMsg.enabled   = true;
+  myMsg.dirty     = true;
 
   myMsg.surface->setSrcSize(myMsg.w, myMsg.h);
   myMsg.surface->setDstSize(myMsg.w * hidpiScaleFactor(), myMsg.h * hidpiScaleFactor());
+}
+#endif
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void FrameBuffer::showTextMessage(const string& message, MessagePosition position,
+                                  bool force)
+{
+#ifdef GUI_SUPPORT
+  const int fontWidth = font().getMaxCharWidth();
+  const int HBORDER = fontWidth * 1.25 / 2.0;
+
+  myMsg.showGauge = false;
+  myMsg.w         = std::min(fontWidth * (MESSAGE_WIDTH) - HBORDER * 2,
+                             font().getStringWidth(message) + HBORDER * 2);
+
+  createMessage(message, position, force);
 #endif
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void FrameBuffer::showMessage(const string& message, const string& valueText,
-                              float value, float minValue, float maxValue)
+void FrameBuffer::showGaugeMessage(const string& message, const string& valueText,
+                                   float value, float minValue, float maxValue)
 {
 #ifdef GUI_SUPPORT
-  // Only show messages if they've been enabled
-  if(myMsg.surface == nullptr || !myOSystem.settings().getBool("uimessages"))
-    return;
-
-  const int fontWidth  = font().getMaxCharWidth(),
-            fontHeight = font().getFontHeight();
-  const int VBORDER = fontHeight / 4;
+  const int fontWidth = font().getMaxCharWidth();
   const int HBORDER = fontWidth * 1.25 / 2.0;
 
-  myMsg.counter = uInt32(myOSystem.frameRate()) * 2; // Show message for 2 seconds
-  if(myMsg.counter == 0)
-    myMsg.counter = 120;
-
-  // Precompute the message coordinates
-  myMsg.text       = message;
-  myMsg.color      = kBtnTextColor;
   myMsg.showGauge  = true;
   if(maxValue - minValue != 0)
     myMsg.value = (value - minValue) / (maxValue - minValue) * 100.F;
@@ -590,16 +570,12 @@ void FrameBuffer::showMessage(const string& message, const string& valueText,
     myMsg.value = 100.F;
   myMsg.valueText  = valueText;
   myMsg.w          = std::min(fontWidth * MESSAGE_WIDTH,
-                              font().getStringWidth(myMsg.text)
+                              font().getStringWidth(message)
                               + fontWidth * (GAUGEBAR_WIDTH + 2)
-                              + font().getStringWidth(myMsg.valueText))
-    + HBORDER * 2;
-  myMsg.h          = fontHeight + VBORDER * 2;
-  myMsg.position   = MessagePosition::BottomCenter;
-  myMsg.enabled    = true;
+                              + font().getStringWidth(valueText))
+                              + HBORDER * 2;
 
-  myMsg.surface->setSrcSize(myMsg.w, myMsg.h);
-  myMsg.surface->setDstSize(myMsg.w * hidpiScaleFactor(), myMsg.h * hidpiScaleFactor());
+  createMessage(message, MessagePosition::BottomCenter);
 #endif
 }
 
@@ -633,7 +609,8 @@ void FrameBuffer::drawFrameStats(float framesPerSecond)
   ss
     << myOSystem.console().tia().frameBufferScanlinesLastFrame()
     << " / "
-    << std::fixed << std::setprecision(1) << myOSystem.console().getFramerate()
+    << std::fixed << std::setprecision(1)
+    << myOSystem.console().currentFrameRate()
     << "Hz => "
     << info.DisplayFormat;
 
@@ -664,7 +641,7 @@ void FrameBuffer::drawFrameStats(float framesPerSecond)
   myStatsMsg.surface->drawString(f, ss.str(), xPos, yPos,
       myStatsMsg.w, myStatsMsg.color, TextAlign::Left, 0, true, kBGColor);
 
-  myStatsMsg.surface->setDstPos(myImageRect.x() + 10, myImageRect.y() + 8);
+  myStatsMsg.surface->setDstPos(imageRect().x() + 10, imageRect().y() + 8);
   myStatsMsg.surface->setDstSize(myStatsMsg.w * hidpiScaleFactor(),
                                  myStatsMsg.h * hidpiScaleFactor());
   myStatsMsg.surface->render();
@@ -679,8 +656,8 @@ void FrameBuffer::toggleFrameStats(bool toggle)
   myOSystem.settings().setValue(
     myOSystem.settings().getBool("dev.settings") ? "dev.stats" : "plr.stats", myStatsEnabled);
 
-  myOSystem.frameBuffer().showMessage(string("Console info ") +
-                                      (myStatsEnabled ? "enabled" : "disabled"));
+  myOSystem.frameBuffer().showTextMessage(string("Console info ") +
+                                          (myStatsEnabled ? "enabled" : "disabled"));
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -703,12 +680,19 @@ void FrameBuffer::enableMessages(bool enable)
     myStatsMsg.enabled = false;
 
     // Erase old messages on the screen
-    myMsg.enabled = false;
-    myMsg.counter = 0;
-    update(true);  // Force update immediately
+    hideMessage();
+
+    update();  // update immediately
   }
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void FrameBuffer::hideMessage()
+{
+  myPendingRender = myMsg.enabled;
+  myMsg.enabled = false;
+}
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 inline bool FrameBuffer::drawMessage()
 {
@@ -717,115 +701,120 @@ inline bool FrameBuffer::drawMessage()
   // or show again this frame
   if(myMsg.counter == 0)
   {
-    myMsg.enabled = false;
-    return true;
-  }
-  else if(myMsg.counter < 0)
-  {
-    myMsg.enabled = false;
+    hideMessage();
     return false;
   }
 
-  // Draw the bounded box and text
-  const Common::Rect& dst = myMsg.surface->dstRect();
-  const int fontWidth  = font().getMaxCharWidth(),
-            fontHeight = font().getFontHeight();
-  const int VBORDER = fontHeight / 4;
-  const int HBORDER = fontWidth * 1.25 / 2.0;
-  constexpr int BORDER = 1;
-
-  switch(myMsg.position)
+  if(myMsg.dirty)
   {
-    case MessagePosition::TopLeft:
-      myMsg.x = 5;
-      myMsg.y = 5;
-      break;
+    cerr << "m";
+    //cerr << "--- draw message ---" << endl;
 
-    case MessagePosition::TopCenter:
-      myMsg.x = (myImageRect.w() - dst.w()) >> 1;
-      myMsg.y = 5;
-      break;
+    // Draw the bounded box and text
+    const Common::Rect& dst = myMsg.surface->dstRect();
+    const int fontWidth = font().getMaxCharWidth(),
+      fontHeight = font().getFontHeight();
+    const int VBORDER = fontHeight / 4;
+    const int HBORDER = fontWidth * 1.25 / 2.0;
+    constexpr int BORDER = 1;
 
-    case MessagePosition::TopRight:
-      myMsg.x = myImageRect.w() - dst.w() - 5;
-      myMsg.y = 5;
-      break;
-
-    case MessagePosition::MiddleLeft:
-      myMsg.x = 5;
-      myMsg.y = (myImageRect.h() - dst.h()) >> 1;
-      break;
-
-    case MessagePosition::MiddleCenter:
-      myMsg.x = (myImageRect.w() - dst.w()) >> 1;
-      myMsg.y = (myImageRect.h() - dst.h()) >> 1;
-      break;
-
-    case MessagePosition::MiddleRight:
-      myMsg.x = myImageRect.w() - dst.w() - 5;
-      myMsg.y = (myImageRect.h() - dst.h()) >> 1;
-      break;
-
-    case MessagePosition::BottomLeft:
-      myMsg.x = 5;
-      myMsg.y = myImageRect.h() - dst.h() - 5;
-      break;
-
-    case MessagePosition::BottomCenter:
-      myMsg.x = (myImageRect.w() - dst.w()) >> 1;
-      myMsg.y = myImageRect.h() - dst.h() - 5;
-      break;
-
-    case MessagePosition::BottomRight:
-      myMsg.x = myImageRect.w() - dst.w() - 5;
-      myMsg.y = myImageRect.h() - dst.h() - 5;
-      break;
-  }
-
-  myMsg.surface->setDstPos(myMsg.x + myImageRect.x(), myMsg.y + myImageRect.y());
-  myMsg.surface->fillRect(0, 0, myMsg.w, myMsg.h, kColor);
-  myMsg.surface->fillRect(BORDER, BORDER, myMsg.w - BORDER * 2, myMsg.h - BORDER * 2, kBtnColor);
-  myMsg.surface->drawString(font(), myMsg.text, HBORDER, VBORDER,
-                            myMsg.w, myMsg.color);
-
-  if(myMsg.showGauge)
-  {
-    constexpr int NUM_TICKMARKS = 4;
-    // limit gauge bar width if texts are too long
-    const int swidth = std::min(fontWidth * GAUGEBAR_WIDTH,
-                                fontWidth * (MESSAGE_WIDTH - 2)
-                                - font().getStringWidth(myMsg.text)
-                                - font().getStringWidth(myMsg.valueText));
-    const int bwidth = swidth * myMsg.value / 100.F;
-    const int bheight = fontHeight >> 1;
-    const int x = HBORDER + font().getStringWidth(myMsg.text) + fontWidth;
-    // align bar with bottom of text
-    const int y = VBORDER + font().desc().ascent - bheight;
-
-    // draw gauge bar
-    myMsg.surface->fillRect(x - BORDER, y, swidth + BORDER * 2, bheight, kSliderBGColor);
-    myMsg.surface->fillRect(x, y + BORDER, bwidth, bheight - BORDER * 2, kSliderColor);
-    // draw tickmark in the middle of the bar
-    for(int i = 1; i < NUM_TICKMARKS; ++i)
+    switch(myMsg.position)
     {
-      ColorId color;
-      int xt = x + swidth * i / NUM_TICKMARKS;
-      if(bwidth < xt - x)
-        color = kCheckColor; // kSliderColor;
-      else
-        color = kSliderBGColor;
-      myMsg.surface->vLine(xt, y + bheight / 2, y + bheight - 1, color);
+      case MessagePosition::TopLeft:
+        myMsg.x = 5;
+        myMsg.y = 5;
+        break;
+
+      case MessagePosition::TopCenter:
+        myMsg.x = (imageRect().w() - dst.w()) >> 1;
+        myMsg.y = 5;
+        break;
+
+      case MessagePosition::TopRight:
+        myMsg.x = imageRect().w() - dst.w() - 5;
+        myMsg.y = 5;
+        break;
+
+      case MessagePosition::MiddleLeft:
+        myMsg.x = 5;
+        myMsg.y = (imageRect().h() - dst.h()) >> 1;
+        break;
+
+      case MessagePosition::MiddleCenter:
+        myMsg.x = (imageRect().w() - dst.w()) >> 1;
+        myMsg.y = (imageRect().h() - dst.h()) >> 1;
+        break;
+
+      case MessagePosition::MiddleRight:
+        myMsg.x = imageRect().w() - dst.w() - 5;
+        myMsg.y = (imageRect().h() - dst.h()) >> 1;
+        break;
+
+      case MessagePosition::BottomLeft:
+        myMsg.x = 5;
+        myMsg.y = imageRect().h() - dst.h() - 5;
+        break;
+
+      case MessagePosition::BottomCenter:
+        myMsg.x = (imageRect().w() - dst.w()) >> 1;
+        myMsg.y = imageRect().h() - dst.h() - 5;
+        break;
+
+      case MessagePosition::BottomRight:
+        myMsg.x = imageRect().w() - dst.w() - 5;
+        myMsg.y = imageRect().h() - dst.h() - 5;
+        break;
     }
-    // draw value text
-    myMsg.surface->drawString(font(), myMsg.valueText,
-                              x + swidth + fontWidth, VBORDER,
+
+    myMsg.surface->setDstPos(myMsg.x + imageRect().x(), myMsg.y + imageRect().y());
+    myMsg.surface->fillRect(0, 0, myMsg.w, myMsg.h, kColor);
+    myMsg.surface->fillRect(BORDER, BORDER, myMsg.w - BORDER * 2, myMsg.h - BORDER * 2, kBtnColor);
+    myMsg.surface->drawString(font(), myMsg.text, HBORDER, VBORDER,
                               myMsg.w, myMsg.color);
+
+    if(myMsg.showGauge)
+    {
+      constexpr int NUM_TICKMARKS = 4;
+      // limit gauge bar width if texts are too long
+      const int swidth = std::min(fontWidth * GAUGEBAR_WIDTH,
+                                  fontWidth * (MESSAGE_WIDTH - 2)
+                                  - font().getStringWidth(myMsg.text)
+                                  - font().getStringWidth(myMsg.valueText));
+      const int bwidth = swidth * myMsg.value / 100.F;
+      const int bheight = fontHeight >> 1;
+      const int x = HBORDER + font().getStringWidth(myMsg.text) + fontWidth;
+      // align bar with bottom of text
+      const int y = VBORDER + font().desc().ascent - bheight;
+
+      // draw gauge bar
+      myMsg.surface->fillRect(x - BORDER, y, swidth + BORDER * 2, bheight, kSliderBGColor);
+      myMsg.surface->fillRect(x, y + BORDER, bwidth, bheight - BORDER * 2, kSliderColor);
+      // draw tickmark in the middle of the bar
+      for(int i = 1; i < NUM_TICKMARKS; ++i)
+      {
+        ColorId color;
+        int xt = x + swidth * i / NUM_TICKMARKS;
+        if(bwidth < xt - x)
+          color = kCheckColor; // kSliderColor;
+        else
+          color = kSliderBGColor;
+        myMsg.surface->vLine(xt, y + bheight / 2, y + bheight - 1, color);
+      }
+      // draw value text
+      myMsg.surface->drawString(font(), myMsg.valueText,
+                                x + swidth + fontWidth, VBORDER,
+                                myMsg.w, myMsg.color);
+    }
+    myMsg.dirty = false;
+    myMsg.surface->render();
+    return true;
   }
-  myMsg.surface->render();
+
   myMsg.counter--;
+  myMsg.surface->render();
 #endif
 
-  return true;
+  return false;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -835,10 +824,12 @@ void FrameBuffer::setPauseDelay()
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-shared_ptr<FBSurface> FrameBuffer::allocateSurface(int w, int h, ScalingInterpolation interpolation, const uInt32* data)
+shared_ptr<FBSurface> FrameBuffer::allocateSurface(
+    int w, int h, ScalingInterpolation inter, const uInt32* data
+)
 {
   // Add new surface to the list
-  mySurfaceList.push_back(createSurface(w, h, interpolation, data));
+  mySurfaceList.push_back(myBackend->createSurface(w, h, inter, data));
 
   // And return a pointer to it (pointer should be treated read-only)
   return mySurfaceList.at(mySurfaceList.size() - 1);
@@ -870,7 +861,7 @@ void FrameBuffer::resetSurfaces()
   freeSurfaces();
   reloadSurfaces();
 
-  update(true); // force full update
+  update(UpdateMode::REDRAW); // force full update
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -923,10 +914,9 @@ void FrameBuffer::setUIPalette()
 void FrameBuffer::stateChanged(EventHandlerState state)
 {
   // Make sure any onscreen messages are removed
-  myMsg.enabled = false;
-  myMsg.counter = 0;
+  hideMessage();
 
-  update(true); // force full update
+  update(); // update immediately
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -941,10 +931,10 @@ string FrameBuffer::getDisplayKey()
     case BufferType::Emulator:
       return "display";
 
-  #ifdef DEBUGGER_SUPPORT
+    #ifdef DEBUGGER_SUPPORT
     case BufferType::Debugger:
       return "dbg.display";
-  #endif
+    #endif
 
     default:
       return "";
@@ -963,10 +953,10 @@ string FrameBuffer::getPositionKey()
     case BufferType::Emulator:
       return  "windowedpos";
 
-  #ifdef DEBUGGER_SUPPORT
+    #ifdef DEBUGGER_SUPPORT
     case BufferType::Debugger:
       return "dbg.pos";
-  #endif
+    #endif
 
     default:
       return "";
@@ -976,9 +966,11 @@ string FrameBuffer::getPositionKey()
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void FrameBuffer::saveCurrentWindowPosition()
 {
-  myOSystem.settings().setValue(getDisplayKey(), getCurrentDisplayIndex());
-  if(isCurrentWindowPositioned())
-    myOSystem.settings().setValue(getPositionKey(), getCurrentWindowPos());
+  myOSystem.settings().setValue(
+    getDisplayKey(), myBackend->getCurrentDisplayIndex());
+  if(myBackend->isCurrentWindowPositioned())
+    myOSystem.settings().setValue(
+      getPositionKey(), myBackend->getCurrentWindowPos());
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -1003,38 +995,19 @@ void FrameBuffer::setFullscreen(bool enable)
     default:
       return;
   }
+
+  myOSystem.settings().setValue("fullscreen", enable);
   saveCurrentWindowPosition();
-
-  // Changing the video mode can take some time, during which the last
-  // sound played may get 'stuck'
-  // So we mute the sound until the operation completes
-  bool oldMuteState = myOSystem.sound().mute(true);
-
-  const VideoMode& mode = getSavedVidMode(enable);
-  if(setVideoMode(myScreenTitle, mode))
-  {
-    myImageRect = mode.image;
-    myScreenSize = mode.screen;
-    myScreenRect = Common::Rect(mode.screen);
-
-    // Inform TIA surface about new mode
-    if(myOSystem.eventHandler().state() != EventHandlerState::LAUNCHER &&
-       myOSystem.eventHandler().state() != EventHandlerState::DEBUGGER)
-      myTIASurface->initialize(myOSystem.console(), mode);
-
-    // Did we get the requested fullscreen state?
-    myOSystem.settings().setValue("fullscreen", fullScreen());
-    resetSurfaces();
-    setCursorState();
-  }
-  myOSystem.sound().mute(oldMuteState);
+  applyVideoMode();
 #endif
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void FrameBuffer::toggleFullscreen(bool toggle)
 {
-  switch (myOSystem.eventHandler().state())
+  EventHandlerState state = myOSystem.eventHandler().state();
+
+  switch(state)
   {
     case EventHandlerState::LAUNCHER:
     case EventHandlerState::EMULATION:
@@ -1042,20 +1015,29 @@ void FrameBuffer::toggleFullscreen(bool toggle)
     case EventHandlerState::DEBUGGER:
     {
       const bool isFullscreen = toggle ? !fullScreen() : fullScreen();
-
       setFullscreen(isFullscreen);
 
-      if (myBufferType != BufferType::Launcher)
+      if(state != EventHandlerState::LAUNCHER)
       {
         ostringstream msg;
-
         msg << "Fullscreen ";
-        if (isFullscreen)
-          msg << "enabled (" << refreshRate() << " Hz)";
-        else
-          msg << "disabled";
 
-        showMessage(msg.str());
+        if(state != EventHandlerState::DEBUGGER)
+        {
+          if(isFullscreen)
+            msg << "enabled (" << myBackend->refreshRate() << " Hz, ";
+          else
+            msg << "disabled (";
+          msg << "Zoom " << myActiveVidMode.zoom * 100 << "%)";
+        }
+        else
+        {
+          if(isFullscreen)
+            msg << "enabled";
+          else
+            msg << "disabled";
+        }
+        showTextMessage(msg.str());
       }
       break;
     }
@@ -1086,9 +1068,9 @@ void FrameBuffer::toggleAdaptRefresh(bool toggle)
 
     msg << "Adapt refresh rate ";
     msg << (isAdaptRefresh ? "enabled" : "disabled");
-    msg << " (" << refreshRate() << " Hz)";
+    msg << " (" << myBackend->refreshRate() << " Hz)";
 
-    showMessage(msg.str());
+    showTextMessage(msg.str());
   }
 }
 #endif
@@ -1114,59 +1096,127 @@ void FrameBuffer::changeOverscan(int direction)
       val << (overscan > 0 ? "+" : "" ) << overscan << "%";
     else
       val << "Off";
-    myOSystem.frameBuffer().showMessage("Overscan", val.str(), overscan, 0, 10);
+    myOSystem.frameBuffer().showGaugeMessage("Overscan", val.str(), overscan, 0, 10);
   }
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void FrameBuffer::selectVidMode(int direction)
+void FrameBuffer::switchVideoMode(int direction)
 {
-  EventHandlerState state = myOSystem.eventHandler().state();
-  bool tiaMode = (state != EventHandlerState::DEBUGGER &&
-                  state != EventHandlerState::LAUNCHER);
-
   // Only applicable when in TIA/emulation mode
-  if(!tiaMode)
+  if(!myOSystem.eventHandler().inTIAMode())
     return;
 
-  if(direction == +1)
-    myCurrentModeList->next();
-  else if(direction == -1)
-    myCurrentModeList->previous();
+  if(!fullScreen())
+  {
+    // Windowed TIA modes support variable zoom levels
+    float zoom = myOSystem.settings().getFloat("tia.zoom");
+    if(direction == +1)       zoom += ZOOM_STEPS;
+    else if(direction == -1)  zoom -= ZOOM_STEPS;
+
+    // Make sure the level is within the allowable desktop size
+    zoom = BSPF::clampw(zoom, supportedTIAMinZoom(), myTIAMaxZoom);
+    myOSystem.settings().setValue("tia.zoom", zoom);
+  }
+  else
+  {
+    // In fullscreen mode, there are only two modes, so direction
+    // is irrelevant
+    if(direction == +1 || direction == -1)
+    {
+      bool stretch = myOSystem.settings().getBool("tia.fs_stretch");
+      myOSystem.settings().setValue("tia.fs_stretch", !stretch);
+    }
+  }
 
   saveCurrentWindowPosition();
+  if(applyVideoMode() == FBInitStatus::Success)
+  {
+    if(fullScreen())
+      showTextMessage(myActiveVidMode.description);
+    else
+      showGaugeMessage("Zoom", myActiveVidMode.description, myActiveVidMode.zoom,
+                  supportedTIAMinZoom(), myTIAMaxZoom);
+  }
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+FBInitStatus FrameBuffer::applyVideoMode()
+{
+  // Update display size, in case windowed/fullscreen mode has changed
+  const Settings& s = myOSystem.settings();
+  if(s.getBool("fullscreen"))
+  {
+    Int32 fsIndex = std::max(myBackend->getCurrentDisplayIndex(), 0);
+    myVidModeHandler.setDisplaySize(myFullscreenDisplays[fsIndex], fsIndex);
+  }
+  else
+    myVidModeHandler.setDisplaySize(myAbsDesktopSize);
+
+  const bool inTIAMode = myOSystem.eventHandler().inTIAMode();
+
+  // Build the new mode based on current settings
+  const VideoModeHandler::Mode& mode = myVidModeHandler.buildMode(s, inTIAMode);
+  if(mode.imageR.size() > mode.screenS)
+    return FBInitStatus::FailTooLarge;
 
   // Changing the video mode can take some time, during which the last
   // sound played may get 'stuck'
   // So we mute the sound until the operation completes
   bool oldMuteState = myOSystem.sound().mute(true);
+  FBInitStatus status = FBInitStatus::FailNotSupported;
 
-  const VideoMode& mode = myCurrentModeList->current();
-  if(setVideoMode(myScreenTitle, mode))
+  if(myBackend->setVideoMode(mode,
+      myOSystem.settings().getInt(getDisplayKey()),
+      myOSystem.settings().getPoint(getPositionKey()))
+    )
   {
-    myImageRect = mode.image;
-    myScreenSize = mode.screen;
-    myScreenRect = Common::Rect(mode.screen);
+    myActiveVidMode = mode;
+    status = FBInitStatus::Success;
 
-    // Inform TIA surface about new mode
-    myTIASurface->initialize(myOSystem.console(), mode);
+    // Did we get the requested fullscreen state?
+    myOSystem.settings().setValue("fullscreen", fullScreen());
+
+    // Inform TIA surface about new mode, and update TIA settings
+    if(inTIAMode)
+    {
+      myTIASurface->initialize(myOSystem.console(), myActiveVidMode);
+      if(fullScreen())
+        myOSystem.settings().setValue("tia.fs_stretch",
+          myActiveVidMode.stretch == VideoModeHandler::Mode::Stretch::Fill);
+      else
+        myOSystem.settings().setValue("tia.zoom", myActiveVidMode.zoom);
+    }
 
     resetSurfaces();
-    if(fullScreen())
-      showMessage(mode.description);
-    else
-      showMessage("Zoom", mode.description, mode.zoom, supportedTIAMinZoom(), myTIAMaxZoom);
-    myOSystem.sound().mute(oldMuteState);
-
-    if(fullScreen())
-      myOSystem.settings().setValue("tia.fs_stretch",
-          mode.stretch == VideoMode::Stretch::Fill);
-    else
-      myOSystem.settings().setValue("tia.zoom", mode.zoom);
-
-    return;
+    setCursorState();
+    myPendingRender = true;
   }
+  else
+    Logger::error("ERROR: Couldn't initialize video subsystem");
+
+  // Restore sound settings
   myOSystem.sound().mute(oldMuteState);
+
+  return status;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+float FrameBuffer::maxWindowZoom(uInt32 baseWidth, uInt32 baseHeight) const
+{
+  float multiplier = 1;
+  for(;;)
+  {
+    // Figure out the zoomed size of the window
+    uInt32 width  = baseWidth * multiplier;
+    uInt32 height = baseHeight * multiplier;
+
+    if((width > myAbsDesktopSize.w) || (height > myAbsDesktopSize.h))
+      break;
+
+    multiplier += ZOOM_STEPS;
+  }
+  return multiplier > 1 ? multiplier - ZOOM_STEPS : 1;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -1208,7 +1258,7 @@ void FrameBuffer::setCursorState()
       break;
   }
 
-  grabMouse(emulation && (analog || alwaysUseMouse) && myGrabMouse);
+  myBackend->grabMouse(emulation && (analog || alwaysUseMouse) && myGrabMouse);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -1226,299 +1276,9 @@ void FrameBuffer::toggleGrabMouse()
   myGrabMouse = !myGrabMouse;
   setCursorState();
   myOSystem.settings().setValue("grabmouse", myGrabMouse);
-  myOSystem.frameBuffer().showMessage(oldState != myGrabMouse ? myGrabMouse
-                                      ? "Grab mouse enabled" : "Grab mouse disabled"
-                                      : "Grab mouse not allowed while cursor shown");
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-float FrameBuffer::maxZoomForScreen(uInt32 baseWidth, uInt32 baseHeight,
-                                    uInt32 screenWidth, uInt32 screenHeight) const
-{
-  float multiplier = 1;
-  for(;;)
-  {
-    // Figure out the zoomed size of the window
-    uInt32 width  = baseWidth * multiplier;
-    uInt32 height = baseHeight * multiplier;
-
-    if((width > screenWidth) || (height > screenHeight))
-      break;
-
-    multiplier += ZOOM_STEPS;
-  }
-  return multiplier > 1 ? multiplier - ZOOM_STEPS : 1;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void FrameBuffer::setAvailableVidModes(uInt32 baseWidth, uInt32 baseHeight)
-{
-  myWindowedModeList.clear();
-
-  for(auto& mode: myFullscreenModeLists)
-    mode.clear();
-  for(size_t i = myFullscreenModeLists.size(); i < myFullscreenDisplays.size(); ++i)
-    myFullscreenModeLists.emplace_back(VideoModeList());
-
-  // Check if zooming is allowed for this state (currently only allowed
-  // for TIA screens)
-  EventHandlerState state = myOSystem.eventHandler().state();
-  bool tiaMode = (state != EventHandlerState::DEBUGGER &&
-                  state != EventHandlerState::LAUNCHER);
-  float overscan = 1 - myOSystem.settings().getInt("tia.fs_overscan") / 100.0;
-
-  // TIA mode allows zooming at integral factors in windowed modes,
-  // and also non-integral factors in fullscreen mode
-  if(tiaMode)
-  {
-    // TIA windowed modes
-    float minZoom = supportedTIAMinZoom();
-    myTIAMaxZoom = maxZoomForScreen(baseWidth, baseHeight,
-                     myAbsDesktopSize.w, myAbsDesktopSize.h);
-    // Determine all zoom levels
-    for(float zoom = minZoom; zoom <= myTIAMaxZoom; zoom += ZOOM_STEPS)
-    {
-      ostringstream desc;
-      desc << (zoom * 100) << "%";
-
-      VideoMode mode(baseWidth*zoom, baseHeight*zoom, baseWidth*zoom, baseHeight*zoom,
-                     VideoMode::Stretch::Fill, 1.0, desc.str(), zoom);
-      myWindowedModeList.add(mode);
-    }
-
-    // TIA fullscreen mode
-    for(uInt32 i = 0; i < myFullscreenDisplays.size(); ++i)
-    {
-      myTIAMaxZoom = maxZoomForScreen(baseWidth, baseHeight,
-          myFullscreenDisplays[i].w * overscan,
-          myFullscreenDisplays[i].h * overscan);
-
-      // Add both normal aspect and filled modes
-      // It's easier to define them both now, and simply switch between
-      // them when necessary
-      VideoMode mode1(baseWidth * myTIAMaxZoom, baseHeight * myTIAMaxZoom,
-                      myFullscreenDisplays[i].w, myFullscreenDisplays[i].h,
-                      VideoMode::Stretch::Preserve, overscan,
-                      "Fullscreen: Preserve aspect, no stretch", myTIAMaxZoom, i);
-      myFullscreenModeLists[i].add(mode1);
-      VideoMode mode2(baseWidth * myTIAMaxZoom, baseHeight * myTIAMaxZoom,
-                      myFullscreenDisplays[i].w, myFullscreenDisplays[i].h,
-                      VideoMode::Stretch::Fill, overscan,
-                      "Fullscreen: Ignore aspect, full stretch", myTIAMaxZoom, i);
-      myFullscreenModeLists[i].add(mode2);
-    }
-  }
-  else  // UI mode
-  {
-    // Windowed and fullscreen mode differ only in screen size
-    myWindowedModeList.add(
-        VideoMode(baseWidth, baseHeight, baseWidth, baseHeight,
-        VideoMode::Stretch::None)
-    );
-    for(uInt32 i = 0; i < myFullscreenDisplays.size(); ++i)
-    {
-      myFullscreenModeLists[i].add(
-          VideoMode(baseWidth, baseHeight,
-                    myFullscreenDisplays[i].w, myFullscreenDisplays[i].h,
-                    VideoMode::Stretch::None, 1.0, "", 1, i)
-      );
-    }
-  }
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-const FrameBuffer::VideoMode& FrameBuffer::getSavedVidMode(bool fullscreen)
-{
-  if(fullscreen)
-  {
-    Int32 i = getCurrentDisplayIndex();
-    if(i < 0)
-    {
-      // default to the first display
-      i = 0;
-    }
-    myCurrentModeList = &myFullscreenModeLists[i];
-  }
-  else
-    myCurrentModeList = &myWindowedModeList;
-
-  // Now select the best resolution depending on the state
-  // UI modes (launcher and debugger) have only one supported resolution
-  // so the 'current' one is the only valid one
-  EventHandlerState state = myOSystem.eventHandler().state();
-  if(state == EventHandlerState::DEBUGGER || state == EventHandlerState::LAUNCHER)
-    myCurrentModeList->setByZoom(1);
-  else  // TIA mode
-  {
-    if(fullscreen)
-      myCurrentModeList->setByStretch(myOSystem.settings().getBool("tia.fs_stretch")
-        ? VideoMode::Stretch::Fill : VideoMode::Stretch::Preserve);
-    else
-      myCurrentModeList->setByZoom(myOSystem.settings().getFloat("tia.zoom"));
-  }
-
-  return myCurrentModeList->current();
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-//
-// VideoMode implementation
-//
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-FrameBuffer::VideoMode::VideoMode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh,
-                                  Stretch smode, float overscan, const string& desc,
-                                  float zoomLevel, Int32 fsindex)
-  : stretch(smode),
-    description(desc),
-    zoom(zoomLevel),
-    fsIndex(fsindex)
-{
-  // First set default size and positioning
-  sw = std::max(sw, TIAConstants::viewableWidth);
-  sh = std::max(sh, TIAConstants::viewableHeight);
-  iw = std::min(iw, sw);
-  ih = std::min(ih, sh);
-  int ix = (sw - iw) >> 1;
-  int iy = (sh - ih) >> 1;
-  image = Common::Rect(ix, iy, ix+iw, iy+ih);
-  screen = Common::Size(sw, sh);
-
-  // Now resize based on windowed/fullscreen mode and stretch factor
-  iw = image.w();
-  ih = image.h();
-
-  if(fsIndex != -1)
-  {
-    switch(stretch)
-    {
-      case Stretch::Preserve:
-      {
-        float stretchFactor = 1.0;
-        float scaleX = float(iw) / screen.w;
-        float scaleY = float(ih) / screen.h;
-
-        // Scale to all available space, keep aspect correct
-        if(scaleX > scaleY)
-          stretchFactor = float(screen.w) / iw;
-        else
-          stretchFactor = float(screen.h) / ih;
-
-        iw = uInt32(stretchFactor * iw) * overscan;
-        ih = uInt32(stretchFactor * ih) * overscan;
-        break;
-      }
-
-      case Stretch::Fill:
-        // Scale to all available space
-        iw = screen.w * overscan;
-        ih = screen.h * overscan;
-        break;
-
-      case Stretch::None:
-        // Don't do any scaling at all, but obey overscan
-        iw = std::min(iw, screen.w) * overscan;
-        ih = std::min(ih, screen.h) * overscan;
-        break;
-    }
-  }
-  else
-  {
-    // In windowed mode, currently the size is scaled to the screen
-    // TODO - this may be updated if/when we allow variable-sized windows
-    switch(stretch)
-    {
-      case Stretch::Preserve:
-      case Stretch::Fill:
-        screen.w = iw;
-        screen.h = ih;
-        break;
-      case Stretch::None:
-        break;  // Do not change image or screen rects whatsoever
-    }
-  }
-
-  // Now re-calculate the dimensions
-  iw = std::min(iw, screen.w);
-  ih = std::min(ih, screen.h);
-
-  image.moveTo((screen.w - iw) >> 1, (screen.h - ih) >> 1);
-  image.setWidth(iw);
-  image.setHeight(ih);
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-//
-// VideoModeList implementation
-//
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void FrameBuffer::VideoModeList::add(const VideoMode& mode)
-{
-  myModeList.emplace_back(mode);
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void FrameBuffer::VideoModeList::clear()
-{
-  myModeList.clear();
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-bool FrameBuffer::VideoModeList::empty() const
-{
-  return myModeList.empty();
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-uInt32 FrameBuffer::VideoModeList::size() const
-{
-  return uInt32(myModeList.size());
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void FrameBuffer::VideoModeList::previous()
-{
-  --myIdx;
-  if(myIdx < 0) myIdx = int(myModeList.size()) - 1;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-const FrameBuffer::VideoMode& FrameBuffer::VideoModeList::current() const
-{
-  return myModeList[myIdx];
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void FrameBuffer::VideoModeList::next()
-{
-  myIdx = (myIdx + 1) % myModeList.size();
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void FrameBuffer::VideoModeList::setByZoom(float zoom)
-{
-  for(uInt32 i = 0; i < myModeList.size(); ++i)
-  {
-    if(myModeList[i].zoom == zoom)
-    {
-      myIdx = i;
-      return;
-    }
-  }
-  myIdx = 0;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void FrameBuffer::VideoModeList::setByStretch(FrameBuffer::VideoMode::Stretch stretch)
-{
-  for(uInt32 i = 0; i < myModeList.size(); ++i)
-  {
-    if(myModeList[i].stretch == stretch)
-    {
-      myIdx = i;
-      return;
-    }
-  }
-  myIdx = 0;
+  myOSystem.frameBuffer().showTextMessage(oldState != myGrabMouse ? myGrabMouse
+                                          ? "Grab mouse enabled" : "Grab mouse disabled"
+                                          : "Grab mouse not allowed while cursor shown");
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -1567,8 +1327,6 @@ void FrameBuffer::VideoModeList::setByStretch(FrameBuffer::VideoMode::Stretch st
     kColorInfo            TIA output position color
     kColorTitleBar        Title bar color
     kColorTitleText       Title text color
-    kColorTitleBarLo      Disabled title bar color
-    kColorTitleTextLo     Disabled title text color
 */
 UIPaletteArray FrameBuffer::ourStandardUIPalette = {
   { 0x686868, 0x000000, 0xa38c61, 0xdccfa5, 0x404040,           // base
@@ -1579,7 +1337,7 @@ UIPaletteArray FrameBuffer::ourStandardUIPalette = {
     0xac3410, 0xd55941,                                         // scrollbar
     0xc80000, 0xffff80, 0xc8c8ff, 0xc80000,                     // debugger
     0xac3410, 0xd55941, 0xdccfa5, 0xf0f0cf, 0xa38c61,           // slider
-    0xffffff, 0xac3410, 0xf0f0cf, 0x686868, 0xdccfa5            // other
+    0xffffff, 0xac3410, 0xf0f0cf                                // other
   }
 };
 
@@ -1592,7 +1350,7 @@ UIPaletteArray FrameBuffer::ourClassicUIPalette = {
     0x20a020, 0x00ff00,                                         // scrollbar
     0xc80000, 0x00ff00, 0xc8c8ff, 0xc80000,                     // debugger
     0x20a020, 0x00ff00, 0x404040, 0x686868, 0x404040,           // slider
-    0x00ff00, 0x20a020, 0x000000, 0x686868, 0x404040            // other
+    0x00ff00, 0x20a020, 0x000000                                // other
   }
 };
 
@@ -1605,7 +1363,7 @@ UIPaletteArray FrameBuffer::ourLightUIPalette = {
     0xc0c0c0, 0x808080,                                         // scrollbar
     0xffc0c0, 0x000000, 0xe00000, 0xc00000,                     // debugger
     0x333333, 0x0078d7, 0xc0c0c0, 0xffffff, 0xc0c0c0,           // slider 0xBDDEF9| 0xe1e1e1 | 0xffffff
-    0xffffff, 0x333333, 0xf0f0f0, 0x808080, 0xc0c0c0            // other
+    0xffffff, 0x333333, 0xf0f0f0                                // other
   }
 };
 
@@ -1618,6 +1376,6 @@ UIPaletteArray FrameBuffer::ourDarkUIPalette = {
     0x3c3c3c, 0x646464,                                         // scrollbar
     0x7f2020, 0xc0c0c0, 0xe00000, 0xc00000,                     // debugger
     0x989898, 0x0059a3, 0x3c3c3c, 0x000000, 0x3c3c3c,           // slider
-    0x000000, 0x989898, 0x202020, 0x646464, 0x3c3c3c            // other
+    0x000000, 0x989898, 0x202020                                // other
   }
 };
diff --git a/src/emucore/FrameBuffer.hxx b/src/emucore/FrameBuffer.hxx
index 58d61dfd3..0971873f2 100644
--- a/src/emucore/FrameBuffer.hxx
+++ b/src/emucore/FrameBuffer.hxx
@@ -33,14 +33,16 @@ class TIASurface;
 #include "Rect.hxx"
 #include "Variant.hxx"
 #include "TIAConstants.hxx"
+#include "FBBackend.hxx"
 #include "FrameBufferConstants.hxx"
 #include "EventHandlerConstants.hxx"
+#include "VideoModeHandler.hxx"
 #include "bspf.hxx"
 
 /**
   This class encapsulates all video buffers and is the basis for the video
-  display in Stella.  All graphics ports should derive from this class for
-  platform-specific video stuff.
+  display in Stella.  The FBBackend object contained in this class is
+  platform-specific, and most rendering tasks are delegated to it.
 
   The TIA is drawn here, and all GUI elements (ala ScummVM, which are drawn
   into FBSurfaces), are in turn drawn here as well.
@@ -50,79 +52,31 @@ class TIASurface;
 class FrameBuffer
 {
   public:
-    // Contains all relevant info for the dimensions of a video screen
-    // Also takes care of the case when the image should be 'centered'
-    // within the given screen:
-    //   'image' is the image dimensions into the screen
-    //   'screen' are the dimensions of the screen itself
-    struct VideoMode
-    {
-      enum class Stretch { Preserve, Fill, None };
-
-      Common::Rect image;
-      Common::Size screen;
-      Stretch stretch{VideoMode::Stretch::None};
-      string description;
-      float zoom{1.F};
-      Int32 fsIndex{-1};
-
-      VideoMode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh,
-                Stretch smode, float overscan = 1.F,
-                const string& desc = "", float zoomLevel = 1, Int32 fsindex = -1);
-
-      friend ostream& operator<<(ostream& os, const VideoMode& vm)
-      {
-        os << "image=" << vm.image << "  screen=" << vm.screen
-           << "  stretch=" << (vm.stretch == Stretch::Preserve ? "preserve" :
-                               vm.stretch == Stretch::Fill ? "fill" : "none")
-           << "  desc=" << vm.description << "  zoom=" << vm.zoom
-           << "  fsIndex= " << vm.fsIndex;
-        return os;
-      }
-    };
-
-    struct DisplayMode
-    {
-      uInt32 display;
-      Common::Size size;
-      uInt32 refresh_rate;
-    };
-
-    enum class BufferType {
-      None,
-      Launcher,
-      Emulator,
-      Debugger
-    };
-
-    enum class ScalingInterpolation {
-      none,
-      sharp,
-      blur
-    };
-
     // Zoom level step interval
     static constexpr float ZOOM_STEPS = 0.25;
 
+    enum UpdateMode {
+      NONE = 0,
+      REDRAW = 1,
+      RERENDER = 2
+    };
+
   public:
-    /**
-      Creates a new Frame Buffer
-    */
     FrameBuffer(OSystem& osystem);
-    virtual ~FrameBuffer();
+    ~FrameBuffer();
 
     /**
-      Initialize the framebuffer object (set up the underlying hardware)
+      Initialize the framebuffer object (set up the underlying hardware).
+      Throws an exception upon encountering any errors.
     */
-    bool initialize();
+    void initialize();
 
     /**
       (Re)creates the framebuffer display.  This must be called before any
       calls are made to derived methods.
 
       @param title   The title of the application / window
-      @param width   The width of the framebuffer
-      @param height  The height of the framebuffer
+      @param size    The dimensions of the display
       @param honourHiDPI  If true, consult the 'hidpi' setting and enlarge
                           the display size accordingly; if false, use the
                           exact dimensions as given
@@ -130,30 +84,34 @@ class FrameBuffer
       @return  Status of initialization (see FBInitStatus 'enum')
     */
     FBInitStatus createDisplay(const string& title, BufferType type,
-                               uInt32 width, uInt32 height,
-                               bool honourHiDPI = true);
+                               Common::Size size, bool honourHiDPI = true);
 
     /**
       Updates the display, which depending on the current mode could mean
       drawing the TIA, any pending menus, etc.
     */
-    void update(bool force = false);
+    void update(UpdateMode mode = UpdateMode::NONE);
 
     /**
       There is a dedicated update method for emulation mode.
-     */
+    */
     void updateInEmulationMode(float framesPerSecond);
 
     /**
-      Shows a message onscreen.
+      Set pending rendering flag.
+    */
+    void setPendingRender() { myPendingRender = true; }
+
+    /**
+      Shows a text message onscreen.
 
       @param message  The message to be shown
       @param position Onscreen position for the message
       @param force    Force showing this message, even if messages are disabled
     */
-    void showMessage(const string& message,
-                     MessagePosition position = MessagePosition::BottomCenter,
-                     bool force = false);
+    void showTextMessage(const string& message,
+                         MessagePosition position = MessagePosition::BottomCenter,
+                         bool force = false);
     /**
       Shows a message with a gauge bar onscreen.
 
@@ -163,8 +121,8 @@ class FrameBuffer
       @param minValue   The minimal value of the gauge bar
       @param maxValue   The maximal value of the gauge bar
     */
-    void showMessage(const string& message, const string& valueText,
-                     float value, float minValue = 0.F, float maxValue = 100.F);
+    void showGaugeMessage(const string& message, const string& valueText,
+                          float value, float minValue = 0.F, float maxValue = 100.F);
 
     bool messageShown() const;
 
@@ -193,17 +151,17 @@ class FrameBuffer
       Allocate a new surface.  The FrameBuffer class takes all responsibility
       for freeing this surface (ie, other classes must not delete it directly).
 
-      @param w                The requested width of the new surface.
-      @param h                The requested height of the new surface.
-      @param interpolation    Interpolation mode
-      @param data             If non-null, use the given data values as a static surface
+      @param w      The requested width of the new surface
+      @param h      The requested height of the new surface
+      @param inter  Interpolation mode
+      @param data   If non-null, use the given data values as a static surface
 
-      @return  A pointer to a valid surface object, or nullptr.
+      @return  A pointer to a valid surface object, or nullptr
     */
     shared_ptr<FBSurface> allocateSurface(
       int w,
       int h,
-      ScalingInterpolation interpolation = ScalingInterpolation::none,
+      ScalingInterpolation inter = ScalingInterpolation::none,
       const uInt32* data = nullptr
     );
 
@@ -225,15 +183,15 @@ class FrameBuffer
       Note that this will take into account the current scaling (if any)
       as well as image 'centering'.
     */
-    const Common::Rect& imageRect() const { return myImageRect; }
+    const Common::Rect& imageRect() const { return myActiveVidMode.imageR; }
 
     /**
       Returns the current dimensions of the framebuffer window.
       This is the entire area containing the framebuffer image as well as any
       'unusable' area.
     */
-    const Common::Size& screenSize() const { return myScreenSize; }
-    const Common::Rect& screenRect() const { return myScreenRect; }
+    const Common::Size& screenSize() const { return myActiveVidMode.screenS; }
+    const Common::Rect& screenRect() const { return myActiveVidMode.screenR; }
 
     /**
       Returns the current dimensions of the users' desktop.
@@ -259,11 +217,6 @@ class FrameBuffer
     */
     TIASurface& tiaSurface() const { return *myTIASurface; }
 
-    /**
-      Enables/disables fullscreen mode.
-    */
-    void setFullscreen(bool enable);
-
     /**
       Toggles between fullscreen and window mode.
     */
@@ -279,21 +232,19 @@ class FrameBuffer
     /**
       Changes the fullscreen overscan.
 
-      @param direction  +1 indicates increase, -1 indicates decrease.
+      @param direction  +1 indicates increase, -1 indicates decrease
     */
     void changeOverscan(int direction = +1);
 
     /**
-      This method is called when the user wants to switch to the next
-      available video mode.  In windowed mode, this typically means going to
-      the next/previous zoom level.  In fullscreen mode, this typically means
-      switching between normal aspect and fully filling the screen.
-        direction = -1 means go to the next lower video mode
-        direction = +1 means go to the next higher video mode
+      This method is called when the user wants to switch to the previous/next
+      available TIA video mode.  In windowed mode, this typically means going
+      to the next/previous zoom level.  In fullscreen mode, this typically
+      means switching between normal aspect and fully filling the screen.
 
-      @param direction  +1 indicates increase, -1 indicates decrease.
+      @param direction  +1 indicates next mode, -1 indicates previous mode
     */
-    void selectVidMode(int direction = +1);
+    void switchVideoMode(int direction = +1);
 
     /**
       Sets the state of the cursor (hidden or grabbed) based on the
@@ -306,16 +257,16 @@ class FrameBuffer
     */
     void enableGrabMouse(bool enable);
 
-    /**
-      Sets the use of grabmouse.
-    */
-    bool grabMouseEnabled() const { return myGrabMouse; }
-
     /**
       Toggles the use of grabmouse (only has effect in emulation mode).
     */
     void toggleGrabMouse();
 
+    /**
+      Query whether grabmouse is enabled.
+    */
+    bool grabMouseEnabled() const { return myGrabMouse; }
+
     /**
       Informs the Framebuffer of a change in EventHandler state.
     */
@@ -335,7 +286,8 @@ class FrameBuffer
     uInt32 hidpiScaleFactor() const { return myHiDPIEnabled ? 2 : 1; }
 
     /**
-      These methods are used to load/save position and display of the current window.
+      These methods are used to load/save position and display of the
+      current window.
     */
     string getPositionKey();
     string getDisplayKey();
@@ -360,27 +312,15 @@ class FrameBuffer
     FontDesc getFontDesc(const string& name) const;
   #endif
 
-  //////////////////////////////////////////////////////////////////////
-  // The following methods are system-specific and can/must be
-  // implemented in derived classes.
-  //////////////////////////////////////////////////////////////////////
-  public:
-    /**
-      Updates window title
-
-      @param title   The title of the application / window
-    */
-    virtual void setTitle(const string& title) = 0;
-
     /**
       Shows or hides the cursor based on the given boolean value.
     */
-    virtual void showCursor(bool show) = 0;
+    void showCursor(bool show) { myBackend->showCursor(show); }
 
     /**
       Answers if the display is currently in fullscreen mode.
     */
-    virtual bool fullScreen() const = 0;
+    bool fullScreen() const { return myBackend->fullScreen(); }
 
     /**
       This method is called to retrieve the R/G/B data from the given pixel.
@@ -390,7 +330,9 @@ class FrameBuffer
       @param g      The green component of the color
       @param b      The blue component of the color
     */
-    virtual void getRGB(uInt32 pixel, uInt8* r, uInt8* g, uInt8* b) const = 0;
+    void getRGB(uInt32 pixel, uInt8* r, uInt8* g, uInt8* b) const {
+      myBackend->getRGB(pixel, r, g, b);
+    }
 
     /**
       This method is called to map a given R/G/B triple to the screen palette.
@@ -399,7 +341,9 @@ class FrameBuffer
       @param g  The green component of the color.
       @param b  The blue component of the color.
     */
-    virtual uInt32 mapRGB(uInt8 r, uInt8 g, uInt8 b) const = 0;
+    uInt32 mapRGB(uInt8 r, uInt8 g, uInt8 b) const {
+      return myBackend->mapRGB(r, g, b);
+    }
 
     /**
       This method is called to get the specified ARGB data from the viewable
@@ -411,89 +355,22 @@ class FrameBuffer
       @param pitch   The pitch (in bytes) for the pixel data
       @param rect    The bounding rectangle for the buffer
     */
-    virtual void readPixels(uInt8* buffer, uInt32 pitch, const Common::Rect& rect) const = 0;
-
-    /**
-      This method is called to query if the current window is not centered or fullscreen.
-
-      @return  True, if the current window is positioned
-    */
-    virtual bool isCurrentWindowPositioned() const = 0;
-
-    /**
-      This method is called to query the video hardware for position of
-      the current window
-
-      @return  The position of the currently displayed window
-    */
-    virtual Common::Point getCurrentWindowPos() const = 0;
-
-    /**
-      This method is called to query the video hardware for the index
-      of the display the current window is displayed on
-
-      @return  the current display index or a negative value if no
-               window is displayed
-    */
-    virtual Int32 getCurrentDisplayIndex() const = 0;
+    void readPixels(uInt8* buffer, uInt32 pitch, const Common::Rect& rect) const {
+      myBackend->readPixels(buffer, pitch, rect);
+    }
 
     /**
       Clear the framebuffer.
     */
-    virtual void clear() = 0;
+    void clear() { myBackend->clear(); }
 
     /**
-      Transform from window to renderer coordinates, x direction
+      Transform from window to renderer coordinates, x/y direction
      */
-    virtual int scaleX(int x) const { return x; }
-
-    /**
-      Transform from window to renderer coordinates, y direction
-     */
-    virtual int scaleY(int y) const { return y; }
-
-  protected:
-
-    /**
-      This method is called to query and initialize the video hardware
-      for desktop and fullscreen resolution information.  Since several
-      monitors may be attached, we need the resolution for all of them.
-
-      @param fullscreenRes  Maximum resolution supported in fullscreen mode
-      @param windowedRes    Maximum resolution supported in windowed mode
-      @param renderers      List of renderer names (internal name -> end-user name)
-    */
-    virtual void queryHardware(vector<Common::Size>& fullscreenRes,
-                               vector<Common::Size>& windowedRes,
-                               VariantList& renderers) = 0;
-
-    /**
-      This method is called to change to the given video mode.
-
-      @param title The title for the created window
-      @param mode  The video mode to use
-
-      @return  False on any errors, else true
-    */
-    virtual bool setVideoMode(const string& title,
-                              const FrameBuffer::VideoMode& mode) = 0;
-
-    /**
-      This method is called to create a surface with the given attributes.
-
-      @param w                The requested width of the new surface.
-      @param h                The requested height of the new surface.
-      @param interpolation    Interpolation mode
-      @param data             If non-null, use the given data values as a static surface
-    */
-    virtual unique_ptr<FBSurface>
-        createSurface(
-          uInt32 w,
-          uInt32 h,
-          ScalingInterpolation interpolation = ScalingInterpolation::none,
-          const uInt32* data = nullptr
-    ) const = 0;
+    int scaleX(int x) const { return myBackend->scaleX(x); }
+    int scaleY(int y) const { return myBackend->scaleY(y); }
 
+  private:
     /**
       Calls 'free()' on all surfaces that the framebuffer knows about.
     */
@@ -505,40 +382,21 @@ class FrameBuffer
     void reloadSurfaces();
 
     /**
-      Grabs or ungrabs the mouse based on the given boolean value.
+      Frees and reloads all surfaces that the framebuffer knows about.
     */
-    virtual void grabMouse(bool grab) = 0;
+    void resetSurfaces();
 
+  #ifdef GUI_SUPPORT
     /**
-      Set the icon for the main window.
+      Helps to create a basic message onscreen.
+
+      @param message  The message to be shown
+      @param position Onscreen position for the message
+      @param force    Force showing this message, even if messages are disabled
     */
-    virtual void setWindowIcon() = 0;
-
-    /**
-      This method must be called after all drawing is done, and indicates
-      that the buffers should be pushed to the physical screen.
-    */
-    virtual void renderToScreen() = 0;
-
-    /**
-      This method is called to provide information about the FrameBuffer.
-    */
-    virtual string about() const = 0;
-
-    /**
-      Retrieve the current display's refresh rate
-    */
-    virtual int refreshRate() const { return 0; }
-
-  protected:
-    // The parent system for the framebuffer
-    OSystem& myOSystem;
-
-  private:
-    // Maximum message width [chars]
-    static constexpr int MESSAGE_WIDTH = 56;
-    // Maximum gauge bar width [chars]
-    static constexpr int GAUGEBAR_WIDTH = 30;
+    void createMessage(const string& message, MessagePosition position,
+                       bool force = false);
+  #endif
 
     /**
       Draw pending messages.
@@ -548,9 +406,34 @@ class FrameBuffer
     bool drawMessage();
 
     /**
-      Frees and reloads all surfaces that the framebuffer knows about.
+      Hide pending messages.
     */
-    void resetSurfaces();
+    void hideMessage();
+
+    /**
+      Draws the frame stats overlay.
+    */
+    void drawFrameStats(float framesPerSecond);
+
+    /**
+      Build an applicable video mode based on the current settings in
+      effect, whether TIA mode is active, etc.  Then tell the backend
+      to actually use the new mode.
+
+      @return  Whether the operation succeeded or failed
+    */
+    FBInitStatus applyVideoMode();
+
+    /**
+      Calculate the maximum level by which the base window can be zoomed and
+      still fit in the desktop screen.
+    */
+    float maxWindowZoom(uInt32 baseWidth, uInt32 baseHeight) const;
+
+    /**
+      Enables/disables fullscreen mode.
+    */
+    void setFullscreen(bool enable);
 
   #ifdef GUI_SUPPORT
     /**
@@ -559,78 +442,12 @@ class FrameBuffer
     void setupFonts();
   #endif
 
-    /**
-      Calculate the maximum level by which the base window can be zoomed and
-      still fit in the given screen dimensions.
-    */
-    float maxZoomForScreen(uInt32 baseWidth, uInt32 baseHeight,
-               uInt32 screenWidth, uInt32 screenHeight) const;
-
-    /**
-      Set all possible video modes (both windowed and fullscreen) available for
-      this framebuffer based on given image dimensions and maximum window size.
-    */
-    void setAvailableVidModes(uInt32 basewidth, uInt32 baseheight);
-
-    /**
-      Returns an appropriate video mode based on the current eventhandler
-      state, taking into account the maximum size of the window.
-
-      @param fullscreen  Whether to use a windowed or fullscreen mode
-      @return  A valid VideoMode for this framebuffer
-    */
-    const FrameBuffer::VideoMode& getSavedVidMode(bool fullscreen);
-
   private:
-    /**
-      This class implements an iterator around an array of VideoMode objects.
-    */
-    class VideoModeList
-    {
-      public:
-        void add(const FrameBuffer::VideoMode& mode);
-        void clear();
+    // The parent system for the framebuffer
+    OSystem& myOSystem;
 
-        bool empty() const;
-        uInt32 size() const;
-
-        void previous();
-        const FrameBuffer::VideoMode& current() const;
-        void next();
-
-        void setByZoom(float zoom);
-        void setByStretch(FrameBuffer::VideoMode::Stretch stretch);
-
-        friend ostream& operator<<(ostream& os, const VideoModeList& l)
-        {
-          for(const auto& vm: l.myModeList)
-            os << "-----\n" << vm << endl << "-----\n";
-          return os;
-        }
-
-      private:
-        vector<FrameBuffer::VideoMode> myModeList;
-        int myIdx{-1};
-    };
-
-  protected:
-    // Title of the main window/screen
-    string myScreenTitle;
-
-    // Type of the frame buffer
-    BufferType myBufferType{BufferType::None};
-
-    // Number of displays
-    int myNumDisplays{1};
-
-    // The resolution of the attached displays in fullscreen mode
-    // The primary display is typically the first in the array
-    // Windowed modes use myDesktopSize directly
-    vector<Common::Size> myFullscreenDisplays;
-
-  private:
-    // Draws the frame stats overlay
-    void drawFrameStats(float framesPerSecond);
+    // Backend used for all platform-specific graphics operations
+    unique_ptr<FBBackend> myBackend;
 
     // Indicates the number of times the framebuffer was initialized
     uInt32 myInitializedCount{0};
@@ -638,16 +455,6 @@ class FrameBuffer
     // Used to set intervals between messages while in pause mode
     Int32 myPausedCount{0};
 
-    // Dimensions of the actual image, after zooming, and taking into account
-    // any image 'centering'
-    Common::Rect myImageRect;
-
-    // Dimensions of the main window (not always the same as the image)
-    // Use 'size' version when only wxh are required
-    // Use 'rect' version when x/y, wxh are required
-    Common::Size myScreenSize;
-    Common::Rect myScreenRect;
-
     // Maximum dimensions of the desktop area
     // Note that this takes 'hidpi' mode into account, so in some cases
     // it will be less than the absolute desktop size
@@ -656,9 +463,25 @@ class FrameBuffer
     // Maximum absolute dimensions of the desktop area
     Common::Size myAbsDesktopSize;
 
+    // The resolution of the attached displays in fullscreen mode
+    // The primary display is typically the first in the array
+    // Windowed modes use myDesktopSize directly
+    vector<Common::Size> myFullscreenDisplays;
+
     // Supported renderers
     VariantList myRenderers;
 
+    // Flag for pending render
+    bool myPendingRender{false};
+
+    // The VideoModeHandler class takes responsibility for all video
+    // mode functionality
+    VideoModeHandler myVidModeHandler;
+    VideoModeHandler::Mode myActiveVidMode;
+
+    // Type of the frame buffer
+    BufferType myBufferType{BufferType::None};
+
   #ifdef GUI_SUPPORT
     // The font object to use for the normal in-game GUI
     unique_ptr<GUI::Font> myFont;
@@ -686,6 +509,7 @@ class FrameBuffer
       ColorId color{kNone};
       shared_ptr<FBSurface> surface;
       bool enabled{false};
+      bool dirty{false};
       bool showGauge{false};
       float value{0.0F};
       string valueText;
@@ -699,11 +523,6 @@ class FrameBuffer
     bool myHiDPIAllowed{false};
     bool myHiDPIEnabled{false};
 
-    // The list of all available video modes for this framebuffer
-    VideoModeList* myCurrentModeList{nullptr};
-    VideoModeList myWindowedModeList;
-    vector<VideoModeList> myFullscreenModeLists;
-
     // Minimum TIA zoom level that can be used for this framebuffer
     float myTIAMinZoom{2.F};
     // Maximum TIA zoom level that can be used for this framebuffer
@@ -712,10 +531,15 @@ class FrameBuffer
     // Holds a reference to all the surfaces that have been created
     vector<shared_ptr<FBSurface>> mySurfaceList;
 
+    // Maximum message width [chars]
+    static constexpr int MESSAGE_WIDTH = 56;
+    // Maximum gauge bar width [chars]
+    static constexpr int GAUGEBAR_WIDTH = 30;
+
     FullPaletteArray myFullPalette;
     // Holds UI palette data (for each variation)
-    static UIPaletteArray ourStandardUIPalette, ourClassicUIPalette, 
-      ourLightUIPalette, ourDarkUIPalette;
+    static UIPaletteArray ourStandardUIPalette, ourClassicUIPalette,
+                          ourLightUIPalette, ourDarkUIPalette;
 
   private:
     // Following constructors and assignment operators not supported
diff --git a/src/emucore/FrameBufferConstants.hxx b/src/emucore/FrameBufferConstants.hxx
index 04bac451b..7896fd04c 100644
--- a/src/emucore/FrameBufferConstants.hxx
+++ b/src/emucore/FrameBufferConstants.hxx
@@ -35,6 +35,19 @@ enum class FBInitStatus {
   FailNotSupported
 };
 
+enum class BufferType {
+  None,
+  Launcher,
+  Emulator,
+  Debugger
+};
+
+enum class ScalingInterpolation {
+  none,
+  sharp,
+  blur
+};
+
 // Positions for onscreen/overlaid messages
 enum class MessagePosition {
   TopLeft,
@@ -96,9 +109,7 @@ static constexpr ColorId
   kColorInfo = 287,
   kColorTitleBar = 288,
   kColorTitleText = 289,
-  kColorTitleBarLo = 290,
-  kColorTitleTextLo = 291,
-  kNumColors = 292,
+  kNumColors = 290,
   kNone = 0  // placeholder to represent default/no color
 ;
 
diff --git a/src/emucore/Joystick.cxx b/src/emucore/Joystick.cxx
index ea0d71300..7f62335f9 100644
--- a/src/emucore/Joystick.cxx
+++ b/src/emucore/Joystick.cxx
@@ -19,26 +19,48 @@
 #include "Joystick.hxx"
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Joystick::Joystick(Jack jack, const Event& event, const System& system)
+Joystick::Joystick(Jack jack, const Event& event, const System& system, bool altmap)
   : Controller(jack, event, system, Controller::Type::Joystick)
 {
   if(myJack == Jack::Left)
   {
-    myUpEvent    = Event::JoystickZeroUp;
-    myDownEvent  = Event::JoystickZeroDown;
-    myLeftEvent  = Event::JoystickZeroLeft;
-    myRightEvent = Event::JoystickZeroRight;
-    myFireEvent  = Event::JoystickZeroFire;
+    if(!altmap)
+    {
+      myUpEvent    = Event::JoystickZeroUp;
+      myDownEvent  = Event::JoystickZeroDown;
+      myLeftEvent  = Event::JoystickZeroLeft;
+      myRightEvent = Event::JoystickZeroRight;
+      myFireEvent  = Event::JoystickZeroFire;
+    }
+    else
+    {
+      myUpEvent    = Event::JoystickTwoUp;
+      myDownEvent  = Event::JoystickTwoDown;
+      myLeftEvent  = Event::JoystickTwoLeft;
+      myRightEvent = Event::JoystickTwoRight;
+      myFireEvent  = Event::JoystickTwoFire;
+    }
     myXAxisValue = Event::PaddleZeroAnalog;
     myYAxisValue = Event::PaddleOneAnalog;
   }
   else
   {
-    myUpEvent    = Event::JoystickOneUp;
-    myDownEvent  = Event::JoystickOneDown;
-    myLeftEvent  = Event::JoystickOneLeft;
-    myRightEvent = Event::JoystickOneRight;
-    myFireEvent  = Event::JoystickOneFire;
+    if(!altmap)
+    {
+      myUpEvent    = Event::JoystickOneUp;
+      myDownEvent  = Event::JoystickOneDown;
+      myLeftEvent  = Event::JoystickOneLeft;
+      myRightEvent = Event::JoystickOneRight;
+      myFireEvent  = Event::JoystickOneFire;
+    }
+    else
+    {
+      myUpEvent    = Event::JoystickThreeUp;
+      myDownEvent  = Event::JoystickThreeDown;
+      myLeftEvent  = Event::JoystickThreeLeft;
+      myRightEvent = Event::JoystickThreeRight;
+      myFireEvent  = Event::JoystickThreeFire;
+    }
     myXAxisValue = Event::PaddleTwoAnalog;
     myYAxisValue = Event::PaddleThreeAnalog;
   }
diff --git a/src/emucore/Joystick.hxx b/src/emucore/Joystick.hxx
index 99675c51e..ec652e98b 100644
--- a/src/emucore/Joystick.hxx
+++ b/src/emucore/Joystick.hxx
@@ -33,11 +33,12 @@ class Joystick : public Controller
     /**
       Create a new joystick controller plugged into the specified jack
 
-      @param jack   The jack the controller is plugged into
-      @param event  The event object to use for events
-      @param system The system using this controller
+      @param jack    The jack the controller is plugged into
+      @param event   The event object to use for events
+      @param system  The system using this controller
+      @param altmap  If true, use alternative mapping
     */
-    Joystick(Jack jack, const Event& event, const System& system);
+    Joystick(Jack jack, const Event& event, const System& system, bool altmap = false);
     ~Joystick() override = default;
 
   public:
diff --git a/src/emucore/M6502.cxx b/src/emucore/M6502.cxx
index 86b050dfb..295697af2 100644
--- a/src/emucore/M6502.cxx
+++ b/src/emucore/M6502.cxx
@@ -243,7 +243,9 @@ inline void M6502::_execute(uInt64 cycles, DispatchResult& result)
           myJustHitReadTrapFlag = myJustHitWriteTrapFlag = false;
 
           myLastBreakCycle = mySystem->cycles();
-          result.setDebugger(currentCycles, myHitTrapInfo.message, myHitTrapInfo.address, read);
+          result.setDebugger(currentCycles, myHitTrapInfo.message,
+                             read ? "Read trap" : "Write trap",
+                             myHitTrapInfo.address, read);
           return;
         }
 
@@ -264,7 +266,7 @@ inline void M6502::_execute(uInt64 cycles, DispatchResult& result)
               ostringstream msg;
 
               msg << "BP: $" << Common::Base::HEX4 << PC << ", bank #" << std::dec << int(bank);
-              result.setDebugger(currentCycles, msg.str());
+              result.setDebugger(currentCycles, msg.str(), "Breakpoint");
             }
             return;
           }
@@ -278,7 +280,7 @@ inline void M6502::_execute(uInt64 cycles, DispatchResult& result)
           msg << "CBP[" << Common::Base::HEX2 << cond << "]: " << myCondBreakNames[cond];
 
           myLastBreakCycle = mySystem->cycles();
-          result.setDebugger(currentCycles, msg.str());
+          result.setDebugger(currentCycles, msg.str(), "Conditional breakpoint");
           return;
         }
       }
@@ -327,7 +329,7 @@ inline void M6502::_execute(uInt64 cycles, DispatchResult& result)
           {
             ostringstream msg;
             msg << "RWP[@ $" << Common::Base::HEX4 << rwpAddr << "]: ";
-            result.setDebugger(currentCycles, msg.str(), oldPC);
+            result.setDebugger(currentCycles, msg.str(), "Read from write port", oldPC);
             return;
           }
         }
@@ -339,7 +341,7 @@ inline void M6502::_execute(uInt64 cycles, DispatchResult& result)
           {
             ostringstream msg;
             msg << "WRP[@ $" << Common::Base::HEX4 << wrpAddr << "]: ";
-            result.setDebugger(currentCycles, msg.str(), oldPC);
+            result.setDebugger(currentCycles, msg.str(), "Write to read port", oldPC);
             return;
           }
         }
@@ -348,7 +350,7 @@ inline void M6502::_execute(uInt64 cycles, DispatchResult& result)
         myExecutionStatus |= FatalErrorBit;
         result.setMessage(e.what());
       } catch (const EmulationWarning& e) {
-        result.setDebugger(currentCycles, e.what(), PC);
+        result.setDebugger(currentCycles, e.what(), "Emulation exception", PC);
         return;
       }
 
diff --git a/src/emucore/M6532.cxx b/src/emucore/M6532.cxx
index 18f950e62..eaa43c61f 100644
--- a/src/emucore/M6532.cxx
+++ b/src/emucore/M6532.cxx
@@ -145,6 +145,10 @@ void M6532::updateEmulation()
   }
 
   myLastCycle = mySystem->cycles();
+
+#ifdef DEBUGGER_SUPPORT
+  myTimWrappedOnRead = myTimWrappedOnWrite = false;
+#endif
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -220,7 +224,10 @@ uInt8 M6532::peek(uInt16 addr)
     {
       // Timer Flag is always cleared when accessing INTIM
       if (!myWrappedThisCycle) myInterruptFlag &= ~TimerBit;
-
+  #ifdef DEBUGGER_SUPPORT
+      myTimWrappedOnRead = myWrappedThisCycle;
+      myTimReadCycles += 7;
+  #endif
       return myTimer;
     }
 
@@ -230,6 +237,9 @@ uInt8 M6532::peek(uInt16 addr)
       // PA7 Flag is always cleared after accessing TIMINT
       uInt8 result = myInterruptFlag;
       myInterruptFlag &= ~PA7Bit;
+    #ifdef DEBUGGER_SUPPORT
+      myTimReadCycles += 7;
+    #endif
       return result;
     }
 
@@ -316,6 +326,9 @@ void M6532::setTimerRegister(uInt8 value, uInt8 interval)
 
   // Interrupt timer flag is cleared (and invalid) when writing to the timer
   if (!myWrappedThisCycle) myInterruptFlag &= ~TimerBit;
+#ifdef DEBUGGER_SUPPORT
+  myTimWrappedOnWrite = myWrappedThisCycle;
+#endif
 
   mySetTimerCycle = mySystem->cycles();
 }
@@ -367,6 +380,9 @@ bool M6532::save(Serializer& out) const
     out.putBool(myWrappedThisCycle);
     out.putLong(myLastCycle);
     out.putLong(mySetTimerCycle);
+  #ifdef DEBUGGER_SUPPORT
+    out.putInt(myTimReadCycles);
+  #endif
 
     out.putByte(myDDRA);
     out.putByte(myDDRB);
@@ -399,6 +415,9 @@ bool M6532::load(Serializer& in)
     myWrappedThisCycle = in.getBool();
     myLastCycle = in.getLong();
     mySetTimerCycle = in.getLong();
+  #ifdef DEBUGGER_SUPPORT
+    myTimReadCycles = in.getInt();
+  #endif
 
     myDDRA = in.getByte();
     myDDRB = in.getByte();
diff --git a/src/emucore/M6532.hxx b/src/emucore/M6532.hxx
index d35877ab8..f0f802135 100644
--- a/src/emucore/M6532.hxx
+++ b/src/emucore/M6532.hxx
@@ -137,6 +137,11 @@ class M6532 : public Device
       @return  The access counters as comma separated string
     */
     string getAccessCounters() const override;
+
+    /**
+      Reset the timer read CPU cycle counter
+    */
+    void resetTimReadCylces() { myTimReadCycles = 0; }
   #endif
 
   private:
@@ -250,6 +255,12 @@ class M6532 : public Device
     std::array<Device::AccessCounter, IO_SIZE * 2>    myIOAccessCounter;
     // The array used to skip the first ZP access tracking
     std::array<uInt8, RAM_SIZE>   myZPAccessDelay;
+
+    // Detect timer being accessed on wraparound
+    bool myTimWrappedOnRead{false};
+    bool myTimWrappedOnWrite{false};
+    // Timer read CPU cycles
+    uInt16 myTimReadCycles{0};
 #endif // DEBUGGER_SUPPORT
 
   private:
diff --git a/src/emucore/MT24LC256.cxx b/src/emucore/MT24LC256.cxx
index b99f2ec2a..ba6d2348b 100644
--- a/src/emucore/MT24LC256.cxx
+++ b/src/emucore/MT24LC256.cxx
@@ -50,17 +50,28 @@ MT24LC256::MT24LC256(const FilesystemNode& eepromfile, const System& system,
     myDataFile(eepromfile)
 {
   // Load the data from an external file (if it exists)
+  bool fileValid = false;
   try
   {
-    // Get length of file; it must be 32768
+    // A valid file must be 32768 bytes; otherwise we create a new one
     if(myDataFile.read(myData) == FLASH_SIZE)
-      myDataFileExists = true;
+      fileValid = true;
   }
   catch(...)
   {
-    myDataFileExists = false;
+    fileValid = false;
   }
 
+  if(!fileValid)
+  {
+    // Work around a bug in XCode 11.2 with -O0 and -O1
+    const uInt8 initialValue = INITIAL_VALUE;
+
+    myData = make_unique<uInt8[]>(FLASH_SIZE);
+    std::fill_n(myData.get(), FLASH_SIZE, initialValue);
+    myDataChanged = true;
+   }
+
   // Then initialize the I2C state
   jpee_init();
 
@@ -71,7 +82,7 @@ MT24LC256::MT24LC256(const FilesystemNode& eepromfile, const System& system,
 MT24LC256::~MT24LC256()
 {
   // Save EEPROM data to external file only when necessary
-  if(!myDataFileExists || myDataChanged)
+  if(myDataChanged)
   {
     try { myDataFile.write(myData, FLASH_SIZE); }
     catch(...) { }
@@ -166,9 +177,6 @@ bool MT24LC256::isPageUsed(uInt32 page) const
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void MT24LC256::jpee_init()
 {
-  // Work around a bug in XCode 11.2 with -O0 and -O1
-  const uInt8 initialValue = INITIAL_VALUE;
-
   jpee_sdat = 1;
   jpee_address = 0;
   jpee_state=0;
@@ -176,8 +184,6 @@ void MT24LC256::jpee_init()
   jpee_pagemask = PAGE_SIZE - 1;
   jpee_smallmode = 0;
   jpee_logmode = -1;
-  if(!myDataFileExists)
-    std::fill_n(myData.get(), FLASH_SIZE, initialValue);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/emucore/MT24LC256.hxx b/src/emucore/MT24LC256.hxx
index 6f51dea26..56c1bf804 100644
--- a/src/emucore/MT24LC256.hxx
+++ b/src/emucore/MT24LC256.hxx
@@ -113,9 +113,6 @@ class MT24LC256
     // The file containing the EEPROM data
     FilesystemNode myDataFile;
 
-    // Indicates if a valid EEPROM data file exists/was successfully loaded
-    bool myDataFileExists{false};
-
     // Indicates if the EEPROM has changed since class invocation
     bool myDataChanged{false};
 
diff --git a/src/emucore/OSystem.cxx b/src/emucore/OSystem.cxx
index 88d546ba2..b8f8842e6 100644
--- a/src/emucore/OSystem.cxx
+++ b/src/emucore/OSystem.cxx
@@ -143,10 +143,15 @@ bool OSystem::create()
   // Get relevant information about the video hardware
   // This must be done before any graphics context is created, since
   // it may be needed to initialize the size of graphical objects
-  try        { myFrameBuffer = MediaFactory::createVideo(*this); }
-  catch(...) { return false; }
-  if(!myFrameBuffer->initialize())
+  try
+  {
+    myFrameBuffer = make_unique<FrameBuffer>(*this);
+    myFrameBuffer->initialize();
+  }
+  catch(...)
+  {
     return false;
+  }
 
   // Create the event handler for the system
   myEventHandler = MediaFactory::createEventHandler(*this);
@@ -185,6 +190,15 @@ bool OSystem::create()
 
   myPropSet->load(myPropertiesFile);
 
+  // Detect serial port for AtariVox-USB
+  // If a previously set port is defined, use it;
+  // otherwise use the first one found (if any)
+  const string& avoxport = mySettings->getString("avoxport");
+  const StringList ports = MediaFactory::createSerialPort()->portNames();
+
+  if(avoxport.empty() && ports.size() > 0)
+    mySettings->setValue("avoxport", ports[0]);
+
   return true;
 }
 
@@ -461,9 +475,9 @@ string OSystem::createConsole(const FilesystemNode& rom, const string& md5sum,
     {
       const string& id = myConsole->cartridge().multiCartID();
       if(id == "")
-        myFrameBuffer->showMessage("New console created");
+        myFrameBuffer->showTextMessage("New console created");
       else
-        myFrameBuffer->showMessage("Multicart " +
+        myFrameBuffer->showTextMessage("Multicart " +
           myConsole->cartridge().detectedType() + ", loading ROM" + id);
     }
     buf << "Game console created:" << endl
@@ -492,7 +506,7 @@ string OSystem::createConsole(const FilesystemNode& rom, const string& md5sum,
       msg << myConsole->leftController().name() << "/" << myConsole->rightController().name()
         << " - " << myConsole->cartridge().detectedType()
         << " - " << myConsole->getFormatString();
-      myFrameBuffer->showMessage(msg.str());
+      myFrameBuffer->showTextMessage(msg.str());
     }
   }
 
@@ -618,11 +632,23 @@ unique_ptr<Console> OSystem::openConsole(const FilesystemNode& romfile, string&
 
     CMDLINE_PROPS_UPDATE("sp", PropType::Console_SwapPorts);
     CMDLINE_PROPS_UPDATE("lc", PropType::Controller_Left);
+    CMDLINE_PROPS_UPDATE("lq1", PropType::Controller_Left1);
+    CMDLINE_PROPS_UPDATE("lq2", PropType::Controller_Left2);
     CMDLINE_PROPS_UPDATE("rc", PropType::Controller_Right);
-    const string& s = mySettings->getString("bc");
-    if(s != "") {
-      props.set(PropType::Controller_Left, s);
-      props.set(PropType::Controller_Right, s);
+    CMDLINE_PROPS_UPDATE("rq1", PropType::Controller_Right1);
+    CMDLINE_PROPS_UPDATE("rq2", PropType::Controller_Right2);
+    const string& bc = mySettings->getString("bc");
+    if(bc != "") {
+      props.set(PropType::Controller_Left, bc);
+      props.set(PropType::Controller_Right, bc);
+    }
+    const string& aq = mySettings->getString("aq");
+    if(aq != "")
+    {
+      props.set(PropType::Controller_Left1, aq);
+      props.set(PropType::Controller_Left2, aq);
+      props.set(PropType::Controller_Right1, aq);
+      props.set(PropType::Controller_Right2, aq);
     }
     CMDLINE_PROPS_UPDATE("cp", PropType::Controller_SwapPaddles);
     CMDLINE_PROPS_UPDATE("ma", PropType::Controller_MouseAxis);
@@ -701,7 +727,7 @@ string OSystem::getROMInfo(const Console& console)
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 float OSystem::frameRate() const
 {
-  return myConsole ? myConsole->getFramerate() : 0;
+  return myConsole ? myConsole->currentFrameRate() : 0;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -749,7 +775,8 @@ double OSystem::dispatchEmulation(EmulationWorker& emulationWorker)
        myDebugger->start(
           dispatchResult.getMessage(),
           dispatchResult.getAddress(),
-          dispatchResult.wasReadTrap()
+          dispatchResult.wasReadTrap(),
+          dispatchResult.getToolTip()
         );
       #endif
 
diff --git a/src/emucore/PointingDevice.cxx b/src/emucore/PointingDevice.cxx
index accf00a04..b48c372a3 100644
--- a/src/emucore/PointingDevice.cxx
+++ b/src/emucore/PointingDevice.cxx
@@ -81,6 +81,7 @@ void PointingDevice::update()
     return;
 
   // Update horizontal direction
+  //cerr << myEvent.get(Event::MouseAxisXMove) << ", " << myHCounterRemainder << endl;
   updateDirection( myEvent.get(Event::MouseAxisXMove), myHCounterRemainder,
       myTrackBallLeft, myTrackBallLinesH, myScanCountH, myFirstScanOffsetH);
 
@@ -89,7 +90,7 @@ void PointingDevice::update()
       myTrackBallDown, myTrackBallLinesV, myScanCountV, myFirstScanOffsetV);
 
   // We allow left and right mouse buttons for fire button
-  setPin(DigitalPin::Six, !getAutoFireState(myEvent.get(Event::JoystickZeroFire) == 0 ||
+  setPin(DigitalPin::Six, !getAutoFireState(myEvent.get(Event::JoystickZeroFire) ||
     myEvent.get(Event::MouseButtonLeftValue) || myEvent.get(Event::MouseButtonRightValue)));
 }
 
diff --git a/src/emucore/Props.cxx b/src/emucore/Props.cxx
index 144955c9c..dfef72a97 100644
--- a/src/emucore/Props.cxx
+++ b/src/emucore/Props.cxx
@@ -51,7 +51,11 @@ void Properties::set(PropType key, const string& value)
       case PropType::Console_TVType:
       case PropType::Console_SwapPorts:
       case PropType::Controller_Left:
+      case PropType::Controller_Left1:
+      case PropType::Controller_Left2:
       case PropType::Controller_Right:
+      case PropType::Controller_Right1:
+      case PropType::Controller_Right2:
       case PropType::Controller_SwapPaddles:
       case PropType::Controller_MouseAxis:
       case PropType::Display_Format:
@@ -249,7 +253,11 @@ void Properties::print() const
        << get(PropType::Console_TVType)         << "|"
        << get(PropType::Console_SwapPorts)      << "|"
        << get(PropType::Controller_Left)        << "|"
+       << get(PropType::Controller_Left1)       << "|"
+       << get(PropType::Controller_Left2)       << "|"
        << get(PropType::Controller_Right)       << "|"
+       << get(PropType::Controller_Right1)      << "|"
+       << get(PropType::Controller_Right2)     << "|"
        << get(PropType::Controller_SwapPaddles) << "|"
        << get(PropType::Controller_PaddlesXCenter) << "|"
        << get(PropType::Controller_PaddlesYCenter) << "|"
@@ -296,7 +304,11 @@ void Properties::printHeader()
        << "Console_TVType|"
        << "Console_SwapPorts|"
        << "Controller_Left|"
+       << "Controller_Left1|"
+       << "Controller_Left2|"
        << "Controller_Right|"
+       << "Controller_Right1|"
+       << "Controller_Right2|"
        << "Controller_SwapPaddles|"
        << "Controller_PaddlesXCenter|"
        << "Controller_PaddlesYCenter|"
@@ -325,7 +337,11 @@ std::array<string, Properties::NUM_PROPS> Properties::ourDefaultProperties =
   "COLOR",  // Console.TVType
   "NO",     // Console.SwapPorts
   "AUTO",   // Controller.Left
+  "",       // Controller.Left1
+  "",       // Controller.Left2
   "AUTO",   // Controller.Right
+  "",       // Controller.Right1
+  "",       // Controller.Right2
   "NO",     // Controller.SwapPaddles
   "0",      // Controller.PaddlesXCenter
   "0",      // Controller.PaddlesYCenter
@@ -353,7 +369,11 @@ std::array<string, Properties::NUM_PROPS> Properties::ourPropertyNames =
   "Console.TVType",
   "Console.SwapPorts",
   "Controller.Left",
+  "Controller.Left1",
+  "Controller.Left2",
   "Controller.Right",
+  "Controller.Right1",
+  "Controller.Right2",
   "Controller.SwapPaddles",
   "Controller.PaddlesXCenter",
   "Controller.PaddlesYCenter",
diff --git a/src/emucore/Props.hxx b/src/emucore/Props.hxx
index 70e9fa727..8f280312c 100644
--- a/src/emucore/Props.hxx
+++ b/src/emucore/Props.hxx
@@ -35,7 +35,11 @@ enum class PropType : uInt8 {
   Console_TVType,
   Console_SwapPorts,
   Controller_Left,
+  Controller_Left1,
+  Controller_Left2,
   Controller_Right,
+  Controller_Right1,
+  Controller_Right2,
   Controller_SwapPaddles,
   Controller_PaddlesXCenter,
   Controller_PaddlesYCenter,
diff --git a/src/emucore/QuadTari.cxx b/src/emucore/QuadTari.cxx
new file mode 100644
index 000000000..f3fb00cdf
--- /dev/null
+++ b/src/emucore/QuadTari.cxx
@@ -0,0 +1,162 @@
+//============================================================================
+//
+//   SSSS    tt          lll  lll
+//  SS  SS   tt           ll   ll
+//  SS     tttttt  eeee   ll   ll   aaaa
+//   SSSS    tt   ee  ee  ll   ll      aa
+//      SS   tt   eeeeee  ll   ll   aaaaa  --  "An Atari 2600 VCS Emulator"
+//  SS  SS   tt   ee      ll   ll  aa  aa
+//   SSSS     ttt  eeeee llll llll  aaaaa
+//
+// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
+// and the Stella Team
+//
+// See the file "License.txt" for information on usage and redistribution of
+// this file, and for a DISCLAIMER OF ALL WARRANTIES.
+//============================================================================
+
+#include "OSystem.hxx"
+#include "EventHandler.hxx"
+#include "Event.hxx"
+#include "Console.hxx"
+#include "System.hxx"
+#include "TIA.hxx"
+#include "FrameBuffer.hxx"
+#include "AtariVox.hxx"
+#include "Driving.hxx"
+#include "Joystick.hxx"
+#include "Paddles.hxx"
+#include "SaveKey.hxx"
+#include "QuadTari.hxx"
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+QuadTari::QuadTari(Jack jack, const OSystem& osystem, const System& system, const Properties& properties)
+  : Controller(jack, osystem.eventHandler().event(), system,
+               Controller::Type::QuadTari),
+    myOSystem(osystem),
+    myProperties(properties)
+{
+  Controller::Type firstType = Controller::Type::Joystick,
+    secondType = Controller::Type::Joystick;
+  string first, second;
+
+  if(jack == Controller::Jack::Left)
+  {
+    first = properties.get(PropType::Controller_Left1);
+    second = properties.get(PropType::Controller_Left2);
+  }
+  else
+  {
+    first = properties.get(PropType::Controller_Right1);
+    second = properties.get(PropType::Controller_Right2);
+  }
+
+  if(!first.empty())
+    firstType = Controller::getType(first);
+  if(!second.empty())
+    secondType = Controller::getType(second);
+
+  myFirstController = addController(firstType, false);
+  mySecondController = addController(secondType, true);
+
+  // QuadTari auto detection setting
+  setPin(AnalogPin::Five, MIN_RESISTANCE);
+  setPin(AnalogPin::Nine, MAX_RESISTANCE);
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+unique_ptr<Controller> QuadTari::addController(const Controller::Type type, bool second)
+{
+  FilesystemNode nvramfile = myOSystem.nvramDir();
+  Controller::onMessageCallback callback = [&os = myOSystem](const string& msg) {
+    bool devSettings = os.settings().getBool("dev.settings");
+    if(os.settings().getBool(devSettings ? "dev.eepromaccess" : "plr.eepromaccess"))
+      os.frameBuffer().showTextMessage(msg);
+  };
+
+  switch(type)
+  {
+    case Controller::Type::Paddles:
+    {
+      // Check if we should swap the paddles plugged into a jack
+      bool swapPaddles = myProperties.get(PropType::Controller_SwapPaddles) == "YES";
+
+      return make_unique<Paddles>(myJack, myEvent, mySystem, swapPaddles, false, false);
+    }
+    case Controller::Type::Driving:
+      return make_unique<Driving>(myJack, myEvent, mySystem, second);
+
+    case Controller::Type::AtariVox:
+    {
+      nvramfile /= "atarivox_eeprom.dat";
+      return make_unique<AtariVox>(myJack, myEvent, mySystem,
+                                   myOSystem.settings().getString("avoxport"),
+                                   nvramfile, callback); // no alternative mapping here
+    }
+    case Controller::Type::SaveKey:
+    {
+      nvramfile /= "savekey_eeprom.dat";
+      return make_unique<SaveKey>(myJack, myEvent, mySystem,
+                                  nvramfile, callback); // no alternative mapping here
+    }
+    default:
+      // fall back to good old Joystick
+      return make_unique<Joystick>(myJack, myEvent, mySystem, second);
+  }
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool QuadTari::read(DigitalPin pin)
+{
+  // We need to override the Controller::read() method, since the QuadTari
+  // can switch the controller multiple times per frame
+  // (we can't just read 60 times per second in the ::update() method)
+
+  constexpr int MIN_CYCLES = 76; // minimal cycles required for stable input switch (just to be safe)
+  bool readFirst;
+
+  if(mySystem.tia().dumpPortsCycles() < MIN_CYCLES)
+    // Random controller if read too soon after dump ports changed
+    readFirst = mySystem.randGenerator().next() % 2;
+  else
+    // If bit 7 of VBlank is not set, read first, else second controller
+    readFirst = !(mySystem.tia().registerValue(VBLANK) & 0x80);
+
+  if(readFirst)
+    return myFirstController->read(pin);
+  else
+    return mySecondController->read(pin);
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void QuadTari::update()
+{
+  myFirstController->update();
+  mySecondController->update();
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+string QuadTari::name() const
+{
+  return "QuadTari (" + myFirstController->name() + "/" + mySecondController->name() + ")";
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool QuadTari::isAnalog() const
+{
+  // For now, use mouse for first controller only
+  return myFirstController->isAnalog();
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool QuadTari::setMouseControl(
+    Controller::Type xtype, int xid, Controller::Type ytype, int yid)
+{
+  // Use mouse for first controller only
+  if(xtype == Controller::Type::QuadTari && ytype == Controller::Type::QuadTari)
+    return myFirstController->setMouseControl(myFirstController->type(), xid,
+                                              myFirstController->type(), yid);
+  else
+    // required for creating the MouseControl mode list
+    return myFirstController->setMouseControl(xtype, xid, ytype, yid);
+}
diff --git a/src/emucore/QuadTari.hxx b/src/emucore/QuadTari.hxx
new file mode 100644
index 000000000..2ce42e319
--- /dev/null
+++ b/src/emucore/QuadTari.hxx
@@ -0,0 +1,108 @@
+//============================================================================
+//
+//   SSSS    tt          lll  lll
+//  SS  SS   tt           ll   ll
+//  SS     tttttt  eeee   ll   ll   aaaa
+//   SSSS    tt   ee  ee  ll   ll      aa
+//      SS   tt   eeeeee  ll   ll   aaaaa  --  "An Atari 2600 VCS Emulator"
+//  SS  SS   tt   ee      ll   ll  aa  aa
+//   SSSS     ttt  eeeee llll llll  aaaaa
+//
+// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
+// and the Stella Team
+//
+// See the file "License.txt" for information on usage and redistribution of
+// this file, and for a DISCLAIMER OF ALL WARRANTIES.
+//============================================================================
+
+#ifndef QUADTARI_HXX
+#define QUADTARI_HXX
+
+class Controller;
+class Event;
+
+/**
+  The QuadTari controller.
+
+  @author  Thomas Jentzsch
+*/
+class QuadTari : public Controller
+{
+  friend class QuadTariWidget;
+  public:
+    /**
+      Create a QuadTari controller plugged into the specified jack
+
+      @param jack       The jack the controller is plugged into
+      @param osystem    The OSystem object to use
+      @param system     The system using this controller
+      @param properties The properties to use for the current ROM
+    */
+    QuadTari(Jack jack, const OSystem& osystem, const System& system, const Properties& properties);
+    ~QuadTari() override = default;
+
+  public:
+     using Controller::read;
+
+    /**
+      Read the value of the specified digital pin for this controller.
+
+      @param pin The pin of the controller jack to read
+      @return The state of the pin
+    */
+    bool read(DigitalPin pin) override;
+
+    /**
+      Update the entire digital and analog pin state according to the
+      events currently set.
+    */
+    void update() override;
+
+    /**
+      Returns the name of this controller.
+    */
+    string name() const override;
+
+    /**
+      Answers whether the controller is intrinsically an analog controller.
+      Depends on the attached controllers.
+    */
+    bool isAnalog() const override;
+
+    /**
+      Determines how this controller will treat values received from the
+      X/Y axis and left/right buttons of the mouse.  Since not all controllers
+      use the mouse the same way (or at all), it's up to the specific class to
+      decide how to use this data.
+
+      In the current implementation, the left button is tied to the X axis,
+      and the right one tied to the Y axis.
+
+      @param xtype  The controller to use for x-axis data
+      @param xid    The controller ID to use for x-axis data (-1 for no id)
+      @param ytype  The controller to use for y-axis data
+      @param yid    The controller ID to use for y-axis data (-1 for no id)
+
+      @return  Whether the controller supports using the mouse
+    */
+    bool setMouseControl(
+      Controller::Type xtype, int xid, Controller::Type ytype, int yid) override;
+
+  private:
+    unique_ptr<Controller> addController(const Controller::Type type, bool second);
+
+    const OSystem& myOSystem;
+    const Properties& myProperties;
+    unique_ptr<Controller> myFirstController;
+    unique_ptr<Controller> mySecondController;
+
+  private:
+    // Following constructors and assignment operators not supported
+    QuadTari() = delete;
+    QuadTari(const QuadTari&) = delete;
+    QuadTari(QuadTari&&) = delete;
+    QuadTari& operator=(const QuadTari&) = delete;
+    QuadTari& operator=(QuadTari&&) = delete;
+  };
+
+#endif
diff --git a/src/emucore/SerialPort.hxx b/src/emucore/SerialPort.hxx
index 5525a51c7..8736d14cd 100644
--- a/src/emucore/SerialPort.hxx
+++ b/src/emucore/SerialPort.hxx
@@ -65,6 +65,13 @@ class SerialPort
     */
     virtual bool isCTS() { return true; }
 
+    /**
+      Get all valid serial ports detected on this system.
+
+      @return  The (possibly empty) list of detected serial ports
+    */
+    virtual StringList portNames() { return StringList{}; }
+
   private:
     // Following constructors and assignment operators not supported
     SerialPort(const SerialPort&) = delete;
diff --git a/src/emucore/Serializer.cxx b/src/emucore/Serializer.cxx
index 80282bdc2..7f94dced2 100644
--- a/src/emucore/Serializer.cxx
+++ b/src/emucore/Serializer.cxx
@@ -91,6 +91,8 @@ void Serializer::rewind()
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 size_t Serializer::size() const
 {
+  myStream->seekp(0, std::ios::end);
+
   return myStream->tellp();
 }
 
diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx
index e9d0de8c8..a074f5697 100644
--- a/src/emucore/Settings.cxx
+++ b/src/emucore/Settings.cxx
@@ -57,10 +57,18 @@ Settings::Settings()
   setPermanent("tia.fs_overscan", "0");
   setPermanent("tia.vsizeadjust", 0);
   setPermanent("tia.dbgcolors", "roygpb");
+  setPermanent("tia.correct_aspect", "true");
   // Palette options
   setPermanent("palette", PaletteHandler::SETTING_STANDARD);
   setPermanent("pal.phase_ntsc", "26.2");
   setPermanent("pal.phase_pal", "31.3");
+  setPermanent("pal.red_scale", "0.0");
+  setPermanent("pal.green_scale", "0.0");
+  setPermanent("pal.blue_scale", "0.0");
+  setPermanent("pal.red_shift", "0.0");
+  setPermanent("pal.green_shift", "0.0");
+  setPermanent("pal.blue_shift", "0.0");
+
   setPermanent("pal.contrast", "0.0");
   setPermanent("pal.brightness", "0.0");
   setPermanent("pal.hue", "0.0");
@@ -137,6 +145,7 @@ Settings::Settings()
   setPermanent("launcherres", Common::Size(900, 600));
   setPermanent("launcherfont", "medium");
   setPermanent("launcherroms", "true");
+  setPermanent("launchersubdirs", "false");
   setPermanent("romviewer", "1");
   setPermanent("lastrom", "");
 
@@ -414,16 +423,24 @@ void Settings::usage() const
     << "  -center       <1|0>          Centers game window in windowed modes\n"
     << "  -windowedpos  <XxY>          Sets the window position in windowed emulator mode\n"
     << "  -display      <number>       Sets the display for Stella's emulator\n"
-    << "  -palette      <standard|     Use the specified color palette\n"
-    << "                 z26|user|\n"
-    << "                 custom>\n"
-    << "  -pal.phase_ntsc <number>      Phase shift for NTSC 'custom' palette\n"
-    << "  -pal.phase_pal  <number>      Phase shift for PAL 'custom' palette\n"
-    << "  -pal.hue        <-1.0 - 1.0>  Adjust hue for current palette\n"
-    << "  -pal.saturation <-1.0 - 1.0>  Adjust saturation of current palette\n"
-    << "  -pal.contrast   <-1.0 - 1.0>  Adjust contrast of current palette\n"
-    << "  -pal.brightness <-1.0 - 1.0>  Adjust brightness of current palette\n"
-    << "  -pal.gamma      <-1.0 - 1.0>  Adjust gamma of current palette\n"
+    << endl
+    << "  -palette        <standard|     Use the specified color palette\n"
+    << "                   z26|user|\n"
+    << "                   custom>\n"
+    << "  -pal.phase_ntsc  <number>      Phase shift for NTSC 'custom' palette\n"
+    << "  -pal.phase_pal   <number>      Phase shift for PAL 'custom' palette\n"
+    << "  -pal.red_scale   <-1.0 - 1.0>  Adjust red scale for 'custom' palette\n"
+    << "  -pal.red_shift   <-1.0 - 1.0>  Adjust red shift for 'custom' palette\n"
+    << "  -pal.green_scale <-1.0 - 1.0>  Adjust green scale for 'custom' palette\n"
+    << "  -pal.green_shift <-1.0 - 1.0>  Adjust green shift for 'custom' palette\n"
+    << "  -pal.blue_scale  <-1.0 - 1.0>  Adjust blue scale for 'custom' palette\n"
+    << "  -pal.blue_shift  <-1.0 - 1.0>  Adjust blue shift for 'custom' palette\n"
+    << "  -pal.hue         <-1.0 - 1.0>  Adjust hue for current palette\n"
+    << "  -pal.saturation  <-1.0 - 1.0>  Adjust saturation of current palette\n"
+    << "  -pal.contrast    <-1.0 - 1.0>  Adjust contrast of current palette\n"
+    << "  -pal.brightness  <-1.0 - 1.0>  Adjust brightness of current palette\n"
+    << "  -pal.gamma       <-1.0 - 1.0>  Adjust gamma of current palette\n"
+    << endl
     << "  -speed        <number>       Run emulation at the given speed\n"
     << "  -turbo        <1|0>          Enable 'Turbo' mode for maximum emulation speed\n"
     << "  -uimessages   <1|0>          Show onscreen UI messages for different events\n"
@@ -453,6 +470,7 @@ void Settings::usage() const
     << "  -tia.fs_overscan <0-10>       Add overscan to TIA image in fullscreen mode\n"
     << "  -tia.dbgcolors   <string>     Debug colors to use for each object (see manual\n"
     << "                                 for description)\n"
+    << "  -tia.correct_aspect <1|0>     Enable aspect ratio correct scaling\n"
     << endl
     << "  -tv.filter    <0-5>           Set TV effects off (0) or to specified mode\n"
     << "                                 (1-5)\n"
@@ -525,6 +543,7 @@ void Settings::usage() const
     << "                 large12|large14|\n"
     << "                 large16>\n"
     << "  -launcherroms <1|0>          Show only ROMs in the launcher (vs. all files)\n"
+    << "  -launchersubdirs <1|0>       Show files from subdirectories too\n"
     << "  -romviewer    <float>        Show ROM info viewer at given zoom level in ROM\n"
     << "                                launcher (use 0 for off)\n"
     << "  -followlauncher <0|1>        Default ROM path follows launcher navigation\n"
diff --git a/src/emucore/TIASurface.cxx b/src/emucore/TIASurface.cxx
index 781ca203a..ec9dfe020 100644
--- a/src/emucore/TIASurface.cxx
+++ b/src/emucore/TIASurface.cxx
@@ -27,19 +27,19 @@
 #include "TIASurface.hxx"
 
 namespace {
-  FrameBuffer::ScalingInterpolation interpolationModeFromSettings(const Settings& settings)
+  ScalingInterpolation interpolationModeFromSettings(const Settings& settings)
   {
 #ifdef RETRON77
   // Witv TV / and or scanline interpolation, the image has a height of ~480px. THe R77 runs at 720p, so there
   // is no benefit from QIS in y-direction. In addition, QIS on the R77 has performance issues if TV effects are
   // enabled.
   return settings.getBool("tia.inter") || settings.getInt("tv.filter") != 0
-    ? FrameBuffer::ScalingInterpolation::blur
-    : FrameBuffer::ScalingInterpolation::sharp;
+    ? ScalingInterpolation::blur
+    : ScalingInterpolation::sharp;
 #else
     return settings.getBool("tia.inter") ?
-      FrameBuffer::ScalingInterpolation::blur :
-      FrameBuffer::ScalingInterpolation::sharp;
+      ScalingInterpolation::blur :
+      ScalingInterpolation::sharp;
 #endif
   }
 }
@@ -56,7 +56,9 @@ TIASurface::TIASurface(OSystem& system)
   myTiaSurface = myFB.allocateSurface(
     AtariNTSC::outWidth(TIAConstants::frameBufferWidth),
     TIAConstants::frameBufferHeight,
-    interpolationModeFromSettings(myOSystem.settings())
+    !correctAspect()
+      ? ScalingInterpolation::none
+      : interpolationModeFromSettings(myOSystem.settings())
   );
 
   // Generate scanline data, and a pre-defined scanline surface
@@ -89,14 +91,14 @@ TIASurface::~TIASurface()
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void TIASurface::initialize(const Console& console,
-                            const FrameBuffer::VideoMode& mode)
+                            const VideoModeHandler::Mode& mode)
 {
   myTIA = &(console.tia());
 
-  myTiaSurface->setDstPos(mode.image.x(), mode.image.y());
-  myTiaSurface->setDstSize(mode.image.w(), mode.image.h());
-  mySLineSurface->setDstPos(mode.image.x(), mode.image.y());
-  mySLineSurface->setDstSize(mode.image.w(), mode.image.h());
+  myTiaSurface->setDstPos(mode.imageR.x(), mode.imageR.y());
+  myTiaSurface->setDstSize(mode.imageR.w(), mode.imageR.h());
+  mySLineSurface->setDstPos(mode.imageR.x(), mode.imageR.y());
+  mySLineSurface->setDstSize(mode.imageR.w(), mode.imageR.h());
 
   myPaletteHandler->setPalette();
 
@@ -165,7 +167,6 @@ uInt32 TIASurface::mapIndexedPixel(uInt8 indexedColor, uInt8 shift) const
   return myPalette[indexedColor | shift];
 }
 
-
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void TIASurface::setNTSC(NTSCFilter::Preset preset, bool show)
 {
@@ -183,7 +184,7 @@ void TIASurface::setNTSC(NTSCFilter::Preset preset, bool show)
   }
   myOSystem.settings().setValue("tv.filter", int(preset));
 
-  if(show) myFB.showMessage(buf.str());
+  if(show) myFB.showTextMessage(buf.str());
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -220,7 +221,7 @@ void TIASurface::setNTSCAdjustable(int direction)
 
   setNTSC(NTSCFilter::Preset::CUSTOM);
   ntsc().selectAdjustable(direction, text, valueText, value);
-  myOSystem.frameBuffer().showMessage(text, valueText, value);
+  myOSystem.frameBuffer().showGaugeMessage(text, valueText, value);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -231,7 +232,7 @@ void TIASurface::changeNTSCAdjustable(int adjustable, int direction)
 
   setNTSC(NTSCFilter::Preset::CUSTOM);
   ntsc().changeAdjustable(adjustable, direction, text, valueText, newValue);
-  myOSystem.frameBuffer().showMessage(text, valueText, newValue);
+  myOSystem.frameBuffer().showGaugeMessage(text, valueText, newValue);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -242,7 +243,7 @@ void TIASurface::changeCurrentNTSCAdjustable(int direction)
 
   setNTSC(NTSCFilter::Preset::CUSTOM);
   ntsc().changeCurrentAdjustable(direction, text, valueText, newValue);
-  myOSystem.frameBuffer().showMessage(text, valueText, newValue);
+  myOSystem.frameBuffer().showGaugeMessage(text, valueText, newValue);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -258,7 +259,7 @@ void TIASurface::setScanlineIntensity(int direction)
     buf << intensity << "%";
   else
     buf << "Off";
-  myFB.showMessage("Scanline intensity", buf.str(), intensity);
+  myFB.showGaugeMessage("Scanline intensity", buf.str(), intensity);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -312,8 +313,8 @@ void TIASurface::enableNTSC(bool enable)
 string TIASurface::effectsInfo() const
 {
   const FBSurface::Attributes& attr = mySLineSurface->attributes();
-
   ostringstream buf;
+
   switch(myFilter)
   {
     case Filter::Normal:
@@ -326,12 +327,12 @@ string TIASurface::effectsInfo() const
       buf << myNTSCFilter.getPreset() << ", scanlines=" << attr.blendalpha;
       break;
     case Filter::BlarggPhosphor:
-      buf << myNTSCFilter.getPreset() << ", phosphor, scanlines="
-          << attr.blendalpha;
+      buf << myNTSCFilter.getPreset() << ", phosphor, scanlines=" << attr.blendalpha;
       break;
   }
 
   buf << ", inter=" << (myOSystem.settings().getBool("tia.inter") ? "enabled" : "disabled");
+  buf << ", aspect correction=" << (correctAspect() ? "enabled" : "disabled");
 
   return buf.str();
 }
@@ -510,8 +511,16 @@ void TIASurface::renderForSnapshot()
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void TIASurface::updateSurfaceSettings()
 {
-  myTiaSurface->setScalingInterpolation(interpolationModeFromSettings(myOSystem.settings()));
+  myTiaSurface->setScalingInterpolation(
+      interpolationModeFromSettings(myOSystem.settings())
+  );
   mySLineSurface->setScalingInterpolation(
       interpolationModeFromSettings(myOSystem.settings())
   );
 }
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool TIASurface::correctAspect() const
+{
+  return myOSystem.settings().getBool("tia.correct_aspect");
+}
diff --git a/src/emucore/TIASurface.hxx b/src/emucore/TIASurface.hxx
index 2b6213785..013fd6deb 100644
--- a/src/emucore/TIASurface.hxx
+++ b/src/emucore/TIASurface.hxx
@@ -54,7 +54,7 @@ class TIASurface
     /**
       Set the TIA object, which is needed for actually rendering the TIA image.
     */
-    void initialize(const Console& console, const FrameBuffer::VideoMode& mode);
+    void initialize(const Console& console, const VideoModeHandler::Mode& mode);
 
     /**
       Set the palette for TIA rendering.  This currently consists of two
@@ -67,7 +67,8 @@ class TIASurface
       @param rgb_palette  The RGB components of the palette, needed for
                           calculating a phosphor palette
     */
-    void setPalette(const PaletteArray& tia_palette, const PaletteArray& rgb_palette);
+    void setPalette(const PaletteArray& tia_palette,
+                    const PaletteArray& rgb_palette);
 
     /**
       Get a TIA surface that has no post-processing whatsoever.  This is
@@ -77,6 +78,11 @@ class TIASurface
     */
     const FBSurface& baseSurface(Common::Rect& rect) const;
 
+    /**
+      Get a underlying FBSurface that the TIA is being rendered into.
+    */
+    const FBSurface& tiaSurface() const { return *myTiaSurface; }
+
     /**
       Use the palette to map a single indexed pixel color. This is used by the
       TIA output widget.
@@ -183,13 +189,10 @@ class TIASurface
     */
     uInt32 averageBuffers(uInt32 bufOfs);
 
+    // Is plain video mode enabled?
+    bool correctAspect() const;
+
   private:
-    OSystem& myOSystem;
-    FrameBuffer& myFB;
-    TIA* myTIA{nullptr};
-
-    shared_ptr<FBSurface> myTiaSurface, mySLineSurface, myBaseTiaSurface;
-
     // Enumeration created such that phosphor off/on is in LSB,
     // and Blargg off/on is in MSB
     enum class Filter: uInt8 {
@@ -200,6 +203,13 @@ class TIASurface
     };
     Filter myFilter{Filter::Normal};
 
+  private:
+    OSystem& myOSystem;
+    FrameBuffer& myFB;
+    TIA* myTIA{nullptr};
+
+    shared_ptr<FBSurface> myTiaSurface, mySLineSurface, myBaseTiaSurface;
+
     // NTSC object to use in TIA rendering mode
     NTSCFilter myNTSCFilter;
 
diff --git a/src/emucore/Thumbulator.cxx b/src/emucore/Thumbulator.cxx
index 2984159cd..bfb835fd5 100644
--- a/src/emucore/Thumbulator.cxx
+++ b/src/emucore/Thumbulator.cxx
@@ -53,17 +53,21 @@ using Common::Base;
 #endif
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Thumbulator::Thumbulator(const uInt16* rom_ptr, uInt16* ram_ptr, uInt16 rom_size,
+Thumbulator::Thumbulator(const uInt16* rom_ptr, uInt16* ram_ptr, uInt32 rom_size,
+                         const uInt32 c_base, const uInt32 c_start, const uInt32 c_stack,
                          bool traponfatal, Thumbulator::ConfigureFor configurefor,
                          Cartridge* cartridge)
   : rom(rom_ptr),
     romSize(rom_size),
+    cBase(c_base),
+    cStart(c_start),
+    cStack(c_stack),
     decodedRom(make_unique<Op[]>(romSize / 2)),  // NOLINT
     ram(ram_ptr),
     configuration(configurefor),
     myCartridge(cartridge)
 {
-  for(uInt16 i = 0; i < romSize / 2; ++i)
+  for(uInt32 i = 0; i < romSize / 2; ++i)
     decodedRom[i] = decodeInstructionWord(CONV_RAMROM(rom[i]));
 
   setConsoleTiming(ConsoleTiming::ntsc);
@@ -217,7 +221,7 @@ uInt32 Thumbulator::fetch16(uInt32 addr)
 void Thumbulator::write16(uInt32 addr, uInt32 data)
 {
 #ifndef UNSAFE_OPTIMIZATIONS
-  if((addr > 0x40001fff) && (addr < 0x50000000))
+  if((addr > 0x40007fff) && (addr < 0x50000000))
     fatalError("write16", addr, "abort - out of range");
 
   if (isProtected(addr)) fatalError("write16", addr, "to driver area");
@@ -376,6 +380,7 @@ bool Thumbulator::isProtected(uInt32 addr)
       return  (addr < 0x0800) && (addr > 0x0028) && !((addr >= 0x00a0) && (addr < (0x00a0 + 284)));
 
     case ConfigureFor::CDFJ:
+    case ConfigureFor::CDFJplus:
       return  (addr < 0x0800) && (addr > 0x0028) && !((addr >= 0x0098) && (addr < (0x0098 + 292)));
 
     case ConfigureFor::BUS:
@@ -391,9 +396,9 @@ uInt32 Thumbulator::read16(uInt32 addr)
 {
   uInt32 data;
 #ifndef UNSAFE_OPTIMIZATIONS
-  if((addr > 0x40001fff) && (addr < 0x50000000))
+  if((addr > 0x40007fff) && (addr < 0x50000000))
     fatalError("read16", addr, "abort - out of range");
-  else if((addr > 0x7fff) && (addr < 0x10000000))
+  else if((addr > 0x0007ffff) && (addr < 0x10000000))
     fatalError("read16", addr, "abort - out of range");
   if(addr & 1)
     fatalError("read16", addr, "abort - misaligned");
@@ -1424,6 +1429,7 @@ int Thumbulator::execute()
 
           case ConfigureFor::CDF1:
           case ConfigureFor::CDFJ:
+          case ConfigureFor::CDFJplus:
             // this subroutine interface is used in the CDF driver,
             // it starts at address 0x00000750
             // _SetNote:
@@ -2521,25 +2527,10 @@ int Thumbulator::execute()
 int Thumbulator::reset()
 {
   reg_norm.fill(0);
-  reg_norm[13] = 0x40001FB4;
 
-  switch(configuration)
-  {
-    // future 2K Harmony/Melody drivers will most likely use these settings
-    case ConfigureFor::BUS:
-    case ConfigureFor::CDF:
-    case ConfigureFor::CDF1:
-    case ConfigureFor::CDFJ:
-      reg_norm[14] = 0x00000800; // Link Register
-      reg_norm[15] = 0x0000080B; // Program Counter
-      break;
-
-    // future 3K Harmony/Melody drivers will most likely use these settings
-    case ConfigureFor::DPCplus:
-      reg_norm[14] = 0x00000C00; // Link Register
-      reg_norm[15] = 0x00000C0B; // Program Counter
-      break;
-  }
+  reg_norm[13] = cStack;              // SP
+  reg_norm[14] = cBase;               // LR
+  reg_norm[15] = (cStart + 2) | 1;    // PC (+2 for pipeline, lower bit for THUMB)
 
   cpsr = mamcr = 0;
   handler_mode = false;
diff --git a/src/emucore/Thumbulator.hxx b/src/emucore/Thumbulator.hxx
index ae62d1755..6713ee5c6 100644
--- a/src/emucore/Thumbulator.hxx
+++ b/src/emucore/Thumbulator.hxx
@@ -35,11 +35,11 @@ class Cartridge;
   #define NO_THUMB_STATS
 #endif
 
-#define ROMADDMASK 0x7FFF
-#define RAMADDMASK 0x1FFF
+#define ROMADDMASK 0x7FFFF
+#define RAMADDMASK 0x7FFF
 
-#define ROMSIZE (ROMADDMASK+1)
-#define RAMSIZE (RAMADDMASK+1)
+#define ROMSIZE (ROMADDMASK+1)      // 512KB
+#define RAMSIZE (RAMADDMASK+1)      // 32KB
 
 #define CPSR_N (1u<<31)
 #define CPSR_Z (1u<<30)
@@ -55,11 +55,13 @@ class Thumbulator
       BUS,      // cartridges of type BUS
       CDF,      // cartridges of type CDF
       CDF1,     // cartridges of type CDF version 1
-      CDFJ,     // cartrdiges of type CDFJ
+      CDFJ,     // cartridges of type CDFJ
+      CDFJplus, // cartridges of type CDFJ+
       DPCplus   // cartridges of type DPC+
     };
 
-    Thumbulator(const uInt16* rom_ptr, uInt16* ram_ptr, uInt16 rom_size,
+    Thumbulator(const uInt16* rom_ptr, uInt16* ram_ptr, uInt32 rom_size,
+                const uInt32 c_base, const uInt32 c_start, const uInt32 c_stack,
                 bool traponfatal, Thumbulator::ConfigureFor configurefor,
                 Cartridge* cartridge);
 
@@ -186,10 +188,12 @@ class Thumbulator
 
   private:
     const uInt16* rom{nullptr};
-    uInt16 romSize{0};
+    uInt32 romSize{0};
+    uInt32 cBase{0};
+    uInt32 cStart{0};
+    uInt32 cStack{0};
     const unique_ptr<Op[]> decodedRom;  // NOLINT
     uInt16* ram{nullptr};
-
     std::array<uInt32, 16> reg_norm; // normal execution mode, do not have a thread mode
     uInt32 cpsr{0}, mamcr{0};
     bool handler_mode{false};
diff --git a/src/emucore/module.mk b/src/emucore/module.mk
index 71bd33847..b7d88d331 100644
--- a/src/emucore/module.mk
+++ b/src/emucore/module.mk
@@ -1,95 +1,96 @@
 MODULE := src/emucore
 
 MODULE_OBJS := \
-	src/emucore/AtariVox.o \
-	src/emucore/Bankswitch.o \
-	src/emucore/Booster.o \
-	src/emucore/Cart.o \
-	src/emucore/CartCreator.o \
-	src/emucore/CartDetector.o \
-	src/emucore/CartEnhanced.o \
-	src/emucore/Cart0840.o \
-	src/emucore/Cart2K.o \
-	src/emucore/Cart3E.o \
-	src/emucore/Cart3EPlus.o \
-	src/emucore/Cart3EX.o \
-	src/emucore/Cart3F.o \
-	src/emucore/Cart4A50.o \
-	src/emucore/Cart4K.o \
-	src/emucore/Cart4KSC.o \
-	src/emucore/CartAR.o \
-	src/emucore/CartBUS.o \
-	src/emucore/CartCDF.o \
-	src/emucore/CartCM.o \
-	src/emucore/CartCTY.o \
-	src/emucore/CartCV.o \
-	src/emucore/CartDPC.o \
-	src/emucore/CartDPCPlus.o \
-	src/emucore/CartE0.o \
-	src/emucore/CartMNetwork.o \
-	src/emucore/CartE7.o \
-	src/emucore/CartE78K.o \
-	src/emucore/CartEF.o \
-	src/emucore/CartEFSC.o \
-	src/emucore/CartBF.o \
-	src/emucore/CartBFSC.o \
-	src/emucore/CartDF.o \
-	src/emucore/CartDFSC.o \
-	src/emucore/CartF0.o \
-	src/emucore/CartF4.o \
-	src/emucore/CartF4SC.o \
-	src/emucore/CartF6.o \
-	src/emucore/CartF6SC.o \
-	src/emucore/CartF8.o \
-	src/emucore/CartF8SC.o \
-	src/emucore/CartFA.o \
-	src/emucore/CartFA2.o \
-	src/emucore/CartFC.o \
-	src/emucore/CartFE.o \
-	src/emucore/CartMDM.o \
-	src/emucore/CartSB.o \
-	src/emucore/CartTVBoy.o \
-	src/emucore/CartUA.o \
-	src/emucore/CartWD.o \
-	src/emucore/CartX07.o \
-	src/emucore/CompuMate.o \
-	src/emucore/Console.o \
-	src/emucore/Control.o \
-	src/emucore/ControllerDetector.o \
-	src/emucore/DispatchResult.o \
-	src/emucore/Driving.o \
-	src/emucore/EventHandler.o \
-	src/emucore/EmulationTiming.o \
-	src/emucore/EmulationWorker.o \
-	src/emucore/FrameBuffer.o \
-	src/emucore/FBSurface.o \
-	src/emucore/FSNode.o \
-	src/emucore/Genesis.o \
-	src/emucore/Joystick.o \
-	src/emucore/Keyboard.o \
-	src/emucore/KidVid.o \
-	src/emucore/Lightgun.o \
-	src/emucore/MindLink.o \
-	src/emucore/M6502.o \
-	src/emucore/M6532.o \
-	src/emucore/MT24LC256.o \
-	src/emucore/MD5.o \
-	src/emucore/OSystem.o \
-	src/emucore/Paddles.o \
-	src/emucore/PointingDevice.o \
-	src/emucore/ProfilingRunner.o \
-	src/emucore/Props.o \
-	src/emucore/PropsSet.o \
-	src/emucore/SaveKey.o \
-	src/emucore/Serializer.o \
-	src/emucore/Settings.o \
-	src/emucore/Switches.o \
-	src/emucore/System.o \
-	src/emucore/TIASurface.o \
-	src/emucore/Thumbulator.o
+        src/emucore/AtariVox.o \
+        src/emucore/Bankswitch.o \
+        src/emucore/Booster.o \
+        src/emucore/Cart.o \
+        src/emucore/CartCreator.o \
+        src/emucore/CartDetector.o \
+        src/emucore/CartEnhanced.o \
+        src/emucore/Cart0840.o \
+        src/emucore/Cart2K.o \
+        src/emucore/Cart3E.o \
+        src/emucore/Cart3EPlus.o \
+        src/emucore/Cart3EX.o \
+        src/emucore/Cart3F.o \
+        src/emucore/Cart4A50.o \
+        src/emucore/Cart4K.o \
+        src/emucore/Cart4KSC.o \
+        src/emucore/CartAR.o \
+        src/emucore/CartBUS.o \
+        src/emucore/CartCDF.o \
+        src/emucore/CartCM.o \
+        src/emucore/CartCTY.o \
+        src/emucore/CartCV.o \
+        src/emucore/CartDPC.o \
+        src/emucore/CartDPCPlus.o \
+        src/emucore/CartE0.o \
+        src/emucore/CartMNetwork.o \
+        src/emucore/CartE7.o \
+        src/emucore/CartE78K.o \
+        src/emucore/CartEF.o \
+        src/emucore/CartEFSC.o \
+        src/emucore/CartBF.o \
+        src/emucore/CartBFSC.o \
+        src/emucore/CartDF.o \
+        src/emucore/CartDFSC.o \
+        src/emucore/CartF0.o \
+        src/emucore/CartF4.o \
+        src/emucore/CartF4SC.o \
+        src/emucore/CartF6.o \
+        src/emucore/CartF6SC.o \
+        src/emucore/CartF8.o \
+        src/emucore/CartF8SC.o \
+        src/emucore/CartFA.o \
+        src/emucore/CartFA2.o \
+        src/emucore/CartFC.o \
+        src/emucore/CartFE.o \
+        src/emucore/CartMDM.o \
+        src/emucore/CartSB.o \
+        src/emucore/CartTVBoy.o \
+        src/emucore/CartUA.o \
+        src/emucore/CartWD.o \
+        src/emucore/CartX07.o \
+        src/emucore/CompuMate.o \
+        src/emucore/Console.o \
+        src/emucore/Control.o \
+        src/emucore/ControllerDetector.o \
+        src/emucore/DispatchResult.o \
+        src/emucore/Driving.o \
+        src/emucore/EventHandler.o \
+        src/emucore/EmulationTiming.o \
+        src/emucore/EmulationWorker.o \
+        src/emucore/FrameBuffer.o \
+        src/emucore/FBSurface.o \
+        src/emucore/FSNode.o \
+        src/emucore/Genesis.o \
+        src/emucore/Joystick.o \
+        src/emucore/Keyboard.o \
+        src/emucore/KidVid.o \
+        src/emucore/Lightgun.o \
+        src/emucore/MindLink.o \
+        src/emucore/M6502.o \
+        src/emucore/M6532.o \
+        src/emucore/MT24LC256.o \
+        src/emucore/MD5.o \
+        src/emucore/OSystem.o \
+        src/emucore/Paddles.o \
+        src/emucore/PointingDevice.o \
+        src/emucore/ProfilingRunner.o \
+        src/emucore/Props.o \
+        src/emucore/PropsSet.o \
+        src/emucore/QuadTari.o \
+        src/emucore/SaveKey.o \
+        src/emucore/Serializer.o \
+        src/emucore/Settings.o \
+        src/emucore/Switches.o \
+        src/emucore/System.o \
+        src/emucore/TIASurface.o \
+        src/emucore/Thumbulator.o
 
 MODULE_DIRS += \
-	src/emucore
+        src/emucore
 
 # Include common rules
 include $(srcdir)/common.rules
diff --git a/src/emucore/tia/TIA.cxx b/src/emucore/tia/TIA.cxx
index 7e4cdbf04..3ae0713c3 100644
--- a/src/emucore/tia/TIA.cxx
+++ b/src/emucore/tia/TIA.cxx
@@ -17,6 +17,7 @@
 
 #include "TIA.hxx"
 #include "M6502.hxx"
+#include "M6532.hxx"
 #include "Control.hxx"
 #include "Paddles.hxx"
 #include "DelayQueueIteratorImpl.hxx"
@@ -162,7 +163,10 @@ void TIA::initialize()
 
   myDelayQueue.reset();
 
+#ifdef DEBUGGER_SUPPORT
   myCyclesAtFrameStart = 0;
+  myFrameWsyncCycles = 0;
+#endif
 
   if (myFrameManager)
     myFrameManager->reset();
@@ -278,7 +282,10 @@ bool TIA::save(Serializer& out) const
 
     out.putByteArray(myShadowRegisters.data(), myShadowRegisters.size());
 
+  #ifdef DEBUGGER_SUPPORT
     out.putLong(myCyclesAtFrameStart);
+    out.putLong(myFrameWsyncCycles);
+  #endif
 
     out.putInt(myFrameBufferScanlines);
     out.putInt(myFrontBufferScanlines);
@@ -350,7 +357,10 @@ bool TIA::load(Serializer& in)
 
     in.getByteArray(myShadowRegisters.data(), myShadowRegisters.size());
 
+  #ifdef DEBUGGER_SUPPORT
     myCyclesAtFrameStart = in.getLong();
+    myFrameWsyncCycles = in.getLong();
+  #endif
 
     myFrameBufferScanlines = in.getInt();
     myFrontBufferScanlines = in.getInt();
@@ -523,6 +533,7 @@ bool TIA::poke(uInt16 address, uInt8 value)
 
       for (PaddleReader& paddleReader : myPaddleReaders)
         paddleReader.vblank(value, myTimestamp);
+      updateDumpPorts(value);
 
       myDelayQueue.push(VBLANK, value, Delay::vblank);
 
@@ -1303,6 +1314,10 @@ void TIA::updateEmulation()
 void TIA::onFrameStart()
 {
   myXAtRenderingStart = 0;
+#ifdef DEBUGGER_SUPPORT
+  myFrameWsyncCycles = 0;
+  mySystem->m6532().resetTimReadCylces();
+#endif
 
   // Check for colour-loss emulation
   if (myColorLossEnabled)
@@ -1328,7 +1343,9 @@ void TIA::onFrameStart()
 void TIA::onFrameComplete()
 {
   mySystem->m6502().stop();
+#ifdef DEBUGGER_SUPPORT
   myCyclesAtFrameStart = mySystem->cycles();
+#endif
 
   if (myXAtRenderingStart > 0)
     std::fill_n(myBackBuffer.begin(), myXAtRenderingStart, 0);
@@ -1350,6 +1367,9 @@ void TIA::onHalt()
 {
   mySubClock += (TIAConstants::H_CLOCKS - myHctr) % TIAConstants::H_CLOCKS;
   mySystem->incrementCycles(mySubClock / TIAConstants::CYCLE_CLOCKS);
+#ifdef DEBUGGER_SUPPORT
+  myFrameWsyncCycles += 3 + mySubClock / TIAConstants::CYCLE_CLOCKS;
+#endif
   mySubClock %= TIAConstants::CYCLE_CLOCKS;
 }
 
@@ -1981,6 +2001,24 @@ void TIA::toggleCollBLPF()
   myCollisionMask ^= (CollisionMask::ball & CollisionMask::playfield);
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void TIA::updateDumpPorts(uInt8 value)
+{
+  bool newIsDumped = value & 0x80;
+
+  if(myArePortsDumped != newIsDumped)
+  {
+    myArePortsDumped = newIsDumped;
+    myDumpPortsTimestamp = myTimestamp;
+  }
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Int64 TIA::dumpPortsCycles()
+{
+  return (myTimestamp - myDumpPortsTimestamp) / 3;
+}
+
 #ifdef DEBUGGER_SUPPORT
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void TIA::createAccessArrays()
diff --git a/src/emucore/tia/TIA.hxx b/src/emucore/tia/TIA.hxx
index ada06a042..4d959e3b0 100644
--- a/src/emucore/tia/TIA.hxx
+++ b/src/emucore/tia/TIA.hxx
@@ -322,6 +322,7 @@ class TIA : public Device
     */
     uInt64 cycles() const { return uInt64(mySystem->cycles()); }
 
+  #ifdef DEBUGGER_SUPPORT
     /**
       Answers the frame count from the start of the emulation.
     */
@@ -334,6 +335,21 @@ class TIA : public Device
       return uInt32(mySystem->cycles() - myCyclesAtFrameStart);
     }
 
+    /**
+      Answers the system cycles used by WSYNC from the start of the current frame.
+    */
+    uInt32 frameWSyncCycles() const {
+      return uInt32(myFrameWsyncCycles);
+    }
+  #endif // DEBUGGER_SUPPORT
+
+    /**
+     * Get the CPU cycles since the last dump ports change.
+     *
+     * @return  The number of CPU cycles since the last dump ports change
+    */
+    Int64 dumpPortsCycles();
+
     /**
       Answers whether the TIA is currently in being rendered
       (we're in between the start and end of drawing a frame).
@@ -546,7 +562,7 @@ class TIA : public Device
       @return  The access counters as comma separated string
     */
     string getAccessCounters() const override;
-  #endif
+  #endif // DEBUGGER_SUPPORT
 
   private:
     /**
@@ -695,6 +711,13 @@ class TIA : public Device
      */
     void applyDeveloperSettings();
 
+    /**
+     * Updates the dump ports state with the time of change.
+     *
+     * @param value  The value to be stored at VBLANK
+    */
+    void updateDumpPorts(uInt8 value);
+
   #ifdef DEBUGGER_SUPPORT
     void createAccessArrays();
 
@@ -894,6 +917,16 @@ class TIA : public Device
      */
     uInt64 myTimestamp{0};
 
+    /**
+     * The number of CPU clocks since the last dump ports state change.
+     */
+    uInt64 myDumpPortsTimestamp{0};
+
+    /**
+     * The current dump ports state.
+    */
+    bool myArePortsDumped{false};
+
     /**
      * The "shadow registers" track the last written register value for the
      * debugger.
@@ -910,11 +943,18 @@ class TIA : public Device
 
     std::array<uInt32, 16> myColorCounts;
 
+  #ifdef DEBUGGER_SUPPORT
     /**
      * System cycles at the end of the previous frame / beginning of next frame.
      */
     uInt64 myCyclesAtFrameStart{0};
 
+    /**
+     * System cycles used by WSYNC during current frame.
+     */
+    uInt64 myFrameWsyncCycles{0};
+  #endif // DEBUGGER_SUPPORT
+
     /**
      * The frame manager can change during our lifetime, so we buffer those two.
      */
diff --git a/src/gui/AboutDialog.cxx b/src/gui/AboutDialog.cxx
index db088d923..426adbeeb 100644
--- a/src/gui/AboutDialog.cxx
+++ b/src/gui/AboutDialog.cxx
@@ -67,11 +67,12 @@ AboutDialog::AboutDialog(OSystem& osystem, DialogContainer& parent,
   addCancelWidget(b);
 
   xpos = HBORDER;  ypos = _th + VBORDER + (buttonHeight - fontHeight) / 2;
-  myTitle = new StaticTextWidget(this, font, xpos, ypos, _w - xpos * 2, fontHeight,
-                                 "", TextAlign::Center);
+  int bwidth = font.getStringWidth("What's New" + ELLIPSIS) + fontWidth * 2.5;
+
+  myTitle = new StaticTextWidget(this, font, xpos + bwidth, ypos, _w - (xpos + bwidth) * 2,
+                                 fontHeight, "", TextAlign::Center);
   myTitle->setTextColor(kTextColorEm);
 
-  int bwidth = font.getStringWidth("What's New" + ELLIPSIS) + fontWidth * 2.5;
   myWhatsNewButton =
     new ButtonWidget(this, font, _w - HBORDER - bwidth, ypos - (buttonHeight - fontHeight) / 2,
                      bwidth, buttonHeight, "What's New" + ELLIPSIS, kWhatsNew);
diff --git a/src/gui/CheckListWidget.cxx b/src/gui/CheckListWidget.cxx
index 0e5a46d82..13afb335a 100644
--- a/src/gui/CheckListWidget.cxx
+++ b/src/gui/CheckListWidget.cxx
@@ -29,8 +29,8 @@ CheckListWidget::CheckListWidget(GuiObject* boss, const GUI::Font& font,
 
   // rowheight is determined by largest item on a line,
   // possibly meaning that number of rows will change
-  _fontHeight = std::max(_fontHeight, CheckboxWidget::boxSize(_font));
-  _rows = h / _fontHeight;
+  _lineHeight = std::max(_lineHeight, CheckboxWidget::boxSize(_font));
+  _rows = h / _lineHeight;
 
   // Create a CheckboxWidget for each row in the list
   for(int i = 0; i < _rows; ++i)
@@ -40,26 +40,12 @@ CheckListWidget::CheckListWidget(GuiObject* boss, const GUI::Font& font,
     t->setTextColor(kTextColor);
     t->setTarget(this);
     t->setID(i);
-    ypos += _fontHeight;
+    ypos += _lineHeight;
 
     _checkList.push_back(t);
   }
 }
 
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void CheckListWidget::handleMouseEntered()
-{
-  setFlags(Widget::FLAG_HILITED);
-  setDirty();
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void CheckListWidget::handleMouseLeft()
-{
-  clearFlags(Widget::FLAG_HILITED);
-  setDirty();
-}
-
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void CheckListWidget::setList(const StringList& list, const BoolArray& state)
 {
@@ -95,7 +81,6 @@ void CheckListWidget::drawWidget(bool hilite)
 {
 //cerr << "CheckListWidget::drawWidget\n";
   FBSurface& s = _boss->dialog().surface();
-  bool onTop = _boss->dialog().isOnTop();
   int i, pos, len = int(_list.size());
 
   // Draw a thin frame around the list and to separate columns
@@ -110,7 +95,7 @@ void CheckListWidget::drawWidget(bool hilite)
     _checkList[i]->setDirty();
     _checkList[i]->draw();
 
-    const int y = _y + 2 + _fontHeight * i + 2;
+    const int y = _y + 2 + _lineHeight * i + 2;
     ColorId textColor = kTextColor;
 
     Common::Rect r(getEditRect());
@@ -120,40 +105,41 @@ void CheckListWidget::drawWidget(bool hilite)
     {
       if(_hasFocus && !_editMode)
       {
-        s.fillRect(_x + r.x() - 3, _y + 1 + _fontHeight * i,
-                   _w - r.x(), _fontHeight, kTextColorHi);
+        s.fillRect(_x + r.x() - 3, _y + 1 + _lineHeight * i,
+                   _w - r.x(), _lineHeight, kTextColorHi);
         textColor = kTextColorInv;
       }
       else
-        s.frameRect(_x + r.x() - 3, _y + 1 + _fontHeight * i,
-                    _w - r.x(), _fontHeight, onTop ? kTextColorHi : kColor);
+        s.frameRect(_x + r.x() - 3, _y + 1 + _lineHeight * i,
+                    _w - r.x(), _lineHeight, kTextColorHi);
     }
 
     if (_selectedItem == pos && _editMode)
     {
       adjustOffset();
-      s.drawString(_font, editString(), _x + r.x(), y, r.w(), onTop ? kTextColor : kColor,
+      s.drawString(_font, editString(), _x + r.x(), y, r.w(), kTextColor,
                    TextAlign::Left, -_editScrollOffset, false);
     }
     else
-      s.drawString(_font, _list[pos], _x + r.x(), y, r.w(),
-                   onTop ? textColor : kColor);
+      s.drawString(_font, _list[pos], _x + r.x(), y, r.w(), textColor);
   }
 
   // Only draw the caret while editing, and if it's in the current viewport
-  if(_editMode && (_selectedItem >= _scrollBar->_currentPos) &&
-    (_selectedItem < _scrollBar->_currentPos + _rows))
-    drawCaret();
+  if(_editMode &&
+     (!_useScrollbar ||
+     ((_selectedItem >= _scrollBar->_currentPos) &&
+      (_selectedItem < _scrollBar->_currentPos + _rows))))
+    drawCaretSelection();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Common::Rect CheckListWidget::getEditRect() const
 {
-  const int yoffset = (_selectedItem - _currentPos) * _fontHeight,
+  const int yoffset = (_selectedItem - _currentPos) * _lineHeight,
             xoffset = CheckboxWidget::boxSize(_font) + 10;
 
   return Common::Rect(2 + xoffset, 1 + yoffset,
-                      _w - (xoffset - 15), _fontHeight + yoffset);
+                      _w - (xoffset - 15), _lineHeight + yoffset);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/gui/CheckListWidget.hxx b/src/gui/CheckListWidget.hxx
index 625875a9d..2ebec0d5d 100644
--- a/src/gui/CheckListWidget.hxx
+++ b/src/gui/CheckListWidget.hxx
@@ -42,10 +42,6 @@ class CheckListWidget : public ListWidget
     bool getState(int line);
     bool getSelectedState() { return getState(_selectedItem); }
 
-  protected:
-    void handleMouseEntered() override;
-    void handleMouseLeft() override;
-
   private:
     bool handleEvent(Event::Type e) override;
     void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
diff --git a/src/gui/ColorWidget.cxx b/src/gui/ColorWidget.cxx
index 27f4bc3cf..94ef4bbf4 100644
--- a/src/gui/ColorWidget.cxx
+++ b/src/gui/ColorWidget.cxx
@@ -37,15 +37,27 @@ ColorWidget::ColorWidget(GuiObject* boss, const GUI::Font& font,
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void ColorWidget::setColor(ColorId color)
 {
-  _color = color;
-  setDirty();
+  if(_color != color)
+  {
+    _color = color;
+    setDirty();
+  }
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void ColorWidget::setCrossed(bool enable)
+{
+  if(_crossGrid != enable)
+  {
+    _crossGrid = enable;
+    setDirty();
+  }
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void ColorWidget::drawWidget(bool hilite)
 {
   FBSurface& s = dialog().surface();
-  bool onTop = _boss->dialog().isOnTop();
 
   if(_framed)
   {
@@ -53,11 +65,11 @@ void ColorWidget::drawWidget(bool hilite)
     s.frameRect(_x, _y, _w, _h + 1, kColor);
 
     // Show the currently selected color
-    s.fillRect(_x + 1, _y + 1, _w - 2, _h - 1, onTop ? isEnabled() ? _color : kWidColor : kBGColorLo);
+    s.fillRect(_x + 1, _y + 1, _w - 2, _h - 1, isEnabled() ? _color : kWidColor);
   }
   else
   {
-    s.fillRect(_x, _y, _w, _h, onTop ? isEnabled() ? _color : kWidColor : kBGColorLo);
+    s.fillRect(_x, _y, _w, _h, isEnabled() ? _color : kWidColor);
   }
 
   // Cross out the grid?
diff --git a/src/gui/ColorWidget.hxx b/src/gui/ColorWidget.hxx
index 4d39871fa..0ec099a95 100644
--- a/src/gui/ColorWidget.hxx
+++ b/src/gui/ColorWidget.hxx
@@ -42,7 +42,7 @@ class ColorWidget : public Widget, public CommandSender
     void setColor(ColorId color);
     ColorId getColor() const { return _color;  }
 
-    void setCrossed(bool enable) { _crossGrid = enable; }
+    void setCrossed(bool enable);
 
   protected:
     void drawWidget(bool hilite) override;
diff --git a/src/gui/ContextMenu.cxx b/src/gui/ContextMenu.cxx
index 41f049ba2..ae1ee09be 100644
--- a/src/gui/ContextMenu.cxx
+++ b/src/gui/ContextMenu.cxx
@@ -77,7 +77,7 @@ void ContextMenu::show(uInt32 x, uInt32 y, const Common::Rect& bossRect, int ite
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void ContextMenu::center()
+void ContextMenu::setPosition()
 {
   // First set position according to original coordinates
   surface().setDstPos(_xorig, _yorig);
@@ -346,8 +346,12 @@ int ContextMenu::findItem(int x, int y) const
 void ContextMenu::drawCurrentSelection(int item)
 {
   // Change selection
-  _selectedOffset = item;
-  setDirty();
+  if(_selectedOffset != item)
+  {
+    _selectedOffset = item;
+    cerr << "ContextMenu" << endl;
+    setDirty();
+  }
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -621,5 +625,5 @@ void ContextMenu::drawDialog()
     s.drawBitmap(_downImg, ((_w-_x)>>1)-4, (_rowHeight>>1)+y-4, _scrollDnColor, _arrowSize);
   }
 
-  setDirty();
+  clearDirty();
 }
diff --git a/src/gui/ContextMenu.hxx b/src/gui/ContextMenu.hxx
index 423ef3074..6807635ba 100644
--- a/src/gui/ContextMenu.hxx
+++ b/src/gui/ContextMenu.hxx
@@ -45,6 +45,8 @@ class ContextMenu : public Dialog, public CommandSender
                 const VariantList& items, int cmd = 0, int width = 0);
     ~ContextMenu() override = default;
 
+    bool isShading() const override { return false; }
+
     /** Set the parent widget's ID */
     void setID(uInt32 id) { _id = id; }
 
@@ -71,8 +73,8 @@ class ContextMenu : public Dialog, public CommandSender
     const string& getSelectedName() const;
     const Variant& getSelectedTag() const;
 
-    /** This dialog uses its own positioning, so we override Dialog::center() */
-    void center() override;
+    /** This dialog uses its own positioning, so we override Dialog::setPosition() */
+    void setPosition() override;
 
     /** The following methods are used when we want to select *and*
         send a command for the new selection.  They are only to be used
diff --git a/src/gui/DeveloperDialog.cxx b/src/gui/DeveloperDialog.cxx
index 6406e33d5..31443e1bf 100644
--- a/src/gui/DeveloperDialog.cxx
+++ b/src/gui/DeveloperDialog.cxx
@@ -115,10 +115,11 @@ void DeveloperDialog::addEmulationTab(const GUI::Font& font)
                                           "Console info overlay");
   wid.push_back(myFrameStatsWidget);
 
-
   myDetectedInfoWidget = new CheckboxWidget(myTab, font,
                                             myFrameStatsWidget->getRight() + fontWidth * 2.5, ypos + 1,
                                             "Detected settings info");
+  myDetectedInfoWidget->setToolTip("Display detected controllers, bankswitching\n"
+                                   "and TV types at ROM start.");
   wid.push_back(myDetectedInfoWidget);
   ypos += lineHeight + VGAP;
 
@@ -131,6 +132,8 @@ void DeveloperDialog::addEmulationTab(const GUI::Font& font)
 
   myConsoleWidget = new PopUpWidget(myTab, font, HBORDER + INDENT * 1, ypos, pwidth, lineHeight, items,
                                     "Console ", lwidth, kConsole);
+  myConsoleWidget->setToolTip("Emulate Color/B&W/Pause key and zero\n"
+                              "page RAM initialization differenly.");
   wid.push_back(myConsoleWidget);
   ypos += lineHeight + VGAP;
 
@@ -141,6 +144,8 @@ void DeveloperDialog::addEmulationTab(const GUI::Font& font)
 
   myRandomBankWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 2, ypos + 1,
                                           "Random startup bank");
+  myRandomBankWidget->setToolTip("Randomize the startup bank for\n"
+                                 "most classic bankswitching types.");
   wid.push_back(myRandomBankWidget);
   ypos += lineHeight + VGAP;
 
@@ -154,11 +159,12 @@ void DeveloperDialog::addEmulationTab(const GUI::Font& font)
   myRandomizeCPULabel = new StaticTextWidget(myTab, font, HBORDER + INDENT * 2, ypos + 1, "Randomize CPU ");
   wid.push_back(myRandomizeCPULabel);
 
+  const std::array<string, 5> cpuregsLabels = {"SP", "A", "X", "Y", "PS"};
   int xpos = myRandomizeCPULabel->getRight() + fontWidth * 1.25;
   for(int i = 0; i < 5; ++i)
   {
     myRandomizeCPUWidget[i] = new CheckboxWidget(myTab, font, xpos, ypos + 1,
-                                           ourCPUregs[i], kRandCPUID);
+                                           cpuregsLabels[i], kRandCPUID);
     wid.push_back(myRandomizeCPUWidget[i]);
     xpos += CheckboxWidget::boxSize(font) + font.getStringWidth("XX") + fontWidth * 2.5;
   }
@@ -167,17 +173,23 @@ void DeveloperDialog::addEmulationTab(const GUI::Font& font)
   // How to handle undriven TIA pins
   myUndrivenPinsWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1,
                                             "Drive unused TIA pins randomly on a read/peek");
+  myUndrivenPinsWidget->setToolTip("Read TIA pins random instead of last databus values.\n"
+                                   "Helps detecting missing '#' for immediate loads.");
   wid.push_back(myUndrivenPinsWidget);
   ypos += lineHeight + VGAP;
 
 #ifdef DEBUGGER_SUPPORT
   myRWPortBreakWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1,
                                            "Break on reads from write ports");
+  myRWPortBreakWidget->setToolTip("Cause reads from write ports to interrupt\n"
+                                  "emulation and enter debugger.");
   wid.push_back(myRWPortBreakWidget);
   ypos += lineHeight + VGAP;
 
   myWRPortBreakWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1,
                                            "Break on writes to read ports");
+  myWRPortBreakWidget->setToolTip("Cause writes to read ports to interrupt\n"
+                                  "emulation and enter debugger.");
   wid.push_back(myWRPortBreakWidget);
   ypos += lineHeight + VGAP;
 #endif
@@ -185,12 +197,16 @@ void DeveloperDialog::addEmulationTab(const GUI::Font& font)
   // Thumb ARM emulation exception
   myThumbExceptionWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1,
                                               "Fatal ARM emulation error throws exception");
+  myThumbExceptionWidget->setToolTip("Cause Thumb ARM emulation to throw exceptions\n"
+                                     "on fatal errors and enter the debugger.");
   wid.push_back(myThumbExceptionWidget);
   ypos += lineHeight + VGAP;
 
   // AtariVox/SaveKey EEPROM access
   myEEPROMAccessWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1,
                                             "Display AtariVox/SaveKey EEPROM R/W access");
+  myEEPROMAccessWidget->setToolTip("Cause message display when AtariVox/\n"
+                                   "SaveKey EEPROM is read or written.");
   wid.push_back(myEEPROMAccessWidget);
 
   // Add items for tab 0
@@ -238,11 +254,15 @@ void DeveloperDialog::addTiaTab(const GUI::Font& font)
   VarList::push_back(items, "Custom", "custom");
   myTIATypeWidget = new PopUpWidget(myTab, font, HBORDER + INDENT, ypos - 1,
                                     pwidth, lineHeight, items, "Chip type ", 0, kTIAType);
+  myTIATypeWidget->setToolTip("Select which TIA chip type to emulate.\n"
+                              "Some types cause defined glitches.");
   wid.push_back(myTIATypeWidget);
   ypos += lineHeight + VGAP * 1;
 
   myInvPhaseLabel = new StaticTextWidget(myTab, font, HBORDER + INDENT * 2, ypos + 1,
                                          "Inverted HMOVE clock phase for");
+  myInvPhaseLabel->setToolTip("Objects react different to too\n"
+                              "early HM" + ELLIPSIS + " after HMOVE changes.");
   wid.push_back(myInvPhaseLabel);
   ypos += lineHeight + VGAP * 1;
 
@@ -261,6 +281,7 @@ void DeveloperDialog::addTiaTab(const GUI::Font& font)
 
   myPlayfieldLabel = new StaticTextWidget(myTab, font, HBORDER + INDENT * 2, ypos + 1,
                                          "Delayed playfield");
+  myPlayfieldLabel->setToolTip("Playfield reacts one color clock slower to updates.");
   wid.push_back(myPlayfieldLabel);
   ypos += lineHeight + VGAP * 1;
 
@@ -274,6 +295,7 @@ void DeveloperDialog::addTiaTab(const GUI::Font& font)
 
   myBackgroundLabel = new StaticTextWidget(myTab, font, HBORDER + INDENT * 2, ypos + 1,
                                           "Delayed background");
+  myBackgroundLabel->setToolTip("Background color reacts one color clock slower to updates.");
   wid.push_back(myBackgroundLabel);
   ypos += lineHeight + VGAP * 1;
 
@@ -284,6 +306,7 @@ void DeveloperDialog::addTiaTab(const GUI::Font& font)
   ostringstream ss;
   ss << "Delayed VDEL" << ELLIPSIS << " swap for";
   mySwapLabel = new StaticTextWidget(myTab, font, HBORDER + INDENT * 2, ypos + 1, ss.str());
+  mySwapLabel->setToolTip("VDELed objects react one color clock slower to updates.");
   wid.push_back(mySwapLabel);
   ypos += lineHeight + VGAP * 1;
 
@@ -331,12 +354,14 @@ void DeveloperDialog::addVideoTab(const GUI::Font& font)
   // TV jitter effect
   myTVJitterWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1,
                                         "Jitter/roll effect", kTVJitter);
+  myTVJitterWidget->setToolTip("Enable to emulate TV loss of sync.");
   wid.push_back(myTVJitterWidget);
   myTVJitterRecWidget = new SliderWidget(myTab, font,
                                          myTVJitterWidget->getRight() + fontWidth * 3, ypos - 1,
                                          "Recovery ", 0, kTVJitterChanged);
   myTVJitterRecWidget->setMinValue(1); myTVJitterRecWidget->setMaxValue(20);
   myTVJitterRecWidget->setTickmarkIntervals(5);
+  myTVJitterRecWidget->setToolTip("Define speed of sync recovery.");
   wid.push_back(myTVJitterRecWidget);
   myTVJitterRecLabelWidget = new StaticTextWidget(myTab, font,
                                                   myTVJitterRecWidget->getRight() + 4,
@@ -346,6 +371,8 @@ void DeveloperDialog::addVideoTab(const GUI::Font& font)
 
   myColorLossWidget = new CheckboxWidget(myTab, font, HBORDER + INDENT * 1, ypos + 1,
                                          "PAL color-loss");
+  myColorLossWidget->setToolTip("PAL games with odd scanline count\n"
+                                "will be displayed without color.");
   wid.push_back(myColorLossWidget);
   ypos += lineHeight + VGAP;
 
@@ -484,6 +511,7 @@ void DeveloperDialog::addTimeMachineTab(const GUI::Font& font)
 #endif
   myStateSizeWidget->setStepValue(20);
   myStateSizeWidget->setTickmarkIntervals(5);
+  myStateSizeWidget->setToolTip("Define the total Time Machine buffer size.");
   wid.push_back(myStateSizeWidget);
   ypos += lineHeight + VGAP;
 
@@ -497,6 +525,9 @@ void DeveloperDialog::addTimeMachineTab(const GUI::Font& font)
 #endif
   myUncompressedWidget->setStepValue(20);
   myUncompressedWidget->setTickmarkIntervals(5);
+  myUncompressedWidget->setToolTip("Define the number of completely kept states.\n"
+                                   "States beyond this number will be slowly removed\n"
+                                   "to fit the requested horizon into the buffer.");
   wid.push_back(myUncompressedWidget);
   ypos += lineHeight + VGAP;
 
@@ -506,6 +537,7 @@ void DeveloperDialog::addTimeMachineTab(const GUI::Font& font)
   int pwidth = font.getStringWidth("10 seconds");
   myStateIntervalWidget = new PopUpWidget(myTab, font, xpos, ypos, pwidth,
                                           lineHeight, items, "Interval          ", 0, kIntervalChanged);
+  myStateIntervalWidget->setToolTip("Define the interval between each saved state.");
   wid.push_back(myStateIntervalWidget);
   ypos += lineHeight + VGAP;
 
@@ -514,6 +546,8 @@ void DeveloperDialog::addTimeMachineTab(const GUI::Font& font)
     VarList::push_back(items, HORIZONS[i], HOR_SETTINGS[i]);
   myStateHorizonWidget = new PopUpWidget(myTab, font, xpos, ypos, pwidth,
                                          lineHeight, items, "Horizon         ~ ", 0, kHorizonChanged);
+  myStateHorizonWidget->setToolTip("Define how far the Time Machine\n"
+                                   "will allow moving back in time.");
   wid.push_back(myStateHorizonWidget);
 
   // Add message concerning usage
@@ -597,6 +631,7 @@ void DeveloperDialog::addDebuggerTab(const GUI::Font& font)
 
   myGhostReadsTrapWidget = new CheckboxWidget(myTab, font, HBORDER, ypos + 1,
                                              "Trap on 'ghost' reads");
+  myGhostReadsTrapWidget->setToolTip("Traps will consider CPU 'ghost' reads too.");
   wid.push_back(myGhostReadsTrapWidget);
 
   // Add message concerning usage
@@ -751,9 +786,11 @@ void DeveloperDialog::getWidgetStates(SettingsSet set)
   myRandomBank[set] = myRandomBankWidget->getState();
   myRandomizeRAM[set] = myRandomizeRAMWidget->getState();
   string cpurandom;
+  const std::array<string, 5> cpuregs = {"S", "A", "X", "Y", "P"};
+
   for(int i = 0; i < 5; ++i)
     if(myRandomizeCPUWidget[i]->getState())
-      cpurandom += ourCPUregs[i];
+      cpurandom += cpuregs[i];
   myRandomizeCPU[set] = cpurandom;
   // Undriven TIA pins
   myUndrivenPins[set] = myUndrivenPinsWidget->getState();
@@ -805,8 +842,10 @@ void DeveloperDialog::setWidgetStates(SettingsSet set)
   myRandomizeRAMWidget->setState(myRandomizeRAM[set]);
 
   const string& cpurandom = myRandomizeCPU[set];
+  const std::array<string, 5> cpuregs = {"S", "A", "X", "Y", "P"};
+
   for(int i = 0; i < 5; ++i)
-    myRandomizeCPUWidget[i]->setState(BSPF::containsIgnoreCase(cpurandom, ourCPUregs[i]));
+    myRandomizeCPUWidget[i]->setState(BSPF::containsIgnoreCase(cpurandom, cpuregs[i]));
   // Undriven TIA pins
   myUndrivenPinsWidget->setState(myUndrivenPins[set]);
 #ifdef DEBUGGER_SUPPORT
@@ -1531,8 +1570,3 @@ void DeveloperDialog::handleFontSize()
     myDebuggerHeightSlider->setValue(minH);
 #endif
 }
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-const std::array<string, 5> DeveloperDialog::ourCPUregs = {
-  "SP", "A", "X", "Y", "PS"
-};
diff --git a/src/gui/DeveloperDialog.hxx b/src/gui/DeveloperDialog.hxx
index f66d58378..e3d31ecfd 100644
--- a/src/gui/DeveloperDialog.hxx
+++ b/src/gui/DeveloperDialog.hxx
@@ -184,8 +184,6 @@ class DeveloperDialog : public Dialog
     std::array<string, 2> myStateInterval;
     std::array<string, 2> myStateHorizon;
 
-    static const std::array<string, 5> ourCPUregs;
-
   private:
     void addEmulationTab(const GUI::Font& font);
     void addTimeMachineTab(const GUI::Font& font);
diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx
index 7c1d7ecd5..f49dede63 100644
--- a/src/gui/Dialog.cxx
+++ b/src/gui/Dialog.cxx
@@ -27,6 +27,7 @@
 #include "Dialog.hxx"
 #include "Widget.hxx"
 #include "TabWidget.hxx"
+#include "ToolTip.hxx"
 
 #include "ContextMenu.hxx"
 #include "PopUpWidget.hxx"
@@ -49,10 +50,24 @@ Dialog::Dialog(OSystem& instance, DialogContainer& parent, const GUI::Font& font
                const string& title, int x, int y, int w, int h)
   : GuiObject(instance, parent, *this, x, y, w, h),
     _font(font),
-    _title(title),
-    _flags(Widget::FLAG_ENABLED | Widget::FLAG_BORDER | Widget::FLAG_CLEARBG)
+    _title(title)
 {
+  _flags = Widget::FLAG_ENABLED | Widget::FLAG_BORDER | Widget::FLAG_CLEARBG;
   setTitle(title);
+
+  // Create shading surface
+  uInt32 data = 0xff000000;
+
+  _shadeSurface = instance.frameBuffer().allocateSurface(
+      1, 1, ScalingInterpolation::sharp, &data);
+
+  FBSurface::Attributes& attr = _shadeSurface->attributes();
+
+  attr.blending = true;
+  attr.blendalpha = 25; // darken background dialogs by 25%
+  _shadeSurface->applyAttributes();
+
+  _toolTip = make_unique<ToolTip>(*this, font);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -91,7 +106,7 @@ void Dialog::open()
   const uInt32 scale = instance().frameBuffer().hidpiScaleFactor();
   _surface->setDstSize(_w * scale, _h * scale);
 
-  center();
+  setPosition();
 
   if(_myTabList.size())
     // (Re)-build the focus list to use for all widgets of all tabs
@@ -110,8 +125,6 @@ void Dialog::open()
   loadConfig(); // has to be done AFTER (re)building the focus list
 
   _visible = true;
-
-  setDirty();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -128,7 +141,6 @@ void Dialog::close()
   _visible = false;
 
   parent().removeDialog();
-  setDirty();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -144,11 +156,36 @@ void Dialog::setTitle(const string& title)
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void Dialog::center()
+void Dialog::setPosition()
 {
   positionAt(instance().settings().getInt("dialogpos"));
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void Dialog::setDirty()
+{
+  _dirty = true;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void Dialog::setDirtyChain()
+{
+  _dirtyChain = true;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void Dialog::tick()
+{
+  // Recursively tick dialog and all child dialogs and widgets
+  Widget* w = _firstWidget;
+
+  while(w)
+  {
+    w->tick();
+    w = w->_next;
+  }
+}
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void Dialog::positionAt(uInt32 pos)
 {
@@ -190,26 +227,49 @@ void Dialog::positionAt(uInt32 pos)
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-bool Dialog::render()
+void Dialog::redraw(bool force)
 {
-  if(!_dirty || !isVisible())
-    return false;
+  if(!isVisible())
+    return;
+
+  if(force)
+    setDirty();
 
   // Draw this dialog
-  center();
+  setPosition();
   drawDialog();
+  // full rendering is caused in dialog container
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void Dialog::render()
+{
+  //cerr << "  render " << typeid(*this).name() << endl;
 
   // Update dialog surface; also render any extra surfaces
   // Extra surfaces must be rendered afterwards, so they are drawn on top
   if(_surface->render())
   {
-    mySurfaceStack.applyAll([](shared_ptr<FBSurface>& surface){
+    mySurfaceStack.applyAll([](shared_ptr<FBSurface>& surface) {
       surface->render();
     });
   }
-  _dirty = false;
 
-  return true;
+  // A dialog is still on top if a non-shading dialog (e.g. ContextMenu)
+  // is opended above it.
+  bool onTop = parent().myDialogStack.top() == this
+    || (parent().myDialogStack.get(parent().myDialogStack.size() - 2) == this
+        && !parent().myDialogStack.top()->isShading());
+
+  if(!onTop)
+  {
+    //cerr << "    shade " << typeid(*this).name() << endl;
+
+    _shadeSurface->setDstRect(_surface->dstRect());
+    _shadeSurface->render();
+  }
+
+  _toolTip->render();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -305,7 +365,7 @@ void Dialog::setFocus(Widget* w)
 {
   // If the click occured inside a widget which is not the currently
   // focused one, change the focus to that widget.
-  if(w && w != _focusedWidget && w->wantsFocus())
+  if(w && w != _focusedWidget && w->wantsFocus() && w->isEnabled())
   {
     // Redraw widgets for new focus
     _focusedWidget = Widget::setFocusForChain(this, getFocusList(), w, 0);
@@ -371,39 +431,43 @@ void Dialog::drawDialog()
 
   FBSurface& s = surface();
 
-  // Dialog is still on top if e.g a ContextMenu is opened
-  _onTop = parent().myDialogStack.top() == this
-    || (parent().myDialogStack.get(parent().myDialogStack.size() - 2) == this
-    && !parent().myDialogStack.top()->hasTitle());
-
-  if(_flags & Widget::FLAG_CLEARBG)
+  if(isDirty())
   {
-    //    cerr << "Dialog::drawDialog(): w = " << _w << ", h = " << _h << " @ " << &s << endl << endl;
-    s.fillRect(_x, _y + _th, _w, _h - _th, _onTop ? kDlgColor : kBGColorLo);
-    if(_th)
+    cerr << endl << "d";
+    //cerr << "*** draw dialog " << typeid(*this).name() << " ***" << endl;
+
+    if(clearsBackground())
     {
-      s.fillRect(_x, _y, _w, _th, _onTop ? kColorTitleBar : kColorTitleBarLo);
-      s.drawString(_font, _title, _x + _font.getMaxCharWidth() * 1.25, _y + _font.getFontHeight() / 6,
-                   _font.getStringWidth(_title),
-                   _onTop ? kColorTitleText : kColorTitleTextLo);
+      //    cerr << "Dialog::drawDialog(): w = " << _w << ", h = " << _h << " @ " << &s << endl << endl;
+
+      if(hasBackground())
+        s.fillRect(_x, _y + _th, _w, _h - _th, kDlgColor);
+      else
+        s.invalidateRect(_x, _y + _th, _w, _h - _th);
+      if(_th)
+      {
+        s.fillRect(_x, _y, _w, _th, kColorTitleBar);
+        s.drawString(_font, _title, _x + _font.getMaxCharWidth() * 1.25, _y + _font.getFontHeight() / 6,
+                     _font.getStringWidth(_title), kColorTitleText);
+      }
     }
+    else {
+      s.invalidate();
+      //cerr << "invalidate " << typeid(*this).name() << endl;
+    }
+    if(hasBorder()) // currently only used by Dialog itself
+      s.frameRect(_x, _y, _w, _h, kColor);
+
+    // Make all child widgets dirty
+    Widget::setDirtyInChain(_firstWidget);
+
+    clearDirty();
   }
   else
-    s.invalidate();
-  if(_flags & Widget::FLAG_BORDER) // currently only used by Dialog itself
-    s.frameRect(_x, _y, _w, _h, _onTop ? kColor : kShadowColor);
-
-  // Make all child widget dirty
-  Widget* w = _firstWidget;
-  Widget::setDirtyInChain(w);
+    cerr << endl;
 
   // Draw all children
-  w = _firstWidget;
-  while(w)
-  {
-    w->draw();
-    w = w->_next;
-  }
+  drawChain();
 
   // Draw outlines for focused widgets
   // Don't change focus, since this will trigger lost and received
@@ -411,9 +475,26 @@ void Dialog::drawDialog()
   if(_focusedWidget)
   {
     _focusedWidget = Widget::setFocusForChain(this, getFocusList(),
-      _focusedWidget, 0, false);
-    if(_focusedWidget)
-      _focusedWidget->draw(); // make sure the highlight color is drawn initially
+                                              _focusedWidget, 0, false);
+    //if(_focusedWidget)
+    //  _focusedWidget->draw(); // make sure the highlight color is drawn initially
+  }
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void Dialog::drawChain()
+{
+  // Clear chain *before* drawing, because some widgets may set it again when
+  //   being drawn (e.g. RomListWidget)
+  clearDirtyChain();
+
+  Widget* w = _firstWidget;
+
+  while(w)
+  {
+    if(w->needsRedraw())
+      w->draw();
+    w = w->_next;
   }
 }
 
@@ -430,6 +511,8 @@ void Dialog::handleKeyDown(StellaKey key, StellaMod mod, bool repeated)
 {
   Event::Type e = Event::NoType;
 
+  tooltip().hide();
+
 // FIXME - I don't think this will compile!
 #if defined(RETRON77)
   // special keys used for R77
@@ -556,6 +639,11 @@ void Dialog::handleMouseMoved(int x, int y)
 
   if (w && (w->getFlags() & Widget::FLAG_TRACK_MOUSE))
     w->handleMouseMoved(x - (w->getAbsX() - _x), y - (w->getAbsY() - _y));
+
+#ifndef RETRON77
+  // Update mouse coordinates for tooltips
+  _toolTip->update(_mouseWidget, Common::Point(x, y));
+#endif
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/gui/Dialog.hxx b/src/gui/Dialog.hxx
index 001dafcc0..c89df3a57 100644
--- a/src/gui/Dialog.hxx
+++ b/src/gui/Dialog.hxx
@@ -26,6 +26,7 @@ class OSystem;
 class DialogContainer;
 class TabWidget;
 class CommandSender;
+class ToolTip;
 
 #include "Stack.hxx"
 #include "Widget.hxx"
@@ -54,19 +55,20 @@ class Dialog : public GuiObject
     void close();
 
     bool isVisible() const override { return _visible; }
-    bool isOnTop() const { return _onTop;  }
 
-    virtual void center();
+    virtual void setPosition();
     virtual void drawDialog();
     virtual void loadConfig()  { }
     virtual void saveConfig()  { }
     virtual void setDefaults() { }
 
-    // A dialog being dirty indicates that its underlying surface needs to be
-    // redrawn and then re-rendered; this is taken care of in ::render()
-    void setDirty() override { _dirty = true; }
-    bool isDirty() const { return _dirty; }
-    bool render();
+    void setDirty() override;
+    void setDirtyChain() override;
+    void redraw(bool force = false);
+    void drawChain() override;
+    void render();
+
+    void tick() override;
 
     void addFocusWidget(Widget* w) override;
     void addToFocusList(WidgetArray& list) override;
@@ -89,13 +91,11 @@ class Dialog : public GuiObject
     */
     void addSurface(const shared_ptr<FBSurface>& surface);
 
-    void setFlags(int flags) { _flags |= flags;  setDirty(); }
-    void clearFlags(int flags) { _flags &= ~flags; setDirty(); }
-    int  getFlags() const { return _flags; }
-
     void setTitle(const string& title);
     bool hasTitle() { return !_title.empty(); }
 
+    virtual bool isShading() const { return true; }
+
     /**
       Determine the maximum width/height of a dialog based on the minimum
       allowable bounds, also taking into account the current window size.
@@ -124,6 +124,8 @@ class Dialog : public GuiObject
     */
     bool shouldResize(uInt32& w, uInt32& h) const;
 
+    ToolTip& tooltip() { return *_toolTip; }
+
   protected:
     void draw() override { }
     void releaseFocus() override;
@@ -197,11 +199,11 @@ class Dialog : public GuiObject
     ButtonWidget* _cancelWidget{nullptr};
 
     bool    _visible{false};
-    bool    _onTop{true};
     bool    _processCancel{false};
     string  _title;
     int     _th{0};
     int     _layer{0};
+    unique_ptr<ToolTip> _toolTip;
 
     Common::FixedStack<shared_ptr<FBSurface>> mySurfaceStack;
 
@@ -232,10 +234,9 @@ class Dialog : public GuiObject
 
     WidgetArray _buttonGroup;
     shared_ptr<FBSurface> _surface;
+    shared_ptr<FBSurface> _shadeSurface;
 
     int _tabID{0};
-    int _flags{0};
-    bool _dirty{false};
     uInt32 _max_w{0}; // maximum wanted width
     uInt32 _max_h{0}; // maximum wanted height
 
diff --git a/src/gui/DialogContainer.cxx b/src/gui/DialogContainer.cxx
index 950d71c06..16f32536a 100644
--- a/src/gui/DialogContainer.cxx
+++ b/src/gui/DialogContainer.cxx
@@ -17,6 +17,7 @@
 
 #include "OSystem.hxx"
 #include "Dialog.hxx"
+#include "ToolTip.hxx"
 #include "Stack.hxx"
 #include "EventHandler.hxx"
 #include "FrameBuffer.hxx"
@@ -89,31 +90,53 @@ void DialogContainer::updateTime(uInt64 time)
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-bool DialogContainer::draw(bool full)
+void DialogContainer::draw(bool full)
 {
   if(myDialogStack.empty())
-    return false;
+    return;
 
-  // Make the top dialog dirty if a full redraw is requested
-  if(full)
-    myDialogStack.top()->setDirty();
+  //cerr << "draw " << full << " " << typeid(*this).name() << endl;
 
-  // If the top dialog is dirty, then all below it must be redrawn too
-  const bool dirty = needsRedraw();
-
-  myDialogStack.applyAll([&](Dialog*& d){
-    if(dirty)
-      d->setDirty();
-    full |= d->render();
+  // Draw and render all dirty dialogs
+  myDialogStack.applyAll([&](Dialog*& d) {
+    if(full || d->needsRedraw())
+      d->redraw(full);
   });
+  // Always render all surfaces, bottom to top
+  render();
+}
 
-  return full;
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void DialogContainer::tick()
+{
+  if(!myDialogStack.empty())
+    myDialogStack.top()->tick();
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void DialogContainer::render()
+{
+  if(myDialogStack.empty())
+    return;
+
+  //cerr << "full re-render " << typeid(*this).name() << endl;
+
+  // Make sure we start in a clean state (with zero'ed buffers)
+  if(!myOSystem.eventHandler().inTIAMode())
+    myOSystem.frameBuffer().clear();
+
+  // Render all dialogs
+  myDialogStack.applyAll([&](Dialog*& d) {
+    d->render();
+  });
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 bool DialogContainer::needsRedraw() const
 {
-  return !myDialogStack.empty() ? myDialogStack.top()->isDirty() : false;
+  return !myDialogStack.empty()
+    ? myDialogStack.top()->needsRedraw()
+    : false;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -129,10 +152,14 @@ int DialogContainer::addDialog(Dialog* d)
   const uInt32 scale = myOSystem.frameBuffer().hidpiScaleFactor();
 
   if(uInt32(d->getWidth() * scale) > r.w() || uInt32(d->getHeight() * scale) > r.h())
-    myOSystem.frameBuffer().showMessage(
-        "Unable to show dialog box; FIX THE CODE");
+    myOSystem.frameBuffer().showTextMessage(
+      "Unable to show dialog box; FIX THE CODE", MessagePosition::BottomCenter, true);
   else
   {
+    // Close all open tooltips
+    if(!myDialogStack.empty())
+      myDialogStack.top()->tooltip().hide();
+
     d->setDirty();
     myDialogStack.push(d);
   }
@@ -144,9 +171,11 @@ void DialogContainer::removeDialog()
 {
   if(!myDialogStack.empty())
   {
+    //cerr << "remove dialog " << typeid(*myDialogStack.top()).name() << endl;
     myDialogStack.pop();
-    if(!myDialogStack.empty())
-      myDialogStack.top()->setDirty();
+
+    // Inform the frame buffer that it has to render all surfaces
+    myOSystem.frameBuffer().setPendingRender();
   }
 }
 
@@ -157,6 +186,9 @@ void DialogContainer::reStack()
   while(!myDialogStack.empty())
     myDialogStack.top()->close();
 
+  // Make sure that all surfaces are cleared
+  myOSystem.frameBuffer().clear();
+
   baseDialog()->open();
 
   // Reset all continuous events
diff --git a/src/gui/DialogContainer.hxx b/src/gui/DialogContainer.hxx
index cc50e23b6..134d82e55 100644
--- a/src/gui/DialogContainer.hxx
+++ b/src/gui/DialogContainer.hxx
@@ -120,11 +120,19 @@ class DialogContainer
     void handleJoyHatEvent(int stick, int hat, JoyHatDir hdir, int button);
 
     /**
-      Draw the stack of menus (full indicates to redraw all items).
-
-      @return  Answers whether any drawing actually occurred.
+      Tick the dialog and all its widgets.
     */
-    bool draw(bool full = false);
+    void tick();
+
+    /**
+      Draw the stack of menus (full indicates to redraw all items).
+    */
+    void draw(bool full = false);
+
+    /**
+      Render the stack of menus.
+    */
+    void render();
 
     /**
       Answers whether a full redraw is required.
diff --git a/src/gui/EditTextWidget.cxx b/src/gui/EditTextWidget.cxx
index ff53ced5a..dde104002 100644
--- a/src/gui/EditTextWidget.cxx
+++ b/src/gui/EditTextWidget.cxx
@@ -18,6 +18,7 @@
 #include "OSystem.hxx"
 #include "FBSurface.hxx"
 #include "Dialog.hxx"
+#include "ToolTip.hxx"
 #include "Font.hxx"
 #include "EditTextWidget.hxx"
 
@@ -45,21 +46,11 @@ void EditTextWidget::setText(const string& str, bool changed)
 {
   EditableWidget::setText(str, changed);
   _backupString = str;
-  _changed = changed;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void EditTextWidget::handleMouseEntered()
-{
-  setFlags(Widget::FLAG_HILITED);
-  setDirty();
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void EditTextWidget::handleMouseLeft()
-{
-  clearFlags(Widget::FLAG_HILITED);
-  setDirty();
+  if(_changed != changed)
+  {
+    _changed = changed;
+    setDirty();
+  }
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -68,6 +59,7 @@ void EditTextWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount
   if(!isEditable())
     return;
 
+  resetSelection();
   x += _editScrollOffset;
 
   int width = 0;
@@ -88,13 +80,12 @@ void EditTextWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount
 void EditTextWidget::drawWidget(bool hilite)
 {
   FBSurface& s = _boss->dialog().surface();
-  bool onTop = _boss->dialog().isOnTop();
 
   // Highlight changes
-  if(_changed && onTop)
+  if(_changed)
     s.fillRect(_x, _y, _w, _h, kDbgChangedColor);
   else if(!isEditable() || !isEnabled())
-    s.fillRect(_x, _y, _w, _h, onTop ? kDlgColor : kBGColorLo);
+    s.fillRect(_x, _y, _w, _h, kDlgColor);
 
   // Draw a thin frame around us.
   s.frameRect(_x, _y, _w, _h, hilite && isEditable() && isEnabled() ? kWidColorHi : kColor);
@@ -102,13 +93,13 @@ void EditTextWidget::drawWidget(bool hilite)
   // Draw the text
   adjustOffset();
   s.drawString(_font, editString(), _x + _textOfs, _y + 2, getEditRect().w(), getEditRect().h(),
-               _changed && onTop && isEnabled()
+               _changed && isEnabled()
                ? kDbgChangedTextColor
-               : onTop && isEnabled() ? _textcolor : kColor,
-               TextAlign::Left, isEditable() ? -_editScrollOffset : 0, !isEditable());
+               : isEnabled() ? _textcolor : kColor,
+               TextAlign::Left, scrollOffset(), !isEditable());
 
-  // Draw the caret
-  drawCaret();
+  // Draw the caret and selection
+  drawCaretSelection();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -120,6 +111,7 @@ Common::Rect EditTextWidget::getEditRect() const
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void EditTextWidget::lostFocusWidget()
 {
+  EditableWidget::lostFocusWidget();
   // If we loose focus, 'commit' the user changes
   _backupString = editString();
 }
diff --git a/src/gui/EditTextWidget.hxx b/src/gui/EditTextWidget.hxx
index fe063e042..e7c21beff 100644
--- a/src/gui/EditTextWidget.hxx
+++ b/src/gui/EditTextWidget.hxx
@@ -54,8 +54,6 @@ class EditTextWidget : public EditableWidget
     Common::Rect getEditRect() const override;
 
     void handleMouseDown(int x, int y, MouseButton b, int clickCount) override;
-    void handleMouseEntered() override;
-    void handleMouseLeft() override;
 
   protected:
     string _backupString;
diff --git a/src/gui/EditableWidget.cxx b/src/gui/EditableWidget.cxx
index 5218e6fc4..eaadbaeeb 100644
--- a/src/gui/EditableWidget.cxx
+++ b/src/gui/EditableWidget.cxx
@@ -19,12 +19,12 @@
 #include "StellaKeys.hxx"
 #include "FBSurface.hxx"
 #include "Font.hxx"
+#include "OSystem.hxx"
+#include "EventHandler.hxx"
+#include "UndoHandler.hxx"
+#include "ToolTip.hxx"
 #include "EditableWidget.hxx"
 
-// Uncomment the following to give full-line copy/paste
-// Note that this will be removed eventually, when we implement proper copy/paste
-//#define PSEUDO_COPY_PASTE
-
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 EditableWidget::EditableWidget(GuiObject* boss, const GUI::Font& font,
                                int x, int y, int w, int h, const string& str)
@@ -38,25 +38,56 @@ EditableWidget::EditableWidget(GuiObject* boss, const GUI::Font& font,
   _bgcolorlo = kDlgColor;
   _textcolor = kTextColor;
   _textcolorhi = kTextColor;
+
+  myUndoHandler = make_unique<UndoHandler>();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void EditableWidget::setText(const string& str, bool)
+void EditableWidget::setText(const string& str, bool changed)
 {
+  const string oldEditString = _editString;
   // Filter input string
   _editString = "";
   for(char c: str)
     if(_filter(tolower(c)))
       _editString.push_back(c);
 
+  if(oldEditString != _editString)
+    setDirty();
+
+  myUndoHandler->reset();
+  myUndoHandler->doo(_editString);
+
   _caretPos = int(_editString.size());
+  _selectSize = 0;
 
   _editScrollOffset = (_font.getStringWidth(_editString) - (getEditRect().w()));
   if (_editScrollOffset < 0)
     _editScrollOffset = 0;
-
-  setDirty();
 }
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void EditableWidget::tick()
+{
+  if(_hasFocus && isEditable() && _editMode && isVisible() && _boss->isVisible())
+  {
+    _caretTimer++;
+    if(_caretTimer > 40) // switch every 2/3rd seconds
+    {
+      _caretTimer = 0;
+      _caretEnabled = !_caretEnabled;
+      setDirty();
+    }
+  }
+  Widget::tick();
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool EditableWidget::wantsToolTip() const
+{
+  return !(_hasFocus && isEditable() && _editMode) && Widget::wantsToolTip();
+}
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void EditableWidget::setEditable(bool editable, bool hiliteBG)
 {
@@ -73,11 +104,28 @@ void EditableWidget::setEditable(bool editable, bool hiliteBG)
   }
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void EditableWidget::receivedFocusWidget()
+{
+  _caretTimer = 0;
+  _caretEnabled = true;
+  dialog().tooltip().hide();
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void EditableWidget::lostFocusWidget()
+{
+  myUndoHandler->reset();
+  _selectSize = 0;
+}
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 bool EditableWidget::tryInsertChar(char c, int pos)
 {
   if(_filter(tolower(c)))
   {
+    killSelectedText();
+    myUndoHandler->doChar(); // aggregate single chars
     _editString.insert(pos, 1, c);
     return true;
   }
@@ -92,7 +140,7 @@ bool EditableWidget::handleText(char text)
 
   if(tryInsertChar(text, _caretPos))
   {
-    _caretPos++;
+    setCaretPos(_caretPos + 1);
     sendCommand(EditableWidget::kChangedCmd, 0, _id);
     setDirty();
     return true;
@@ -106,73 +154,178 @@ bool EditableWidget::handleKeyDown(StellaKey key, StellaMod mod)
   if(!_editable)
     return true;
 
-  // Ignore all alt-mod keys
-  if(StellaModTest::isAlt(mod))
-    return true;
-
   bool handled = true;
-  bool dirty = false;
+  Event::Type event = instance().eventHandler().eventForKey(EventMode::kEditMode, key, mod);
 
-  switch(key)
+  switch(event)
   {
-    case KBDK_RETURN:
-    case KBDK_KP_ENTER:
+    case Event::MoveLeftChar:
+      if(_selectSize)
+        handled = setCaretPos(selectStartPos());
+      else if(_caretPos > 0)
+        handled = setCaretPos(_caretPos - 1);
+      _selectSize = 0;
+      break;
+
+    case Event::MoveRightChar:
+      if(_selectSize)
+        handled = setCaretPos(selectEndPos());
+      else if(_caretPos < int(_editString.size()))
+        handled = setCaretPos(_caretPos + 1);
+      _selectSize = 0;
+      break;
+
+    case Event::MoveLeftWord:
+      handled = moveWord(-1, false);
+      _selectSize = 0;
+      break;
+
+    case Event::MoveRightWord:
+      handled = moveWord(+1, false);
+      _selectSize = 0;
+      break;
+
+    case Event::MoveHome:
+      handled = setCaretPos(0);
+      _selectSize = 0;
+      break;
+
+    case Event::MoveEnd:
+      handled = setCaretPos(int(_editString.size()));
+      _selectSize = 0;
+      break;
+
+    case Event::SelectLeftChar:
+      if(_caretPos > 0)
+        handled = moveCaretPos(-1);
+      break;
+
+    case Event::SelectRightChar:
+      if(_caretPos < int(_editString.size()))
+        handled = moveCaretPos(+1);
+      break;
+
+    case Event::SelectLeftWord:
+      handled = moveWord(-1, true);
+      break;
+
+    case Event::SelectRightWord:
+      handled = moveWord(+1, true);
+      break;
+
+    case Event::SelectHome:
+      handled = moveCaretPos(-_caretPos);
+      break;
+
+    case Event::SelectEnd:
+      handled = moveCaretPos(int(_editString.size()) - _caretPos);
+      break;
+
+    case Event::SelectAll:
+      if(setCaretPos(int(_editString.size())))
+        _selectSize = -int(_editString.size());
+      break;
+
+    case Event::Backspace:
+      handled = killSelectedText();
+      if(!handled)
+        handled = killChar(-1);
+      if(handled)
+        sendCommand(EditableWidget::kChangedCmd, key, _id);
+      break;
+
+    case Event::Delete:
+      handled = killSelectedText();
+      if(!handled)
+        handled = killChar(+1);
+      if(handled)
+        sendCommand(EditableWidget::kChangedCmd, key, _id);
+      break;
+
+    case Event::DeleteLeftWord:
+      handled = killWord(-1);
+      if(handled)
+        sendCommand(EditableWidget::kChangedCmd, key, _id);
+      break;
+
+    case Event::DeleteRightWord:
+      handled = killWord(+1);
+      if(handled)
+        sendCommand(EditableWidget::kChangedCmd, key, _id);
+      break;
+
+    case Event::DeleteEnd:
+      handled = killLine(+1);
+      if(handled)
+        sendCommand(EditableWidget::kChangedCmd, key, _id);
+      break;
+
+    case Event::DeleteHome:
+      handled = killLine(-1);
+      if(handled)
+        sendCommand(EditableWidget::kChangedCmd, key, _id);
+      break;
+
+    case Event::Cut:
+      handled = cutSelectedText();
+      if(handled)
+        sendCommand(EditableWidget::kChangedCmd, key, _id);
+      break;
+
+    case Event::Copy:
+      handled = copySelectedText();
+      break;
+
+    case Event::Paste:
+      handled = pasteSelectedText();
+      if(handled)
+        sendCommand(EditableWidget::kChangedCmd, key, _id);
+      break;
+
+    case Event::Undo:
+    case Event::Redo:
+    {
+      string oldString = _editString;
+
+      myUndoHandler->endChars(_editString);
+      // Reverse Y and Z for QWERTZ keyboards
+      if(event == Event::Redo)
+        handled = myUndoHandler->redo(_editString);
+      else
+        handled = myUndoHandler->undo(_editString);
+
+      if(handled)
+      {
+        // Put caret at last difference
+        myUndoHandler->lastDiff(_editString, oldString);
+        setCaretPos(myUndoHandler->lastDiff(_editString, oldString));
+        _selectSize = 0;
+        sendCommand(EditableWidget::kChangedCmd, key, _id);
+      }
+      break;
+    }
+
+    case Event::EndEdit:
       // confirm edit and exit editmode
       endEditMode();
       sendCommand(EditableWidget::kAcceptCmd, 0, _id);
-      dirty = true;
       break;
 
-    case KBDK_ESCAPE:
+    case Event::AbortEdit:
       abortEditMode();
       sendCommand(EditableWidget::kCancelCmd, 0, _id);
-      dirty = true;
-      break;
-
-    case KBDK_BACKSPACE:
-      dirty = killChar(-1);
-      if(dirty)  sendCommand(EditableWidget::kChangedCmd, key, _id);
-      break;
-
-    case KBDK_DELETE:
-    case KBDK_KP_PERIOD:
-      dirty = killChar(+1);
-      if(dirty)  sendCommand(EditableWidget::kChangedCmd, key, _id);
-      break;
-
-    case KBDK_LEFT:
-      if(StellaModTest::isControl(mod))
-        dirty = specialKeys(key);
-      else if(_caretPos > 0)
-        dirty = setCaretPos(_caretPos - 1);
-      break;
-
-    case KBDK_RIGHT:
-      if(StellaModTest::isControl(mod))
-        dirty = specialKeys(key);
-      else if(_caretPos < int(_editString.size()))
-        dirty = setCaretPos(_caretPos + 1);
-      break;
-
-    case KBDK_HOME:
-      dirty = setCaretPos(0);
-      break;
-
-    case KBDK_END:
-      dirty = setCaretPos(int(_editString.size()));
       break;
 
     default:
-      if (StellaModTest::isControl(mod))
-      {
-        dirty = specialKeys(key);
-      }
-      else
-        handled = false;
+      handled = false;
+      break;
   }
 
-  if (dirty)
+  if(handled)
+  {
+    myUndoHandler->endChars(_editString);
     setDirty();
+  }
 
   return handled;
 }
@@ -180,33 +333,76 @@ bool EditableWidget::handleKeyDown(StellaKey key, StellaMod mod)
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 int EditableWidget::getCaretOffset() const
 {
-  int caretpos = 0;
+  int caretOfs = 0;
   for (int i = 0; i < _caretPos; i++)
-    caretpos += _font.getCharWidth(_editString[i]);
+    caretOfs += _font.getCharWidth(_editString[i]);
 
-  caretpos -= _editScrollOffset;
+  caretOfs -= _editScrollOffset;
 
-  return caretpos;
+  return caretOfs;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void EditableWidget::drawCaret()
+void EditableWidget::drawCaretSelection()
 {
   // Only draw if item is visible
   if (!_editable || !isVisible() || !_boss->isVisible() || !_hasFocus)
     return;
 
-  const Common::Rect& editRect = getEditRect();
-  int x = editRect.x();
-  int y = editRect.y();
+  // Draw the selection
+  if(_selectSize)
+  {
+    FBSurface& s = _boss->dialog().surface();
+    const Common::Rect& editRect = getEditRect();
+    int x = editRect.x();
+    int y = editRect.y();
 
-  x += getCaretOffset();
+    string text = selectString();
 
-  x += _x;
-  y += _y;
+    x = editRect.x();
+    y = editRect.y();
+    int w = editRect.w();
+    int h = editRect.h();
+    int wt = int(text.length()) * _font.getMaxCharWidth() + 1;
+    int dx = selectStartPos() * _font.getMaxCharWidth() - _editScrollOffset;
 
-  FBSurface& s = _boss->dialog().surface();
-  s.vLine(x, y+2, y + editRect.h() - 2, kTextColorHi);
+    if(dx < 0)
+    {
+      // selected text starts left of displayed rect
+      text = text.substr(-(dx - 1) / _font.getMaxCharWidth());
+      wt += dx;
+      dx = 0;
+    }
+    else
+      x += dx;
+    // limit selection to the right of displayed rect
+    w = std::min(w - dx + 1, wt);
+
+    x += _x;
+    y += _y;
+
+    s.fillRect(x - 1, y + 1, w + 1, h - 3, kTextColorHi);
+    s.drawString(_font, text, x, y + 1 + _dyText, w, h,
+                 kTextColorInv, TextAlign::Left, 0, false);
+  }
+
+  // Draw the caret
+  if(_caretEnabled ^ (_selectSize != 0))
+  {
+    FBSurface& s = _boss->dialog().surface();
+    const Common::Rect& editRect = getEditRect();
+    int x = editRect.x();
+    int y = editRect.y();
+    ColorId color = _caretEnabled ? kTextColorHi : kTextColorInv;
+
+    x += getCaretOffset();
+    x += _x;
+    y += _y;
+
+    s.vLine(x, y + 1, y + editRect.h() - 3, color);
+    s.vLine(x - 1, y + 1, y + editRect.h() - 3, color);
+    clearDirty();
+  }
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -215,9 +411,25 @@ bool EditableWidget::setCaretPos(int newPos)
   assert(newPos >= 0 && newPos <= int(_editString.size()));
   _caretPos = newPos;
 
+  _caretTimer = 0;
+  _caretEnabled = true;
+
   return adjustOffset();
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool EditableWidget::moveCaretPos(int direction)
+{
+  if(setCaretPos(_caretPos + direction))
+  {
+    _selectSize -= direction;
+    _caretTimer = 0;
+    _caretEnabled = true;
+    return true;
+  }
+  return false;
+}
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 bool EditableWidget::adjustOffset()
 {
@@ -227,18 +439,18 @@ bool EditableWidget::adjustOffset()
   // For some reason (differences in ScummVM event handling??),
   // this method should always return true.
 
-  int caretpos = getCaretOffset();
+  int caretOfs = getCaretOffset();
   const int editWidth = getEditRect().w();
 
-  if (caretpos < 0)
+  if (caretOfs < 0)
   {
     // scroll left
-    _editScrollOffset += caretpos;
+    _editScrollOffset += caretOfs;
   }
-  else if (caretpos >= editWidth)
+  else if (caretOfs >= editWidth)
   {
     // scroll right
-    _editScrollOffset -= (editWidth - caretpos);
+    _editScrollOffset -= (editWidth - caretOfs);
   }
   else if (_editScrollOffset > 0)
   {
@@ -256,67 +468,13 @@ bool EditableWidget::adjustOffset()
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-bool EditableWidget::specialKeys(StellaKey key)
+int EditableWidget::scrollOffset()
 {
-  bool handled = true;
-
-  switch (key)
-  {
-    case KBDK_A:
-      setCaretPos(0);
-      break;
-
-    case KBDK_C:
-      copySelectedText();
-      if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id);
-      break;
-
-    case KBDK_E:
-      setCaretPos(int(_editString.size()));
-      break;
-
-    case KBDK_D:
-      handled = killChar(+1);
-      if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id);
-      break;
-
-    case KBDK_K:
-      handled = killLine(+1);
-      if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id);
-      break;
-
-    case KBDK_U:
-      handled = killLine(-1);
-      if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id);
-      break;
-
-    case KBDK_V:
-      pasteSelectedText();
-      if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id);
-      break;
-
-    case KBDK_W:
-      handled = killLastWord();
-      if(handled) sendCommand(EditableWidget::kChangedCmd, key, _id);
-      break;
-
-    case KBDK_LEFT:
-      handled = moveWord(-1);
-      break;
-
-    case KBDK_RIGHT:
-      handled = moveWord(+1);
-      break;
-
-    default:
-      handled = false;
-  }
-
-  return handled;
+  return _editable ? -_editScrollOffset : 0;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-bool EditableWidget::killChar(int direction)
+bool EditableWidget::killChar(int direction, bool addEdit)
 {
   bool handled = false;
 
@@ -325,14 +483,29 @@ bool EditableWidget::killChar(int direction)
     if(_caretPos > 0)
     {
       _caretPos--;
-      _editString.erase(_caretPos, 1);
+      if(_selectSize < 0)
+        _selectSize++;
       handled = true;
     }
   }
   else if(direction == 1)  // Delete next character (delete)
   {
+    if(_caretPos < int(_editString.size()))
+    {
+      if(_selectSize > 0)
+        _selectSize--;
+      handled = true;
+    }
+  }
+
+  if(handled)
+  {
+    myUndoHandler->endChars(_editString);
     _editString.erase(_caretPos, 1);
-    handled = true;
+    setCaretPos(_caretPos);
+
+    if(addEdit)
+      myUndoHandler->doo(_editString);
   }
 
   return handled;
@@ -341,67 +514,78 @@ bool EditableWidget::killChar(int direction)
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 bool EditableWidget::killLine(int direction)
 {
-  bool handled = false;
+  int count = 0;
 
   if(direction == -1)  // erase from current position to beginning of line
-  {
-    int count = _caretPos;
-    if(count > 0)
-    {
-      for (int i = 0; i < count; i++)
-        killChar(-1);
+    count = _caretPos;
+  else if(direction == +1)  // erase from current position to end of line
+    count = int(_editString.size()) - _caretPos;
 
-      handled = true;
-    }
-  }
-  else if(direction == 1)  // erase from current position to end of line
+  if(count > 0)
   {
-    int count = int(_editString.size()) - _caretPos;
-    if(count > 0)
-    {
-      for (int i = 0; i < count; i++)
-        killChar(+1);
+    for(int i = 0; i < count; i++)
+      killChar(direction, false);
 
-      handled = true;
-    }
+    myUndoHandler->doo(_editString);
+    return true;
   }
 
-  return handled;
+  return false;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-bool EditableWidget::killLastWord()
+bool EditableWidget::killWord(int direction)
 {
-  bool handled = false;
-  int count = 0, currentPos = _caretPos;
   bool space = true;
-  while (currentPos > 0)
-  {
-    if (_editString[currentPos - 1] == ' ')
-    {
-      if (!space)
-        break;
-    }
-    else
-      space = false;
+  int count = 0, currentPos = _caretPos;
 
-    currentPos--;
-    count++;
+  if(direction == -1)  // move to first character of previous word
+  {
+    while(currentPos > 0)
+    {
+      if(_editString[currentPos - 1] == ' ')
+      {
+        if(!space)
+          break;
+      }
+      else
+        space = false;
+
+      currentPos--;
+      count++;
+    }
+  }
+  else if(direction == +1)  // move to first character of next word
+  {
+    while(currentPos < int(_editString.size()))
+    {
+      if(currentPos && _editString[currentPos - 1] == ' ')
+      {
+        if(!space)
+          break;
+      }
+      else
+        space = false;
+
+      currentPos++;
+      count++;
+    }
   }
 
   if(count > 0)
   {
-    for (int i = 0; i < count; i++)
-      killChar(-1);
+    for(int i = 0; i < count; i++)
+      killChar(direction, false);
 
-    handled = true;
+    myUndoHandler->doo(_editString);
+    return true;
   }
 
-  return handled;
+  return false;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-bool EditableWidget::moveWord(int direction)
+bool EditableWidget::moveWord(int direction, bool select)
 {
   bool handled = false;
   bool space = true;
@@ -420,15 +604,17 @@ bool EditableWidget::moveWord(int direction)
         space = false;
 
       currentPos--;
+      if(select)
+        _selectSize++;
     }
-    _caretPos = currentPos;
+    setCaretPos(currentPos);
     handled = true;
   }
   else if(direction == +1)  // move to first character of next word
   {
     while (currentPos < int(_editString.size()))
     {
-      if (_editString[currentPos - 1] == ' ')
+      if (currentPos && _editString[currentPos - 1] == ' ')
       {
         if (!space)
           break;
@@ -437,8 +623,10 @@ bool EditableWidget::moveWord(int direction)
         space = false;
 
       currentPos++;
+      if(select)
+        _selectSize--;
     }
-    _caretPos = currentPos;
+    setCaretPos(currentPos);
     handled = true;
   }
 
@@ -446,20 +634,119 @@ bool EditableWidget::moveWord(int direction)
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void EditableWidget::copySelectedText()
+const string EditableWidget::selectString() const
 {
-#if defined(PSEUDO_COPY_PASTE)
-  _clippedText = _editString;
-#endif
+  if(_selectSize)
+  {
+    int caretPos = _caretPos;
+    int selectSize = _selectSize;
+
+    if(selectSize < 0)
+    {
+      caretPos += selectSize;
+      selectSize = -selectSize;
+    }
+    return _editString.substr(caretPos, selectSize);
+  }
+  return EmptyString;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void EditableWidget::pasteSelectedText()
+int EditableWidget::selectStartPos()
 {
-#if defined(PSEUDO_COPY_PASTE)
-  _editString = _clippedText;
-#endif
+  if(_selectSize < 0)
+    return _caretPos + _selectSize;
+  else
+    return _caretPos;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-string EditableWidget::_clippedText = "";
+int EditableWidget::selectEndPos()
+{
+  if(_selectSize > 0)
+    return _caretPos + _selectSize;
+  else
+    return _caretPos;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool EditableWidget::killSelectedText(bool addEdit)
+{
+  if(_selectSize)
+  {
+    myUndoHandler->endChars(_editString);
+    if(_selectSize < 0)
+    {
+      _caretPos += _selectSize;
+      _selectSize = -_selectSize;
+    }
+    _editString.erase(_caretPos, _selectSize);
+    setCaretPos(_caretPos);
+    _selectSize = 0;
+    if(addEdit)
+      myUndoHandler->doo(_editString);
+    return true;
+  }
+  return false;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool EditableWidget::cutSelectedText()
+{
+  return copySelectedText() && killSelectedText();
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool EditableWidget::copySelectedText()
+{
+  string selected = selectString();
+
+  // only copy if anything is selected, else keep old copied text
+  if(!selected.empty())
+  {
+    instance().eventHandler().copyText(selected);
+    return true;
+  }
+  return false;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool EditableWidget::pasteSelectedText()
+{
+  bool selected = !selectString().empty();
+  string pasted;
+
+  myUndoHandler->endChars(_editString);
+
+  // retrieve the pasted text
+  instance().eventHandler().pasteText(pasted);
+  // remove the currently selected text
+  killSelectedText(false);
+  // insert filtered paste text instead
+  ostringstream buf;
+  bool lastOk = true; // only one filler char per invalid character (block)
+
+  for(char c : pasted)
+    if(_filter(tolower(c)))
+    {
+      buf << c;
+      lastOk = true;
+    }
+    else
+    {
+      if(lastOk)
+        buf << '_';
+      lastOk = false;
+    }
+
+  _editString.insert(_caretPos, buf.str());
+  // position cursor at the end of pasted text
+  setCaretPos(_caretPos + int(buf.str().length()));
+
+  if(selected || !pasted.empty())
+  {
+    myUndoHandler->doo(_editString);
+    return true;
+  }
+  return false;
+}
diff --git a/src/gui/EditableWidget.hxx b/src/gui/EditableWidget.hxx
index 933d033af..3ffe09a65 100644
--- a/src/gui/EditableWidget.hxx
+++ b/src/gui/EditableWidget.hxx
@@ -22,6 +22,7 @@
 
 #include "Widget.hxx"
 #include "Rect.hxx"
+#include "UndoHandler.hxx"
 
 /**
  * Base class for widgets which need to edit text, like ListWidget and
@@ -64,31 +65,43 @@ class EditableWidget : public Widget, public CommandSender
     void setTextFilter(const TextFilter& filter) { _filter = filter; }
 
   protected:
+    void receivedFocusWidget() override;
+    void lostFocusWidget() override;
+    void tick() override;
+    bool wantsToolTip() const override; 
+
     virtual void startEditMode() { setFlags(Widget::FLAG_WANTS_RAWDATA);   }
     virtual void endEditMode()   { clearFlags(Widget::FLAG_WANTS_RAWDATA); }
     virtual void abortEditMode() { clearFlags(Widget::FLAG_WANTS_RAWDATA); }
 
     virtual Common::Rect getEditRect() const = 0;
     virtual int getCaretOffset() const;
-    void drawCaret();
+    void drawCaretSelection();
     bool setCaretPos(int newPos);
+    bool moveCaretPos(int direction);
     bool adjustOffset();
 
     // This method is used internally by child classes wanting to
     // access/edit the internal buffer
     string& editString() { return _editString; }
+    const string selectString() const;
+    void resetSelection() { _selectSize = 0; }
+    int scrollOffset();
 
   private:
     // Line editing
-    bool specialKeys(StellaKey key);
-    bool killChar(int direction);
+    bool killChar(int direction, bool addEdit = true);
     bool killLine(int direction);
-    bool killLastWord();
-    bool moveWord(int direction);
+    bool killWord(int direction);
+    bool moveWord(int direction, bool select);
 
+    bool killSelectedText(bool addEdit = true);
+    int selectStartPos();
+    int selectEndPos();
     // Clipboard
-    void copySelectedText();
-    void pasteSelectedText();
+    bool cutSelectedText();
+    bool copySelectedText();
+    bool pasteSelectedText();
 
     // Use the current TextFilter to insert a character into the
     // internal buffer
@@ -97,17 +110,22 @@ class EditableWidget : public Widget, public CommandSender
   private:
     bool   _editable{true};
     string _editString;
+    unique_ptr<UndoHandler> myUndoHandler;
 
-//     bool  _caretVisible{false};
-//     int   _caretTime{0};
-    int   _caretPos{0};
+    int    _caretPos{0};
+    int    _caretTimer{0};
+    bool   _caretEnabled{true};
+
+    // Size of current selected text
+    //    0 = no selection
+    //   <0 = selected left of caret
+    //   >0 = selected right of caret
+    int    _selectSize{0};
 
   protected:
-    bool  _caretInverse{false};
-
     int   _editScrollOffset{0};
-
-    static string _clippedText;
+    bool  _editMode{true};
+    int   _dyText{0};
 
   private:
     TextFilter _filter;
diff --git a/src/gui/EmulationDialog.cxx b/src/gui/EmulationDialog.cxx
index dcbb42859..a2c0bee9c 100644
--- a/src/gui/EmulationDialog.cxx
+++ b/src/gui/EmulationDialog.cxx
@@ -99,6 +99,7 @@ EmulationDialog::EmulationDialog(OSystem& osystem, DialogContainer& parent,
 
   // Use sync to vblank
   myUseVSync = new CheckboxWidget(this, _font, xpos, ypos + 1, "VSync");
+  myUseVSync->setToolTip("Check to enable vertical synced display updates.");
   wid.push_back(myUseVSync);
   ypos += lineHeight + VGAP;
 
diff --git a/src/gui/EventMappingWidget.cxx b/src/gui/EventMappingWidget.cxx
index 8051e4a56..7b3ae540b 100644
--- a/src/gui/EventMappingWidget.cxx
+++ b/src/gui/EventMappingWidget.cxx
@@ -97,6 +97,7 @@ EventMappingWidget::EventMappingWidget(GuiObject* boss, const GUI::Font& font,
   myCancelMapButton = new ButtonWidget(boss, font, xpos, ypos,
                                        buttonWidth, buttonHeight,
                                        "Cancel", kStopMapCmd);
+  myCancelMapButton->setToolTip("Cancel current mapping.");
   myCancelMapButton->setTarget(this);
   myCancelMapButton->clearFlags(Widget::FLAG_ENABLED);
   addFocusWidget(myCancelMapButton);
@@ -106,12 +107,14 @@ EventMappingWidget::EventMappingWidget(GuiObject* boss, const GUI::Font& font,
                                    buttonWidth, buttonHeight,
                                    "Erase", kEraseCmd);
   myEraseButton->setTarget(this);
+  myEraseButton->setToolTip("Erase any mapping for selected event.");
   addFocusWidget(myEraseButton);
 
   ypos += buttonHeight + VGAP;
   myResetButton = new ButtonWidget(boss, font, xpos, ypos,
                                    buttonWidth, buttonHeight,
                                    "Reset", kResetCmd);
+  myResetButton->setToolTip("Reset mapping for selected event to defaults.");
   myResetButton->setTarget(this);
   addFocusWidget(myResetButton);
 
diff --git a/src/gui/FileListWidget.cxx b/src/gui/FileListWidget.cxx
index ab231fa97..613b05811 100644
--- a/src/gui/FileListWidget.cxx
+++ b/src/gui/FileListWidget.cxx
@@ -20,6 +20,7 @@
 #include "ScrollBarWidget.hxx"
 #include "FileListWidget.hxx"
 #include "TimerManager.hxx"
+#include "ProgressDialog.hxx"
 
 #include "bspf.hxx"
 
@@ -50,7 +51,7 @@ void FileListWidget::setDirectory(const FilesystemNode& node,
 
   // Initialize history
   FilesystemNode tmp = _node;
-  while(tmp.hasParent())
+  while(tmp.hasParent() && !_history.full())
   {
     string name = tmp.getName();
     if(name.back() == '/' || name.back() == '\\')
@@ -72,22 +73,52 @@ void FileListWidget::setDirectory(const FilesystemNode& node,
 void FileListWidget::setLocation(const FilesystemNode& node,
                                  const string& select)
 {
+  progress().resetProgress();
+  progress().open();
+  FilesystemNode::CancelCheck isCancelled = []() {
+    return myProgressDialog->isCancelled();
+  };
+
   _node = node;
 
   // Read in the data from the file system (start with an empty list)
   _fileList.clear();
-  _fileList.reserve(512);
-  _node.getChildren(_fileList, _fsmode, _filter);
 
-  // Now fill the list widget with the names from the file list
+  if(_includeSubDirs)
+  {
+    // Actually this could become HUGE
+    _fileList.reserve(0x2000);
+    _node.getAllChildren(_fileList, _fsmode, _filter, true, isCancelled);
+  }
+  else
+  {
+    _fileList.reserve(0x200);
+    _node.getChildren(_fileList, _fsmode, _filter, false, true, isCancelled);
+  }
+
+  // Now fill the list widget with the names from the file list,
+  // even if cancelled
   StringList l;
-  for(const auto& file: _fileList)
+  size_t orgLen = node.getShortPath().length();
+
+  _dirList.clear();
+  for(const auto& file : _fileList)
+  {
+    const string path = file.getShortPath();
+
     l.push_back(file.getName());
+    // display only relative path in tooltip
+    if(path.length() >= orgLen)
+      _dirList.push_back(path.substr(orgLen));
+    else
+      _dirList.push_back(path);
+  }
 
   setList(l);
   setSelected(select);
-
   ListWidget::recalc();
+
+  progress().close();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -114,6 +145,21 @@ void FileListWidget::reload()
   }
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ProgressDialog& FileListWidget::progress()
+{
+  if(myProgressDialog == nullptr)
+    myProgressDialog = make_unique<ProgressDialog>(this, _font, "");
+
+  return *myProgressDialog;
+}
+
+void FileListWidget::incProgress()
+{
+  if(_includeSubDirs)
+    progress().incProgress();
+}
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 bool FileListWidget::handleText(char text)
 {
@@ -178,7 +224,10 @@ void FileListWidget::handleCommand(CommandSender* sender, int cmd, int data, int
         }
       }
       else
+      {
+        _selectedFile = selected().getName();
         cmd = ItemActivated;
+      }
       break;
 
     case ListWidget::kLongButtonPressCmd:
@@ -197,5 +246,28 @@ void FileListWidget::handleCommand(CommandSender* sender, int cmd, int data, int
   setTarget(this);
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+string FileListWidget::getToolTip(const Common::Point& pos) const
+{
+  Common::Rect rect = getEditRect();
+  int idx = getToolTipIndex(pos);
+
+  if(idx < 0)
+    return EmptyString;
+
+  if(_includeSubDirs && static_cast<int>(_dirList.size()) > idx)
+    return _toolTipText + _dirList[idx];
+
+  const string value = _list[idx];
+
+  if(uInt32(_font.getStringWidth(value)) > rect.w())
+    return _toolTipText + value;
+  else
+    return _toolTipText;
+}
+
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 uInt64 FileListWidget::_QUICK_SELECT_DELAY = 300;
+
+unique_ptr<ProgressDialog> FileListWidget::myProgressDialog{nullptr};
diff --git a/src/gui/FileListWidget.hxx b/src/gui/FileListWidget.hxx
index 2bcc64048..32f6517f7 100644
--- a/src/gui/FileListWidget.hxx
+++ b/src/gui/FileListWidget.hxx
@@ -19,6 +19,7 @@
 #define FILE_LIST_WIDGET_HXX
 
 class CommandSender;
+class ProgressDialog;
 
 #include "FSNode.hxx"
 #include "Stack.hxx"
@@ -52,19 +53,27 @@ class FileListWidget : public StringListWidget
                    int x, int y, int w, int h);
     ~FileListWidget() override = default;
 
+    string getToolTip(const Common::Point& pos) const override;
+
     /** Determines how to display files/folders; either setDirectory or reload
         must be called after any of these are called. */
     void setListMode(FilesystemNode::ListMode mode) { _fsmode = mode; }
-    void setNameFilter(const FilesystemNode::NameFilter& filter) { _filter = filter; }
+    void setNameFilter(const FilesystemNode::NameFilter& filter) {
+      _filter = filter;
+    }
+
+    // When enabled, all subdirectories will be searched too.
+    void setIncludeSubDirs(bool enable) { _includeSubDirs = enable; }
 
     /**
       Set initial directory, and optionally select the given item.
 
-        @param node  The directory to display.  If this is a file, its parent
-                     will instead be used, and the file will be selected
-        @param select  An optional entry to select (if applicable)
+        @param node       The directory to display.  If this is a file, its parent
+                          will instead be used, and the file will be selected
+        @param select     An optional entry to select (if applicable)
     */
-    void setDirectory(const FilesystemNode& node, const string& select = EmptyString);
+    void setDirectory(const FilesystemNode& node,
+                      const string& select = EmptyString);
 
     /** Select parent directory (if applicable) */
     void selectParent();
@@ -80,6 +89,13 @@ class FileListWidget : public StringListWidget
     const FilesystemNode& currentDir() const { return _node; }
 
     static void setQuickSelectDelay(uInt64 time) { _QUICK_SELECT_DELAY = time; }
+    uInt64 getQuickSelectDelay() { return _QUICK_SELECT_DELAY; }
+
+    ProgressDialog& progress();
+    void incProgress();
+
+  protected:
+    static unique_ptr<ProgressDialog> myProgressDialog;
 
   private:
     /** Very similar to setDirectory(), but also updates the history */
@@ -96,6 +112,9 @@ class FileListWidget : public StringListWidget
     FilesystemNode::NameFilter _filter;
     FilesystemNode _node;
     FSList _fileList;
+    bool _includeSubDirs{false};
+
+    StringList _dirList;
 
     Common::FixedStack<string> _history;
     uInt32 _selected{0};
diff --git a/src/gui/GameInfoDialog.cxx b/src/gui/GameInfoDialog.cxx
index 6017c65d3..57ad900d2 100644
--- a/src/gui/GameInfoDialog.cxx
+++ b/src/gui/GameInfoDialog.cxx
@@ -31,6 +31,7 @@
 #include "PopUpWidget.hxx"
 #include "Props.hxx"
 #include "PropsSet.hxx"
+#include "QuadTariDialog.hxx"
 #include "TabWidget.hxx"
 #include "TIAConstants.hxx"
 #include "Widget.hxx"
@@ -92,7 +93,7 @@ GameInfoDialog::GameInfoDialog(
   for(uInt32 i = 0; i < uInt32(Bankswitch::Type::NumSchemes); ++i)
     VarList::push_back(items, Bankswitch::BSList[i].desc, Bankswitch::BSList[i].name);
   myBSType = new PopUpWidget(myTab, font, t->getRight() + fontWidth, ypos,
-                           pwidth, lineHeight, items, "");
+                             pwidth, lineHeight, items);
   wid.push_back(myBSType);
   ypos += lineHeight + VGAP;
 
@@ -104,7 +105,7 @@ GameInfoDialog::GameInfoDialog(
   myStartBankLabel = new StaticTextWidget(myTab, font, HBORDER, ypos + 1, "Start bank (*) ");
   items.clear();
   myStartBank = new PopUpWidget(myTab, font, myStartBankLabel->getRight(), ypos,
-                                font.getStringWidth("AUTO"), lineHeight, items, "", 0, 0);
+                                font.getStringWidth("AUTO"), lineHeight, items);
   wid.push_back(myStartBank);
   ypos += lineHeight + VGAP * 4;
 
@@ -119,7 +120,7 @@ GameInfoDialog::GameInfoDialog(
   VarList::push_back(items, "PAL60", "PAL60");
   VarList::push_back(items, "SECAM60", "SECAM60");
   myFormat = new PopUpWidget(myTab, font, t->getRight(), ypos,
-                             pwidth, lineHeight, items, "", 0, 0);
+                             pwidth, lineHeight, items);
   wid.push_back(myFormat);
 
   myFormatDetected = new StaticTextWidget(myTab, ifont, myFormat->getRight() + fontWidth, ypos + 4,
@@ -227,6 +228,7 @@ GameInfoDialog::GameInfoDialog(
   VarList::push_back(ctrls, "KidVid", "KIDVID");
   VarList::push_back(ctrls, "Lightgun", "LIGHTGUN");
   VarList::push_back(ctrls, "MindLink", "MINDLINK");
+  VarList::push_back(ctrls, "QuadTari", "QUADTARI");
 
   ypos = VBORDER;
   pwidth = font.getStringWidth("Paddles_IAxis");
@@ -246,20 +248,21 @@ GameInfoDialog::GameInfoDialog(
                                 myRightPortLabel->getTop()-1,
                                 pwidth, lineHeight, ctrls, "", 0, kRightCChanged);
   wid.push_back(myRightPort);
+
   ypos += lineHeight + VGAP;
   myRightPortDetected = new StaticTextWidget(myTab, ifont, myRightPort->getLeft(), ypos,
                                              "Sega Genesis detected");
-  ypos += ifont.getLineHeight() + VGAP + 4;
 
-  mySwapPorts = new CheckboxWidget(myTab, font, myLeftPort->getRight() + fontWidth*4,
-                                   myLeftPort->getTop()+1, "Swap ports");
+  mySwapPorts = new CheckboxWidget(myTab, font, myLeftPort->getRight() + fontWidth * 4,
+                                   myLeftPort->getTop() + 1, "Swap ports");
   wid.push_back(mySwapPorts);
-  mySwapPaddles = new CheckboxWidget(myTab, font, myRightPort->getRight() + fontWidth*4,
-                                     myRightPort->getTop()+1, "Swap paddles");
-  wid.push_back(mySwapPaddles);
+
+  myQuadTariButton = new ButtonWidget(myTab, font, myRightPort->getRight() + fontWidth * 4, myRightPort->getTop() - 2,
+                                      " QuadTari" + ELLIPSIS + " ", kQuadTariPressed);
+  wid.push_back(myQuadTariButton);
 
   // EEPROM erase button for left/right controller
-  //ypos += lineHeight + VGAP + 4;
+  ypos += ifont.getLineHeight() + VGAP + 4;
   pwidth = myRightPort->getWidth();   //font.getStringWidth("Erase EEPROM ") + 23;
   myEraseEEPROMLabel = new StaticTextWidget(myTab, font, HBORDER, ypos, "AtariVox/SaveKey ");
   myEraseEEPROMButton = new ButtonWidget(myTab, font, myEraseEEPROMLabel->getRight(), ypos - 4,
@@ -270,6 +273,10 @@ GameInfoDialog::GameInfoDialog(
                                            "(for this game only)");
   ypos += lineHeight + VGAP * 4;
 
+  mySwapPaddles = new CheckboxWidget(myTab, font, xpos, ypos, "Swap paddles");
+  wid.push_back(mySwapPaddles);
+  ypos += lineHeight + VGAP;
+
   // Paddles
   myPaddlesCenter = new StaticTextWidget(myTab, font, xpos, ypos, "Paddles center:");
   ypos += lineHeight + VGAP;
@@ -292,7 +299,7 @@ GameInfoDialog::GameInfoDialog(
 
   // Mouse
   xpos = HBORDER + fontWidth * 24 - INDENT;
-  ypos = myPaddlesCenter->getTop();
+  ypos = mySwapPaddles->getTop() - 1;
   myMouseControl = new CheckboxWidget(myTab, font, xpos, ypos + 1, "Specific mouse axes",
                                       kMCtrlChanged);
   wid.push_back(myMouseControl);
@@ -387,6 +394,11 @@ GameInfoDialog::GameInfoDialog(
   addBGroupToFocusList(wid);
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+GameInfoDialog::~GameInfoDialog()
+{
+}
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void GameInfoDialog::loadConfig()
 {
@@ -590,8 +602,22 @@ void GameInfoDialog::saveProperties()
   myGameProperties.set(PropType::Console_RightDiff, myRightDiffGroup->getSelected() ? "B" : "A");
 
   // Controller properties
-  myGameProperties.set(PropType::Controller_Left, myLeftPort->getSelectedTag().toString());
-  myGameProperties.set(PropType::Controller_Right, myRightPort->getSelectedTag().toString());
+  string controller = myLeftPort->getSelectedTag().toString();
+  myGameProperties.set(PropType::Controller_Left, controller);
+  if(controller != "AUTO" && controller != "QUADTARI")
+  {
+    myGameProperties.set(PropType::Controller_Left1, "");
+    myGameProperties.set(PropType::Controller_Left2, "");
+  }
+
+  controller = myRightPort->getSelectedTag().toString();
+  myGameProperties.set(PropType::Controller_Right, controller);
+  if(controller != "AUTO" && controller != "QUADTARI")
+  {
+    myGameProperties.set(PropType::Controller_Right1, "");
+    myGameProperties.set(PropType::Controller_Right2, "");
+  }
+
   myGameProperties.set(PropType::Console_SwapPorts, (mySwapPorts->isEnabled() && mySwapPorts->getState()) ? "YES" : "NO");
   myGameProperties.set(PropType::Controller_SwapPaddles, mySwapPaddles->getState() ? "YES" : "NO");
 
@@ -704,8 +730,12 @@ void GameInfoDialog::updateControllerStates()
   if(type == Controller::Type::Unknown)
   {
     if(instance().hasConsole())
+    {
       label = (!swapPorts ? instance().console().leftController().name()
                : instance().console().rightController().name()) + " detected";
+      if(BSPF::startsWithIgnoreCase(label, "QUADTARI"))
+        label = "QuadTari detected"; // remove plugged-in controller names
+    }
     else if(autoDetect)
       label = ControllerDetector::detectName(image, size, type,
                                              !swapPorts ? Controller::Jack::Left : Controller::Jack::Right,
@@ -719,8 +749,12 @@ void GameInfoDialog::updateControllerStates()
   if(type == Controller::Type::Unknown)
   {
     if(instance().hasConsole())
+    {
       label = (!swapPorts ? instance().console().rightController().name()
                : instance().console().leftController().name()) + " detected";
+      if(BSPF::startsWithIgnoreCase(label, "QUADTARI"))
+        label = "QuadTari detected"; // remove plugged-in controller names
+    }
     else if(autoDetect)
       label = ControllerDetector::detectName(image, size, type,
                                              !swapPorts ? Controller::Jack::Right : Controller::Jack::Left,
@@ -759,6 +793,10 @@ void GameInfoDialog::updateControllerStates()
   myRightPortLabel->setEnabled(enableSelectControl);
   myLeftPort->setEnabled(enableSelectControl);
   myRightPort->setEnabled(enableSelectControl);
+  myQuadTariButton->setEnabled(BSPF::startsWithIgnoreCase(contrLeft, "QUADTARI") ||
+                               BSPF::startsWithIgnoreCase(contrRight, "QUADTARI") ||
+                               BSPF::startsWithIgnoreCase(myLeftPortDetected->getLabel(), "QUADTARI") ||
+                               BSPF::startsWithIgnoreCase(myRightPortDetected->getLabel(), "QUADTARI"));
 
   mySwapPorts->setEnabled(enableSelectControl);
   mySwapPaddles->setEnabled(enablePaddles);
@@ -771,7 +809,6 @@ void GameInfoDialog::updateControllerStates()
   myPaddleXCenter->setEnabled(enablePaddles);
   myPaddleYCenter->setEnabled(enablePaddles);
 
-
   bool enableMouse = enablePaddles ||
     BSPF::startsWithIgnoreCase(contrLeft, "Driving") ||
     BSPF::startsWithIgnoreCase(contrRight, "Driving") ||
@@ -818,12 +855,12 @@ void GameInfoDialog::saveCurrentPropertiesToDisk()
     propfile /= myGameFile.getNameWithExt(".pro");
 
     propfile.write(out);
-    instance().frameBuffer().showMessage("Properties saved to " +
-                                         propfile.getShortPath());
+    instance().frameBuffer().showTextMessage("Properties saved to " +
+                                             propfile.getShortPath());
   }
   catch(...)
   {
-    instance().frameBuffer().showMessage("Error saving properties");
+    instance().frameBuffer().showTextMessage("Error saving properties");
   }
 }
 
@@ -831,7 +868,7 @@ void GameInfoDialog::saveCurrentPropertiesToDisk()
 void GameInfoDialog::handleCommand(CommandSender* sender, int cmd,
                                    int data, int id)
 {
-  switch (cmd)
+  switch(cmd)
   {
     case GuiObject::kOKCmd:
       saveConfig();
@@ -859,6 +896,22 @@ void GameInfoDialog::handleCommand(CommandSender* sender, int cmd,
       updateControllerStates();
       break;
 
+    case kQuadTariPressed:
+    {
+      bool enableLeft =
+        BSPF::startsWithIgnoreCase(myLeftPort->getSelectedTag().toString(), "QUADTARI") ||
+        BSPF::startsWithIgnoreCase(myLeftPortDetected->getLabel(), "QUADTARI");
+      bool enableRight =
+        BSPF::startsWithIgnoreCase(myRightPort->getSelectedTag().toString(), "QUADTARI") ||
+        BSPF::startsWithIgnoreCase(myRightPortDetected->getLabel(), "QUADTARI");
+
+      if(!myQuadTariDialog)
+        myQuadTariDialog = make_unique<QuadTariDialog>
+          (this, _font, _font.getMaxCharWidth() * 37, _font.getFontHeight() * 8,
+           myGameProperties);
+      myQuadTariDialog->show(enableLeft, enableRight);
+      break;
+    }
     case kEEButtonPressed:
       eraseEEPROM();
       break;
diff --git a/src/gui/GameInfoDialog.hxx b/src/gui/GameInfoDialog.hxx
index c1302e753..72e3df1a7 100644
--- a/src/gui/GameInfoDialog.hxx
+++ b/src/gui/GameInfoDialog.hxx
@@ -26,6 +26,7 @@ class StaticTextWidget;
 class RadioButtonGroup;
 class TabWidget;
 class SliderWidget;
+class QuadTariDialog;
 
 #include "Dialog.hxx"
 #include "Command.hxx"
@@ -36,7 +37,7 @@ class GameInfoDialog : public Dialog, public CommandSender
   public:
     GameInfoDialog(OSystem& osystem, DialogContainer& parent,
                    const GUI::Font& font, GuiObject* boss, int max_w, int max_h);
-    ~GameInfoDialog() override = default;
+    ~GameInfoDialog() override;
 
   private:
     void loadConfig() override;
@@ -87,6 +88,7 @@ class GameInfoDialog : public Dialog, public CommandSender
     StaticTextWidget* myLeftPortDetected{nullptr};
     PopUpWidget*      myRightPort{nullptr};
     StaticTextWidget* myRightPortDetected{nullptr};
+    ButtonWidget*     myQuadTariButton{nullptr};
     CheckboxWidget*   mySwapPorts{nullptr};
     CheckboxWidget*   mySwapPaddles{nullptr};
     StaticTextWidget* myEraseEEPROMLabel{nullptr};
@@ -100,6 +102,9 @@ class GameInfoDialog : public Dialog, public CommandSender
     PopUpWidget*      myMouseY{nullptr};
     SliderWidget*     myMouseRange{nullptr};
 
+    // Allow assigning the four QuadTari controllers
+    unique_ptr<QuadTariDialog> myQuadTariDialog;
+
     // Cartridge properties
     EditTextWidget*   myName{nullptr};
     EditTextWidget*   myMD5{nullptr};
@@ -114,6 +119,7 @@ class GameInfoDialog : public Dialog, public CommandSender
       kPPBlendChanged  = 'PBch',
       kLeftCChanged    = 'LCch',
       kRightCChanged   = 'RCch',
+      kQuadTariPressed = 'QTpr',
       kMCtrlChanged    = 'MCch',
       kEEButtonPressed = 'EEgb',
       kPXCenterChanged = 'Pxch',
diff --git a/src/gui/GuiObject.hxx b/src/gui/GuiObject.hxx
index 77392209c..85424a670 100644
--- a/src/gui/GuiObject.hxx
+++ b/src/gui/GuiObject.hxx
@@ -41,6 +41,21 @@ class GuiObject : public CommandReceiver
   friend class Widget;
   friend class DialogContainer;
 
+  public:
+    enum : uInt32 {
+      FLAG_ENABLED = 1 << 0,
+      FLAG_INVISIBLE = 1 << 1,
+      FLAG_HILITED = 1 << 2,
+      FLAG_BORDER = 1 << 3,
+      FLAG_CLEARBG = 1 << 4,
+      FLAG_TRACK_MOUSE = 1 << 5,
+      FLAG_RETAIN_FOCUS = 1 << 6,
+      FLAG_WANTS_TAB = 1 << 7,
+      FLAG_WANTS_RAWDATA = 1 << 8,
+      FLAG_NOBG = 1 << 9,
+      FLAG_MOUSE_FOCUS = 1 << 10
+    };
+
   public:
     // The commands generated by various widgets
     enum {
@@ -77,7 +92,41 @@ class GuiObject : public CommandReceiver
     virtual void setHeight(int h)   { _h = h; }
 
     virtual bool isVisible() const = 0;
+
     virtual void setDirty() = 0;
+    virtual void setDirtyChain() = 0;
+    void clearDirty() { _dirty = false; }
+    void clearDirtyChain() { _dirtyChain = false; }
+    bool isDirty() const { return _dirty; }
+    bool isChainDirty() const { return _dirtyChain; }
+
+    // The GUI indicates if its underlying surface needs to be redrawn
+    //  and then re-rendered
+    virtual bool needsRedraw() { return isDirty() || isChainDirty(); }
+
+    virtual void tick() = 0;
+
+    void setFlags(uInt32 flags, bool updateDirty = true)
+    {
+      uInt32 oldFlags = _flags;
+
+      _flags |= flags;
+      if(updateDirty && oldFlags != _flags)
+        setDirty();
+    }
+    void clearFlags(uInt32 flags, bool updateDirty = true)
+    {
+      uInt32 oldFlags = _flags;
+
+      _flags &= ~flags;
+      if(updateDirty && oldFlags != _flags)
+        setDirty();
+    }
+    uInt32 getFlags() const { return _flags; }
+
+    bool hasBorder() const { return _flags & FLAG_BORDER; }
+    bool clearsBackground() const { return _flags & FLAG_CLEARBG; }
+    bool hasBackground() const { return !(_flags & FLAG_NOBG); }
 
     /** Add given widget(s) to the focus list */
     virtual void addFocusWidget(Widget* w) = 0;
@@ -96,6 +145,7 @@ class GuiObject : public CommandReceiver
   protected:
     virtual void releaseFocus() = 0;
     virtual void draw() = 0;
+    virtual void drawChain() = 0;
 
   private:
     OSystem&         myOSystem;
@@ -103,9 +153,12 @@ class GuiObject : public CommandReceiver
     Dialog&          myDialog;
 
   protected:
-    int _x{0}, _y{0}, _w{0}, _h{0};
+    int         _x{0}, _y{0}, _w{0}, _h{0};
+    bool        _dirty{false};
+    bool        _dirtyChain{false};
+    uInt32      _flags{0};
 
-    Widget* _firstWidget{nullptr};
+    Widget*     _firstWidget{nullptr};
     WidgetArray _focusList;
 
   private:
diff --git a/src/gui/HelpDialog.cxx b/src/gui/HelpDialog.cxx
index 77c01f174..0b08ca0cc 100644
--- a/src/gui/HelpDialog.cxx
+++ b/src/gui/HelpDialog.cxx
@@ -134,16 +134,16 @@ void HelpDialog::updateStrings(uInt8 page, uInt8 lines, string& title)
 
     case 3:
       title = "TV effects";
-      ADD_EVENT(Event::VidmodeStd,          "Disable TV effects");
-      ADD_EVENT(Event::VidmodeRGB,          "Enable 'RGB' mode");
-      ADD_EVENT(Event::VidmodeSVideo,       "Enable 'S-Video' mode");
-      ADD_EVENT(Event::VidModeComposite,    "Enable 'Composite' mode");
-      ADD_EVENT(Event::VidModeBad,          "Enable 'Badly adjusted' mode");
-      ADD_EVENT(Event::VidModeCustom,       "Enable 'Custom' mode");
-      ADD_EVENT(Event::NextAttribute,       "Select 'Custom' attribute");
-      ADD_EVENT(Event::IncreaseAttribute,   "Modify 'Custom' attribute");
-      ADD_EVENT(Event::PhosphorIncrease,    "Adjust phosphor blend");
-      ADD_EVENT(Event::ScanlinesIncrease,   "Adjust scanline intensity");
+      ADD_EVENT(Event::NextVideoMode,       "Select next TV effect mode");
+      ADD_EVENT(Event::PreviousVideoMode,   "Select previous TV effect mode");
+      ADD_EVENT(Event::NextAttribute,       "Select next 'Custom' attribute");
+      ADD_EVENT(Event::PreviousAttribute,   "Select previous 'Custom' attr.");
+      ADD_EVENT(Event::IncreaseAttribute,   "Increase 'Custom' attribute");
+      ADD_EVENT(Event::DecreaseAttribute,   "Decrease 'Custom' attribute");
+      ADD_EVENT(Event::PhosphorIncrease,    "Increase phosphor blend");
+      ADD_EVENT(Event::PhosphorDecrease,    "Decrease phosphor blend");
+      ADD_EVENT(Event::ScanlinesIncrease,   "Increase scanline intensity");
+      ADD_EVENT(Event::ScanlinesDecrease,   "Decrease scanline intensity");
       break;
 
     case 4:
diff --git a/src/gui/InputDialog.cxx b/src/gui/InputDialog.cxx
index 727c9a874..82dae982a 100644
--- a/src/gui/InputDialog.cxx
+++ b/src/gui/InputDialog.cxx
@@ -34,6 +34,7 @@
 #include "Widget.hxx"
 #include "Font.hxx"
 #include "MessageBox.hxx"
+#include "MediaFactory.hxx"
 #include "InputDialog.hxx"
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -129,7 +130,7 @@ void InputDialog::addDevicePortTab()
   myDeadzone->setTickmarkIntervals(4);
   wid.push_back(myDeadzone);
 
-  xpos = HBORDER; ypos += lineHeight + VGAP * 4;
+  xpos = HBORDER; ypos += lineHeight + VGAP * 3;
   new StaticTextWidget(myTab, _font, xpos, ypos+1, "Analog paddle:");
   xpos += fontWidth * 2;
 
@@ -164,7 +165,7 @@ void InputDialog::addDevicePortTab()
   wid.push_back(myDejitterDiff);
 
   // Add paddle speed (digital emulation)
-  ypos += lineHeight + VGAP * 4;
+  ypos += lineHeight + VGAP * 3;
   myDPaddleSpeed = new SliderWidget(myTab, _font, HBORDER, ypos - 1, 13 * fontWidth, lineHeight,
                                     "Digital paddle sensitivity",
                                     lwidth, kDPSpeedChanged, 4 * fontWidth, "%");
@@ -172,7 +173,7 @@ void InputDialog::addDevicePortTab()
   myDPaddleSpeed->setTickmarkIntervals(4);
   wid.push_back(myDPaddleSpeed);
 
-  ypos += lineHeight + VGAP * 4;
+  ypos += lineHeight + VGAP * 3;
   myAutoFireRate = new SliderWidget(myTab, _font, HBORDER, ypos - 1, 13 * fontWidth, lineHeight,
                                     "Autofire rate",
                                     lwidth, kAutoFireChanged, 5 * fontWidth, "Hz");
@@ -222,10 +223,10 @@ void InputDialog::addDevicePortTab()
   // Add AtariVox serial port
   ypos += lineHeight + VGAP * 3;
   lwidth = _font.getStringWidth("AtariVox serial port ");
-  fwidth = _w - HBORDER * 2 - 2 - lwidth;
-  new StaticTextWidget(myTab, _font, HBORDER, ypos + 2, "AtariVox serial port ");
-  myAVoxPort = new EditTextWidget(myTab, _font, HBORDER + lwidth, ypos,
-                                  fwidth, fontHeight);
+  fwidth = _w - HBORDER * 2 - 2 - lwidth - PopUpWidget::dropDownWidth(_font);
+  myAVoxPort = new PopUpWidget(myTab, _font, HBORDER, ypos, fwidth, lineHeight, EmptyVarList,
+                               "AtariVox serial port ", lwidth, kCursorStateChanged);
+  myAVoxPort->setEditable(true);
   wid.push_back(myAVoxPort);
 
   // Add items for virtual device ports
@@ -359,7 +360,19 @@ void InputDialog::loadConfig()
   myAutoFireRate->setValue(settings.getInt("autofirerate"));
 
   // AtariVox serial port
-  myAVoxPort->setText(settings.getString("avoxport"));
+  const string& avoxport = settings.getString("avoxport");
+  const StringList ports = MediaFactory::createSerialPort()->portNames();
+  VariantList items;
+
+  for(const auto& port: ports)
+    VarList::push_back(items, port, port);
+  if(avoxport != EmptyString && !BSPF::contains(ports, avoxport))
+    VarList::push_back(items, avoxport, avoxport);
+  if(items.size() == 0)
+    VarList::push_back(items, "None detected");
+
+  myAVoxPort->addItems(items);
+  myAVoxPort->setSelected(avoxport);
 
   // EEPROM erase (only enable in emulation mode and for valid controllers)
   if(instance().hasConsole())
@@ -479,17 +492,11 @@ void InputDialog::setDefaults()
       break;
 
     case 2:  // Devices & Ports
-      // Left & right ports
-      mySAPort->setState(false);
-
       // Joystick deadzone
       myDeadzone->setValue(0);
 
       // Paddle speed (analog)
       myPaddleSpeed->setValue(20);
-
-      // Paddle speed (digital)
-      myDPaddleSpeed->setValue(10);
     #if defined(RETRON77)
       myDejitterBase->setValue(2);
       myDejitterDiff->setValue(6);
@@ -497,10 +504,12 @@ void InputDialog::setDefaults()
       myDejitterBase->setValue(0);
       myDejitterDiff->setValue(0);
     #endif
+
+      // Paddle speed (digital)
+      myDPaddleSpeed->setValue(10);
+
       // Autofire rate
       myAutoFireRate->setValue(0);
-      // AtariVox serial port
-      myAVoxPort->setText("");
 
       // Allow all 4 joystick directions
       myAllowAll4->setState(false);
@@ -508,6 +517,11 @@ void InputDialog::setDefaults()
       // Enable/disable modifier key-combos
       myModCombo->setState(true);
 
+      // Left & right ports
+      mySAPort->setState(false);
+
+      // AtariVox serial port
+      myAVoxPort->setSelectedIndex(0);
       break;
 
     case 3:  // Mouse
@@ -658,7 +672,8 @@ void InputDialog::handleCommand(CommandSender* sender, int cmd,
       break;
 
     case kPSpeedChanged:
-      myPaddleSpeed->setValueLabel(Paddles::setAnalogSensitivity(myPaddleSpeed->getValue()) * 100.F + 0.5F);
+      myPaddleSpeed->setValueLabel(std::round(Paddles::setAnalogSensitivity(
+            myPaddleSpeed->getValue()) * 100.F));
       break;
 
     case kDejitterAvChanged:
diff --git a/src/gui/InputDialog.hxx b/src/gui/InputDialog.hxx
index 6cb6c4742..201f807d3 100644
--- a/src/gui/InputDialog.hxx
+++ b/src/gui/InputDialog.hxx
@@ -94,7 +94,7 @@ class InputDialog : public Dialog
 
     CheckboxWidget*   mySAPort{nullptr};
 
-    EditTextWidget*   myAVoxPort{nullptr};
+    PopUpWidget*      myAVoxPort{nullptr};
 
     SliderWidget*     myDeadzone{nullptr};
     SliderWidget*     myPaddleSpeed{nullptr};
diff --git a/src/gui/InputTextDialog.cxx b/src/gui/InputTextDialog.cxx
index 12e7a66d4..4c34de23e 100644
--- a/src/gui/InputTextDialog.cxx
+++ b/src/gui/InputTextDialog.cxx
@@ -81,9 +81,10 @@ void InputTextDialog::initialize(const GUI::Font& lfont, const GUI::Font& nfont,
   for(i = 0; i < labels.size(); ++i)
   {
     xpos = HBORDER;
-    new StaticTextWidget(this, lfont, xpos, ypos + 2,
-                         lwidth, fontHeight,
-                         labels[i], TextAlign::Left);
+    StaticTextWidget* s = new StaticTextWidget(this, lfont, xpos, ypos + 2,
+                                               lwidth, fontHeight,
+                                               labels[i]);
+    myLabel.push_back(s);
 
     xpos += lwidth + fontWidth;
     EditTextWidget* w = new EditTextWidget(this, nfont, xpos, ypos,
@@ -130,7 +131,7 @@ void InputTextDialog::show(uInt32 x, uInt32 y, const Common::Rect& bossRect)
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void InputTextDialog::center()
+void InputTextDialog::setPosition()
 {
   if(!myEnableCenter)
   {
@@ -144,7 +145,7 @@ void InputTextDialog::center()
       surface().setDstPos(myXOrig, myYOrig);
   }
   else
-    Dialog::center();
+    Dialog::setPosition();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -177,6 +178,13 @@ void InputTextDialog::setTextFilter(const EditableWidget::TextFilter& f, int idx
     myInput[idx]->setTextFilter(f);
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void InputTextDialog::setToolTip(const string& str, int idx)
+{
+  if(uInt32(idx) < myLabel.size())
+    myLabel[idx]->setToolTip(str);
+}
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void InputTextDialog::setFocus(int idx)
 {
diff --git a/src/gui/InputTextDialog.hxx b/src/gui/InputTextDialog.hxx
index e89e00651..059c7ada7 100644
--- a/src/gui/InputTextDialog.hxx
+++ b/src/gui/InputTextDialog.hxx
@@ -46,6 +46,7 @@ class InputTextDialog : public Dialog, public CommandSender
 
     void setText(const string& str, int idx = 0);
     void setTextFilter(const EditableWidget::TextFilter& f, int idx = 0);
+    void setToolTip(const string& str, int idx = 0);
 
     void setEmitSignal(int cmd) { myCmd = cmd; }
     void setMessage(const string& title);
@@ -58,9 +59,10 @@ class InputTextDialog : public Dialog, public CommandSender
     void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
 
     /** This dialog uses its own positioning, so we override Dialog::center() */
-    void center() override;
+    void setPosition() override;
 
   private:
+    vector<StaticTextWidget*> myLabel;
     vector<EditTextWidget*> myInput;
     StaticTextWidget* myMessage{nullptr};
 
diff --git a/src/gui/Launcher.cxx b/src/gui/Launcher.cxx
index 315a14f41..694395cfa 100644
--- a/src/gui/Launcher.cxx
+++ b/src/gui/Launcher.cxx
@@ -29,24 +29,20 @@
 Launcher::Launcher(OSystem& osystem)
   : DialogContainer(osystem)
 {
-  const Common::Size& s = myOSystem.settings().getSize("launcherres");
+  mySize = myOSystem.settings().getSize("launcherres");
   const Common::Size& d = myOSystem.frameBuffer().desktopSize();
   double overscan = 1 - myOSystem.settings().getInt("tia.fs_overscan") / 100.0;
-  myWidth = s.w;  myHeight = s.h;
 
   // The launcher dialog is resizable, within certain bounds
   // We check those bounds now
-  myWidth  = std::max(myWidth,  FBMinimum::Width);
-  myHeight = std::max(myHeight, FBMinimum::Height);
-  myWidth  = std::min(myWidth,  d.w);
-  myHeight = std::min(myHeight, d.h);
-  // do not include overscan when launcher saving size
-  myOSystem.settings().setValue("launcherres", Common::Size(myWidth, myHeight));
-  // now make overscan effective
-  myWidth  = std::min(myWidth,  uInt32(d.w * overscan));
-  myHeight = std::min(myHeight, uInt32(d.h * overscan));
+  mySize.clamp(FBMinimum::Width, d.w, FBMinimum::Height, d.h);
+  // Do not include overscan when launcher saving size
+  myOSystem.settings().setValue("launcherres", mySize);
+  // Now make overscan effective
+  mySize.w = std::min(mySize.w, uInt32(d.w * overscan));
+  mySize.h = std::min(mySize.h, uInt32(d.h * overscan));
 
-  myBaseDialog = new LauncherDialog(myOSystem, *this, 0, 0, myWidth, myHeight);
+  myBaseDialog = new LauncherDialog(myOSystem, *this, 0, 0, mySize.w, mySize.h);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -59,8 +55,9 @@ Launcher::~Launcher()
 FBInitStatus Launcher::initializeVideo()
 {
   string title = string("Stella ") + STELLA_VERSION;
-  return myOSystem.frameBuffer().createDisplay(title, FrameBuffer::BufferType::Launcher,
-                                               myWidth, myHeight);
+  return myOSystem.frameBuffer().createDisplay(
+      title, BufferType::Launcher, mySize
+  );
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/gui/Launcher.hxx b/src/gui/Launcher.hxx
index 4148db945..9f5cecaa4 100644
--- a/src/gui/Launcher.hxx
+++ b/src/gui/Launcher.hxx
@@ -22,6 +22,7 @@ class Properties;
 class OSystem;
 class FilesystemNode;
 
+#include "Rect.hxx"
 #include "FrameBufferConstants.hxx"
 #include "DialogContainer.hxx"
 
@@ -72,9 +73,8 @@ class Launcher : public DialogContainer
   private:
     Dialog* myBaseDialog{nullptr};
 
-    // The width and height of this dialog
-    uInt32 myWidth{0};
-    uInt32 myHeight{0};
+    // The dimensions of this dialog
+    Common::Size mySize;
 
   private:
     // Following constructors and assignment operators not supported
diff --git a/src/gui/LauncherDialog.cxx b/src/gui/LauncherDialog.cxx
index 3f6ddcec8..4a8f437d4 100644
--- a/src/gui/LauncherDialog.cxx
+++ b/src/gui/LauncherDialog.cxx
@@ -29,7 +29,10 @@
 #include "GlobalPropsDialog.hxx"
 #include "StellaSettingsDialog.hxx"
 #include "WhatsNewDialog.hxx"
+#include "ProgressDialog.hxx"
 #include "MessageBox.hxx"
+#include "ToolTip.hxx"
+#include "TimerManager.hxx"
 #include "OSystem.hxx"
 #include "FrameBuffer.hxx"
 #include "FBSurface.hxx"
@@ -72,23 +75,71 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
             buttonHeight = myUseMinimalUI ? lineHeight - VGAP * 2: lineHeight * 1.25,
             buttonWidth  = (_w - 2 * HBORDER - BUTTON_GAP * (4 - 1));
 
-  int xpos = HBORDER, ypos = VBORDER, lwidth = 0, lwidth2 = 0;
+  int xpos = HBORDER, ypos = VBORDER;
   WidgetArray wid;
-  string lblRom = "Select a ROM from the list" + ELLIPSIS;
+  string lblSelect = "Select a ROM from the list" + ELLIPSIS;
+  string lblAllFiles = "Show all files";
   const string& lblFilter = "Filter";
-  const string& lblAllFiles = "Show all files";
-  const string& lblFound = "XXXX items found";
+  string lblSubDirs = "Incl. subdirectories";
+  string lblFound = "12345 items found";
 
-  lwidth = font.getStringWidth(lblRom);
-  lwidth2 = font.getStringWidth(lblAllFiles) + CheckboxWidget::boxSize(font);
-  int lwidth3 = font.getStringWidth(lblFilter);
-  int lwidth4 = font.getStringWidth(lblFound);
+  tooltip().setFont(font);
 
-  if(w < HBORDER * 2 + lwidth + lwidth2 + lwidth3 + lwidth4 + fontWidth * 6 + LBL_GAP * 8)
+  int lwSelect = font.getStringWidth(lblSelect);
+  int cwAllFiles = font.getStringWidth(lblAllFiles) + CheckboxWidget::prefixSize(font);
+  int cwSubDirs = font.getStringWidth(lblSubDirs) + CheckboxWidget::prefixSize(font);
+  int lwFilter = font.getStringWidth(lblFilter);
+  int lwFound = font.getStringWidth(lblFound);
+  int wTotal = HBORDER * 2 + lwSelect + cwAllFiles + cwSubDirs + lwFilter + lwFound
+    + EditTextWidget::calcWidth(font, "123456") + LBL_GAP * 7;
+  bool noSelect = false;
+
+  if(w < wTotal)
   {
     // make sure there is space for at least 6 characters in the filter field
-    lblRom = "Select a ROM" + ELLIPSIS;
-    lwidth = font.getStringWidth(lblRom);
+    lblSelect = "Select a ROM" + ELLIPSIS;
+    int lwSelectShort = font.getStringWidth(lblSelect);
+
+    wTotal -= lwSelect - lwSelectShort;
+    lwSelect = lwSelectShort;
+  }
+  if(w < wTotal)
+  {
+    // make sure there is space for at least 6 characters in the filter field
+    lblSubDirs = "Subdir.";
+    int cwSubDirsShort = font.getStringWidth(lblSubDirs) + CheckboxWidget::prefixSize(font);
+
+    wTotal -= cwSubDirs - cwSubDirsShort;
+    cwSubDirs = cwSubDirsShort;
+  }
+  if(w < wTotal)
+  {
+    // make sure there is space for at least 6 characters in the filter field
+    lblAllFiles = "All files";
+    int cwAllFilesShort = font.getStringWidth(lblAllFiles) + CheckboxWidget::prefixSize(font);
+
+    wTotal -= cwAllFiles - cwAllFilesShort;
+    cwAllFiles = cwAllFilesShort;
+  }
+  if(w < wTotal)
+  {
+    // make sure there is space for at least 6 characters in the filter field
+    lblFound = "12345 found";
+    int lwFoundShort = font.getStringWidth(lblFound);
+
+    wTotal -= lwFound - lwFoundShort;
+    lwFound = lwFoundShort;
+    myShortCount = true;
+  }
+  if(w < wTotal)
+  {
+    // make sure there is space for at least 6 characters in the filter field
+    lblSelect = "";
+    int lwSelectShort = font.getStringWidth(lblSelect);
+
+    wTotal -= lwSelect - lwSelectShort;
+    lwSelect = lwSelectShort;
+    noSelect = true;
   }
 
   if(myUseMinimalUI)
@@ -105,29 +156,49 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
   }
 
   // Show the header
-  new StaticTextWidget(this, font, xpos, ypos, lblRom);
+  new StaticTextWidget(this, font, xpos, ypos, lblSelect);
   // Shop the files counter
-  xpos = _w - HBORDER - lwidth4;
+  xpos = _w - HBORDER - lwFound;
   myRomCount = new StaticTextWidget(this, font, xpos, ypos,
-                                    lwidth4, fontHeight,
+                                    lwFound, fontHeight,
                                     "", TextAlign::Right);
 
   // Add filter that can narrow the results shown in the listing
   // It has to fit between both labels
   if(!myUseMinimalUI && w >= 640)
   {
-    int fwidth = std::min(15 * fontWidth, xpos - lwidth3 - lwidth2 - lwidth - HBORDER - LBL_GAP * 8);
+    int fwFilter = std::min(EditTextWidget::calcWidth(font, "123456789012345"),
+                            xpos - cwSubDirs - lwFilter - cwAllFiles
+                            - lwSelect - HBORDER - LBL_GAP * (noSelect ? 5 : 7));
+
     // Show the filter input field
-    xpos -= fwidth + LBL_GAP;
-    myPattern = new EditTextWidget(this, font, xpos, ypos - 2, fwidth, lineHeight, "");
+    xpos -= fwFilter + LBL_GAP;
+    myPattern = new EditTextWidget(this, font, xpos, ypos - 2, fwFilter, lineHeight, "");
+    myPattern->setToolTip("Enter filter text to reduce file list.\n"
+                          "Use '*' and '?' as wildcards.");
+
     // Show the "Filter" label
-    xpos -= lwidth3 + LBL_GAP;
+    xpos -= lwFilter + LBL_GAP;
     new StaticTextWidget(this, font, xpos, ypos, lblFilter);
+
+    // Show the subdirectories checkbox
+    xpos -= cwSubDirs + LBL_GAP * 2;
+    mySubDirs = new CheckboxWidget(this, font, xpos, ypos, lblSubDirs, kSubDirsCmd);
+    ostringstream tip;
+    tip << "Search files in subdirectories too.";
+    mySubDirs->setToolTip(tip.str());
+
     // Show the checkbox for all files
-    xpos -= lwidth2 + LBL_GAP * 3;
+    if(noSelect)
+      xpos = HBORDER;
+    else
+      xpos -= cwAllFiles + LBL_GAP;
     myAllFiles = new CheckboxWidget(this, font, xpos, ypos, lblAllFiles, kAllfilesCmd);
+    myAllFiles->setToolTip("Uncheck to show ROM files only.");
+
     wid.push_back(myAllFiles);
     wid.push_back(myPattern);
+    wid.push_back(mySubDirs);
   }
 
   // Add list with game titles
@@ -162,11 +233,11 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
 
   // Add textfield to show current directory
   xpos = HBORDER;
-  ypos += myList->getHeight() + VGAP * 2;
-  lwidth = font.getStringWidth("Path") + LBL_GAP;
-  myDirLabel = new StaticTextWidget(this, font, xpos, ypos+2, lwidth, fontHeight,
+  ypos += myList->getHeight() + VGAP;
+  lwSelect = font.getStringWidth("Path") + LBL_GAP;
+  myDirLabel = new StaticTextWidget(this, font, xpos, ypos+2, lwSelect, fontHeight,
                                     "Path", TextAlign::Left);
-  xpos += lwidth;
+  xpos += lwSelect;
   myDir = new EditTextWidget(this, font, xpos, ypos, _w - xpos - HBORDER, lineHeight, "");
   myDir->setEditable(false, true);
   myDir->clearFlags(Widget::FLAG_RETAIN_FOCUS);
@@ -214,11 +285,12 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
                                      "Select", kLoadROMCmd);
     wid.push_back(myStartButton);
   #endif
+    myStartButton->setToolTip("Start emulation of selected ROM.");
   }
   if(myUseMinimalUI) // Highlight 'Rom Listing'
     mySelectedItem = 0;
   else
-    mySelectedItem = 2;
+    mySelectedItem = 3;
 
   addToFocusList(wid);
 
@@ -230,6 +302,10 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
   myGlobalProps = make_unique<GlobalPropsDialog>(this,
     myUseMinimalUI ? osystem.frameBuffer().launcherFont() : osystem.frameBuffer().font());
 
+  // since we cannot know how many files there are, use are really high value here
+  myList->progress().setRange(0, 50000, 5);
+  myList->progress().setMessage("        Filtering files" + ELLIPSIS + "        ");
+
   // Do we show only ROMs or all files?
   bool onlyROMs = instance().settings().getBool("launcherroms");
   showOnlyROMs(onlyROMs);
@@ -278,6 +354,16 @@ void LauncherDialog::reload()
 {
   myMD5List.clear();
   myList->reload();
+  myPendingReload = false;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void LauncherDialog::tick()
+{
+  if(myPendingReload && myReloadTime < TimerManager::getTicks() / 1000)
+    reload();
+
+  Dialog::tick();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -297,6 +383,10 @@ void LauncherDialog::loadConfig()
     instance().settings().setValue("stella.version", STELLA_VERSION);
   }
 
+  bool subDirs = instance().settings().getBool("launchersubdirs");
+  if (mySubDirs) mySubDirs->setState(subDirs);
+  myList->setIncludeSubDirs(subDirs);
+
   // Assume that if the list is empty, this is the first time that loadConfig()
   // has been called (and we should reload the list)
   if(myList->getList().empty())
@@ -319,6 +409,7 @@ void LauncherDialog::loadConfig()
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void LauncherDialog::saveConfig()
 {
+  instance().settings().setValue("launchersubdirs", mySubDirs->getState());
   if(instance().settings().getBool("followlauncher"))
     instance().settings().setValue("romdir", myList->currentDir().getShortPath());
 }
@@ -335,18 +426,88 @@ void LauncherDialog::updateUI()
 
   // Indicate how many files were found
   ostringstream buf;
-  buf << (myList->getList().size() - 1) << " items found";
+  buf << (myList->getList().size() - 1) << (myShortCount ? " found" : " items found");
   myRomCount->setLabel(buf.str());
 
   // Update ROM info UI item
   loadRomInfo();
 }
 
+size_t LauncherDialog::matchWithJoker(const string& str, const string& pattern)
+{
+  if(str.length() >= pattern.length())
+  {
+    // optimize a bit
+    if(pattern.find('?') != string::npos)
+    {
+      for(size_t pos = 0; pos < str.length() - pattern.length() + 1; ++pos)
+      {
+        bool found = true;
+
+        for(size_t i = 0; found && i < pattern.length(); ++i)
+          if(pattern[i] != str[pos + i] && pattern[i] != '?')
+            found = false;
+
+        if(found)
+          return pos;
+      }
+    }
+    else
+      return str.find(pattern);
+  }
+  return string::npos;
+}
+
+bool LauncherDialog::matchWithWildcards(const string& str, const string& pattern)
+{
+  string pat = pattern;
+
+  // remove leading and trailing '*'
+  size_t i = 0;
+  while(pat[i++] == '*');
+  pat = pat.substr(i - 1);
+
+  i = pat.length();
+  while(pat[--i] == '*');
+  pat.erase(i + 1);
+
+  // Search for first '*'
+  size_t pos = pat.find('*');
+
+  if(pos != string::npos)
+  {
+    // '*' found, split pattern into left and right part, search recursively
+    const string leftPat = pat.substr(0, pos);
+    const string rightPat = pat.substr(pos + 1);
+    size_t posLeft = matchWithJoker(str, leftPat);
+
+    if(posLeft != string::npos)
+      return matchWithWildcards(str.substr(pos + posLeft), rightPat);
+    else
+      return false;
+  }
+  // no further '*' found
+  return matchWithJoker(str, pat) != string::npos;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool LauncherDialog::matchWithWildcardsIgnoreCase(const string& str, const string& pattern)
+{
+  string in = str;
+  string pat = pattern;
+
+  BSPF::toUpperCase(in);
+  BSPF::toUpperCase(pat);
+
+  return matchWithWildcards(in, pat);
+}
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void LauncherDialog::applyFiltering()
 {
   myList->setNameFilter(
     [&](const FilesystemNode& node) {
+      myList->incProgress();
       if(!node.isDirectory())
       {
         // Do we want to show only ROMs or all files?
@@ -355,7 +516,7 @@ void LauncherDialog::applyFiltering()
 
         // Skip over files that don't match the pattern in the 'pattern' textbox
         if(myPattern && myPattern->getText() != "" &&
-          !BSPF::containsIgnoreCase(node.getName(), myPattern->getText()))
+           !matchWithWildcardsIgnoreCase(node.getName(), myPattern->getText()))
           return false;
       }
       return true;
@@ -589,6 +750,11 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd,
       reload();
       break;
 
+    case kSubDirsCmd:
+      myList->setIncludeSubDirs(mySubDirs->getState());
+      reload();
+      break;
+
     case kLoadROMCmd:
     case FileListWidget::ItemActivated:
       saveConfig();
@@ -614,9 +780,23 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd,
       break;
 
     case EditableWidget::kChangedCmd:
+    case EditableWidget::kAcceptCmd:
+    {
+      bool subDirs = mySubDirs->getState();
+
+      myList->setIncludeSubDirs(subDirs);
       applyFiltering();  // pattern matching taken care of directly in this method
-      reload();
+
+      if(subDirs && cmd == EditableWidget::kChangedCmd)
+      {
+        // delay (potentially slow) subdirectories reloads until user stops typing
+        myReloadTime = TimerManager::getTicks() / 1000 + myList->getQuickSelectDelay();
+        myPendingReload = true;
+      }
+      else
+        reload();
       break;
+    }
 
     case kQuitCmd:
       saveConfig();
@@ -662,7 +842,7 @@ void LauncherDialog::loadRom()
       instance().settings().setValue("romdir", currentNode().getParent().getShortPath());
   }
   else
-    instance().frameBuffer().showMessage(result, MessagePosition::MiddleCenter, true);
+    instance().frameBuffer().showTextMessage(result, MessagePosition::MiddleCenter, true);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/gui/LauncherDialog.hxx b/src/gui/LauncherDialog.hxx
index 0dd9b898d..a5acc262f 100644
--- a/src/gui/LauncherDialog.hxx
+++ b/src/gui/LauncherDialog.hxx
@@ -95,13 +95,15 @@ class LauncherDialog : public Dialog
     */
     void reload();
 
+    void tick() override;
+
   private:
     static constexpr int MIN_LAUNCHER_CHARS = 24;
     static constexpr int MIN_ROMINFO_CHARS = 30;
     static constexpr int MIN_ROMINFO_ROWS = 7; // full lines
     static constexpr int MIN_ROMINFO_LINES = 4; // extra lines
 
-    void center() override { positionAt(0); }
+    void setPosition() override { positionAt(0); }
     void handleKeyDown(StellaKey key, StellaMod mod, bool repeated) override;
     void handleMouseDown(int x, int y, MouseButton b, int clickCount) override;
     void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
@@ -112,6 +114,39 @@ class LauncherDialog : public Dialog
     void loadConfig() override;
     void saveConfig() override;
     void updateUI();
+
+    /**
+      Search if string contains pattern including wildcard '*'
+      and '?' as joker, ignoring case.
+
+      @param str      The searched string
+      @param pattern  The pattern to search for
+
+      @return True if pattern was found.
+    */
+    bool matchWithWildcardsIgnoreCase(const string& str, const string& pattern);
+
+    /**
+      Search if string contains pattern including wildcard '*'
+      and '?' as joker.
+
+      @param str      The searched string
+      @param pattern  The pattern to search for
+
+      @return True if pattern was found.
+    */
+    bool matchWithWildcards(const string& str, const string& pattern);
+
+    /**
+      Search if string contains pattern including '?' as joker.
+
+      @param str      The searched string
+      @param pattern  The pattern to search for
+
+      @return Position of pattern in string.
+    */
+    size_t matchWithJoker(const string& str, const string& pattern);
+
     void applyFiltering();
 
     float getRomInfoZoom(int listHeight) const;
@@ -136,19 +171,22 @@ class LauncherDialog : public Dialog
     // automatically sized font for ROM info viewer
     unique_ptr<GUI::Font> myROMInfoFont;
 
-    ButtonWidget* myStartButton{nullptr};
-    ButtonWidget* myPrevDirButton{nullptr};
-    ButtonWidget* myOptionsButton{nullptr};
-    ButtonWidget* myQuitButton{nullptr};
+    CheckboxWidget*   myAllFiles{nullptr};
+    EditTextWidget*   myPattern{nullptr};
+    CheckboxWidget*   mySubDirs{nullptr};
+    StaticTextWidget* myRomCount{nullptr};
 
     FileListWidget*   myList{nullptr};
+
     StaticTextWidget* myDirLabel{nullptr};
     EditTextWidget*   myDir{nullptr};
-    StaticTextWidget* myRomCount{nullptr};
-    EditTextWidget*   myPattern{nullptr};
-    CheckboxWidget*   myAllFiles{nullptr};
 
-    RomInfoWidget* myRomInfoWidget{nullptr};
+    ButtonWidget*     myStartButton{nullptr};
+    ButtonWidget*     myPrevDirButton{nullptr};
+    ButtonWidget*     myOptionsButton{nullptr};
+    ButtonWidget*     myQuitButton{nullptr};
+
+    RomInfoWidget*    myRomInfoWidget{nullptr};
     std::unordered_map<string,string> myMD5List;
 
     int mySelectedItem{0};
@@ -156,9 +194,13 @@ class LauncherDialog : public Dialog
     bool myShowOnlyROMs{false};
     bool myUseMinimalUI{false};
     bool myEventHandled{false};
+    bool myShortCount{false};
+    bool myPendingReload{false};
+    uInt64 myReloadTime{0};
 
     enum {
       kAllfilesCmd   = 'lalf',  // show all files (or ROMs only)
+      kSubDirsCmd    = 'lred',
       kPrevDirCmd    = 'PRVD',
       kOptionsCmd    = 'OPTI',
       kQuitCmd       = 'QUIT'
diff --git a/src/gui/ListWidget.cxx b/src/gui/ListWidget.cxx
index aa8ed9455..1cf6c7e0d 100644
--- a/src/gui/ListWidget.cxx
+++ b/src/gui/ListWidget.cxx
@@ -26,8 +26,9 @@
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 ListWidget::ListWidget(GuiObject* boss, const GUI::Font& font,
-                       int x, int y, int w, int h)
-  : EditableWidget(boss, font, x, y, 16, 16)
+                       int x, int y, int w, int h, bool useScrollbar)
+  : EditableWidget(boss, font, x, y, 16, 16),
+    _useScrollbar(useScrollbar)
 {
   _flags = Widget::FLAG_ENABLED | Widget::FLAG_CLEARBG | Widget::FLAG_RETAIN_FOCUS;
   _bgcolor = kWidColor;
@@ -35,17 +36,24 @@ ListWidget::ListWidget(GuiObject* boss, const GUI::Font& font,
   _textcolor = kTextColor;
   _textcolorhi = kTextColor;
 
+  _editMode = false;
+
   _cols = w / _fontWidth;
-  _rows = h / _fontHeight;
+  _rows = h / _lineHeight;
 
   // Set real dimensions
-  _w = w - ScrollBarWidget::scrollBarWidth(_font);
   _h = h + 2;
 
   // Create scrollbar and attach to the list
-  _scrollBar = new ScrollBarWidget(boss, font, _x + _w, _y,
-                                   ScrollBarWidget::scrollBarWidth(_font), _h);
-  _scrollBar->setTarget(this);
+  if(_useScrollbar)
+  {
+    _w = w - ScrollBarWidget::scrollBarWidth(_font);
+    _scrollBar = new ScrollBarWidget(boss, font, _x + _w, _y,
+                                     ScrollBarWidget::scrollBarWidth(_font), _h);
+    _scrollBar->setTarget(this);
+  }
+  else
+    _w = w - 1;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -168,10 +176,13 @@ void ListWidget::recalc()
 
   _editMode = false;
 
-  _scrollBar->_numEntries     = int(_list.size());
-  _scrollBar->_entriesPerPage = _rows;
-  // disable scrollbar if no longer necessary
-  scrollBarRecalc();
+  if(_useScrollbar)
+  {
+    _scrollBar->_numEntries = int(_list.size());
+    _scrollBar->_entriesPerPage = _rows;
+    // disable scrollbar if no longer necessary
+    scrollBarRecalc();
+  }
 
   // Reset to normal data entry
   abortEditMode();
@@ -182,9 +193,12 @@ void ListWidget::recalc()
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void ListWidget::scrollBarRecalc()
 {
-  _scrollBar->_currentPos = _currentPos;
-  _scrollBar->recalc();
-  sendCommand(ListWidget::kScrolledCmd, _currentPos, _id);
+  if(_useScrollbar)
+  {
+    _scrollBar->_currentPos = _currentPos;
+    _scrollBar->recalc();
+    sendCommand(ListWidget::kScrolledCmd, _currentPos, _id);
+  }
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -193,6 +207,7 @@ void ListWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount)
   if (!isEnabled())
     return;
 
+  resetSelection();
   // First check whether the selection changed
   int newSelectedItem;
   newSelectedItem = findItem(x, y);
@@ -230,13 +245,14 @@ void ListWidget::handleMouseUp(int x, int y, MouseButton b, int clickCount)
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void ListWidget::handleMouseWheel(int x, int y, int direction)
 {
-  _scrollBar->handleMouseWheel(x, y, direction);
+  if(_useScrollbar)
+    _scrollBar->handleMouseWheel(x, y, direction);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 int ListWidget::findItem(int x, int y) const
 {
-  return (y - 1) / _fontHeight + _currentPos;
+  return (y - 1) / _lineHeight + _currentPos;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -354,8 +370,11 @@ bool ListWidget::handleEvent(Event::Type e)
 
   if (_selectedItem != oldSelectedItem)
   {
-    _scrollBar->draw();
-    scrollToSelected();
+    if(_useScrollbar)
+    {
+      _scrollBar->draw();
+      scrollToSelected();
+    }
 
     sendCommand(ListWidget::kSelectionChangedCmd, _selectedItem, _id);
   }
@@ -408,14 +427,17 @@ void ListWidget::scrollToCurrent(int item)
   else if (_currentPos + _rows > int(_list.size()))
     _currentPos = int(_list.size()) - _rows;
 
-  int oldScrollPos = _scrollBar->_currentPos;
-  _scrollBar->_currentPos = _currentPos;
-  _scrollBar->recalc();
+  if(_useScrollbar)
+  {
+    int oldScrollPos = _scrollBar->_currentPos;
+    _scrollBar->_currentPos = _currentPos;
+    _scrollBar->recalc();
 
-  setDirty();
+    setDirty();
 
-  if(oldScrollPos != _currentPos)
-    sendCommand(ListWidget::kScrolledCmd, _currentPos, _id);
+    if(oldScrollPos != _currentPos)
+      sendCommand(ListWidget::kScrolledCmd, _currentPos, _id);
+  }
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/gui/ListWidget.hxx b/src/gui/ListWidget.hxx
index 75d2600ae..1fba03f01 100644
--- a/src/gui/ListWidget.hxx
+++ b/src/gui/ListWidget.hxx
@@ -42,7 +42,7 @@ class ListWidget : public EditableWidget
 
   public:
     ListWidget(GuiObject* boss, const GUI::Font& font,
-               int x, int y, int w, int h);
+               int x, int y, int w, int h, bool useScrollbar = true);
     ~ListWidget() override = default;
 
     int rows() const        { return _rows; }
@@ -99,7 +99,7 @@ class ListWidget : public EditableWidget
     int  _currentPos{0};
     int  _selectedItem{-1};
     int  _highlightedItem{-1};
-    bool _editMode{false};
+    bool _useScrollbar{true};
 
     ScrollBarWidget* _scrollBar{nullptr};
 
diff --git a/src/gui/LoggerDialog.cxx b/src/gui/LoggerDialog.cxx
index bf53d80a0..3f94e093e 100644
--- a/src/gui/LoggerDialog.cxx
+++ b/src/gui/LoggerDialog.cxx
@@ -123,12 +123,12 @@ void LoggerDialog::saveLogFile()
   {
     stringstream out;
     out << Logger::instance().logMessages();
-    instance().frameBuffer().showMessage("Saving log file to " + node.getShortPath());
+    instance().frameBuffer().showTextMessage("Saving log file to " + node.getShortPath());
     node.write(out);
   }
   catch(...)
   {
-    instance().frameBuffer().showMessage("Error saving log file to " + node.getShortPath());
+    instance().frameBuffer().showTextMessage("Error saving log file to " + node.getShortPath());
   }
 }
 
diff --git a/src/gui/OptionsDialog.hxx b/src/gui/OptionsDialog.hxx
index 55d4d4b0d..bd13c3f37 100644
--- a/src/gui/OptionsDialog.hxx
+++ b/src/gui/OptionsDialog.hxx
@@ -52,7 +52,7 @@ class OptionsDialog : public Dialog
     void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
 
   private:
-    unique_ptr<VideoAudioDialog>      myVideoDialog;
+    unique_ptr<VideoAudioDialog> myVideoDialog;
     unique_ptr<EmulationDialog>  myEmulationDialog;
     unique_ptr<InputDialog>      myInputDialog;
     unique_ptr<UIDialog>         myUIDialog;
diff --git a/src/gui/PopUpWidget.cxx b/src/gui/PopUpWidget.cxx
index 3f4474fea..b4dd27b84 100644
--- a/src/gui/PopUpWidget.cxx
+++ b/src/gui/PopUpWidget.cxx
@@ -20,6 +20,7 @@
 #include "FBSurface.hxx"
 #include "Font.hxx"
 #include "ContextMenu.hxx"
+#include "Dialog.hxx"
 #include "DialogContainer.hxx"
 #include "PopUpWidget.hxx"
 
@@ -27,8 +28,7 @@
 PopUpWidget::PopUpWidget(GuiObject* boss, const GUI::Font& font,
                          int x, int y, int w, int h, const VariantList& list,
                          const string& label, int labelWidth, int cmd)
-  : Widget(boss, font, x, y - 1, w, h + 2),
-    CommandSender(boss),
+  : EditableWidget(boss, font, x, y - 1, w, h + 2),
     _label(label),
     _labelWidth(labelWidth)
 {
@@ -38,6 +38,8 @@ PopUpWidget::PopUpWidget(GuiObject* boss, const GUI::Font& font,
   _textcolor = kTextColor;
   _textcolorhi = kTextColor;  // do not highlight the label
 
+  setEditable(false);
+
   if(!_label.empty() && _labelWidth == 0)
     _labelWidth = _font.getStringWidth(_label);
 
@@ -70,20 +72,32 @@ void PopUpWidget::addItems(const VariantList& items)
 void PopUpWidget::setSelected(const Variant& tag, const Variant& def)
 {
   myMenu->setSelected(tag, def);
+  setText(myMenu->getSelectedName());
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void PopUpWidget::setSelectedIndex(int idx, bool changed)
 {
-  _changed = changed;
+  if(_changed != changed)
+  {
+    _changed = changed;
+    setDirty();
+  }
   myMenu->setSelectedIndex(idx);
+  setText(myMenu->getSelectedName());
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void PopUpWidget::setSelectedMax(bool changed)
 {
+  if(_changed != changed)
+  {
+    _changed = changed;
+    setDirty();
+  }
   _changed = changed;
   myMenu->setSelectedMax();
+  setText(myMenu->getSelectedName());
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -113,11 +127,32 @@ const Variant& PopUpWidget::getSelectedTag() const
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void PopUpWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount)
 {
-  if(isEnabled() && !myMenu->isVisible())
+  resetSelection();
+  if(!isEditable() || x > _w - dropDownWidth(_font))
   {
-    // Add menu just underneath parent widget
-    myMenu->show(getAbsX() + _labelWidth, getAbsY() + getHeight(),
-                 dialog().surface().dstRect(), myMenu->getSelected());
+    if(isEnabled() && !myMenu->isVisible())
+    {
+      // Add menu just underneath parent widget
+      myMenu->show(getAbsX() + _labelWidth, getAbsY() + getHeight(),
+                   dialog().surface().dstRect(), myMenu->getSelected());
+    }
+  }
+  else
+  {
+    x += _editScrollOffset - _labelWidth;
+
+    int width = 0;
+    uInt32 i;
+
+    for(i = 0; i < editString().size(); ++i)
+    {
+      width += _font.getCharWidth(editString()[i]);
+      if(width >= x)
+        break;
+    }
+
+    if(setCaretPos(i))
+      setDirty();
   }
 }
 
@@ -133,20 +168,6 @@ void PopUpWidget::handleMouseWheel(int x, int y, int direction)
   }
 }
 
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void PopUpWidget::handleMouseEntered()
-{
-  setFlags(Widget::FLAG_HILITED);
-  setDirty();
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void PopUpWidget::handleMouseLeft()
-{
-  clearFlags(Widget::FLAG_HILITED);
-  setDirty();
-}
-
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 bool PopUpWidget::handleEvent(Event::Type e)
 {
@@ -180,6 +201,7 @@ void PopUpWidget::handleCommand(CommandSender* sender, int cmd, int data, int id
 {
   // Intercept all events sent through the PromptWidget
   // They're likely from our ContextMenu, indicating a redraw is required
+  setText(myMenu->getSelectedName());
   dialog().setDirty();
 
   // Pass the cmd on to our parent
@@ -234,7 +256,6 @@ void PopUpWidget::drawWidget(bool hilite)
 {
 //cerr << "PopUpWidget::drawWidget\n";
   FBSurface& s = dialog().surface();
-  bool onTop = _boss->dialog().isOnTop();
 
   int x = _x + _labelWidth;
   int w = _w - _labelWidth;
@@ -242,27 +263,53 @@ void PopUpWidget::drawWidget(bool hilite)
   // Draw the label, if any
   if(_labelWidth > 0)
     s.drawString(_font, _label, _x, _y + myTextY, _labelWidth,
-                 isEnabled() && onTop ? _textcolor : kColor, TextAlign::Left);
+                 isEnabled() ? _textcolor : kColor, TextAlign::Left);
 
   // Draw a thin frame around us.
   s.frameRect(x, _y, w, _h, isEnabled() && hilite ? kWidColorHi : kColor);
-  s.frameRect(x + w - (_arrowWidth * 2 - 2), _y + 1, (_arrowWidth * 2 - 3), _h - 2,
-              isEnabled() && hilite ? kWidColorHi : kBGColorLo);
+  if(isEnabled() && hilite)
+    s.frameRect(x + w - (_arrowWidth * 2 - 1), _y, (_arrowWidth * 2 - 1), _h, kWidColorHi);
 
   // Fill the background
+  ColorId bgCol = isEditable() ? kWidColor : kDlgColor;
   s.fillRect(x + 1, _y + 1, w - (_arrowWidth * 2 - 1), _h - 2,
-             onTop ? _changed ? kDbgChangedColor : kWidColor : kDlgColor);
-  s.fillRect(x + w - (_arrowWidth * 2 - 3), _y + 2, (_arrowWidth * 2 - 5), _h - 4,
-             onTop ? isEnabled() && hilite ? kWidColor : kBGColorHi : kBGColorLo);
+             _changed ? kDbgChangedColor : bgCol);
+  s.fillRect(x + w - (_arrowWidth * 2 - 2), _y + 1, (_arrowWidth * 2 - 3), _h - 2,
+             isEnabled() && hilite ? kBtnColorHi : bgCol);
   // Draw an arrow pointing down at the right end to signal this is a dropdown/popup
   s.drawBitmap(_arrowImg, x + w - (_arrowWidth * 1.5 - 1), _y + myArrowsY + 1,
-               !(isEnabled() && onTop) ? kColor : kTextColor, _arrowWidth, _arrowHeight);
+               !isEnabled() ? kColor : kTextColor, _arrowWidth, _arrowHeight);
 
   // Draw the selected entry, if any
-  const string& name = myMenu->getSelectedName();
+  const string& name = editString();
+  bool editable = isEditable();
+
   w -= dropDownWidth(_font);
-  TextAlign align = (_font.getStringWidth(name) > w) ?
+  TextAlign align = (_font.getStringWidth(name) > w && !editable) ?
                      TextAlign::Right : TextAlign::Left;
+  adjustOffset();
   s.drawString(_font, name, x + _textOfs, _y + myTextY, w,
-               !(isEnabled() && onTop) ? kColor : _changed ? kDbgChangedTextColor : kTextColor, align);
+               !isEnabled() ? kColor : _changed ? kDbgChangedTextColor : kTextColor,
+               align, editable ? -_editScrollOffset : 0, !editable);
+
+  if(editable)
+    drawCaretSelection();
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Common::Rect PopUpWidget::getEditRect() const
+{
+  return Common::Rect(_labelWidth + _textOfs, 1, _w - _textOfs - dropDownWidth(_font), _h);
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void PopUpWidget::endEditMode()
+{
+  // Editing is always enabled
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void PopUpWidget::abortEditMode()
+{
+  // Editing is always enabled
 }
diff --git a/src/gui/PopUpWidget.hxx b/src/gui/PopUpWidget.hxx
index a3c122509..babe28686 100644
--- a/src/gui/PopUpWidget.hxx
+++ b/src/gui/PopUpWidget.hxx
@@ -24,7 +24,7 @@ class ContextMenu;
 #include "bspf.hxx"
 #include "Variant.hxx"
 #include "Command.hxx"
-#include "Widget.hxx"
+#include "EditableWidget.hxx"
 
 /**
  * Popup or dropdown widget which, when clicked, "pop up" a list of items and
@@ -33,12 +33,12 @@ class ContextMenu;
  * Implementation wise, when the user selects an item, then a kPopUpItemSelectedCmd
  * is broadcast, with data being equal to the tag value of the selected entry.
  */
-class PopUpWidget : public Widget, public CommandSender
+class PopUpWidget : public EditableWidget
 {
   public:
     PopUpWidget(GuiObject* boss, const GUI::Font& font,
                 int x, int y, int w, int h, const VariantList& items,
-                const string& label, int labelWidth = 0, int cmd = 0);
+                const string& label = "", int labelWidth = 0, int cmd = 0);
     ~PopUpWidget() override = default;
 
     void setID(uInt32 id);
@@ -70,14 +70,17 @@ class PopUpWidget : public Widget, public CommandSender
   protected:
     void handleMouseDown(int x, int y, MouseButton b, int clickCount) override;
     void handleMouseWheel(int x, int y, int direction) override;
-    void handleMouseEntered() override;
-    void handleMouseLeft() override;
     bool handleEvent(Event::Type e) override;
     void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
 
     void setArrow();
     void drawWidget(bool hilite) override;
 
+    void endEditMode() override;
+    void abortEditMode() override;
+
+    Common::Rect getEditRect() const override;
+
   private:
     unique_ptr<ContextMenu> myMenu;
     int myArrowsY{0};
diff --git a/src/gui/ProgressDialog.cxx b/src/gui/ProgressDialog.cxx
index 04bc2adae..80aafc8c4 100644
--- a/src/gui/ProgressDialog.cxx
+++ b/src/gui/ProgressDialog.cxx
@@ -18,6 +18,8 @@
 #include "bspf.hxx"
 #include "OSystem.hxx"
 #include "FrameBuffer.hxx"
+#include "EventHandler.hxx"
+#include "TimerManager.hxx"
 #include "Widget.hxx"
 #include "Dialog.hxx"
 #include "Font.hxx"
@@ -27,38 +29,64 @@
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 ProgressDialog::ProgressDialog(GuiObject* boss, const GUI::Font& font,
                                const string& message)
-  : Dialog(boss->instance(), boss->parent())
+  : Dialog(boss->instance(), boss->parent()),
+    myFont(font)
 {
   const int fontWidth  = font.getMaxCharWidth(),
             fontHeight = font.getFontHeight(),
             lineHeight = font.getLineHeight(),
             VBORDER = fontHeight / 2,
             HBORDER = fontWidth * 1.25,
-            VGAP = fontHeight / 4;
-  int xpos, ypos, lwidth;
+            VGAP = fontHeight / 4,
+            buttonHeight = font.getLineHeight() * 1.25,
+            BTN_BORDER = fontWidth * 2.5,
+            buttonWidth = font.getStringWidth("Cancel") + BTN_BORDER,
+            lwidth = font.getStringWidth(message);
+
+  int xpos, ypos;
+  WidgetArray wid;
 
   // Calculate real dimensions
-  lwidth = font.getStringWidth(message);
-  _w = HBORDER * 2 + lwidth;
-  _h = VBORDER * 2 + lineHeight * 2 + VGAP * 2;
+  _w = HBORDER * 2 + std::max(lwidth, buttonWidth);
+  _h = VBORDER * 2 + lineHeight * 2 + buttonHeight + VGAP * 6;
 
   xpos = HBORDER; ypos = VBORDER;
   myMessage = new StaticTextWidget(this, font, xpos, ypos, lwidth, fontHeight,
                                    message, TextAlign::Center);
   myMessage->setTextColor(kTextColorEm);
 
-  xpos = HBORDER; ypos += lineHeight + VGAP * 2;
-  mySlider = new SliderWidget(this, font, xpos, ypos, lwidth, lineHeight, "", 0, 0);
+  ypos += lineHeight + VGAP * 2;
+  mySlider = new SliderWidget(this, font, xpos, ypos, lwidth, lineHeight,
+                              "", 0, 0);
   mySlider->setMinValue(1);
   mySlider->setMaxValue(100);
 
-  open();
+  ypos += lineHeight + VGAP * 4;
+  ButtonWidget* b = new ButtonWidget(this, font, (_w - buttonWidth) / 2, ypos,
+                                     buttonWidth, buttonHeight, "Cancel",
+                                     Event::UICancel);
+  wid.push_back(b);
+  addCancelWidget(b);
+  addToFocusList(wid);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void ProgressDialog::setMessage(const string& message)
 {
+  const int fontWidth = myFont.getMaxCharWidth(),
+    HBORDER = fontWidth * 1.25,
+    lwidth = myFont.getStringWidth(message),
+    BTN_BORDER = fontWidth * 2.5,
+    buttonWidth = myFont.getStringWidth("Cancel") + BTN_BORDER;
+
+  // Recalculate real dimensions
+  _w = HBORDER * 2 + std::max(lwidth, buttonWidth);
+
+  myMessage->setWidth(lwidth);
   myMessage->setLabel(message);
+  mySlider->setWidth(lwidth);
+
+  _cancelWidget->setPosX((_w - buttonWidth) / 2);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -68,23 +96,57 @@ void ProgressDialog::setRange(int start, int finish, int step)
   myFinish = finish;
   myStep = int((step / 100.0) * (myFinish - myStart + 1));
 
-  mySlider->setMinValue(myStart);
+  mySlider->setMinValue(myStart + myStep);
   mySlider->setMaxValue(myFinish);
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void ProgressDialog::resetProgress()
+{
+  myProgress = myStepProgress = 0;
+  mySlider->setValue(0);
+  myIsCancelled = false;
+}
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void ProgressDialog::setProgress(int progress)
 {
   // Only increase the progress bar if we have arrived at a new step
-  if(progress - mySlider->getValue() > myStep)
+  if(progress - myStepProgress >= myStep)
   {
-    mySlider->setValue(progress);
+    myStepProgress = progress;
+    mySlider->setValue(progress % (myFinish - myStart + 1));
 
     // Since this dialog is usually called in a tight loop that doesn't
-    // yield, we need to manually tell the framebuffer that a redraw is
-    // necessary
+    // yield, we need to manually:
+    // - tell the framebuffer that a redraw is necessary
+    // - poll the events
     // This isn't really an ideal solution, since all redrawing and
     // event handling is suspended until the dialog is closed
     instance().frameBuffer().update();
+    instance().eventHandler().poll(TimerManager::getTicks());
   }
 }
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void ProgressDialog::incProgress()
+{
+  setProgress(++myProgress);
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void ProgressDialog::handleCommand(CommandSender* sender, int cmd,
+                                   int data, int id)
+{
+  switch(cmd)
+  {
+    case Event::UICancel:
+      myIsCancelled = true;
+      break;
+
+    default:
+      Dialog::handleCommand(sender, cmd, data, 0);
+      break;
+  }
+}
+
diff --git a/src/gui/ProgressDialog.hxx b/src/gui/ProgressDialog.hxx
index 0ec8731b5..a62fb8cbf 100644
--- a/src/gui/ProgressDialog.hxx
+++ b/src/gui/ProgressDialog.hxx
@@ -21,25 +21,37 @@
 class GuiObject;
 class StaticTextWidget;
 class SliderWidget;
+class ButtonWidget;
 
 #include "bspf.hxx"
+#include "Dialog.hxx"
 
 class ProgressDialog : public Dialog
 {
   public:
     ProgressDialog(GuiObject* boss, const GUI::Font& font,
-                   const string& message);
+                   const string& message = "");
     ~ProgressDialog() override = default;
 
     void setMessage(const string& message);
     void setRange(int begin, int end, int step);
+    void resetProgress();
     void setProgress(int progress);
+    void incProgress();
+    bool isCancelled() const { return myIsCancelled; }
 
   private:
+    const GUI::Font& myFont;
     StaticTextWidget* myMessage{nullptr};
     SliderWidget*     mySlider{nullptr};
 
     int myStart{0}, myFinish{0}, myStep{0};
+    int myProgress{0};
+    int myStepProgress{0};
+    bool myIsCancelled{false};
+
+  private:
+    void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
 
   private:
     // Following constructors and assignment operators not supported
diff --git a/src/gui/QuadTariDialog.cxx b/src/gui/QuadTariDialog.cxx
new file mode 100644
index 000000000..b4d1891ef
--- /dev/null
+++ b/src/gui/QuadTariDialog.cxx
@@ -0,0 +1,199 @@
+//============================================================================
+//
+//   SSSS    tt          lll  lll
+//  SS  SS   tt           ll   ll
+//  SS     tttttt  eeee   ll   ll   aaaa
+//   SSSS    tt   ee  ee  ll   ll      aa
+//      SS   tt   eeeeee  ll   ll   aaaaa  --  "An Atari 2600 VCS Emulator"
+//  SS  SS   tt   ee      ll   ll  aa  aa
+//   SSSS     ttt  eeeee llll llll  aaaaa
+//
+// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
+// and the Stella Team
+//
+// See the file "License.txt" for information on usage and redistribution of
+// this file, and for a DISCLAIMER OF ALL WARRANTIES.
+//============================================================================
+
+#include "OSystem.hxx"
+#include "EventHandler.hxx"
+#include "Widget.hxx"
+#include "PopUpWidget.hxx"
+#include "Font.hxx"
+#include "Variant.hxx"
+#include "Props.hxx"
+#include "PropsSet.hxx"
+#include "QuadTariDialog.hxx"
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+QuadTariDialog::QuadTariDialog(GuiObject* boss, const GUI::Font& font, int max_w, int max_h,
+                               Properties& properties)
+  : Dialog(boss->instance(), boss->parent(), font, "QuadTari controllers", 0, 0, max_w, max_h),
+    myGameProperties(properties)
+{
+  const int lineHeight = font.getLineHeight(),
+    fontHeight = font.getFontHeight(),
+    fontWidth = font.getMaxCharWidth();
+  const int VBORDER = fontHeight / 2;
+  const int HBORDER = fontWidth * 1.25;
+  const int VGAP = fontHeight / 4;
+
+  int xpos, ypos;
+  WidgetArray wid;
+  VariantList ctrls;
+
+  xpos = HBORDER; ypos = VBORDER + _th;
+
+  ctrls.clear();
+  //VarList::push_back(ctrls, "Auto-detect", "AUTO");
+  VarList::push_back(ctrls, "Joystick", "JOYSTICK");
+  VarList::push_back(ctrls, "Paddles", "PADDLES");
+  //VarList::push_back(ctrls, "Paddles_IAxis", "PADDLES_IAXIS");
+  //VarList::push_back(ctrls, "Paddles_IAxDr", "PADDLES_IAXDR");
+  //VarList::push_back(ctrls, "BoosterGrip", "BOOSTERGRIP");
+  VarList::push_back(ctrls, "Driving", "DRIVING");
+  //VarList::push_back(ctrls, "Keyboard", "KEYBOARD");
+  //VarList::push_back(ctrls, "AmigaMouse", "AMIGAMOUSE");
+  //VarList::push_back(ctrls, "AtariMouse", "ATARIMOUSE");
+  //VarList::push_back(ctrls, "Trakball", "TRAKBALL");
+  VarList::push_back(ctrls, "AtariVox", "ATARIVOX");
+  VarList::push_back(ctrls, "SaveKey", "SAVEKEY");
+  //VarList::push_back(ctrls, "Sega Genesis", "GENESIS");
+  //VarList::push_back(ctrls, "KidVid", "KIDVID");
+  //VarList::push_back(ctrls, "Lightgun", "LIGHTGUN");
+  //VarList::push_back(ctrls, "MindLink", "MINDLINK");
+  //VarList::push_back(ctrls, "QuadTari", "QUADTARI");
+
+  int pwidth = font.getStringWidth("Joystick12"); // a bit wider looks better overall
+
+  myLeftPortLabel = new StaticTextWidget(this, font, xpos, ypos + 1, "Left port");
+
+  ypos += lineHeight + VGAP * 2;
+  myLeft1Port = new PopUpWidget(this, font, xpos, ypos,
+                               pwidth, lineHeight, ctrls, "P1 ");
+  wid.push_back(myLeft1Port);
+
+  ypos += lineHeight + VGAP * 2;
+  myLeft2Port = new PopUpWidget(this, font, xpos, ypos,
+                               pwidth, lineHeight, ctrls, "P2 ");
+  wid.push_back(myLeft2Port);
+
+  xpos = _w - HBORDER - myLeft1Port->getWidth(); // aligned right
+  ypos = myLeftPortLabel->getTop() - 1;
+  myRightPortLabel = new StaticTextWidget(this, font, xpos, ypos + 1, "Right port");
+
+  ypos += lineHeight + VGAP * 2;
+  myRight1Port = new PopUpWidget(this, font, xpos, ypos,
+                                pwidth, lineHeight, ctrls, "P3 ");
+  wid.push_back(myRight1Port);
+
+  ypos += lineHeight + VGAP * 2;
+  myRight2Port = new PopUpWidget(this, font, xpos, ypos,
+                                pwidth, lineHeight, ctrls, "P4 ");
+  wid.push_back(myRight2Port);
+
+  addDefaultsOKCancelBGroup(wid, _font);
+  addBGroupToFocusList(wid);
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void QuadTariDialog::show(bool enableLeft, bool enableRight)
+{
+  myLeftPortLabel->setEnabled(enableLeft);
+  myLeft1Port->setEnabled(enableLeft);
+  myLeft2Port->setEnabled(enableLeft);
+  myRightPortLabel->setEnabled(enableRight);
+  myRight1Port->setEnabled(enableRight);
+  myRight2Port->setEnabled(enableRight);
+
+  open();
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void QuadTariDialog::loadControllerProperties(const Properties& props)
+{
+  string controller;
+
+  if(myLeftPortLabel->isEnabled())
+  {
+    controller = props.get(PropType::Controller_Left1);
+    myLeft1Port->setSelected(controller, "Joystick");
+    controller = props.get(PropType::Controller_Left2);
+    myLeft2Port->setSelected(controller, "Joystick");
+  }
+
+  if(myRightPortLabel->isEnabled())
+  {
+    controller = props.get(PropType::Controller_Right1);
+    myRight1Port->setSelected(controller, "Joystick");
+    controller = props.get(PropType::Controller_Right2);
+    myRight2Port->setSelected(controller, "Joystick");
+  }
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void QuadTariDialog::loadConfig()
+{
+  loadControllerProperties(myGameProperties);
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void QuadTariDialog::saveConfig()
+{
+  if(myLeftPortLabel->isEnabled())
+  {
+    string controller = myLeft1Port->getSelectedTag().toString();
+    myGameProperties.set(PropType::Controller_Left1, controller);
+    controller = myLeft2Port->getSelectedTag().toString();
+    myGameProperties.set(PropType::Controller_Left2, controller);
+  }
+  else
+  {
+    myGameProperties.set(PropType::Controller_Left1, "");
+    myGameProperties.set(PropType::Controller_Left2, "");
+  }
+
+  if(myRightPortLabel->isEnabled())
+  {
+    string controller = myRight1Port->getSelectedTag().toString();
+    myGameProperties.set(PropType::Controller_Right1, controller);
+    controller = myRight2Port->getSelectedTag().toString();
+    myGameProperties.set(PropType::Controller_Right2, controller);
+  }
+  else
+  {
+    myGameProperties.set(PropType::Controller_Right1, "");
+    myGameProperties.set(PropType::Controller_Right2, "");
+  }
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void QuadTariDialog::setDefaults()
+{
+  // Load the default properties
+  const string& md5 = myGameProperties.get(PropType::Cart_MD5);
+  Properties defaultProperties;
+
+  instance().propSet().getMD5(md5, defaultProperties, true);
+  loadControllerProperties(defaultProperties);
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void QuadTariDialog::handleCommand(CommandSender* sender, int cmd, int data, int id)
+{
+  switch(cmd)
+  {
+    case GuiObject::kOKCmd:
+      saveConfig();
+      close();
+      break;
+
+    case GuiObject::kDefaultsCmd:
+      setDefaults();
+      break;
+
+    default:
+      Dialog::handleCommand(sender, cmd, data, id);
+      break;
+  }
+}
diff --git a/src/gui/QuadTariDialog.hxx b/src/gui/QuadTariDialog.hxx
new file mode 100644
index 000000000..070a0bd71
--- /dev/null
+++ b/src/gui/QuadTariDialog.hxx
@@ -0,0 +1,69 @@
+//============================================================================
+//
+//   SSSS    tt          lll  lll
+//  SS  SS   tt           ll   ll
+//  SS     tttttt  eeee   ll   ll   aaaa
+//   SSSS    tt   ee  ee  ll   ll      aa
+//      SS   tt   eeeeee  ll   ll   aaaaa  --  "An Atari 2600 VCS Emulator"
+//  SS  SS   tt   ee      ll   ll  aa  aa
+//   SSSS     ttt  eeeee llll llll  aaaaa
+//
+// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
+// and the Stella Team
+//
+// See the file "License.txt" for information on usage and redistribution of
+// this file, and for a DISCLAIMER OF ALL WARRANTIES.
+//============================================================================
+
+#ifndef JOYSTICK_DIALOG_HXX
+#define JOYSTICK_DIALOG_HXX
+
+class CommandSender;
+class PopUpWidget;
+
+#include "Dialog.hxx"
+
+/**
+ * Allow assigning controllers to the four QuadTari ports.
+ */
+class QuadTariDialog: public Dialog
+{
+  public:
+    QuadTariDialog(GuiObject* boss, const GUI::Font& font, int max_w, int max_h,
+                   Properties& properties);
+    ~QuadTariDialog() override = default;
+
+    /** Place the dialog onscreen */
+    void show(bool enableLeft, bool enableRight);
+
+  private:
+    void loadConfig() override;
+    void saveConfig() override;
+    void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
+
+    void setDefaults() override;
+
+    void loadControllerProperties(const Properties& props);
+
+  private:
+    StaticTextWidget* myLeftPortLabel{nullptr};
+    PopUpWidget*      myLeft1Port{nullptr};
+    PopUpWidget*      myLeft2Port{nullptr};
+
+    StaticTextWidget* myRightPortLabel{nullptr};
+    PopUpWidget*      myRight1Port{nullptr};
+    PopUpWidget*      myRight2Port{nullptr};
+
+    // Game properties for currently loaded ROM
+    Properties& myGameProperties;
+
+  private:
+    // Following constructors and assignment operators not supported
+    QuadTariDialog() = delete;
+    QuadTariDialog(const QuadTariDialog&) = delete;
+    QuadTariDialog(QuadTariDialog&&) = delete;
+    QuadTariDialog& operator=(const QuadTariDialog&) = delete;
+    QuadTariDialog& operator=(QuadTariDialog&&) = delete;
+};
+
+#endif
diff --git a/src/gui/RomAuditDialog.cxx b/src/gui/RomAuditDialog.cxx
index 58b9acaba..a95e4fce5 100644
--- a/src/gui/RomAuditDialog.cxx
+++ b/src/gui/RomAuditDialog.cxx
@@ -119,13 +119,17 @@ void RomAuditDialog::auditRoms()
 
   // Create a progress dialog box to show the progress of processing
   // the ROMs, since this is usually a time-consuming operation
-  ProgressDialog progress(this, instance().frameBuffer().font(),
-                          "Auditing ROM files ...");
+  ostringstream buf;
+  ProgressDialog progress(this, instance().frameBuffer().font());
+
+  buf << "Auditing ROM files" << ELLIPSIS;
+  progress.setMessage(buf.str());
   progress.setRange(0, int(files.size()) - 1, 5);
+  progress.open();
 
   Properties props;
   uInt32 renamed = 0, notfound = 0;
-  for(uInt32 idx = 0; idx < files.size(); ++idx)
+  for(uInt32 idx = 0; idx < files.size() && !progress.isCancelled(); ++idx)
   {
     string extension;
     if(files[idx].isFile() &&
@@ -143,7 +147,8 @@ void RomAuditDialog::auditRoms()
         // Only rename the file if we found a valid properties entry
         if(name != "" && name != files[idx].getName())
         {
-          const string& newfile = node.getPath() + name + "." + extension;
+          string newfile = node.getPath();
+          newfile.append(name).append(".").append(extension);
           if(files[idx].getPath() != newfile && files[idx].rename(newfile))
             renameSucceeded = true;
         }
@@ -155,7 +160,7 @@ void RomAuditDialog::auditRoms()
     }
 
     // Update the progress bar, indicating one more ROM has been processed
-    progress.setProgress(idx);
+    progress.incProgress();
   }
   progress.close();
 
diff --git a/src/gui/RomInfoWidget.cxx b/src/gui/RomInfoWidget.cxx
index 7e29d19e4..325cadfda 100644
--- a/src/gui/RomInfoWidget.cxx
+++ b/src/gui/RomInfoWidget.cxx
@@ -91,7 +91,7 @@ void RomInfoWidget::parseProperties(const FilesystemNode& node)
   if(mySurface == nullptr)
   {
     mySurface = instance().frameBuffer().allocateSurface(
-        myAvail.w, myAvail.h, FrameBuffer::ScalingInterpolation::blur);
+        myAvail.w, myAvail.h, ScalingInterpolation::blur);
     mySurface->applyAttributes();
 
     dialog().addSurface(mySurface);
@@ -172,17 +172,17 @@ void RomInfoWidget::parseProperties(const FilesystemNode& node)
     myRomInfo.push_back("Controllers: " + (left + " (left), " + right + " (right)"));
   if (bsDetected != "")
     myRomInfo.push_back("Type: " + Bankswitch::typeToDesc(Bankswitch::nameToType(bsDetected)));
+
+  setDirty();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void RomInfoWidget::drawWidget(bool hilite)
 {
   FBSurface& s = dialog().surface();
-  bool onTop = _boss->dialog().isOnTop();
-
   const int yoff = myAvail.h + 10;
 
-  s.fillRect(_x+2, _y+2, _w-4, _h-4, onTop ? _bgcolor : _bgcolorlo);
+  s.fillRect(_x+2, _y+2, _w-4, _h-4, _bgcolor);
   s.frameRect(_x, _y, _w, _h, kColor);
   s.frameRect(_x, _y+yoff, _w, _h-yoff, kColor);
 
@@ -204,7 +204,7 @@ void RomInfoWidget::drawWidget(bool hilite)
   {
     uInt32 x = _x + ((_w - _font.getStringWidth(mySurfaceErrorMsg)) >> 1);
     uInt32 y = _y + ((yoff - _font.getLineHeight()) >> 1);
-    s.drawString(_font, mySurfaceErrorMsg, x, y, _w - 10, onTop ? _textcolor : _shadowcolor);
+    s.drawString(_font, mySurfaceErrorMsg, x, y, _w - 10, _textcolor);
   }
 
   int xpos = _x + 8, ypos = _y + yoff + 5;
@@ -224,7 +224,8 @@ void RomInfoWidget::drawWidget(bool hilite)
         break;
     }
     int lines = s.drawString(_font, info, xpos, ypos, _w - 16, _font.getFontHeight() * 3,
-                             onTop ? _textcolor : _shadowcolor);
+                             _textcolor);
     ypos += _font.getLineHeight() + (lines - 1) * _font.getFontHeight();
   }
+  clearDirty();
 }
diff --git a/src/gui/ScrollBarWidget.cxx b/src/gui/ScrollBarWidget.cxx
index 335b716de..c9d68cb82 100644
--- a/src/gui/ScrollBarWidget.cxx
+++ b/src/gui/ScrollBarWidget.cxx
@@ -240,25 +240,20 @@ void ScrollBarWidget::checkBounds(int old_pos)
   }
 }
 
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void ScrollBarWidget::handleMouseEntered()
-{
-  setFlags(Widget::FLAG_HILITED);
-  setDirty();
-}
-
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void ScrollBarWidget::handleMouseLeft()
 {
   _part = Part::None;
-  clearFlags(Widget::FLAG_HILITED);
-  setDirty();
+  Widget::handleMouseLeft();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void ScrollBarWidget::recalc()
 {
 //cerr << "ScrollBarWidget::recalc()\n";
+  int oldSliderHeight = _sliderHeight,
+    oldSliderPos = _sliderPos;
+
   if(_numEntries > _entriesPerPage)
   {
     _sliderHeight = (_h - 2 * _upDownBoxHeight) * _entriesPerPage / _numEntries;
@@ -276,15 +271,14 @@ void ScrollBarWidget::recalc()
     _sliderPos = _upDownBoxHeight;
   }
 
-  setDirty();
+  if(oldSliderHeight != _sliderHeight || oldSliderPos != _sliderPos)
+    setDirty(); // only set dirty when something changed
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void ScrollBarWidget::drawWidget(bool hilite)
 {
-//cerr << "ScrollBarWidget::drawWidget\n";
   FBSurface& s = _boss->dialog().surface();
-  bool onTop = _boss->dialog().isOnTop();
   int bottomY = _y + _h;
   bool isSinglePage = (_numEntries <= _entriesPerPage);
 
@@ -298,23 +292,26 @@ void ScrollBarWidget::drawWidget(bool hilite)
     s.fillRect(_x + 1, _y + 1, _w - 2, _upDownBoxHeight - 2, kScrollColor);
   s.drawBitmap(_upImg, _x + (_scrollBarWidth - _upDownWidth) / 2,
                _y + (_upDownBoxHeight - _upDownHeight) / 2,
-               onTop ? isSinglePage ? kColor : (hilite && _part == Part::UpArrow) ? kWidColor
-               : kTextColor : kColor, _upDownWidth, _upDownHeight);
+               isSinglePage ? kColor
+                            : (hilite && _part == Part::UpArrow) ? kWidColor : kTextColor,
+               _upDownWidth, _upDownHeight);
 
   // Down arrow
   if(hilite && _part == Part::DownArrow)
     s.fillRect(_x + 1, bottomY - _upDownBoxHeight + 1, _w - 2, _upDownBoxHeight - 2, kScrollColor);
   s.drawBitmap(_downImg, _x + (_scrollBarWidth - _upDownWidth) / 2,
                bottomY - _upDownBoxHeight + (_upDownBoxHeight - _upDownHeight) / 2,
-               onTop ? isSinglePage ? kColor : (hilite && _part == Part::DownArrow) ?
-               kWidColor : kTextColor : kColor, _upDownWidth, _upDownHeight);
+               isSinglePage ? kColor
+                            : (hilite && _part == Part::DownArrow) ? kWidColor : kTextColor,
+               _upDownWidth, _upDownHeight);
 
   // Slider
   if(!isSinglePage)
   {
     s.fillRect(_x + 1, _y + _sliderPos - 1, _w - 2, _sliderHeight + 2,
-              onTop ? (hilite && _part == Part::Slider) ? kScrollColorHi : kScrollColor : kColor);
+              (hilite && _part == Part::Slider) ? kScrollColorHi : kScrollColor);
   }
+  clearDirty();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/gui/ScrollBarWidget.hxx b/src/gui/ScrollBarWidget.hxx
index 1d1b4c34a..0c29fde17 100644
--- a/src/gui/ScrollBarWidget.hxx
+++ b/src/gui/ScrollBarWidget.hxx
@@ -49,7 +49,6 @@ class ScrollBarWidget : public Widget, public CommandSender
     void handleMouseUp(int x, int y, MouseButton b, int clickCount) override;
     void handleMouseMoved(int x, int y) override;
     bool handleMouseClicks(int x, int y, MouseButton b) override;
-    void handleMouseEntered() override;
     void handleMouseLeft() override;
     void setArrows();
 
diff --git a/src/gui/StellaSettingsDialog.cxx b/src/gui/StellaSettingsDialog.cxx
index 74e8ca35f..06ff03b3e 100644
--- a/src/gui/StellaSettingsDialog.cxx
+++ b/src/gui/StellaSettingsDialog.cxx
@@ -195,6 +195,7 @@ void StellaSettingsDialog::addGameOptions(WidgetArray& wid, int& xpos, int& ypos
   VarList::push_back(ctrls, "AtariMouse", "ATARIMOUSE");
   VarList::push_back(ctrls, "Trakball", "TRAKBALL");
   VarList::push_back(ctrls, "Sega Genesis", "GENESIS");
+  VarList::push_back(ctrls, "QuadTari", "QUADTARI");
 
   int pwidth = _font.getStringWidth("Sega Genesis");
   myLeftPortLabel = new StaticTextWidget(this, _font, xpos, ypos + 1, "Left port  ");
@@ -267,6 +268,7 @@ void StellaSettingsDialog::saveConfig()
   settings.setValue("uipalette",
     myThemePopup->getSelectedTag().toString());
   instance().frameBuffer().setUIPalette();
+  instance().frameBuffer().update(FrameBuffer::UpdateMode::REDRAW);
 
   // Dialog position
   settings.setValue("dialogpos", myPositionPopup->getSelectedTag().toString());
diff --git a/src/gui/StringListWidget.cxx b/src/gui/StringListWidget.cxx
index 46aed13ba..b94d1b5c4 100644
--- a/src/gui/StringListWidget.cxx
+++ b/src/gui/StringListWidget.cxx
@@ -24,8 +24,9 @@
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 StringListWidget::StringListWidget(GuiObject* boss, const GUI::Font& font,
-                                   int x, int y, int w, int h, bool hilite)
-  : ListWidget(boss, font, x, y, w, h),
+                                   int x, int y, int w, int h, bool hilite,
+                                   bool useScrollbar)
+  : ListWidget(boss, font, x, y, w, h, useScrollbar),
     _hilite(hilite)
 {
   _bgcolorlo = kDlgColor;
@@ -50,48 +51,69 @@ void StringListWidget::setList(const StringList& list)
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void StringListWidget::handleMouseEntered()
+int StringListWidget::getToolTipIndex(const Common::Point& pos) const
 {
-  setFlags(Widget::FLAG_HILITED);
-  setDirty();
+  int idx = (pos.y - getAbsY()) / _lineHeight + _currentPos;
+
+  if(idx >= int(_list.size()))
+    return -1;
+  else
+    return idx;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void StringListWidget::handleMouseLeft()
+string StringListWidget::getToolTip(const Common::Point& pos) const
 {
-  clearFlags(Widget::FLAG_HILITED);
-  setDirty();
+  Common::Rect rect = getEditRect();
+  int idx = getToolTipIndex(pos);
+
+  if(idx < 0)
+    return EmptyString;
+
+  const string value = _list[idx];
+
+  if(uInt32(_font.getStringWidth(value)) > rect.w())
+    return _toolTipText + value;
+  else
+    return _toolTipText;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool StringListWidget::changedToolTip(const Common::Point& oldPos,
+                                      const Common::Point& newPos) const
+{
+  return getToolTipIndex(oldPos) != getToolTipIndex(newPos)
+    && getToolTip(oldPos) != getToolTip(newPos);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void StringListWidget::drawWidget(bool hilite)
 {
   FBSurface& s = _boss->dialog().surface();
-  bool onTop = _boss->dialog().isOnTop();
   int i, pos, len = int(_list.size());
 
   // Draw a thin frame around the list.
-  s.frameRect(_x, _y, _w + 1, _h, onTop && hilite && _hilite ? kWidColorHi : kColor);
+  s.frameRect(_x, _y, _w + 1, _h, hilite && _hilite ? kWidColorHi : kColor);
 
   if (!isEnabled())
-    s.fillRect(_x + 1, _y + 1, _w - 1, _h - 2, onTop ? kDlgColor : kBGColorLo);
+    s.fillRect(_x + 1, _y + 1, _w - 1, _h - 2, kDlgColor);
 
   // Draw the list items
   for (i = 0, pos = _currentPos; i < _rows && pos < len; i++, pos++)
   {
-    const int y = _y + 2 + _fontHeight * i;
-    ColorId textColor = onTop ? kTextColor : kShadowColor;
+    const int y = _y + 2 + _lineHeight * i;
+    ColorId textColor = kTextColor;
 
     // Draw the selected item inverted, on a highlighted background.
-    if (onTop && _selectedItem == pos && _hilite)
+    if (_selectedItem == pos && _hilite)
     {
       if(_hasFocus && !_editMode)
       {
-        s.fillRect(_x + 1, _y + 1 + _fontHeight * i, _w - 1, _fontHeight, kTextColorHi);
+        s.fillRect(_x + 1, _y + 1 + _lineHeight * i, _w - 1, _lineHeight, kTextColorHi);
         textColor = kTextColorInv;
       }
       else
-        s.frameRect(_x + 1, _y + 1 + _fontHeight * i, _w - 1, _fontHeight, kWidColorHi);
+        s.frameRect(_x + 1, _y + 1 + _lineHeight * i, _w - 1, _lineHeight, kWidColorHi);
     }
 
     Common::Rect r(getEditRect());
@@ -107,14 +129,16 @@ void StringListWidget::drawWidget(bool hilite)
   }
 
   // Only draw the caret while editing, and if it's in the current viewport
-  if(_editMode && (_selectedItem >= _scrollBar->_currentPos) &&
-    (_selectedItem < _scrollBar->_currentPos + _rows))
-    drawCaret();
+  if(_editMode &&
+     (!_useScrollbar ||
+     ((_selectedItem >= _scrollBar->_currentPos) &&
+      (_selectedItem < _scrollBar->_currentPos + _rows))))
+    drawCaretSelection();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Common::Rect StringListWidget::getEditRect() const
 {
-  const int offset = std::max(0, (_selectedItem - _currentPos) * _fontHeight);
-  return Common::Rect(_textOfs, 1 + offset, _w - _textOfs, _fontHeight + offset);
+  const int offset = std::max(0, (_selectedItem - _currentPos) * _lineHeight);
+  return Common::Rect(_textOfs, 1 + offset, _w - _textOfs, _lineHeight + offset);
 }
diff --git a/src/gui/StringListWidget.hxx b/src/gui/StringListWidget.hxx
index 490c6b6a2..668414c4c 100644
--- a/src/gui/StringListWidget.hxx
+++ b/src/gui/StringListWidget.hxx
@@ -25,15 +25,24 @@ class StringListWidget : public ListWidget
 {
   public:
     StringListWidget(GuiObject* boss, const GUI::Font& font,
-                     int x, int y, int w, int h, bool hilite = true);
+                     int x, int y, int w, int h, bool hilite = true,
+                     bool useScrollbar = true);
     ~StringListWidget() override = default;
 
     void setList(const StringList& list);
     bool wantsFocus() const override { return true; }
 
+    string getToolTip(const Common::Point& pos) const override;
+    bool changedToolTip(const Common::Point& oldPos, const Common::Point& newPos) const override;
+
   protected:
-    void handleMouseEntered() override;
-    void handleMouseLeft() override;
+    // display depends on _hasFocus so we have to redraw when focus changes
+    void receivedFocusWidget() override { setDirty(); }
+    void lostFocusWidget() override { setDirty(); }
+
+    bool hasToolTip() const override { return true; }
+    int getToolTipIndex(const Common::Point& pos) const;
+
     void drawWidget(bool hilite) override;
     Common::Rect getEditRect() const override;
 
diff --git a/src/gui/TabWidget.cxx b/src/gui/TabWidget.cxx
index accd65445..89967d041 100644
--- a/src/gui/TabWidget.cxx
+++ b/src/gui/TabWidget.cxx
@@ -110,6 +110,9 @@ void TabWidget::setActiveTab(int tabID, bool show)
     _tabs[_activeTab].firstWidget = _firstWidget;
   }
 
+  if(_activeTab != tabID)
+    setDirty();
+
   _activeTab = tabID;
   _firstWidget  = _tabs[tabID].firstWidget;
 
@@ -138,8 +141,6 @@ void TabWidget::updateActiveTab()
   if(_tabs[_activeTab].parentWidget)
     _tabs[_activeTab].parentWidget->loadConfig();
 
-  setDirty();
-
   // Redraw focused areas
   _boss->redrawFocus(); // TJ: Does nothing!
 }
@@ -213,20 +214,6 @@ void TabWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount)
   }
 }
 
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void TabWidget::handleMouseEntered()
-{
-  setFlags(Widget::FLAG_HILITED);
-  setDirty();
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void TabWidget::handleMouseLeft()
-{
-  clearFlags(Widget::FLAG_HILITED);
-  setDirty();
-}
-
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void TabWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
 {
@@ -275,39 +262,43 @@ void TabWidget::drawWidget(bool hilite)
   // The tab widget is strange in that it acts as both a widget (obviously)
   // and a dialog (it contains other widgets).  Because of the latter,
   // it must assume responsibility for refreshing all its children.
-  Widget::setDirtyInChain(_tabs[_activeTab].firstWidget);
 
-  FBSurface& s = dialog().surface();
-  bool onTop = _boss->dialog().isOnTop();
-
-  // Iterate over all tabs and draw them
-  int i, x = _x + kTabLeftOffset;
-  for (i = 0; i < int(_tabs.size()); ++i)
+  if(isDirty())
   {
-    int tabWidth = _tabs[i].tabWidth ? _tabs[i].tabWidth : _tabWidth;
-    ColorId fontcolor = _tabs[i].enabled && onTop? kTextColor : kColor;
-    int yOffset = (i == _activeTab) ? 0 : 1;
-    s.fillRect(x, _y + 1, tabWidth, _tabHeight - 1,
-              (i == _activeTab)
-               ? onTop ? kDlgColor : kBGColorLo
-               : onTop ? kBGColorHi : kDlgColor); // ? kWidColor : kDlgColor
-    s.drawString(_font, _tabs[i].title, x + kTabPadding + yOffset,
-                 _y + yOffset + (_tabHeight - _fontHeight - 1),
-                 tabWidth - 2 * kTabPadding, fontcolor, TextAlign::Center);
-    if(i == _activeTab)
+    FBSurface& s = dialog().surface();
+
+    // Iterate over all tabs and draw them
+    int i, x = _x + kTabLeftOffset;
+    for(i = 0; i < int(_tabs.size()); ++i)
     {
-      s.hLine(x, _y, x + tabWidth - 1, onTop ? kWidColor : kDlgColor);
-      s.vLine(x + tabWidth, _y + 1, _y + _tabHeight - 1, onTop ? kBGColorLo : kColor);
+      int tabWidth = _tabs[i].tabWidth ? _tabs[i].tabWidth : _tabWidth;
+      ColorId fontcolor = _tabs[i].enabled ? kTextColor : kColor;
+      int yOffset = (i == _activeTab) ? 0 : 1;
+      s.fillRect(x, _y + 1, tabWidth, _tabHeight - 1,
+                 (i == _activeTab)
+                 ? kDlgColor : kBGColorHi); // ? kWidColor : kDlgColor
+      s.drawString(_font, _tabs[i].title, x + kTabPadding + yOffset,
+                   _y + yOffset + (_tabHeight - _lineHeight - 1),
+                   tabWidth - 2 * kTabPadding, fontcolor, TextAlign::Center);
+      if(i == _activeTab)
+      {
+        s.hLine(x, _y, x + tabWidth - 1, kWidColor);
+        s.vLine(x + tabWidth, _y + 1, _y + _tabHeight - 1, kBGColorLo);
+      }
+      else
+        s.hLine(x, _y + _tabHeight, x + tabWidth, kWidColor);
+
+      x += tabWidth + kTabSpacing;
     }
-    else
-      s.hLine(x, _y + _tabHeight, x + tabWidth, onTop ? kWidColor : kDlgColor);
 
-    x += tabWidth + kTabSpacing;
+    // fill empty right space
+    s.hLine(x - kTabSpacing + 1, _y + _tabHeight, _x + _w - 1, kWidColor);
+    s.hLine(_x, _y + _h - 1, _x + _w - 1, kBGColorLo);
+
+    clearDirty();
+    // Make all child widgets of currently active tab dirty
+    Widget::setDirtyInChain(_tabs[_activeTab].firstWidget);
   }
-
-  // fill empty right space
-  s.hLine(x - kTabSpacing + 1, _y + _tabHeight, _x + _w - 1, onTop ? kWidColor : kDlgColor);
-  s.hLine(_x, _y + _h - 1, _x + _w - 1, onTop ? kBGColorLo : kColor);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/gui/TabWidget.hxx b/src/gui/TabWidget.hxx
index 1f581df5c..141b29497 100644
--- a/src/gui/TabWidget.hxx
+++ b/src/gui/TabWidget.hxx
@@ -63,8 +63,8 @@ class TabWidget : public Widget, public CommandSender
 
   protected:
     void handleMouseDown(int x, int y, MouseButton b, int clickCount) override;
-    void handleMouseEntered() override;
-    void handleMouseLeft() override;
+    void handleMouseEntered() override {}
+    void handleMouseLeft() override {}
 
     void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
     bool handleEvent(Event::Type event) override;
diff --git a/src/gui/TimeLineWidget.cxx b/src/gui/TimeLineWidget.cxx
index 053d7bccf..5f6e0e687 100644
--- a/src/gui/TimeLineWidget.cxx
+++ b/src/gui/TimeLineWidget.cxx
@@ -35,7 +35,9 @@ TimeLineWidget::TimeLineWidget(GuiObject* boss, const GUI::Font& font,
   : ButtonWidget(boss, font, x, y, w, h, label, cmd),
     _labelWidth(labelWidth)
 {
-  _flags = Widget::FLAG_ENABLED | Widget::FLAG_TRACK_MOUSE;
+  _flags = Widget::FLAG_ENABLED | Widget::FLAG_TRACK_MOUSE
+    | Widget::FLAG_CLEARBG | Widget::FLAG_NOBG;
+
   _bgcolor = kDlgColor;
   _bgcolorhi = kDlgColor;
 
@@ -84,7 +86,7 @@ void TimeLineWidget::setStepValues(const IntArray& steps)
     if(steps.size() > _stepValue.capacity())
       _stepValue.reserve(2 * steps.size());
 
-    double scale = (_w - _labelWidth - 2 - HANDLE_W*0) / double(steps.back());
+    double scale = (_w - _labelWidth - 2 - HANDLE_W) / double(steps.back());
 
     // Skip the very last value; we take care of it outside the end of the loop
     for(uInt32 i = 0; i < steps.size() - 1; ++i)
@@ -92,7 +94,7 @@ void TimeLineWidget::setStepValues(const IntArray& steps)
 
     // Due to integer <-> double conversion, the last value is sometimes
     // slightly less than the maximum value; we assign it manually to fix this
-    _stepValue.push_back(_w - _labelWidth - 2 - HANDLE_W*0);
+    _stepValue.push_back(_w - _labelWidth - 2 - HANDLE_W);
   }
   else
     _stepValue.push_back(0);
@@ -141,17 +143,18 @@ void TimeLineWidget::drawWidget(bool hilite)
 {
   FBSurface& s = _boss->dialog().surface();
 
+  //cerr << "TimeLineWidget::drawWidget " << typeid(s).name() << endl;
+
   // Draw the label, if any
   if(_labelWidth > 0)
     s.drawString(_font, _label, _x, _y + 2, _labelWidth,
                  isEnabled() ? kTextColor : kColor, TextAlign::Left);
 
-  int p = valueToPos(_value),
-    x = _x + _labelWidth,
-    w = _w - _labelWidth;
-
   // Frame the handle
   const int HANDLE_W2 = (HANDLE_W + 1) / 2;
+  int p = valueToPos(_value),
+    x = _x + _labelWidth + HANDLE_W2,
+    w = _w - _labelWidth - HANDLE_W;
   s.hLine(x + p - HANDLE_W2, _y + 0, x + p - HANDLE_W2 + HANDLE_W, kColorInfo);
   s.vLine(x + p - HANDLE_W2, _y + 1, _y + _h - 2, kColorInfo);
   s.hLine(x + p - HANDLE_W2 + 1, _y + _h - 1, x + p - HANDLE_W2 + 1 + HANDLE_W, kBGColor);
diff --git a/src/gui/TimeMachineDialog.cxx b/src/gui/TimeMachineDialog.cxx
index 3b591a62d..8e550d2a9 100644
--- a/src/gui/TimeMachineDialog.cxx
+++ b/src/gui/TimeMachineDialog.cxx
@@ -218,6 +218,7 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
 
   this->clearFlags(Widget::FLAG_CLEARBG); // does only work combined with blending (0..100)!
   this->clearFlags(Widget::FLAG_BORDER);
+  this->setFlags(Widget::FLAG_NOBG);
 
   xpos = H_BORDER;
   ypos = V_BORDER;
@@ -225,8 +226,10 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
   // Add index info
   myCurrentIdxWidget = new StaticTextWidget(this, font, xpos, ypos, "1000", TextAlign::Left, kBGColor);
   myCurrentIdxWidget->setTextColor(kColorInfo);
+  myCurrentIdxWidget->setFlags(Widget::FLAG_CLEARBG | Widget::FLAG_NOBG);
   myLastIdxWidget = new StaticTextWidget(this, font, _w - H_BORDER - font.getStringWidth("1000"), ypos,
                                          "1000", TextAlign::Right, kBGColor);
+  myLastIdxWidget->setFlags(Widget::FLAG_CLEARBG | Widget::FLAG_NOBG);
   myLastIdxWidget->setTextColor(kColorInfo);
 
   // Add timeline
@@ -241,9 +244,11 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
   // Add time info
   int ypos_s = ypos + (buttonHeight - font.getFontHeight() + 1) / 2; // align to button vertical center
   myCurrentTimeWidget = new StaticTextWidget(this, font, xpos, ypos_s, "00:00.00", TextAlign::Left, kBGColor);
+  myCurrentTimeWidget->setFlags(Widget::FLAG_CLEARBG | Widget::FLAG_NOBG);
   myCurrentTimeWidget->setTextColor(kColorInfo);
   myLastTimeWidget = new StaticTextWidget(this, font, _w - H_BORDER - font.getStringWidth("00:00.00"), ypos_s,
                                           "00:00.00", TextAlign::Right, kBGColor);
+  myLastTimeWidget->setFlags(Widget::FLAG_CLEARBG | Widget::FLAG_NOBG);
   myLastTimeWidget->setTextColor(kColorInfo);
   xpos = myCurrentTimeWidget->getRight() + BUTTON_GAP * 4;
 
@@ -287,11 +292,12 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
   // Add message
   myMessageWidget = new StaticTextWidget(this, font, xpos, ypos_s,
       "                                             ", TextAlign::Left, kBGColor);
+  myMessageWidget->setFlags(Widget::FLAG_CLEARBG | Widget::FLAG_NOBG);
   myMessageWidget->setTextColor(kColorInfo);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void TimeMachineDialog::center()
+void TimeMachineDialog::setPosition()
 {
   // Place on the bottom of the screen, centered horizontally
   const Common::Size& screen = instance().frameBuffer().screenSize();
@@ -434,11 +440,11 @@ void TimeMachineDialog::handleCommand(CommandSender* sender, int cmd,
       break;
 
     case kSaveAll:
-      instance().frameBuffer().showMessage(instance().state().rewindManager().saveAllStates());
+      instance().frameBuffer().showTextMessage(instance().state().rewindManager().saveAllStates());
       break;
 
     case kLoadAll:
-      instance().frameBuffer().showMessage(instance().state().rewindManager().loadAllStates());
+      instance().frameBuffer().showTextMessage(instance().state().rewindManager().loadAllStates());
       initBar();
       break;
 
diff --git a/src/gui/TimeMachineDialog.hxx b/src/gui/TimeMachineDialog.hxx
index a4a489b79..1d15d6b15 100644
--- a/src/gui/TimeMachineDialog.hxx
+++ b/src/gui/TimeMachineDialog.hxx
@@ -44,8 +44,8 @@ class TimeMachineDialog : public Dialog
     /** initialize timeline bar */
     void initBar();
 
-    /** This dialog uses its own positioning, so we override Dialog::center() */
-    void center() override;
+    /** This dialog uses its own positioning, so we override Dialog::setPosition() */
+    void setPosition() override;
 
     /** convert cycles into time */
     string getTimeString(uInt64 cycles);
diff --git a/src/gui/ToolTip.cxx b/src/gui/ToolTip.cxx
new file mode 100644
index 000000000..a887e0096
--- /dev/null
+++ b/src/gui/ToolTip.cxx
@@ -0,0 +1,183 @@
+//============================================================================
+//
+//   SSSS    tt          lll  lll
+//  SS  SS   tt           ll   ll
+//  SS     tttttt  eeee   ll   ll   aaaa
+//   SSSS    tt   ee  ee  ll   ll      aa
+//      SS   tt   eeeeee  ll   ll   aaaaa  --  "An Atari 2600 VCS Emulator"
+//  SS  SS   tt   ee      ll   ll  aa  aa
+//   SSSS     ttt  eeeee llll llll  aaaaa
+//
+// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
+// and the Stella Team
+//
+// See the file "License.txt" for information on usage and redistribution of
+// this file, and for a DISCLAIMER OF ALL WARRANTIES.
+//============================================================================
+
+#include "OSystem.hxx"
+#include "Dialog.hxx"
+#include "DialogContainer.hxx"
+#include "Font.hxx"
+#include "FrameBuffer.hxx"
+#include "FBSurface.hxx"
+#include "Widget.hxx"
+
+#include "ToolTip.hxx"
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ToolTip::ToolTip(Dialog& dialog, const GUI::Font& font)
+  : myDialog(dialog)
+{
+  myScale = myDialog.instance().frameBuffer().hidpiScaleFactor();
+
+  setFont(font);
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void ToolTip::setFont(const GUI::Font& font)
+{
+  myFont = &font;
+  const int fontWidth = font.getMaxCharWidth(),
+    fontHeight = font.getFontHeight();
+
+  myTextXOfs = fontHeight < 24 ? 5 : 8;
+  myTextYOfs = fontHeight < 24 ? 2 : 3;
+  myWidth = fontWidth * MAX_COLUMNS + myTextXOfs * 2;
+  myHeight = fontHeight * MAX_ROWS + myTextYOfs * 2;
+
+  mySurface = myDialog.instance().frameBuffer().allocateSurface(myWidth, myHeight);
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void ToolTip::request()
+{
+  // Called each frame when a tooltip is wanted
+  if(myFocusWidget && myTimer < DELAY_TIME * RELEASE_SPEED)
+  {
+    const string tip = myFocusWidget->getToolTip(myMousePos);
+
+    if(!tip.empty())
+    {
+      myTipWidget = myFocusWidget;
+      myTimer += RELEASE_SPEED;
+      if(myTimer >= DELAY_TIME * RELEASE_SPEED)
+        show(tip);
+    }
+  }
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void ToolTip::update(const Widget* widget, const Common::Point& pos)
+{
+  // Called each mouse move
+  myMousePos = pos;
+  myFocusWidget = widget;
+
+  if(myTipWidget != widget)
+    release(false);
+
+  if(!myTipShown)
+    release(true);
+  else
+  {
+    if(myTipWidget->changedToolTip(myTipPos, myMousePos))
+    {
+      const string tip = myTipWidget->getToolTip(myMousePos);
+
+      if(!tip.empty())
+        show(tip);
+      else
+        release(true);
+    }
+  }
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void ToolTip::hide()
+{
+  if(myTipShown)
+  {
+    myTimer = 0;
+    myTipWidget = myFocusWidget = nullptr;
+    myTipShown = false;
+    myDialog.instance().frameBuffer().setPendingRender();
+  }
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void ToolTip::release(bool emptyTip)
+{
+  if(myTipShown)
+  {
+    myTipShown = false;
+    myDialog.instance().frameBuffer().setPendingRender();
+  }
+
+  // After displaying a tip, slowly reset the timer to 0
+  //  until a new tip is requested
+  if((emptyTip || myTipWidget != myFocusWidget) && myTimer)
+    myTimer--;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void ToolTip::show(const string& tip)
+{
+  myTipPos = myMousePos;
+
+  uInt32 maxWidth = std::min(myWidth - myTextXOfs * 2, uInt32(myFont->getStringWidth(tip)));
+
+  mySurface->fillRect(1, 1, maxWidth + myTextXOfs * 2 - 2, myHeight - 2, kWidColor);
+  int lines = std::min(MAX_ROWS,
+                       uInt32(mySurface->drawString(*myFont, tip, myTextXOfs, myTextYOfs,
+                                                    maxWidth, myHeight - myTextYOfs * 2,
+                                                    kTextColor)));
+  // Calculate maximum width of drawn string lines
+  uInt32 width = 0;
+  string inStr = tip;
+  for(int i = 0; i < lines; ++i)
+  {
+    string leftStr, rightStr;
+
+    mySurface->splitString(*myFont, inStr, maxWidth, leftStr, rightStr);
+    width = std::max(width, uInt32(myFont->getStringWidth(leftStr)));
+    inStr = rightStr;
+  }
+  width += myTextXOfs * 2;
+
+  // Calculate and set surface size and position
+  const uInt32 height = std::min(myHeight, myFont->getFontHeight() * lines + myTextYOfs * 2);
+  const uInt32 V_GAP = 1;
+  const uInt32 H_CURSOR = 18;
+  // Note: The rects include HiDPI scaling
+  const Common::Rect imageRect = myDialog.instance().frameBuffer().imageRect();
+  const Common::Rect dialogRect = myDialog.surface().dstRect();
+  // Limit position to app size and adjust accordingly
+  const Int32 xAbs = myTipPos.x + dialogRect.x() / myScale;
+  const uInt32 yAbs = myTipPos.y + dialogRect.y() / myScale;
+  Int32 x = std::min(xAbs, Int32(imageRect.w() / myScale - width));
+  const uInt32 y = (yAbs + height + H_CURSOR > imageRect.h() / myScale)
+    ? yAbs - height - V_GAP
+    : yAbs + H_CURSOR / myScale + V_GAP;
+
+  if(x < 0)
+  {
+    x = 0;
+    width = std::min(width, imageRect.w() / myScale);
+  }
+
+  mySurface->setSrcSize(width, height);
+  mySurface->setDstSize(width * myScale, height * myScale);
+  mySurface->setDstPos(x * myScale, y * myScale);
+  mySurface->frameRect(0, 0, width, height, kColor);
+
+  myTipShown = true;
+  myDialog.instance().frameBuffer().setPendingRender();
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void ToolTip::render()
+{
+  if(myTipShown)
+    mySurface->render(); // , cerr << "    render tooltip" << endl;
+}
diff --git a/src/gui/ToolTip.hxx b/src/gui/ToolTip.hxx
new file mode 100644
index 000000000..71da6dc13
--- /dev/null
+++ b/src/gui/ToolTip.hxx
@@ -0,0 +1,101 @@
+//============================================================================
+//
+//   SSSS    tt          lll  lll
+//  SS  SS   tt           ll   ll
+//  SS     tttttt  eeee   ll   ll   aaaa
+//   SSSS    tt   ee  ee  ll   ll      aa
+//      SS   tt   eeeeee  ll   ll   aaaaa  --  "An Atari 2600 VCS Emulator"
+//  SS  SS   tt   ee      ll   ll  aa  aa
+//   SSSS     ttt  eeeee llll llll  aaaaa
+//
+// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
+// and the Stella Team
+//
+// See the file "License.txt" for information on usage and redistribution of
+// this file, and for a DISCLAIMER OF ALL WARRANTIES.
+//============================================================================
+
+#ifndef TOOL_TIP_HXX
+#define TOOL_TIP_HXX
+
+/**
+ * Class for providing tooltip functionality
+ *
+ * @author Thomas Jentzsch
+ */
+
+class OSystem;
+class Dialog;
+class Widget;
+class FBSurface;
+
+#include "Rect.hxx"
+
+class ToolTip
+{
+  private:
+    static constexpr uInt32 MAX_COLUMNS = 60;
+    static constexpr uInt32 MAX_ROWS = 5;
+
+  public:
+    // Maximum tooltip length
+    static constexpr uInt32 MAX_LEN = MAX_COLUMNS * MAX_ROWS;
+
+    ToolTip(Dialog& dialog, const GUI::Font& font);
+    ~ToolTip() = default;
+
+    void setFont(const GUI::Font& font);
+
+    /**
+      Request a tooltip display.
+    */
+    void request();
+
+    /**
+      Hide a displayed tooltip and reset the timer.
+    */
+    void hide();
+
+    /**
+      Hide a displayed tooltip and reset the timer slowly.
+      This allows faster tip display of the next tip.
+    */
+    void release(bool emptyTip);
+
+    /**
+      Update focused widget and current mouse position.
+    */
+    void update(const Widget* widget, const Common::Point& pos);
+
+    /*
+      Render the tooltip
+    */
+    void render();
+
+  private:
+    void show(const string& tip);
+
+  private:
+    static constexpr uInt32 DELAY_TIME = 45;   // display delay [frames]
+    // Tips are slower released than requested, so that repeated tips are shown
+    //  faster. This constant defines how much faster.
+    static constexpr uInt32 RELEASE_SPEED = 2;
+
+    Dialog& myDialog;
+    const GUI::Font* myFont{nullptr};
+    const Widget* myTipWidget{nullptr};
+    const Widget* myFocusWidget{nullptr};
+
+    uInt32 myTimer{0};
+    Common::Point myMousePos;
+    Common::Point myTipPos;
+    uInt32 myWidth{0};
+    uInt32 myHeight{0};
+    uInt32 myTextXOfs{0};
+    uInt32 myTextYOfs{0};
+    bool myTipShown{false};
+    uInt32 myScale{1};
+    shared_ptr<FBSurface> mySurface;
+};
+
+#endif
diff --git a/src/gui/UIDialog.cxx b/src/gui/UIDialog.cxx
index 1b64d73f2..2d773b888 100644
--- a/src/gui/UIDialog.cxx
+++ b/src/gui/UIDialog.cxx
@@ -109,6 +109,8 @@ UIDialog::UIDialog(OSystem& osystem, DialogContainer& parent,
   xpos = myDialogFontPopup->getRight() + fontWidth * 5;
   myHidpiWidget = new CheckboxWidget(myTab, font, xpos,
                                      ypos + 1, "HiDPI mode (*)");
+  myHidpiWidget->setToolTip("Scale the UI by a factor of two when enabled.");
+
   wid.push_back(myHidpiWidget);
 
   // Dialog position
@@ -126,6 +128,7 @@ UIDialog::UIDialog(OSystem& osystem, DialogContainer& parent,
   // Center window (in windowed mode)
   xpos = myHidpiWidget->getLeft();
   myCenter = new CheckboxWidget(myTab, _font, xpos, ypos + 1, "Center windows");
+  myCenter->setToolTip("Check to center all windows, else remember last position.");
   wid.push_back(myCenter);
 
   // Delay between quick-selecting characters in ListWidget
@@ -138,6 +141,8 @@ UIDialog::UIDialog(OSystem& osystem, DialogContainer& parent,
   myListDelaySlider->setMaxValue(1000);
   myListDelaySlider->setStepValue(50);
   myListDelaySlider->setTickmarkIntervals(5);
+  myListDelaySlider->setToolTip("Set delay between key presses in file lists"
+                                " before a search string resets.");
   wid.push_back(myListDelaySlider);
   ypos += lineHeight + VGAP;
 
@@ -441,6 +446,7 @@ void UIDialog::saveConfig()
   settings.setValue("uipalette",
     myPalettePopup->getSelectedTag().toString());
   instance().frameBuffer().setUIPalette();
+  instance().frameBuffer().update(FrameBuffer::UpdateMode::REDRAW);
 
   // Dialog font
   settings.setValue("dialogfont",
diff --git a/src/gui/UndoHandler.cxx b/src/gui/UndoHandler.cxx
new file mode 100644
index 000000000..f8eeb0c48
--- /dev/null
+++ b/src/gui/UndoHandler.cxx
@@ -0,0 +1,106 @@
+//============================================================================
+//
+//   SSSS    tt          lll  lll
+//  SS  SS   tt           ll   ll
+//  SS     tttttt  eeee   ll   ll   aaaa
+//   SSSS    tt   ee  ee  ll   ll      aa
+//      SS   tt   eeeeee  ll   ll   aaaaa  --  "An Atari 2600 VCS Emulator"
+//  SS  SS   tt   ee      ll   ll  aa  aa
+//   SSSS     ttt  eeeee llll llll  aaaaa
+//
+// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
+// and the Stella Team
+//
+// See the file "License.txt" for information on usage and redistribution of
+// this file, and for a DISCLAIMER OF ALL WARRANTIES.
+//============================================================================
+
+#include "UndoHandler.hxx"
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+UndoHandler::UndoHandler(size_t size)
+  : mySize(size)
+{
+  reset();
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void UndoHandler::reset()
+{
+  myBuffer.clear();
+  myCharMode = false;
+  myRedoCount = 0;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void UndoHandler::doChar()
+{
+  myCharMode = true;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool UndoHandler::endChars(const string& text)
+{
+  if(myCharMode)
+  {
+    doo(text);
+
+    return true;
+  }
+  return false;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void UndoHandler::doo(const string& text)
+{
+  // clear redos
+  for(; myRedoCount; myRedoCount--)
+    myBuffer.pop_front();
+
+  // limit buffer size
+  if(myBuffer.size() == mySize)
+    myBuffer.pop_back();
+
+  // add text to buffer
+  myBuffer.push_front(text);
+  myCharMode = false;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool UndoHandler::undo(string& text)
+{
+  if(myBuffer.size() > myRedoCount + 1)
+  {
+    text = myBuffer[++myRedoCount];
+
+    return true;
+  }
+  return false;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+bool UndoHandler::redo(string& text)
+{
+  if(myRedoCount)
+  {
+    text = myBuffer[--myRedoCount];
+
+    return true;
+  }
+  return false;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+uInt32 UndoHandler::lastDiff(const string& text, const string& oldText) const
+{
+  uInt32 pos = uInt32(text.size());
+
+  for(auto itn = text.crbegin(), ito = oldText.crbegin();
+      itn != text.crend() && ito != oldText.crend(); ++itn, ++ito)
+  {
+    if(*itn != *ito)
+      break;
+    pos--;
+  }
+  return uInt32(pos);
+}
diff --git a/src/gui/UndoHandler.hxx b/src/gui/UndoHandler.hxx
new file mode 100644
index 000000000..499423caf
--- /dev/null
+++ b/src/gui/UndoHandler.hxx
@@ -0,0 +1,71 @@
+//============================================================================
+//
+//   SSSS    tt          lll  lll
+//  SS  SS   tt           ll   ll
+//  SS     tttttt  eeee   ll   ll   aaaa
+//   SSSS    tt   ee  ee  ll   ll      aa
+//      SS   tt   eeeeee  ll   ll   aaaaa  --  "An Atari 2600 VCS Emulator"
+//  SS  SS   tt   ee      ll   ll  aa  aa
+//   SSSS     ttt  eeeee llll llll  aaaaa
+//
+// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
+// and the Stella Team
+//
+// See the file "License.txt" for information on usage and redistribution of
+// this file, and for a DISCLAIMER OF ALL WARRANTIES.
+//============================================================================
+
+
+#ifndef UNDO_HANDLER_HXX
+#define UNDO_HANDLER_HXX
+
+#include "bspf.hxx"
+#include <deque>
+
+/**
+ * Class for providing undo/redo functionality
+ *
+ * @author Thomas Jentzsch
+ */
+class UndoHandler
+{
+  public:
+    UndoHandler(size_t size = 100);
+    ~UndoHandler() = default;
+
+    // Reset undo buffer
+    void reset();
+
+    // Add input to undo buffer
+    void doo(const string& text);
+    // Retrieve last input from undo buffer
+    bool undo(string& text);
+    // Retrieve next input from undo buffer
+    bool redo(string& text);
+
+    // Add single char for aggregation
+    void doChar();
+    // Add aggregated single chars to undo buffer
+    bool endChars(const string& text);
+
+    // Get index into text of last different character
+    uInt32 lastDiff(const string& text, const string& oldText) const;
+
+  private:
+    std::deque<string> myBuffer;
+    // Undo buffer size
+    size_t  mySize{0};
+    // Aggregated single chars flag
+    bool    myCharMode{false};
+    // Number of chars available for redo
+    uInt32  myRedoCount{0};
+
+  private:
+    // Following constructors and assignment operators not supported
+    UndoHandler(const UndoHandler&) = delete;
+    UndoHandler(UndoHandler&&) = delete;
+    UndoHandler& operator=(const UndoHandler&) = delete;
+    UndoHandler& operator=(UndoHandler&&) = delete;
+};
+
+#endif
diff --git a/src/gui/VideoAudioDialog.cxx b/src/gui/VideoAudioDialog.cxx
index edb40c7bb..ac2ad19bf 100644
--- a/src/gui/VideoAudioDialog.cxx
+++ b/src/gui/VideoAudioDialog.cxx
@@ -102,6 +102,7 @@ VideoAudioDialog::VideoAudioDialog(OSystem& osystem, DialogContainer& parent,
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void VideoAudioDialog::addDisplayTab()
 {
+  const GUI::Font& ifont = instance().frameBuffer().infoFont();
   const int lineHeight   = _font.getLineHeight(),
             fontHeight   = _font.getFontHeight(),
             fontWidth    = _font.getMaxCharWidth();
@@ -121,14 +122,17 @@ void VideoAudioDialog::addDisplayTab()
   myRenderer = new PopUpWidget(myTab, _font, xpos, ypos, pwidth, lineHeight,
                                instance().frameBuffer().supportedRenderers(),
                                "Renderer ", lwidth);
+  myRenderer->setToolTip("Select renderer used for displaying screen.");
   wid.push_back(myRenderer);
   const int swidth = myRenderer->getWidth() - lwidth;
   ypos += lineHeight + VGAP;
 
   // TIA interpolation
   myTIAInterpolate = new CheckboxWidget(myTab, _font, xpos, ypos + 1, "Interpolation ");
-  wid.push_back(myTIAInterpolate);  ypos += lineHeight + VGAP * 4;
+  myTIAInterpolate->setToolTip("Blur emulated display.");
+  wid.push_back(myTIAInterpolate);
 
+  ypos += lineHeight + VGAP * 4;
   // TIA zoom levels (will be dynamically filled later)
   myTIAZoom = new SliderWidget(myTab, _font, xpos, ypos - 1, swidth, lineHeight,
                                "Zoom ", lwidth, 0, fontWidth * 4, "%");
@@ -143,12 +147,14 @@ void VideoAudioDialog::addDisplayTab()
 
   // FS stretch
   myUseStretch = new CheckboxWidget(myTab, _font, xpos + INDENT, ypos + 1, "Stretch");
+  myUseStretch->setToolTip("Stretch emulated display to fill whole screen.");
   wid.push_back(myUseStretch);
 
 #ifdef ADAPTABLE_REFRESH_SUPPORT
   // Adapt refresh rate
   ypos += lineHeight + VGAP;
   myRefreshAdapt = new CheckboxWidget(myTab, _font, xpos + INDENT, ypos + 1, "Adapt display refresh rate");
+  myRefreshAdapt->setToolTip("Select optimal display refresh rate for each ROM.");
   wid.push_back(myRefreshAdapt);
 #else
   myRefreshAdapt = nullptr;
@@ -162,6 +168,12 @@ void VideoAudioDialog::addDisplayTab()
   myTVOverscan->setTickmarkIntervals(2);
   wid.push_back(myTVOverscan);
 
+  // Aspect ratio correction
+  ypos += lineHeight + VGAP * 4;
+  myCorrectAspect = new CheckboxWidget(myTab, _font, xpos, ypos + 1, "Correct aspect ratio (*)");
+  myCorrectAspect->setToolTip("Uncheck to disable real world aspect ratio correction.");
+  wid.push_back(myCorrectAspect);
+
   // Vertical size
   ypos += lineHeight + VGAP;
   myVSizeAdjust =
@@ -169,9 +181,17 @@ void VideoAudioDialog::addDisplayTab()
                      "V-Size adjust", lwidth, kVSizeChanged, fontWidth * 7, "%", 0, true);
   myVSizeAdjust->setMinValue(-5); myVSizeAdjust->setMaxValue(5);
   myVSizeAdjust->setTickmarkIntervals(2);
+  myVSizeAdjust->setToolTip("Adjust vertical size to match emulated TV display.");
   wid.push_back(myVSizeAdjust);
 
 
+  // Add message concerning usage
+  ypos = myTab->getHeight() - fontHeight - ifont.getFontHeight() - VGAP - VBORDER;
+  int iwidth = ifont.getStringWidth("(*) Change may require an application restart");
+  new StaticTextWidget(myTab, ifont, xpos, ypos,
+                       std::min(iwidth, _w - HBORDER * 2), ifont.getFontHeight(),
+                       "(*) Change may require an application restart");
+
   // Add items for tab 0
   addToFocusList(wid, myTab, tabID);
 }
@@ -209,25 +229,90 @@ void VideoAudioDialog::addPaletteTab()
   const int swidth = myTIAPalette->getWidth() - lwidth;
   const int plWidth = _font.getStringWidth("NTSC phase ");
   const int pswidth = swidth - INDENT + lwidth - plWidth;
+  xpos += INDENT;
 
   myPhaseShiftNtsc =
-    new SliderWidget(myTab, _font, xpos + INDENT, ypos-1, pswidth, lineHeight,
+    new SliderWidget(myTab, _font, xpos, ypos - 1, pswidth, lineHeight,
                      "NTSC phase", plWidth, kNtscShiftChanged, fontWidth * 5);
-  myPhaseShiftNtsc->setMinValue((PaletteHandler::DEF_NTSC_SHIFT - PaletteHandler::MAX_SHIFT) * 10);
-  myPhaseShiftNtsc->setMaxValue((PaletteHandler::DEF_NTSC_SHIFT + PaletteHandler::MAX_SHIFT) * 10);
+  myPhaseShiftNtsc->setMinValue((PaletteHandler::DEF_NTSC_SHIFT - PaletteHandler::MAX_PHASE_SHIFT) * 10);
+  myPhaseShiftNtsc->setMaxValue((PaletteHandler::DEF_NTSC_SHIFT + PaletteHandler::MAX_PHASE_SHIFT) * 10);
   myPhaseShiftNtsc->setTickmarkIntervals(4);
+  myPhaseShiftNtsc->setToolTip("Adjust NTSC phase shift of 'Custom' palette.");
   wid.push_back(myPhaseShiftNtsc);
   ypos += lineHeight + VGAP;
 
   myPhaseShiftPal =
-    new SliderWidget(myTab, _font, xpos + INDENT, ypos-1, pswidth, lineHeight,
+    new SliderWidget(myTab, _font, xpos, ypos - 1, pswidth, lineHeight,
                      "PAL phase", plWidth, kPalShiftChanged, fontWidth * 5);
-  myPhaseShiftPal->setMinValue((PaletteHandler::DEF_PAL_SHIFT - PaletteHandler::MAX_SHIFT) * 10);
-  myPhaseShiftPal->setMaxValue((PaletteHandler::DEF_PAL_SHIFT + PaletteHandler::MAX_SHIFT) * 10);
+  myPhaseShiftPal->setMinValue((PaletteHandler::DEF_PAL_SHIFT - PaletteHandler::MAX_PHASE_SHIFT) * 10);
+  myPhaseShiftPal->setMaxValue((PaletteHandler::DEF_PAL_SHIFT + PaletteHandler::MAX_PHASE_SHIFT) * 10);
   myPhaseShiftPal->setTickmarkIntervals(4);
+  myPhaseShiftPal->setToolTip("Adjust PAL phase shift of 'Custom' palette.");
   wid.push_back(myPhaseShiftPal);
   ypos += lineHeight + VGAP;
 
+  const int rgblWidth = _font.getStringWidth("R ");
+  const int rgbsWidth = (myTIAPalette->getWidth() - INDENT - rgblWidth - fontWidth * 5) / 2;
+
+  myTVRedScale =
+    new SliderWidget(myTab, _font, xpos, ypos - 1, rgbsWidth, lineHeight,
+                     "R", rgblWidth, kPaletteUpdated, fontWidth * 4, "%");
+  myTVRedScale->setMinValue(0);
+  myTVRedScale->setMaxValue(100);
+  myTVRedScale->setTickmarkIntervals(2);
+  myTVRedScale->setToolTip("Adjust red saturation of 'Custom' palette.");
+  wid.push_back(myTVRedScale);
+
+  const int xposr = myTIAPalette->getRight() - rgbsWidth;
+  myTVRedShift =
+    new SliderWidget(myTab, _font, xposr, ypos - 1, rgbsWidth, lineHeight,
+                     "", 0, kRedShiftChanged, fontWidth * 6);
+  myTVRedShift->setMinValue((PaletteHandler::DEF_RGB_SHIFT - PaletteHandler::MAX_RGB_SHIFT) * 10);
+  myTVRedShift->setMaxValue((PaletteHandler::DEF_RGB_SHIFT + PaletteHandler::MAX_RGB_SHIFT) * 10);
+  myTVRedShift->setTickmarkIntervals(2);
+  myTVRedShift->setToolTip("Adjust red shift of 'Custom' palette.");
+  wid.push_back(myTVRedShift);
+  ypos += lineHeight + VGAP;
+
+  myTVGreenScale =
+    new SliderWidget(myTab, _font, xpos, ypos - 1, rgbsWidth, lineHeight,
+                     "G", rgblWidth, kPaletteUpdated, fontWidth * 4, "%");
+  myTVGreenScale->setMinValue(0);
+  myTVGreenScale->setMaxValue(100);
+  myTVGreenScale->setTickmarkIntervals(2);
+  myTVGreenScale->setToolTip("Adjust green saturation of 'Custom' palette.");
+  wid.push_back(myTVGreenScale);
+
+  myTVGreenShift =
+    new SliderWidget(myTab, _font, xposr, ypos - 1, rgbsWidth, lineHeight,
+                     "", 0, kGreenShiftChanged, fontWidth * 6);
+  myTVGreenShift->setMinValue((PaletteHandler::DEF_RGB_SHIFT - PaletteHandler::MAX_RGB_SHIFT) * 10);
+  myTVGreenShift->setMaxValue((PaletteHandler::DEF_RGB_SHIFT + PaletteHandler::MAX_RGB_SHIFT) * 10);
+  myTVGreenShift->setTickmarkIntervals(2);
+  myTVGreenShift->setToolTip("Adjust green shift of 'Custom' palette.");
+  wid.push_back(myTVGreenShift);
+  ypos += lineHeight + VGAP;
+
+  myTVBlueScale =
+    new SliderWidget(myTab, _font, xpos, ypos - 1, rgbsWidth, lineHeight,
+                     "B", rgblWidth, kPaletteUpdated, fontWidth * 4, "%");
+  myTVBlueScale->setMinValue(0);
+  myTVBlueScale->setMaxValue(100);
+  myTVBlueScale->setTickmarkIntervals(2);
+  myTVBlueScale->setToolTip("Adjust blue saturation of 'Custom' palette.");
+  wid.push_back(myTVBlueScale);
+
+  myTVBlueShift =
+    new SliderWidget(myTab, _font, xposr, ypos - 1, rgbsWidth, lineHeight,
+                     "", 0, kBlueShiftChanged, fontWidth * 6);
+  myTVBlueShift->setMinValue((PaletteHandler::DEF_RGB_SHIFT - PaletteHandler::MAX_RGB_SHIFT) * 10);
+  myTVBlueShift->setMaxValue((PaletteHandler::DEF_RGB_SHIFT + PaletteHandler::MAX_RGB_SHIFT) * 10);
+  myTVBlueShift->setTickmarkIntervals(2);
+  myTVBlueShift->setToolTip("Adjust blue shift of 'Custom' palette.");
+  wid.push_back(myTVBlueShift);
+  ypos += lineHeight + VGAP;
+  xpos -= INDENT;
+
   CREATE_CUSTOM_SLIDERS(Hue, "Hue ", kPaletteUpdated)
   CREATE_CUSTOM_SLIDERS(Satur, "Saturation ", kPaletteUpdated)
   CREATE_CUSTOM_SLIDERS(Contrast, "Contrast ", kPaletteUpdated)
@@ -494,6 +579,9 @@ void VideoAudioDialog::loadConfig()
   myTVOverscan->setValue(instance().settings().getInt("tia.fs_overscan"));
   handleFullScreenChange();
 
+  // Aspect ratio correction
+  myCorrectAspect->setState(instance().settings().getBool("tia.correct_aspect"));
+
   // Aspect ratio setting (NTSC and PAL)
   myVSizeAdjust->setValue(instance().settings().getInt("tia.vsizeadjust"));
 
@@ -507,6 +595,12 @@ void VideoAudioDialog::loadConfig()
   instance().frameBuffer().tiaSurface().paletteHandler().getAdjustables(myPaletteAdj);
   myPhaseShiftNtsc->setValue(myPaletteAdj.phaseNtsc);
   myPhaseShiftPal->setValue(myPaletteAdj.phasePal);
+  myTVRedScale->setValue(myPaletteAdj.redScale);
+  myTVRedShift->setValue(myPaletteAdj.redShift);
+  myTVGreenScale->setValue(myPaletteAdj.greenScale);
+  myTVGreenShift->setValue(myPaletteAdj.greenShift);
+  myTVBlueScale->setValue(myPaletteAdj.blueScale);
+  myTVBlueShift->setValue(myPaletteAdj.blueShift);
   myTVHue->setValue(myPaletteAdj.hue);
   myTVBright->setValue(myPaletteAdj.brightness);
   myTVContrast->setValue(myPaletteAdj.contrast);
@@ -551,7 +645,7 @@ void VideoAudioDialog::loadConfig()
   myVolumeSlider->setValue(audioSettings.volume());
 
   // Device
-  uInt32 deviceId = BSPF::clamp(audioSettings.device(), 0u,
+  uInt32 deviceId = BSPF::clamp(audioSettings.device(), 0U,
                                 uInt32(instance().sound().supportedDevices().size() - 1));
   myDevicePopup->setSelected(deviceId);
 
@@ -616,6 +710,9 @@ void VideoAudioDialog::saveConfig()
   // TIA zoom levels
   instance().settings().setValue("tia.zoom", myTIAZoom->getValue() / 100.0);
 
+  // Aspect ratio correction
+  instance().settings().setValue("tia.correct_aspect", myCorrectAspect->getState());
+
   // Aspect ratio setting (NTSC and PAL)
   const int oldAdjust = instance().settings().getInt("tia.vsizeadjust");
   const int newAdjust = myVSizeAdjust->getValue();
@@ -729,6 +826,7 @@ void VideoAudioDialog::setDefaults()
     #endif
       myTVOverscan->setValue(0);
       myTIAZoom->setValue(300);
+      myCorrectAspect->setState(true);
       myVSizeAdjust->setValue(0);
 
       handleFullScreenChange();
@@ -739,6 +837,12 @@ void VideoAudioDialog::setDefaults()
       myTIAPalette->setSelected(PaletteHandler::SETTING_STANDARD);
       myPhaseShiftNtsc->setValue(PaletteHandler::DEF_NTSC_SHIFT * 10);
       myPhaseShiftPal->setValue(PaletteHandler::DEF_PAL_SHIFT * 10);
+      myTVRedScale->setValue(50);
+      myTVRedShift->setValue(PaletteHandler::DEF_RGB_SHIFT);
+      myTVGreenScale->setValue(50);
+      myTVGreenShift->setValue(PaletteHandler::DEF_RGB_SHIFT);
+      myTVBlueScale->setValue(50);
+      myTVBlueShift->setValue(PaletteHandler::DEF_RGB_SHIFT);
       myTVHue->setValue(50);
       myTVSatur->setValue(50);
       myTVContrast->setValue(50);
@@ -826,6 +930,23 @@ void VideoAudioDialog::handlePaletteChange()
 
   myPhaseShiftNtsc->setEnabled(enable);
   myPhaseShiftPal->setEnabled(enable);
+  myTVRedScale->setEnabled(enable);
+  myTVRedShift->setEnabled(enable);
+  myTVGreenScale->setEnabled(enable);
+  myTVGreenShift->setEnabled(enable);
+  myTVBlueScale->setEnabled(enable);
+  myTVBlueShift->setEnabled(enable);
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void VideoAudioDialog::handleShiftChanged(SliderWidget* widget)
+{
+  std::ostringstream ss;
+
+  ss << std::setw(4) << std::fixed << std::setprecision(1)
+    << (0.1 * (widget->getValue())) << DEGREE;
+  widget->setValueLabel(ss.str());
+  handlePaletteUpdate();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -838,6 +959,12 @@ void VideoAudioDialog::handlePaletteUpdate()
   PaletteHandler::Adjustable paletteAdj;
   paletteAdj.phaseNtsc  = myPhaseShiftNtsc->getValue();
   paletteAdj.phasePal   = myPhaseShiftPal->getValue();
+  paletteAdj.redScale   = myTVRedScale->getValue();
+  paletteAdj.redShift   = myTVRedShift->getValue();
+  paletteAdj.greenScale = myTVGreenScale->getValue();
+  paletteAdj.greenShift = myTVGreenShift->getValue();
+  paletteAdj.blueScale  = myTVBlueScale->getValue();
+  paletteAdj.blueShift  = myTVBlueShift->getValue();
   paletteAdj.hue        = myTVHue->getValue();
   paletteAdj.saturation = myTVSatur->getValue();
   paletteAdj.contrast   = myTVContrast->getValue();
@@ -846,7 +973,16 @@ void VideoAudioDialog::handlePaletteUpdate()
   instance().frameBuffer().tiaSurface().paletteHandler().setAdjustables(paletteAdj);
 
   if(instance().hasConsole())
+  {
     instance().frameBuffer().tiaSurface().paletteHandler().setPalette();
+
+    constexpr int NUM_LUMA = 8;
+    constexpr int NUM_CHROMA = 16;
+
+    for(int idx = 0; idx < NUM_CHROMA; ++idx)
+      for(int lum = 0; lum < NUM_LUMA; ++lum)
+        myColor[idx][lum]->setDirty();
+  }
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -910,25 +1046,25 @@ void VideoAudioDialog::handleCommand(CommandSender* sender, int cmd,
       break;
 
     case kNtscShiftChanged:
-    {
-      std::ostringstream ss;
-
-      ss << std::setw(4) << std::fixed << std::setprecision(1)
-        << (0.1 * abs(myPhaseShiftNtsc->getValue())) << DEGREE;
-      myPhaseShiftNtsc->setValueLabel(ss.str());
-      handlePaletteUpdate();
+      handleShiftChanged(myPhaseShiftNtsc);
       break;
-    }
+
     case kPalShiftChanged:
-    {
-      std::ostringstream ss;
-
-      ss << std::setw(4) << std::fixed << std::setprecision(1)
-        << (0.1 * abs(myPhaseShiftPal->getValue())) << DEGREE;
-      myPhaseShiftPal->setValueLabel(ss.str());
-      handlePaletteUpdate();
+      handleShiftChanged(myPhaseShiftPal);
       break;
-    }
+
+    case kRedShiftChanged:
+      handleShiftChanged(myTVRedShift);
+      break;
+
+    case kGreenShiftChanged:
+      handleShiftChanged(myTVGreenShift);
+      break;
+
+    case kBlueShiftChanged:
+      handleShiftChanged(myTVBlueShift);
+      break;
+
     case kVSizeChanged:
     {
       int adjust = myVSizeAdjust->getValue();
@@ -1044,10 +1180,11 @@ void VideoAudioDialog::addPalette(int x, int y, int w, int h)
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void VideoAudioDialog::colorPalette()
 {
+  constexpr int NUM_LUMA = 8;
+  constexpr int NUM_CHROMA = 16;
+
   if(instance().hasConsole())
   {
-    constexpr int NUM_LUMA = 8;
-    constexpr int NUM_CHROMA = 16;
     const int order[2][NUM_CHROMA] =
     {
       {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
@@ -1063,11 +1200,14 @@ void VideoAudioDialog::colorPalette()
       ss << Common::Base::HEX1 << std::uppercase << color;
       myColorLbl[idx]->setLabel(ss.str());
       for(int lum = 0; lum < NUM_LUMA; ++lum)
-      {
         myColor[idx][lum]->setColor(color * NUM_CHROMA + lum * 2); // skip grayscale colors
-      }
     }
   }
+  else
+    // disable palette
+    for(int idx = 0; idx < NUM_CHROMA; ++idx)
+      for(int lum = 0; lum < NUM_LUMA; ++lum)
+        myColor[idx][lum]->setEnabled(false);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/gui/VideoAudioDialog.hxx b/src/gui/VideoAudioDialog.hxx
index 7f0fd817e..550617d2d 100644
--- a/src/gui/VideoAudioDialog.hxx
+++ b/src/gui/VideoAudioDialog.hxx
@@ -38,7 +38,7 @@ class VideoAudioDialog : public Dialog
 {
   public:
     VideoAudioDialog(OSystem& osystem, DialogContainer& parent, const GUI::Font& font,
-                int max_w, int max_h);
+                     int max_w, int max_h);
     ~VideoAudioDialog() override = default;
 
   private:
@@ -53,6 +53,7 @@ class VideoAudioDialog : public Dialog
     void handleTVModeChange(NTSCFilter::Preset);
     void loadTVAdjustables(NTSCFilter::Preset preset);
     void handlePaletteChange();
+    void handleShiftChanged(SliderWidget* widget);
     void handlePaletteUpdate();
     void handleFullScreenChange();
     void handleOverscanChange();
@@ -75,6 +76,7 @@ class VideoAudioDialog : public Dialog
     SliderWidget*     myTVOverscan{nullptr};
     CheckboxWidget*   myRefreshAdapt{nullptr};
     SliderWidget*     myTIAZoom{nullptr};
+    CheckboxWidget*   myCorrectAspect{nullptr};
     SliderWidget*     myVSizeAdjust{nullptr};
 
     // TV effects adjustables (custom mode)
@@ -104,6 +106,12 @@ class VideoAudioDialog : public Dialog
     PopUpWidget*      myTIAPalette{nullptr};
     SliderWidget*     myPhaseShiftNtsc{nullptr};
     SliderWidget*     myPhaseShiftPal{nullptr};
+    SliderWidget*     myTVRedScale{nullptr};
+    SliderWidget*     myTVRedShift{nullptr};
+    SliderWidget*     myTVGreenScale{nullptr};
+    SliderWidget*     myTVGreenShift{nullptr};
+    SliderWidget*     myTVBlueScale{nullptr};
+    SliderWidget*     myTVBlueShift{nullptr};
     SliderWidget*     myTVHue{nullptr};
     SliderWidget*     myTVSatur{nullptr};
     SliderWidget*     myTVBright{nullptr};
@@ -137,6 +145,9 @@ class VideoAudioDialog : public Dialog
       kPaletteChanged     = 'VDpl',
       kNtscShiftChanged   = 'VDns',
       kPalShiftChanged    = 'VDps',
+      kRedShiftChanged    = 'VDrs',
+      kGreenShiftChanged  = 'VDgs',
+      kBlueShiftChanged   = 'VDbs',
       kPaletteUpdated     = 'VDpu',
 
       kTVModeChanged      = 'VDtv',
diff --git a/src/gui/WhatsNewDialog.cxx b/src/gui/WhatsNewDialog.cxx
index 7f6c15084..4baa36101 100644
--- a/src/gui/WhatsNewDialog.cxx
+++ b/src/gui/WhatsNewDialog.cxx
@@ -38,25 +38,21 @@ WhatsNewDialog::WhatsNewDialog(OSystem& osystem, DialogContainer& parent, const
   const int HBORDER = fontWidth * 1.25;
   int ypos = _th + VBORDER;
 
-
   // Set preliminary dimensions
   setSize(MAX_CHARS * fontWidth + HBORDER * 2, max_h,
           max_w, max_h);
 
 #if defined(RETRON77)
-  add(ypos, "added adjustable autofire (see 'Advanced Settings')");
-  add(ypos, "added new UI theme 'Dark' (see 'Advanced Settings')");
+  add(ypos, "increased sample size for CDFJ+");
+  add(ypos, "fixed navigation bug in Video & Audio settings dialog");
+  add(ypos, "fixed autofire bug for trackball controllers");
 #else
-  add(ypos, "added adjustable autofire");
-  add(ypos, "added 'Dark' UI theme");
-  //add(ypos, "extended global hotkeys for debug options");
-  add(ypos, "added option to playback a game using the Time Machine");
-  //add(ypos, "allow taking snapshots from within the Time Machine dialog");
-  add(ypos, "added the ability to access most files that Stella uses from within a ZIP file");
-  add(ypos, "added option to select the audio device");
-  //add(ypos, "added option to display detected settings info when a ROM is loaded");
-  //add(ypos, "replaced 'Re-disassemble' with 'Disassemble @ current line' in debugger");
-  //add(ypos, "fixed bug when taking fullscreen snapshots; the dimensions were sometimes cut");
+  add(ypos, "enhanced cut/copy/paste for text editing");
+  add(ypos, "added undo and redo to text editing");
+  add(ypos, "added wildcard support to launcher dialog filter");
+  add(ypos, "added option to search subdirectories in launcher");
+  add(ypos, "added tooltips to many UI items");
+  add(ypos, "increased sample size for CDFJ+");
   add(ypos, ELLIPSIS + " (for a complete list see 'docs/Changes.txt')");
 #endif
 
diff --git a/src/gui/Widget.cxx b/src/gui/Widget.cxx
index ed6ba2f02..38c46bdbe 100644
--- a/src/gui/Widget.cxx
+++ b/src/gui/Widget.cxx
@@ -21,6 +21,7 @@
 #include "bspf.hxx"
 #include "Command.hxx"
 #include "Dialog.hxx"
+#include "ToolTip.hxx"
 #include "FBSurface.hxx"
 #include "GuiObject.hxx"
 #include "OSystem.hxx"
@@ -39,7 +40,7 @@ Widget::Widget(GuiObject* boss, const GUI::Font& font,
   _boss->_firstWidget = this;
 
   _fontWidth  = _font.getMaxCharWidth();
-  _fontHeight = _font.getLineHeight();
+  _lineHeight = _font.getLineHeight();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -54,9 +55,40 @@ Widget::~Widget()
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void Widget::setDirty()
 {
-  // A widget being dirty indicates that its parent dialog is dirty
-  // So we inform the parent about it
-  _boss->dialog().setDirty();
+  _dirty = true;
+
+  // Inform the parent object that its children chain is dirty
+  _boss->setDirtyChain();
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void Widget::setDirtyChain()
+{
+  _dirtyChain = true;
+
+  // Inform the parent object that its children chain is dirty
+  _boss->setDirtyChain();
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void Widget::tick()
+{
+  if(isEnabled())
+  {
+  #ifndef RETRON77
+    if(wantsToolTip())
+      dialog().tooltip().request();
+  #endif
+
+    // Recursively tick widget and all child dialogs and widgets
+    Widget* w = _firstWidget;
+
+    while(w)
+    {
+      w->tick();
+      w = w->_next;
+    }
+  }
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -65,62 +97,126 @@ void Widget::draw()
   if(!isVisible() || !_boss->isVisible())
     return;
 
-  FBSurface& s = _boss->dialog().surface();
-
-  bool onTop = _boss->dialog().isOnTop();
-
-  bool hasBorder = _flags & Widget::FLAG_BORDER; // currently only used by Dialog widget
-  int oldX = _x, oldY = _y;
-
-  // Account for our relative position in the dialog
-  _x = getAbsX();
-  _y = getAbsY();
-
-  // Clear background (unless alpha blending is enabled)
-  if(_flags & Widget::FLAG_CLEARBG)
+  if(isDirty())
   {
-    int x = _x, y = _y, w = _w, h = _h;
-    if(hasBorder)
+    //cerr << "  *** draw widget " << typeid(*this).name() << " ***" << endl;
+    cerr << "w";
+
+    FBSurface& s = _boss->dialog().surface();
+    int oldX = _x, oldY = _y;
+
+    // Account for our relative position in the dialog
+    _x = getAbsX();
+    _y = getAbsY();
+
+    // Clear background (unless alpha blending is enabled)
+    if(clearsBackground())
     {
-      x++; y++; w-=2; h-=2;
+      int x = _x, y = _y, w = _w, h = _h;
+      if(hasBorder())
+      {
+        x++; y++; w -= 2; h -= 2;
+      }
+      if(hasBackground())
+        s.fillRect(x, y, w, h, (_flags & Widget::FLAG_HILITED) && isEnabled()
+                   ? _bgcolorhi : _bgcolor);
+      else
+        s.invalidateRect(x, y, w, h);
     }
-    s.fillRect(x, y, w, h, !onTop ? _bgcolorlo : (_flags & Widget::FLAG_HILITED) && isEnabled() ? _bgcolorhi : _bgcolor);
+
+    // Draw border
+    if(hasBorder())
+    {
+      s.frameRect(_x, _y, _w, _h, (_flags & Widget::FLAG_HILITED) && isEnabled()
+                  ? kWidColorHi : kColor);
+      _x += 4;
+      _y += 4;
+      _w -= 8;
+      _h -= 8;
+    }
+
+    // Now perform the actual widget draw
+    drawWidget((_flags & Widget::FLAG_HILITED) ? true : false);
+
+    // Restore x/y
+    if(hasBorder())
+    {
+      _x -= 4;
+      _y -= 4;
+      _w += 8;
+      _h += 8;
+    }
+
+    _x = oldX;
+    _y = oldY;
   }
-
-  // Draw border
-  if(hasBorder)
-  {
-    s.frameRect(_x, _y, _w, _h, !onTop ? kColor : (_flags & Widget::FLAG_HILITED) && isEnabled() ? kWidColorHi : kColor);
-    _x += 4;
-    _y += 4;
-    _w -= 8;
-    _h -= 8;
-  }
-
-  // Now perform the actual widget draw
-  drawWidget((_flags & Widget::FLAG_HILITED) ? true : false);
-
-  // Restore x/y
-  if (hasBorder)
-  {
-    _x -= 4;
-    _y -= 4;
-    _w += 8;
-    _h += 8;
-  }
-
-  _x = oldX;
-  _y = oldY;
+  clearDirty();
 
   // Draw all children
+  drawChain();
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void Widget::drawChain()
+{
+  // Clear chain *before* drawing, because some widgets may set it again when
+  //   being drawn (e.g. RomListWidget)
+  clearDirtyChain();
+
   Widget* w = _firstWidget;
+
   while(w)
   {
-    w->draw();
+    if(w->needsRedraw())
+      w->draw();
     w = w->_next;
   }
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void Widget::setPosX(int x)
+{
+  setPos(x, _y);
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void Widget::setPosY(int y)
+{
+  setPos(_x, y);
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void Widget::setPos(int x, int y)
+{
+  setPos(Common::Point(x, y));
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void Widget::setPos(const Common::Point& pos)
+{
+  if(pos != Common::Point(_x, _y))
+  {
+    _x = pos.x;
+    _y = pos.y;
+    // we have to redraw the whole dialog!
+    dialog().setDirty();
+  }
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void Widget::handleMouseEntered()
+{
+  if(isEnabled())
+    setFlags(Widget::FLAG_HILITED | Widget::FLAG_MOUSE_FOCUS);
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void Widget::handleMouseLeft()
+{
+  if(isEnabled())
+    clearFlags(Widget::FLAG_HILITED | Widget::FLAG_MOUSE_FOCUS);
+}
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void Widget::receivedFocus()
 {
@@ -150,6 +246,14 @@ void Widget::setEnabled(bool e)
   else  clearFlags(Widget::FLAG_ENABLED);
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void Widget::setToolTip(const string& text)
+{
+  assert(text.length() <= ToolTip::MAX_LEN);
+
+  _toolTipText = text;
+}
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Widget* Widget::findWidgetInChain(Widget* w, int x, int y)
 {
@@ -197,7 +301,6 @@ Widget* Widget::setFocusForChain(GuiObject* boss, WidgetArray& arr,
   FBSurface& s = boss->dialog().surface();
   int size = int(arr.size()), pos = -1;
   Widget* tmp;
-  bool onTop = boss->dialog().isOnTop();
 
   for(int i = 0; i < size; ++i)
   {
@@ -222,9 +325,7 @@ Widget* Widget::setFocusForChain(GuiObject* boss, WidgetArray& arr,
       else
         tmp->_hasFocus = false;
 
-      s.frameRect(x, y, w, h, onTop ? kDlgColor : kBGColorLo);
-
-      tmp->setDirty();
+      s.frameRect(x, y, w, h, kDlgColor);
     }
   }
 
@@ -277,10 +378,7 @@ Widget* Widget::setFocusForChain(GuiObject* boss, WidgetArray& arr,
     tmp->setFlags(Widget::FLAG_HILITED);
   }
 
-  if (onTop)
-      s.frameRect(x, y, w, h, kWidFrameColor, FrameStyle::Dashed);
-
-  tmp->setDirty();
+  s.frameRect(x, y, w, h, kWidFrameColor, FrameStyle::Dashed);
 
   return tmp;
 }
@@ -290,6 +388,7 @@ void Widget::setDirtyInChain(Widget* start)
 {
   while(start)
   {
+    //cerr << "setDirtyInChain " << typeid(*start).name() << endl;
     start->setDirty();
     start = start->_next;
   }
@@ -304,7 +403,8 @@ StaticTextWidget::StaticTextWidget(GuiObject* boss, const GUI::Font& font,
     _label(text),
     _align(align)
 {
-  _flags = Widget::FLAG_ENABLED;
+  _flags = Widget::FLAG_ENABLED | FLAG_CLEARBG;
+
   _bgcolor = kDlgColor;
   _bgcolorhi = kDlgColor;
   _textcolor = kTextColor;
@@ -325,28 +425,42 @@ StaticTextWidget::StaticTextWidget(GuiObject* boss, const GUI::Font& font,
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void StaticTextWidget::setValue(int value)
 {
-  _label = std::to_string(value);
-
-  setDirty();
+  setLabel(std::to_string(value));
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void StaticTextWidget::setLabel(const string& label)
 {
-  _label = label;
+  if(_label != label)
+  {
+    _label = label;
+    setDirty();
+  }
+}
 
-  setDirty();
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void StaticTextWidget::handleMouseEntered()
+{
+  if(isEnabled())
+    // Mouse focus for tooltips must not change dirty status
+    setFlags(Widget::FLAG_MOUSE_FOCUS, false);
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void StaticTextWidget::handleMouseLeft()
+{
+  if(isEnabled())
+    // Mouse focus for tooltips must not change dirty status
+    clearFlags(Widget::FLAG_MOUSE_FOCUS, false);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void StaticTextWidget::drawWidget(bool hilite)
 {
   FBSurface& s = _boss->dialog().surface();
-  bool onTop = _boss->dialog().isOnTop();
-  s.drawString(_font, _label, _x, _y, _w,
-               isEnabled() && onTop ? _textcolor : kColor, _align, 0, true, _shadowcolor);
 
-  setDirty();
+  s.drawString(_font, _label, _x, _y, _w,
+               isEnabled() ? _textcolor : kColor, _align, 0, true, _shadowcolor);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -400,13 +514,15 @@ ButtonWidget::ButtonWidget(GuiObject* boss, const GUI::Font& font,
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void ButtonWidget::handleMouseEntered()
 {
-  setFlags(Widget::FLAG_HILITED);
+  if(isEnabled())
+    setFlags(Widget::FLAG_HILITED | Widget::FLAG_MOUSE_FOCUS);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void ButtonWidget::handleMouseLeft()
 {
-  clearFlags(Widget::FLAG_HILITED);
+  if(isEnabled())
+    clearFlags(Widget::FLAG_HILITED | Widget::FLAG_MOUSE_FOCUS);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -461,21 +577,18 @@ void ButtonWidget::setBitmap(const uInt32* bitmap, int bmw, int bmh)
 void ButtonWidget::drawWidget(bool hilite)
 {
   FBSurface& s = _boss->dialog().surface();
-  bool onTop = _boss->dialog().isOnTop();
 
-  s.frameRect(_x, _y, _w, _h, !onTop ? kShadowColor : hilite && isEnabled() ? kBtnBorderColorHi : kBtnBorderColor);
+  s.frameRect(_x, _y, _w, _h, hilite && isEnabled() ? kBtnBorderColorHi : kBtnBorderColor);
 
   if (!_useBitmap)
-    s.drawString(_font, _label, _x, _y + (_h - _fontHeight)/2 + 1, _w,
-                 !(isEnabled() && onTop) ? _textcolorlo :
+    s.drawString(_font, _label, _x, _y + (_h - _lineHeight)/2 + 1, _w,
+                 !isEnabled() ? _textcolorlo :
                  hilite ? _textcolorhi : _textcolor, _align);
   else
     s.drawBitmap(_bitmap, _x + (_w - _bmw) / 2, _y + (_h - _bmh) / 2,
-                 !(isEnabled() && onTop) ? _textcolorlo :
+                 !isEnabled() ? _textcolorlo :
                  hilite ? _textcolorhi : _textcolor,
                  _bmw, _bmh);
-
-  setDirty();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -508,18 +621,6 @@ CheckboxWidget::CheckboxWidget(GuiObject* boss, const GUI::Font& font,
   setFill(CheckboxWidget::FillType::Normal);
 }
 
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void CheckboxWidget::handleMouseEntered()
-{
-  setFlags(Widget::FLAG_HILITED);
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void CheckboxWidget::handleMouseLeft()
-{
-  clearFlags(Widget::FLAG_HILITED);
-}
-
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void CheckboxWidget::handleMouseUp(int x, int y, MouseButton b, int clickCount)
 {
@@ -608,35 +709,32 @@ void CheckboxWidget::setFill(FillType type)
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void CheckboxWidget::setState(bool state, bool changed)
 {
-  if(_state != state)
+  if(_state != state || _changed != changed)
   {
-    _state = state;
     setDirty();
+
+    _state = state;
+    _changed = changed;
   }
-  _changed = changed;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void CheckboxWidget::drawWidget(bool hilite)
 {
   FBSurface& s = _boss->dialog().surface();
-  bool onTop = _boss->dialog().isOnTop();
 
   if(_drawBox)
-    s.frameRect(_x, _y + _boxY, _boxSize, _boxSize, onTop && hilite && isEnabled() && isEditable() ? kWidColorHi : kColor);
+    s.frameRect(_x, _y + _boxY, _boxSize, _boxSize, hilite && isEnabled() && isEditable() ? kWidColorHi : kColor);
   // Do we draw a square or cross?
   s.fillRect(_x + 1, _y + _boxY + 1, _boxSize - 2, _boxSize - 2,
-      _changed ? onTop ? kDbgChangedColor : kDlgColor :
-      isEnabled() && onTop ? _bgcolor : kDlgColor);
+      _changed ? kDbgChangedColor : isEnabled() ? _bgcolor : kDlgColor);
   if(_state)
-    s.drawBitmap(_img, _x + 2, _y + _boxY + 2, onTop && isEnabled() ? hilite && isEditable() ? kWidColorHi : kCheckColor
+    s.drawBitmap(_img, _x + 2, _y + _boxY + 2, isEnabled() ? hilite && isEditable() ? kWidColorHi : kCheckColor
                  : kColor, _boxSize - 4);
 
   // Finally draw the label
   s.drawString(_font, _label, _x + prefixSize(_font), _y + _textY, _w,
-               onTop && isEnabled() ? kTextColor : kColor);
-
-  setDirty();
+               isEnabled() ? kTextColor : kColor);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -652,7 +750,7 @@ SliderWidget::SliderWidget(GuiObject* boss, const GUI::Font& font,
     _valueLabelWidth(valueLabelWidth),
     _forceLabelSign(forceLabelSign)
 {
-  _flags = Widget::FLAG_ENABLED | Widget::FLAG_TRACK_MOUSE;
+  _flags = Widget::FLAG_ENABLED | Widget::FLAG_TRACK_MOUSE | Widget::FLAG_CLEARBG;
   _bgcolor = kDlgColor;
   _bgcolorhi = kDlgColor;
 
@@ -870,8 +968,6 @@ void SliderWidget::drawWidget(bool hilite)
   if(_valueLabelWidth > 0)
     s.drawString(_font, _valueLabel + _valueUnit, _x + _w - _valueLabelWidth, _y + 2,
                  _valueLabelWidth, isEnabled() ? kTextColor : kColor);
-
-  setDirty();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/gui/Widget.hxx b/src/gui/Widget.hxx
index 3add250ba..cf4637ea1 100644
--- a/src/gui/Widget.hxx
+++ b/src/gui/Widget.hxx
@@ -26,6 +26,7 @@ class Dialog;
 #include <cassert>
 
 #include "bspf.hxx"
+#include "Rect.hxx"
 #include "Event.hxx"
 #include "EventHandlerConstants.hxx"
 #include "FrameBufferConstants.hxx"
@@ -42,19 +43,6 @@ class Widget : public GuiObject
 {
   friend class Dialog;
 
-  public:
-    enum : uInt32 {
-      FLAG_ENABLED       = 1 << 0,
-      FLAG_INVISIBLE     = 1 << 1,
-      FLAG_HILITED       = 1 << 2,
-      FLAG_BORDER        = 1 << 3,
-      FLAG_CLEARBG       = 1 << 4,
-      FLAG_TRACK_MOUSE   = 1 << 5,
-      FLAG_RETAIN_FOCUS  = 1 << 6,
-      FLAG_WANTS_TAB     = 1 << 7,
-      FLAG_WANTS_RAWDATA = 1 << 8
-    };
-
   public:
     Widget(GuiObject* boss, const GUI::Font& font, int x, int y, int w, int h);
     ~Widget() override;
@@ -65,14 +53,18 @@ class Widget : public GuiObject
     virtual int getTop() const { return _y; }
     virtual int getRight() const { return _x + getWidth(); }
     virtual int getBottom() const { return _y + getHeight(); }
+    virtual void setPosX(int x);
+    virtual void setPosY(int y);
+    virtual void setPos(int x, int y);
+    virtual void setPos(const Common::Point& pos);
 
     virtual bool handleText(char text)                        { return false; }
     virtual bool handleKeyDown(StellaKey key, StellaMod mod)  { return false; }
     virtual bool handleKeyUp(StellaKey key, StellaMod mod)    { return false; }
     virtual void handleMouseDown(int x, int y, MouseButton b, int clickCount) { }
     virtual void handleMouseUp(int x, int y, MouseButton b, int clickCount) { }
-    virtual void handleMouseEntered() { }
-    virtual void handleMouseLeft() { }
+    virtual void handleMouseEntered();
+    virtual void handleMouseLeft();
     virtual void handleMouseMoved(int x, int y) { }
     virtual void handleMouseWheel(int x, int y, int direction) { }
     virtual bool handleMouseClicks(int x, int y, MouseButton b) { return false; }
@@ -82,8 +74,12 @@ class Widget : public GuiObject
     virtual bool handleJoyHat(int stick, int hat, JoyHatDir hdir, int button = JOY_CTRL_NONE) { return false; }
     virtual bool handleEvent(Event::Type event) { return false; }
 
+    void tick() override;
+
     void setDirty() override;
+    void setDirtyChain() override;
     void draw() override;
+    void drawChain() override;
     void receivedFocus();
     void lostFocus();
     void addFocusWidget(Widget* w) override { _focusList.push_back(w); }
@@ -94,12 +90,10 @@ class Widget : public GuiObject
     /** Set/clear FLAG_ENABLED */
     void setEnabled(bool e);
 
-    void setFlags(uInt32 flags)    { _flags |= flags;  setDirty(); }
-    void clearFlags(uInt32 flags)  { _flags &= ~flags; setDirty(); }
-    uInt32 getFlags() const        { return _flags; }
-
     bool isEnabled() const          { return _flags & FLAG_ENABLED;         }
     bool isVisible() const override { return !(_flags & FLAG_INVISIBLE);    }
+    bool isHighlighted() const      { return _flags & FLAG_HILITED; }
+    bool hasMouseFocus() const      { return _flags & FLAG_MOUSE_FOCUS; }
     virtual bool wantsFocus() const { return _flags & FLAG_RETAIN_FOCUS;    }
     bool wantsTab() const           { return _flags & FLAG_WANTS_TAB;       }
     bool wantsRaw() const           { return _flags & FLAG_WANTS_RAWDATA;   }
@@ -115,6 +109,11 @@ class Widget : public GuiObject
     void setBGColorHi(ColorId color)   { _bgcolorhi = color;   setDirty(); }
     void setShadowColor(ColorId color) { _shadowcolor = color; setDirty(); }
 
+    void setToolTip(const string& text);
+    virtual string getToolTip(const Common::Point& pos) const { return _toolTipText; }
+    virtual bool changedToolTip(const Common::Point& oldPos,
+                                const Common::Point& newPos) const { return false; }
+
     virtual void loadConfig() { }
 
   protected:
@@ -127,6 +126,9 @@ class Widget : public GuiObject
 
     void releaseFocus() override { assert(_boss); _boss->releaseFocus(); }
 
+    virtual bool wantsToolTip() const { return hasMouseFocus() && hasToolTip(); }
+    virtual bool hasToolTip() const { return !_toolTipText.empty(); }
+
     // By default, delegate unhandled commands to the boss
     void handleCommand(CommandSender* sender, int cmd, int data, int id) override
          { assert(_boss); _boss->handleCommand(sender, cmd, data, id); }
@@ -136,10 +138,9 @@ class Widget : public GuiObject
     const GUI::Font& _font;
     Widget*    _next{nullptr};
     uInt32     _id{0};
-    uInt32     _flags{0};
     bool       _hasFocus{false};
     int        _fontWidth{0};
-    int        _fontHeight{0};
+    int        _lineHeight{0};
     ColorId    _bgcolor{kWidColor};
     ColorId    _bgcolorhi{kWidColor};
     ColorId    _bgcolorlo{kBGColorLo};
@@ -147,6 +148,7 @@ class Widget : public GuiObject
     ColorId    _textcolorhi{kTextColorHi};
     ColorId    _textcolorlo{kBGColorLo};
     ColorId    _shadowcolor{kShadowColor};
+    string     _toolTipText;
 
   public:
     static Widget* findWidgetInChain(Widget* start, int x, int y);
@@ -188,6 +190,10 @@ class StaticTextWidget : public Widget
                      const string& text = "", TextAlign align = TextAlign::Left,
                      ColorId shadowColor = kNone);
     ~StaticTextWidget() override = default;
+
+    void handleMouseEntered() override;
+    void handleMouseLeft() override;
+
     void setValue(int value);
     void setLabel(const string& label);
     void setAlign(TextAlign align) { _align = align; setDirty(); }
@@ -281,8 +287,6 @@ class CheckboxWidget : public ButtonWidget
     bool getState() const  { return _state;     }
 
     void handleMouseUp(int x, int y, MouseButton b, int clickCount) override;
-    void handleMouseEntered() override;
-    void handleMouseLeft() override;
 
     static int boxSize(const GUI::Font& font)
     {
@@ -336,7 +340,7 @@ class SliderWidget : public ButtonWidget
     ~SliderWidget() override = default;
 
     void setValue(int value);
-    int getValue() const { return _value; }
+    int getValue() const { return BSPF::clamp(_value, _valueMin, _valueMax); }
 
     void setMinValue(int value);
     int  getMinValue() const { return _valueMin; }
diff --git a/src/gui/module.mk b/src/gui/module.mk
index 4b52d3996..4be9b66ad 100644
--- a/src/gui/module.mk
+++ b/src/gui/module.mk
@@ -36,6 +36,7 @@ MODULE_OBJS := \
 	src/gui/OptionsDialog.o \
 	src/gui/PopUpWidget.o \
 	src/gui/ProgressDialog.o \
+	src/gui/QuadTariDialog.o \
 	src/gui/R77HelpDialog.o \
 	src/gui/RadioButtonWidget.o \
 	src/gui/RomAuditDialog.o \
@@ -48,6 +49,8 @@ MODULE_OBJS := \
 	src/gui/TimeLineWidget.o \
 	src/gui/TimeMachineDialog.o \
 	src/gui/TimeMachine.o \
+	src/gui/ToolTip.o \
+	src/gui/UndoHandler.o \
 	src/gui/UIDialog.o \
 	src/gui/VideoAudioDialog.o \
 	src/gui/WhatsNewDialog.o \
diff --git a/src/json/LICENSE.MIT b/src/json/LICENSE.MIT
new file mode 100644
index 000000000..ffef714b9
--- /dev/null
+++ b/src/json/LICENSE.MIT
@@ -0,0 +1,21 @@
+MIT License 
+
+Copyright (c) 2013-2020 Niels Lohmann
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/src/json/README.md b/src/json/README.md
new file mode 100644
index 000000000..288f2b0ea
--- /dev/null
+++ b/src/json/README.md
@@ -0,0 +1,1633 @@
+[![JSON for Modern C++](https://raw.githubusercontent.com/nlohmann/json/master/doc/json.gif)](https://github.com/nlohmann/json/releases)
+
+[![Build Status](https://travis-ci.org/nlohmann/json.svg?branch=master)](https://travis-ci.org/nlohmann/json)
+[![Build Status](https://ci.appveyor.com/api/projects/status/1acb366xfyg3qybk/branch/develop?svg=true)](https://ci.appveyor.com/project/nlohmann/json)
+[![Ubuntu](https://github.com/nlohmann/json/workflows/Ubuntu/badge.svg)](https://github.com/nlohmann/json/actions?query=workflow%3AUbuntu)
+[![macOS](https://github.com/nlohmann/json/workflows/macOS/badge.svg)](https://github.com/nlohmann/json/actions?query=workflow%3AmacOS)
+[![Windows](https://github.com/nlohmann/json/workflows/Windows/badge.svg)](https://github.com/nlohmann/json/actions?query=workflow%3AWindows)
+[![Build Status](https://circleci.com/gh/nlohmann/json.svg?style=svg)](https://circleci.com/gh/nlohmann/json)
+[![Coverage Status](https://coveralls.io/repos/github/nlohmann/json/badge.svg?branch=develop)](https://coveralls.io/github/nlohmann/json?branch=develop)
+[![Coverity Scan Build Status](https://scan.coverity.com/projects/5550/badge.svg)](https://scan.coverity.com/projects/nlohmann-json)
+[![Codacy Badge](https://api.codacy.com/project/badge/Grade/f3732b3327e34358a0e9d1fe9f661f08)](https://www.codacy.com/app/nlohmann/json?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=nlohmann/json&amp;utm_campaign=Badge_Grade)
+[![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/nlohmann/json.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/nlohmann/json/context:cpp)
+[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/json.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:json)
+[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/3lCHrFUZANONKv7a)
+[![Documentation](https://img.shields.io/badge/docs-doxygen-blue.svg)](https://nlohmann.github.io/json/doxygen/index.html)
+[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/nlohmann/json/master/LICENSE.MIT)
+[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fnlohmann%2Fjson.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fnlohmann%2Fjson?ref=badge_shield)
+[![GitHub Releases](https://img.shields.io/github/release/nlohmann/json.svg)](https://github.com/nlohmann/json/releases)
+[![GitHub Downloads](https://img.shields.io/github/downloads/nlohmann/json/total)](https://github.com/nlohmann/json/releases)
+[![GitHub Issues](https://img.shields.io/github/issues/nlohmann/json.svg)](https://github.com/nlohmann/json/issues)
+[![Average time to resolve an issue](https://isitmaintained.com/badge/resolution/nlohmann/json.svg)](https://isitmaintained.com/project/nlohmann/json "Average time to resolve an issue")
+[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/289/badge)](https://bestpractices.coreinfrastructure.org/projects/289)
+[![GitHub Sponsors](https://img.shields.io/badge/GitHub-Sponsors-ff69b4)](https://github.com/sponsors/nlohmann)
+
+- [Design goals](#design-goals)
+- [Sponsors](#sponsors)
+- [Integration](#integration)
+  - [CMake](#cmake)
+  - [Package Managers](#package-managers)
+  - [Pkg-config](#pkg-config)
+- [Examples](#examples)
+  - [JSON as first-class data type](#json-as-first-class-data-type)
+  - [Serialization / Deserialization](#serialization--deserialization)
+  - [STL-like access](#stl-like-access)
+  - [Conversion from STL containers](#conversion-from-stl-containers)
+  - [JSON Pointer and JSON Patch](#json-pointer-and-json-patch)
+  - [JSON Merge Patch](#json-merge-patch)
+  - [Implicit conversions](#implicit-conversions)
+  - [Conversions to/from arbitrary types](#arbitrary-types-conversions)
+  - [Specializing enum conversion](#specializing-enum-conversion)
+  - [Binary formats (BSON, CBOR, MessagePack, and UBJSON)](#binary-formats-bson-cbor-messagepack-and-ubjson)
+- [Supported compilers](#supported-compilers)
+- [License](#license)
+- [Contact](#contact)
+- [Thanks](#thanks)
+- [Used third-party tools](#used-third-party-tools)
+- [Projects using JSON for Modern C++](#projects-using-json-for-modern-c)
+- [Notes](#notes)
+- [Execute unit tests](#execute-unit-tests)
+
+## Design goals
+
+There are myriads of [JSON](https://json.org) libraries out there, and each may even have its reason to exist. Our class had these design goals:
+
+- **Intuitive syntax**. In languages such as Python, JSON feels like a first class data type. We used all the operator magic of modern C++ to achieve the same feeling in your code. Check out the [examples below](#examples) and you'll know what I mean.
+
+- **Trivial integration**. Our whole code consists of a single header file [`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp). That's it. No library, no subproject, no dependencies, no complex build system. The class is written in vanilla C++11. All in all, everything should require no adjustment of your compiler flags or project settings.
+
+- **Serious testing**. Our class is heavily [unit-tested](https://github.com/nlohmann/json/tree/develop/test/src) and covers [100%](https://coveralls.io/r/nlohmann/json) of the code, including all exceptional behavior. Furthermore, we checked with [Valgrind](https://valgrind.org) and the [Clang Sanitizers](https://clang.llvm.org/docs/index.html) that there are no memory leaks. [Google OSS-Fuzz](https://github.com/google/oss-fuzz/tree/master/projects/json) additionally runs fuzz tests against all parsers 24/7, effectively executing billions of tests so far. To maintain high quality, the project is following the [Core Infrastructure Initiative (CII) best practices](https://bestpractices.coreinfrastructure.org/projects/289).
+
+Other aspects were not so important to us:
+
+- **Memory efficiency**. Each JSON object has an overhead of one pointer (the maximal size of a union) and one enumeration element (1 byte). The default generalization uses the following C++ data types: `std::string` for strings, `int64_t`, `uint64_t` or `double` for numbers, `std::map` for objects, `std::vector` for arrays, and `bool` for Booleans. However, you can template the generalized class `basic_json` to your needs.
+
+- **Speed**. There are certainly [faster JSON libraries](https://github.com/miloyip/nativejson-benchmark#parsing-time) out there. However, if your goal is to speed up your development by adding JSON support with a single header, then this library is the way to go. If you know how to use a `std::vector` or `std::map`, you are already set.
+
+See the [contribution guidelines](https://github.com/nlohmann/json/blob/master/.github/CONTRIBUTING.md#please-dont) for more information.
+
+
+## Sponsors
+
+You can sponsor this library at [GitHub Sponsors](https://github.com/sponsors/nlohmann).
+
+### :label: Named Sponsors
+
+- [Michael Hartmann](https://github.com/reFX-Mike)
+- [Stefan Hagen](https://github.com/sthagen)
+- [Steve Sperandeo](https://github.com/homer6)
+- [Robert Jefe Lindstädt](https://github.com/eljefedelrodeodeljefe)
+
+Thanks everyone!
+
+
+## Integration
+
+[`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp) is the single required file in `single_include/nlohmann` or [released here](https://github.com/nlohmann/json/releases). You need to add
+
+```cpp
+#include <nlohmann/json.hpp>
+
+// for convenience
+using json = nlohmann::json;
+```
+
+to the files you want to process JSON and set the necessary switches to enable C++11 (e.g., `-std=c++11` for GCC and Clang).
+
+You can further use file [`include/nlohmann/json_fwd.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/json_fwd.hpp) for forward-declarations. The installation of json_fwd.hpp (as part of cmake's install step), can be achieved by setting `-DJSON_MultipleHeaders=ON`.
+
+### CMake
+
+You can also use the `nlohmann_json::nlohmann_json` interface target in CMake.  This target populates the appropriate usage requirements for `INTERFACE_INCLUDE_DIRECTORIES` to point to the appropriate include directories and `INTERFACE_COMPILE_FEATURES` for the necessary C++11 flags.
+
+#### External
+
+To use this library from a CMake project, you can locate it directly with `find_package()` and use the namespaced imported target from the generated package configuration:
+
+```cmake
+# CMakeLists.txt
+find_package(nlohmann_json 3.2.0 REQUIRED)
+...
+add_library(foo ...)
+...
+target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
+```
+
+The package configuration file, `nlohmann_jsonConfig.cmake`, can be used either from an install tree or directly out of the build tree.
+
+#### Embedded
+
+To embed the library directly into an existing CMake project, place the entire source tree in a subdirectory and call `add_subdirectory()` in your `CMakeLists.txt` file:
+
+```cmake
+# Typically you don't care so much for a third party library's tests to be
+# run from your own project's code.
+set(JSON_BuildTests OFF CACHE INTERNAL "")
+
+# If you only include this third party in PRIVATE source files, you do not
+# need to install it when your main project gets installed.
+# set(JSON_Install OFF CACHE INTERNAL "")
+
+# Don't use include(nlohmann_json/CMakeLists.txt) since that carries with it
+# unintended consequences that will break the build.  It's generally
+# discouraged (although not necessarily well documented as such) to use
+# include(...) for pulling in other CMake projects anyways.
+add_subdirectory(nlohmann_json)
+...
+add_library(foo ...)
+...
+target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
+```
+
+##### Embedded (FetchContent)
+
+Since CMake v3.11,
+[FetchContent](https://cmake.org/cmake/help/v3.11/module/FetchContent.html) can
+be used to automatically download the repository as a dependency at configure type.
+
+Example:
+```cmake
+include(FetchContent)
+
+FetchContent_Declare(json
+  GIT_REPOSITORY https://github.com/nlohmann/json.git
+  GIT_TAG v3.7.3)
+
+FetchContent_GetProperties(json)
+if(NOT json_POPULATED)
+  FetchContent_Populate(json)
+  add_subdirectory(${json_SOURCE_DIR} ${json_BINARY_DIR} EXCLUDE_FROM_ALL)
+endif()
+
+target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
+```
+
+**Note**: The repository https://github.com/nlohmann/json download size is huge.
+It contains all the dataset used for the benchmarks. You might want to depend on
+a smaller repository. For instance, you might want to replace the URL above by
+https://github.com/ArthurSonzogni/nlohmann_json_cmake_fetchcontent
+
+#### Supporting Both
+
+To allow your project to support either an externally supplied or an embedded JSON library, you can use a pattern akin to the following:
+
+``` cmake
+# Top level CMakeLists.txt
+project(FOO)
+...
+option(FOO_USE_EXTERNAL_JSON "Use an external JSON library" OFF)
+...
+add_subdirectory(thirdparty)
+...
+add_library(foo ...)
+...
+# Note that the namespaced target will always be available regardless of the
+# import method
+target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
+```
+```cmake
+# thirdparty/CMakeLists.txt
+...
+if(FOO_USE_EXTERNAL_JSON)
+  find_package(nlohmann_json 3.2.0 REQUIRED)
+else()
+  set(JSON_BuildTests OFF CACHE INTERNAL "")
+  add_subdirectory(nlohmann_json)
+endif()
+...
+```
+
+`thirdparty/nlohmann_json` is then a complete copy of this source tree.
+
+### Package Managers
+
+:beer: If you are using OS X and [Homebrew](https://brew.sh), just type `brew tap nlohmann/json` and `brew install nlohmann-json` and you're set. If you want the bleeding edge rather than the latest release, use `brew install nlohmann-json --HEAD`.
+
+If you are using the [Meson Build System](https://mesonbuild.com), add this source tree as a [meson subproject](https://mesonbuild.com/Subprojects.html#using-a-subproject). You may also use the `include.zip` published in this project's [Releases](https://github.com/nlohmann/json/releases) to reduce the size of the vendored source tree. Alternatively, you can get a wrap file by downloading it from [Meson WrapDB](https://wrapdb.mesonbuild.com/nlohmann_json), or simply use `meson wrap install nlohmann_json`. Please see the meson project for any issues regarding the packaging.
+
+The provided meson.build can also be used as an alternative to cmake for installing `nlohmann_json` system-wide in which case a pkg-config file is installed. To use it, simply have your build system require the `nlohmann_json` pkg-config dependency. In Meson, it is preferred to use the [`dependency()`](https://mesonbuild.com/Reference-manual.html#dependency) object with a subproject fallback, rather than using the subproject directly.
+
+If you are using [Conan](https://www.conan.io/) to manage your dependencies, merely add `nlohmann_json/x.y.z` to your `conanfile`'s requires, where `x.y.z` is the release version you want to use. Please file issues [here](https://github.com/conan-io/conan-center-index/issues) if you experience problems with the packages.
+
+If you are using [Spack](https://www.spack.io/) to manage your dependencies, you can use the [`nlohmann-json` package](https://spack.readthedocs.io/en/latest/package_list.html#nlohmann-json). Please see the [spack project](https://github.com/spack/spack) for any issues regarding the packaging.
+
+If you are using [hunter](https://github.com/cpp-pm/hunter) on your project for external dependencies, then you can use the [nlohmann_json package](https://hunter.readthedocs.io/en/latest/packages/pkg/nlohmann_json.html). Please see the hunter project for any issues regarding the packaging.
+
+If you are using [Buckaroo](https://buckaroo.pm), you can install this library's module with `buckaroo add github.com/buckaroo-pm/nlohmann-json`. Please file issues [here](https://github.com/buckaroo-pm/nlohmann-json). There is a demo repo [here](https://github.com/njlr/buckaroo-nholmann-json-example).
+
+If you are using [vcpkg](https://github.com/Microsoft/vcpkg/) on your project for external dependencies, then you can use the [nlohmann-json package](https://github.com/Microsoft/vcpkg/tree/master/ports/nlohmann-json). Please see the vcpkg project for any issues regarding the packaging.
+
+If you are using [cget](https://cget.readthedocs.io/en/latest/), you can install the latest development version with `cget install nlohmann/json`. A specific version can be installed with `cget install nlohmann/json@v3.1.0`. Also, the multiple header version can be installed by adding the `-DJSON_MultipleHeaders=ON` flag (i.e., `cget install nlohmann/json -DJSON_MultipleHeaders=ON`).
+
+If you are using [CocoaPods](https://cocoapods.org), you can use the library by adding pod `"nlohmann_json", '~>3.1.2'` to your podfile (see [an example](https://bitbucket.org/benman/nlohmann_json-cocoapod/src/master/)). Please file issues [here](https://bitbucket.org/benman/nlohmann_json-cocoapod/issues?status=new&status=open).
+
+If you are using [NuGet](https://www.nuget.org), you can use the package [nlohmann.json](https://www.nuget.org/packages/nlohmann.json/). Please check [this extensive description](https://github.com/nlohmann/json/issues/1132#issuecomment-452250255) on how to use the package. Please files issues [here](https://github.com/hnkb/nlohmann-json-nuget/issues).
+
+If you are using [conda](https://conda.io/), you can use the package [nlohmann_json](https://github.com/conda-forge/nlohmann_json-feedstock) from [conda-forge](https://conda-forge.org) executing `conda install -c conda-forge nlohmann_json`. Please file issues [here](https://github.com/conda-forge/nlohmann_json-feedstock/issues).
+
+If you are using [MSYS2](https://www.msys2.org/), your can use the [mingw-w64-nlohmann-json](https://packages.msys2.org/base/mingw-w64-nlohmann-json) package, just type `pacman -S mingw-w64-i686-nlohmann-json` or `pacman -S mingw-w64-x86_64-nlohmann-json` for installation. Please file issues [here](https://github.com/msys2/MINGW-packages/issues/new?title=%5Bnlohmann-json%5D) if you experience problems with the packages.
+
+If you are using [`build2`](https://build2.org), you can use the [`nlohmann-json`](https://cppget.org/nlohmann-json) package from the public repository https://cppget.org or directly from the [package's sources repository](https://github.com/build2-packaging/nlohmann-json). In your project's `manifest` file, just add `depends: nlohmann-json` (probably with some [version constraints](https://build2.org/build2-toolchain/doc/build2-toolchain-intro.xhtml#guide-add-remove-deps)). If you are not familiar with using dependencies in `build2`, [please read this introduction](https://build2.org/build2-toolchain/doc/build2-toolchain-intro.xhtml).
+Please file issues [here](https://github.com/build2-packaging/nlohmann-json) if you experience problems with the packages.
+
+If you are using [`wsjcpp`](https://wsjcpp.org), you can use the command `wsjcpp install "https://github.com/nlohmann/json:develop"` to get the latest version. Note you can change the branch ":develop" to an existing tag or another branch.
+
+### Pkg-config
+
+If you are using bare Makefiles, you can use `pkg-config` to generate the include flags that point to where the library is installed:
+
+```sh
+pkg-config nlohmann_json --cflags
+```
+
+Users of the Meson build system will also be able to use a system wide library, which will be found by `pkg-config`:
+
+```meson
+json = dependency('nlohmann_json', required: true)
+```
+
+## Examples
+
+Beside the examples below, you may want to check the [documentation](https://nlohmann.github.io/json/) where each function contains a separate code example (e.g., check out [`emplace()`](https://nlohmann.github.io/json/api/basic_json/emplace/)). All [example files](https://github.com/nlohmann/json/tree/develop/doc/examples) can be compiled and executed on their own (e.g., file [emplace.cpp](https://github.com/nlohmann/json/blob/develop/doc/examples/emplace.cpp)).
+
+### JSON as first-class data type
+
+Here are some examples to give you an idea how to use the class.
+
+Assume you want to create the JSON object
+
+```json
+{
+  "pi": 3.141,
+  "happy": true,
+  "name": "Niels",
+  "nothing": null,
+  "answer": {
+    "everything": 42
+  },
+  "list": [1, 0, 2],
+  "object": {
+    "currency": "USD",
+    "value": 42.99
+  }
+}
+```
+
+With this library, you could write:
+
+```cpp
+// create an empty structure (null)
+json j;
+
+// add a number that is stored as double (note the implicit conversion of j to an object)
+j["pi"] = 3.141;
+
+// add a Boolean that is stored as bool
+j["happy"] = true;
+
+// add a string that is stored as std::string
+j["name"] = "Niels";
+
+// add another null object by passing nullptr
+j["nothing"] = nullptr;
+
+// add an object inside the object
+j["answer"]["everything"] = 42;
+
+// add an array that is stored as std::vector (using an initializer list)
+j["list"] = { 1, 0, 2 };
+
+// add another object (using an initializer list of pairs)
+j["object"] = { {"currency", "USD"}, {"value", 42.99} };
+
+// instead, you could also write (which looks very similar to the JSON above)
+json j2 = {
+  {"pi", 3.141},
+  {"happy", true},
+  {"name", "Niels"},
+  {"nothing", nullptr},
+  {"answer", {
+    {"everything", 42}
+  }},
+  {"list", {1, 0, 2}},
+  {"object", {
+    {"currency", "USD"},
+    {"value", 42.99}
+  }}
+};
+```
+
+Note that in all these cases, you never need to "tell" the compiler which JSON value type you want to use. If you want to be explicit or express some edge cases, the functions [`json::array()`](https://nlohmann.github.io/json/api/basic_json/array/) and [`json::object()`](https://nlohmann.github.io/json/api/basic_json/object/) will help:
+
+```cpp
+// a way to express the empty array []
+json empty_array_explicit = json::array();
+
+// ways to express the empty object {}
+json empty_object_implicit = json({});
+json empty_object_explicit = json::object();
+
+// a way to express an _array_ of key/value pairs [["currency", "USD"], ["value", 42.99]]
+json array_not_object = json::array({ {"currency", "USD"}, {"value", 42.99} });
+```
+
+### Serialization / Deserialization
+
+#### To/from strings
+
+You can create a JSON value (deserialization) by appending `_json` to a string literal:
+
+```cpp
+// create object from string literal
+json j = "{ \"happy\": true, \"pi\": 3.141 }"_json;
+
+// or even nicer with a raw string literal
+auto j2 = R"(
+  {
+    "happy": true,
+    "pi": 3.141
+  }
+)"_json;
+```
+
+Note that without appending the `_json` suffix, the passed string literal is not parsed, but just used as JSON string value. That is, `json j = "{ \"happy\": true, \"pi\": 3.141 }"` would just store the string `"{ "happy": true, "pi": 3.141 }"` rather than parsing the actual object.
+
+The above example can also be expressed explicitly using [`json::parse()`](https://nlohmann.github.io/json/api/basic_json/parse/):
+
+```cpp
+// parse explicitly
+auto j3 = json::parse("{ \"happy\": true, \"pi\": 3.141 }");
+```
+
+You can also get a string representation of a JSON value (serialize):
+
+```cpp
+// explicit conversion to string
+std::string s = j.dump();    // {"happy":true,"pi":3.141}
+
+// serialization with pretty printing
+// pass in the amount of spaces to indent
+std::cout << j.dump(4) << std::endl;
+// {
+//     "happy": true,
+//     "pi": 3.141
+// }
+```
+
+Note the difference between serialization and assignment:
+
+```cpp
+// store a string in a JSON value
+json j_string = "this is a string";
+
+// retrieve the string value
+auto cpp_string = j_string.get<std::string>();
+// retrieve the string value (alternative when an variable already exists)
+std::string cpp_string2;
+j_string.get_to(cpp_string2);
+
+// retrieve the serialized value (explicit JSON serialization)
+std::string serialized_string = j_string.dump();
+
+// output of original string
+std::cout << cpp_string << " == " << cpp_string2 << " == " << j_string.get<std::string>() << '\n';
+// output of serialized value
+std::cout << j_string << " == " << serialized_string << std::endl;
+```
+
+[`.dump()`](https://nlohmann.github.io/json/api/basic_json/dump/) returns the originally stored string value.
+
+Note the library only supports UTF-8. When you store strings with different encodings in the library, calling [`dump()`](https://nlohmann.github.io/json/api/basic_json/dump/) may throw an exception unless `json::error_handler_t::replace` or `json::error_handler_t::ignore` are used as error handlers.
+
+#### To/from streams (e.g. files, string streams)
+
+You can also use streams to serialize and deserialize:
+
+```cpp
+// deserialize from standard input
+json j;
+std::cin >> j;
+
+// serialize to standard output
+std::cout << j;
+
+// the setw manipulator was overloaded to set the indentation for pretty printing
+std::cout << std::setw(4) << j << std::endl;
+```
+
+These operators work for any subclasses of `std::istream` or `std::ostream`. Here is the same example with files:
+
+```cpp
+// read a JSON file
+std::ifstream i("file.json");
+json j;
+i >> j;
+
+// write prettified JSON to another file
+std::ofstream o("pretty.json");
+o << std::setw(4) << j << std::endl;
+```
+
+Please note that setting the exception bit for `failbit` is inappropriate for this use case. It will result in program termination due to the `noexcept` specifier in use.
+
+#### Read from iterator range
+
+You can also parse JSON from an iterator range; that is, from any container accessible by iterators whose `value_type` is an integral type of 1, 2 or 4 bytes, which will be interpreted as UTF-8, UTF-16 and UTF-32 respectively. For instance, a `std::vector<std::uint8_t>`, or a `std::list<std::uint16_t>`:
+
+```cpp
+std::vector<std::uint8_t> v = {'t', 'r', 'u', 'e'};
+json j = json::parse(v.begin(), v.end());
+```
+
+You may leave the iterators for the range [begin, end):
+
+```cpp
+std::vector<std::uint8_t> v = {'t', 'r', 'u', 'e'};
+json j = json::parse(v);
+```
+
+#### Custom data source
+
+Since the parse function accepts arbitrary iterator ranges, you can provide your own data sources by implementing the `LegacyInputIterator` concept.
+
+```cpp
+struct MyContainer {
+  void advance();
+  const char& get_current();
+};
+
+struct MyIterator {
+    using difference_type = std::ptrdiff_t;
+    using value_type = char;
+    using pointer = const char*;
+    using reference = const char&;
+    using iterator_category = std::input_iterator_tag;
+
+    MyIterator& operator++() {
+        MyContainer.advance();
+        return *this;
+    }
+
+    bool operator!=(const MyIterator& rhs) const {
+        return rhs.target != target;
+    }
+
+    reference operator*() const {
+        return target.get_current();
+    }
+
+    MyContainer* target = nullptr;
+};
+
+MyIterator begin(MyContainer& tgt) {
+    return MyIterator{&tgt};
+}
+
+MyIterator end(const MyContainer&) {
+    return {};
+}
+
+void foo() {
+    MyContainer c;
+    json j = json::parse(c);
+}
+```
+
+#### SAX interface
+
+The library uses a SAX-like interface with the following functions:
+
+```cpp
+// called when null is parsed
+bool null();
+
+// called when a boolean is parsed; value is passed
+bool boolean(bool val);
+
+// called when a signed or unsigned integer number is parsed; value is passed
+bool number_integer(number_integer_t val);
+bool number_unsigned(number_unsigned_t val);
+
+// called when a floating-point number is parsed; value and original string is passed
+bool number_float(number_float_t val, const string_t& s);
+
+// called when a string is parsed; value is passed and can be safely moved away
+bool string(string_t& val);
+// called when a binary value is parsed; value is passed and can be safely moved away
+bool binary(binary_t& val);
+
+// called when an object or array begins or ends, resp. The number of elements is passed (or -1 if not known)
+bool start_object(std::size_t elements);
+bool end_object();
+bool start_array(std::size_t elements);
+bool end_array();
+// called when an object key is parsed; value is passed and can be safely moved away
+bool key(string_t& val);
+
+// called when a parse error occurs; byte position, the last token, and an exception is passed
+bool parse_error(std::size_t position, const std::string& last_token, const detail::exception& ex);
+```
+
+The return value of each function determines whether parsing should proceed.
+
+To implement your own SAX handler, proceed as follows:
+
+1. Implement the SAX interface in a class. You can use class `nlohmann::json_sax<json>` as base class, but you can also use any class where the functions described above are implemented and public.
+2. Create an object of your SAX interface class, e.g. `my_sax`.
+3. Call `bool json::sax_parse(input, &my_sax)`; where the first parameter can be any input like a string or an input stream and the second parameter is a pointer to your SAX interface.
+
+Note the `sax_parse` function only returns a `bool` indicating the result of the last executed SAX event. It does not return a  `json` value - it is up to you to decide what to do with the SAX events. Furthermore, no exceptions are thrown in case of a parse error - it is up to you what to do with the exception object passed to your `parse_error` implementation. Internally, the SAX interface is used for the DOM parser (class `json_sax_dom_parser`) as well as the acceptor (`json_sax_acceptor`), see file [`json_sax.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/input/json_sax.hpp).
+
+### STL-like access
+
+We designed the JSON class to behave just like an STL container. In fact, it satisfies the [**ReversibleContainer**](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer) requirement.
+
+```cpp
+// create an array using push_back
+json j;
+j.push_back("foo");
+j.push_back(1);
+j.push_back(true);
+
+// also use emplace_back
+j.emplace_back(1.78);
+
+// iterate the array
+for (json::iterator it = j.begin(); it != j.end(); ++it) {
+  std::cout << *it << '\n';
+}
+
+// range-based for
+for (auto& element : j) {
+  std::cout << element << '\n';
+}
+
+// getter/setter
+const auto tmp = j[0].get<std::string>();
+j[1] = 42;
+bool foo = j.at(2);
+
+// comparison
+j == "[\"foo\", 42, true]"_json;  // true
+
+// other stuff
+j.size();     // 3 entries
+j.empty();    // false
+j.type();     // json::value_t::array
+j.clear();    // the array is empty again
+
+// convenience type checkers
+j.is_null();
+j.is_boolean();
+j.is_number();
+j.is_object();
+j.is_array();
+j.is_string();
+
+// create an object
+json o;
+o["foo"] = 23;
+o["bar"] = false;
+o["baz"] = 3.141;
+
+// also use emplace
+o.emplace("weather", "sunny");
+
+// special iterator member functions for objects
+for (json::iterator it = o.begin(); it != o.end(); ++it) {
+  std::cout << it.key() << " : " << it.value() << "\n";
+}
+
+// the same code as range for
+for (auto& el : o.items()) {
+  std::cout << el.key() << " : " << el.value() << "\n";
+}
+
+// even easier with structured bindings (C++17)
+for (auto& [key, value] : o.items()) {
+  std::cout << key << " : " << value << "\n";
+}
+
+// find an entry
+if (o.contains("foo")) {
+  // there is an entry with key "foo"
+}
+
+// or via find and an iterator
+if (o.find("foo") != o.end()) {
+  // there is an entry with key "foo"
+}
+
+// or simpler using count()
+int foo_present = o.count("foo"); // 1
+int fob_present = o.count("fob"); // 0
+
+// delete an entry
+o.erase("foo");
+```
+
+
+### Conversion from STL containers
+
+Any sequence container (`std::array`, `std::vector`, `std::deque`, `std::forward_list`, `std::list`) whose values can be used to construct JSON values (e.g., integers, floating point numbers, Booleans, string types, or again STL containers described in this section) can be used to create a JSON array. The same holds for similar associative containers (`std::set`, `std::multiset`, `std::unordered_set`, `std::unordered_multiset`), but in these cases the order of the elements of the array depends on how the elements are ordered in the respective STL container.
+
+```cpp
+std::vector<int> c_vector {1, 2, 3, 4};
+json j_vec(c_vector);
+// [1, 2, 3, 4]
+
+std::deque<double> c_deque {1.2, 2.3, 3.4, 5.6};
+json j_deque(c_deque);
+// [1.2, 2.3, 3.4, 5.6]
+
+std::list<bool> c_list {true, true, false, true};
+json j_list(c_list);
+// [true, true, false, true]
+
+std::forward_list<int64_t> c_flist {12345678909876, 23456789098765, 34567890987654, 45678909876543};
+json j_flist(c_flist);
+// [12345678909876, 23456789098765, 34567890987654, 45678909876543]
+
+std::array<unsigned long, 4> c_array {{1, 2, 3, 4}};
+json j_array(c_array);
+// [1, 2, 3, 4]
+
+std::set<std::string> c_set {"one", "two", "three", "four", "one"};
+json j_set(c_set); // only one entry for "one" is used
+// ["four", "one", "three", "two"]
+
+std::unordered_set<std::string> c_uset {"one", "two", "three", "four", "one"};
+json j_uset(c_uset); // only one entry for "one" is used
+// maybe ["two", "three", "four", "one"]
+
+std::multiset<std::string> c_mset {"one", "two", "one", "four"};
+json j_mset(c_mset); // both entries for "one" are used
+// maybe ["one", "two", "one", "four"]
+
+std::unordered_multiset<std::string> c_umset {"one", "two", "one", "four"};
+json j_umset(c_umset); // both entries for "one" are used
+// maybe ["one", "two", "one", "four"]
+```
+
+Likewise, any associative key-value containers (`std::map`, `std::multimap`, `std::unordered_map`, `std::unordered_multimap`) whose keys can construct an `std::string` and whose values can be used to construct JSON values (see examples above) can be used to create a JSON object. Note that in case of multimaps only one key is used in the JSON object and the value depends on the internal order of the STL container.
+
+```cpp
+std::map<std::string, int> c_map { {"one", 1}, {"two", 2}, {"three", 3} };
+json j_map(c_map);
+// {"one": 1, "three": 3, "two": 2 }
+
+std::unordered_map<const char*, double> c_umap { {"one", 1.2}, {"two", 2.3}, {"three", 3.4} };
+json j_umap(c_umap);
+// {"one": 1.2, "two": 2.3, "three": 3.4}
+
+std::multimap<std::string, bool> c_mmap { {"one", true}, {"two", true}, {"three", false}, {"three", true} };
+json j_mmap(c_mmap); // only one entry for key "three" is used
+// maybe {"one": true, "two": true, "three": true}
+
+std::unordered_multimap<std::string, bool> c_ummap { {"one", true}, {"two", true}, {"three", false}, {"three", true} };
+json j_ummap(c_ummap); // only one entry for key "three" is used
+// maybe {"one": true, "two": true, "three": true}
+```
+
+### JSON Pointer and JSON Patch
+
+The library supports **JSON Pointer** ([RFC 6901](https://tools.ietf.org/html/rfc6901)) as alternative means to address structured values. On top of this, **JSON Patch** ([RFC 6902](https://tools.ietf.org/html/rfc6902)) allows to describe differences between two JSON values - effectively allowing patch and diff operations known from Unix.
+
+```cpp
+// a JSON value
+json j_original = R"({
+  "baz": ["one", "two", "three"],
+  "foo": "bar"
+})"_json;
+
+// access members with a JSON pointer (RFC 6901)
+j_original["/baz/1"_json_pointer];
+// "two"
+
+// a JSON patch (RFC 6902)
+json j_patch = R"([
+  { "op": "replace", "path": "/baz", "value": "boo" },
+  { "op": "add", "path": "/hello", "value": ["world"] },
+  { "op": "remove", "path": "/foo"}
+])"_json;
+
+// apply the patch
+json j_result = j_original.patch(j_patch);
+// {
+//    "baz": "boo",
+//    "hello": ["world"]
+// }
+
+// calculate a JSON patch from two JSON values
+json::diff(j_result, j_original);
+// [
+//   { "op":" replace", "path": "/baz", "value": ["one", "two", "three"] },
+//   { "op": "remove","path": "/hello" },
+//   { "op": "add", "path": "/foo", "value": "bar" }
+// ]
+```
+
+### JSON Merge Patch
+
+The library supports **JSON Merge Patch** ([RFC 7386](https://tools.ietf.org/html/rfc7386)) as a patch format. Instead of using JSON Pointer (see above) to specify values to be manipulated, it describes the changes using a syntax that closely mimics the document being modified.
+
+```cpp
+// a JSON value
+json j_document = R"({
+  "a": "b",
+  "c": {
+    "d": "e",
+    "f": "g"
+  }
+})"_json;
+
+// a patch
+json j_patch = R"({
+  "a":"z",
+  "c": {
+    "f": null
+  }
+})"_json;
+
+// apply the patch
+j_document.merge_patch(j_patch);
+// {
+//  "a": "z",
+//  "c": {
+//    "d": "e"
+//  }
+// }
+```
+
+### Implicit conversions
+
+Supported types can be implicitly converted to JSON values.
+
+It is recommended to **NOT USE** implicit conversions **FROM** a JSON value.
+You can find more details about this recommendation [here](https://www.github.com/nlohmann/json/issues/958).
+You can switch off implicit conversions by defining `JSON_USE_IMPLICIT_CONVERSIONS` to `0` before including the `json.hpp` header. When using CMake, you can also achieve this by setting the option `JSON_ImplicitConversions` to `OFF`.
+
+```cpp
+// strings
+std::string s1 = "Hello, world!";
+json js = s1;
+auto s2 = js.get<std::string>();
+// NOT RECOMMENDED
+std::string s3 = js;
+std::string s4;
+s4 = js;
+
+// Booleans
+bool b1 = true;
+json jb = b1;
+auto b2 = jb.get<bool>();
+// NOT RECOMMENDED
+bool b3 = jb;
+bool b4;
+b4 = jb;
+
+// numbers
+int i = 42;
+json jn = i;
+auto f = jn.get<double>();
+// NOT RECOMMENDED
+double f2 = jb;
+double f3;
+f3 = jb;
+
+// etc.
+```
+
+Note that `char` types are not automatically converted to JSON strings, but to integer numbers. A conversion to a string must be specified explicitly:
+
+```cpp
+char ch = 'A';                       // ASCII value 65
+json j_default = ch;                 // stores integer number 65
+json j_string = std::string(1, ch);  // stores string "A"
+```
+
+### Arbitrary types conversions
+
+Every type can be serialized in JSON, not just STL containers and scalar types. Usually, you would do something along those lines:
+
+```cpp
+namespace ns {
+    // a simple struct to model a person
+    struct person {
+        std::string name;
+        std::string address;
+        int age;
+    };
+}
+
+ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60};
+
+// convert to JSON: copy each value into the JSON object
+json j;
+j["name"] = p.name;
+j["address"] = p.address;
+j["age"] = p.age;
+
+// ...
+
+// convert from JSON: copy each value from the JSON object
+ns::person p {
+    j["name"].get<std::string>(),
+    j["address"].get<std::string>(),
+    j["age"].get<int>()
+};
+```
+
+It works, but that's quite a lot of boilerplate... Fortunately, there's a better way:
+
+```cpp
+// create a person
+ns::person p {"Ned Flanders", "744 Evergreen Terrace", 60};
+
+// conversion: person -> json
+json j = p;
+
+std::cout << j << std::endl;
+// {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"}
+
+// conversion: json -> person
+auto p2 = j.get<ns::person>();
+
+// that's it
+assert(p == p2);
+```
+
+#### Basic usage
+
+To make this work with one of your types, you only need to provide two functions:
+
+```cpp
+using nlohmann::json;
+
+namespace ns {
+    void to_json(json& j, const person& p) {
+        j = json{{"name", p.name}, {"address", p.address}, {"age", p.age}};
+    }
+
+    void from_json(const json& j, person& p) {
+        j.at("name").get_to(p.name);
+        j.at("address").get_to(p.address);
+        j.at("age").get_to(p.age);
+    }
+} // namespace ns
+```
+
+That's all! When calling the `json` constructor with your type, your custom `to_json` method will be automatically called.
+Likewise, when calling `get<your_type>()` or `get_to(your_type&)`, the `from_json` method will be called.
+
+Some important things:
+
+* Those methods **MUST** be in your type's namespace (which can be the global namespace), or the library will not be able to locate them (in this example, they are in namespace `ns`, where `person` is defined).
+* Those methods **MUST** be available (e.g., proper headers must be included) everywhere you use these conversions. Look at [issue 1108](https://github.com/nlohmann/json/issues/1108) for errors that may occur otherwise.
+* When using `get<your_type>()`, `your_type` **MUST** be [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). (There is a way to bypass this requirement described later.)
+* In function `from_json`, use function [`at()`](https://nlohmann.github.io/json/api/basic_json/at/) to access the object values rather than `operator[]`. In case a key does not exist, `at` throws an exception that you can handle, whereas `operator[]` exhibits undefined behavior.
+* You do not need to add serializers or deserializers for STL types like `std::vector`: the library already implements these.
+
+#### Simplify your life with macros
+
+If you just want to serialize/deserialize some structs, the `to_json`/`from_json` functions can be a lot of boilerplate.
+
+There are two macros to make your life easier as long as you (1) want to use a JSON object as serialization and (2) want to use the member variable names as object keys in that object:
+
+- `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(name, member1, member2, ...)` is to be defined inside of the namespace of the class/struct to create code for.
+- `NLOHMANN_DEFINE_TYPE_INTRUSIVE(name, member1, member2, ...)` is to be defined inside of the class/struct to create code for. This macro can also access private members.
+
+In both macros, the first parameter is the name of the class/struct, and all remaining parameters name the members.
+
+##### Examples
+
+The `to_json`/`from_json` functions for the `person` struct above can be created with:
+
+```cpp
+namespace ns {
+    NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person, name, address, age)
+}
+```
+
+Here is an example with private members, where `NLOHMANN_DEFINE_TYPE_INTRUSIVE` is needed:
+
+```cpp
+namespace ns {
+    class address {
+      private:
+        std::string street;
+        int housenumber;
+        int postcode;
+
+      public:
+        NLOHMANN_DEFINE_TYPE_INTRUSIVE(address, street, housenumber, postcode)
+    };
+}
+```
+
+#### How do I convert third-party types?
+
+This requires a bit more advanced technique. But first, let's see how this conversion mechanism works:
+
+The library uses **JSON Serializers** to convert types to json.
+The default serializer for `nlohmann::json` is `nlohmann::adl_serializer` (ADL means [Argument-Dependent Lookup](https://en.cppreference.com/w/cpp/language/adl)).
+
+It is implemented like this (simplified):
+
+```cpp
+template <typename T>
+struct adl_serializer {
+    static void to_json(json& j, const T& value) {
+        // calls the "to_json" method in T's namespace
+    }
+
+    static void from_json(const json& j, T& value) {
+        // same thing, but with the "from_json" method
+    }
+};
+```
+
+This serializer works fine when you have control over the type's namespace. However, what about `boost::optional` or `std::filesystem::path` (C++17)? Hijacking the `boost` namespace is pretty bad, and it's illegal to add something other than template specializations to `std`...
+
+To solve this, you need to add a specialization of `adl_serializer` to the `nlohmann` namespace, here's an example:
+
+```cpp
+// partial specialization (full specialization works too)
+namespace nlohmann {
+    template <typename T>
+    struct adl_serializer<boost::optional<T>> {
+        static void to_json(json& j, const boost::optional<T>& opt) {
+            if (opt == boost::none) {
+                j = nullptr;
+            } else {
+              j = *opt; // this will call adl_serializer<T>::to_json which will
+                        // find the free function to_json in T's namespace!
+            }
+        }
+
+        static void from_json(const json& j, boost::optional<T>& opt) {
+            if (j.is_null()) {
+                opt = boost::none;
+            } else {
+                opt = j.get<T>(); // same as above, but with
+                                  // adl_serializer<T>::from_json
+            }
+        }
+    };
+}
+```
+
+#### How can I use `get()` for non-default constructible/non-copyable types?
+
+There is a way, if your type is [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible). You will need to specialize the `adl_serializer` as well, but with a special `from_json` overload:
+
+```cpp
+struct move_only_type {
+    move_only_type() = delete;
+    move_only_type(int ii): i(ii) {}
+    move_only_type(const move_only_type&) = delete;
+    move_only_type(move_only_type&&) = default;
+
+    int i;
+};
+
+namespace nlohmann {
+    template <>
+    struct adl_serializer<move_only_type> {
+        // note: the return type is no longer 'void', and the method only takes
+        // one argument
+        static move_only_type from_json(const json& j) {
+            return {j.get<int>()};
+        }
+
+        // Here's the catch! You must provide a to_json method! Otherwise you
+        // will not be able to convert move_only_type to json, since you fully
+        // specialized adl_serializer on that type
+        static void to_json(json& j, move_only_type t) {
+            j = t.i;
+        }
+    };
+}
+```
+
+#### Can I write my own serializer? (Advanced use)
+
+Yes. You might want to take a look at [`unit-udt.cpp`](https://github.com/nlohmann/json/blob/develop/test/src/unit-udt.cpp) in the test suite, to see a few examples.
+
+If you write your own serializer, you'll need to do a few things:
+
+- use a different `basic_json` alias than `nlohmann::json` (the last template parameter of `basic_json` is the `JSONSerializer`)
+- use your `basic_json` alias (or a template parameter) in all your `to_json`/`from_json` methods
+- use `nlohmann::to_json` and `nlohmann::from_json` when you need ADL
+
+Here is an example, without simplifications, that only accepts types with a size <= 32, and uses ADL.
+
+```cpp
+// You should use void as a second template argument
+// if you don't need compile-time checks on T
+template<typename T, typename SFINAE = typename std::enable_if<sizeof(T) <= 32>::type>
+struct less_than_32_serializer {
+    template <typename BasicJsonType>
+    static void to_json(BasicJsonType& j, T value) {
+        // we want to use ADL, and call the correct to_json overload
+        using nlohmann::to_json; // this method is called by adl_serializer,
+                                 // this is where the magic happens
+        to_json(j, value);
+    }
+
+    template <typename BasicJsonType>
+    static void from_json(const BasicJsonType& j, T& value) {
+        // same thing here
+        using nlohmann::from_json;
+        from_json(j, value);
+    }
+};
+```
+
+Be **very** careful when reimplementing your serializer, you can stack overflow if you don't pay attention:
+
+```cpp
+template <typename T, void>
+struct bad_serializer
+{
+    template <typename BasicJsonType>
+    static void to_json(BasicJsonType& j, const T& value) {
+      // this calls BasicJsonType::json_serializer<T>::to_json(j, value);
+      // if BasicJsonType::json_serializer == bad_serializer ... oops!
+      j = value;
+    }
+
+    template <typename BasicJsonType>
+    static void to_json(const BasicJsonType& j, T& value) {
+      // this calls BasicJsonType::json_serializer<T>::from_json(j, value);
+      // if BasicJsonType::json_serializer == bad_serializer ... oops!
+      value = j.template get<T>(); // oops!
+    }
+};
+```
+
+### Specializing enum conversion
+
+By default, enum values are serialized to JSON as integers. In some cases this could result in undesired behavior. If an enum is modified or re-ordered after data has been serialized to JSON, the later de-serialized JSON data may be undefined or a different enum value than was originally intended.
+
+It is possible to more precisely specify how a given enum is mapped to and from JSON as shown below:
+
+```cpp
+// example enum type declaration
+enum TaskState {
+    TS_STOPPED,
+    TS_RUNNING,
+    TS_COMPLETED,
+    TS_INVALID=-1,
+};
+
+// map TaskState values to JSON as strings
+NLOHMANN_JSON_SERIALIZE_ENUM( TaskState, {
+    {TS_INVALID, nullptr},
+    {TS_STOPPED, "stopped"},
+    {TS_RUNNING, "running"},
+    {TS_COMPLETED, "completed"},
+})
+```
+
+The `NLOHMANN_JSON_SERIALIZE_ENUM()` macro declares a set of `to_json()` / `from_json()` functions for type `TaskState` while avoiding repetition and boilerplate serialization code.
+
+**Usage:**
+
+```cpp
+// enum to JSON as string
+json j = TS_STOPPED;
+assert(j == "stopped");
+
+// json string to enum
+json j3 = "running";
+assert(j3.get<TaskState>() == TS_RUNNING);
+
+// undefined json value to enum (where the first map entry above is the default)
+json jPi = 3.14;
+assert(jPi.get<TaskState>() == TS_INVALID );
+```
+
+Just as in [Arbitrary Type Conversions](#arbitrary-types-conversions) above,
+- `NLOHMANN_JSON_SERIALIZE_ENUM()` MUST be declared in your enum type's namespace (which can be the global namespace), or the library will not be able to locate it and it will default to integer serialization.
+- It MUST be available (e.g., proper headers must be included) everywhere you use the conversions.
+
+Other Important points:
+- When using `get<ENUM_TYPE>()`, undefined JSON values will default to the first pair specified in your map. Select this default pair carefully.
+- If an enum or JSON value is specified more than once in your map, the first matching occurrence from the top of the map will be returned when converting to or from JSON.
+
+### Binary formats (BSON, CBOR, MessagePack, and UBJSON)
+
+Though JSON is a ubiquitous data format, it is not a very compact format suitable for data exchange, for instance over a network. Hence, the library supports [BSON](http://bsonspec.org) (Binary JSON), [CBOR](https://cbor.io) (Concise Binary Object Representation), [MessagePack](https://msgpack.org), and [UBJSON](http://ubjson.org) (Universal Binary JSON Specification) to efficiently encode JSON values to byte vectors and to decode such vectors.
+
+```cpp
+// create a JSON value
+json j = R"({"compact": true, "schema": 0})"_json;
+
+// serialize to BSON
+std::vector<std::uint8_t> v_bson = json::to_bson(j);
+
+// 0x1B, 0x00, 0x00, 0x00, 0x08, 0x63, 0x6F, 0x6D, 0x70, 0x61, 0x63, 0x74, 0x00, 0x01, 0x10, 0x73, 0x63, 0x68, 0x65, 0x6D, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+
+// roundtrip
+json j_from_bson = json::from_bson(v_bson);
+
+// serialize to CBOR
+std::vector<std::uint8_t> v_cbor = json::to_cbor(j);
+
+// 0xA2, 0x67, 0x63, 0x6F, 0x6D, 0x70, 0x61, 0x63, 0x74, 0xF5, 0x66, 0x73, 0x63, 0x68, 0x65, 0x6D, 0x61, 0x00
+
+// roundtrip
+json j_from_cbor = json::from_cbor(v_cbor);
+
+// serialize to MessagePack
+std::vector<std::uint8_t> v_msgpack = json::to_msgpack(j);
+
+// 0x82, 0xA7, 0x63, 0x6F, 0x6D, 0x70, 0x61, 0x63, 0x74, 0xC3, 0xA6, 0x73, 0x63, 0x68, 0x65, 0x6D, 0x61, 0x00
+
+// roundtrip
+json j_from_msgpack = json::from_msgpack(v_msgpack);
+
+// serialize to UBJSON
+std::vector<std::uint8_t> v_ubjson = json::to_ubjson(j);
+
+// 0x7B, 0x69, 0x07, 0x63, 0x6F, 0x6D, 0x70, 0x61, 0x63, 0x74, 0x54, 0x69, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6D, 0x61, 0x69, 0x00, 0x7D
+
+// roundtrip
+json j_from_ubjson = json::from_ubjson(v_ubjson);
+```
+
+The library also supports binary types from BSON, CBOR (byte strings), and MessagePack (bin, ext, fixext). They are stored by default as `std::vector<std::uint8_t>` to be processed outside of the library.
+
+```cpp
+// CBOR byte string with payload 0xCAFE
+std::vector<std::uint8_t> v = {0x42, 0xCA, 0xFE};
+
+// read value
+json j = json::from_cbor(v);
+
+// the JSON value has type binary
+j.is_binary(); // true
+
+// get reference to stored binary value
+auto& binary = j.get_binary();
+
+// the binary value has no subtype (CBOR has no binary subtypes)
+binary.has_subtype(); // false
+
+// access std::vector<std::uint8_t> member functions
+binary.size(); // 2
+binary[0]; // 0xCA
+binary[1]; // 0xFE
+
+// set subtype to 0x10
+binary.set_subtype(0x10);
+
+// serialize to MessagePack
+auto cbor = json::to_msgpack(j); // 0xD5 (fixext2), 0x10, 0xCA, 0xFE
+```
+
+
+## Supported compilers
+
+Though it's 2020 already, the support for C++11 is still a bit sparse. Currently, the following compilers are known to work:
+
+- GCC 4.8 - 10.1 (and possibly later)
+- Clang 3.4 - 10.0 (and possibly later)
+- Apple Clang 9.1 - 12.0 (and possibly later)
+- Intel C++ Compiler 17.0.2 (and possibly later)
+- Microsoft Visual C++ 2015 / Build Tools 14.0.25123.0 (and possibly later)
+- Microsoft Visual C++ 2017 / Build Tools 15.5.180.51428 (and possibly later)
+- Microsoft Visual C++ 2019 / Build Tools 16.3.1+1def00d3d (and possibly later)
+
+I would be happy to learn about other compilers/versions.
+
+Please note:
+
+- GCC 4.8 has a bug [57824](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57824)): multiline raw strings cannot be the arguments to macros. Don't use multiline raw strings directly in macros with this compiler.
+- Android defaults to using very old compilers and C++ libraries. To fix this, add the following to your `Application.mk`. This will switch to the LLVM C++ library, the Clang compiler, and enable C++11 and other features disabled by default.
+
+    ```
+    APP_STL := c++_shared
+    NDK_TOOLCHAIN_VERSION := clang3.6
+    APP_CPPFLAGS += -frtti -fexceptions
+    ```
+
+    The code compiles successfully with [Android NDK](https://developer.android.com/ndk/index.html?hl=ml), Revision 9 - 11 (and possibly later) and [CrystaX's Android NDK](https://www.crystax.net/en/android/ndk) version 10.
+
+- For GCC running on MinGW or Android SDK, the error `'to_string' is not a member of 'std'` (or similarly, for `strtod` or `strtof`) may occur. Note this is not an issue with the code,  but rather with the compiler itself. On Android, see above to build with a newer environment.  For MinGW, please refer to [this site](https://tehsausage.com/mingw-to-string) and [this discussion](https://github.com/nlohmann/json/issues/136) for information on how to fix this bug. For Android NDK using `APP_STL := gnustl_static`, please refer to [this discussion](https://github.com/nlohmann/json/issues/219).
+
+- Unsupported versions of GCC and Clang are rejected by `#error` directives. This can be switched off by defining `JSON_SKIP_UNSUPPORTED_COMPILER_CHECK`. Note that you can expect no support in this case.
+
+The following compilers are currently used in continuous integration at [Travis](https://travis-ci.org/nlohmann/json), [AppVeyor](https://ci.appveyor.com/project/nlohmann/json), [GitHub Actions](https://github.com/nlohmann/json/actions), and [CircleCI](https://circleci.com/gh/nlohmann/json):
+
+| Compiler                                                        | Operating System   | CI Provider    |
+|-----------------------------------------------------------------|--------------------|----------------|
+| Apple Clang 9.1.0 (clang-902.0.39.1); Xcode 9.3                 | macOS 10.13.3      | Travis         |
+| Apple Clang 9.1.0 (clang-902.0.39.2); Xcode 9.4.1               | macOS 10.13.6      | Travis         |
+| Apple Clang 10.0.0 (clang-1000.11.45.2); Xcode 10.0             | macOS 10.13.6      | Travis         |
+| Apple Clang 10.0.0 (clang-1000.11.45.5); Xcode 10.1             | macOS 10.13.6      | Travis         |
+| Apple Clang 10.0.1 (clang-1001.0.46.4); Xcode 10.2.1            | macOS 10.14.4      | Travis         |
+| Apple Clang 11.0.0 (clang-1100.0.33.12); Xcode 11.2.1           | macOS 10.14.6      | Travis         |
+| Apple Clang 11.0.3 (clang-1103.0.32.59); Xcode 11.4.1           | macOS 10.15.4      | GitHub Actions |
+| Apple Clang 12.0.0 (clang-1200.0.22.7); Xcode 11.4.1            | macOS 10.15.5      | Travis         |
+| Clang 3.5.0 (3.5.0-4ubuntu2~trusty2)                            | Ubuntu 14.04.5 LTS | Travis         |
+| Clang 3.6.2 (3.6.2-svn240577-1~exp1)                            | Ubuntu 14.04.5 LTS | Travis         |
+| Clang 3.7.1 (3.7.1-svn253571-1~exp1)                            | Ubuntu 14.04.5 LTS | Travis         |
+| Clang 3.8.0 (3.8.0-2ubuntu3~trusty5)                            | Ubuntu 14.04.5 LTS | Travis         |
+| Clang 3.9.1 (3.9.1-4ubuntu3~14.04.3)                            | Ubuntu 14.04.5 LTS | Travis         |
+| Clang 4.0.1 (4.0.1-svn305264-1~exp1)                            | Ubuntu 14.04.5 LTS | Travis         |
+| Clang 5.0.2 (version 5.0.2-svn328729-1~exp1~20180509123505.100) | Ubuntu 14.04.5 LTS | Travis         |
+| Clang 6.0.1 (6.0.1-svn334776-1~exp1~20190309042707.121)         | Ubuntu 14.04.5 LTS | Travis         |
+| Clang 7.1.0 (7.1.0-svn353565-1~exp1~20190419134007.64)          | Ubuntu 14.04.5 LTS | Travis         |
+| Clang 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)                       | Ubuntu 18.04.4 LTS | Travis         |
+| Clang 9.0.0 (x86_64-pc-windows-msvc)                            | Windows-10.0.17763 | GitHub Actions |
+| Clang 10.0.0 (x86_64-pc-windows-msvc)                           | Windows-10.0.17763 | GitHub Actions |
+| GCC 4.8.5 (Ubuntu 4.8.5-4ubuntu8~14.04.2)                       | Ubuntu 14.04.5 LTS | Travis         |
+| GCC 4.9.4 (Ubuntu 4.9.4-2ubuntu1~14.04.1)                       | Ubuntu 14.04.5 LTS | Travis         |
+| GCC 5.5.0 (Ubuntu 5.5.0-12ubuntu1~14.04)                        | Ubuntu 14.04.5 LTS | Travis         |
+| GCC 6.3.0 (Debian 6.3.0-18+deb9u1)                              | Debian 9           | Circle CI      |
+| GCC 6.5.0 (Ubuntu 6.5.0-2ubuntu1~14.04.1)                       | Ubuntu 14.04.5 LTS | Travis         |
+| GCC 7.3.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project)   | Windows-6.3.9600   | AppVeyor       |
+| GCC 7.5.0 (Ubuntu 7.5.0-3ubuntu1~14.04.1)                       | Ubuntu 14.04.5 LTS | Travis         |
+| GCC 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)                         | Ubuntu 18.04.4 LTS | GitHub Actions |
+| GCC 8.4.0 (Ubuntu 8.4.0-1ubuntu1~14.04)                         | Ubuntu 14.04.5 LTS | Travis         |
+| GCC 9.3.0 (Ubuntu 9.3.0-11ubuntu0~14.04)                        | Ubuntu 14.04.5 LTS | Travis         |
+| GCC 10.1.0 (Arch Linux latest)                                  | Arch Linux         | Circle CI      |
+| MSVC 19.0.24241.7 (Build Engine version 14.0.25420.1)           | Windows-6.3.9600   | AppVeyor       |
+| MSVC 19.16.27035.0 (15.9.21+g9802d43bc3 for .NET Framework)     | Windows-10.0.14393 | AppVeyor       |
+| MSVC 19.25.28614.0 (Build Engine version 16.5.0+d4cbfca49 for .NET Framework) | Windows-10.0.17763  | AppVeyor       |
+| MSVC 19.25.28614.0 (Build Engine version 16.5.0+d4cbfca49 for .NET Framework) | Windows-10.0.17763  | GitHub Actions |
+| MSVC 19.25.28614.0 (Build Engine version 16.5.0+d4cbfca49 for .NET Framework) with ClangCL 10.0.0 | Windows-10.0.17763  | GitHub Actions |
+
+## License
+
+<img align="right" src="http://opensource.org/trademarks/opensource/OSI-Approved-License-100x137.png">
+
+The class is licensed under the [MIT License](http://opensource.org/licenses/MIT):
+
+Copyright &copy; 2013-2019 [Niels Lohmann](http://nlohmann.me)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+* * *
+
+The class contains the UTF-8 Decoder from Bjoern Hoehrmann which is licensed under the [MIT License](http://opensource.org/licenses/MIT) (see above). Copyright &copy; 2008-2009 [Björn Hoehrmann](https://bjoern.hoehrmann.de/) <bjoern@hoehrmann.de>
+
+The class contains a slightly modified version of the Grisu2 algorithm from Florian Loitsch which is licensed under the [MIT License](http://opensource.org/licenses/MIT) (see above). Copyright &copy; 2009 [Florian Loitsch](https://florian.loitsch.com/)
+
+The class contains a copy of [Hedley](https://nemequ.github.io/hedley/) from Evan Nemerson which is licensed as [CC0-1.0](https://creativecommons.org/publicdomain/zero/1.0/).
+
+## Contact
+
+If you have questions regarding the library, I would like to invite you to [open an issue at GitHub](https://github.com/nlohmann/json/issues/new/choose). Please describe your request, problem, or question as detailed as possible, and also mention the version of the library you are using as well as the version of your compiler and operating system. Opening an issue at GitHub allows other users and contributors to this library to collaborate. For instance, I have little experience with MSVC, and most issues in this regard have been solved by a growing community. If you have a look at the [closed issues](https://github.com/nlohmann/json/issues?q=is%3Aissue+is%3Aclosed), you will see that we react quite timely in most cases.
+
+Only if your request would contain confidential information, please [send me an email](mailto:mail@nlohmann.me). For encrypted messages, please use [this key](https://keybase.io/nlohmann/pgp_keys.asc).
+
+## Security
+
+[Commits by Niels Lohmann](https://github.com/nlohmann/json/commits) and [releases](https://github.com/nlohmann/json/releases) are signed with this [PGP Key](https://keybase.io/nlohmann/pgp_keys.asc?fingerprint=797167ae41c0a6d9232e48457f3cea63ae251b69).
+
+## Thanks
+
+I deeply appreciate the help of the following people.
+
+<img src="https://raw.githubusercontent.com/nlohmann/json/develop/doc/avatars.png" align="right">
+
+- [Teemperor](https://github.com/Teemperor) implemented CMake support and lcov integration, realized escape and Unicode handling in the string parser, and fixed the JSON serialization.
+- [elliotgoodrich](https://github.com/elliotgoodrich) fixed an issue with double deletion in the iterator classes.
+- [kirkshoop](https://github.com/kirkshoop) made the iterators of the class composable to other libraries.
+- [wancw](https://github.com/wanwc) fixed a bug that hindered the class to compile with Clang.
+- Tomas Åblad found a bug in the iterator implementation.
+- [Joshua C. Randall](https://github.com/jrandall) fixed a bug in the floating-point serialization.
+- [Aaron Burghardt](https://github.com/aburgh) implemented code to parse streams incrementally. Furthermore, he greatly improved the parser class by allowing the definition of a filter function to discard undesired elements while parsing.
+- [Daniel Kopeček](https://github.com/dkopecek) fixed a bug in the compilation with GCC 5.0.
+- [Florian Weber](https://github.com/Florianjw) fixed a bug in and improved the performance of the comparison operators.
+- [Eric Cornelius](https://github.com/EricMCornelius) pointed out a bug in the handling with NaN and infinity values. He also improved the performance of the string escaping.
+- [易思龙](https://github.com/likebeta) implemented a conversion from anonymous enums.
+- [kepkin](https://github.com/kepkin) patiently pushed forward the support for Microsoft Visual studio.
+- [gregmarr](https://github.com/gregmarr) simplified the implementation of reverse iterators and helped with numerous hints and improvements. In particular, he pushed forward the implementation of user-defined types.
+- [Caio Luppi](https://github.com/caiovlp) fixed a bug in the Unicode handling.
+- [dariomt](https://github.com/dariomt) fixed some typos in the examples.
+- [Daniel Frey](https://github.com/d-frey) cleaned up some pointers and implemented exception-safe memory allocation.
+- [Colin Hirsch](https://github.com/ColinH) took care of a small namespace issue.
+- [Huu Nguyen](https://github.com/whoshuu) correct a variable name in the documentation.
+- [Silverweed](https://github.com/silverweed) overloaded `parse()` to accept an rvalue reference.
+- [dariomt](https://github.com/dariomt) fixed a subtlety in MSVC type support and implemented the `get_ref()` function to get a reference to stored values.
+- [ZahlGraf](https://github.com/ZahlGraf) added a workaround that allows compilation using Android NDK.
+- [whackashoe](https://github.com/whackashoe) replaced a function that was marked as unsafe by Visual Studio.
+- [406345](https://github.com/406345) fixed two small warnings.
+- [Glen Fernandes](https://github.com/glenfe) noted a potential portability problem in the `has_mapped_type` function.
+- [Corbin Hughes](https://github.com/nibroc) fixed some typos in the contribution guidelines.
+- [twelsby](https://github.com/twelsby) fixed the array subscript operator, an issue that failed the MSVC build, and floating-point parsing/dumping. He further added support for unsigned integer numbers and implemented better roundtrip support for parsed numbers.
+- [Volker Diels-Grabsch](https://github.com/vog) fixed a link in the README file.
+- [msm-](https://github.com/msm-) added support for American Fuzzy Lop.
+- [Annihil](https://github.com/Annihil) fixed an example in the README file.
+- [Themercee](https://github.com/Themercee) noted a wrong URL in the README file.
+- [Lv Zheng](https://github.com/lv-zheng) fixed a namespace issue with `int64_t` and `uint64_t`.
+- [abc100m](https://github.com/abc100m) analyzed the issues with GCC 4.8 and proposed a [partial solution](https://github.com/nlohmann/json/pull/212).
+- [zewt](https://github.com/zewt) added useful notes to the README file about Android.
+- [Róbert Márki](https://github.com/robertmrk) added a fix to use move iterators and improved the integration via CMake.
+- [Chris Kitching](https://github.com/ChrisKitching) cleaned up the CMake files.
+- [Tom Needham](https://github.com/06needhamt) fixed a subtle bug with MSVC 2015 which was also proposed by [Michael K.](https://github.com/Epidal).
+- [Mário Feroldi](https://github.com/thelostt) fixed a small typo.
+- [duncanwerner](https://github.com/duncanwerner) found a really embarrassing performance regression in the 2.0.0 release.
+- [Damien](https://github.com/dtoma) fixed one of the last conversion warnings.
+- [Thomas Braun](https://github.com/t-b) fixed a warning in a test case and adjusted MSVC calls in the CI.
+- [Théo DELRIEU](https://github.com/theodelrieu) patiently and constructively oversaw the long way toward [iterator-range parsing](https://github.com/nlohmann/json/issues/290). He also implemented the magic behind the serialization/deserialization of user-defined types and split the single header file into smaller chunks.
+- [Stefan](https://github.com/5tefan) fixed a minor issue in the documentation.
+- [Vasil Dimov](https://github.com/vasild) fixed the documentation regarding conversions from `std::multiset`.
+- [ChristophJud](https://github.com/ChristophJud) overworked the CMake files to ease project inclusion.
+- [Vladimir Petrigo](https://github.com/vpetrigo) made a SFINAE hack more readable and added Visual Studio 17 to the build matrix.
+- [Denis Andrejew](https://github.com/seeekr) fixed a grammar issue in the README file.
+- [Pierre-Antoine Lacaze](https://github.com/palacaze) found a subtle bug in the `dump()` function.
+- [TurpentineDistillery](https://github.com/TurpentineDistillery) pointed to [`std::locale::classic()`](https://en.cppreference.com/w/cpp/locale/locale/classic) to avoid too much locale joggling, found some nice performance improvements in the parser, improved the benchmarking code, and realized locale-independent number parsing and printing.
+- [cgzones](https://github.com/cgzones) had an idea how to fix the Coverity scan.
+- [Jared Grubb](https://github.com/jaredgrubb) silenced a nasty documentation warning.
+- [Yixin Zhang](https://github.com/qwename) fixed an integer overflow check.
+- [Bosswestfalen](https://github.com/Bosswestfalen) merged two iterator classes into a smaller one.
+- [Daniel599](https://github.com/Daniel599) helped to get Travis execute the tests with Clang's sanitizers.
+- [Jonathan Lee](https://github.com/vjon) fixed an example in the README file.
+- [gnzlbg](https://github.com/gnzlbg) supported the implementation of user-defined types.
+- [Alexej Harm](https://github.com/qis) helped to get the user-defined types working with Visual Studio.
+- [Jared Grubb](https://github.com/jaredgrubb) supported the implementation of user-defined types.
+- [EnricoBilla](https://github.com/EnricoBilla) noted a typo in an example.
+- [Martin Hořeňovský](https://github.com/horenmar) found a way for a 2x speedup for the compilation time of the test suite.
+- [ukhegg](https://github.com/ukhegg) found proposed an improvement for the examples section.
+- [rswanson-ihi](https://github.com/rswanson-ihi) noted a typo in the README.
+- [Mihai Stan](https://github.com/stanmihai4) fixed a bug in the comparison with `nullptr`s.
+- [Tushar Maheshwari](https://github.com/tusharpm) added [cotire](https://github.com/sakra/cotire) support to speed up the compilation.
+- [TedLyngmo](https://github.com/TedLyngmo) noted a typo in the README, removed unnecessary bit arithmetic, and fixed some `-Weffc++` warnings.
+- [Krzysztof Woś](https://github.com/krzysztofwos) made exceptions more visible.
+- [ftillier](https://github.com/ftillier) fixed a compiler warning.
+- [tinloaf](https://github.com/tinloaf) made sure all pushed warnings are properly popped.
+- [Fytch](https://github.com/Fytch) found a bug in the documentation.
+- [Jay Sistar](https://github.com/Type1J) implemented a Meson build description.
+- [Henry Lee](https://github.com/HenryRLee) fixed a warning in ICC and improved the iterator implementation.
+- [Vincent Thiery](https://github.com/vthiery) maintains a package for the Conan package manager.
+- [Steffen](https://github.com/koemeet) fixed a potential issue with MSVC and `std::min`.
+- [Mike Tzou](https://github.com/Chocobo1) fixed some typos.
+- [amrcode](https://github.com/amrcode) noted a misleading documentation about comparison of floats.
+- [Oleg Endo](https://github.com/olegendo) reduced the memory consumption by replacing `<iostream>` with `<iosfwd>`.
+- [dan-42](https://github.com/dan-42) cleaned up the CMake files to simplify including/reusing of the library.
+- [Nikita Ofitserov](https://github.com/himikof) allowed for moving values from initializer lists.
+- [Greg Hurrell](https://github.com/wincent) fixed a typo.
+- [Dmitry Kukovinets](https://github.com/DmitryKuk) fixed a typo.
+- [kbthomp1](https://github.com/kbthomp1) fixed an issue related to the Intel OSX compiler.
+- [Markus Werle](https://github.com/daixtrose) fixed a typo.
+- [WebProdPP](https://github.com/WebProdPP) fixed a subtle error in a precondition check.
+- [Alex](https://github.com/leha-bot) noted an error in a code sample.
+- [Tom de Geus](https://github.com/tdegeus) reported some warnings with ICC and helped fixing them.
+- [Perry Kundert](https://github.com/pjkundert) simplified reading from input streams.
+- [Sonu Lohani](https://github.com/sonulohani) fixed a small compilation error.
+- [Jamie Seward](https://github.com/jseward) fixed all MSVC warnings.
+- [Nate Vargas](https://github.com/eld00d) added a Doxygen tag file.
+- [pvleuven](https://github.com/pvleuven) helped fixing a warning in ICC.
+- [Pavel](https://github.com/crea7or) helped fixing some warnings in MSVC.
+- [Jamie Seward](https://github.com/jseward) avoided unnecessary string copies in `find()` and `count()`.
+- [Mitja](https://github.com/Itja) fixed some typos.
+- [Jorrit Wronski](https://github.com/jowr) updated the Hunter package links.
+- [Matthias Möller](https://github.com/TinyTinni) added a `.natvis` for the MSVC debug view.
+- [bogemic](https://github.com/bogemic) fixed some C++17 deprecation warnings.
+- [Eren Okka](https://github.com/erengy) fixed some MSVC warnings.
+- [abolz](https://github.com/abolz) integrated the Grisu2 algorithm for proper floating-point formatting, allowing more roundtrip checks to succeed.
+- [Vadim Evard](https://github.com/Pipeliner) fixed a Markdown issue in the README.
+- [zerodefect](https://github.com/zerodefect) fixed a compiler warning.
+- [Kert](https://github.com/kaidokert) allowed to template the string type in the serialization and added the possibility to override the exceptional behavior.
+- [mark-99](https://github.com/mark-99) helped fixing an ICC error.
+- [Patrik Huber](https://github.com/patrikhuber) fixed links in the README file.
+- [johnfb](https://github.com/johnfb) found a bug in the implementation of CBOR's indefinite length strings.
+- [Paul Fultz II](https://github.com/pfultz2) added a note on the cget package manager.
+- [Wilson Lin](https://github.com/wla80) made the integration section of the README more concise.
+- [RalfBielig](https://github.com/ralfbielig) detected and fixed a memory leak in the parser callback.
+- [agrianius](https://github.com/agrianius) allowed to dump JSON to an alternative string type.
+- [Kevin Tonon](https://github.com/ktonon) overworked the C++11 compiler checks in CMake.
+- [Axel Huebl](https://github.com/ax3l) simplified a CMake check and added support for the [Spack package manager](https://spack.io).
+- [Carlos O'Ryan](https://github.com/coryan) fixed a typo.
+- [James Upjohn](https://github.com/jammehcow) fixed a version number in the compilers section.
+- [Chuck Atkins](https://github.com/chuckatkins) adjusted the CMake files to the CMake packaging guidelines and provided documentation for the CMake integration.
+- [Jan Schöppach](https://github.com/dns13) fixed a typo.
+- [martin-mfg](https://github.com/martin-mfg) fixed a typo.
+- [Matthias Möller](https://github.com/TinyTinni) removed the dependency from `std::stringstream`.
+- [agrianius](https://github.com/agrianius) added code to use alternative string implementations.
+- [Daniel599](https://github.com/Daniel599) allowed to use more algorithms with the `items()` function.
+- [Julius Rakow](https://github.com/jrakow) fixed the Meson include directory and fixed the links to [cppreference.com](cppreference.com).
+- [Sonu Lohani](https://github.com/sonulohani) fixed the compilation with MSVC 2015 in debug mode.
+- [grembo](https://github.com/grembo) fixed the test suite and re-enabled several test cases.
+- [Hyeon Kim](https://github.com/simnalamburt) introduced the macro `JSON_INTERNAL_CATCH` to control the exception handling inside the library.
+- [thyu](https://github.com/thyu) fixed a compiler warning.
+- [David Guthrie](https://github.com/LEgregius) fixed a subtle compilation error with Clang 3.4.2.
+- [Dennis Fischer](https://github.com/dennisfischer) allowed to call `find_package` without installing the library.
+- [Hyeon Kim](https://github.com/simnalamburt) fixed an issue with a double macro definition.
+- [Ben Berman](https://github.com/rivertam) made some error messages more understandable.
+- [zakalibit](https://github.com/zakalibit) fixed a compilation problem with the Intel C++ compiler.
+- [mandreyel](https://github.com/mandreyel) fixed a compilation problem.
+- [Kostiantyn Ponomarenko](https://github.com/koponomarenko) added version and license information to the Meson build file.
+- [Henry Schreiner](https://github.com/henryiii) added support for GCC 4.8.
+- [knilch](https://github.com/knilch0r) made sure the test suite does not stall when run in the wrong directory.
+- [Antonio Borondo](https://github.com/antonioborondo) fixed an MSVC 2017 warning.
+- [Dan Gendreau](https://github.com/dgendreau) implemented the `NLOHMANN_JSON_SERIALIZE_ENUM` macro to quickly define a enum/JSON mapping.
+- [efp](https://github.com/efp) added line and column information to parse errors.
+- [julian-becker](https://github.com/julian-becker) added BSON support.
+- [Pratik Chowdhury](https://github.com/pratikpc) added support for structured bindings.
+- [David Avedissian](https://github.com/davedissian) added support for Clang 5.0.1 (PS4 version).
+- [Jonathan Dumaresq](https://github.com/dumarjo) implemented an input adapter to read from `FILE*`.
+- [kjpus](https://github.com/kjpus) fixed a link in the documentation.
+- [Manvendra Singh](https://github.com/manu-chroma) fixed a typo in the documentation.
+- [ziggurat29](https://github.com/ziggurat29) fixed an MSVC warning.
+- [Sylvain Corlay](https://github.com/SylvainCorlay) added code to avoid an issue with MSVC.
+- [mefyl](https://github.com/mefyl) fixed a bug when JSON was parsed from an input stream.
+- [Millian Poquet](https://github.com/mpoquet) allowed to install the library via Meson.
+- [Michael Behrns-Miller](https://github.com/moodboom) found an issue with a missing namespace.
+- [Nasztanovics Ferenc](https://github.com/naszta) fixed a compilation issue with libc 2.12.
+- [Andreas Schwab](https://github.com/andreas-schwab) fixed the endian conversion.
+- [Mark-Dunning](https://github.com/Mark-Dunning) fixed a warning in MSVC.
+- [Gareth Sylvester-Bradley](https://github.com/garethsb-sony) added `operator/` for JSON Pointers.
+- [John-Mark](https://github.com/johnmarkwayve) noted a missing header.
+- [Vitaly Zaitsev](https://github.com/xvitaly) fixed compilation with GCC 9.0.
+- [Laurent Stacul](https://github.com/stac47) fixed compilation with GCC 9.0.
+- [Ivor Wanders](https://github.com/iwanders) helped reducing the CMake requirement to version 3.1.
+- [njlr](https://github.com/njlr) updated the Buckaroo instructions.
+- [Lion](https://github.com/lieff) fixed a compilation issue with GCC 7 on CentOS.
+- [Isaac Nickaein](https://github.com/nickaein) improved the integer serialization performance and  implemented the `contains()` function.
+- [past-due](https://github.com/past-due) suppressed an unfixable warning.
+- [Elvis Oric](https://github.com/elvisoric) improved Meson support.
+- [Matěj Plch](https://github.com/Afforix) fixed an example in the README.
+- [Mark Beckwith](https://github.com/wythe) fixed a typo.
+- [scinart](https://github.com/scinart) fixed bug in the serializer.
+- [Patrick Boettcher](https://github.com/pboettch) implemented `push_back()` and `pop_back()` for JSON Pointers.
+- [Bruno Oliveira](https://github.com/nicoddemus) added support for Conda.
+- [Michele Caini](https://github.com/skypjack) fixed links in the README.
+- [Hani](https://github.com/hnkb) documented how to install the library with NuGet.
+- [Mark Beckwith](https://github.com/wythe) fixed a typo.
+- [yann-morin-1998](https://github.com/yann-morin-1998) helped reducing the CMake requirement to version 3.1.
+- [Konstantin Podsvirov](https://github.com/podsvirov) maintains a package for the MSYS2 software distro.
+- [remyabel](https://github.com/remyabel) added GNUInstallDirs to the CMake files.
+- [Taylor Howard](https://github.com/taylorhoward92) fixed a unit test.
+- [Gabe Ron](https://github.com/Macr0Nerd) implemented the `to_string` method.
+- [Watal M. Iwasaki](https://github.com/heavywatal) fixed a Clang warning.
+- [Viktor Kirilov](https://github.com/onqtam) switched the unit tests from [Catch](https://github.com/philsquared/Catch) to [doctest](https://github.com/onqtam/doctest)
+- [Juncheng E](https://github.com/ejcjason) fixed a typo.
+- [tete17](https://github.com/tete17) fixed a bug in the `contains` function.
+- [Xav83](https://github.com/Xav83) fixed some cppcheck warnings.
+- [0xflotus](https://github.com/0xflotus) fixed some typos.
+- [Christian Deneke](https://github.com/chris0x44) added a const version of `json_pointer::back`.
+- [Julien Hamaide](https://github.com/crazyjul) made the `items()` function work with custom string types.
+- [Evan Nemerson](https://github.com/nemequ) updated fixed a bug in Hedley and updated this library accordingly.
+- [Florian Pigorsch](https://github.com/flopp) fixed a lot of typos.
+- [Camille Bégué](https://github.com/cbegue) fixed an issue in the conversion from  `std::pair` and `std::tuple` to `json`.
+- [Anthony VH](https://github.com/AnthonyVH) fixed a compile error in an enum deserialization.
+- [Yuriy Vountesmery](https://github.com/ua-code-dragon) noted a subtle bug in a preprocessor check.
+- [Chen](https://github.com/dota17) fixed numerous issues in the library.
+- [Antony Kellermann](https://github.com/aokellermann) added a CI step for GCC 10.1.
+- [Alex](https://github.com/gistrec) fixed an MSVC warning.
+- [Rainer](https://github.com/rvjr) proposed an improvement in the floating-point serialization in CBOR.
+- [Francois Chabot](https://github.com/FrancoisChabot) made performance improvements in the input adapters.
+- [Arthur Sonzogni](https://github.com/ArthurSonzogni) documented how the library can be included via `FetchContent`.
+- [Rimas Misevičius](https://github.com/rmisev) fixed an error message.
+- [Alexander Myasnikov](https://github.com/alexandermyasnikov) fixed some examples and a link in the README.
+- [Hubert Chathi](https://github.com/uhoreg) made CMake's version config file architecture-independent.
+- [OmnipotentEntity](https://github.com/OmnipotentEntity) implemented the binary values for CBOR, MessagePack, BSON, and UBJSON.
+- [ArtemSarmini](https://github.com/ArtemSarmini) fixed a compilation issue with GCC 10 and fixed a leak.
+- [Evgenii Sopov](https://github.com/sea-kg) integrated the library to the wsjcpp package manager.
+- [Sergey Linev](https://github.com/linev) fixed a compiler warning.
+- [Miguel Magalhães](https://github.com/magamig) fixed the year in the copyright.
+- [Gareth Sylvester-Bradley](https://github.com/garethsb-sony) fixed a compilation issue with MSVC.
+- [Alexander “weej” Jones](https://github.com/alex-weej) fixed an example in the README.
+- [Antoine Cœur](https://github.com/Coeur) fixed some typos in the documentation.
+- [jothepro](https://github.com/jothepro) updated links to the Hunter package.
+- [Dave Lee](https://github.com/kastiglione) fixed link in the README.
+- [Joël Lamotte](https://github.com/Klaim) added instruction for using Build2's package manager.
+- [Paul Jurczak](https://github.com/pauljurczak) fixed an example in the README.
+- [Sonu Lohani](https://github.com/sonulohani) fixed a warning.
+- [Carlos Gomes Martinho](https://github.com/gocarlos) updated the Conan package source.
+- [Konstantin Podsvirov](https://github.com/podsvirov) fixed the MSYS2 package documentation.
+- [Tridacnid](https://github.com/Tridacnid) improved the CMake tests.
+- [Michael](https://github.com/MBalszun) fixed MSVC warnings.
+- [Quentin Barbarat](https://github.com/quentin-dev) fixed an example in the documentation.
+- [XyFreak](https://github.com/XyFreak) fixed a compiler warning.
+- [TotalCaesar659](https://github.com/TotalCaesar659) fixed links in the README.
+- [Tanuj Garg](https://github.com/tanuj208) improved the fuzzer coverage for UBSAN input.
+- [AODQ](https://github.com/AODQ) fixed a compiler warning.
+- [jwittbrodt](https://github.com/jwittbrodt) made `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE` inline.
+- [pfeatherstone](https://github.com/pfeatherstone) improved the upper bound of arguments of the `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE`/`NLOHMANN_DEFINE_TYPE_INTRUSIVE` macros.
+- [Jan Procházka](https://github.com/jprochazk) fixed a bug in the CBOR parser for binary and string values.
+- [T0b1-iOS](https://github.com/T0b1-iOS) fixed a bug in the new hash implementation.
+- [Matthew Bauer](https://github.com/matthewbauer) adjusted the CBOR writer to create tags for binary subtypes.
+- [gatopeich](https://github.com/gatopeich) implemented an ordered map container for `nlohmann::ordered_json`.
+- [Érico Nogueira Rolim](https://github.com/ericonr) added support for pkg-config.
+- [KonanM](https://github.com/KonanM) proposed an implementation for the `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE`/`NLOHMANN_DEFINE_TYPE_INTRUSIVE` macros.
+- [Guillaume Racicot](https://github.com/gracicot) implemented `string_view` support and allowed C++20 support.
+- [Alex Reinking](https://github.com/alexreinking) improved CMake support for `FetchContent`.
+
+Thanks a lot for helping out! Please [let me know](mailto:mail@nlohmann.me) if I forgot someone.
+
+
+## Used third-party tools
+
+The library itself consists of a single header file licensed under the MIT license. However, it is built, tested, documented, and whatnot using a lot of third-party tools and services. Thanks a lot!
+
+- [**amalgamate.py - Amalgamate C source and header files**](https://github.com/edlund/amalgamate) to create a single header file
+- [**American fuzzy lop**](https://lcamtuf.coredump.cx/afl/) for fuzz testing
+- [**AppVeyor**](https://www.appveyor.com) for [continuous integration](https://ci.appveyor.com/project/nlohmann/json) on Windows
+- [**Artistic Style**](http://astyle.sourceforge.net) for automatic source code indentation
+- [**CircleCI**](https://circleci.com) for [continuous integration](https://circleci.com/gh/nlohmann/json).
+- [**Clang**](https://clang.llvm.org) for compilation with code sanitizers
+- [**CMake**](https://cmake.org) for build automation
+- [**Codacity**](https://www.codacy.com) for further [code analysis](https://www.codacy.com/app/nlohmann/json)
+- [**Coveralls**](https://coveralls.io) to measure [code coverage](https://coveralls.io/github/nlohmann/json)
+- [**Coverity Scan**](https://scan.coverity.com) for [static analysis](https://scan.coverity.com/projects/nlohmann-json)
+- [**cppcheck**](http://cppcheck.sourceforge.net) for static analysis
+- [**doctest**](https://github.com/onqtam/doctest) for the unit tests
+- [**Doxygen**](https://www.doxygen.nl/index.html) to generate [documentation](https://nlohmann.github.io/json/doxygen/index.html)
+- [**git-update-ghpages**](https://github.com/rstacruz/git-update-ghpages) to upload the documentation to gh-pages
+- [**GitHub Changelog Generator**](https://github.com/skywinder/github-changelog-generator) to generate the [ChangeLog](https://github.com/nlohmann/json/blob/develop/ChangeLog.md)
+- [**Google Benchmark**](https://github.com/google/benchmark) to implement the benchmarks
+- [**Hedley**](https://nemequ.github.io/hedley/) to avoid re-inventing several compiler-agnostic feature macros
+- [**lcov**](http://ltp.sourceforge.net/coverage/lcov.php) to process coverage information and create a HTML view
+- [**libFuzzer**](https://llvm.org/docs/LibFuzzer.html) to implement fuzz testing for OSS-Fuzz
+- [**OSS-Fuzz**](https://github.com/google/oss-fuzz) for continuous fuzz testing of the library ([project repository](https://github.com/google/oss-fuzz/tree/master/projects/json))
+- [**Probot**](https://probot.github.io) for automating maintainer tasks such as closing stale issues, requesting missing information, or detecting toxic comments.
+- [**send_to_wandbox**](https://github.com/nlohmann/json/blob/develop/doc/scripts/send_to_wandbox.py) to send code examples to [Wandbox](http://melpon.org/wandbox)
+- [**Travis**](https://travis-ci.org) for [continuous integration](https://travis-ci.org/nlohmann/json) on Linux and macOS
+- [**Valgrind**](https://valgrind.org) to check for correct memory management
+- [**Wandbox**](https://wandbox.org) for [online examples](https://wandbox.org/permlink/3lCHrFUZANONKv7a)
+
+
+## Projects using JSON for Modern C++
+
+The library is currently used in Apple macOS Sierra and iOS 10. I am not sure what they are using the library for, but I am happy that it runs on so many devices.
+
+
+## Notes
+
+### Character encoding
+
+The library supports **Unicode input** as follows:
+
+- Only **UTF-8** encoded input is supported which is the default encoding for JSON according to [RFC 8259](https://tools.ietf.org/html/rfc8259.html#section-8.1).
+- `std::u16string` and `std::u32string` can be parsed, assuming UTF-16 and UTF-32 encoding, respectively. These encodings are not supported when reading from files or other input containers.
+- Other encodings such as Latin-1 or ISO 8859-1 are **not** supported and will yield parse or serialization errors.
+- [Unicode noncharacters](https://www.unicode.org/faq/private_use.html#nonchar1) will not be replaced by the library.
+- Invalid surrogates (e.g., incomplete pairs such as `\uDEAD`) will yield parse errors.
+- The strings stored in the library are UTF-8 encoded. When using the default string type (`std::string`), note that its length/size functions return the number of stored bytes rather than the number of characters or glyphs.
+- When you store strings with different encodings in the library, calling [`dump()`](https://nlohmann.github.io/json/api/basic_json/dump/) may throw an exception unless `json::error_handler_t::replace` or `json::error_handler_t::ignore` are used as error handlers.
+
+### Comments in JSON
+
+This library does not support comments by default. It does so for three reasons:
+
+1. Comments are not part of the [JSON specification](https://tools.ietf.org/html/rfc8259). You may argue that `//` or `/* */` are allowed in JavaScript, but JSON is not JavaScript.
+2. This was not an oversight: Douglas Crockford [wrote on this](https://plus.google.com/118095276221607585885/posts/RK8qyGVaGSr) in May 2012:
+
+	> I removed comments from JSON because I saw people were using them to hold parsing directives, a practice which would have destroyed interoperability.  I know that the lack of comments makes some people sad, but it shouldn't.
+
+	> Suppose you are using JSON to keep configuration files, which you would like to annotate. Go ahead and insert all the comments you like. Then pipe it through JSMin before handing it to your JSON parser.
+
+3. It is dangerous for interoperability if some libraries would add comment support while others don't. Please check [The Harmful Consequences of the Robustness Principle](https://tools.ietf.org/html/draft-iab-protocol-maintenance-01) on this.
+
+However, you can pass set parameter `ignore_comments` to true in the `parse` function to ignore `//` or `/* */` comments. Comments will then be treated as whitespace.
+
+### Order of object keys
+
+By default, the library does not preserve the **insertion order of object elements**. This is standards-compliant, as the [JSON standard](https://tools.ietf.org/html/rfc8259.html) defines objects as "an unordered collection of zero or more name/value pairs".
+
+If you do want to preserve the insertion order, you can try the type [`nlohmann::ordered_json`](https://github.com/nlohmann/json/issues/2179). Alternatively, you can use a more sophisticated ordered map like [`tsl::ordered_map`](https://github.com/Tessil/ordered-map) ([integration](https://github.com/nlohmann/json/issues/546#issuecomment-304447518)) or [`nlohmann::fifo_map`](https://github.com/nlohmann/fifo_map) ([integration](https://github.com/nlohmann/json/issues/485#issuecomment-333652309)).
+
+### Memory Release
+
+We checked with Valgrind and the Address Sanitizer (ASAN) that there are no memory leaks.
+
+If you find that a parsing program with this library does not release memory, please consider the following case and it maybe unrelated to this library.
+
+**Your program is compiled with glibc.** There is a tunable threshold that glibc uses to decide whether to actually return memory to the system or whether to cache it for later reuse. If in your program you make lots of small allocations and those small allocations are not a contiguous block and are presumably below the threshold, then they will not get returned to the OS.
+Here is a related issue [#1924](https://github.com/nlohmann/json/issues/1924).
+
+### Further notes
+
+- The code contains numerous debug **assertions** which can be switched off by defining the preprocessor macro `NDEBUG`, see the [documentation of `assert`](https://en.cppreference.com/w/cpp/error/assert). In particular, note [`operator[]`](https://nlohmann.github.io/json/api/basic_json/operator%5B%5D/) implements **unchecked access** for const objects: If the given key is not present, the behavior is undefined (think of a dereferenced null pointer) and yields an [assertion failure](https://github.com/nlohmann/json/issues/289) if assertions are switched on. If you are not sure whether an element in an object exists, use checked access with the [`at()` function](https://nlohmann.github.io/json/api/basic_json/at/). Furthermore, you can define `JSON_ASSERT(x)` to replace calls to `assert(x)`.
+- As the exact type of a number is not defined in the [JSON specification](https://tools.ietf.org/html/rfc8259.html), this library tries to choose the best fitting C++ number type automatically. As a result, the type `double` may be used to store numbers which may yield [**floating-point exceptions**](https://github.com/nlohmann/json/issues/181) in certain rare situations if floating-point exceptions have been unmasked in the calling code. These exceptions are not caused by the library and need to be fixed in the calling code, such as by re-masking the exceptions prior to calling library functions.
+- The code can be compiled without C++ **runtime type identification** features; that is, you can use the `-fno-rtti` compiler flag.
+- **Exceptions** are used widely within the library. They can, however, be switched off with either using the compiler flag `-fno-exceptions` or by defining the symbol `JSON_NOEXCEPTION`. In this case, exceptions are replaced by `abort()` calls. You can further control this behavior by defining `JSON_THROW_USER` (overriding `throw`), `JSON_TRY_USER` (overriding `try`), and `JSON_CATCH_USER` (overriding `catch`). Note that `JSON_THROW_USER` should leave the current scope (e.g., by throwing or aborting), as continuing after it may yield undefined behavior.
+
+## Execute unit tests
+
+To compile and run the tests, you need to execute
+
+```sh
+$ mkdir build
+$ cd build
+$ cmake .. -DJSON_BuildTests=On
+$ cmake --build .
+$ ctest --output-on-failure
+```
+
+Note that during the `ctest` stage, several JSON test files are downloaded from an [external repository](https://github.com/nlohmann/json_test_data). If policies forbid downloading artifacts during testing, you can download the files yourself and pass the directory with the test files via `-DJSON_TestDataDirectory=path` to CMake. Then, no Internet connectivity is required. See [issue #2189](https://github.com/nlohmann/json/issues/2189) for more information.
+
+In case you have downloaded the library rather than checked out the code via Git, test `cmake_fetch_content_configure`. Please execute `ctest -LE git_required` to skip these tests. See [issue #2189](https://github.com/nlohmann/json/issues/2189) for more information.
+
+As Intel compilers use unsafe floating point optimization by default, the unit tests may fail. Use flag [`/fp:precise`](https://software.intel.com/content/www/us/en/develop/documentation/cpp-compiler-developer-guide-and-reference/top/compiler-reference/compiler-options/compiler-option-details/floating-point-options/fp-model-fp.html) then.
diff --git a/src/json/json.hxx b/src/json/json.hxx
new file mode 100644
index 000000000..a70aaf8cb
--- /dev/null
+++ b/src/json/json.hxx
@@ -0,0 +1,25447 @@
+/*
+    __ _____ _____ _____
+ __|  |   __|     |   | |  JSON for Modern C++
+|  |  |__   |  |  | | | |  version 3.9.1
+|_____|_____|_____|_|___|  https://github.com/nlohmann/json
+
+Licensed under the MIT License <http://opensource.org/licenses/MIT>.
+SPDX-License-Identifier: MIT
+Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
+
+Permission is hereby  granted, free of charge, to any  person obtaining a copy
+of this software and associated  documentation files (the "Software"), to deal
+in the Software  without restriction, including without  limitation the rights
+to  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell
+copies  of  the Software,  and  to  permit persons  to  whom  the Software  is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE  IS PROVIDED "AS  IS", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR
+IMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,
+FITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE
+AUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER
+LIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#ifndef INCLUDE_NLOHMANN_JSON_HPP_
+#define INCLUDE_NLOHMANN_JSON_HPP_
+
+#define NLOHMANN_JSON_VERSION_MAJOR 3
+#define NLOHMANN_JSON_VERSION_MINOR 9
+#define NLOHMANN_JSON_VERSION_PATCH 1
+
+#include <algorithm> // all_of, find, for_each
+#include <cstddef> // nullptr_t, ptrdiff_t, size_t
+#include <functional> // hash, less
+#include <initializer_list> // initializer_list
+#include <iosfwd> // istream, ostream
+#include <iterator> // random_access_iterator_tag
+#include <memory> // unique_ptr
+#include <numeric> // accumulate
+#include <string> // string, stoi, to_string
+#include <utility> // declval, forward, move, pair, swap
+#include <vector> // vector
+
+// #include <nlohmann/adl_serializer.hpp>
+
+
+#include <utility>
+
+// #include <nlohmann/detail/conversions/from_json.hpp>
+
+
+#include <algorithm> // transform
+#include <array> // array
+#include <forward_list> // forward_list
+#include <iterator> // inserter, front_inserter, end
+#include <map> // map
+#include <string> // string
+#include <tuple> // tuple, make_tuple
+#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
+#include <unordered_map> // unordered_map
+#include <utility> // pair, declval
+#include <valarray> // valarray
+
+// #include <nlohmann/detail/exceptions.hpp>
+
+
+#include <exception> // exception
+#include <stdexcept> // runtime_error
+#include <string> // to_string
+
+// #include <nlohmann/detail/input/position_t.hpp>
+
+
+#include <cstddef> // size_t
+
+namespace nlohmann
+{
+namespace detail
+{
+/// struct to capture the start position of the current token
+struct position_t
+{
+    /// the total number of characters read
+    std::size_t chars_read_total = 0;
+    /// the number of characters read in the current line
+    std::size_t chars_read_current_line = 0;
+    /// the number of lines read
+    std::size_t lines_read = 0;
+
+    /// conversion to size_t to preserve SAX interface
+    constexpr operator size_t() const
+    {
+        return chars_read_total;
+    }
+};
+
+} // namespace detail
+} // namespace nlohmann
+
+// #include <nlohmann/detail/macro_scope.hpp>
+
+
+#include <utility> // pair
+// #include <nlohmann/thirdparty/hedley/hedley.hpp>
+/* Hedley - https://nemequ.github.io/hedley
+ * Created by Evan Nemerson <evan@nemerson.com>
+ *
+ * To the extent possible under law, the author(s) have dedicated all
+ * copyright and related and neighboring rights to this software to
+ * the public domain worldwide. This software is distributed without
+ * any warranty.
+ *
+ * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.
+ * SPDX-License-Identifier: CC0-1.0
+ */
+
+#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 13)
+#if defined(JSON_HEDLEY_VERSION)
+    #undef JSON_HEDLEY_VERSION
+#endif
+#define JSON_HEDLEY_VERSION 13
+
+#if defined(JSON_HEDLEY_STRINGIFY_EX)
+    #undef JSON_HEDLEY_STRINGIFY_EX
+#endif
+#define JSON_HEDLEY_STRINGIFY_EX(x) #x
+
+#if defined(JSON_HEDLEY_STRINGIFY)
+    #undef JSON_HEDLEY_STRINGIFY
+#endif
+#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
+
+#if defined(JSON_HEDLEY_CONCAT_EX)
+    #undef JSON_HEDLEY_CONCAT_EX
+#endif
+#define JSON_HEDLEY_CONCAT_EX(a,b) a##b
+
+#if defined(JSON_HEDLEY_CONCAT)
+    #undef JSON_HEDLEY_CONCAT
+#endif
+#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
+
+#if defined(JSON_HEDLEY_CONCAT3_EX)
+    #undef JSON_HEDLEY_CONCAT3_EX
+#endif
+#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
+
+#if defined(JSON_HEDLEY_CONCAT3)
+    #undef JSON_HEDLEY_CONCAT3
+#endif
+#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
+
+#if defined(JSON_HEDLEY_VERSION_ENCODE)
+    #undef JSON_HEDLEY_VERSION_ENCODE
+#endif
+#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
+
+#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
+    #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
+#endif
+#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
+
+#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
+    #undef JSON_HEDLEY_VERSION_DECODE_MINOR
+#endif
+#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
+
+#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
+    #undef JSON_HEDLEY_VERSION_DECODE_REVISION
+#endif
+#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
+
+#if defined(JSON_HEDLEY_GNUC_VERSION)
+    #undef JSON_HEDLEY_GNUC_VERSION
+#endif
+#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
+    #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
+#elif defined(__GNUC__)
+    #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
+#endif
+
+#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
+    #undef JSON_HEDLEY_GNUC_VERSION_CHECK
+#endif
+#if defined(JSON_HEDLEY_GNUC_VERSION)
+    #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
+#else
+    #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
+#endif
+
+#if defined(JSON_HEDLEY_MSVC_VERSION)
+    #undef JSON_HEDLEY_MSVC_VERSION
+#endif
+#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000)
+    #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
+#elif defined(_MSC_FULL_VER)
+    #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
+#elif defined(_MSC_VER)
+    #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
+#endif
+
+#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
+    #undef JSON_HEDLEY_MSVC_VERSION_CHECK
+#endif
+#if !defined(_MSC_VER)
+    #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
+#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
+    #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
+#elif defined(_MSC_VER) && (_MSC_VER >= 1200)
+    #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
+#else
+    #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
+#endif
+
+#if defined(JSON_HEDLEY_INTEL_VERSION)
+    #undef JSON_HEDLEY_INTEL_VERSION
+#endif
+#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE)
+    #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
+#elif defined(__INTEL_COMPILER)
+    #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
+#endif
+
+#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
+    #undef JSON_HEDLEY_INTEL_VERSION_CHECK
+#endif
+#if defined(JSON_HEDLEY_INTEL_VERSION)
+    #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
+#else
+    #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
+#endif
+
+#if defined(JSON_HEDLEY_PGI_VERSION)
+    #undef JSON_HEDLEY_PGI_VERSION
+#endif
+#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
+    #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
+#endif
+
+#if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
+    #undef JSON_HEDLEY_PGI_VERSION_CHECK
+#endif
+#if defined(JSON_HEDLEY_PGI_VERSION)
+    #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
+#else
+    #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
+#endif
+
+#if defined(JSON_HEDLEY_SUNPRO_VERSION)
+    #undef JSON_HEDLEY_SUNPRO_VERSION
+#endif
+#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
+    #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10)
+#elif defined(__SUNPRO_C)
+    #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
+#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
+    #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10)
+#elif defined(__SUNPRO_CC)
+    #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
+#endif
+
+#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
+    #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
+#endif
+#if defined(JSON_HEDLEY_SUNPRO_VERSION)
+    #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
+#else
+    #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
+#endif
+
+#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
+    #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
+#endif
+#if defined(__EMSCRIPTEN__)
+    #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
+#endif
+
+#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
+    #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
+#endif
+#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
+    #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
+#else
+    #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
+#endif
+
+#if defined(JSON_HEDLEY_ARM_VERSION)
+    #undef JSON_HEDLEY_ARM_VERSION
+#endif
+#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
+    #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
+#elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
+    #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
+#endif
+
+#if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
+    #undef JSON_HEDLEY_ARM_VERSION_CHECK
+#endif
+#if defined(JSON_HEDLEY_ARM_VERSION)
+    #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
+#else
+    #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
+#endif
+
+#if defined(JSON_HEDLEY_IBM_VERSION)
+    #undef JSON_HEDLEY_IBM_VERSION
+#endif
+#if defined(__ibmxl__)
+    #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
+#elif defined(__xlC__) && defined(__xlC_ver__)
+    #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
+#elif defined(__xlC__)
+    #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
+#endif
+
+#if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
+    #undef JSON_HEDLEY_IBM_VERSION_CHECK
+#endif
+#if defined(JSON_HEDLEY_IBM_VERSION)
+    #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
+#else
+    #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
+#endif
+
+#if defined(JSON_HEDLEY_TI_VERSION)
+    #undef JSON_HEDLEY_TI_VERSION
+#endif
+#if \
+    defined(__TI_COMPILER_VERSION__) && \
+    ( \
+      defined(__TMS470__) || defined(__TI_ARM__) || \
+      defined(__MSP430__) || \
+      defined(__TMS320C2000__) \
+    )
+#if (__TI_COMPILER_VERSION__ >= 16000000)
+    #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
+#endif
+#endif
+
+#if defined(JSON_HEDLEY_TI_VERSION_CHECK)
+    #undef JSON_HEDLEY_TI_VERSION_CHECK
+#endif
+#if defined(JSON_HEDLEY_TI_VERSION)
+    #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
+#else
+    #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
+#endif
+
+#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
+    #undef JSON_HEDLEY_TI_CL2000_VERSION
+#endif
+#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
+    #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
+#endif
+
+#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
+    #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
+#endif
+#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
+    #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
+#else
+    #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
+#endif
+
+#if defined(JSON_HEDLEY_TI_CL430_VERSION)
+    #undef JSON_HEDLEY_TI_CL430_VERSION
+#endif
+#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
+    #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
+#endif
+
+#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
+    #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
+#endif
+#if defined(JSON_HEDLEY_TI_CL430_VERSION)
+    #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
+#else
+    #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
+#endif
+
+#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
+    #undef JSON_HEDLEY_TI_ARMCL_VERSION
+#endif
+#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
+    #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
+#endif
+
+#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
+    #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
+#endif
+#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
+    #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
+#else
+    #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
+#endif
+
+#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
+    #undef JSON_HEDLEY_TI_CL6X_VERSION
+#endif
+#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
+    #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
+#endif
+
+#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
+    #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
+#endif
+#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
+    #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
+#else
+    #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
+#endif
+
+#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
+    #undef JSON_HEDLEY_TI_CL7X_VERSION
+#endif
+#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
+    #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
+#endif
+
+#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
+    #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
+#endif
+#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
+    #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
+#else
+    #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
+#endif
+
+#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
+    #undef JSON_HEDLEY_TI_CLPRU_VERSION
+#endif
+#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
+    #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
+#endif
+
+#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
+    #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
+#endif
+#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
+    #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
+#else
+    #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
+#endif
+
+#if defined(JSON_HEDLEY_CRAY_VERSION)
+    #undef JSON_HEDLEY_CRAY_VERSION
+#endif
+#if defined(_CRAYC)
+    #if defined(_RELEASE_PATCHLEVEL)
+        #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
+    #else
+        #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
+    #endif
+#endif
+
+#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
+    #undef JSON_HEDLEY_CRAY_VERSION_CHECK
+#endif
+#if defined(JSON_HEDLEY_CRAY_VERSION)
+    #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
+#else
+    #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
+#endif
+
+#if defined(JSON_HEDLEY_IAR_VERSION)
+    #undef JSON_HEDLEY_IAR_VERSION
+#endif
+#if defined(__IAR_SYSTEMS_ICC__)
+    #if __VER__ > 1000
+        #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
+    #else
+        #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(VER / 100, __VER__ % 100, 0)
+    #endif
+#endif
+
+#if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
+    #undef JSON_HEDLEY_IAR_VERSION_CHECK
+#endif
+#if defined(JSON_HEDLEY_IAR_VERSION)
+    #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
+#else
+    #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
+#endif
+
+#if defined(JSON_HEDLEY_TINYC_VERSION)
+    #undef JSON_HEDLEY_TINYC_VERSION
+#endif
+#if defined(__TINYC__)
+    #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
+#endif
+
+#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
+    #undef JSON_HEDLEY_TINYC_VERSION_CHECK
+#endif
+#if defined(JSON_HEDLEY_TINYC_VERSION)
+    #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
+#else
+    #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
+#endif
+
+#if defined(JSON_HEDLEY_DMC_VERSION)
+    #undef JSON_HEDLEY_DMC_VERSION
+#endif
+#if defined(__DMC__)
+    #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
+#endif
+
+#if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
+    #undef JSON_HEDLEY_DMC_VERSION_CHECK
+#endif
+#if defined(JSON_HEDLEY_DMC_VERSION)
+    #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
+#else
+    #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
+#endif
+
+#if defined(JSON_HEDLEY_COMPCERT_VERSION)
+    #undef JSON_HEDLEY_COMPCERT_VERSION
+#endif
+#if defined(__COMPCERT_VERSION__)
+    #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
+#endif
+
+#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
+    #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
+#endif
+#if defined(JSON_HEDLEY_COMPCERT_VERSION)
+    #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
+#else
+    #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
+#endif
+
+#if defined(JSON_HEDLEY_PELLES_VERSION)
+    #undef JSON_HEDLEY_PELLES_VERSION
+#endif
+#if defined(__POCC__)
+    #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
+#endif
+
+#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
+    #undef JSON_HEDLEY_PELLES_VERSION_CHECK
+#endif
+#if defined(JSON_HEDLEY_PELLES_VERSION)
+    #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
+#else
+    #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
+#endif
+
+#if defined(JSON_HEDLEY_GCC_VERSION)
+    #undef JSON_HEDLEY_GCC_VERSION
+#endif
+#if \
+    defined(JSON_HEDLEY_GNUC_VERSION) && \
+    !defined(__clang__) && \
+    !defined(JSON_HEDLEY_INTEL_VERSION) && \
+    !defined(JSON_HEDLEY_PGI_VERSION) && \
+    !defined(JSON_HEDLEY_ARM_VERSION) && \
+    !defined(JSON_HEDLEY_TI_VERSION) && \
+    !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
+    !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
+    !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
+    !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
+    !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
+    !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
+    !defined(__COMPCERT__)
+    #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
+#endif
+
+#if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
+    #undef JSON_HEDLEY_GCC_VERSION_CHECK
+#endif
+#if defined(JSON_HEDLEY_GCC_VERSION)
+    #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
+#else
+    #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
+#endif
+
+#if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
+    #undef JSON_HEDLEY_HAS_ATTRIBUTE
+#endif
+#if defined(__has_attribute)
+    #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
+#else
+    #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
+#endif
+
+#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
+    #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
+#endif
+#if defined(__has_attribute)
+    #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
+#else
+    #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
+#endif
+
+#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
+    #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
+#endif
+#if defined(__has_attribute)
+    #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
+#else
+    #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
+#endif
+
+#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
+    #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
+#endif
+#if \
+    defined(__has_cpp_attribute) && \
+    defined(__cplusplus) && \
+    (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
+    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
+#else
+    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
+#endif
+
+#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
+    #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
+#endif
+#if !defined(__cplusplus) || !defined(__has_cpp_attribute)
+    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
+#elif \
+    !defined(JSON_HEDLEY_PGI_VERSION) && \
+    !defined(JSON_HEDLEY_IAR_VERSION) && \
+    (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
+    (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
+    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
+#else
+    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
+#endif
+
+#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
+    #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
+#endif
+#if defined(__has_cpp_attribute) && defined(__cplusplus)
+    #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
+#else
+    #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
+#endif
+
+#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
+    #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
+#endif
+#if defined(__has_cpp_attribute) && defined(__cplusplus)
+    #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
+#else
+    #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
+#endif
+
+#if defined(JSON_HEDLEY_HAS_BUILTIN)
+    #undef JSON_HEDLEY_HAS_BUILTIN
+#endif
+#if defined(__has_builtin)
+    #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
+#else
+    #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
+#endif
+
+#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
+    #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
+#endif
+#if defined(__has_builtin)
+    #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
+#else
+    #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
+#endif
+
+#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
+    #undef JSON_HEDLEY_GCC_HAS_BUILTIN
+#endif
+#if defined(__has_builtin)
+    #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
+#else
+    #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
+#endif
+
+#if defined(JSON_HEDLEY_HAS_FEATURE)
+    #undef JSON_HEDLEY_HAS_FEATURE
+#endif
+#if defined(__has_feature)
+    #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
+#else
+    #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
+#endif
+
+#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
+    #undef JSON_HEDLEY_GNUC_HAS_FEATURE
+#endif
+#if defined(__has_feature)
+    #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
+#else
+    #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
+#endif
+
+#if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
+    #undef JSON_HEDLEY_GCC_HAS_FEATURE
+#endif
+#if defined(__has_feature)
+    #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
+#else
+    #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
+#endif
+
+#if defined(JSON_HEDLEY_HAS_EXTENSION)
+    #undef JSON_HEDLEY_HAS_EXTENSION
+#endif
+#if defined(__has_extension)
+    #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
+#else
+    #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
+#endif
+
+#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
+    #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
+#endif
+#if defined(__has_extension)
+    #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
+#else
+    #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
+#endif
+
+#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
+    #undef JSON_HEDLEY_GCC_HAS_EXTENSION
+#endif
+#if defined(__has_extension)
+    #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
+#else
+    #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
+#endif
+
+#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
+    #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
+#endif
+#if defined(__has_declspec_attribute)
+    #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
+#else
+    #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
+#endif
+
+#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
+    #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
+#endif
+#if defined(__has_declspec_attribute)
+    #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
+#else
+    #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
+#endif
+
+#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
+    #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
+#endif
+#if defined(__has_declspec_attribute)
+    #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
+#else
+    #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
+#endif
+
+#if defined(JSON_HEDLEY_HAS_WARNING)
+    #undef JSON_HEDLEY_HAS_WARNING
+#endif
+#if defined(__has_warning)
+    #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
+#else
+    #define JSON_HEDLEY_HAS_WARNING(warning) (0)
+#endif
+
+#if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
+    #undef JSON_HEDLEY_GNUC_HAS_WARNING
+#endif
+#if defined(__has_warning)
+    #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
+#else
+    #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
+#endif
+
+#if defined(JSON_HEDLEY_GCC_HAS_WARNING)
+    #undef JSON_HEDLEY_GCC_HAS_WARNING
+#endif
+#if defined(__has_warning)
+    #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
+#else
+    #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
+#endif
+
+/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
+   HEDLEY INTERNAL USE ONLY.  API subject to change without notice. */
+#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
+    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
+#endif
+#if defined(__cplusplus)
+#  if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
+#    if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
+#      define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
+    JSON_HEDLEY_DIAGNOSTIC_PUSH \
+    _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
+    _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
+    xpr \
+    JSON_HEDLEY_DIAGNOSTIC_POP
+#    else
+#      define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
+    JSON_HEDLEY_DIAGNOSTIC_PUSH \
+    _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
+    xpr \
+    JSON_HEDLEY_DIAGNOSTIC_POP
+#    endif
+#  endif
+#endif
+#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
+#endif
+
+#if defined(JSON_HEDLEY_CONST_CAST)
+    #undef JSON_HEDLEY_CONST_CAST
+#endif
+#if defined(__cplusplus)
+#  define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
+#elif \
+  JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
+  JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
+  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
+#  define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
+        JSON_HEDLEY_DIAGNOSTIC_PUSH \
+        JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
+        ((T) (expr)); \
+        JSON_HEDLEY_DIAGNOSTIC_POP \
+    }))
+#else
+#  define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
+#endif
+
+#if defined(JSON_HEDLEY_REINTERPRET_CAST)
+    #undef JSON_HEDLEY_REINTERPRET_CAST
+#endif
+#if defined(__cplusplus)
+    #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
+#else
+    #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
+#endif
+
+#if defined(JSON_HEDLEY_STATIC_CAST)
+    #undef JSON_HEDLEY_STATIC_CAST
+#endif
+#if defined(__cplusplus)
+    #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
+#else
+    #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
+#endif
+
+#if defined(JSON_HEDLEY_CPP_CAST)
+    #undef JSON_HEDLEY_CPP_CAST
+#endif
+#if defined(__cplusplus)
+#  if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
+#    define JSON_HEDLEY_CPP_CAST(T, expr) \
+    JSON_HEDLEY_DIAGNOSTIC_PUSH \
+    _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
+    ((T) (expr)) \
+    JSON_HEDLEY_DIAGNOSTIC_POP
+#  elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
+#    define JSON_HEDLEY_CPP_CAST(T, expr) \
+    JSON_HEDLEY_DIAGNOSTIC_PUSH \
+    _Pragma("diag_suppress=Pe137") \
+    JSON_HEDLEY_DIAGNOSTIC_POP \
+#  else
+#    define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
+#  endif
+#else
+#  define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
+#endif
+
+#if \
+    (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
+    defined(__clang__) || \
+    JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
+    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
+    JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
+    JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
+    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
+    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
+    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
+    JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
+    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
+    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
+    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
+    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
+    JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
+    JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
+    JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
+    (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
+    #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
+#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
+    #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
+#else
+    #define JSON_HEDLEY_PRAGMA(value)
+#endif
+
+#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
+    #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
+#endif
+#if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
+    #undef JSON_HEDLEY_DIAGNOSTIC_POP
+#endif
+#if defined(__clang__)
+    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
+    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
+#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
+    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
+    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
+#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
+    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
+    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
+#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
+    #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
+    #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
+#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
+    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
+    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
+#elif \
+    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
+    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
+    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
+    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
+    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
+    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
+    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
+    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
+#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
+    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
+    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
+#else
+    #define JSON_HEDLEY_DIAGNOSTIC_PUSH
+    #define JSON_HEDLEY_DIAGNOSTIC_POP
+#endif
+
+#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
+    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
+#endif
+#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
+#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
+#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
+#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
+#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
+#elif \
+    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
+    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
+    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
+    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
+    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
+    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
+    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
+#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
+#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
+#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
+#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
+#else
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
+#endif
+
+#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
+    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
+#endif
+#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
+#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
+#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
+#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
+#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
+#elif \
+    JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
+    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
+    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
+    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
+#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
+#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
+#else
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
+#endif
+
+#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
+    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
+#endif
+#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
+#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
+#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
+#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
+#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
+#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
+#elif \
+    JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
+    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
+    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
+#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
+#else
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
+#endif
+
+#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
+    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
+#endif
+#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
+#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
+#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
+#else
+    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
+#endif
+
+#if defined(JSON_HEDLEY_DEPRECATED)
+    #undef JSON_HEDLEY_DEPRECATED
+#endif
+#if defined(JSON_HEDLEY_DEPRECATED_FOR)
+    #undef JSON_HEDLEY_DEPRECATED_FOR
+#endif
+#if JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0)
+    #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
+    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
+#elif defined(__cplusplus) && (__cplusplus >= 201402L)
+    #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
+    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
+#elif \
+    JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) || \
+    JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
+    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
+    JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
+    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
+    JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
+    JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
+    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
+    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
+    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
+    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
+    #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
+    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
+#elif \
+    JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
+    JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
+    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
+    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
+    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
+    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
+    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
+    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
+    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
+    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
+    #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
+    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
+#elif \
+    JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
+    JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0)
+    #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
+    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
+#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
+    #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
+    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
+#else
+    #define JSON_HEDLEY_DEPRECATED(since)
+    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
+#endif
+
+#if defined(JSON_HEDLEY_UNAVAILABLE)
+    #undef JSON_HEDLEY_UNAVAILABLE
+#endif
+#if \
+    JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
+    JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
+    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
+    #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
+#else
+    #define JSON_HEDLEY_UNAVAILABLE(available_since)
+#endif
+
+#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
+    #undef JSON_HEDLEY_WARN_UNUSED_RESULT
+#endif
+#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
+    #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
+#endif
+#if (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
+    #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
+    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
+#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
+    #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
+    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
+#elif \
+    JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
+    JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
+    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
+    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
+    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
+    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
+    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
+    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
+    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
+    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
+    (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
+    JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
+    #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
+    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
+#elif defined(_Check_return_) /* SAL */
+    #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
+    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
+#else
+    #define JSON_HEDLEY_WARN_UNUSED_RESULT
+    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)
+#endif
+
+#if defined(JSON_HEDLEY_SENTINEL)
+    #undef JSON_HEDLEY_SENTINEL
+#endif
+#if \
+    JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
+    JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
+    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
+    JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0)
+    #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
+#else
+    #define JSON_HEDLEY_SENTINEL(position)
+#endif
+
+#if defined(JSON_HEDLEY_NO_RETURN)
+    #undef JSON_HEDLEY_NO_RETURN
+#endif
+#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
+    #define JSON_HEDLEY_NO_RETURN __noreturn
+#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
+    #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
+#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
+    #define JSON_HEDLEY_NO_RETURN _Noreturn
+#elif defined(__cplusplus) && (__cplusplus >= 201103L)
+    #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
+#elif \
+    JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
+    JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
+    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
+    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
+    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
+    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
+    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
+    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
+    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
+    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
+    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
+    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
+    #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
+#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
+    #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
+#elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0)
+    #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
+#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
+    #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
+#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
+    #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
+#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
+    #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
+#else
+    #define JSON_HEDLEY_NO_RETURN
+#endif
+
+#if defined(JSON_HEDLEY_NO_ESCAPE)
+    #undef JSON_HEDLEY_NO_ESCAPE
+#endif
+#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
+    #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
+#else
+    #define JSON_HEDLEY_NO_ESCAPE
+#endif
+
+#if defined(JSON_HEDLEY_UNREACHABLE)
+    #undef JSON_HEDLEY_UNREACHABLE
+#endif
+#if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
+    #undef JSON_HEDLEY_UNREACHABLE_RETURN
+#endif
+#if defined(JSON_HEDLEY_ASSUME)
+    #undef JSON_HEDLEY_ASSUME
+#endif
+#if \
+    JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
+    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
+    #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
+#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
+    #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
+#elif \
+    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
+    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
+    #if defined(__cplusplus)
+        #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
+    #else
+        #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
+    #endif
+#endif
+#if \
+    (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
+    JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
+    JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
+    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
+    JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5)
+    #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
+#elif defined(JSON_HEDLEY_ASSUME)
+    #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
+#endif
+#if !defined(JSON_HEDLEY_ASSUME)
+    #if defined(JSON_HEDLEY_UNREACHABLE)
+        #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
+    #else
+        #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
+    #endif
+#endif
+#if defined(JSON_HEDLEY_UNREACHABLE)
+    #if  \
+        JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
+        JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
+        #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
+    #else
+        #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
+    #endif
+#else
+    #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
+#endif
+#if !defined(JSON_HEDLEY_UNREACHABLE)
+    #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
+#endif
+
+JSON_HEDLEY_DIAGNOSTIC_PUSH
+#if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
+    #pragma clang diagnostic ignored "-Wpedantic"
+#endif
+#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
+    #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
+#endif
+#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
+    #if defined(__clang__)
+        #pragma clang diagnostic ignored "-Wvariadic-macros"
+    #elif defined(JSON_HEDLEY_GCC_VERSION)
+        #pragma GCC diagnostic ignored "-Wvariadic-macros"
+    #endif
+#endif
+#if defined(JSON_HEDLEY_NON_NULL)
+    #undef JSON_HEDLEY_NON_NULL
+#endif
+#if \
+    JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
+    JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
+    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
+    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
+    #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
+#else
+    #define JSON_HEDLEY_NON_NULL(...)
+#endif
+JSON_HEDLEY_DIAGNOSTIC_POP
+
+#if defined(JSON_HEDLEY_PRINTF_FORMAT)
+    #undef JSON_HEDLEY_PRINTF_FORMAT
+#endif
+#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
+    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
+#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
+    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
+#elif \
+    JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
+    JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
+    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
+    JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
+    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
+    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
+    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
+    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
+    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
+    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
+    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
+    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
+    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
+#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
+    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
+#else
+    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
+#endif
+
+#if defined(JSON_HEDLEY_CONSTEXPR)
+    #undef JSON_HEDLEY_CONSTEXPR
+#endif
+#if defined(__cplusplus)
+    #if __cplusplus >= 201103L
+        #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
+    #endif
+#endif
+#if !defined(JSON_HEDLEY_CONSTEXPR)
+    #define JSON_HEDLEY_CONSTEXPR
+#endif
+
+#if defined(JSON_HEDLEY_PREDICT)
+    #undef JSON_HEDLEY_PREDICT
+#endif
+#if defined(JSON_HEDLEY_LIKELY)
+    #undef JSON_HEDLEY_LIKELY
+#endif
+#if defined(JSON_HEDLEY_UNLIKELY)
+    #undef JSON_HEDLEY_UNLIKELY
+#endif
+#if defined(JSON_HEDLEY_UNPREDICTABLE)
+    #undef JSON_HEDLEY_UNPREDICTABLE
+#endif
+#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
+    #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
+#endif
+#if \
+  JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) || \
+  JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0)
+#  define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability(  (expr), (value), (probability))
+#  define JSON_HEDLEY_PREDICT_TRUE(expr, probability)   __builtin_expect_with_probability(!!(expr),    1   , (probability))
+#  define JSON_HEDLEY_PREDICT_FALSE(expr, probability)  __builtin_expect_with_probability(!!(expr),    0   , (probability))
+#  define JSON_HEDLEY_LIKELY(expr)                      __builtin_expect                 (!!(expr),    1                  )
+#  define JSON_HEDLEY_UNLIKELY(expr)                    __builtin_expect                 (!!(expr),    0                  )
+#elif \
+  JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) || \
+  JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
+  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
+  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
+  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
+  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
+  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
+  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
+  JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
+  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
+  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
+  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
+  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
+  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
+  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0)
+#  define JSON_HEDLEY_PREDICT(expr, expected, probability) \
+    (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
+#  define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
+    (__extension__ ({ \
+        double hedley_probability_ = (probability); \
+        ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
+    }))
+#  define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
+    (__extension__ ({ \
+        double hedley_probability_ = (probability); \
+        ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
+    }))
+#  define JSON_HEDLEY_LIKELY(expr)   __builtin_expect(!!(expr), 1)
+#  define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
+#else
+#  define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
+#  define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
+#  define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
+#  define JSON_HEDLEY_LIKELY(expr) (!!(expr))
+#  define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
+#endif
+#if !defined(JSON_HEDLEY_UNPREDICTABLE)
+    #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
+#endif
+
+#if defined(JSON_HEDLEY_MALLOC)
+    #undef JSON_HEDLEY_MALLOC
+#endif
+#if \
+    JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
+    JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
+    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
+    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
+    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
+    JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
+    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
+    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
+    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
+    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
+    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
+    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
+    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
+    #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
+#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
+    #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
+#elif JSON_HEDLEY_MSVC_VERSION_CHECK(14, 0, 0)
+    #define JSON_HEDLEY_MALLOC __declspec(restrict)
+#else
+    #define JSON_HEDLEY_MALLOC
+#endif
+
+#if defined(JSON_HEDLEY_PURE)
+    #undef JSON_HEDLEY_PURE
+#endif
+#if \
+  JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
+  JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
+  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
+  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
+  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
+  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
+  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
+  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
+  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
+  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
+  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
+  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
+  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
+  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
+#  define JSON_HEDLEY_PURE __attribute__((__pure__))
+#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
+#  define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
+#elif defined(__cplusplus) && \
+    ( \
+      JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
+      JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
+      JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
+    )
+#  define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
+#else
+#  define JSON_HEDLEY_PURE
+#endif
+
+#if defined(JSON_HEDLEY_CONST)
+    #undef JSON_HEDLEY_CONST
+#endif
+#if \
+    JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
+    JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
+    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
+    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
+    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
+    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
+    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
+    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
+    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
+    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
+    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
+    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
+    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
+    JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
+    #define JSON_HEDLEY_CONST __attribute__((__const__))
+#elif \
+    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
+    #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
+#else
+    #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
+#endif
+
+#if defined(JSON_HEDLEY_RESTRICT)
+    #undef JSON_HEDLEY_RESTRICT
+#endif
+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
+    #define JSON_HEDLEY_RESTRICT restrict
+#elif \
+    JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
+    JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
+    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
+    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
+    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
+    JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
+    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
+    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
+    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
+    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
+    (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
+    JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
+    defined(__clang__)
+    #define JSON_HEDLEY_RESTRICT __restrict
+#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
+    #define JSON_HEDLEY_RESTRICT _Restrict
+#else
+    #define JSON_HEDLEY_RESTRICT
+#endif
+
+#if defined(JSON_HEDLEY_INLINE)
+    #undef JSON_HEDLEY_INLINE
+#endif
+#if \
+    (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
+    (defined(__cplusplus) && (__cplusplus >= 199711L))
+    #define JSON_HEDLEY_INLINE inline
+#elif \
+    defined(JSON_HEDLEY_GCC_VERSION) || \
+    JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
+    #define JSON_HEDLEY_INLINE __inline__
+#elif \
+    JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
+    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
+    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
+    JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
+    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
+    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
+    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
+    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
+    #define JSON_HEDLEY_INLINE __inline
+#else
+    #define JSON_HEDLEY_INLINE
+#endif
+
+#if defined(JSON_HEDLEY_ALWAYS_INLINE)
+    #undef JSON_HEDLEY_ALWAYS_INLINE
+#endif
+#if \
+  JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
+  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
+  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
+  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
+  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
+  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
+  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
+  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
+  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
+  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
+  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
+  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
+  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
+#  define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
+#elif JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0)
+#  define JSON_HEDLEY_ALWAYS_INLINE __forceinline
+#elif defined(__cplusplus) && \
+    ( \
+      JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
+      JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
+      JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
+      JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
+      JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
+      JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
+    )
+#  define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
+#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
+#  define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
+#else
+#  define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
+#endif
+
+#if defined(JSON_HEDLEY_NEVER_INLINE)
+    #undef JSON_HEDLEY_NEVER_INLINE
+#endif
+#if \
+    JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
+    JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
+    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
+    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
+    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
+    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
+    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
+    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
+    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
+    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
+    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
+    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
+    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
+    #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
+#elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0)
+    #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
+#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
+    #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
+#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
+    #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
+#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
+    #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
+#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
+    #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
+#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
+    #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
+#else
+    #define JSON_HEDLEY_NEVER_INLINE
+#endif
+
+#if defined(JSON_HEDLEY_PRIVATE)
+    #undef JSON_HEDLEY_PRIVATE
+#endif
+#if defined(JSON_HEDLEY_PUBLIC)
+    #undef JSON_HEDLEY_PUBLIC
+#endif
+#if defined(JSON_HEDLEY_IMPORT)
+    #undef JSON_HEDLEY_IMPORT
+#endif
+#if defined(_WIN32) || defined(__CYGWIN__)
+#  define JSON_HEDLEY_PRIVATE
+#  define JSON_HEDLEY_PUBLIC   __declspec(dllexport)
+#  define JSON_HEDLEY_IMPORT   __declspec(dllimport)
+#else
+#  if \
+    JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
+    JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
+    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
+    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
+    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
+    JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
+    ( \
+      defined(__TI_EABI__) && \
+      ( \
+        (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
+        JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
+      ) \
+    )
+#    define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
+#    define JSON_HEDLEY_PUBLIC  __attribute__((__visibility__("default")))
+#  else
+#    define JSON_HEDLEY_PRIVATE
+#    define JSON_HEDLEY_PUBLIC
+#  endif
+#  define JSON_HEDLEY_IMPORT    extern
+#endif
+
+#if defined(JSON_HEDLEY_NO_THROW)
+    #undef JSON_HEDLEY_NO_THROW
+#endif
+#if \
+    JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
+    JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
+    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
+    #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
+#elif \
+    JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
+    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
+    #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
+#else
+    #define JSON_HEDLEY_NO_THROW
+#endif
+
+#if defined(JSON_HEDLEY_FALL_THROUGH)
+    #undef JSON_HEDLEY_FALL_THROUGH
+#endif
+#if \
+    JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
+    JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0)
+    #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
+#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
+    #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
+#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
+    #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
+#elif defined(__fallthrough) /* SAL */
+    #define JSON_HEDLEY_FALL_THROUGH __fallthrough
+#else
+    #define JSON_HEDLEY_FALL_THROUGH
+#endif
+
+#if defined(JSON_HEDLEY_RETURNS_NON_NULL)
+    #undef JSON_HEDLEY_RETURNS_NON_NULL
+#endif
+#if \
+    JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
+    JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
+    #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
+#elif defined(_Ret_notnull_) /* SAL */
+    #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
+#else
+    #define JSON_HEDLEY_RETURNS_NON_NULL
+#endif
+
+#if defined(JSON_HEDLEY_ARRAY_PARAM)
+    #undef JSON_HEDLEY_ARRAY_PARAM
+#endif
+#if \
+    defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
+    !defined(__STDC_NO_VLA__) && \
+    !defined(__cplusplus) && \
+    !defined(JSON_HEDLEY_PGI_VERSION) && \
+    !defined(JSON_HEDLEY_TINYC_VERSION)
+    #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
+#else
+    #define JSON_HEDLEY_ARRAY_PARAM(name)
+#endif
+
+#if defined(JSON_HEDLEY_IS_CONSTANT)
+    #undef JSON_HEDLEY_IS_CONSTANT
+#endif
+#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
+    #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
+#endif
+/* JSON_HEDLEY_IS_CONSTEXPR_ is for
+   HEDLEY INTERNAL USE ONLY.  API subject to change without notice. */
+#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
+    #undef JSON_HEDLEY_IS_CONSTEXPR_
+#endif
+#if \
+    JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
+    JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
+    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
+    JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
+    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
+    JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
+    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
+    (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
+    JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0)
+    #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
+#endif
+#if !defined(__cplusplus)
+#  if \
+       JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
+       JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
+       JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
+       JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
+       JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
+       JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
+       JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
+#if defined(__INTPTR_TYPE__)
+    #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
+#else
+    #include <stdint.h>
+    #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
+#endif
+#  elif \
+       ( \
+          defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
+          !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
+          !defined(JSON_HEDLEY_PGI_VERSION) && \
+          !defined(JSON_HEDLEY_IAR_VERSION)) || \
+       JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) || \
+       JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
+       JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
+       JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
+       JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
+#if defined(__INTPTR_TYPE__)
+    #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
+#else
+    #include <stdint.h>
+    #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
+#endif
+#  elif \
+       defined(JSON_HEDLEY_GCC_VERSION) || \
+       defined(JSON_HEDLEY_INTEL_VERSION) || \
+       defined(JSON_HEDLEY_TINYC_VERSION) || \
+       defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
+       JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
+       defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
+       defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
+       defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
+       defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
+       defined(__clang__)
+#    define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
+        sizeof(void) != \
+        sizeof(*( \
+                  1 ? \
+                  ((void*) ((expr) * 0L) ) : \
+((struct { char v[sizeof(void) * 2]; } *) 1) \
+                ) \
+              ) \
+                                            )
+#  endif
+#endif
+#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
+    #if !defined(JSON_HEDLEY_IS_CONSTANT)
+        #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
+    #endif
+    #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
+#else
+    #if !defined(JSON_HEDLEY_IS_CONSTANT)
+        #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
+    #endif
+    #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
+#endif
+
+#if defined(JSON_HEDLEY_BEGIN_C_DECLS)
+    #undef JSON_HEDLEY_BEGIN_C_DECLS
+#endif
+#if defined(JSON_HEDLEY_END_C_DECLS)
+    #undef JSON_HEDLEY_END_C_DECLS
+#endif
+#if defined(JSON_HEDLEY_C_DECL)
+    #undef JSON_HEDLEY_C_DECL
+#endif
+#if defined(__cplusplus)
+    #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
+    #define JSON_HEDLEY_END_C_DECLS }
+    #define JSON_HEDLEY_C_DECL extern "C"
+#else
+    #define JSON_HEDLEY_BEGIN_C_DECLS
+    #define JSON_HEDLEY_END_C_DECLS
+    #define JSON_HEDLEY_C_DECL
+#endif
+
+#if defined(JSON_HEDLEY_STATIC_ASSERT)
+    #undef JSON_HEDLEY_STATIC_ASSERT
+#endif
+#if \
+  !defined(__cplusplus) && ( \
+      (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
+      JSON_HEDLEY_HAS_FEATURE(c_static_assert) || \
+      JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
+      JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
+      defined(_Static_assert) \
+    )
+#  define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
+#elif \
+  (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
+  JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0)
+#  define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
+#else
+#  define JSON_HEDLEY_STATIC_ASSERT(expr, message)
+#endif
+
+#if defined(JSON_HEDLEY_NULL)
+    #undef JSON_HEDLEY_NULL
+#endif
+#if defined(__cplusplus)
+    #if __cplusplus >= 201103L
+        #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
+    #elif defined(NULL)
+        #define JSON_HEDLEY_NULL NULL
+    #else
+        #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
+    #endif
+#elif defined(NULL)
+    #define JSON_HEDLEY_NULL NULL
+#else
+    #define JSON_HEDLEY_NULL ((void*) 0)
+#endif
+
+#if defined(JSON_HEDLEY_MESSAGE)
+    #undef JSON_HEDLEY_MESSAGE
+#endif
+#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
+#  define JSON_HEDLEY_MESSAGE(msg) \
+    JSON_HEDLEY_DIAGNOSTIC_PUSH \
+    JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
+    JSON_HEDLEY_PRAGMA(message msg) \
+    JSON_HEDLEY_DIAGNOSTIC_POP
+#elif \
+  JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
+  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
+#  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
+#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
+#  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
+#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
+#  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
+#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
+#  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
+#else
+#  define JSON_HEDLEY_MESSAGE(msg)
+#endif
+
+#if defined(JSON_HEDLEY_WARNING)
+    #undef JSON_HEDLEY_WARNING
+#endif
+#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
+#  define JSON_HEDLEY_WARNING(msg) \
+    JSON_HEDLEY_DIAGNOSTIC_PUSH \
+    JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
+    JSON_HEDLEY_PRAGMA(clang warning msg) \
+    JSON_HEDLEY_DIAGNOSTIC_POP
+#elif \
+  JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
+  JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
+  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
+#  define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
+#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
+#  define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
+#else
+#  define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
+#endif
+
+#if defined(JSON_HEDLEY_REQUIRE)
+    #undef JSON_HEDLEY_REQUIRE
+#endif
+#if defined(JSON_HEDLEY_REQUIRE_MSG)
+    #undef JSON_HEDLEY_REQUIRE_MSG
+#endif
+#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
+#  if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
+#    define JSON_HEDLEY_REQUIRE(expr) \
+    JSON_HEDLEY_DIAGNOSTIC_PUSH \
+    _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
+    __attribute__((diagnose_if(!(expr), #expr, "error"))) \
+    JSON_HEDLEY_DIAGNOSTIC_POP
+#    define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
+    JSON_HEDLEY_DIAGNOSTIC_PUSH \
+    _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
+    __attribute__((diagnose_if(!(expr), msg, "error"))) \
+    JSON_HEDLEY_DIAGNOSTIC_POP
+#  else
+#    define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
+#    define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
+#  endif
+#else
+#  define JSON_HEDLEY_REQUIRE(expr)
+#  define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
+#endif
+
+#if defined(JSON_HEDLEY_FLAGS)
+    #undef JSON_HEDLEY_FLAGS
+#endif
+#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum)
+    #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
+#endif
+
+#if defined(JSON_HEDLEY_FLAGS_CAST)
+    #undef JSON_HEDLEY_FLAGS_CAST
+#endif
+#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
+#  define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
+        JSON_HEDLEY_DIAGNOSTIC_PUSH \
+        _Pragma("warning(disable:188)") \
+        ((T) (expr)); \
+        JSON_HEDLEY_DIAGNOSTIC_POP \
+    }))
+#else
+#  define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
+#endif
+
+#if defined(JSON_HEDLEY_EMPTY_BASES)
+    #undef JSON_HEDLEY_EMPTY_BASES
+#endif
+#if JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)
+    #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
+#else
+    #define JSON_HEDLEY_EMPTY_BASES
+#endif
+
+/* Remaining macros are deprecated. */
+
+#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
+    #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
+#endif
+#if defined(__clang__)
+    #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
+#else
+    #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
+#endif
+
+#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
+    #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
+#endif
+#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
+
+#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
+    #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
+#endif
+#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
+
+#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
+    #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
+#endif
+#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
+
+#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
+    #undef JSON_HEDLEY_CLANG_HAS_FEATURE
+#endif
+#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
+
+#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
+    #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
+#endif
+#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
+
+#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
+    #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
+#endif
+#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
+
+#if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
+    #undef JSON_HEDLEY_CLANG_HAS_WARNING
+#endif
+#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
+
+#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
+
+
+// This file contains all internal macro definitions
+// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
+
+// exclude unsupported compilers
+#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
+    #if defined(__clang__)
+        #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
+            #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
+        #endif
+    #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
+        #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
+            #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
+        #endif
+    #endif
+#endif
+
+// C++ language standard detection
+#if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
+    #define JSON_HAS_CPP_20
+    #define JSON_HAS_CPP_17
+    #define JSON_HAS_CPP_14
+#elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
+    #define JSON_HAS_CPP_17
+    #define JSON_HAS_CPP_14
+#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
+    #define JSON_HAS_CPP_14
+#endif
+
+// disable float-equal warnings on GCC/clang
+#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
+    #pragma GCC diagnostic push
+    #pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+
+// disable documentation warnings on clang
+#if defined(__clang__)
+    #pragma GCC diagnostic push
+    #pragma GCC diagnostic ignored "-Wdocumentation"
+#endif
+
+// allow to disable exceptions
+#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
+    #define JSON_THROW(exception) throw exception
+    #define JSON_TRY try
+    #define JSON_CATCH(exception) catch(exception)
+    #define JSON_INTERNAL_CATCH(exception) catch(exception)
+#else
+    #include <cstdlib>
+    #define JSON_THROW(exception) std::abort()
+    #define JSON_TRY if(true)
+    #define JSON_CATCH(exception) if(false)
+    #define JSON_INTERNAL_CATCH(exception) if(false)
+#endif
+
+// override exception macros
+#if defined(JSON_THROW_USER)
+    #undef JSON_THROW
+    #define JSON_THROW JSON_THROW_USER
+#endif
+#if defined(JSON_TRY_USER)
+    #undef JSON_TRY
+    #define JSON_TRY JSON_TRY_USER
+#endif
+#if defined(JSON_CATCH_USER)
+    #undef JSON_CATCH
+    #define JSON_CATCH JSON_CATCH_USER
+    #undef JSON_INTERNAL_CATCH
+    #define JSON_INTERNAL_CATCH JSON_CATCH_USER
+#endif
+#if defined(JSON_INTERNAL_CATCH_USER)
+    #undef JSON_INTERNAL_CATCH
+    #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
+#endif
+
+// allow to override assert
+#if !defined(JSON_ASSERT)
+    #include <cassert> // assert
+    #define JSON_ASSERT(x) assert(x)
+#endif
+
+/*!
+@brief macro to briefly define a mapping between an enum and JSON
+@def NLOHMANN_JSON_SERIALIZE_ENUM
+@since version 3.4.0
+*/
+#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...)                                            \
+    template<typename BasicJsonType>                                                            \
+    inline void to_json(BasicJsonType& j, const ENUM_TYPE& e)                                   \
+    {                                                                                           \
+        static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!");          \
+        static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;                     \
+        auto it = std::find_if(std::begin(m), std::end(m),                                      \
+                               [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool  \
+        {                                                                                       \
+            return ej_pair.first == e;                                                          \
+        });                                                                                     \
+        j = ((it != std::end(m)) ? it : std::begin(m))->second;                                 \
+    }                                                                                           \
+    template<typename BasicJsonType>                                                            \
+    inline void from_json(const BasicJsonType& j, ENUM_TYPE& e)                                 \
+    {                                                                                           \
+        static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!");          \
+        static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;                     \
+        auto it = std::find_if(std::begin(m), std::end(m),                                      \
+                               [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
+        {                                                                                       \
+            return ej_pair.second == j;                                                         \
+        });                                                                                     \
+        e = ((it != std::end(m)) ? it : std::begin(m))->first;                                  \
+    }
+
+// Ugly macros to avoid uglier copy-paste when specializing basic_json. They
+// may be removed in the future once the class is split.
+
+#define NLOHMANN_BASIC_JSON_TPL_DECLARATION                                \
+    template<template<typename, typename, typename...> class ObjectType,   \
+             template<typename, typename...> class ArrayType,              \
+             class StringType, class BooleanType, class NumberIntegerType, \
+             class NumberUnsignedType, class NumberFloatType,              \
+             template<typename> class AllocatorType,                       \
+             template<typename, typename = void> class JSONSerializer,     \
+             class BinaryType>
+
+#define NLOHMANN_BASIC_JSON_TPL                                            \
+    basic_json<ObjectType, ArrayType, StringType, BooleanType,             \
+    NumberIntegerType, NumberUnsignedType, NumberFloatType,                \
+    AllocatorType, JSONSerializer, BinaryType>
+
+// Macros to simplify conversion from/to types
+
+#define NLOHMANN_JSON_EXPAND( x ) x
+#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME
+#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
+        NLOHMANN_JSON_PASTE64, \
+        NLOHMANN_JSON_PASTE63, \
+        NLOHMANN_JSON_PASTE62, \
+        NLOHMANN_JSON_PASTE61, \
+        NLOHMANN_JSON_PASTE60, \
+        NLOHMANN_JSON_PASTE59, \
+        NLOHMANN_JSON_PASTE58, \
+        NLOHMANN_JSON_PASTE57, \
+        NLOHMANN_JSON_PASTE56, \
+        NLOHMANN_JSON_PASTE55, \
+        NLOHMANN_JSON_PASTE54, \
+        NLOHMANN_JSON_PASTE53, \
+        NLOHMANN_JSON_PASTE52, \
+        NLOHMANN_JSON_PASTE51, \
+        NLOHMANN_JSON_PASTE50, \
+        NLOHMANN_JSON_PASTE49, \
+        NLOHMANN_JSON_PASTE48, \
+        NLOHMANN_JSON_PASTE47, \
+        NLOHMANN_JSON_PASTE46, \
+        NLOHMANN_JSON_PASTE45, \
+        NLOHMANN_JSON_PASTE44, \
+        NLOHMANN_JSON_PASTE43, \
+        NLOHMANN_JSON_PASTE42, \
+        NLOHMANN_JSON_PASTE41, \
+        NLOHMANN_JSON_PASTE40, \
+        NLOHMANN_JSON_PASTE39, \
+        NLOHMANN_JSON_PASTE38, \
+        NLOHMANN_JSON_PASTE37, \
+        NLOHMANN_JSON_PASTE36, \
+        NLOHMANN_JSON_PASTE35, \
+        NLOHMANN_JSON_PASTE34, \
+        NLOHMANN_JSON_PASTE33, \
+        NLOHMANN_JSON_PASTE32, \
+        NLOHMANN_JSON_PASTE31, \
+        NLOHMANN_JSON_PASTE30, \
+        NLOHMANN_JSON_PASTE29, \
+        NLOHMANN_JSON_PASTE28, \
+        NLOHMANN_JSON_PASTE27, \
+        NLOHMANN_JSON_PASTE26, \
+        NLOHMANN_JSON_PASTE25, \
+        NLOHMANN_JSON_PASTE24, \
+        NLOHMANN_JSON_PASTE23, \
+        NLOHMANN_JSON_PASTE22, \
+        NLOHMANN_JSON_PASTE21, \
+        NLOHMANN_JSON_PASTE20, \
+        NLOHMANN_JSON_PASTE19, \
+        NLOHMANN_JSON_PASTE18, \
+        NLOHMANN_JSON_PASTE17, \
+        NLOHMANN_JSON_PASTE16, \
+        NLOHMANN_JSON_PASTE15, \
+        NLOHMANN_JSON_PASTE14, \
+        NLOHMANN_JSON_PASTE13, \
+        NLOHMANN_JSON_PASTE12, \
+        NLOHMANN_JSON_PASTE11, \
+        NLOHMANN_JSON_PASTE10, \
+        NLOHMANN_JSON_PASTE9, \
+        NLOHMANN_JSON_PASTE8, \
+        NLOHMANN_JSON_PASTE7, \
+        NLOHMANN_JSON_PASTE6, \
+        NLOHMANN_JSON_PASTE5, \
+        NLOHMANN_JSON_PASTE4, \
+        NLOHMANN_JSON_PASTE3, \
+        NLOHMANN_JSON_PASTE2, \
+        NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
+#define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
+#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
+#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
+#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
+#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
+#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6)
+#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7)
+#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8)
+#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9)
+#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10)
+#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)
+#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12)
+#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13)
+#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14)
+#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)
+#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16)
+#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17)
+#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18)
+#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19)
+#define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20)
+#define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21)
+#define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22)
+#define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23)
+#define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24)
+#define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25)
+#define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26)
+#define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27)
+#define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28)
+#define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29)
+#define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30)
+#define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31)
+#define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32)
+#define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33)
+#define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34)
+#define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35)
+#define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36)
+#define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37)
+#define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38)
+#define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39)
+#define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40)
+#define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41)
+#define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42)
+#define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43)
+#define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44)
+#define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45)
+#define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46)
+#define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47)
+#define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48)
+#define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49)
+#define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50)
+#define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51)
+#define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52)
+#define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53)
+#define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54)
+#define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55)
+#define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56)
+#define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57)
+#define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58)
+#define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59)
+#define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60)
+#define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61)
+#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62)
+#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63)
+
+#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
+#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
+
+/*!
+@brief macro
+@def NLOHMANN_DEFINE_TYPE_INTRUSIVE
+@since version 3.9.0
+*/
+#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...)  \
+    friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
+    friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
+
+/*!
+@brief macro
+@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE
+@since version 3.9.0
+*/
+#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...)  \
+    inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
+    inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
+
+#ifndef JSON_USE_IMPLICIT_CONVERSIONS
+    #define JSON_USE_IMPLICIT_CONVERSIONS 1
+#endif
+
+#if JSON_USE_IMPLICIT_CONVERSIONS
+    #define JSON_EXPLICIT
+#else
+    #define JSON_EXPLICIT explicit
+#endif
+
+
+namespace nlohmann
+{
+namespace detail
+{
+////////////////
+// exceptions //
+////////////////
+
+/*!
+@brief general exception of the @ref basic_json class
+
+This class is an extension of `std::exception` objects with a member @a id for
+exception ids. It is used as the base class for all exceptions thrown by the
+@ref basic_json class. This class can hence be used as "wildcard" to catch
+exceptions.
+
+Subclasses:
+- @ref parse_error for exceptions indicating a parse error
+- @ref invalid_iterator for exceptions indicating errors with iterators
+- @ref type_error for exceptions indicating executing a member function with
+                  a wrong type
+- @ref out_of_range for exceptions indicating access out of the defined range
+- @ref other_error for exceptions indicating other library errors
+
+@internal
+@note To have nothrow-copy-constructible exceptions, we internally use
+      `std::runtime_error` which can cope with arbitrary-length error messages.
+      Intermediate strings are built with static functions and then passed to
+      the actual constructor.
+@endinternal
+
+@liveexample{The following code shows how arbitrary library exceptions can be
+caught.,exception}
+
+@since version 3.0.0
+*/
+class exception : public std::exception
+{
+  public:
+    /// returns the explanatory string
+    JSON_HEDLEY_RETURNS_NON_NULL
+    const char* what() const noexcept override
+    {
+        return m.what();
+    }
+
+    /// the id of the exception
+    const int id;
+
+  protected:
+    JSON_HEDLEY_NON_NULL(3)
+    exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
+
+    static std::string name(const std::string& ename, int id_)
+    {
+        return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
+    }
+
+  private:
+    /// an exception object as storage for error messages
+    std::runtime_error m;
+};
+
+/*!
+@brief exception indicating a parse error
+
+This exception is thrown by the library when a parse error occurs. Parse errors
+can occur during the deserialization of JSON text, CBOR, MessagePack, as well
+as when using JSON Patch.
+
+Member @a byte holds the byte index of the last read character in the input
+file.
+
+Exceptions have ids 1xx.
+
+name / id                      | example message | description
+------------------------------ | --------------- | -------------------------
+json.exception.parse_error.101 | parse error at 2: unexpected end of input; expected string literal | This error indicates a syntax error while deserializing a JSON text. The error message describes that an unexpected token (character) was encountered, and the member @a byte indicates the error position.
+json.exception.parse_error.102 | parse error at 14: missing or wrong low surrogate | JSON uses the `\uxxxx` format to describe Unicode characters. Code points above above 0xFFFF are split into two `\uxxxx` entries ("surrogate pairs"). This error indicates that the surrogate pair is incomplete or contains an invalid code point.
+json.exception.parse_error.103 | parse error: code points above 0x10FFFF are invalid | Unicode supports code points up to 0x10FFFF. Code points above 0x10FFFF are invalid.
+json.exception.parse_error.104 | parse error: JSON patch must be an array of objects | [RFC 6902](https://tools.ietf.org/html/rfc6902) requires a JSON Patch document to be a JSON document that represents an array of objects.
+json.exception.parse_error.105 | parse error: operation must have string member 'op' | An operation of a JSON Patch document must contain exactly one "op" member, whose value indicates the operation to perform. Its value must be one of "add", "remove", "replace", "move", "copy", or "test"; other values are errors.
+json.exception.parse_error.106 | parse error: array index '01' must not begin with '0' | An array index in a JSON Pointer ([RFC 6901](https://tools.ietf.org/html/rfc6901)) may be `0` or any number without a leading `0`.
+json.exception.parse_error.107 | parse error: JSON pointer must be empty or begin with '/' - was: 'foo' | A JSON Pointer must be a Unicode string containing a sequence of zero or more reference tokens, each prefixed by a `/` character.
+json.exception.parse_error.108 | parse error: escape character '~' must be followed with '0' or '1' | In a JSON Pointer, only `~0` and `~1` are valid escape sequences.
+json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number.
+json.exception.parse_error.110 | parse error at 1: cannot read 2 bytes from vector | When parsing CBOR or MessagePack, the byte vector ends before the complete value has been read.
+json.exception.parse_error.112 | parse error at 1: error reading CBOR; last byte: 0xF8 | Not all types of CBOR or MessagePack are supported. This exception occurs if an unsupported byte was read.
+json.exception.parse_error.113 | parse error at 2: expected a CBOR string; last byte: 0x98 | While parsing a map key, a value that is not a string has been read.
+json.exception.parse_error.114 | parse error: Unsupported BSON record type 0x0F | The parsing of the corresponding BSON record type is not implemented (yet).
+json.exception.parse_error.115 | parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1A | A UBJSON high-precision number could not be parsed.
+
+@note For an input with n bytes, 1 is the index of the first character and n+1
+      is the index of the terminating null byte or the end of file. This also
+      holds true when reading a byte vector (CBOR or MessagePack).
+
+@liveexample{The following code shows how a `parse_error` exception can be
+caught.,parse_error}
+
+@sa - @ref exception for the base class of the library exceptions
+@sa - @ref invalid_iterator for exceptions indicating errors with iterators
+@sa - @ref type_error for exceptions indicating executing a member function with
+                    a wrong type
+@sa - @ref out_of_range for exceptions indicating access out of the defined range
+@sa - @ref other_error for exceptions indicating other library errors
+
+@since version 3.0.0
+*/
+class parse_error : public exception
+{
+  public:
+    /*!
+    @brief create a parse error exception
+    @param[in] id_       the id of the exception
+    @param[in] pos       the position where the error occurred (or with
+                         chars_read_total=0 if the position cannot be
+                         determined)
+    @param[in] what_arg  the explanatory string
+    @return parse_error object
+    */
+    static parse_error create(int id_, const position_t& pos, const std::string& what_arg)
+    {
+        std::string w = exception::name("parse_error", id_) + "parse error" +
+                        position_string(pos) + ": " + what_arg;
+        return parse_error(id_, pos.chars_read_total, w.c_str());
+    }
+
+    static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
+    {
+        std::string w = exception::name("parse_error", id_) + "parse error" +
+                        (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
+                        ": " + what_arg;
+        return parse_error(id_, byte_, w.c_str());
+    }
+
+    /*!
+    @brief byte index of the parse error
+
+    The byte index of the last read character in the input file.
+
+    @note For an input with n bytes, 1 is the index of the first character and
+          n+1 is the index of the terminating null byte or the end of file.
+          This also holds true when reading a byte vector (CBOR or MessagePack).
+    */
+    const std::size_t byte;
+
+  private:
+    parse_error(int id_, std::size_t byte_, const char* what_arg)
+        : exception(id_, what_arg), byte(byte_) {}
+
+    static std::string position_string(const position_t& pos)
+    {
+        return " at line " + std::to_string(pos.lines_read + 1) +
+               ", column " + std::to_string(pos.chars_read_current_line);
+    }
+};
+
+/*!
+@brief exception indicating errors with iterators
+
+This exception is thrown if iterators passed to a library function do not match
+the expected semantics.
+
+Exceptions have ids 2xx.
+
+name / id                           | example message | description
+----------------------------------- | --------------- | -------------------------
+json.exception.invalid_iterator.201 | iterators are not compatible | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid.
+json.exception.invalid_iterator.202 | iterator does not fit current value | In an erase or insert function, the passed iterator @a pos does not belong to the JSON value for which the function was called. It hence does not define a valid position for the deletion/insertion.
+json.exception.invalid_iterator.203 | iterators do not fit current value | Either iterator passed to function @ref erase(IteratorType first, IteratorType last) does not belong to the JSON value from which values shall be erased. It hence does not define a valid range to delete values from.
+json.exception.invalid_iterator.204 | iterators out of range | When an iterator range for a primitive type (number, boolean, or string) is passed to a constructor or an erase function, this range has to be exactly (@ref begin(), @ref end()), because this is the only way the single stored value is expressed. All other ranges are invalid.
+json.exception.invalid_iterator.205 | iterator out of range | When an iterator for a primitive type (number, boolean, or string) is passed to an erase function, the iterator has to be the @ref begin() iterator, because it is the only way to address the stored value. All other iterators are invalid.
+json.exception.invalid_iterator.206 | cannot construct with iterators from null | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) belong to a JSON null value and hence to not define a valid range.
+json.exception.invalid_iterator.207 | cannot use key() for non-object iterators | The key() member function can only be used on iterators belonging to a JSON object, because other types do not have a concept of a key.
+json.exception.invalid_iterator.208 | cannot use operator[] for object iterators | The operator[] to specify a concrete offset cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.
+json.exception.invalid_iterator.209 | cannot use offsets with object iterators | The offset operators (+, -, +=, -=) cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.
+json.exception.invalid_iterator.210 | iterators do not fit | The iterator range passed to the insert function are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid.
+json.exception.invalid_iterator.211 | passed iterators may not belong to container | The iterator range passed to the insert function must not be a subrange of the container to insert to.
+json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container.
+json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered.
+json.exception.invalid_iterator.214 | cannot get value | Cannot get value for iterator: Either the iterator belongs to a null value or it is an iterator to a primitive type (number, boolean, or string), but the iterator is different to @ref begin().
+
+@liveexample{The following code shows how an `invalid_iterator` exception can be
+caught.,invalid_iterator}
+
+@sa - @ref exception for the base class of the library exceptions
+@sa - @ref parse_error for exceptions indicating a parse error
+@sa - @ref type_error for exceptions indicating executing a member function with
+                    a wrong type
+@sa - @ref out_of_range for exceptions indicating access out of the defined range
+@sa - @ref other_error for exceptions indicating other library errors
+
+@since version 3.0.0
+*/
+class invalid_iterator : public exception
+{
+  public:
+    static invalid_iterator create(int id_, const std::string& what_arg)
+    {
+        std::string w = exception::name("invalid_iterator", id_) + what_arg;
+        return invalid_iterator(id_, w.c_str());
+    }
+
+  private:
+    JSON_HEDLEY_NON_NULL(3)
+    invalid_iterator(int id_, const char* what_arg)
+        : exception(id_, what_arg) {}
+};
+
+/*!
+@brief exception indicating executing a member function with a wrong type
+
+This exception is thrown in case of a type error; that is, a library function is
+executed on a JSON value whose type does not match the expected semantics.
+
+Exceptions have ids 3xx.
+
+name / id                     | example message | description
+----------------------------- | --------------- | -------------------------
+json.exception.type_error.301 | cannot create object from initializer list | To create an object from an initializer list, the initializer list must consist only of a list of pairs whose first element is a string. When this constraint is violated, an array is created instead.
+json.exception.type_error.302 | type must be object, but is array | During implicit or explicit value conversion, the JSON type must be compatible to the target type. For instance, a JSON string can only be converted into string types, but not into numbers or boolean types.
+json.exception.type_error.303 | incompatible ReferenceType for get_ref, actual type is object | To retrieve a reference to a value stored in a @ref basic_json object with @ref get_ref, the type of the reference must match the value type. For instance, for a JSON array, the @a ReferenceType must be @ref array_t &.
+json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types.
+json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types.
+json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types.
+json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types.
+json.exception.type_error.308 | cannot use push_back() with string | The @ref push_back() and @ref operator+= member functions can only be executed for certain JSON types.
+json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types.
+json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types.
+json.exception.type_error.311 | cannot use emplace_back() with string | The @ref emplace_back() member function can only be executed for certain JSON types.
+json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types.
+json.exception.type_error.313 | invalid value to unflatten | The @ref unflatten function converts an object whose keys are JSON Pointers back into an arbitrary nested JSON value. The JSON Pointers must not overlap, because then the resulting value would not be well defined.
+json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers.
+json.exception.type_error.315 | values in object must be primitive | The @ref unflatten function only works for an object whose keys are JSON Pointers and whose values are primitive.
+json.exception.type_error.316 | invalid UTF-8 byte at index 10: 0x7E | The @ref dump function only works with UTF-8 encoded strings; that is, if you assign a `std::string` to a JSON value, make sure it is UTF-8 encoded. |
+json.exception.type_error.317 | JSON value cannot be serialized to requested format | The dynamic type of the object cannot be represented in the requested serialization format (e.g. a raw `true` or `null` JSON object cannot be serialized to BSON) |
+
+@liveexample{The following code shows how a `type_error` exception can be
+caught.,type_error}
+
+@sa - @ref exception for the base class of the library exceptions
+@sa - @ref parse_error for exceptions indicating a parse error
+@sa - @ref invalid_iterator for exceptions indicating errors with iterators
+@sa - @ref out_of_range for exceptions indicating access out of the defined range
+@sa - @ref other_error for exceptions indicating other library errors
+
+@since version 3.0.0
+*/
+class type_error : public exception
+{
+  public:
+    static type_error create(int id_, const std::string& what_arg)
+    {
+        std::string w = exception::name("type_error", id_) + what_arg;
+        return type_error(id_, w.c_str());
+    }
+
+  private:
+    JSON_HEDLEY_NON_NULL(3)
+    type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
+};
+
+/*!
+@brief exception indicating access out of the defined range
+
+This exception is thrown in case a library function is called on an input
+parameter that exceeds the expected range, for instance in case of array
+indices or nonexisting object keys.
+
+Exceptions have ids 4xx.
+
+name / id                       | example message | description
+------------------------------- | --------------- | -------------------------
+json.exception.out_of_range.401 | array index 3 is out of range | The provided array index @a i is larger than @a size-1.
+json.exception.out_of_range.402 | array index '-' (3) is out of range | The special array index `-` in a JSON Pointer never describes a valid element of the array, but the index past the end. That is, it can only be used to add elements at this position, but not to read it.
+json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object.
+json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved.
+json.exception.out_of_range.405 | JSON pointer has no parent | The JSON Patch operations 'remove' and 'add' can not be applied to the root element of the JSON value.
+json.exception.out_of_range.406 | number overflow parsing '10E1000' | A parsed number could not be stored as without changing it to NaN or INF.
+json.exception.out_of_range.407 | number overflow serializing '9223372036854775808' | UBJSON and BSON only support integer numbers up to 9223372036854775807. (until version 3.8.0) |
+json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. |
+json.exception.out_of_range.409 | BSON key cannot contain code point U+0000 (at byte 2) | Key identifiers to be serialized to BSON cannot contain code point U+0000, since the key is stored as zero-terminated c-string |
+
+@liveexample{The following code shows how an `out_of_range` exception can be
+caught.,out_of_range}
+
+@sa - @ref exception for the base class of the library exceptions
+@sa - @ref parse_error for exceptions indicating a parse error
+@sa - @ref invalid_iterator for exceptions indicating errors with iterators
+@sa - @ref type_error for exceptions indicating executing a member function with
+                    a wrong type
+@sa - @ref other_error for exceptions indicating other library errors
+
+@since version 3.0.0
+*/
+class out_of_range : public exception
+{
+  public:
+    static out_of_range create(int id_, const std::string& what_arg)
+    {
+        std::string w = exception::name("out_of_range", id_) + what_arg;
+        return out_of_range(id_, w.c_str());
+    }
+
+  private:
+    JSON_HEDLEY_NON_NULL(3)
+    out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
+};
+
+/*!
+@brief exception indicating other library errors
+
+This exception is thrown in case of errors that cannot be classified with the
+other exception types.
+
+Exceptions have ids 5xx.
+
+name / id                      | example message | description
+------------------------------ | --------------- | -------------------------
+json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.
+
+@sa - @ref exception for the base class of the library exceptions
+@sa - @ref parse_error for exceptions indicating a parse error
+@sa - @ref invalid_iterator for exceptions indicating errors with iterators
+@sa - @ref type_error for exceptions indicating executing a member function with
+                    a wrong type
+@sa - @ref out_of_range for exceptions indicating access out of the defined range
+
+@liveexample{The following code shows how an `other_error` exception can be
+caught.,other_error}
+
+@since version 3.0.0
+*/
+class other_error : public exception
+{
+  public:
+    static other_error create(int id_, const std::string& what_arg)
+    {
+        std::string w = exception::name("other_error", id_) + what_arg;
+        return other_error(id_, w.c_str());
+    }
+
+  private:
+    JSON_HEDLEY_NON_NULL(3)
+    other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
+};
+}  // namespace detail
+}  // namespace nlohmann
+
+// #include <nlohmann/detail/macro_scope.hpp>
+
+// #include <nlohmann/detail/meta/cpp_future.hpp>
+
+
+#include <cstddef> // size_t
+#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
+
+namespace nlohmann
+{
+namespace detail
+{
+// alias templates to reduce boilerplate
+template<bool B, typename T = void>
+using enable_if_t = typename std::enable_if<B, T>::type;
+
+template<typename T>
+using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
+
+// implementation of C++14 index_sequence and affiliates
+// source: https://stackoverflow.com/a/32223343
+template<std::size_t... Ints>
+struct index_sequence
+{
+    using type = index_sequence;
+    using value_type = std::size_t;
+    static constexpr std::size_t size() noexcept
+    {
+        return sizeof...(Ints);
+    }
+};
+
+template<class Sequence1, class Sequence2>
+struct merge_and_renumber;
+
+template<std::size_t... I1, std::size_t... I2>
+struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
+        : index_sequence < I1..., (sizeof...(I1) + I2)... > {};
+
+template<std::size_t N>
+struct make_index_sequence
+    : merge_and_renumber < typename make_index_sequence < N / 2 >::type,
+      typename make_index_sequence < N - N / 2 >::type > {};
+
+template<> struct make_index_sequence<0> : index_sequence<> {};
+template<> struct make_index_sequence<1> : index_sequence<0> {};
+
+template<typename... Ts>
+using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
+
+// dispatch utility (taken from ranges-v3)
+template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
+template<> struct priority_tag<0> {};
+
+// taken from ranges-v3
+template<typename T>
+struct static_const
+{
+    static constexpr T value{};
+};
+
+template<typename T>
+constexpr T static_const<T>::value;
+}  // namespace detail
+}  // namespace nlohmann
+
+// #include <nlohmann/detail/meta/type_traits.hpp>
+
+
+#include <limits> // numeric_limits
+#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
+#include <utility> // declval
+
+// #include <nlohmann/detail/iterators/iterator_traits.hpp>
+
+
+#include <iterator> // random_access_iterator_tag
+
+// #include <nlohmann/detail/meta/void_t.hpp>
+
+
+namespace nlohmann
+{
+namespace detail
+{
+template<typename ...Ts> struct make_void
+{
+    using type = void;
+};
+template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
+} // namespace detail
+}  // namespace nlohmann
+
+// #include <nlohmann/detail/meta/cpp_future.hpp>
+
+
+namespace nlohmann
+{
+namespace detail
+{
+template<typename It, typename = void>
+struct iterator_types {};
+
+template<typename It>
+struct iterator_types <
+    It,
+    void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
+    typename It::reference, typename It::iterator_category >>
+{
+    using difference_type = typename It::difference_type;
+    using value_type = typename It::value_type;
+    using pointer = typename It::pointer;
+    using reference = typename It::reference;
+    using iterator_category = typename It::iterator_category;
+};
+
+// This is required as some compilers implement std::iterator_traits in a way that
+// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
+template<typename T, typename = void>
+struct iterator_traits
+{
+};
+
+template<typename T>
+struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
+            : iterator_types<T>
+{
+};
+
+template<typename T>
+struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
+{
+    using iterator_category = std::random_access_iterator_tag;
+    using value_type = T;
+    using difference_type = ptrdiff_t;
+    using pointer = T*;
+    using reference = T&;
+};
+} // namespace detail
+} // namespace nlohmann
+
+// #include <nlohmann/detail/macro_scope.hpp>
+
+// #include <nlohmann/detail/meta/cpp_future.hpp>
+
+// #include <nlohmann/detail/meta/detected.hpp>
+
+
+#include <type_traits>
+
+// #include <nlohmann/detail/meta/void_t.hpp>
+
+
+// https://en.cppreference.com/w/cpp/experimental/is_detected
+namespace nlohmann
+{
+namespace detail
+{
+struct nonesuch
+{
+    nonesuch() = delete;
+    ~nonesuch() = delete;
+    nonesuch(nonesuch const&) = delete;
+    nonesuch(nonesuch const&&) = delete;
+    void operator=(nonesuch const&) = delete;
+    void operator=(nonesuch&&) = delete;
+};
+
+template<class Default,
+         class AlwaysVoid,
+         template<class...> class Op,
+         class... Args>
+struct detector
+{
+    using value_t = std::false_type;
+    using type = Default;
+};
+
+template<class Default, template<class...> class Op, class... Args>
+struct detector<Default, void_t<Op<Args...>>, Op, Args...>
+{
+    using value_t = std::true_type;
+    using type = Op<Args...>;
+};
+
+template<template<class...> class Op, class... Args>
+using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
+
+template<template<class...> class Op, class... Args>
+using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
+
+template<class Default, template<class...> class Op, class... Args>
+using detected_or = detector<Default, void, Op, Args...>;
+
+template<class Default, template<class...> class Op, class... Args>
+using detected_or_t = typename detected_or<Default, Op, Args...>::type;
+
+template<class Expected, template<class...> class Op, class... Args>
+using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
+
+template<class To, template<class...> class Op, class... Args>
+using is_detected_convertible =
+    std::is_convertible<detected_t<Op, Args...>, To>;
+}  // namespace detail
+}  // namespace nlohmann
+
+// #include <nlohmann/json_fwd.hpp>
+#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
+#define INCLUDE_NLOHMANN_JSON_FWD_HPP_
+
+#include <cstdint> // int64_t, uint64_t
+#include <map> // map
+#include <memory> // allocator
+#include <string> // string
+#include <vector> // vector
+
+/*!
+@brief namespace for Niels Lohmann
+@see https://github.com/nlohmann
+@since version 1.0.0
+*/
+namespace nlohmann
+{
+/*!
+@brief default JSONSerializer template argument
+
+This serializer ignores the template arguments and uses ADL
+([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))
+for serialization.
+*/
+template<typename T = void, typename SFINAE = void>
+struct adl_serializer;
+
+template<template<typename U, typename V, typename... Args> class ObjectType =
+         std::map,
+         template<typename U, typename... Args> class ArrayType = std::vector,
+         class StringType = std::string, class BooleanType = bool,
+         class NumberIntegerType = std::int64_t,
+         class NumberUnsignedType = std::uint64_t,
+         class NumberFloatType = double,
+         template<typename U> class AllocatorType = std::allocator,
+         template<typename T, typename SFINAE = void> class JSONSerializer =
+         adl_serializer,
+         class BinaryType = std::vector<std::uint8_t>>
+class basic_json;
+
+/*!
+@brief JSON Pointer
+
+A JSON pointer defines a string syntax for identifying a specific value
+within a JSON document. It can be used with functions `at` and
+`operator[]`. Furthermore, JSON pointers are the base for JSON patches.
+
+@sa [RFC 6901](https://tools.ietf.org/html/rfc6901)
+
+@since version 2.0.0
+*/
+template<typename BasicJsonType>
+class json_pointer;
+
+/*!
+@brief default JSON class
+
+This type is the default specialization of the @ref basic_json class which
+uses the standard template types.
+
+@since version 1.0.0
+*/
+using json = basic_json<>;
+
+template<class Key, class T, class IgnoredLess, class Allocator>
+struct ordered_map;
+
+/*!
+@brief ordered JSON class
+
+This type preserves the insertion order of object keys.
+
+@since version 3.9.0
+*/
+using ordered_json = basic_json<nlohmann::ordered_map>;
+
+}  // namespace nlohmann
+
+#endif  // INCLUDE_NLOHMANN_JSON_FWD_HPP_
+
+
+namespace nlohmann
+{
+/*!
+@brief detail namespace with internal helper functions
+
+This namespace collects functions that should not be exposed,
+implementations of some @ref basic_json methods, and meta-programming helpers.
+
+@since version 2.1.0
+*/
+namespace detail
+{
+/////////////
+// helpers //
+/////////////
+
+// Note to maintainers:
+//
+// Every trait in this file expects a non CV-qualified type.
+// The only exceptions are in the 'aliases for detected' section
+// (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
+//
+// In this case, T has to be properly CV-qualified to constraint the function arguments
+// (e.g. to_json(BasicJsonType&, const T&))
+
+template<typename> struct is_basic_json : std::false_type {};
+
+NLOHMANN_BASIC_JSON_TPL_DECLARATION
+struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
+
+//////////////////////
+// json_ref helpers //
+//////////////////////
+
+template<typename>
+class json_ref;
+
+template<typename>
+struct is_json_ref : std::false_type {};
+
+template<typename T>
+struct is_json_ref<json_ref<T>> : std::true_type {};
+
+//////////////////////////
+// aliases for detected //
+//////////////////////////
+
+template<typename T>
+using mapped_type_t = typename T::mapped_type;
+
+template<typename T>
+using key_type_t = typename T::key_type;
+
+template<typename T>
+using value_type_t = typename T::value_type;
+
+template<typename T>
+using difference_type_t = typename T::difference_type;
+
+template<typename T>
+using pointer_t = typename T::pointer;
+
+template<typename T>
+using reference_t = typename T::reference;
+
+template<typename T>
+using iterator_category_t = typename T::iterator_category;
+
+template<typename T>
+using iterator_t = typename T::iterator;
+
+template<typename T, typename... Args>
+using to_json_function = decltype(T::to_json(std::declval<Args>()...));
+
+template<typename T, typename... Args>
+using from_json_function = decltype(T::from_json(std::declval<Args>()...));
+
+template<typename T, typename U>
+using get_template_function = decltype(std::declval<T>().template get<U>());
+
+// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
+template<typename BasicJsonType, typename T, typename = void>
+struct has_from_json : std::false_type {};
+
+// trait checking if j.get<T> is valid
+// use this trait instead of std::is_constructible or std::is_convertible,
+// both rely on, or make use of implicit conversions, and thus fail when T
+// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
+template <typename BasicJsonType, typename T>
+struct is_getable
+{
+    static constexpr bool value = is_detected<get_template_function, const BasicJsonType&, T>::value;
+};
+
+template<typename BasicJsonType, typename T>
+struct has_from_json < BasicJsonType, T,
+           enable_if_t < !is_basic_json<T>::value >>
+{
+    using serializer = typename BasicJsonType::template json_serializer<T, void>;
+
+    static constexpr bool value =
+        is_detected_exact<void, from_json_function, serializer,
+        const BasicJsonType&, T&>::value;
+};
+
+// This trait checks if JSONSerializer<T>::from_json(json const&) exists
+// this overload is used for non-default-constructible user-defined-types
+template<typename BasicJsonType, typename T, typename = void>
+struct has_non_default_from_json : std::false_type {};
+
+template<typename BasicJsonType, typename T>
+struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
+{
+    using serializer = typename BasicJsonType::template json_serializer<T, void>;
+
+    static constexpr bool value =
+        is_detected_exact<T, from_json_function, serializer,
+        const BasicJsonType&>::value;
+};
+
+// This trait checks if BasicJsonType::json_serializer<T>::to_json exists
+// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
+template<typename BasicJsonType, typename T, typename = void>
+struct has_to_json : std::false_type {};
+
+template<typename BasicJsonType, typename T>
+struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
+{
+    using serializer = typename BasicJsonType::template json_serializer<T, void>;
+
+    static constexpr bool value =
+        is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
+        T>::value;
+};
+
+
+///////////////////
+// is_ functions //
+///////////////////
+
+template<typename T, typename = void>
+struct is_iterator_traits : std::false_type {};
+
+template<typename T>
+struct is_iterator_traits<iterator_traits<T>>
+{
+  private:
+    using traits = iterator_traits<T>;
+
+  public:
+    static constexpr auto value =
+        is_detected<value_type_t, traits>::value &&
+        is_detected<difference_type_t, traits>::value &&
+        is_detected<pointer_t, traits>::value &&
+        is_detected<iterator_category_t, traits>::value &&
+        is_detected<reference_t, traits>::value;
+};
+
+// source: https://stackoverflow.com/a/37193089/4116453
+
+template<typename T, typename = void>
+struct is_complete_type : std::false_type {};
+
+template<typename T>
+struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
+
+template<typename BasicJsonType, typename CompatibleObjectType,
+         typename = void>
+struct is_compatible_object_type_impl : std::false_type {};
+
+template<typename BasicJsonType, typename CompatibleObjectType>
+struct is_compatible_object_type_impl <
+    BasicJsonType, CompatibleObjectType,
+    enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
+    is_detected<key_type_t, CompatibleObjectType>::value >>
+{
+
+    using object_t = typename BasicJsonType::object_t;
+
+    // macOS's is_constructible does not play well with nonesuch...
+    static constexpr bool value =
+        std::is_constructible<typename object_t::key_type,
+        typename CompatibleObjectType::key_type>::value &&
+        std::is_constructible<typename object_t::mapped_type,
+        typename CompatibleObjectType::mapped_type>::value;
+};
+
+template<typename BasicJsonType, typename CompatibleObjectType>
+struct is_compatible_object_type
+    : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
+
+template<typename BasicJsonType, typename ConstructibleObjectType,
+         typename = void>
+struct is_constructible_object_type_impl : std::false_type {};
+
+template<typename BasicJsonType, typename ConstructibleObjectType>
+struct is_constructible_object_type_impl <
+    BasicJsonType, ConstructibleObjectType,
+    enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
+    is_detected<key_type_t, ConstructibleObjectType>::value >>
+{
+    using object_t = typename BasicJsonType::object_t;
+
+    static constexpr bool value =
+        (std::is_default_constructible<ConstructibleObjectType>::value &&
+         (std::is_move_assignable<ConstructibleObjectType>::value ||
+          std::is_copy_assignable<ConstructibleObjectType>::value) &&
+         (std::is_constructible<typename ConstructibleObjectType::key_type,
+          typename object_t::key_type>::value &&
+          std::is_same <
+          typename object_t::mapped_type,
+          typename ConstructibleObjectType::mapped_type >::value)) ||
+        (has_from_json<BasicJsonType,
+         typename ConstructibleObjectType::mapped_type>::value ||
+         has_non_default_from_json <
+         BasicJsonType,
+         typename ConstructibleObjectType::mapped_type >::value);
+};
+
+template<typename BasicJsonType, typename ConstructibleObjectType>
+struct is_constructible_object_type
+    : is_constructible_object_type_impl<BasicJsonType,
+      ConstructibleObjectType> {};
+
+template<typename BasicJsonType, typename CompatibleStringType,
+         typename = void>
+struct is_compatible_string_type_impl : std::false_type {};
+
+template<typename BasicJsonType, typename CompatibleStringType>
+struct is_compatible_string_type_impl <
+    BasicJsonType, CompatibleStringType,
+    enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
+    value_type_t, CompatibleStringType>::value >>
+{
+    static constexpr auto value =
+        std::is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
+};
+
+template<typename BasicJsonType, typename ConstructibleStringType>
+struct is_compatible_string_type
+    : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
+
+template<typename BasicJsonType, typename ConstructibleStringType,
+         typename = void>
+struct is_constructible_string_type_impl : std::false_type {};
+
+template<typename BasicJsonType, typename ConstructibleStringType>
+struct is_constructible_string_type_impl <
+    BasicJsonType, ConstructibleStringType,
+    enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
+    value_type_t, ConstructibleStringType>::value >>
+{
+    static constexpr auto value =
+        std::is_constructible<ConstructibleStringType,
+        typename BasicJsonType::string_t>::value;
+};
+
+template<typename BasicJsonType, typename ConstructibleStringType>
+struct is_constructible_string_type
+    : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
+
+template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
+struct is_compatible_array_type_impl : std::false_type {};
+
+template<typename BasicJsonType, typename CompatibleArrayType>
+struct is_compatible_array_type_impl <
+    BasicJsonType, CompatibleArrayType,
+    enable_if_t < is_detected<value_type_t, CompatibleArrayType>::value&&
+    is_detected<iterator_t, CompatibleArrayType>::value&&
+// This is needed because json_reverse_iterator has a ::iterator type...
+// Therefore it is detected as a CompatibleArrayType.
+// The real fix would be to have an Iterable concept.
+    !is_iterator_traits <
+    iterator_traits<CompatibleArrayType >>::value >>
+{
+    static constexpr bool value =
+        std::is_constructible<BasicJsonType,
+        typename CompatibleArrayType::value_type>::value;
+};
+
+template<typename BasicJsonType, typename CompatibleArrayType>
+struct is_compatible_array_type
+    : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
+
+template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
+struct is_constructible_array_type_impl : std::false_type {};
+
+template<typename BasicJsonType, typename ConstructibleArrayType>
+struct is_constructible_array_type_impl <
+    BasicJsonType, ConstructibleArrayType,
+    enable_if_t<std::is_same<ConstructibleArrayType,
+    typename BasicJsonType::value_type>::value >>
+            : std::true_type {};
+
+template<typename BasicJsonType, typename ConstructibleArrayType>
+struct is_constructible_array_type_impl <
+    BasicJsonType, ConstructibleArrayType,
+    enable_if_t < !std::is_same<ConstructibleArrayType,
+    typename BasicJsonType::value_type>::value&&
+    std::is_default_constructible<ConstructibleArrayType>::value&&
+(std::is_move_assignable<ConstructibleArrayType>::value ||
+ std::is_copy_assignable<ConstructibleArrayType>::value)&&
+is_detected<value_type_t, ConstructibleArrayType>::value&&
+is_detected<iterator_t, ConstructibleArrayType>::value&&
+is_complete_type <
+detected_t<value_type_t, ConstructibleArrayType >>::value >>
+{
+    static constexpr bool value =
+        // This is needed because json_reverse_iterator has a ::iterator type,
+        // furthermore, std::back_insert_iterator (and other iterators) have a
+        // base class `iterator`... Therefore it is detected as a
+        // ConstructibleArrayType. The real fix would be to have an Iterable
+        // concept.
+        !is_iterator_traits<iterator_traits<ConstructibleArrayType>>::value &&
+
+        (std::is_same<typename ConstructibleArrayType::value_type,
+         typename BasicJsonType::array_t::value_type>::value ||
+         has_from_json<BasicJsonType,
+         typename ConstructibleArrayType::value_type>::value ||
+         has_non_default_from_json <
+         BasicJsonType, typename ConstructibleArrayType::value_type >::value);
+};
+
+template<typename BasicJsonType, typename ConstructibleArrayType>
+struct is_constructible_array_type
+    : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
+
+template<typename RealIntegerType, typename CompatibleNumberIntegerType,
+         typename = void>
+struct is_compatible_integer_type_impl : std::false_type {};
+
+template<typename RealIntegerType, typename CompatibleNumberIntegerType>
+struct is_compatible_integer_type_impl <
+    RealIntegerType, CompatibleNumberIntegerType,
+    enable_if_t < std::is_integral<RealIntegerType>::value&&
+    std::is_integral<CompatibleNumberIntegerType>::value&&
+    !std::is_same<bool, CompatibleNumberIntegerType>::value >>
+{
+    // is there an assert somewhere on overflows?
+    using RealLimits = std::numeric_limits<RealIntegerType>;
+    using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
+
+    static constexpr auto value =
+        std::is_constructible<RealIntegerType,
+        CompatibleNumberIntegerType>::value &&
+        CompatibleLimits::is_integer &&
+        RealLimits::is_signed == CompatibleLimits::is_signed;
+};
+
+template<typename RealIntegerType, typename CompatibleNumberIntegerType>
+struct is_compatible_integer_type
+    : is_compatible_integer_type_impl<RealIntegerType,
+      CompatibleNumberIntegerType> {};
+
+template<typename BasicJsonType, typename CompatibleType, typename = void>
+struct is_compatible_type_impl: std::false_type {};
+
+template<typename BasicJsonType, typename CompatibleType>
+struct is_compatible_type_impl <
+    BasicJsonType, CompatibleType,
+    enable_if_t<is_complete_type<CompatibleType>::value >>
+{
+    static constexpr bool value =
+        has_to_json<BasicJsonType, CompatibleType>::value;
+};
+
+template<typename BasicJsonType, typename CompatibleType>
+struct is_compatible_type
+    : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
+
+// https://en.cppreference.com/w/cpp/types/conjunction
+template<class...> struct conjunction : std::true_type { };
+template<class B1> struct conjunction<B1> : B1 { };
+template<class B1, class... Bn>
+struct conjunction<B1, Bn...>
+: std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
+
+template<typename T1, typename T2>
+struct is_constructible_tuple : std::false_type {};
+
+template<typename T1, typename... Args>
+struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<std::is_constructible<T1, Args>...> {};
+}  // namespace detail
+}  // namespace nlohmann
+
+// #include <nlohmann/detail/value_t.hpp>
+
+
+#include <array> // array
+#include <cstddef> // size_t
+#include <cstdint> // uint8_t
+#include <string> // string
+
+namespace nlohmann
+{
+namespace detail
+{
+///////////////////////////
+// JSON type enumeration //
+///////////////////////////
+
+/*!
+@brief the JSON type enumeration
+
+This enumeration collects the different JSON types. It is internally used to
+distinguish the stored values, and the functions @ref basic_json::is_null(),
+@ref basic_json::is_object(), @ref basic_json::is_array(),
+@ref basic_json::is_string(), @ref basic_json::is_boolean(),
+@ref basic_json::is_number() (with @ref basic_json::is_number_integer(),
+@ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),
+@ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and
+@ref basic_json::is_structured() rely on it.
+
+@note There are three enumeration entries (number_integer, number_unsigned, and
+number_float), because the library distinguishes these three types for numbers:
+@ref basic_json::number_unsigned_t is used for unsigned integers,
+@ref basic_json::number_integer_t is used for signed integers, and
+@ref basic_json::number_float_t is used for floating-point numbers or to
+approximate integers which do not fit in the limits of their respective type.
+
+@sa @ref basic_json::basic_json(const value_t value_type) -- create a JSON
+value with the default value for a given type
+
+@since version 1.0.0
+*/
+enum class value_t : std::uint8_t
+{
+    null,             ///< null value
+    object,           ///< object (unordered set of name/value pairs)
+    array,            ///< array (ordered collection of values)
+    string,           ///< string value
+    boolean,          ///< boolean value
+    number_integer,   ///< number value (signed integer)
+    number_unsigned,  ///< number value (unsigned integer)
+    number_float,     ///< number value (floating-point)
+    binary,           ///< binary array (ordered collection of bytes)
+    discarded         ///< discarded by the parser callback function
+};
+
+/*!
+@brief comparison operator for JSON types
+
+Returns an ordering that is similar to Python:
+- order: null < boolean < number < object < array < string < binary
+- furthermore, each type is not smaller than itself
+- discarded values are not comparable
+- binary is represented as a b"" string in python and directly comparable to a
+  string; however, making a binary array directly comparable with a string would
+  be surprising behavior in a JSON file.
+
+@since version 1.0.0
+*/
+inline bool operator<(const value_t lhs, const value_t rhs) noexcept
+{
+    static constexpr std::array<std::uint8_t, 9> order = {{
+            0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
+            1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
+            6 /* binary */
+        }
+    };
+
+    const auto l_index = static_cast<std::size_t>(lhs);
+    const auto r_index = static_cast<std::size_t>(rhs);
+    return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
+}
+}  // namespace detail
+}  // namespace nlohmann
+
+
+namespace nlohmann
+{
+namespace detail
+{
+template<typename BasicJsonType>
+void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
+{
+    if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
+    {
+        JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name())));
+    }
+    n = nullptr;
+}
+
+// overloads for basic_json template parameters
+template < typename BasicJsonType, typename ArithmeticType,
+           enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
+                         !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
+                         int > = 0 >
+void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
+{
+    switch (static_cast<value_t>(j))
+    {
+        case value_t::number_unsigned:
+        {
+            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
+            break;
+        }
+        case value_t::number_integer:
+        {
+            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
+            break;
+        }
+        case value_t::number_float:
+        {
+            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
+            break;
+        }
+
+        default:
+            JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
+    }
+}
+
+template<typename BasicJsonType>
+void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
+{
+    if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
+    {
+        JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
+    }
+    b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
+}
+
+template<typename BasicJsonType>
+void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
+{
+    if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
+    {
+        JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
+    }
+    s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
+}
+
+template <
+    typename BasicJsonType, typename ConstructibleStringType,
+    enable_if_t <
+        is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value&&
+        !std::is_same<typename BasicJsonType::string_t,
+                      ConstructibleStringType>::value,
+        int > = 0 >
+void from_json(const BasicJsonType& j, ConstructibleStringType& s)
+{
+    if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
+    {
+        JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
+    }
+
+    s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
+}
+
+template<typename BasicJsonType>
+void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
+{
+    get_arithmetic_value(j, val);
+}
+
+template<typename BasicJsonType>
+void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
+{
+    get_arithmetic_value(j, val);
+}
+
+template<typename BasicJsonType>
+void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
+{
+    get_arithmetic_value(j, val);
+}
+
+template<typename BasicJsonType, typename EnumType,
+         enable_if_t<std::is_enum<EnumType>::value, int> = 0>
+void from_json(const BasicJsonType& j, EnumType& e)
+{
+    typename std::underlying_type<EnumType>::type val;
+    get_arithmetic_value(j, val);
+    e = static_cast<EnumType>(val);
+}
+
+// forward_list doesn't have an insert method
+template<typename BasicJsonType, typename T, typename Allocator,
+         enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
+void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
+{
+    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
+    {
+        JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
+    }
+    l.clear();
+    std::transform(j.rbegin(), j.rend(),
+                   std::front_inserter(l), [](const BasicJsonType & i)
+    {
+        return i.template get<T>();
+    });
+}
+
+// valarray doesn't have an insert method
+template<typename BasicJsonType, typename T,
+         enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
+void from_json(const BasicJsonType& j, std::valarray<T>& l)
+{
+    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
+    {
+        JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
+    }
+    l.resize(j.size());
+    std::transform(j.begin(), j.end(), std::begin(l),
+                   [](const BasicJsonType & elem)
+    {
+        return elem.template get<T>();
+    });
+}
+
+template<typename BasicJsonType, typename T, std::size_t N>
+auto from_json(const BasicJsonType& j, T (&arr)[N])
+-> decltype(j.template get<T>(), void())
+{
+    for (std::size_t i = 0; i < N; ++i)
+    {
+        arr[i] = j.at(i).template get<T>();
+    }
+}
+
+template<typename BasicJsonType>
+void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
+{
+    arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
+}
+
+template<typename BasicJsonType, typename T, std::size_t N>
+auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
+                          priority_tag<2> /*unused*/)
+-> decltype(j.template get<T>(), void())
+{
+    for (std::size_t i = 0; i < N; ++i)
+    {
+        arr[i] = j.at(i).template get<T>();
+    }
+}
+
+template<typename BasicJsonType, typename ConstructibleArrayType>
+auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
+-> decltype(
+    arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
+    j.template get<typename ConstructibleArrayType::value_type>(),
+    void())
+{
+    using std::end;
+
+    ConstructibleArrayType ret;
+    ret.reserve(j.size());
+    std::transform(j.begin(), j.end(),
+                   std::inserter(ret, end(ret)), [](const BasicJsonType & i)
+    {
+        // get<BasicJsonType>() returns *this, this won't call a from_json
+        // method when value_type is BasicJsonType
+        return i.template get<typename ConstructibleArrayType::value_type>();
+    });
+    arr = std::move(ret);
+}
+
+template<typename BasicJsonType, typename ConstructibleArrayType>
+void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
+                          priority_tag<0> /*unused*/)
+{
+    using std::end;
+
+    ConstructibleArrayType ret;
+    std::transform(
+        j.begin(), j.end(), std::inserter(ret, end(ret)),
+        [](const BasicJsonType & i)
+    {
+        // get<BasicJsonType>() returns *this, this won't call a from_json
+        // method when value_type is BasicJsonType
+        return i.template get<typename ConstructibleArrayType::value_type>();
+    });
+    arr = std::move(ret);
+}
+
+template < typename BasicJsonType, typename ConstructibleArrayType,
+           enable_if_t <
+               is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
+               !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
+               !is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
+               !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
+               !is_basic_json<ConstructibleArrayType>::value,
+               int > = 0 >
+auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
+-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
+j.template get<typename ConstructibleArrayType::value_type>(),
+void())
+{
+    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
+    {
+        JSON_THROW(type_error::create(302, "type must be array, but is " +
+                                      std::string(j.type_name())));
+    }
+
+    from_json_array_impl(j, arr, priority_tag<3> {});
+}
+
+template<typename BasicJsonType>
+void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
+{
+    if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
+    {
+        JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name())));
+    }
+
+    bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
+}
+
+template<typename BasicJsonType, typename ConstructibleObjectType,
+         enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
+void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
+{
+    if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
+    {
+        JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
+    }
+
+    ConstructibleObjectType ret;
+    auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
+    using value_type = typename ConstructibleObjectType::value_type;
+    std::transform(
+        inner_object->begin(), inner_object->end(),
+        std::inserter(ret, ret.begin()),
+        [](typename BasicJsonType::object_t::value_type const & p)
+    {
+        return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
+    });
+    obj = std::move(ret);
+}
+
+// overload for arithmetic types, not chosen for basic_json template arguments
+// (BooleanType, etc..); note: Is it really necessary to provide explicit
+// overloads for boolean_t etc. in case of a custom BooleanType which is not
+// an arithmetic type?
+template < typename BasicJsonType, typename ArithmeticType,
+           enable_if_t <
+               std::is_arithmetic<ArithmeticType>::value&&
+               !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
+               !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
+               !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
+               !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
+               int > = 0 >
+void from_json(const BasicJsonType& j, ArithmeticType& val)
+{
+    switch (static_cast<value_t>(j))
+    {
+        case value_t::number_unsigned:
+        {
+            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
+            break;
+        }
+        case value_t::number_integer:
+        {
+            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
+            break;
+        }
+        case value_t::number_float:
+        {
+            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
+            break;
+        }
+        case value_t::boolean:
+        {
+            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
+            break;
+        }
+
+        default:
+            JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
+    }
+}
+
+template<typename BasicJsonType, typename A1, typename A2>
+void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
+{
+    p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
+}
+
+template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
+void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...> /*unused*/)
+{
+    t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
+}
+
+template<typename BasicJsonType, typename... Args>
+void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
+{
+    from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
+}
+
+template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
+           typename = enable_if_t < !std::is_constructible <
+                                        typename BasicJsonType::string_t, Key >::value >>
+void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
+{
+    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
+    {
+        JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
+    }
+    m.clear();
+    for (const auto& p : j)
+    {
+        if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
+        {
+            JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
+        }
+        m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
+    }
+}
+
+template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
+           typename = enable_if_t < !std::is_constructible <
+                                        typename BasicJsonType::string_t, Key >::value >>
+void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
+{
+    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
+    {
+        JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
+    }
+    m.clear();
+    for (const auto& p : j)
+    {
+        if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
+        {
+            JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
+        }
+        m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
+    }
+}
+
+struct from_json_fn
+{
+    template<typename BasicJsonType, typename T>
+    auto operator()(const BasicJsonType& j, T& val) const
+    noexcept(noexcept(from_json(j, val)))
+    -> decltype(from_json(j, val), void())
+    {
+        return from_json(j, val);
+    }
+};
+}  // namespace detail
+
+/// namespace to hold default `from_json` function
+/// to see why this is required:
+/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
+namespace
+{
+constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
+} // namespace
+} // namespace nlohmann
+
+// #include <nlohmann/detail/conversions/to_json.hpp>
+
+
+#include <algorithm> // copy
+#include <iterator> // begin, end
+#include <string> // string
+#include <tuple> // tuple, get
+#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
+#include <utility> // move, forward, declval, pair
+#include <valarray> // valarray
+#include <vector> // vector
+
+// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
+
+
+#include <cstddef> // size_t
+#include <iterator> // input_iterator_tag
+#include <string> // string, to_string
+#include <tuple> // tuple_size, get, tuple_element
+
+// #include <nlohmann/detail/meta/type_traits.hpp>
+
+// #include <nlohmann/detail/value_t.hpp>
+
+
+namespace nlohmann
+{
+namespace detail
+{
+template<typename string_type>
+void int_to_string( string_type& target, std::size_t value )
+{
+    // For ADL
+    using std::to_string;
+    target = to_string(value);
+}
+template<typename IteratorType> class iteration_proxy_value
+{
+  public:
+    using difference_type = std::ptrdiff_t;
+    using value_type = iteration_proxy_value;
+    using pointer = value_type * ;
+    using reference = value_type & ;
+    using iterator_category = std::input_iterator_tag;
+    using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
+
+  private:
+    /// the iterator
+    IteratorType anchor;
+    /// an index for arrays (used to create key names)
+    std::size_t array_index = 0;
+    /// last stringified array index
+    mutable std::size_t array_index_last = 0;
+    /// a string representation of the array index
+    mutable string_type array_index_str = "0";
+    /// an empty string (to return a reference for primitive values)
+    const string_type empty_str = "";
+
+  public:
+    explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}
+
+    /// dereference operator (needed for range-based for)
+    iteration_proxy_value& operator*()
+    {
+        return *this;
+    }
+
+    /// increment operator (needed for range-based for)
+    iteration_proxy_value& operator++()
+    {
+        ++anchor;
+        ++array_index;
+
+        return *this;
+    }
+
+    /// equality operator (needed for InputIterator)
+    bool operator==(const iteration_proxy_value& o) const
+    {
+        return anchor == o.anchor;
+    }
+
+    /// inequality operator (needed for range-based for)
+    bool operator!=(const iteration_proxy_value& o) const
+    {
+        return anchor != o.anchor;
+    }
+
+    /// return key of the iterator
+    const string_type& key() const
+    {
+        JSON_ASSERT(anchor.m_object != nullptr);
+
+        switch (anchor.m_object->type())
+        {
+            // use integer array index as key
+            case value_t::array:
+            {
+                if (array_index != array_index_last)
+                {
+                    int_to_string( array_index_str, array_index );
+                    array_index_last = array_index;
+                }
+                return array_index_str;
+            }
+
+            // use key from the object
+            case value_t::object:
+                return anchor.key();
+
+            // use an empty key for all primitive types
+            default:
+                return empty_str;
+        }
+    }
+
+    /// return value of the iterator
+    typename IteratorType::reference value() const
+    {
+        return anchor.value();
+    }
+};
+
+/// proxy class for the items() function
+template<typename IteratorType> class iteration_proxy
+{
+  private:
+    /// the container to iterate
+    typename IteratorType::reference container;
+
+  public:
+    /// construct iteration proxy from a container
+    explicit iteration_proxy(typename IteratorType::reference cont) noexcept
+        : container(cont) {}
+
+    /// return iterator begin (needed for range-based for)
+    iteration_proxy_value<IteratorType> begin() noexcept
+    {
+        return iteration_proxy_value<IteratorType>(container.begin());
+    }
+
+    /// return iterator end (needed for range-based for)
+    iteration_proxy_value<IteratorType> end() noexcept
+    {
+        return iteration_proxy_value<IteratorType>(container.end());
+    }
+};
+// Structured Bindings Support
+// For further reference see https://blog.tartanllama.xyz/structured-bindings/
+// And see https://github.com/nlohmann/json/pull/1391
+template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
+auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
+{
+    return i.key();
+}
+// Structured Bindings Support
+// For further reference see https://blog.tartanllama.xyz/structured-bindings/
+// And see https://github.com/nlohmann/json/pull/1391
+template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
+auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
+{
+    return i.value();
+}
+}  // namespace detail
+}  // namespace nlohmann
+
+// The Addition to the STD Namespace is required to add
+// Structured Bindings Support to the iteration_proxy_value class
+// For further reference see https://blog.tartanllama.xyz/structured-bindings/
+// And see https://github.com/nlohmann/json/pull/1391
+namespace std
+{
+#if defined(__clang__)
+    // Fix: https://github.com/nlohmann/json/issues/1401
+    #pragma clang diagnostic push
+    #pragma clang diagnostic ignored "-Wmismatched-tags"
+#endif
+template<typename IteratorType>
+class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
+            : public std::integral_constant<std::size_t, 2> {};
+
+template<std::size_t N, typename IteratorType>
+class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
+{
+  public:
+    using type = decltype(
+                     get<N>(std::declval <
+                            ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
+};
+#if defined(__clang__)
+    #pragma clang diagnostic pop
+#endif
+} // namespace std
+
+// #include <nlohmann/detail/meta/cpp_future.hpp>
+
+// #include <nlohmann/detail/meta/type_traits.hpp>
+
+// #include <nlohmann/detail/value_t.hpp>
+
+
+namespace nlohmann
+{
+namespace detail
+{
+//////////////////
+// constructors //
+//////////////////
+
+template<value_t> struct external_constructor;
+
+template<>
+struct external_constructor<value_t::boolean>
+{
+    template<typename BasicJsonType>
+    static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
+    {
+        j.m_type = value_t::boolean;
+        j.m_value = b;
+        j.assert_invariant();
+    }
+};
+
+template<>
+struct external_constructor<value_t::string>
+{
+    template<typename BasicJsonType>
+    static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
+    {
+        j.m_type = value_t::string;
+        j.m_value = s;
+        j.assert_invariant();
+    }
+
+    template<typename BasicJsonType>
+    static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
+    {
+        j.m_type = value_t::string;
+        j.m_value = std::move(s);
+        j.assert_invariant();
+    }
+
+    template < typename BasicJsonType, typename CompatibleStringType,
+               enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
+                             int > = 0 >
+    static void construct(BasicJsonType& j, const CompatibleStringType& str)
+    {
+        j.m_type = value_t::string;
+        j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
+        j.assert_invariant();
+    }
+};
+
+template<>
+struct external_constructor<value_t::binary>
+{
+    template<typename BasicJsonType>
+    static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
+    {
+        j.m_type = value_t::binary;
+        typename BasicJsonType::binary_t value{b};
+        j.m_value = value;
+        j.assert_invariant();
+    }
+
+    template<typename BasicJsonType>
+    static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
+    {
+        j.m_type = value_t::binary;
+        typename BasicJsonType::binary_t value{std::move(b)};
+        j.m_value = value;
+        j.assert_invariant();
+    }
+};
+
+template<>
+struct external_constructor<value_t::number_float>
+{
+    template<typename BasicJsonType>
+    static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
+    {
+        j.m_type = value_t::number_float;
+        j.m_value = val;
+        j.assert_invariant();
+    }
+};
+
+template<>
+struct external_constructor<value_t::number_unsigned>
+{
+    template<typename BasicJsonType>
+    static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
+    {
+        j.m_type = value_t::number_unsigned;
+        j.m_value = val;
+        j.assert_invariant();
+    }
+};
+
+template<>
+struct external_constructor<value_t::number_integer>
+{
+    template<typename BasicJsonType>
+    static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
+    {
+        j.m_type = value_t::number_integer;
+        j.m_value = val;
+        j.assert_invariant();
+    }
+};
+
+template<>
+struct external_constructor<value_t::array>
+{
+    template<typename BasicJsonType>
+    static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
+    {
+        j.m_type = value_t::array;
+        j.m_value = arr;
+        j.assert_invariant();
+    }
+
+    template<typename BasicJsonType>
+    static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
+    {
+        j.m_type = value_t::array;
+        j.m_value = std::move(arr);
+        j.assert_invariant();
+    }
+
+    template < typename BasicJsonType, typename CompatibleArrayType,
+               enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
+                             int > = 0 >
+    static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
+    {
+        using std::begin;
+        using std::end;
+        j.m_type = value_t::array;
+        j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
+        j.assert_invariant();
+    }
+
+    template<typename BasicJsonType>
+    static void construct(BasicJsonType& j, const std::vector<bool>& arr)
+    {
+        j.m_type = value_t::array;
+        j.m_value = value_t::array;
+        j.m_value.array->reserve(arr.size());
+        for (const bool x : arr)
+        {
+            j.m_value.array->push_back(x);
+        }
+        j.assert_invariant();
+    }
+
+    template<typename BasicJsonType, typename T,
+             enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
+    static void construct(BasicJsonType& j, const std::valarray<T>& arr)
+    {
+        j.m_type = value_t::array;
+        j.m_value = value_t::array;
+        j.m_value.array->resize(arr.size());
+        if (arr.size() > 0)
+        {
+            std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
+        }
+        j.assert_invariant();
+    }
+};
+
+template<>
+struct external_constructor<value_t::object>
+{
+    template<typename BasicJsonType>
+    static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
+    {
+        j.m_type = value_t::object;
+        j.m_value = obj;
+        j.assert_invariant();
+    }
+
+    template<typename BasicJsonType>
+    static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
+    {
+        j.m_type = value_t::object;
+        j.m_value = std::move(obj);
+        j.assert_invariant();
+    }
+
+    template < typename BasicJsonType, typename CompatibleObjectType,
+               enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >
+    static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
+    {
+        using std::begin;
+        using std::end;
+
+        j.m_type = value_t::object;
+        j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
+        j.assert_invariant();
+    }
+};
+
+/////////////
+// to_json //
+/////////////
+
+template<typename BasicJsonType, typename T,
+         enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
+void to_json(BasicJsonType& j, T b) noexcept
+{
+    external_constructor<value_t::boolean>::construct(j, b);
+}
+
+template<typename BasicJsonType, typename CompatibleString,
+         enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
+void to_json(BasicJsonType& j, const CompatibleString& s)
+{
+    external_constructor<value_t::string>::construct(j, s);
+}
+
+template<typename BasicJsonType>
+void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
+{
+    external_constructor<value_t::string>::construct(j, std::move(s));
+}
+
+template<typename BasicJsonType, typename FloatType,
+         enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
+void to_json(BasicJsonType& j, FloatType val) noexcept
+{
+    external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
+}
+
+template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
+         enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
+void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
+{
+    external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
+}
+
+template<typename BasicJsonType, typename CompatibleNumberIntegerType,
+         enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
+void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
+{
+    external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
+}
+
+template<typename BasicJsonType, typename EnumType,
+         enable_if_t<std::is_enum<EnumType>::value, int> = 0>
+void to_json(BasicJsonType& j, EnumType e) noexcept
+{
+    using underlying_type = typename std::underlying_type<EnumType>::type;
+    external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
+}
+
+template<typename BasicJsonType>
+void to_json(BasicJsonType& j, const std::vector<bool>& e)
+{
+    external_constructor<value_t::array>::construct(j, e);
+}
+
+template < typename BasicJsonType, typename CompatibleArrayType,
+           enable_if_t < is_compatible_array_type<BasicJsonType,
+                         CompatibleArrayType>::value&&
+                         !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
+                         !is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value&&
+                         !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
+                         !is_basic_json<CompatibleArrayType>::value,
+                         int > = 0 >
+void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
+{
+    external_constructor<value_t::array>::construct(j, arr);
+}
+
+template<typename BasicJsonType>
+void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
+{
+    external_constructor<value_t::binary>::construct(j, bin);
+}
+
+template<typename BasicJsonType, typename T,
+         enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
+void to_json(BasicJsonType& j, const std::valarray<T>& arr)
+{
+    external_constructor<value_t::array>::construct(j, std::move(arr));
+}
+
+template<typename BasicJsonType>
+void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
+{
+    external_constructor<value_t::array>::construct(j, std::move(arr));
+}
+
+template < typename BasicJsonType, typename CompatibleObjectType,
+           enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
+void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
+{
+    external_constructor<value_t::object>::construct(j, obj);
+}
+
+template<typename BasicJsonType>
+void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
+{
+    external_constructor<value_t::object>::construct(j, std::move(obj));
+}
+
+template <
+    typename BasicJsonType, typename T, std::size_t N,
+    enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
+                  const T(&)[N]>::value,
+                  int > = 0 >
+void to_json(BasicJsonType& j, const T(&arr)[N])
+{
+    external_constructor<value_t::array>::construct(j, arr);
+}
+
+template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
+void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
+{
+    j = { p.first, p.second };
+}
+
+// for https://github.com/nlohmann/json/pull/1134
+template<typename BasicJsonType, typename T,
+         enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
+void to_json(BasicJsonType& j, const T& b)
+{
+    j = { {b.key(), b.value()} };
+}
+
+template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
+void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
+{
+    j = { std::get<Idx>(t)... };
+}
+
+template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
+void to_json(BasicJsonType& j, const T& t)
+{
+    to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
+}
+
+struct to_json_fn
+{
+    template<typename BasicJsonType, typename T>
+    auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
+    -> decltype(to_json(j, std::forward<T>(val)), void())
+    {
+        return to_json(j, std::forward<T>(val));
+    }
+};
+}  // namespace detail
+
+/// namespace to hold default `to_json` function
+namespace
+{
+constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
+} // namespace
+} // namespace nlohmann
+
+
+namespace nlohmann
+{
+
+template<typename, typename>
+struct adl_serializer
+{
+    /*!
+    @brief convert a JSON value to any value type
+
+    This function is usually called by the `get()` function of the
+    @ref basic_json class (either explicit or via conversion operators).
+
+    @param[in] j        JSON value to read from
+    @param[in,out] val  value to write to
+    */
+    template<typename BasicJsonType, typename ValueType>
+    static auto from_json(BasicJsonType&& j, ValueType& val) noexcept(
+        noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
+    -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
+    {
+        ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
+    }
+
+    /*!
+    @brief convert any value type to a JSON value
+
+    This function is usually called by the constructors of the @ref basic_json
+    class.
+
+    @param[in,out] j  JSON value to write to
+    @param[in] val    value to read from
+    */
+    template<typename BasicJsonType, typename ValueType>
+    static auto to_json(BasicJsonType& j, ValueType&& val) noexcept(
+        noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
+    -> decltype(::nlohmann::to_json(j, std::forward<ValueType>(val)), void())
+    {
+        ::nlohmann::to_json(j, std::forward<ValueType>(val));
+    }
+};
+
+}  // namespace nlohmann
+
+// #include <nlohmann/byte_container_with_subtype.hpp>
+
+
+#include <cstdint> // uint8_t
+#include <tuple> // tie
+#include <utility> // move
+
+namespace nlohmann
+{
+
+/*!
+@brief an internal type for a backed binary type
+
+This type extends the template parameter @a BinaryType provided to `basic_json`
+with a subtype used by BSON and MessagePack. This type exists so that the user
+does not have to specify a type themselves with a specific naming scheme in
+order to override the binary type.
+
+@tparam BinaryType container to store bytes (`std::vector<std::uint8_t>` by
+                   default)
+
+@since version 3.8.0
+*/
+template<typename BinaryType>
+class byte_container_with_subtype : public BinaryType
+{
+  public:
+    /// the type of the underlying container
+    using container_type = BinaryType;
+
+    byte_container_with_subtype() noexcept(noexcept(container_type()))
+        : container_type()
+    {}
+
+    byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b)))
+        : container_type(b)
+    {}
+
+    byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
+        : container_type(std::move(b))
+    {}
+
+    byte_container_with_subtype(const container_type& b, std::uint8_t subtype) noexcept(noexcept(container_type(b)))
+        : container_type(b)
+        , m_subtype(subtype)
+        , m_has_subtype(true)
+    {}
+
+    byte_container_with_subtype(container_type&& b, std::uint8_t subtype) noexcept(noexcept(container_type(std::move(b))))
+        : container_type(std::move(b))
+        , m_subtype(subtype)
+        , m_has_subtype(true)
+    {}
+
+    bool operator==(const byte_container_with_subtype& rhs) const
+    {
+        return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
+               std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
+    }
+
+    bool operator!=(const byte_container_with_subtype& rhs) const
+    {
+        return !(rhs == *this);
+    }
+
+    /*!
+    @brief sets the binary subtype
+
+    Sets the binary subtype of the value, also flags a binary JSON value as
+    having a subtype, which has implications for serialization.
+
+    @complexity Constant.
+
+    @exceptionsafety No-throw guarantee: this member function never throws
+    exceptions.
+
+    @sa @ref subtype() -- return the binary subtype
+    @sa @ref clear_subtype() -- clears the binary subtype
+    @sa @ref has_subtype() -- returns whether or not the binary value has a
+    subtype
+
+    @since version 3.8.0
+    */
+    void set_subtype(std::uint8_t subtype) noexcept
+    {
+        m_subtype = subtype;
+        m_has_subtype = true;
+    }
+
+    /*!
+    @brief return the binary subtype
+
+    Returns the numerical subtype of the value if it has a subtype. If it does
+    not have a subtype, this function will return size_t(-1) as a sentinel
+    value.
+
+    @return the numerical subtype of the binary value
+
+    @complexity Constant.
+
+    @exceptionsafety No-throw guarantee: this member function never throws
+    exceptions.
+
+    @sa @ref set_subtype() -- sets the binary subtype
+    @sa @ref clear_subtype() -- clears the binary subtype
+    @sa @ref has_subtype() -- returns whether or not the binary value has a
+    subtype
+
+    @since version 3.8.0
+    */
+    constexpr std::uint8_t subtype() const noexcept
+    {
+        return m_subtype;
+    }
+
+    /*!
+    @brief return whether the value has a subtype
+
+    @return whether the value has a subtype
+
+    @complexity Constant.
+
+    @exceptionsafety No-throw guarantee: this member function never throws
+    exceptions.
+
+    @sa @ref subtype() -- return the binary subtype
+    @sa @ref set_subtype() -- sets the binary subtype
+    @sa @ref clear_subtype() -- clears the binary subtype
+
+    @since version 3.8.0
+    */
+    constexpr bool has_subtype() const noexcept
+    {
+        return m_has_subtype;
+    }
+
+    /*!
+    @brief clears the binary subtype
+
+    Clears the binary subtype and flags the value as not having a subtype, which
+    has implications for serialization; for instance MessagePack will prefer the
+    bin family over the ext family.
+
+    @complexity Constant.
+
+    @exceptionsafety No-throw guarantee: this member function never throws
+    exceptions.
+
+    @sa @ref subtype() -- return the binary subtype
+    @sa @ref set_subtype() -- sets the binary subtype
+    @sa @ref has_subtype() -- returns whether or not the binary value has a
+    subtype
+
+    @since version 3.8.0
+    */
+    void clear_subtype() noexcept
+    {
+        m_subtype = 0;
+        m_has_subtype = false;
+    }
+
+  private:
+    std::uint8_t m_subtype = 0;
+    bool m_has_subtype = false;
+};
+
+}  // namespace nlohmann
+
+// #include <nlohmann/detail/conversions/from_json.hpp>
+
+// #include <nlohmann/detail/conversions/to_json.hpp>
+
+// #include <nlohmann/detail/exceptions.hpp>
+
+// #include <nlohmann/detail/hash.hpp>
+
+
+#include <cstddef> // size_t, uint8_t
+#include <functional> // hash
+
+namespace nlohmann
+{
+namespace detail
+{
+
+// boost::hash_combine
+inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
+{
+    seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
+    return seed;
+}
+
+/*!
+@brief hash a JSON value
+
+The hash function tries to rely on std::hash where possible. Furthermore, the
+type of the JSON value is taken into account to have different hash values for
+null, 0, 0U, and false, etc.
+
+@tparam BasicJsonType basic_json specialization
+@param j JSON value to hash
+@return hash value of j
+*/
+template<typename BasicJsonType>
+std::size_t hash(const BasicJsonType& j)
+{
+    using string_t = typename BasicJsonType::string_t;
+    using number_integer_t = typename BasicJsonType::number_integer_t;
+    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+    using number_float_t = typename BasicJsonType::number_float_t;
+
+    const auto type = static_cast<std::size_t>(j.type());
+    switch (j.type())
+    {
+        case BasicJsonType::value_t::null:
+        case BasicJsonType::value_t::discarded:
+        {
+            return combine(type, 0);
+        }
+
+        case BasicJsonType::value_t::object:
+        {
+            auto seed = combine(type, j.size());
+            for (const auto& element : j.items())
+            {
+                const auto h = std::hash<string_t> {}(element.key());
+                seed = combine(seed, h);
+                seed = combine(seed, hash(element.value()));
+            }
+            return seed;
+        }
+
+        case BasicJsonType::value_t::array:
+        {
+            auto seed = combine(type, j.size());
+            for (const auto& element : j)
+            {
+                seed = combine(seed, hash(element));
+            }
+            return seed;
+        }
+
+        case BasicJsonType::value_t::string:
+        {
+            const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
+            return combine(type, h);
+        }
+
+        case BasicJsonType::value_t::boolean:
+        {
+            const auto h = std::hash<bool> {}(j.template get<bool>());
+            return combine(type, h);
+        }
+
+        case BasicJsonType::value_t::number_integer:
+        {
+            const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
+            return combine(type, h);
+        }
+
+        case nlohmann::detail::value_t::number_unsigned:
+        {
+            const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
+            return combine(type, h);
+        }
+
+        case nlohmann::detail::value_t::number_float:
+        {
+            const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
+            return combine(type, h);
+        }
+
+        case nlohmann::detail::value_t::binary:
+        {
+            auto seed = combine(type, j.get_binary().size());
+            const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
+            seed = combine(seed, h);
+            seed = combine(seed, j.get_binary().subtype());
+            for (const auto byte : j.get_binary())
+            {
+                seed = combine(seed, std::hash<std::uint8_t> {}(byte));
+            }
+            return seed;
+        }
+
+        default: // LCOV_EXCL_LINE
+            JSON_ASSERT(false); // LCOV_EXCL_LINE
+    }
+}
+
+}  // namespace detail
+}  // namespace nlohmann
+
+// #include <nlohmann/detail/input/binary_reader.hpp>
+
+
+#include <algorithm> // generate_n
+#include <array> // array
+#include <cmath> // ldexp
+#include <cstddef> // size_t
+#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
+#include <cstdio> // snprintf
+#include <cstring> // memcpy
+#include <iterator> // back_inserter
+#include <limits> // numeric_limits
+#include <string> // char_traits, string
+#include <utility> // make_pair, move
+
+// #include <nlohmann/detail/exceptions.hpp>
+
+// #include <nlohmann/detail/input/input_adapters.hpp>
+
+
+#include <array> // array
+#include <cstddef> // size_t
+#include <cstdio> //FILE *
+#include <cstring> // strlen
+#include <istream> // istream
+#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
+#include <memory> // shared_ptr, make_shared, addressof
+#include <numeric> // accumulate
+#include <string> // string, char_traits
+#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
+#include <utility> // pair, declval
+
+// #include <nlohmann/detail/iterators/iterator_traits.hpp>
+
+// #include <nlohmann/detail/macro_scope.hpp>
+
+
+namespace nlohmann
+{
+namespace detail
+{
+/// the supported input formats
+enum class input_format_t { json, cbor, msgpack, ubjson, bson };
+
+////////////////////
+// input adapters //
+////////////////////
+
+/*!
+Input adapter for stdio file access. This adapter read only 1 byte and do not use any
+ buffer. This adapter is a very low level adapter.
+*/
+class file_input_adapter
+{
+  public:
+    using char_type = char;
+
+    JSON_HEDLEY_NON_NULL(2)
+    explicit file_input_adapter(std::FILE* f) noexcept
+        : m_file(f)
+    {}
+
+    // make class move-only
+    file_input_adapter(const file_input_adapter&) = delete;
+    file_input_adapter(file_input_adapter&&) = default;
+    file_input_adapter& operator=(const file_input_adapter&) = delete;
+    file_input_adapter& operator=(file_input_adapter&&) = delete;
+
+    std::char_traits<char>::int_type get_character() noexcept
+    {
+        return std::fgetc(m_file);
+    }
+
+  private:
+    /// the file pointer to read from
+    std::FILE* m_file;
+};
+
+
+/*!
+Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
+beginning of input. Does not support changing the underlying std::streambuf
+in mid-input. Maintains underlying std::istream and std::streambuf to support
+subsequent use of standard std::istream operations to process any input
+characters following those used in parsing the JSON input.  Clears the
+std::istream flags; any input errors (e.g., EOF) will be detected by the first
+subsequent call for input from the std::istream.
+*/
+class input_stream_adapter
+{
+  public:
+    using char_type = char;
+
+    ~input_stream_adapter()
+    {
+        // clear stream flags; we use underlying streambuf I/O, do not
+        // maintain ifstream flags, except eof
+        if (is != nullptr)
+        {
+            is->clear(is->rdstate() & std::ios::eofbit);
+        }
+    }
+
+    explicit input_stream_adapter(std::istream& i)
+        : is(&i), sb(i.rdbuf())
+    {}
+
+    // delete because of pointer members
+    input_stream_adapter(const input_stream_adapter&) = delete;
+    input_stream_adapter& operator=(input_stream_adapter&) = delete;
+    input_stream_adapter& operator=(input_stream_adapter&& rhs) = delete;
+
+    input_stream_adapter(input_stream_adapter&& rhs) noexcept : is(rhs.is), sb(rhs.sb)
+    {
+        rhs.is = nullptr;
+        rhs.sb = nullptr;
+    }
+
+    // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
+    // ensure that std::char_traits<char>::eof() and the character 0xFF do not
+    // end up as the same value, eg. 0xFFFFFFFF.
+    std::char_traits<char>::int_type get_character()
+    {
+        auto res = sb->sbumpc();
+        // set eof manually, as we don't use the istream interface.
+        if (JSON_HEDLEY_UNLIKELY(res == EOF))
+        {
+            is->clear(is->rdstate() | std::ios::eofbit);
+        }
+        return res;
+    }
+
+  private:
+    /// the associated input stream
+    std::istream* is = nullptr;
+    std::streambuf* sb = nullptr;
+};
+
+// General-purpose iterator-based adapter. It might not be as fast as
+// theoretically possible for some containers, but it is extremely versatile.
+template<typename IteratorType>
+class iterator_input_adapter
+{
+  public:
+    using char_type = typename std::iterator_traits<IteratorType>::value_type;
+
+    iterator_input_adapter(IteratorType first, IteratorType last)
+        : current(std::move(first)), end(std::move(last)) {}
+
+    typename std::char_traits<char_type>::int_type get_character()
+    {
+        if (JSON_HEDLEY_LIKELY(current != end))
+        {
+            auto result = std::char_traits<char_type>::to_int_type(*current);
+            std::advance(current, 1);
+            return result;
+        }
+        else
+        {
+            return std::char_traits<char_type>::eof();
+        }
+    }
+
+  private:
+    IteratorType current;
+    IteratorType end;
+
+    template<typename BaseInputAdapter, size_t T>
+    friend struct wide_string_input_helper;
+
+    bool empty() const
+    {
+        return current == end;
+    }
+
+};
+
+
+template<typename BaseInputAdapter, size_t T>
+struct wide_string_input_helper;
+
+template<typename BaseInputAdapter>
+struct wide_string_input_helper<BaseInputAdapter, 4>
+{
+    // UTF-32
+    static void fill_buffer(BaseInputAdapter& input,
+                            std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
+                            size_t& utf8_bytes_index,
+                            size_t& utf8_bytes_filled)
+    {
+        utf8_bytes_index = 0;
+
+        if (JSON_HEDLEY_UNLIKELY(input.empty()))
+        {
+            utf8_bytes[0] = std::char_traits<char>::eof();
+            utf8_bytes_filled = 1;
+        }
+        else
+        {
+            // get the current character
+            const auto wc = input.get_character();
+
+            // UTF-32 to UTF-8 encoding
+            if (wc < 0x80)
+            {
+                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
+                utf8_bytes_filled = 1;
+            }
+            else if (wc <= 0x7FF)
+            {
+                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
+                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
+                utf8_bytes_filled = 2;
+            }
+            else if (wc <= 0xFFFF)
+            {
+                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
+                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
+                utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
+                utf8_bytes_filled = 3;
+            }
+            else if (wc <= 0x10FFFF)
+            {
+                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
+                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
+                utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
+                utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
+                utf8_bytes_filled = 4;
+            }
+            else
+            {
+                // unknown character
+                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
+                utf8_bytes_filled = 1;
+            }
+        }
+    }
+};
+
+template<typename BaseInputAdapter>
+struct wide_string_input_helper<BaseInputAdapter, 2>
+{
+    // UTF-16
+    static void fill_buffer(BaseInputAdapter& input,
+                            std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
+                            size_t& utf8_bytes_index,
+                            size_t& utf8_bytes_filled)
+    {
+        utf8_bytes_index = 0;
+
+        if (JSON_HEDLEY_UNLIKELY(input.empty()))
+        {
+            utf8_bytes[0] = std::char_traits<char>::eof();
+            utf8_bytes_filled = 1;
+        }
+        else
+        {
+            // get the current character
+            const auto wc = input.get_character();
+
+            // UTF-16 to UTF-8 encoding
+            if (wc < 0x80)
+            {
+                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
+                utf8_bytes_filled = 1;
+            }
+            else if (wc <= 0x7FF)
+            {
+                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
+                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
+                utf8_bytes_filled = 2;
+            }
+            else if (0xD800 > wc || wc >= 0xE000)
+            {
+                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
+                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
+                utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
+                utf8_bytes_filled = 3;
+            }
+            else
+            {
+                if (JSON_HEDLEY_UNLIKELY(!input.empty()))
+                {
+                    const auto wc2 = static_cast<unsigned int>(input.get_character());
+                    const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
+                    utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
+                    utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
+                    utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
+                    utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
+                    utf8_bytes_filled = 4;
+                }
+                else
+                {
+                    utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
+                    utf8_bytes_filled = 1;
+                }
+            }
+        }
+    }
+};
+
+// Wraps another input apdater to convert wide character types into individual bytes.
+template<typename BaseInputAdapter, typename WideCharType>
+class wide_string_input_adapter
+{
+  public:
+    using char_type = char;
+
+    wide_string_input_adapter(BaseInputAdapter base)
+        : base_adapter(base) {}
+
+    typename std::char_traits<char>::int_type get_character() noexcept
+    {
+        // check if buffer needs to be filled
+        if (utf8_bytes_index == utf8_bytes_filled)
+        {
+            fill_buffer<sizeof(WideCharType)>();
+
+            JSON_ASSERT(utf8_bytes_filled > 0);
+            JSON_ASSERT(utf8_bytes_index == 0);
+        }
+
+        // use buffer
+        JSON_ASSERT(utf8_bytes_filled > 0);
+        JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
+        return utf8_bytes[utf8_bytes_index++];
+    }
+
+  private:
+    BaseInputAdapter base_adapter;
+
+    template<size_t T>
+    void fill_buffer()
+    {
+        wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
+    }
+
+    /// a buffer for UTF-8 bytes
+    std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
+
+    /// index to the utf8_codes array for the next valid byte
+    std::size_t utf8_bytes_index = 0;
+    /// number of valid bytes in the utf8_codes array
+    std::size_t utf8_bytes_filled = 0;
+};
+
+
+template<typename IteratorType, typename Enable = void>
+struct iterator_input_adapter_factory
+{
+    using iterator_type = IteratorType;
+    using char_type = typename std::iterator_traits<iterator_type>::value_type;
+    using adapter_type = iterator_input_adapter<iterator_type>;
+
+    static adapter_type create(IteratorType first, IteratorType last)
+    {
+        return adapter_type(std::move(first), std::move(last));
+    }
+};
+
+template<typename T>
+struct is_iterator_of_multibyte
+{
+    using value_type = typename std::iterator_traits<T>::value_type;
+    enum
+    {
+        value = sizeof(value_type) > 1
+    };
+};
+
+template<typename IteratorType>
+struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>>
+{
+    using iterator_type = IteratorType;
+    using char_type = typename std::iterator_traits<iterator_type>::value_type;
+    using base_adapter_type = iterator_input_adapter<iterator_type>;
+    using adapter_type = wide_string_input_adapter<base_adapter_type, char_type>;
+
+    static adapter_type create(IteratorType first, IteratorType last)
+    {
+        return adapter_type(base_adapter_type(std::move(first), std::move(last)));
+    }
+};
+
+// General purpose iterator-based input
+template<typename IteratorType>
+typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
+{
+    using factory_type = iterator_input_adapter_factory<IteratorType>;
+    return factory_type::create(first, last);
+}
+
+// Convenience shorthand from container to iterator
+template<typename ContainerType>
+auto input_adapter(const ContainerType& container) -> decltype(input_adapter(begin(container), end(container)))
+{
+    // Enable ADL
+    using std::begin;
+    using std::end;
+
+    return input_adapter(begin(container), end(container));
+}
+
+// Special cases with fast paths
+inline file_input_adapter input_adapter(std::FILE* file)
+{
+    return file_input_adapter(file);
+}
+
+inline input_stream_adapter input_adapter(std::istream& stream)
+{
+    return input_stream_adapter(stream);
+}
+
+inline input_stream_adapter input_adapter(std::istream&& stream)
+{
+    return input_stream_adapter(stream);
+}
+
+using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
+
+// Null-delimited strings, and the like.
+template < typename CharT,
+           typename std::enable_if <
+               std::is_pointer<CharT>::value&&
+               !std::is_array<CharT>::value&&
+               std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
+               sizeof(typename std::remove_pointer<CharT>::type) == 1,
+               int >::type = 0 >
+contiguous_bytes_input_adapter input_adapter(CharT b)
+{
+    auto length = std::strlen(reinterpret_cast<const char*>(b));
+    const auto* ptr = reinterpret_cast<const char*>(b);
+    return input_adapter(ptr, ptr + length);
+}
+
+template<typename T, std::size_t N>
+auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N))
+{
+    return input_adapter(array, array + N);
+}
+
+// This class only handles inputs of input_buffer_adapter type.
+// It's required so that expressions like {ptr, len} can be implicitely casted
+// to the correct adapter.
+class span_input_adapter
+{
+  public:
+    template < typename CharT,
+               typename std::enable_if <
+                   std::is_pointer<CharT>::value&&
+                   std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
+                   sizeof(typename std::remove_pointer<CharT>::type) == 1,
+                   int >::type = 0 >
+    span_input_adapter(CharT b, std::size_t l)
+        : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
+
+    template<class IteratorType,
+             typename std::enable_if<
+                 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
+                 int>::type = 0>
+    span_input_adapter(IteratorType first, IteratorType last)
+        : ia(input_adapter(first, last)) {}
+
+    contiguous_bytes_input_adapter&& get()
+    {
+        return std::move(ia);
+    }
+
+  private:
+    contiguous_bytes_input_adapter ia;
+};
+}  // namespace detail
+}  // namespace nlohmann
+
+// #include <nlohmann/detail/input/json_sax.hpp>
+
+
+#include <cstddef>
+#include <string> // string
+#include <utility> // move
+#include <vector> // vector
+
+// #include <nlohmann/detail/exceptions.hpp>
+
+// #include <nlohmann/detail/macro_scope.hpp>
+
+
+namespace nlohmann
+{
+
+/*!
+@brief SAX interface
+
+This class describes the SAX interface used by @ref nlohmann::json::sax_parse.
+Each function is called in different situations while the input is parsed. The
+boolean return value informs the parser whether to continue processing the
+input.
+*/
+template<typename BasicJsonType>
+struct json_sax
+{
+    using number_integer_t = typename BasicJsonType::number_integer_t;
+    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+    using number_float_t = typename BasicJsonType::number_float_t;
+    using string_t = typename BasicJsonType::string_t;
+    using binary_t = typename BasicJsonType::binary_t;
+
+    /*!
+    @brief a null value was read
+    @return whether parsing should proceed
+    */
+    virtual bool null() = 0;
+
+    /*!
+    @brief a boolean value was read
+    @param[in] val  boolean value
+    @return whether parsing should proceed
+    */
+    virtual bool boolean(bool val) = 0;
+
+    /*!
+    @brief an integer number was read
+    @param[in] val  integer value
+    @return whether parsing should proceed
+    */
+    virtual bool number_integer(number_integer_t val) = 0;
+
+    /*!
+    @brief an unsigned integer number was read
+    @param[in] val  unsigned integer value
+    @return whether parsing should proceed
+    */
+    virtual bool number_unsigned(number_unsigned_t val) = 0;
+
+    /*!
+    @brief an floating-point number was read
+    @param[in] val  floating-point value
+    @param[in] s    raw token value
+    @return whether parsing should proceed
+    */
+    virtual bool number_float(number_float_t val, const string_t& s) = 0;
+
+    /*!
+    @brief a string was read
+    @param[in] val  string value
+    @return whether parsing should proceed
+    @note It is safe to move the passed string.
+    */
+    virtual bool string(string_t& val) = 0;
+
+    /*!
+    @brief a binary string was read
+    @param[in] val  binary value
+    @return whether parsing should proceed
+    @note It is safe to move the passed binary.
+    */
+    virtual bool binary(binary_t& val) = 0;
+
+    /*!
+    @brief the beginning of an object was read
+    @param[in] elements  number of object elements or -1 if unknown
+    @return whether parsing should proceed
+    @note binary formats may report the number of elements
+    */
+    virtual bool start_object(std::size_t elements) = 0;
+
+    /*!
+    @brief an object key was read
+    @param[in] val  object key
+    @return whether parsing should proceed
+    @note It is safe to move the passed string.
+    */
+    virtual bool key(string_t& val) = 0;
+
+    /*!
+    @brief the end of an object was read
+    @return whether parsing should proceed
+    */
+    virtual bool end_object() = 0;
+
+    /*!
+    @brief the beginning of an array was read
+    @param[in] elements  number of array elements or -1 if unknown
+    @return whether parsing should proceed
+    @note binary formats may report the number of elements
+    */
+    virtual bool start_array(std::size_t elements) = 0;
+
+    /*!
+    @brief the end of an array was read
+    @return whether parsing should proceed
+    */
+    virtual bool end_array() = 0;
+
+    /*!
+    @brief a parse error occurred
+    @param[in] position    the position in the input where the error occurs
+    @param[in] last_token  the last read token
+    @param[in] ex          an exception object describing the error
+    @return whether parsing should proceed (must return false)
+    */
+    virtual bool parse_error(std::size_t position,
+                             const std::string& last_token,
+                             const detail::exception& ex) = 0;
+
+    virtual ~json_sax() = default;
+};
+
+
+namespace detail
+{
+/*!
+@brief SAX implementation to create a JSON value from SAX events
+
+This class implements the @ref json_sax interface and processes the SAX events
+to create a JSON value which makes it basically a DOM parser. The structure or
+hierarchy of the JSON value is managed by the stack `ref_stack` which contains
+a pointer to the respective array or object for each recursion depth.
+
+After successful parsing, the value that is passed by reference to the
+constructor contains the parsed value.
+
+@tparam BasicJsonType  the JSON type
+*/
+template<typename BasicJsonType>
+class json_sax_dom_parser
+{
+  public:
+    using number_integer_t = typename BasicJsonType::number_integer_t;
+    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+    using number_float_t = typename BasicJsonType::number_float_t;
+    using string_t = typename BasicJsonType::string_t;
+    using binary_t = typename BasicJsonType::binary_t;
+
+    /*!
+    @param[in, out] r  reference to a JSON value that is manipulated while
+                       parsing
+    @param[in] allow_exceptions_  whether parse errors yield exceptions
+    */
+    explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
+        : root(r), allow_exceptions(allow_exceptions_)
+    {}
+
+    // make class move-only
+    json_sax_dom_parser(const json_sax_dom_parser&) = delete;
+    json_sax_dom_parser(json_sax_dom_parser&&) = default;
+    json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
+    json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default;
+    ~json_sax_dom_parser() = default;
+
+    bool null()
+    {
+        handle_value(nullptr);
+        return true;
+    }
+
+    bool boolean(bool val)
+    {
+        handle_value(val);
+        return true;
+    }
+
+    bool number_integer(number_integer_t val)
+    {
+        handle_value(val);
+        return true;
+    }
+
+    bool number_unsigned(number_unsigned_t val)
+    {
+        handle_value(val);
+        return true;
+    }
+
+    bool number_float(number_float_t val, const string_t& /*unused*/)
+    {
+        handle_value(val);
+        return true;
+    }
+
+    bool string(string_t& val)
+    {
+        handle_value(val);
+        return true;
+    }
+
+    bool binary(binary_t& val)
+    {
+        handle_value(std::move(val));
+        return true;
+    }
+
+    bool start_object(std::size_t len)
+    {
+        ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
+
+        if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
+        {
+            JSON_THROW(out_of_range::create(408,
+                                            "excessive object size: " + std::to_string(len)));
+        }
+
+        return true;
+    }
+
+    bool key(string_t& val)
+    {
+        // add null at given key and store the reference for later
+        object_element = &(ref_stack.back()->m_value.object->operator[](val));
+        return true;
+    }
+
+    bool end_object()
+    {
+        ref_stack.pop_back();
+        return true;
+    }
+
+    bool start_array(std::size_t len)
+    {
+        ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
+
+        if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
+        {
+            JSON_THROW(out_of_range::create(408,
+                                            "excessive array size: " + std::to_string(len)));
+        }
+
+        return true;
+    }
+
+    bool end_array()
+    {
+        ref_stack.pop_back();
+        return true;
+    }
+
+    template<class Exception>
+    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
+                     const Exception& ex)
+    {
+        errored = true;
+        static_cast<void>(ex);
+        if (allow_exceptions)
+        {
+            JSON_THROW(ex);
+        }
+        return false;
+    }
+
+    constexpr bool is_errored() const
+    {
+        return errored;
+    }
+
+  private:
+    /*!
+    @invariant If the ref stack is empty, then the passed value will be the new
+               root.
+    @invariant If the ref stack contains a value, then it is an array or an
+               object to which we can add elements
+    */
+    template<typename Value>
+    JSON_HEDLEY_RETURNS_NON_NULL
+    BasicJsonType* handle_value(Value&& v)
+    {
+        if (ref_stack.empty())
+        {
+            root = BasicJsonType(std::forward<Value>(v));
+            return &root;
+        }
+
+        JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
+
+        if (ref_stack.back()->is_array())
+        {
+            ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
+            return &(ref_stack.back()->m_value.array->back());
+        }
+
+        JSON_ASSERT(ref_stack.back()->is_object());
+        JSON_ASSERT(object_element);
+        *object_element = BasicJsonType(std::forward<Value>(v));
+        return object_element;
+    }
+
+    /// the parsed JSON value
+    BasicJsonType& root;
+    /// stack to model hierarchy of values
+    std::vector<BasicJsonType*> ref_stack {};
+    /// helper to hold the reference for the next object element
+    BasicJsonType* object_element = nullptr;
+    /// whether a syntax error occurred
+    bool errored = false;
+    /// whether to throw exceptions in case of errors
+    const bool allow_exceptions = true;
+};
+
+template<typename BasicJsonType>
+class json_sax_dom_callback_parser
+{
+  public:
+    using number_integer_t = typename BasicJsonType::number_integer_t;
+    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+    using number_float_t = typename BasicJsonType::number_float_t;
+    using string_t = typename BasicJsonType::string_t;
+    using binary_t = typename BasicJsonType::binary_t;
+    using parser_callback_t = typename BasicJsonType::parser_callback_t;
+    using parse_event_t = typename BasicJsonType::parse_event_t;
+
+    json_sax_dom_callback_parser(BasicJsonType& r,
+                                 const parser_callback_t cb,
+                                 const bool allow_exceptions_ = true)
+        : root(r), callback(cb), allow_exceptions(allow_exceptions_)
+    {
+        keep_stack.push_back(true);
+    }
+
+    // make class move-only
+    json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;
+    json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default;
+    json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
+    json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default;
+    ~json_sax_dom_callback_parser() = default;
+
+    bool null()
+    {
+        handle_value(nullptr);
+        return true;
+    }
+
+    bool boolean(bool val)
+    {
+        handle_value(val);
+        return true;
+    }
+
+    bool number_integer(number_integer_t val)
+    {
+        handle_value(val);
+        return true;
+    }
+
+    bool number_unsigned(number_unsigned_t val)
+    {
+        handle_value(val);
+        return true;
+    }
+
+    bool number_float(number_float_t val, const string_t& /*unused*/)
+    {
+        handle_value(val);
+        return true;
+    }
+
+    bool string(string_t& val)
+    {
+        handle_value(val);
+        return true;
+    }
+
+    bool binary(binary_t& val)
+    {
+        handle_value(std::move(val));
+        return true;
+    }
+
+    bool start_object(std::size_t len)
+    {
+        // check callback for object start
+        const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
+        keep_stack.push_back(keep);
+
+        auto val = handle_value(BasicJsonType::value_t::object, true);
+        ref_stack.push_back(val.second);
+
+        // check object limit
+        if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
+        {
+            JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len)));
+        }
+
+        return true;
+    }
+
+    bool key(string_t& val)
+    {
+        BasicJsonType k = BasicJsonType(val);
+
+        // check callback for key
+        const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
+        key_keep_stack.push_back(keep);
+
+        // add discarded value at given key and store the reference for later
+        if (keep && ref_stack.back())
+        {
+            object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
+        }
+
+        return true;
+    }
+
+    bool end_object()
+    {
+        if (ref_stack.back() && !callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
+        {
+            // discard object
+            *ref_stack.back() = discarded;
+        }
+
+        JSON_ASSERT(!ref_stack.empty());
+        JSON_ASSERT(!keep_stack.empty());
+        ref_stack.pop_back();
+        keep_stack.pop_back();
+
+        if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
+        {
+            // remove discarded value
+            for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
+            {
+                if (it->is_discarded())
+                {
+                    ref_stack.back()->erase(it);
+                    break;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    bool start_array(std::size_t len)
+    {
+        const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
+        keep_stack.push_back(keep);
+
+        auto val = handle_value(BasicJsonType::value_t::array, true);
+        ref_stack.push_back(val.second);
+
+        // check array limit
+        if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
+        {
+            JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len)));
+        }
+
+        return true;
+    }
+
+    bool end_array()
+    {
+        bool keep = true;
+
+        if (ref_stack.back())
+        {
+            keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
+            if (!keep)
+            {
+                // discard array
+                *ref_stack.back() = discarded;
+            }
+        }
+
+        JSON_ASSERT(!ref_stack.empty());
+        JSON_ASSERT(!keep_stack.empty());
+        ref_stack.pop_back();
+        keep_stack.pop_back();
+
+        // remove discarded value
+        if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
+        {
+            ref_stack.back()->m_value.array->pop_back();
+        }
+
+        return true;
+    }
+
+    template<class Exception>
+    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
+                     const Exception& ex)
+    {
+        errored = true;
+        static_cast<void>(ex);
+        if (allow_exceptions)
+        {
+            JSON_THROW(ex);
+        }
+        return false;
+    }
+
+    constexpr bool is_errored() const
+    {
+        return errored;
+    }
+
+  private:
+    /*!
+    @param[in] v  value to add to the JSON value we build during parsing
+    @param[in] skip_callback  whether we should skip calling the callback
+               function; this is required after start_array() and
+               start_object() SAX events, because otherwise we would call the
+               callback function with an empty array or object, respectively.
+
+    @invariant If the ref stack is empty, then the passed value will be the new
+               root.
+    @invariant If the ref stack contains a value, then it is an array or an
+               object to which we can add elements
+
+    @return pair of boolean (whether value should be kept) and pointer (to the
+            passed value in the ref_stack hierarchy; nullptr if not kept)
+    */
+    template<typename Value>
+    std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
+    {
+        JSON_ASSERT(!keep_stack.empty());
+
+        // do not handle this value if we know it would be added to a discarded
+        // container
+        if (!keep_stack.back())
+        {
+            return {false, nullptr};
+        }
+
+        // create value
+        auto value = BasicJsonType(std::forward<Value>(v));
+
+        // check callback
+        const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
+
+        // do not handle this value if we just learnt it shall be discarded
+        if (!keep)
+        {
+            return {false, nullptr};
+        }
+
+        if (ref_stack.empty())
+        {
+            root = std::move(value);
+            return {true, &root};
+        }
+
+        // skip this value if we already decided to skip the parent
+        // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
+        if (!ref_stack.back())
+        {
+            return {false, nullptr};
+        }
+
+        // we now only expect arrays and objects
+        JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
+
+        // array
+        if (ref_stack.back()->is_array())
+        {
+            ref_stack.back()->m_value.array->push_back(std::move(value));
+            return {true, &(ref_stack.back()->m_value.array->back())};
+        }
+
+        // object
+        JSON_ASSERT(ref_stack.back()->is_object());
+        // check if we should store an element for the current key
+        JSON_ASSERT(!key_keep_stack.empty());
+        const bool store_element = key_keep_stack.back();
+        key_keep_stack.pop_back();
+
+        if (!store_element)
+        {
+            return {false, nullptr};
+        }
+
+        JSON_ASSERT(object_element);
+        *object_element = std::move(value);
+        return {true, object_element};
+    }
+
+    /// the parsed JSON value
+    BasicJsonType& root;
+    /// stack to model hierarchy of values
+    std::vector<BasicJsonType*> ref_stack {};
+    /// stack to manage which values to keep
+    std::vector<bool> keep_stack {};
+    /// stack to manage which object keys to keep
+    std::vector<bool> key_keep_stack {};
+    /// helper to hold the reference for the next object element
+    BasicJsonType* object_element = nullptr;
+    /// whether a syntax error occurred
+    bool errored = false;
+    /// callback function
+    const parser_callback_t callback = nullptr;
+    /// whether to throw exceptions in case of errors
+    const bool allow_exceptions = true;
+    /// a discarded value for the callback
+    BasicJsonType discarded = BasicJsonType::value_t::discarded;
+};
+
+template<typename BasicJsonType>
+class json_sax_acceptor
+{
+  public:
+    using number_integer_t = typename BasicJsonType::number_integer_t;
+    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+    using number_float_t = typename BasicJsonType::number_float_t;
+    using string_t = typename BasicJsonType::string_t;
+    using binary_t = typename BasicJsonType::binary_t;
+
+    bool null()
+    {
+        return true;
+    }
+
+    bool boolean(bool /*unused*/)
+    {
+        return true;
+    }
+
+    bool number_integer(number_integer_t /*unused*/)
+    {
+        return true;
+    }
+
+    bool number_unsigned(number_unsigned_t /*unused*/)
+    {
+        return true;
+    }
+
+    bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
+    {
+        return true;
+    }
+
+    bool string(string_t& /*unused*/)
+    {
+        return true;
+    }
+
+    bool binary(binary_t& /*unused*/)
+    {
+        return true;
+    }
+
+    bool start_object(std::size_t /*unused*/ = std::size_t(-1))
+    {
+        return true;
+    }
+
+    bool key(string_t& /*unused*/)
+    {
+        return true;
+    }
+
+    bool end_object()
+    {
+        return true;
+    }
+
+    bool start_array(std::size_t /*unused*/ = std::size_t(-1))
+    {
+        return true;
+    }
+
+    bool end_array()
+    {
+        return true;
+    }
+
+    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
+    {
+        return false;
+    }
+};
+}  // namespace detail
+
+}  // namespace nlohmann
+
+// #include <nlohmann/detail/input/lexer.hpp>
+
+
+#include <array> // array
+#include <clocale> // localeconv
+#include <cstddef> // size_t
+#include <cstdio> // snprintf
+#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
+#include <initializer_list> // initializer_list
+#include <string> // char_traits, string
+#include <utility> // move
+#include <vector> // vector
+
+// #include <nlohmann/detail/input/input_adapters.hpp>
+
+// #include <nlohmann/detail/input/position_t.hpp>
+
+// #include <nlohmann/detail/macro_scope.hpp>
+
+
+namespace nlohmann
+{
+namespace detail
+{
+///////////
+// lexer //
+///////////
+
+template<typename BasicJsonType>
+class lexer_base
+{
+  public:
+    /// token types for the parser
+    enum class token_type
+    {
+        uninitialized,    ///< indicating the scanner is uninitialized
+        literal_true,     ///< the `true` literal
+        literal_false,    ///< the `false` literal
+        literal_null,     ///< the `null` literal
+        value_string,     ///< a string -- use get_string() for actual value
+        value_unsigned,   ///< an unsigned integer -- use get_number_unsigned() for actual value
+        value_integer,    ///< a signed integer -- use get_number_integer() for actual value
+        value_float,      ///< an floating point number -- use get_number_float() for actual value
+        begin_array,      ///< the character for array begin `[`
+        begin_object,     ///< the character for object begin `{`
+        end_array,        ///< the character for array end `]`
+        end_object,       ///< the character for object end `}`
+        name_separator,   ///< the name separator `:`
+        value_separator,  ///< the value separator `,`
+        parse_error,      ///< indicating a parse error
+        end_of_input,     ///< indicating the end of the input buffer
+        literal_or_value  ///< a literal or the begin of a value (only for diagnostics)
+    };
+
+    /// return name of values of type token_type (only used for errors)
+    JSON_HEDLEY_RETURNS_NON_NULL
+    JSON_HEDLEY_CONST
+    static const char* token_type_name(const token_type t) noexcept
+    {
+        switch (t)
+        {
+            case token_type::uninitialized:
+                return "<uninitialized>";
+            case token_type::literal_true:
+                return "true literal";
+            case token_type::literal_false:
+                return "false literal";
+            case token_type::literal_null:
+                return "null literal";
+            case token_type::value_string:
+                return "string literal";
+            case token_type::value_unsigned:
+            case token_type::value_integer:
+            case token_type::value_float:
+                return "number literal";
+            case token_type::begin_array:
+                return "'['";
+            case token_type::begin_object:
+                return "'{'";
+            case token_type::end_array:
+                return "']'";
+            case token_type::end_object:
+                return "'}'";
+            case token_type::name_separator:
+                return "':'";
+            case token_type::value_separator:
+                return "','";
+            case token_type::parse_error:
+                return "<parse error>";
+            case token_type::end_of_input:
+                return "end of input";
+            case token_type::literal_or_value:
+                return "'[', '{', or a literal";
+            // LCOV_EXCL_START
+            default: // catch non-enum values
+                return "unknown token";
+                // LCOV_EXCL_STOP
+        }
+    }
+};
+/*!
+@brief lexical analysis
+
+This class organizes the lexical analysis during JSON deserialization.
+*/
+template<typename BasicJsonType, typename InputAdapterType>
+class lexer : public lexer_base<BasicJsonType>
+{
+    using number_integer_t = typename BasicJsonType::number_integer_t;
+    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+    using number_float_t = typename BasicJsonType::number_float_t;
+    using string_t = typename BasicJsonType::string_t;
+    using char_type = typename InputAdapterType::char_type;
+    using char_int_type = typename std::char_traits<char_type>::int_type;
+
+  public:
+    using token_type = typename lexer_base<BasicJsonType>::token_type;
+
+    explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false)
+        : ia(std::move(adapter))
+        , ignore_comments(ignore_comments_)
+        , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
+    {}
+
+    // delete because of pointer members
+    lexer(const lexer&) = delete;
+    lexer(lexer&&) = default;
+    lexer& operator=(lexer&) = delete;
+    lexer& operator=(lexer&&) = default;
+    ~lexer() = default;
+
+  private:
+    /////////////////////
+    // locales
+    /////////////////////
+
+    /// return the locale-dependent decimal point
+    JSON_HEDLEY_PURE
+    static char get_decimal_point() noexcept
+    {
+        const auto* loc = localeconv();
+        JSON_ASSERT(loc != nullptr);
+        return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
+    }
+
+    /////////////////////
+    // scan functions
+    /////////////////////
+
+    /*!
+    @brief get codepoint from 4 hex characters following `\u`
+
+    For input "\u c1 c2 c3 c4" the codepoint is:
+      (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
+    = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
+
+    Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'
+    must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The
+    conversion is done by subtracting the offset (0x30, 0x37, and 0x57)
+    between the ASCII value of the character and the desired integer value.
+
+    @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or
+            non-hex character)
+    */
+    int get_codepoint()
+    {
+        // this function only makes sense after reading `\u`
+        JSON_ASSERT(current == 'u');
+        int codepoint = 0;
+
+        const auto factors = { 12u, 8u, 4u, 0u };
+        for (const auto factor : factors)
+        {
+            get();
+
+            if (current >= '0' && current <= '9')
+            {
+                codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
+            }
+            else if (current >= 'A' && current <= 'F')
+            {
+                codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
+            }
+            else if (current >= 'a' && current <= 'f')
+            {
+                codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
+            }
+            else
+            {
+                return -1;
+            }
+        }
+
+        JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
+        return codepoint;
+    }
+
+    /*!
+    @brief check if the next byte(s) are inside a given range
+
+    Adds the current byte and, for each passed range, reads a new byte and
+    checks if it is inside the range. If a violation was detected, set up an
+    error message and return false. Otherwise, return true.
+
+    @param[in] ranges  list of integers; interpreted as list of pairs of
+                       inclusive lower and upper bound, respectively
+
+    @pre The passed list @a ranges must have 2, 4, or 6 elements; that is,
+         1, 2, or 3 pairs. This precondition is enforced by an assertion.
+
+    @return true if and only if no range violation was detected
+    */
+    bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
+    {
+        JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
+        add(current);
+
+        for (auto range = ranges.begin(); range != ranges.end(); ++range)
+        {
+            get();
+            if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
+            {
+                add(current);
+            }
+            else
+            {
+                error_message = "invalid string: ill-formed UTF-8 byte";
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /*!
+    @brief scan a string literal
+
+    This function scans a string according to Sect. 7 of RFC 7159. While
+    scanning, bytes are escaped and copied into buffer token_buffer. Then the
+    function returns successfully, token_buffer is *not* null-terminated (as it
+    may contain \0 bytes), and token_buffer.size() is the number of bytes in the
+    string.
+
+    @return token_type::value_string if string could be successfully scanned,
+            token_type::parse_error otherwise
+
+    @note In case of errors, variable error_message contains a textual
+          description.
+    */
+    token_type scan_string()
+    {
+        // reset token_buffer (ignore opening quote)
+        reset();
+
+        // we entered the function by reading an open quote
+        JSON_ASSERT(current == '\"');
+
+        while (true)
+        {
+            // get next character
+            switch (get())
+            {
+                // end of file while parsing string
+                case std::char_traits<char_type>::eof():
+                {
+                    error_message = "invalid string: missing closing quote";
+                    return token_type::parse_error;
+                }
+
+                // closing quote
+                case '\"':
+                {
+                    return token_type::value_string;
+                }
+
+                // escapes
+                case '\\':
+                {
+                    switch (get())
+                    {
+                        // quotation mark
+                        case '\"':
+                            add('\"');
+                            break;
+                        // reverse solidus
+                        case '\\':
+                            add('\\');
+                            break;
+                        // solidus
+                        case '/':
+                            add('/');
+                            break;
+                        // backspace
+                        case 'b':
+                            add('\b');
+                            break;
+                        // form feed
+                        case 'f':
+                            add('\f');
+                            break;
+                        // line feed
+                        case 'n':
+                            add('\n');
+                            break;
+                        // carriage return
+                        case 'r':
+                            add('\r');
+                            break;
+                        // tab
+                        case 't':
+                            add('\t');
+                            break;
+
+                        // unicode escapes
+                        case 'u':
+                        {
+                            const int codepoint1 = get_codepoint();
+                            int codepoint = codepoint1; // start with codepoint1
+
+                            if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
+                            {
+                                error_message = "invalid string: '\\u' must be followed by 4 hex digits";
+                                return token_type::parse_error;
+                            }
+
+                            // check if code point is a high surrogate
+                            if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
+                            {
+                                // expect next \uxxxx entry
+                                if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
+                                {
+                                    const int codepoint2 = get_codepoint();
+
+                                    if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
+                                    {
+                                        error_message = "invalid string: '\\u' must be followed by 4 hex digits";
+                                        return token_type::parse_error;
+                                    }
+
+                                    // check if codepoint2 is a low surrogate
+                                    if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
+                                    {
+                                        // overwrite codepoint
+                                        codepoint = static_cast<int>(
+                                                        // high surrogate occupies the most significant 22 bits
+                                                        (static_cast<unsigned int>(codepoint1) << 10u)
+                                                        // low surrogate occupies the least significant 15 bits
+                                                        + static_cast<unsigned int>(codepoint2)
+                                                        // there is still the 0xD800, 0xDC00 and 0x10000 noise
+                                                        // in the result so we have to subtract with:
+                                                        // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
+                                                        - 0x35FDC00u);
+                                    }
+                                    else
+                                    {
+                                        error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
+                                        return token_type::parse_error;
+                                    }
+                                }
+                                else
+                                {
+                                    error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
+                                    return token_type::parse_error;
+                                }
+                            }
+                            else
+                            {
+                                if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
+                                {
+                                    error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
+                                    return token_type::parse_error;
+                                }
+                            }
+
+                            // result of the above calculation yields a proper codepoint
+                            JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
+
+                            // translate codepoint into bytes
+                            if (codepoint < 0x80)
+                            {
+                                // 1-byte characters: 0xxxxxxx (ASCII)
+                                add(static_cast<char_int_type>(codepoint));
+                            }
+                            else if (codepoint <= 0x7FF)
+                            {
+                                // 2-byte characters: 110xxxxx 10xxxxxx
+                                add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
+                                add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
+                            }
+                            else if (codepoint <= 0xFFFF)
+                            {
+                                // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
+                                add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
+                                add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
+                                add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
+                            }
+                            else
+                            {
+                                // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+                                add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
+                                add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
+                                add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
+                                add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
+                            }
+
+                            break;
+                        }
+
+                        // other characters after escape
+                        default:
+                            error_message = "invalid string: forbidden character after backslash";
+                            return token_type::parse_error;
+                    }
+
+                    break;
+                }
+
+                // invalid control characters
+                case 0x00:
+                {
+                    error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
+                    return token_type::parse_error;
+                }
+
+                case 0x01:
+                {
+                    error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
+                    return token_type::parse_error;
+                }
+
+                case 0x02:
+                {
+                    error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
+                    return token_type::parse_error;
+                }
+
+                case 0x03:
+                {
+                    error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
+                    return token_type::parse_error;
+                }
+
+                case 0x04:
+                {
+                    error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
+                    return token_type::parse_error;
+                }
+
+                case 0x05:
+                {
+                    error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
+                    return token_type::parse_error;
+                }
+
+                case 0x06:
+                {
+                    error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
+                    return token_type::parse_error;
+                }
+
+                case 0x07:
+                {
+                    error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
+                    return token_type::parse_error;
+                }
+
+                case 0x08:
+                {
+                    error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
+                    return token_type::parse_error;
+                }
+
+                case 0x09:
+                {
+                    error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
+                    return token_type::parse_error;
+                }
+
+                case 0x0A:
+                {
+                    error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
+                    return token_type::parse_error;
+                }
+
+                case 0x0B:
+                {
+                    error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
+                    return token_type::parse_error;
+                }
+
+                case 0x0C:
+                {
+                    error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
+                    return token_type::parse_error;
+                }
+
+                case 0x0D:
+                {
+                    error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
+                    return token_type::parse_error;
+                }
+
+                case 0x0E:
+                {
+                    error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
+                    return token_type::parse_error;
+                }
+
+                case 0x0F:
+                {
+                    error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
+                    return token_type::parse_error;
+                }
+
+                case 0x10:
+                {
+                    error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
+                    return token_type::parse_error;
+                }
+
+                case 0x11:
+                {
+                    error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
+                    return token_type::parse_error;
+                }
+
+                case 0x12:
+                {
+                    error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
+                    return token_type::parse_error;
+                }
+
+                case 0x13:
+                {
+                    error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
+                    return token_type::parse_error;
+                }
+
+                case 0x14:
+                {
+                    error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
+                    return token_type::parse_error;
+                }
+
+                case 0x15:
+                {
+                    error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
+                    return token_type::parse_error;
+                }
+
+                case 0x16:
+                {
+                    error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
+                    return token_type::parse_error;
+                }
+
+                case 0x17:
+                {
+                    error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
+                    return token_type::parse_error;
+                }
+
+                case 0x18:
+                {
+                    error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
+                    return token_type::parse_error;
+                }
+
+                case 0x19:
+                {
+                    error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
+                    return token_type::parse_error;
+                }
+
+                case 0x1A:
+                {
+                    error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
+                    return token_type::parse_error;
+                }
+
+                case 0x1B:
+                {
+                    error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
+                    return token_type::parse_error;
+                }
+
+                case 0x1C:
+                {
+                    error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
+                    return token_type::parse_error;
+                }
+
+                case 0x1D:
+                {
+                    error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
+                    return token_type::parse_error;
+                }
+
+                case 0x1E:
+                {
+                    error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
+                    return token_type::parse_error;
+                }
+
+                case 0x1F:
+                {
+                    error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
+                    return token_type::parse_error;
+                }
+
+                // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
+                case 0x20:
+                case 0x21:
+                case 0x23:
+                case 0x24:
+                case 0x25:
+                case 0x26:
+                case 0x27:
+                case 0x28:
+                case 0x29:
+                case 0x2A:
+                case 0x2B:
+                case 0x2C:
+                case 0x2D:
+                case 0x2E:
+                case 0x2F:
+                case 0x30:
+                case 0x31:
+                case 0x32:
+                case 0x33:
+                case 0x34:
+                case 0x35:
+                case 0x36:
+                case 0x37:
+                case 0x38:
+                case 0x39:
+                case 0x3A:
+                case 0x3B:
+                case 0x3C:
+                case 0x3D:
+                case 0x3E:
+                case 0x3F:
+                case 0x40:
+                case 0x41:
+                case 0x42:
+                case 0x43:
+                case 0x44:
+                case 0x45:
+                case 0x46:
+                case 0x47:
+                case 0x48:
+                case 0x49:
+                case 0x4A:
+                case 0x4B:
+                case 0x4C:
+                case 0x4D:
+                case 0x4E:
+                case 0x4F:
+                case 0x50:
+                case 0x51:
+                case 0x52:
+                case 0x53:
+                case 0x54:
+                case 0x55:
+                case 0x56:
+                case 0x57:
+                case 0x58:
+                case 0x59:
+                case 0x5A:
+                case 0x5B:
+                case 0x5D:
+                case 0x5E:
+                case 0x5F:
+                case 0x60:
+                case 0x61:
+                case 0x62:
+                case 0x63:
+                case 0x64:
+                case 0x65:
+                case 0x66:
+                case 0x67:
+                case 0x68:
+                case 0x69:
+                case 0x6A:
+                case 0x6B:
+                case 0x6C:
+                case 0x6D:
+                case 0x6E:
+                case 0x6F:
+                case 0x70:
+                case 0x71:
+                case 0x72:
+                case 0x73:
+                case 0x74:
+                case 0x75:
+                case 0x76:
+                case 0x77:
+                case 0x78:
+                case 0x79:
+                case 0x7A:
+                case 0x7B:
+                case 0x7C:
+                case 0x7D:
+                case 0x7E:
+                case 0x7F:
+                {
+                    add(current);
+                    break;
+                }
+
+                // U+0080..U+07FF: bytes C2..DF 80..BF
+                case 0xC2:
+                case 0xC3:
+                case 0xC4:
+                case 0xC5:
+                case 0xC6:
+                case 0xC7:
+                case 0xC8:
+                case 0xC9:
+                case 0xCA:
+                case 0xCB:
+                case 0xCC:
+                case 0xCD:
+                case 0xCE:
+                case 0xCF:
+                case 0xD0:
+                case 0xD1:
+                case 0xD2:
+                case 0xD3:
+                case 0xD4:
+                case 0xD5:
+                case 0xD6:
+                case 0xD7:
+                case 0xD8:
+                case 0xD9:
+                case 0xDA:
+                case 0xDB:
+                case 0xDC:
+                case 0xDD:
+                case 0xDE:
+                case 0xDF:
+                {
+                    if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
+                    {
+                        return token_type::parse_error;
+                    }
+                    break;
+                }
+
+                // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
+                case 0xE0:
+                {
+                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
+                    {
+                        return token_type::parse_error;
+                    }
+                    break;
+                }
+
+                // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
+                // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
+                case 0xE1:
+                case 0xE2:
+                case 0xE3:
+                case 0xE4:
+                case 0xE5:
+                case 0xE6:
+                case 0xE7:
+                case 0xE8:
+                case 0xE9:
+                case 0xEA:
+                case 0xEB:
+                case 0xEC:
+                case 0xEE:
+                case 0xEF:
+                {
+                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
+                    {
+                        return token_type::parse_error;
+                    }
+                    break;
+                }
+
+                // U+D000..U+D7FF: bytes ED 80..9F 80..BF
+                case 0xED:
+                {
+                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
+                    {
+                        return token_type::parse_error;
+                    }
+                    break;
+                }
+
+                // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
+                case 0xF0:
+                {
+                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
+                    {
+                        return token_type::parse_error;
+                    }
+                    break;
+                }
+
+                // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
+                case 0xF1:
+                case 0xF2:
+                case 0xF3:
+                {
+                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
+                    {
+                        return token_type::parse_error;
+                    }
+                    break;
+                }
+
+                // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
+                case 0xF4:
+                {
+                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
+                    {
+                        return token_type::parse_error;
+                    }
+                    break;
+                }
+
+                // remaining bytes (80..C1 and F5..FF) are ill-formed
+                default:
+                {
+                    error_message = "invalid string: ill-formed UTF-8 byte";
+                    return token_type::parse_error;
+                }
+            }
+        }
+    }
+
+    /*!
+     * @brief scan a comment
+     * @return whether comment could be scanned successfully
+     */
+    bool scan_comment()
+    {
+        switch (get())
+        {
+            // single-line comments skip input until a newline or EOF is read
+            case '/':
+            {
+                while (true)
+                {
+                    switch (get())
+                    {
+                        case '\n':
+                        case '\r':
+                        case std::char_traits<char_type>::eof():
+                        case '\0':
+                            return true;
+
+                        default:
+                            break;
+                    }
+                }
+            }
+
+            // multi-line comments skip input until */ is read
+            case '*':
+            {
+                while (true)
+                {
+                    switch (get())
+                    {
+                        case std::char_traits<char_type>::eof():
+                        case '\0':
+                        {
+                            error_message = "invalid comment; missing closing '*/'";
+                            return false;
+                        }
+
+                        case '*':
+                        {
+                            switch (get())
+                            {
+                                case '/':
+                                    return true;
+
+                                default:
+                                {
+                                    unget();
+                                    continue;
+                                }
+                            }
+                        }
+
+                        default:
+                            continue;
+                    }
+                }
+            }
+
+            // unexpected character after reading '/'
+            default:
+            {
+                error_message = "invalid comment; expecting '/' or '*' after '/'";
+                return false;
+            }
+        }
+    }
+
+    JSON_HEDLEY_NON_NULL(2)
+    static void strtof(float& f, const char* str, char** endptr) noexcept
+    {
+        f = std::strtof(str, endptr);
+    }
+
+    JSON_HEDLEY_NON_NULL(2)
+    static void strtof(double& f, const char* str, char** endptr) noexcept
+    {
+        f = std::strtod(str, endptr);
+    }
+
+    JSON_HEDLEY_NON_NULL(2)
+    static void strtof(long double& f, const char* str, char** endptr) noexcept
+    {
+        f = std::strtold(str, endptr);
+    }
+
+    /*!
+    @brief scan a number literal
+
+    This function scans a string according to Sect. 6 of RFC 7159.
+
+    The function is realized with a deterministic finite state machine derived
+    from the grammar described in RFC 7159. Starting in state "init", the
+    input is read and used to determined the next state. Only state "done"
+    accepts the number. State "error" is a trap state to model errors. In the
+    table below, "anything" means any character but the ones listed before.
+
+    state    | 0        | 1-9      | e E      | +       | -       | .        | anything
+    ---------|----------|----------|----------|---------|---------|----------|-----------
+    init     | zero     | any1     | [error]  | [error] | minus   | [error]  | [error]
+    minus    | zero     | any1     | [error]  | [error] | [error] | [error]  | [error]
+    zero     | done     | done     | exponent | done    | done    | decimal1 | done
+    any1     | any1     | any1     | exponent | done    | done    | decimal1 | done
+    decimal1 | decimal2 | decimal2 | [error]  | [error] | [error] | [error]  | [error]
+    decimal2 | decimal2 | decimal2 | exponent | done    | done    | done     | done
+    exponent | any2     | any2     | [error]  | sign    | sign    | [error]  | [error]
+    sign     | any2     | any2     | [error]  | [error] | [error] | [error]  | [error]
+    any2     | any2     | any2     | done     | done    | done    | done     | done
+
+    The state machine is realized with one label per state (prefixed with
+    "scan_number_") and `goto` statements between them. The state machine
+    contains cycles, but any cycle can be left when EOF is read. Therefore,
+    the function is guaranteed to terminate.
+
+    During scanning, the read bytes are stored in token_buffer. This string is
+    then converted to a signed integer, an unsigned integer, or a
+    floating-point number.
+
+    @return token_type::value_unsigned, token_type::value_integer, or
+            token_type::value_float if number could be successfully scanned,
+            token_type::parse_error otherwise
+
+    @note The scanner is independent of the current locale. Internally, the
+          locale's decimal point is used instead of `.` to work with the
+          locale-dependent converters.
+    */
+    token_type scan_number()  // lgtm [cpp/use-of-goto]
+    {
+        // reset token_buffer to store the number's bytes
+        reset();
+
+        // the type of the parsed number; initially set to unsigned; will be
+        // changed if minus sign, decimal point or exponent is read
+        token_type number_type = token_type::value_unsigned;
+
+        // state (init): we just found out we need to scan a number
+        switch (current)
+        {
+            case '-':
+            {
+                add(current);
+                goto scan_number_minus;
+            }
+
+            case '0':
+            {
+                add(current);
+                goto scan_number_zero;
+            }
+
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+            {
+                add(current);
+                goto scan_number_any1;
+            }
+
+            // all other characters are rejected outside scan_number()
+            default:            // LCOV_EXCL_LINE
+                JSON_ASSERT(false);  // LCOV_EXCL_LINE
+        }
+
+scan_number_minus:
+        // state: we just parsed a leading minus sign
+        number_type = token_type::value_integer;
+        switch (get())
+        {
+            case '0':
+            {
+                add(current);
+                goto scan_number_zero;
+            }
+
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+            {
+                add(current);
+                goto scan_number_any1;
+            }
+
+            default:
+            {
+                error_message = "invalid number; expected digit after '-'";
+                return token_type::parse_error;
+            }
+        }
+
+scan_number_zero:
+        // state: we just parse a zero (maybe with a leading minus sign)
+        switch (get())
+        {
+            case '.':
+            {
+                add(decimal_point_char);
+                goto scan_number_decimal1;
+            }
+
+            case 'e':
+            case 'E':
+            {
+                add(current);
+                goto scan_number_exponent;
+            }
+
+            default:
+                goto scan_number_done;
+        }
+
+scan_number_any1:
+        // state: we just parsed a number 0-9 (maybe with a leading minus sign)
+        switch (get())
+        {
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+            {
+                add(current);
+                goto scan_number_any1;
+            }
+
+            case '.':
+            {
+                add(decimal_point_char);
+                goto scan_number_decimal1;
+            }
+
+            case 'e':
+            case 'E':
+            {
+                add(current);
+                goto scan_number_exponent;
+            }
+
+            default:
+                goto scan_number_done;
+        }
+
+scan_number_decimal1:
+        // state: we just parsed a decimal point
+        number_type = token_type::value_float;
+        switch (get())
+        {
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+            {
+                add(current);
+                goto scan_number_decimal2;
+            }
+
+            default:
+            {
+                error_message = "invalid number; expected digit after '.'";
+                return token_type::parse_error;
+            }
+        }
+
+scan_number_decimal2:
+        // we just parsed at least one number after a decimal point
+        switch (get())
+        {
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+            {
+                add(current);
+                goto scan_number_decimal2;
+            }
+
+            case 'e':
+            case 'E':
+            {
+                add(current);
+                goto scan_number_exponent;
+            }
+
+            default:
+                goto scan_number_done;
+        }
+
+scan_number_exponent:
+        // we just parsed an exponent
+        number_type = token_type::value_float;
+        switch (get())
+        {
+            case '+':
+            case '-':
+            {
+                add(current);
+                goto scan_number_sign;
+            }
+
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+            {
+                add(current);
+                goto scan_number_any2;
+            }
+
+            default:
+            {
+                error_message =
+                    "invalid number; expected '+', '-', or digit after exponent";
+                return token_type::parse_error;
+            }
+        }
+
+scan_number_sign:
+        // we just parsed an exponent sign
+        switch (get())
+        {
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+            {
+                add(current);
+                goto scan_number_any2;
+            }
+
+            default:
+            {
+                error_message = "invalid number; expected digit after exponent sign";
+                return token_type::parse_error;
+            }
+        }
+
+scan_number_any2:
+        // we just parsed a number after the exponent or exponent sign
+        switch (get())
+        {
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+            {
+                add(current);
+                goto scan_number_any2;
+            }
+
+            default:
+                goto scan_number_done;
+        }
+
+scan_number_done:
+        // unget the character after the number (we only read it to know that
+        // we are done scanning a number)
+        unget();
+
+        char* endptr = nullptr;
+        errno = 0;
+
+        // try to parse integers first and fall back to floats
+        if (number_type == token_type::value_unsigned)
+        {
+            const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
+
+            // we checked the number format before
+            JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
+
+            if (errno == 0)
+            {
+                value_unsigned = static_cast<number_unsigned_t>(x);
+                if (value_unsigned == x)
+                {
+                    return token_type::value_unsigned;
+                }
+            }
+        }
+        else if (number_type == token_type::value_integer)
+        {
+            const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
+
+            // we checked the number format before
+            JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
+
+            if (errno == 0)
+            {
+                value_integer = static_cast<number_integer_t>(x);
+                if (value_integer == x)
+                {
+                    return token_type::value_integer;
+                }
+            }
+        }
+
+        // this code is reached if we parse a floating-point number or if an
+        // integer conversion above failed
+        strtof(value_float, token_buffer.data(), &endptr);
+
+        // we checked the number format before
+        JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
+
+        return token_type::value_float;
+    }
+
+    /*!
+    @param[in] literal_text  the literal text to expect
+    @param[in] length        the length of the passed literal text
+    @param[in] return_type   the token type to return on success
+    */
+    JSON_HEDLEY_NON_NULL(2)
+    token_type scan_literal(const char_type* literal_text, const std::size_t length,
+                            token_type return_type)
+    {
+        JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
+        for (std::size_t i = 1; i < length; ++i)
+        {
+            if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
+            {
+                error_message = "invalid literal";
+                return token_type::parse_error;
+            }
+        }
+        return return_type;
+    }
+
+    /////////////////////
+    // input management
+    /////////////////////
+
+    /// reset token_buffer; current character is beginning of token
+    void reset() noexcept
+    {
+        token_buffer.clear();
+        token_string.clear();
+        token_string.push_back(std::char_traits<char_type>::to_char_type(current));
+    }
+
+    /*
+    @brief get next character from the input
+
+    This function provides the interface to the used input adapter. It does
+    not throw in case the input reached EOF, but returns a
+    `std::char_traits<char>::eof()` in that case.  Stores the scanned characters
+    for use in error messages.
+
+    @return character read from the input
+    */
+    char_int_type get()
+    {
+        ++position.chars_read_total;
+        ++position.chars_read_current_line;
+
+        if (next_unget)
+        {
+            // just reset the next_unget variable and work with current
+            next_unget = false;
+        }
+        else
+        {
+            current = ia.get_character();
+        }
+
+        if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
+        {
+            token_string.push_back(std::char_traits<char_type>::to_char_type(current));
+        }
+
+        if (current == '\n')
+        {
+            ++position.lines_read;
+            position.chars_read_current_line = 0;
+        }
+
+        return current;
+    }
+
+    /*!
+    @brief unget current character (read it again on next get)
+
+    We implement unget by setting variable next_unget to true. The input is not
+    changed - we just simulate ungetting by modifying chars_read_total,
+    chars_read_current_line, and token_string. The next call to get() will
+    behave as if the unget character is read again.
+    */
+    void unget()
+    {
+        next_unget = true;
+
+        --position.chars_read_total;
+
+        // in case we "unget" a newline, we have to also decrement the lines_read
+        if (position.chars_read_current_line == 0)
+        {
+            if (position.lines_read > 0)
+            {
+                --position.lines_read;
+            }
+        }
+        else
+        {
+            --position.chars_read_current_line;
+        }
+
+        if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
+        {
+            JSON_ASSERT(!token_string.empty());
+            token_string.pop_back();
+        }
+    }
+
+    /// add a character to token_buffer
+    void add(char_int_type c)
+    {
+        token_buffer.push_back(static_cast<typename string_t::value_type>(c));
+    }
+
+  public:
+    /////////////////////
+    // value getters
+    /////////////////////
+
+    /// return integer value
+    constexpr number_integer_t get_number_integer() const noexcept
+    {
+        return value_integer;
+    }
+
+    /// return unsigned integer value
+    constexpr number_unsigned_t get_number_unsigned() const noexcept
+    {
+        return value_unsigned;
+    }
+
+    /// return floating-point value
+    constexpr number_float_t get_number_float() const noexcept
+    {
+        return value_float;
+    }
+
+    /// return current string value (implicitly resets the token; useful only once)
+    string_t& get_string()
+    {
+        return token_buffer;
+    }
+
+    /////////////////////
+    // diagnostics
+    /////////////////////
+
+    /// return position of last read token
+    constexpr position_t get_position() const noexcept
+    {
+        return position;
+    }
+
+    /// return the last read token (for errors only).  Will never contain EOF
+    /// (an arbitrary value that is not a valid char value, often -1), because
+    /// 255 may legitimately occur.  May contain NUL, which should be escaped.
+    std::string get_token_string() const
+    {
+        // escape control characters
+        std::string result;
+        for (const auto c : token_string)
+        {
+            if (static_cast<unsigned char>(c) <= '\x1F')
+            {
+                // escape control characters
+                std::array<char, 9> cs{{}};
+                (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c));
+                result += cs.data();
+            }
+            else
+            {
+                // add character as is
+                result.push_back(static_cast<std::string::value_type>(c));
+            }
+        }
+
+        return result;
+    }
+
+    /// return syntax error message
+    JSON_HEDLEY_RETURNS_NON_NULL
+    constexpr const char* get_error_message() const noexcept
+    {
+        return error_message;
+    }
+
+    /////////////////////
+    // actual scanner
+    /////////////////////
+
+    /*!
+    @brief skip the UTF-8 byte order mark
+    @return true iff there is no BOM or the correct BOM has been skipped
+    */
+    bool skip_bom()
+    {
+        if (get() == 0xEF)
+        {
+            // check if we completely parse the BOM
+            return get() == 0xBB && get() == 0xBF;
+        }
+
+        // the first character is not the beginning of the BOM; unget it to
+        // process is later
+        unget();
+        return true;
+    }
+
+    void skip_whitespace()
+    {
+        do
+        {
+            get();
+        }
+        while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
+    }
+
+    token_type scan()
+    {
+        // initially, skip the BOM
+        if (position.chars_read_total == 0 && !skip_bom())
+        {
+            error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
+            return token_type::parse_error;
+        }
+
+        // read next character and ignore whitespace
+        skip_whitespace();
+
+        // ignore comments
+        while (ignore_comments && current == '/')
+        {
+            if (!scan_comment())
+            {
+                return token_type::parse_error;
+            }
+
+            // skip following whitespace
+            skip_whitespace();
+        }
+
+        switch (current)
+        {
+            // structural characters
+            case '[':
+                return token_type::begin_array;
+            case ']':
+                return token_type::end_array;
+            case '{':
+                return token_type::begin_object;
+            case '}':
+                return token_type::end_object;
+            case ':':
+                return token_type::name_separator;
+            case ',':
+                return token_type::value_separator;
+
+            // literals
+            case 't':
+            {
+                std::array<char_type, 4> true_literal = {{'t', 'r', 'u', 'e'}};
+                return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
+            }
+            case 'f':
+            {
+                std::array<char_type, 5> false_literal = {{'f', 'a', 'l', 's', 'e'}};
+                return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
+            }
+            case 'n':
+            {
+                std::array<char_type, 4> null_literal = {{'n', 'u', 'l', 'l'}};
+                return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
+            }
+
+            // string
+            case '\"':
+                return scan_string();
+
+            // number
+            case '-':
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+                return scan_number();
+
+            // end of input (the null byte is needed when parsing from
+            // string literals)
+            case '\0':
+            case std::char_traits<char_type>::eof():
+                return token_type::end_of_input;
+
+            // error
+            default:
+                error_message = "invalid literal";
+                return token_type::parse_error;
+        }
+    }
+
+  private:
+    /// input adapter
+    InputAdapterType ia;
+
+    /// whether comments should be ignored (true) or signaled as errors (false)
+    const bool ignore_comments = false;
+
+    /// the current character
+    char_int_type current = std::char_traits<char_type>::eof();
+
+    /// whether the next get() call should just return current
+    bool next_unget = false;
+
+    /// the start position of the current token
+    position_t position {};
+
+    /// raw input token string (for error messages)
+    std::vector<char_type> token_string {};
+
+    /// buffer for variable-length tokens (numbers, strings)
+    string_t token_buffer {};
+
+    /// a description of occurred lexer errors
+    const char* error_message = "";
+
+    // number values
+    number_integer_t value_integer = 0;
+    number_unsigned_t value_unsigned = 0;
+    number_float_t value_float = 0;
+
+    /// the decimal point
+    const char_int_type decimal_point_char = '.';
+};
+}  // namespace detail
+}  // namespace nlohmann
+
+// #include <nlohmann/detail/macro_scope.hpp>
+
+// #include <nlohmann/detail/meta/is_sax.hpp>
+
+
+#include <cstdint> // size_t
+#include <utility> // declval
+#include <string> // string
+
+// #include <nlohmann/detail/meta/detected.hpp>
+
+// #include <nlohmann/detail/meta/type_traits.hpp>
+
+
+namespace nlohmann
+{
+namespace detail
+{
+template<typename T>
+using null_function_t = decltype(std::declval<T&>().null());
+
+template<typename T>
+using boolean_function_t =
+    decltype(std::declval<T&>().boolean(std::declval<bool>()));
+
+template<typename T, typename Integer>
+using number_integer_function_t =
+    decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
+
+template<typename T, typename Unsigned>
+using number_unsigned_function_t =
+    decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
+
+template<typename T, typename Float, typename String>
+using number_float_function_t = decltype(std::declval<T&>().number_float(
+                                    std::declval<Float>(), std::declval<const String&>()));
+
+template<typename T, typename String>
+using string_function_t =
+    decltype(std::declval<T&>().string(std::declval<String&>()));
+
+template<typename T, typename Binary>
+using binary_function_t =
+    decltype(std::declval<T&>().binary(std::declval<Binary&>()));
+
+template<typename T>
+using start_object_function_t =
+    decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
+
+template<typename T, typename String>
+using key_function_t =
+    decltype(std::declval<T&>().key(std::declval<String&>()));
+
+template<typename T>
+using end_object_function_t = decltype(std::declval<T&>().end_object());
+
+template<typename T>
+using start_array_function_t =
+    decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
+
+template<typename T>
+using end_array_function_t = decltype(std::declval<T&>().end_array());
+
+template<typename T, typename Exception>
+using parse_error_function_t = decltype(std::declval<T&>().parse_error(
+        std::declval<std::size_t>(), std::declval<const std::string&>(),
+        std::declval<const Exception&>()));
+
+template<typename SAX, typename BasicJsonType>
+struct is_sax
+{
+  private:
+    static_assert(is_basic_json<BasicJsonType>::value,
+                  "BasicJsonType must be of type basic_json<...>");
+
+    using number_integer_t = typename BasicJsonType::number_integer_t;
+    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+    using number_float_t = typename BasicJsonType::number_float_t;
+    using string_t = typename BasicJsonType::string_t;
+    using binary_t = typename BasicJsonType::binary_t;
+    using exception_t = typename BasicJsonType::exception;
+
+  public:
+    static constexpr bool value =
+        is_detected_exact<bool, null_function_t, SAX>::value &&
+        is_detected_exact<bool, boolean_function_t, SAX>::value &&
+        is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value &&
+        is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value &&
+        is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value &&
+        is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
+        is_detected_exact<bool, binary_function_t, SAX, binary_t>::value &&
+        is_detected_exact<bool, start_object_function_t, SAX>::value &&
+        is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
+        is_detected_exact<bool, end_object_function_t, SAX>::value &&
+        is_detected_exact<bool, start_array_function_t, SAX>::value &&
+        is_detected_exact<bool, end_array_function_t, SAX>::value &&
+        is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
+};
+
+template<typename SAX, typename BasicJsonType>
+struct is_sax_static_asserts
+{
+  private:
+    static_assert(is_basic_json<BasicJsonType>::value,
+                  "BasicJsonType must be of type basic_json<...>");
+
+    using number_integer_t = typename BasicJsonType::number_integer_t;
+    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+    using number_float_t = typename BasicJsonType::number_float_t;
+    using string_t = typename BasicJsonType::string_t;
+    using binary_t = typename BasicJsonType::binary_t;
+    using exception_t = typename BasicJsonType::exception;
+
+  public:
+    static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
+                  "Missing/invalid function: bool null()");
+    static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
+                  "Missing/invalid function: bool boolean(bool)");
+    static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
+                  "Missing/invalid function: bool boolean(bool)");
+    static_assert(
+        is_detected_exact<bool, number_integer_function_t, SAX,
+        number_integer_t>::value,
+        "Missing/invalid function: bool number_integer(number_integer_t)");
+    static_assert(
+        is_detected_exact<bool, number_unsigned_function_t, SAX,
+        number_unsigned_t>::value,
+        "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
+    static_assert(is_detected_exact<bool, number_float_function_t, SAX,
+                  number_float_t, string_t>::value,
+                  "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
+    static_assert(
+        is_detected_exact<bool, string_function_t, SAX, string_t>::value,
+        "Missing/invalid function: bool string(string_t&)");
+    static_assert(
+        is_detected_exact<bool, binary_function_t, SAX, binary_t>::value,
+        "Missing/invalid function: bool binary(binary_t&)");
+    static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
+                  "Missing/invalid function: bool start_object(std::size_t)");
+    static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
+                  "Missing/invalid function: bool key(string_t&)");
+    static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
+                  "Missing/invalid function: bool end_object()");
+    static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
+                  "Missing/invalid function: bool start_array(std::size_t)");
+    static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
+                  "Missing/invalid function: bool end_array()");
+    static_assert(
+        is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
+        "Missing/invalid function: bool parse_error(std::size_t, const "
+        "std::string&, const exception&)");
+};
+}  // namespace detail
+}  // namespace nlohmann
+
+// #include <nlohmann/detail/value_t.hpp>
+
+
+namespace nlohmann
+{
+namespace detail
+{
+
+/// how to treat CBOR tags
+enum class cbor_tag_handler_t
+{
+    error,  ///< throw a parse_error exception in case of a tag
+    ignore   ///< ignore tags
+};
+
+/*!
+@brief determine system byte order
+
+@return true if and only if system's byte order is little endian
+
+@note from https://stackoverflow.com/a/1001328/266378
+*/
+static inline bool little_endianess(int num = 1) noexcept
+{
+    return *reinterpret_cast<char*>(&num) == 1;
+}
+
+
+///////////////////
+// binary reader //
+///////////////////
+
+/*!
+@brief deserialization of CBOR, MessagePack, and UBJSON values
+*/
+template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
+class binary_reader
+{
+    using number_integer_t = typename BasicJsonType::number_integer_t;
+    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+    using number_float_t = typename BasicJsonType::number_float_t;
+    using string_t = typename BasicJsonType::string_t;
+    using binary_t = typename BasicJsonType::binary_t;
+    using json_sax_t = SAX;
+    using char_type = typename InputAdapterType::char_type;
+    using char_int_type = typename std::char_traits<char_type>::int_type;
+
+  public:
+    /*!
+    @brief create a binary reader
+
+    @param[in] adapter  input adapter to read from
+    */
+    explicit binary_reader(InputAdapterType&& adapter) : ia(std::move(adapter))
+    {
+        (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
+    }
+
+    // make class move-only
+    binary_reader(const binary_reader&) = delete;
+    binary_reader(binary_reader&&) = default;
+    binary_reader& operator=(const binary_reader&) = delete;
+    binary_reader& operator=(binary_reader&&) = default;
+    ~binary_reader() = default;
+
+    /*!
+    @param[in] format  the binary format to parse
+    @param[in] sax_    a SAX event processor
+    @param[in] strict  whether to expect the input to be consumed completed
+    @param[in] tag_handler  how to treat CBOR tags
+
+    @return
+    */
+    JSON_HEDLEY_NON_NULL(3)
+    bool sax_parse(const input_format_t format,
+                   json_sax_t* sax_,
+                   const bool strict = true,
+                   const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
+    {
+        sax = sax_;
+        bool result = false;
+
+        switch (format)
+        {
+            case input_format_t::bson:
+                result = parse_bson_internal();
+                break;
+
+            case input_format_t::cbor:
+                result = parse_cbor_internal(true, tag_handler);
+                break;
+
+            case input_format_t::msgpack:
+                result = parse_msgpack_internal();
+                break;
+
+            case input_format_t::ubjson:
+                result = parse_ubjson_internal();
+                break;
+
+            default:            // LCOV_EXCL_LINE
+                JSON_ASSERT(false);  // LCOV_EXCL_LINE
+        }
+
+        // strict mode: next byte must be EOF
+        if (result && strict)
+        {
+            if (format == input_format_t::ubjson)
+            {
+                get_ignore_noop();
+            }
+            else
+            {
+                get();
+            }
+
+            if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
+            {
+                return sax->parse_error(chars_read, get_token_string(),
+                                        parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value")));
+            }
+        }
+
+        return result;
+    }
+
+  private:
+    //////////
+    // BSON //
+    //////////
+
+    /*!
+    @brief Reads in a BSON-object and passes it to the SAX-parser.
+    @return whether a valid BSON-value was passed to the SAX parser
+    */
+    bool parse_bson_internal()
+    {
+        std::int32_t document_size{};
+        get_number<std::int32_t, true>(input_format_t::bson, document_size);
+
+        if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
+        {
+            return false;
+        }
+
+        if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
+        {
+            return false;
+        }
+
+        return sax->end_object();
+    }
+
+    /*!
+    @brief Parses a C-style string from the BSON input.
+    @param[in, out] result  A reference to the string variable where the read
+                            string is to be stored.
+    @return `true` if the \x00-byte indicating the end of the string was
+             encountered before the EOF; false` indicates an unexpected EOF.
+    */
+    bool get_bson_cstr(string_t& result)
+    {
+        auto out = std::back_inserter(result);
+        while (true)
+        {
+            get();
+            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
+            {
+                return false;
+            }
+            if (current == 0x00)
+            {
+                return true;
+            }
+            *out++ = static_cast<typename string_t::value_type>(current);
+        }
+    }
+
+    /*!
+    @brief Parses a zero-terminated string of length @a len from the BSON
+           input.
+    @param[in] len  The length (including the zero-byte at the end) of the
+                    string to be read.
+    @param[in, out] result  A reference to the string variable where the read
+                            string is to be stored.
+    @tparam NumberType The type of the length @a len
+    @pre len >= 1
+    @return `true` if the string was successfully parsed
+    */
+    template<typename NumberType>
+    bool get_bson_string(const NumberType len, string_t& result)
+    {
+        if (JSON_HEDLEY_UNLIKELY(len < 1))
+        {
+            auto last_token = get_token_string();
+            return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "string length must be at least 1, is " + std::to_string(len), "string")));
+        }
+
+        return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
+    }
+
+    /*!
+    @brief Parses a byte array input of length @a len from the BSON input.
+    @param[in] len  The length of the byte array to be read.
+    @param[in, out] result  A reference to the binary variable where the read
+                            array is to be stored.
+    @tparam NumberType The type of the length @a len
+    @pre len >= 0
+    @return `true` if the byte array was successfully parsed
+    */
+    template<typename NumberType>
+    bool get_bson_binary(const NumberType len, binary_t& result)
+    {
+        if (JSON_HEDLEY_UNLIKELY(len < 0))
+        {
+            auto last_token = get_token_string();
+            return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "byte array length cannot be negative, is " + std::to_string(len), "binary")));
+        }
+
+        // All BSON binary values have a subtype
+        std::uint8_t subtype{};
+        get_number<std::uint8_t>(input_format_t::bson, subtype);
+        result.set_subtype(subtype);
+
+        return get_binary(input_format_t::bson, len, result);
+    }
+
+    /*!
+    @brief Read a BSON document element of the given @a element_type.
+    @param[in] element_type The BSON element type, c.f. http://bsonspec.org/spec.html
+    @param[in] element_type_parse_position The position in the input stream,
+               where the `element_type` was read.
+    @warning Not all BSON element types are supported yet. An unsupported
+             @a element_type will give rise to a parse_error.114:
+             Unsupported BSON record type 0x...
+    @return whether a valid BSON-object/array was passed to the SAX parser
+    */
+    bool parse_bson_element_internal(const char_int_type element_type,
+                                     const std::size_t element_type_parse_position)
+    {
+        switch (element_type)
+        {
+            case 0x01: // double
+            {
+                double number{};
+                return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
+            }
+
+            case 0x02: // string
+            {
+                std::int32_t len{};
+                string_t value;
+                return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
+            }
+
+            case 0x03: // object
+            {
+                return parse_bson_internal();
+            }
+
+            case 0x04: // array
+            {
+                return parse_bson_array();
+            }
+
+            case 0x05: // binary
+            {
+                std::int32_t len{};
+                binary_t value;
+                return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
+            }
+
+            case 0x08: // boolean
+            {
+                return sax->boolean(get() != 0);
+            }
+
+            case 0x0A: // null
+            {
+                return sax->null();
+            }
+
+            case 0x10: // int32
+            {
+                std::int32_t value{};
+                return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
+            }
+
+            case 0x12: // int64
+            {
+                std::int64_t value{};
+                return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
+            }
+
+            default: // anything else not supported (yet)
+            {
+                std::array<char, 3> cr{{}};
+                (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type));
+                return sax->parse_error(element_type_parse_position, std::string(cr.data()), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr.data())));
+            }
+        }
+    }
+
+    /*!
+    @brief Read a BSON element list (as specified in the BSON-spec)
+
+    The same binary layout is used for objects and arrays, hence it must be
+    indicated with the argument @a is_array which one is expected
+    (true --> array, false --> object).
+
+    @param[in] is_array Determines if the element list being read is to be
+                        treated as an object (@a is_array == false), or as an
+                        array (@a is_array == true).
+    @return whether a valid BSON-object/array was passed to the SAX parser
+    */
+    bool parse_bson_element_list(const bool is_array)
+    {
+        string_t key;
+
+        while (auto element_type = get())
+        {
+            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
+            {
+                return false;
+            }
+
+            const std::size_t element_type_parse_position = chars_read;
+            if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
+            {
+                return false;
+            }
+
+            if (!is_array && !sax->key(key))
+            {
+                return false;
+            }
+
+            if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
+            {
+                return false;
+            }
+
+            // get_bson_cstr only appends
+            key.clear();
+        }
+
+        return true;
+    }
+
+    /*!
+    @brief Reads an array from the BSON input and passes it to the SAX-parser.
+    @return whether a valid BSON-array was passed to the SAX parser
+    */
+    bool parse_bson_array()
+    {
+        std::int32_t document_size{};
+        get_number<std::int32_t, true>(input_format_t::bson, document_size);
+
+        if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
+        {
+            return false;
+        }
+
+        if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
+        {
+            return false;
+        }
+
+        return sax->end_array();
+    }
+
+    //////////
+    // CBOR //
+    //////////
+
+    /*!
+    @param[in] get_char  whether a new character should be retrieved from the
+                         input (true) or whether the last read character should
+                         be considered instead (false)
+    @param[in] tag_handler how CBOR tags should be treated
+
+    @return whether a valid CBOR value was passed to the SAX parser
+    */
+    bool parse_cbor_internal(const bool get_char,
+                             const cbor_tag_handler_t tag_handler)
+    {
+        switch (get_char ? get() : current)
+        {
+            // EOF
+            case std::char_traits<char_type>::eof():
+                return unexpect_eof(input_format_t::cbor, "value");
+
+            // Integer 0x00..0x17 (0..23)
+            case 0x00:
+            case 0x01:
+            case 0x02:
+            case 0x03:
+            case 0x04:
+            case 0x05:
+            case 0x06:
+            case 0x07:
+            case 0x08:
+            case 0x09:
+            case 0x0A:
+            case 0x0B:
+            case 0x0C:
+            case 0x0D:
+            case 0x0E:
+            case 0x0F:
+            case 0x10:
+            case 0x11:
+            case 0x12:
+            case 0x13:
+            case 0x14:
+            case 0x15:
+            case 0x16:
+            case 0x17:
+                return sax->number_unsigned(static_cast<number_unsigned_t>(current));
+
+            case 0x18: // Unsigned integer (one-byte uint8_t follows)
+            {
+                std::uint8_t number{};
+                return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
+            }
+
+            case 0x19: // Unsigned integer (two-byte uint16_t follows)
+            {
+                std::uint16_t number{};
+                return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
+            }
+
+            case 0x1A: // Unsigned integer (four-byte uint32_t follows)
+            {
+                std::uint32_t number{};
+                return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
+            }
+
+            case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
+            {
+                std::uint64_t number{};
+                return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
+            }
+
+            // Negative integer -1-0x00..-1-0x17 (-1..-24)
+            case 0x20:
+            case 0x21:
+            case 0x22:
+            case 0x23:
+            case 0x24:
+            case 0x25:
+            case 0x26:
+            case 0x27:
+            case 0x28:
+            case 0x29:
+            case 0x2A:
+            case 0x2B:
+            case 0x2C:
+            case 0x2D:
+            case 0x2E:
+            case 0x2F:
+            case 0x30:
+            case 0x31:
+            case 0x32:
+            case 0x33:
+            case 0x34:
+            case 0x35:
+            case 0x36:
+            case 0x37:
+                return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
+
+            case 0x38: // Negative integer (one-byte uint8_t follows)
+            {
+                std::uint8_t number{};
+                return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
+            }
+
+            case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
+            {
+                std::uint16_t number{};
+                return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
+            }
+
+            case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
+            {
+                std::uint32_t number{};
+                return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
+            }
+
+            case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
+            {
+                std::uint64_t number{};
+                return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
+                        - static_cast<number_integer_t>(number));
+            }
+
+            // Binary data (0x00..0x17 bytes follow)
+            case 0x40:
+            case 0x41:
+            case 0x42:
+            case 0x43:
+            case 0x44:
+            case 0x45:
+            case 0x46:
+            case 0x47:
+            case 0x48:
+            case 0x49:
+            case 0x4A:
+            case 0x4B:
+            case 0x4C:
+            case 0x4D:
+            case 0x4E:
+            case 0x4F:
+            case 0x50:
+            case 0x51:
+            case 0x52:
+            case 0x53:
+            case 0x54:
+            case 0x55:
+            case 0x56:
+            case 0x57:
+            case 0x58: // Binary data (one-byte uint8_t for n follows)
+            case 0x59: // Binary data (two-byte uint16_t for n follow)
+            case 0x5A: // Binary data (four-byte uint32_t for n follow)
+            case 0x5B: // Binary data (eight-byte uint64_t for n follow)
+            case 0x5F: // Binary data (indefinite length)
+            {
+                binary_t b;
+                return get_cbor_binary(b) && sax->binary(b);
+            }
+
+            // UTF-8 string (0x00..0x17 bytes follow)
+            case 0x60:
+            case 0x61:
+            case 0x62:
+            case 0x63:
+            case 0x64:
+            case 0x65:
+            case 0x66:
+            case 0x67:
+            case 0x68:
+            case 0x69:
+            case 0x6A:
+            case 0x6B:
+            case 0x6C:
+            case 0x6D:
+            case 0x6E:
+            case 0x6F:
+            case 0x70:
+            case 0x71:
+            case 0x72:
+            case 0x73:
+            case 0x74:
+            case 0x75:
+            case 0x76:
+            case 0x77:
+            case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
+            case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
+            case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
+            case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
+            case 0x7F: // UTF-8 string (indefinite length)
+            {
+                string_t s;
+                return get_cbor_string(s) && sax->string(s);
+            }
+
+            // array (0x00..0x17 data items follow)
+            case 0x80:
+            case 0x81:
+            case 0x82:
+            case 0x83:
+            case 0x84:
+            case 0x85:
+            case 0x86:
+            case 0x87:
+            case 0x88:
+            case 0x89:
+            case 0x8A:
+            case 0x8B:
+            case 0x8C:
+            case 0x8D:
+            case 0x8E:
+            case 0x8F:
+            case 0x90:
+            case 0x91:
+            case 0x92:
+            case 0x93:
+            case 0x94:
+            case 0x95:
+            case 0x96:
+            case 0x97:
+                return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
+
+            case 0x98: // array (one-byte uint8_t for n follows)
+            {
+                std::uint8_t len{};
+                return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
+            }
+
+            case 0x99: // array (two-byte uint16_t for n follow)
+            {
+                std::uint16_t len{};
+                return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
+            }
+
+            case 0x9A: // array (four-byte uint32_t for n follow)
+            {
+                std::uint32_t len{};
+                return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
+            }
+
+            case 0x9B: // array (eight-byte uint64_t for n follow)
+            {
+                std::uint64_t len{};
+                return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
+            }
+
+            case 0x9F: // array (indefinite length)
+                return get_cbor_array(std::size_t(-1), tag_handler);
+
+            // map (0x00..0x17 pairs of data items follow)
+            case 0xA0:
+            case 0xA1:
+            case 0xA2:
+            case 0xA3:
+            case 0xA4:
+            case 0xA5:
+            case 0xA6:
+            case 0xA7:
+            case 0xA8:
+            case 0xA9:
+            case 0xAA:
+            case 0xAB:
+            case 0xAC:
+            case 0xAD:
+            case 0xAE:
+            case 0xAF:
+            case 0xB0:
+            case 0xB1:
+            case 0xB2:
+            case 0xB3:
+            case 0xB4:
+            case 0xB5:
+            case 0xB6:
+            case 0xB7:
+                return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
+
+            case 0xB8: // map (one-byte uint8_t for n follows)
+            {
+                std::uint8_t len{};
+                return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
+            }
+
+            case 0xB9: // map (two-byte uint16_t for n follow)
+            {
+                std::uint16_t len{};
+                return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
+            }
+
+            case 0xBA: // map (four-byte uint32_t for n follow)
+            {
+                std::uint32_t len{};
+                return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
+            }
+
+            case 0xBB: // map (eight-byte uint64_t for n follow)
+            {
+                std::uint64_t len{};
+                return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
+            }
+
+            case 0xBF: // map (indefinite length)
+                return get_cbor_object(std::size_t(-1), tag_handler);
+
+            case 0xC6: // tagged item
+            case 0xC7:
+            case 0xC8:
+            case 0xC9:
+            case 0xCA:
+            case 0xCB:
+            case 0xCC:
+            case 0xCD:
+            case 0xCE:
+            case 0xCF:
+            case 0xD0:
+            case 0xD1:
+            case 0xD2:
+            case 0xD3:
+            case 0xD4:
+            case 0xD8: // tagged item (1 bytes follow)
+            case 0xD9: // tagged item (2 bytes follow)
+            case 0xDA: // tagged item (4 bytes follow)
+            case 0xDB: // tagged item (8 bytes follow)
+            {
+                switch (tag_handler)
+                {
+                    case cbor_tag_handler_t::error:
+                    {
+                        auto last_token = get_token_string();
+                        return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value")));
+                    }
+
+                    case cbor_tag_handler_t::ignore:
+                    {
+                        switch (current)
+                        {
+                            case 0xD8:
+                            {
+                                std::uint8_t len{};
+                                get_number(input_format_t::cbor, len);
+                                break;
+                            }
+                            case 0xD9:
+                            {
+                                std::uint16_t len{};
+                                get_number(input_format_t::cbor, len);
+                                break;
+                            }
+                            case 0xDA:
+                            {
+                                std::uint32_t len{};
+                                get_number(input_format_t::cbor, len);
+                                break;
+                            }
+                            case 0xDB:
+                            {
+                                std::uint64_t len{};
+                                get_number(input_format_t::cbor, len);
+                                break;
+                            }
+                            default:
+                                break;
+                        }
+                        return parse_cbor_internal(true, tag_handler);
+                    }
+
+                    default:            // LCOV_EXCL_LINE
+                        JSON_ASSERT(false);  // LCOV_EXCL_LINE
+                }
+            }
+
+            case 0xF4: // false
+                return sax->boolean(false);
+
+            case 0xF5: // true
+                return sax->boolean(true);
+
+            case 0xF6: // null
+                return sax->null();
+
+            case 0xF9: // Half-Precision Float (two-byte IEEE 754)
+            {
+                const auto byte1_raw = get();
+                if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
+                {
+                    return false;
+                }
+                const auto byte2_raw = get();
+                if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
+                {
+                    return false;
+                }
+
+                const auto byte1 = static_cast<unsigned char>(byte1_raw);
+                const auto byte2 = static_cast<unsigned char>(byte2_raw);
+
+                // code from RFC 7049, Appendix D, Figure 3:
+                // As half-precision floating-point numbers were only added
+                // to IEEE 754 in 2008, today's programming platforms often
+                // still only have limited support for them. It is very
+                // easy to include at least decoding support for them even
+                // without such support. An example of a small decoder for
+                // half-precision floating-point numbers in the C language
+                // is shown in Fig. 3.
+                const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
+                const double val = [&half]
+                {
+                    const int exp = (half >> 10u) & 0x1Fu;
+                    const unsigned int mant = half & 0x3FFu;
+                    JSON_ASSERT(0 <= exp&& exp <= 32);
+                    JSON_ASSERT(mant <= 1024);
+                    switch (exp)
+                    {
+                        case 0:
+                            return std::ldexp(mant, -24);
+                        case 31:
+                            return (mant == 0)
+                            ? std::numeric_limits<double>::infinity()
+                            : std::numeric_limits<double>::quiet_NaN();
+                        default:
+                            return std::ldexp(mant + 1024, exp - 25);
+                    }
+                }();
+                return sax->number_float((half & 0x8000u) != 0
+                                         ? static_cast<number_float_t>(-val)
+                                         : static_cast<number_float_t>(val), "");
+            }
+
+            case 0xFA: // Single-Precision Float (four-byte IEEE 754)
+            {
+                float number{};
+                return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
+            }
+
+            case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
+            {
+                double number{};
+                return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
+            }
+
+            default: // anything else (0xFF is handled inside the other types)
+            {
+                auto last_token = get_token_string();
+                return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value")));
+            }
+        }
+    }
+
+    /*!
+    @brief reads a CBOR string
+
+    This function first reads starting bytes to determine the expected
+    string length and then copies this number of bytes into a string.
+    Additionally, CBOR's strings with indefinite lengths are supported.
+
+    @param[out] result  created string
+
+    @return whether string creation completed
+    */
+    bool get_cbor_string(string_t& result)
+    {
+        if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
+        {
+            return false;
+        }
+
+        switch (current)
+        {
+            // UTF-8 string (0x00..0x17 bytes follow)
+            case 0x60:
+            case 0x61:
+            case 0x62:
+            case 0x63:
+            case 0x64:
+            case 0x65:
+            case 0x66:
+            case 0x67:
+            case 0x68:
+            case 0x69:
+            case 0x6A:
+            case 0x6B:
+            case 0x6C:
+            case 0x6D:
+            case 0x6E:
+            case 0x6F:
+            case 0x70:
+            case 0x71:
+            case 0x72:
+            case 0x73:
+            case 0x74:
+            case 0x75:
+            case 0x76:
+            case 0x77:
+            {
+                return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
+            }
+
+            case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
+            {
+                std::uint8_t len{};
+                return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
+            }
+
+            case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
+            {
+                std::uint16_t len{};
+                return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
+            }
+
+            case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
+            {
+                std::uint32_t len{};
+                return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
+            }
+
+            case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
+            {
+                std::uint64_t len{};
+                return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
+            }
+
+            case 0x7F: // UTF-8 string (indefinite length)
+            {
+                while (get() != 0xFF)
+                {
+                    string_t chunk;
+                    if (!get_cbor_string(chunk))
+                    {
+                        return false;
+                    }
+                    result.append(chunk);
+                }
+                return true;
+            }
+
+            default:
+            {
+                auto last_token = get_token_string();
+                return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token, "string")));
+            }
+        }
+    }
+
+    /*!
+    @brief reads a CBOR byte array
+
+    This function first reads starting bytes to determine the expected
+    byte array length and then copies this number of bytes into the byte array.
+    Additionally, CBOR's byte arrays with indefinite lengths are supported.
+
+    @param[out] result  created byte array
+
+    @return whether byte array creation completed
+    */
+    bool get_cbor_binary(binary_t& result)
+    {
+        if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
+        {
+            return false;
+        }
+
+        switch (current)
+        {
+            // Binary data (0x00..0x17 bytes follow)
+            case 0x40:
+            case 0x41:
+            case 0x42:
+            case 0x43:
+            case 0x44:
+            case 0x45:
+            case 0x46:
+            case 0x47:
+            case 0x48:
+            case 0x49:
+            case 0x4A:
+            case 0x4B:
+            case 0x4C:
+            case 0x4D:
+            case 0x4E:
+            case 0x4F:
+            case 0x50:
+            case 0x51:
+            case 0x52:
+            case 0x53:
+            case 0x54:
+            case 0x55:
+            case 0x56:
+            case 0x57:
+            {
+                return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
+            }
+
+            case 0x58: // Binary data (one-byte uint8_t for n follows)
+            {
+                std::uint8_t len{};
+                return get_number(input_format_t::cbor, len) &&
+                       get_binary(input_format_t::cbor, len, result);
+            }
+
+            case 0x59: // Binary data (two-byte uint16_t for n follow)
+            {
+                std::uint16_t len{};
+                return get_number(input_format_t::cbor, len) &&
+                       get_binary(input_format_t::cbor, len, result);
+            }
+
+            case 0x5A: // Binary data (four-byte uint32_t for n follow)
+            {
+                std::uint32_t len{};
+                return get_number(input_format_t::cbor, len) &&
+                       get_binary(input_format_t::cbor, len, result);
+            }
+
+            case 0x5B: // Binary data (eight-byte uint64_t for n follow)
+            {
+                std::uint64_t len{};
+                return get_number(input_format_t::cbor, len) &&
+                       get_binary(input_format_t::cbor, len, result);
+            }
+
+            case 0x5F: // Binary data (indefinite length)
+            {
+                while (get() != 0xFF)
+                {
+                    binary_t chunk;
+                    if (!get_cbor_binary(chunk))
+                    {
+                        return false;
+                    }
+                    result.insert(result.end(), chunk.begin(), chunk.end());
+                }
+                return true;
+            }
+
+            default:
+            {
+                auto last_token = get_token_string();
+                return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x" + last_token, "binary")));
+            }
+        }
+    }
+
+    /*!
+    @param[in] len  the length of the array or std::size_t(-1) for an
+                    array of indefinite size
+    @param[in] tag_handler how CBOR tags should be treated
+    @return whether array creation completed
+    */
+    bool get_cbor_array(const std::size_t len,
+                        const cbor_tag_handler_t tag_handler)
+    {
+        if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
+        {
+            return false;
+        }
+
+        if (len != std::size_t(-1))
+        {
+            for (std::size_t i = 0; i < len; ++i)
+            {
+                if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
+                {
+                    return false;
+                }
+            }
+        }
+        else
+        {
+            while (get() != 0xFF)
+            {
+                if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
+                {
+                    return false;
+                }
+            }
+        }
+
+        return sax->end_array();
+    }
+
+    /*!
+    @param[in] len  the length of the object or std::size_t(-1) for an
+                    object of indefinite size
+    @param[in] tag_handler how CBOR tags should be treated
+    @return whether object creation completed
+    */
+    bool get_cbor_object(const std::size_t len,
+                         const cbor_tag_handler_t tag_handler)
+    {
+        if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
+        {
+            return false;
+        }
+
+        string_t key;
+        if (len != std::size_t(-1))
+        {
+            for (std::size_t i = 0; i < len; ++i)
+            {
+                get();
+                if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
+                {
+                    return false;
+                }
+
+                if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
+                {
+                    return false;
+                }
+                key.clear();
+            }
+        }
+        else
+        {
+            while (get() != 0xFF)
+            {
+                if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
+                {
+                    return false;
+                }
+
+                if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
+                {
+                    return false;
+                }
+                key.clear();
+            }
+        }
+
+        return sax->end_object();
+    }
+
+    /////////////
+    // MsgPack //
+    /////////////
+
+    /*!
+    @return whether a valid MessagePack value was passed to the SAX parser
+    */
+    bool parse_msgpack_internal()
+    {
+        switch (get())
+        {
+            // EOF
+            case std::char_traits<char_type>::eof():
+                return unexpect_eof(input_format_t::msgpack, "value");
+
+            // positive fixint
+            case 0x00:
+            case 0x01:
+            case 0x02:
+            case 0x03:
+            case 0x04:
+            case 0x05:
+            case 0x06:
+            case 0x07:
+            case 0x08:
+            case 0x09:
+            case 0x0A:
+            case 0x0B:
+            case 0x0C:
+            case 0x0D:
+            case 0x0E:
+            case 0x0F:
+            case 0x10:
+            case 0x11:
+            case 0x12:
+            case 0x13:
+            case 0x14:
+            case 0x15:
+            case 0x16:
+            case 0x17:
+            case 0x18:
+            case 0x19:
+            case 0x1A:
+            case 0x1B:
+            case 0x1C:
+            case 0x1D:
+            case 0x1E:
+            case 0x1F:
+            case 0x20:
+            case 0x21:
+            case 0x22:
+            case 0x23:
+            case 0x24:
+            case 0x25:
+            case 0x26:
+            case 0x27:
+            case 0x28:
+            case 0x29:
+            case 0x2A:
+            case 0x2B:
+            case 0x2C:
+            case 0x2D:
+            case 0x2E:
+            case 0x2F:
+            case 0x30:
+            case 0x31:
+            case 0x32:
+            case 0x33:
+            case 0x34:
+            case 0x35:
+            case 0x36:
+            case 0x37:
+            case 0x38:
+            case 0x39:
+            case 0x3A:
+            case 0x3B:
+            case 0x3C:
+            case 0x3D:
+            case 0x3E:
+            case 0x3F:
+            case 0x40:
+            case 0x41:
+            case 0x42:
+            case 0x43:
+            case 0x44:
+            case 0x45:
+            case 0x46:
+            case 0x47:
+            case 0x48:
+            case 0x49:
+            case 0x4A:
+            case 0x4B:
+            case 0x4C:
+            case 0x4D:
+            case 0x4E:
+            case 0x4F:
+            case 0x50:
+            case 0x51:
+            case 0x52:
+            case 0x53:
+            case 0x54:
+            case 0x55:
+            case 0x56:
+            case 0x57:
+            case 0x58:
+            case 0x59:
+            case 0x5A:
+            case 0x5B:
+            case 0x5C:
+            case 0x5D:
+            case 0x5E:
+            case 0x5F:
+            case 0x60:
+            case 0x61:
+            case 0x62:
+            case 0x63:
+            case 0x64:
+            case 0x65:
+            case 0x66:
+            case 0x67:
+            case 0x68:
+            case 0x69:
+            case 0x6A:
+            case 0x6B:
+            case 0x6C:
+            case 0x6D:
+            case 0x6E:
+            case 0x6F:
+            case 0x70:
+            case 0x71:
+            case 0x72:
+            case 0x73:
+            case 0x74:
+            case 0x75:
+            case 0x76:
+            case 0x77:
+            case 0x78:
+            case 0x79:
+            case 0x7A:
+            case 0x7B:
+            case 0x7C:
+            case 0x7D:
+            case 0x7E:
+            case 0x7F:
+                return sax->number_unsigned(static_cast<number_unsigned_t>(current));
+
+            // fixmap
+            case 0x80:
+            case 0x81:
+            case 0x82:
+            case 0x83:
+            case 0x84:
+            case 0x85:
+            case 0x86:
+            case 0x87:
+            case 0x88:
+            case 0x89:
+            case 0x8A:
+            case 0x8B:
+            case 0x8C:
+            case 0x8D:
+            case 0x8E:
+            case 0x8F:
+                return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
+
+            // fixarray
+            case 0x90:
+            case 0x91:
+            case 0x92:
+            case 0x93:
+            case 0x94:
+            case 0x95:
+            case 0x96:
+            case 0x97:
+            case 0x98:
+            case 0x99:
+            case 0x9A:
+            case 0x9B:
+            case 0x9C:
+            case 0x9D:
+            case 0x9E:
+            case 0x9F:
+                return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
+
+            // fixstr
+            case 0xA0:
+            case 0xA1:
+            case 0xA2:
+            case 0xA3:
+            case 0xA4:
+            case 0xA5:
+            case 0xA6:
+            case 0xA7:
+            case 0xA8:
+            case 0xA9:
+            case 0xAA:
+            case 0xAB:
+            case 0xAC:
+            case 0xAD:
+            case 0xAE:
+            case 0xAF:
+            case 0xB0:
+            case 0xB1:
+            case 0xB2:
+            case 0xB3:
+            case 0xB4:
+            case 0xB5:
+            case 0xB6:
+            case 0xB7:
+            case 0xB8:
+            case 0xB9:
+            case 0xBA:
+            case 0xBB:
+            case 0xBC:
+            case 0xBD:
+            case 0xBE:
+            case 0xBF:
+            case 0xD9: // str 8
+            case 0xDA: // str 16
+            case 0xDB: // str 32
+            {
+                string_t s;
+                return get_msgpack_string(s) && sax->string(s);
+            }
+
+            case 0xC0: // nil
+                return sax->null();
+
+            case 0xC2: // false
+                return sax->boolean(false);
+
+            case 0xC3: // true
+                return sax->boolean(true);
+
+            case 0xC4: // bin 8
+            case 0xC5: // bin 16
+            case 0xC6: // bin 32
+            case 0xC7: // ext 8
+            case 0xC8: // ext 16
+            case 0xC9: // ext 32
+            case 0xD4: // fixext 1
+            case 0xD5: // fixext 2
+            case 0xD6: // fixext 4
+            case 0xD7: // fixext 8
+            case 0xD8: // fixext 16
+            {
+                binary_t b;
+                return get_msgpack_binary(b) && sax->binary(b);
+            }
+
+            case 0xCA: // float 32
+            {
+                float number{};
+                return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
+            }
+
+            case 0xCB: // float 64
+            {
+                double number{};
+                return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
+            }
+
+            case 0xCC: // uint 8
+            {
+                std::uint8_t number{};
+                return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
+            }
+
+            case 0xCD: // uint 16
+            {
+                std::uint16_t number{};
+                return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
+            }
+
+            case 0xCE: // uint 32
+            {
+                std::uint32_t number{};
+                return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
+            }
+
+            case 0xCF: // uint 64
+            {
+                std::uint64_t number{};
+                return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
+            }
+
+            case 0xD0: // int 8
+            {
+                std::int8_t number{};
+                return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
+            }
+
+            case 0xD1: // int 16
+            {
+                std::int16_t number{};
+                return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
+            }
+
+            case 0xD2: // int 32
+            {
+                std::int32_t number{};
+                return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
+            }
+
+            case 0xD3: // int 64
+            {
+                std::int64_t number{};
+                return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
+            }
+
+            case 0xDC: // array 16
+            {
+                std::uint16_t len{};
+                return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
+            }
+
+            case 0xDD: // array 32
+            {
+                std::uint32_t len{};
+                return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
+            }
+
+            case 0xDE: // map 16
+            {
+                std::uint16_t len{};
+                return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
+            }
+
+            case 0xDF: // map 32
+            {
+                std::uint32_t len{};
+                return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
+            }
+
+            // negative fixint
+            case 0xE0:
+            case 0xE1:
+            case 0xE2:
+            case 0xE3:
+            case 0xE4:
+            case 0xE5:
+            case 0xE6:
+            case 0xE7:
+            case 0xE8:
+            case 0xE9:
+            case 0xEA:
+            case 0xEB:
+            case 0xEC:
+            case 0xED:
+            case 0xEE:
+            case 0xEF:
+            case 0xF0:
+            case 0xF1:
+            case 0xF2:
+            case 0xF3:
+            case 0xF4:
+            case 0xF5:
+            case 0xF6:
+            case 0xF7:
+            case 0xF8:
+            case 0xF9:
+            case 0xFA:
+            case 0xFB:
+            case 0xFC:
+            case 0xFD:
+            case 0xFE:
+            case 0xFF:
+                return sax->number_integer(static_cast<std::int8_t>(current));
+
+            default: // anything else
+            {
+                auto last_token = get_token_string();
+                return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, "invalid byte: 0x" + last_token, "value")));
+            }
+        }
+    }
+
+    /*!
+    @brief reads a MessagePack string
+
+    This function first reads starting bytes to determine the expected
+    string length and then copies this number of bytes into a string.
+
+    @param[out] result  created string
+
+    @return whether string creation completed
+    */
+    bool get_msgpack_string(string_t& result)
+    {
+        if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
+        {
+            return false;
+        }
+
+        switch (current)
+        {
+            // fixstr
+            case 0xA0:
+            case 0xA1:
+            case 0xA2:
+            case 0xA3:
+            case 0xA4:
+            case 0xA5:
+            case 0xA6:
+            case 0xA7:
+            case 0xA8:
+            case 0xA9:
+            case 0xAA:
+            case 0xAB:
+            case 0xAC:
+            case 0xAD:
+            case 0xAE:
+            case 0xAF:
+            case 0xB0:
+            case 0xB1:
+            case 0xB2:
+            case 0xB3:
+            case 0xB4:
+            case 0xB5:
+            case 0xB6:
+            case 0xB7:
+            case 0xB8:
+            case 0xB9:
+            case 0xBA:
+            case 0xBB:
+            case 0xBC:
+            case 0xBD:
+            case 0xBE:
+            case 0xBF:
+            {
+                return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
+            }
+
+            case 0xD9: // str 8
+            {
+                std::uint8_t len{};
+                return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
+            }
+
+            case 0xDA: // str 16
+            {
+                std::uint16_t len{};
+                return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
+            }
+
+            case 0xDB: // str 32
+            {
+                std::uint32_t len{};
+                return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
+            }
+
+            default:
+            {
+                auto last_token = get_token_string();
+                return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, "expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token, "string")));
+            }
+        }
+    }
+
+    /*!
+    @brief reads a MessagePack byte array
+
+    This function first reads starting bytes to determine the expected
+    byte array length and then copies this number of bytes into a byte array.
+
+    @param[out] result  created byte array
+
+    @return whether byte array creation completed
+    */
+    bool get_msgpack_binary(binary_t& result)
+    {
+        // helper function to set the subtype
+        auto assign_and_return_true = [&result](std::int8_t subtype)
+        {
+            result.set_subtype(static_cast<std::uint8_t>(subtype));
+            return true;
+        };
+
+        switch (current)
+        {
+            case 0xC4: // bin 8
+            {
+                std::uint8_t len{};
+                return get_number(input_format_t::msgpack, len) &&
+                       get_binary(input_format_t::msgpack, len, result);
+            }
+
+            case 0xC5: // bin 16
+            {
+                std::uint16_t len{};
+                return get_number(input_format_t::msgpack, len) &&
+                       get_binary(input_format_t::msgpack, len, result);
+            }
+
+            case 0xC6: // bin 32
+            {
+                std::uint32_t len{};
+                return get_number(input_format_t::msgpack, len) &&
+                       get_binary(input_format_t::msgpack, len, result);
+            }
+
+            case 0xC7: // ext 8
+            {
+                std::uint8_t len{};
+                std::int8_t subtype{};
+                return get_number(input_format_t::msgpack, len) &&
+                       get_number(input_format_t::msgpack, subtype) &&
+                       get_binary(input_format_t::msgpack, len, result) &&
+                       assign_and_return_true(subtype);
+            }
+
+            case 0xC8: // ext 16
+            {
+                std::uint16_t len{};
+                std::int8_t subtype{};
+                return get_number(input_format_t::msgpack, len) &&
+                       get_number(input_format_t::msgpack, subtype) &&
+                       get_binary(input_format_t::msgpack, len, result) &&
+                       assign_and_return_true(subtype);
+            }
+
+            case 0xC9: // ext 32
+            {
+                std::uint32_t len{};
+                std::int8_t subtype{};
+                return get_number(input_format_t::msgpack, len) &&
+                       get_number(input_format_t::msgpack, subtype) &&
+                       get_binary(input_format_t::msgpack, len, result) &&
+                       assign_and_return_true(subtype);
+            }
+
+            case 0xD4: // fixext 1
+            {
+                std::int8_t subtype{};
+                return get_number(input_format_t::msgpack, subtype) &&
+                       get_binary(input_format_t::msgpack, 1, result) &&
+                       assign_and_return_true(subtype);
+            }
+
+            case 0xD5: // fixext 2
+            {
+                std::int8_t subtype{};
+                return get_number(input_format_t::msgpack, subtype) &&
+                       get_binary(input_format_t::msgpack, 2, result) &&
+                       assign_and_return_true(subtype);
+            }
+
+            case 0xD6: // fixext 4
+            {
+                std::int8_t subtype{};
+                return get_number(input_format_t::msgpack, subtype) &&
+                       get_binary(input_format_t::msgpack, 4, result) &&
+                       assign_and_return_true(subtype);
+            }
+
+            case 0xD7: // fixext 8
+            {
+                std::int8_t subtype{};
+                return get_number(input_format_t::msgpack, subtype) &&
+                       get_binary(input_format_t::msgpack, 8, result) &&
+                       assign_and_return_true(subtype);
+            }
+
+            case 0xD8: // fixext 16
+            {
+                std::int8_t subtype{};
+                return get_number(input_format_t::msgpack, subtype) &&
+                       get_binary(input_format_t::msgpack, 16, result) &&
+                       assign_and_return_true(subtype);
+            }
+
+            default:           // LCOV_EXCL_LINE
+                return false;  // LCOV_EXCL_LINE
+        }
+    }
+
+    /*!
+    @param[in] len  the length of the array
+    @return whether array creation completed
+    */
+    bool get_msgpack_array(const std::size_t len)
+    {
+        if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
+        {
+            return false;
+        }
+
+        for (std::size_t i = 0; i < len; ++i)
+        {
+            if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
+            {
+                return false;
+            }
+        }
+
+        return sax->end_array();
+    }
+
+    /*!
+    @param[in] len  the length of the object
+    @return whether object creation completed
+    */
+    bool get_msgpack_object(const std::size_t len)
+    {
+        if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
+        {
+            return false;
+        }
+
+        string_t key;
+        for (std::size_t i = 0; i < len; ++i)
+        {
+            get();
+            if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
+            {
+                return false;
+            }
+
+            if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
+            {
+                return false;
+            }
+            key.clear();
+        }
+
+        return sax->end_object();
+    }
+
+    ////////////
+    // UBJSON //
+    ////////////
+
+    /*!
+    @param[in] get_char  whether a new character should be retrieved from the
+                         input (true, default) or whether the last read
+                         character should be considered instead
+
+    @return whether a valid UBJSON value was passed to the SAX parser
+    */
+    bool parse_ubjson_internal(const bool get_char = true)
+    {
+        return get_ubjson_value(get_char ? get_ignore_noop() : current);
+    }
+
+    /*!
+    @brief reads a UBJSON string
+
+    This function is either called after reading the 'S' byte explicitly
+    indicating a string, or in case of an object key where the 'S' byte can be
+    left out.
+
+    @param[out] result   created string
+    @param[in] get_char  whether a new character should be retrieved from the
+                         input (true, default) or whether the last read
+                         character should be considered instead
+
+    @return whether string creation completed
+    */
+    bool get_ubjson_string(string_t& result, const bool get_char = true)
+    {
+        if (get_char)
+        {
+            get();  // TODO(niels): may we ignore N here?
+        }
+
+        if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
+        {
+            return false;
+        }
+
+        switch (current)
+        {
+            case 'U':
+            {
+                std::uint8_t len{};
+                return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
+            }
+
+            case 'i':
+            {
+                std::int8_t len{};
+                return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
+            }
+
+            case 'I':
+            {
+                std::int16_t len{};
+                return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
+            }
+
+            case 'l':
+            {
+                std::int32_t len{};
+                return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
+            }
+
+            case 'L':
+            {
+                std::int64_t len{};
+                return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
+            }
+
+            default:
+                auto last_token = get_token_string();
+                return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string")));
+        }
+    }
+
+    /*!
+    @param[out] result  determined size
+    @return whether size determination completed
+    */
+    bool get_ubjson_size_value(std::size_t& result)
+    {
+        switch (get_ignore_noop())
+        {
+            case 'U':
+            {
+                std::uint8_t number{};
+                if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
+                {
+                    return false;
+                }
+                result = static_cast<std::size_t>(number);
+                return true;
+            }
+
+            case 'i':
+            {
+                std::int8_t number{};
+                if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
+                {
+                    return false;
+                }
+                result = static_cast<std::size_t>(number);
+                return true;
+            }
+
+            case 'I':
+            {
+                std::int16_t number{};
+                if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
+                {
+                    return false;
+                }
+                result = static_cast<std::size_t>(number);
+                return true;
+            }
+
+            case 'l':
+            {
+                std::int32_t number{};
+                if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
+                {
+                    return false;
+                }
+                result = static_cast<std::size_t>(number);
+                return true;
+            }
+
+            case 'L':
+            {
+                std::int64_t number{};
+                if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
+                {
+                    return false;
+                }
+                result = static_cast<std::size_t>(number);
+                return true;
+            }
+
+            default:
+            {
+                auto last_token = get_token_string();
+                return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size")));
+            }
+        }
+    }
+
+    /*!
+    @brief determine the type and size for a container
+
+    In the optimized UBJSON format, a type and a size can be provided to allow
+    for a more compact representation.
+
+    @param[out] result  pair of the size and the type
+
+    @return whether pair creation completed
+    */
+    bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)
+    {
+        result.first = string_t::npos; // size
+        result.second = 0; // type
+
+        get_ignore_noop();
+
+        if (current == '$')
+        {
+            result.second = get();  // must not ignore 'N', because 'N' maybe the type
+            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "type")))
+            {
+                return false;
+            }
+
+            get_ignore_noop();
+            if (JSON_HEDLEY_UNLIKELY(current != '#'))
+            {
+                if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
+                {
+                    return false;
+                }
+                auto last_token = get_token_string();
+                return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "expected '#' after type information; last byte: 0x" + last_token, "size")));
+            }
+
+            return get_ubjson_size_value(result.first);
+        }
+
+        if (current == '#')
+        {
+            return get_ubjson_size_value(result.first);
+        }
+
+        return true;
+    }
+
+    /*!
+    @param prefix  the previously read or set type prefix
+    @return whether value creation completed
+    */
+    bool get_ubjson_value(const char_int_type prefix)
+    {
+        switch (prefix)
+        {
+            case std::char_traits<char_type>::eof():  // EOF
+                return unexpect_eof(input_format_t::ubjson, "value");
+
+            case 'T':  // true
+                return sax->boolean(true);
+            case 'F':  // false
+                return sax->boolean(false);
+
+            case 'Z':  // null
+                return sax->null();
+
+            case 'U':
+            {
+                std::uint8_t number{};
+                return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number);
+            }
+
+            case 'i':
+            {
+                std::int8_t number{};
+                return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
+            }
+
+            case 'I':
+            {
+                std::int16_t number{};
+                return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
+            }
+
+            case 'l':
+            {
+                std::int32_t number{};
+                return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
+            }
+
+            case 'L':
+            {
+                std::int64_t number{};
+                return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
+            }
+
+            case 'd':
+            {
+                float number{};
+                return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
+            }
+
+            case 'D':
+            {
+                double number{};
+                return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
+            }
+
+            case 'H':
+            {
+                return get_ubjson_high_precision_number();
+            }
+
+            case 'C':  // char
+            {
+                get();
+                if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "char")))
+                {
+                    return false;
+                }
+                if (JSON_HEDLEY_UNLIKELY(current > 127))
+                {
+                    auto last_token = get_token_string();
+                    return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char")));
+                }
+                string_t s(1, static_cast<typename string_t::value_type>(current));
+                return sax->string(s);
+            }
+
+            case 'S':  // string
+            {
+                string_t s;
+                return get_ubjson_string(s) && sax->string(s);
+            }
+
+            case '[':  // array
+                return get_ubjson_array();
+
+            case '{':  // object
+                return get_ubjson_object();
+
+            default: // anything else
+            {
+                auto last_token = get_token_string();
+                return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "invalid byte: 0x" + last_token, "value")));
+            }
+        }
+    }
+
+    /*!
+    @return whether array creation completed
+    */
+    bool get_ubjson_array()
+    {
+        std::pair<std::size_t, char_int_type> size_and_type;
+        if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
+        {
+            return false;
+        }
+
+        if (size_and_type.first != string_t::npos)
+        {
+            if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
+            {
+                return false;
+            }
+
+            if (size_and_type.second != 0)
+            {
+                if (size_and_type.second != 'N')
+                {
+                    for (std::size_t i = 0; i < size_and_type.first; ++i)
+                    {
+                        if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
+                        {
+                            return false;
+                        }
+                    }
+                }
+            }
+            else
+            {
+                for (std::size_t i = 0; i < size_and_type.first; ++i)
+                {
+                    if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
+                    {
+                        return false;
+                    }
+                }
+            }
+        }
+        else
+        {
+            if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
+            {
+                return false;
+            }
+
+            while (current != ']')
+            {
+                if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
+                {
+                    return false;
+                }
+                get_ignore_noop();
+            }
+        }
+
+        return sax->end_array();
+    }
+
+    /*!
+    @return whether object creation completed
+    */
+    bool get_ubjson_object()
+    {
+        std::pair<std::size_t, char_int_type> size_and_type;
+        if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
+        {
+            return false;
+        }
+
+        string_t key;
+        if (size_and_type.first != string_t::npos)
+        {
+            if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
+            {
+                return false;
+            }
+
+            if (size_and_type.second != 0)
+            {
+                for (std::size_t i = 0; i < size_and_type.first; ++i)
+                {
+                    if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
+                    {
+                        return false;
+                    }
+                    if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
+                    {
+                        return false;
+                    }
+                    key.clear();
+                }
+            }
+            else
+            {
+                for (std::size_t i = 0; i < size_and_type.first; ++i)
+                {
+                    if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
+                    {
+                        return false;
+                    }
+                    if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
+                    {
+                        return false;
+                    }
+                    key.clear();
+                }
+            }
+        }
+        else
+        {
+            if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
+            {
+                return false;
+            }
+
+            while (current != '}')
+            {
+                if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
+                {
+                    return false;
+                }
+                if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
+                {
+                    return false;
+                }
+                get_ignore_noop();
+                key.clear();
+            }
+        }
+
+        return sax->end_object();
+    }
+
+    // Note, no reader for UBJSON binary types is implemented because they do
+    // not exist
+
+    bool get_ubjson_high_precision_number()
+    {
+        // get size of following number string
+        std::size_t size{};
+        auto res = get_ubjson_size_value(size);
+        if (JSON_HEDLEY_UNLIKELY(!res))
+        {
+            return res;
+        }
+
+        // get number string
+        std::vector<char> number_vector;
+        for (std::size_t i = 0; i < size; ++i)
+        {
+            get();
+            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "number")))
+            {
+                return false;
+            }
+            number_vector.push_back(static_cast<char>(current));
+        }
+
+        // parse number string
+        auto number_ia = detail::input_adapter(std::forward<decltype(number_vector)>(number_vector));
+        auto number_lexer = detail::lexer<BasicJsonType, decltype(number_ia)>(std::move(number_ia), false);
+        const auto result_number = number_lexer.scan();
+        const auto number_string = number_lexer.get_token_string();
+        const auto result_remainder = number_lexer.scan();
+
+        using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
+
+        if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
+        {
+            return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number")));
+        }
+
+        switch (result_number)
+        {
+            case token_type::value_integer:
+                return sax->number_integer(number_lexer.get_number_integer());
+            case token_type::value_unsigned:
+                return sax->number_unsigned(number_lexer.get_number_unsigned());
+            case token_type::value_float:
+                return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
+            default:
+                return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number")));
+        }
+    }
+
+    ///////////////////////
+    // Utility functions //
+    ///////////////////////
+
+    /*!
+    @brief get next character from the input
+
+    This function provides the interface to the used input adapter. It does
+    not throw in case the input reached EOF, but returns a -'ve valued
+    `std::char_traits<char_type>::eof()` in that case.
+
+    @return character read from the input
+    */
+    char_int_type get()
+    {
+        ++chars_read;
+        return current = ia.get_character();
+    }
+
+    /*!
+    @return character read from the input after ignoring all 'N' entries
+    */
+    char_int_type get_ignore_noop()
+    {
+        do
+        {
+            get();
+        }
+        while (current == 'N');
+
+        return current;
+    }
+
+    /*
+    @brief read a number from the input
+
+    @tparam NumberType the type of the number
+    @param[in] format   the current format (for diagnostics)
+    @param[out] result  number of type @a NumberType
+
+    @return whether conversion completed
+
+    @note This function needs to respect the system's endianess, because
+          bytes in CBOR, MessagePack, and UBJSON are stored in network order
+          (big endian) and therefore need reordering on little endian systems.
+    */
+    template<typename NumberType, bool InputIsLittleEndian = false>
+    bool get_number(const input_format_t format, NumberType& result)
+    {
+        // step 1: read input into array with system's byte order
+        std::array<std::uint8_t, sizeof(NumberType)> vec;
+        for (std::size_t i = 0; i < sizeof(NumberType); ++i)
+        {
+            get();
+            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
+            {
+                return false;
+            }
+
+            // reverse byte order prior to conversion if necessary
+            if (is_little_endian != InputIsLittleEndian)
+            {
+                vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
+            }
+            else
+            {
+                vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
+            }
+        }
+
+        // step 2: convert array into number of type T and return
+        std::memcpy(&result, vec.data(), sizeof(NumberType));
+        return true;
+    }
+
+    /*!
+    @brief create a string by reading characters from the input
+
+    @tparam NumberType the type of the number
+    @param[in] format the current format (for diagnostics)
+    @param[in] len number of characters to read
+    @param[out] result string created by reading @a len bytes
+
+    @return whether string creation completed
+
+    @note We can not reserve @a len bytes for the result, because @a len
+          may be too large. Usually, @ref unexpect_eof() detects the end of
+          the input before we run out of string memory.
+    */
+    template<typename NumberType>
+    bool get_string(const input_format_t format,
+                    const NumberType len,
+                    string_t& result)
+    {
+        bool success = true;
+        for (NumberType i = 0; i < len; i++)
+        {
+            get();
+            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
+            {
+                success = false;
+                break;
+            }
+            result.push_back(static_cast<typename string_t::value_type>(current));
+        };
+        return success;
+    }
+
+    /*!
+    @brief create a byte array by reading bytes from the input
+
+    @tparam NumberType the type of the number
+    @param[in] format the current format (for diagnostics)
+    @param[in] len number of bytes to read
+    @param[out] result byte array created by reading @a len bytes
+
+    @return whether byte array creation completed
+
+    @note We can not reserve @a len bytes for the result, because @a len
+          may be too large. Usually, @ref unexpect_eof() detects the end of
+          the input before we run out of memory.
+    */
+    template<typename NumberType>
+    bool get_binary(const input_format_t format,
+                    const NumberType len,
+                    binary_t& result)
+    {
+        bool success = true;
+        for (NumberType i = 0; i < len; i++)
+        {
+            get();
+            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
+            {
+                success = false;
+                break;
+            }
+            result.push_back(static_cast<std::uint8_t>(current));
+        }
+        return success;
+    }
+
+    /*!
+    @param[in] format   the current format (for diagnostics)
+    @param[in] context  further context information (for diagnostics)
+    @return whether the last read character is not EOF
+    */
+    JSON_HEDLEY_NON_NULL(3)
+    bool unexpect_eof(const input_format_t format, const char* context) const
+    {
+        if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
+        {
+            return sax->parse_error(chars_read, "<end of file>",
+                                    parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context)));
+        }
+        return true;
+    }
+
+    /*!
+    @return a string representation of the last read byte
+    */
+    std::string get_token_string() const
+    {
+        std::array<char, 3> cr{{}};
+        (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current));
+        return std::string{cr.data()};
+    }
+
+    /*!
+    @param[in] format   the current format
+    @param[in] detail   a detailed error message
+    @param[in] context  further context information
+    @return a message string to use in the parse_error exceptions
+    */
+    std::string exception_message(const input_format_t format,
+                                  const std::string& detail,
+                                  const std::string& context) const
+    {
+        std::string error_msg = "syntax error while parsing ";
+
+        switch (format)
+        {
+            case input_format_t::cbor:
+                error_msg += "CBOR";
+                break;
+
+            case input_format_t::msgpack:
+                error_msg += "MessagePack";
+                break;
+
+            case input_format_t::ubjson:
+                error_msg += "UBJSON";
+                break;
+
+            case input_format_t::bson:
+                error_msg += "BSON";
+                break;
+
+            default:            // LCOV_EXCL_LINE
+                JSON_ASSERT(false);  // LCOV_EXCL_LINE
+        }
+
+        return error_msg + " " + context + ": " + detail;
+    }
+
+  private:
+    /// input adapter
+    InputAdapterType ia;
+
+    /// the current character
+    char_int_type current = std::char_traits<char_type>::eof();
+
+    /// the number of characters read
+    std::size_t chars_read = 0;
+
+    /// whether we can assume little endianess
+    const bool is_little_endian = little_endianess();
+
+    /// the SAX parser
+    json_sax_t* sax = nullptr;
+};
+}  // namespace detail
+}  // namespace nlohmann
+
+// #include <nlohmann/detail/input/input_adapters.hpp>
+
+// #include <nlohmann/detail/input/lexer.hpp>
+
+// #include <nlohmann/detail/input/parser.hpp>
+
+
+#include <cmath> // isfinite
+#include <cstdint> // uint8_t
+#include <functional> // function
+#include <string> // string
+#include <utility> // move
+#include <vector> // vector
+
+// #include <nlohmann/detail/exceptions.hpp>
+
+// #include <nlohmann/detail/input/input_adapters.hpp>
+
+// #include <nlohmann/detail/input/json_sax.hpp>
+
+// #include <nlohmann/detail/input/lexer.hpp>
+
+// #include <nlohmann/detail/macro_scope.hpp>
+
+// #include <nlohmann/detail/meta/is_sax.hpp>
+
+// #include <nlohmann/detail/value_t.hpp>
+
+
+namespace nlohmann
+{
+namespace detail
+{
+////////////
+// parser //
+////////////
+
+enum class parse_event_t : uint8_t
+{
+    /// the parser read `{` and started to process a JSON object
+    object_start,
+    /// the parser read `}` and finished processing a JSON object
+    object_end,
+    /// the parser read `[` and started to process a JSON array
+    array_start,
+    /// the parser read `]` and finished processing a JSON array
+    array_end,
+    /// the parser read a key of a value in an object
+    key,
+    /// the parser finished reading a JSON value
+    value
+};
+
+template<typename BasicJsonType>
+using parser_callback_t =
+    std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
+
+/*!
+@brief syntax analysis
+
+This class implements a recursive descent parser.
+*/
+template<typename BasicJsonType, typename InputAdapterType>
+class parser
+{
+    using number_integer_t = typename BasicJsonType::number_integer_t;
+    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+    using number_float_t = typename BasicJsonType::number_float_t;
+    using string_t = typename BasicJsonType::string_t;
+    using lexer_t = lexer<BasicJsonType, InputAdapterType>;
+    using token_type = typename lexer_t::token_type;
+
+  public:
+    /// a parser reading from an input adapter
+    explicit parser(InputAdapterType&& adapter,
+                    const parser_callback_t<BasicJsonType> cb = nullptr,
+                    const bool allow_exceptions_ = true,
+                    const bool skip_comments = false)
+        : callback(cb)
+        , m_lexer(std::move(adapter), skip_comments)
+        , allow_exceptions(allow_exceptions_)
+    {
+        // read first token
+        get_token();
+    }
+
+    /*!
+    @brief public parser interface
+
+    @param[in] strict      whether to expect the last token to be EOF
+    @param[in,out] result  parsed JSON value
+
+    @throw parse_error.101 in case of an unexpected token
+    @throw parse_error.102 if to_unicode fails or surrogate error
+    @throw parse_error.103 if to_unicode fails
+    */
+    void parse(const bool strict, BasicJsonType& result)
+    {
+        if (callback)
+        {
+            json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
+            sax_parse_internal(&sdp);
+            result.assert_invariant();
+
+            // in strict mode, input must be completely read
+            if (strict && (get_token() != token_type::end_of_input))
+            {
+                sdp.parse_error(m_lexer.get_position(),
+                                m_lexer.get_token_string(),
+                                parse_error::create(101, m_lexer.get_position(),
+                                                    exception_message(token_type::end_of_input, "value")));
+            }
+
+            // in case of an error, return discarded value
+            if (sdp.is_errored())
+            {
+                result = value_t::discarded;
+                return;
+            }
+
+            // set top-level value to null if it was discarded by the callback
+            // function
+            if (result.is_discarded())
+            {
+                result = nullptr;
+            }
+        }
+        else
+        {
+            json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
+            sax_parse_internal(&sdp);
+            result.assert_invariant();
+
+            // in strict mode, input must be completely read
+            if (strict && (get_token() != token_type::end_of_input))
+            {
+                sdp.parse_error(m_lexer.get_position(),
+                                m_lexer.get_token_string(),
+                                parse_error::create(101, m_lexer.get_position(),
+                                                    exception_message(token_type::end_of_input, "value")));
+            }
+
+            // in case of an error, return discarded value
+            if (sdp.is_errored())
+            {
+                result = value_t::discarded;
+                return;
+            }
+        }
+    }
+
+    /*!
+    @brief public accept interface
+
+    @param[in] strict  whether to expect the last token to be EOF
+    @return whether the input is a proper JSON text
+    */
+    bool accept(const bool strict = true)
+    {
+        json_sax_acceptor<BasicJsonType> sax_acceptor;
+        return sax_parse(&sax_acceptor, strict);
+    }
+
+    template<typename SAX>
+    JSON_HEDLEY_NON_NULL(2)
+    bool sax_parse(SAX* sax, const bool strict = true)
+    {
+        (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
+        const bool result = sax_parse_internal(sax);
+
+        // strict mode: next byte must be EOF
+        if (result && strict && (get_token() != token_type::end_of_input))
+        {
+            return sax->parse_error(m_lexer.get_position(),
+                                    m_lexer.get_token_string(),
+                                    parse_error::create(101, m_lexer.get_position(),
+                                            exception_message(token_type::end_of_input, "value")));
+        }
+
+        return result;
+    }
+
+  private:
+    template<typename SAX>
+    JSON_HEDLEY_NON_NULL(2)
+    bool sax_parse_internal(SAX* sax)
+    {
+        // stack to remember the hierarchy of structured values we are parsing
+        // true = array; false = object
+        std::vector<bool> states;
+        // value to avoid a goto (see comment where set to true)
+        bool skip_to_state_evaluation = false;
+
+        while (true)
+        {
+            if (!skip_to_state_evaluation)
+            {
+                // invariant: get_token() was called before each iteration
+                switch (last_token)
+                {
+                    case token_type::begin_object:
+                    {
+                        if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
+                        {
+                            return false;
+                        }
+
+                        // closing } -> we are done
+                        if (get_token() == token_type::end_object)
+                        {
+                            if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
+                            {
+                                return false;
+                            }
+                            break;
+                        }
+
+                        // parse key
+                        if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
+                        {
+                            return sax->parse_error(m_lexer.get_position(),
+                                                    m_lexer.get_token_string(),
+                                                    parse_error::create(101, m_lexer.get_position(),
+                                                            exception_message(token_type::value_string, "object key")));
+                        }
+                        if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
+                        {
+                            return false;
+                        }
+
+                        // parse separator (:)
+                        if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
+                        {
+                            return sax->parse_error(m_lexer.get_position(),
+                                                    m_lexer.get_token_string(),
+                                                    parse_error::create(101, m_lexer.get_position(),
+                                                            exception_message(token_type::name_separator, "object separator")));
+                        }
+
+                        // remember we are now inside an object
+                        states.push_back(false);
+
+                        // parse values
+                        get_token();
+                        continue;
+                    }
+
+                    case token_type::begin_array:
+                    {
+                        if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
+                        {
+                            return false;
+                        }
+
+                        // closing ] -> we are done
+                        if (get_token() == token_type::end_array)
+                        {
+                            if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
+                            {
+                                return false;
+                            }
+                            break;
+                        }
+
+                        // remember we are now inside an array
+                        states.push_back(true);
+
+                        // parse values (no need to call get_token)
+                        continue;
+                    }
+
+                    case token_type::value_float:
+                    {
+                        const auto res = m_lexer.get_number_float();
+
+                        if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
+                        {
+                            return sax->parse_error(m_lexer.get_position(),
+                                                    m_lexer.get_token_string(),
+                                                    out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
+                        }
+
+                        if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
+                        {
+                            return false;
+                        }
+
+                        break;
+                    }
+
+                    case token_type::literal_false:
+                    {
+                        if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
+                        {
+                            return false;
+                        }
+                        break;
+                    }
+
+                    case token_type::literal_null:
+                    {
+                        if (JSON_HEDLEY_UNLIKELY(!sax->null()))
+                        {
+                            return false;
+                        }
+                        break;
+                    }
+
+                    case token_type::literal_true:
+                    {
+                        if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
+                        {
+                            return false;
+                        }
+                        break;
+                    }
+
+                    case token_type::value_integer:
+                    {
+                        if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
+                        {
+                            return false;
+                        }
+                        break;
+                    }
+
+                    case token_type::value_string:
+                    {
+                        if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
+                        {
+                            return false;
+                        }
+                        break;
+                    }
+
+                    case token_type::value_unsigned:
+                    {
+                        if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
+                        {
+                            return false;
+                        }
+                        break;
+                    }
+
+                    case token_type::parse_error:
+                    {
+                        // using "uninitialized" to avoid "expected" message
+                        return sax->parse_error(m_lexer.get_position(),
+                                                m_lexer.get_token_string(),
+                                                parse_error::create(101, m_lexer.get_position(),
+                                                        exception_message(token_type::uninitialized, "value")));
+                    }
+
+                    default: // the last token was unexpected
+                    {
+                        return sax->parse_error(m_lexer.get_position(),
+                                                m_lexer.get_token_string(),
+                                                parse_error::create(101, m_lexer.get_position(),
+                                                        exception_message(token_type::literal_or_value, "value")));
+                    }
+                }
+            }
+            else
+            {
+                skip_to_state_evaluation = false;
+            }
+
+            // we reached this line after we successfully parsed a value
+            if (states.empty())
+            {
+                // empty stack: we reached the end of the hierarchy: done
+                return true;
+            }
+
+            if (states.back())  // array
+            {
+                // comma -> next value
+                if (get_token() == token_type::value_separator)
+                {
+                    // parse a new value
+                    get_token();
+                    continue;
+                }
+
+                // closing ]
+                if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
+                {
+                    if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
+                    {
+                        return false;
+                    }
+
+                    // We are done with this array. Before we can parse a
+                    // new value, we need to evaluate the new state first.
+                    // By setting skip_to_state_evaluation to false, we
+                    // are effectively jumping to the beginning of this if.
+                    JSON_ASSERT(!states.empty());
+                    states.pop_back();
+                    skip_to_state_evaluation = true;
+                    continue;
+                }
+
+                return sax->parse_error(m_lexer.get_position(),
+                                        m_lexer.get_token_string(),
+                                        parse_error::create(101, m_lexer.get_position(),
+                                                exception_message(token_type::end_array, "array")));
+            }
+            else  // object
+            {
+                // comma -> next value
+                if (get_token() == token_type::value_separator)
+                {
+                    // parse key
+                    if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
+                    {
+                        return sax->parse_error(m_lexer.get_position(),
+                                                m_lexer.get_token_string(),
+                                                parse_error::create(101, m_lexer.get_position(),
+                                                        exception_message(token_type::value_string, "object key")));
+                    }
+
+                    if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
+                    {
+                        return false;
+                    }
+
+                    // parse separator (:)
+                    if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
+                    {
+                        return sax->parse_error(m_lexer.get_position(),
+                                                m_lexer.get_token_string(),
+                                                parse_error::create(101, m_lexer.get_position(),
+                                                        exception_message(token_type::name_separator, "object separator")));
+                    }
+
+                    // parse values
+                    get_token();
+                    continue;
+                }
+
+                // closing }
+                if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
+                {
+                    if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
+                    {
+                        return false;
+                    }
+
+                    // We are done with this object. Before we can parse a
+                    // new value, we need to evaluate the new state first.
+                    // By setting skip_to_state_evaluation to false, we
+                    // are effectively jumping to the beginning of this if.
+                    JSON_ASSERT(!states.empty());
+                    states.pop_back();
+                    skip_to_state_evaluation = true;
+                    continue;
+                }
+
+                return sax->parse_error(m_lexer.get_position(),
+                                        m_lexer.get_token_string(),
+                                        parse_error::create(101, m_lexer.get_position(),
+                                                exception_message(token_type::end_object, "object")));
+            }
+        }
+    }
+
+    /// get next token from lexer
+    token_type get_token()
+    {
+        return last_token = m_lexer.scan();
+    }
+
+    std::string exception_message(const token_type expected, const std::string& context)
+    {
+        std::string error_msg = "syntax error ";
+
+        if (!context.empty())
+        {
+            error_msg += "while parsing " + context + " ";
+        }
+
+        error_msg += "- ";
+
+        if (last_token == token_type::parse_error)
+        {
+            error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
+                         m_lexer.get_token_string() + "'";
+        }
+        else
+        {
+            error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
+        }
+
+        if (expected != token_type::uninitialized)
+        {
+            error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
+        }
+
+        return error_msg;
+    }
+
+  private:
+    /// callback function
+    const parser_callback_t<BasicJsonType> callback = nullptr;
+    /// the type of the last read token
+    token_type last_token = token_type::uninitialized;
+    /// the lexer
+    lexer_t m_lexer;
+    /// whether to throw exceptions in case of errors
+    const bool allow_exceptions = true;
+};
+}  // namespace detail
+}  // namespace nlohmann
+
+// #include <nlohmann/detail/iterators/internal_iterator.hpp>
+
+
+// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
+
+
+#include <cstddef> // ptrdiff_t
+#include <limits>  // numeric_limits
+
+namespace nlohmann
+{
+namespace detail
+{
+/*
+@brief an iterator for primitive JSON types
+
+This class models an iterator for primitive JSON types (boolean, number,
+string). It's only purpose is to allow the iterator/const_iterator classes
+to "iterate" over primitive values. Internally, the iterator is modeled by
+a `difference_type` variable. Value begin_value (`0`) models the begin,
+end_value (`1`) models past the end.
+*/
+class primitive_iterator_t
+{
+  private:
+    using difference_type = std::ptrdiff_t;
+    static constexpr difference_type begin_value = 0;
+    static constexpr difference_type end_value = begin_value + 1;
+
+    /// iterator as signed integer type
+    difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
+
+  public:
+    constexpr difference_type get_value() const noexcept
+    {
+        return m_it;
+    }
+
+    /// set iterator to a defined beginning
+    void set_begin() noexcept
+    {
+        m_it = begin_value;
+    }
+
+    /// set iterator to a defined past the end
+    void set_end() noexcept
+    {
+        m_it = end_value;
+    }
+
+    /// return whether the iterator can be dereferenced
+    constexpr bool is_begin() const noexcept
+    {
+        return m_it == begin_value;
+    }
+
+    /// return whether the iterator is at end
+    constexpr bool is_end() const noexcept
+    {
+        return m_it == end_value;
+    }
+
+    friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
+    {
+        return lhs.m_it == rhs.m_it;
+    }
+
+    friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
+    {
+        return lhs.m_it < rhs.m_it;
+    }
+
+    primitive_iterator_t operator+(difference_type n) noexcept
+    {
+        auto result = *this;
+        result += n;
+        return result;
+    }
+
+    friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
+    {
+        return lhs.m_it - rhs.m_it;
+    }
+
+    primitive_iterator_t& operator++() noexcept
+    {
+        ++m_it;
+        return *this;
+    }
+
+    primitive_iterator_t const operator++(int) noexcept
+    {
+        auto result = *this;
+        ++m_it;
+        return result;
+    }
+
+    primitive_iterator_t& operator--() noexcept
+    {
+        --m_it;
+        return *this;
+    }
+
+    primitive_iterator_t const operator--(int) noexcept
+    {
+        auto result = *this;
+        --m_it;
+        return result;
+    }
+
+    primitive_iterator_t& operator+=(difference_type n) noexcept
+    {
+        m_it += n;
+        return *this;
+    }
+
+    primitive_iterator_t& operator-=(difference_type n) noexcept
+    {
+        m_it -= n;
+        return *this;
+    }
+};
+}  // namespace detail
+}  // namespace nlohmann
+
+
+namespace nlohmann
+{
+namespace detail
+{
+/*!
+@brief an iterator value
+
+@note This structure could easily be a union, but MSVC currently does not allow
+unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
+*/
+template<typename BasicJsonType> struct internal_iterator
+{
+    /// iterator for JSON objects
+    typename BasicJsonType::object_t::iterator object_iterator {};
+    /// iterator for JSON arrays
+    typename BasicJsonType::array_t::iterator array_iterator {};
+    /// generic iterator for all other types
+    primitive_iterator_t primitive_iterator {};
+};
+}  // namespace detail
+}  // namespace nlohmann
+
+// #include <nlohmann/detail/iterators/iter_impl.hpp>
+
+
+#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
+#include <type_traits> // conditional, is_const, remove_const
+
+// #include <nlohmann/detail/exceptions.hpp>
+
+// #include <nlohmann/detail/iterators/internal_iterator.hpp>
+
+// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
+
+// #include <nlohmann/detail/macro_scope.hpp>
+
+// #include <nlohmann/detail/meta/cpp_future.hpp>
+
+// #include <nlohmann/detail/meta/type_traits.hpp>
+
+// #include <nlohmann/detail/value_t.hpp>
+
+
+namespace nlohmann
+{
+namespace detail
+{
+// forward declare, to be able to friend it later on
+template<typename IteratorType> class iteration_proxy;
+template<typename IteratorType> class iteration_proxy_value;
+
+/*!
+@brief a template for a bidirectional iterator for the @ref basic_json class
+This class implements a both iterators (iterator and const_iterator) for the
+@ref basic_json class.
+@note An iterator is called *initialized* when a pointer to a JSON value has
+      been set (e.g., by a constructor or a copy assignment). If the iterator is
+      default-constructed, it is *uninitialized* and most methods are undefined.
+      **The library uses assertions to detect calls on uninitialized iterators.**
+@requirement The class satisfies the following concept requirements:
+-
+[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
+  The iterator that can be moved can be moved in both directions (i.e.
+  incremented and decremented).
+@since version 1.0.0, simplified in version 2.0.9, change to bidirectional
+       iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
+*/
+template<typename BasicJsonType>
+class iter_impl
+{
+    /// allow basic_json to access private members
+    friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
+    friend BasicJsonType;
+    friend iteration_proxy<iter_impl>;
+    friend iteration_proxy_value<iter_impl>;
+
+    using object_t = typename BasicJsonType::object_t;
+    using array_t = typename BasicJsonType::array_t;
+    // make sure BasicJsonType is basic_json or const basic_json
+    static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
+                  "iter_impl only accepts (const) basic_json");
+
+  public:
+
+    /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
+    /// The C++ Standard has never required user-defined iterators to derive from std::iterator.
+    /// A user-defined iterator should provide publicly accessible typedefs named
+    /// iterator_category, value_type, difference_type, pointer, and reference.
+    /// Note that value_type is required to be non-const, even for constant iterators.
+    using iterator_category = std::bidirectional_iterator_tag;
+
+    /// the type of the values when the iterator is dereferenced
+    using value_type = typename BasicJsonType::value_type;
+    /// a type to represent differences between iterators
+    using difference_type = typename BasicJsonType::difference_type;
+    /// defines a pointer to the type iterated over (value_type)
+    using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
+          typename BasicJsonType::const_pointer,
+          typename BasicJsonType::pointer>::type;
+    /// defines a reference to the type iterated over (value_type)
+    using reference =
+        typename std::conditional<std::is_const<BasicJsonType>::value,
+        typename BasicJsonType::const_reference,
+        typename BasicJsonType::reference>::type;
+
+    /// default constructor
+    iter_impl() = default;
+
+    /*!
+    @brief constructor for a given JSON instance
+    @param[in] object  pointer to a JSON object for this iterator
+    @pre object != nullptr
+    @post The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    explicit iter_impl(pointer object) noexcept : m_object(object)
+    {
+        JSON_ASSERT(m_object != nullptr);
+
+        switch (m_object->m_type)
+        {
+            case value_t::object:
+            {
+                m_it.object_iterator = typename object_t::iterator();
+                break;
+            }
+
+            case value_t::array:
+            {
+                m_it.array_iterator = typename array_t::iterator();
+                break;
+            }
+
+            default:
+            {
+                m_it.primitive_iterator = primitive_iterator_t();
+                break;
+            }
+        }
+    }
+
+    /*!
+    @note The conventional copy constructor and copy assignment are implicitly
+          defined. Combined with the following converting constructor and
+          assignment, they support: (1) copy from iterator to iterator, (2)
+          copy from const iterator to const iterator, and (3) conversion from
+          iterator to const iterator. However conversion from const iterator
+          to iterator is not defined.
+    */
+
+    /*!
+    @brief const copy constructor
+    @param[in] other const iterator to copy from
+    @note This copy constructor had to be defined explicitly to circumvent a bug
+          occurring on msvc v19.0 compiler (VS 2015) debug build. For more
+          information refer to: https://github.com/nlohmann/json/issues/1608
+    */
+    iter_impl(const iter_impl<const BasicJsonType>& other) noexcept
+        : m_object(other.m_object), m_it(other.m_it)
+    {}
+
+    /*!
+    @brief converting assignment
+    @param[in] other const iterator to copy from
+    @return const/non-const iterator
+    @note It is not checked whether @a other is initialized.
+    */
+    iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept
+    {
+        m_object = other.m_object;
+        m_it = other.m_it;
+        return *this;
+    }
+
+    /*!
+    @brief converting constructor
+    @param[in] other  non-const iterator to copy from
+    @note It is not checked whether @a other is initialized.
+    */
+    iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
+        : m_object(other.m_object), m_it(other.m_it)
+    {}
+
+    /*!
+    @brief converting assignment
+    @param[in] other  non-const iterator to copy from
+    @return const/non-const iterator
+    @note It is not checked whether @a other is initialized.
+    */
+    iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
+    {
+        m_object = other.m_object;
+        m_it = other.m_it;
+        return *this;
+    }
+
+  private:
+    /*!
+    @brief set the iterator to the first value
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    void set_begin() noexcept
+    {
+        JSON_ASSERT(m_object != nullptr);
+
+        switch (m_object->m_type)
+        {
+            case value_t::object:
+            {
+                m_it.object_iterator = m_object->m_value.object->begin();
+                break;
+            }
+
+            case value_t::array:
+            {
+                m_it.array_iterator = m_object->m_value.array->begin();
+                break;
+            }
+
+            case value_t::null:
+            {
+                // set to end so begin()==end() is true: null is empty
+                m_it.primitive_iterator.set_end();
+                break;
+            }
+
+            default:
+            {
+                m_it.primitive_iterator.set_begin();
+                break;
+            }
+        }
+    }
+
+    /*!
+    @brief set the iterator past the last value
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    void set_end() noexcept
+    {
+        JSON_ASSERT(m_object != nullptr);
+
+        switch (m_object->m_type)
+        {
+            case value_t::object:
+            {
+                m_it.object_iterator = m_object->m_value.object->end();
+                break;
+            }
+
+            case value_t::array:
+            {
+                m_it.array_iterator = m_object->m_value.array->end();
+                break;
+            }
+
+            default:
+            {
+                m_it.primitive_iterator.set_end();
+                break;
+            }
+        }
+    }
+
+  public:
+    /*!
+    @brief return a reference to the value pointed to by the iterator
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    reference operator*() const
+    {
+        JSON_ASSERT(m_object != nullptr);
+
+        switch (m_object->m_type)
+        {
+            case value_t::object:
+            {
+                JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
+                return m_it.object_iterator->second;
+            }
+
+            case value_t::array:
+            {
+                JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
+                return *m_it.array_iterator;
+            }
+
+            case value_t::null:
+                JSON_THROW(invalid_iterator::create(214, "cannot get value"));
+
+            default:
+            {
+                if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
+                {
+                    return *m_object;
+                }
+
+                JSON_THROW(invalid_iterator::create(214, "cannot get value"));
+            }
+        }
+    }
+
+    /*!
+    @brief dereference the iterator
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    pointer operator->() const
+    {
+        JSON_ASSERT(m_object != nullptr);
+
+        switch (m_object->m_type)
+        {
+            case value_t::object:
+            {
+                JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
+                return &(m_it.object_iterator->second);
+            }
+
+            case value_t::array:
+            {
+                JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
+                return &*m_it.array_iterator;
+            }
+
+            default:
+            {
+                if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
+                {
+                    return m_object;
+                }
+
+                JSON_THROW(invalid_iterator::create(214, "cannot get value"));
+            }
+        }
+    }
+
+    /*!
+    @brief post-increment (it++)
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    iter_impl const operator++(int)
+    {
+        auto result = *this;
+        ++(*this);
+        return result;
+    }
+
+    /*!
+    @brief pre-increment (++it)
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    iter_impl& operator++()
+    {
+        JSON_ASSERT(m_object != nullptr);
+
+        switch (m_object->m_type)
+        {
+            case value_t::object:
+            {
+                std::advance(m_it.object_iterator, 1);
+                break;
+            }
+
+            case value_t::array:
+            {
+                std::advance(m_it.array_iterator, 1);
+                break;
+            }
+
+            default:
+            {
+                ++m_it.primitive_iterator;
+                break;
+            }
+        }
+
+        return *this;
+    }
+
+    /*!
+    @brief post-decrement (it--)
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    iter_impl const operator--(int)
+    {
+        auto result = *this;
+        --(*this);
+        return result;
+    }
+
+    /*!
+    @brief pre-decrement (--it)
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    iter_impl& operator--()
+    {
+        JSON_ASSERT(m_object != nullptr);
+
+        switch (m_object->m_type)
+        {
+            case value_t::object:
+            {
+                std::advance(m_it.object_iterator, -1);
+                break;
+            }
+
+            case value_t::array:
+            {
+                std::advance(m_it.array_iterator, -1);
+                break;
+            }
+
+            default:
+            {
+                --m_it.primitive_iterator;
+                break;
+            }
+        }
+
+        return *this;
+    }
+
+    /*!
+    @brief  comparison: equal
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    bool operator==(const iter_impl& other) const
+    {
+        // if objects are not the same, the comparison is undefined
+        if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
+        {
+            JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
+        }
+
+        JSON_ASSERT(m_object != nullptr);
+
+        switch (m_object->m_type)
+        {
+            case value_t::object:
+                return (m_it.object_iterator == other.m_it.object_iterator);
+
+            case value_t::array:
+                return (m_it.array_iterator == other.m_it.array_iterator);
+
+            default:
+                return (m_it.primitive_iterator == other.m_it.primitive_iterator);
+        }
+    }
+
+    /*!
+    @brief  comparison: not equal
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    bool operator!=(const iter_impl& other) const
+    {
+        return !operator==(other);
+    }
+
+    /*!
+    @brief  comparison: smaller
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    bool operator<(const iter_impl& other) const
+    {
+        // if objects are not the same, the comparison is undefined
+        if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
+        {
+            JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
+        }
+
+        JSON_ASSERT(m_object != nullptr);
+
+        switch (m_object->m_type)
+        {
+            case value_t::object:
+                JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
+
+            case value_t::array:
+                return (m_it.array_iterator < other.m_it.array_iterator);
+
+            default:
+                return (m_it.primitive_iterator < other.m_it.primitive_iterator);
+        }
+    }
+
+    /*!
+    @brief  comparison: less than or equal
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    bool operator<=(const iter_impl& other) const
+    {
+        return !other.operator < (*this);
+    }
+
+    /*!
+    @brief  comparison: greater than
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    bool operator>(const iter_impl& other) const
+    {
+        return !operator<=(other);
+    }
+
+    /*!
+    @brief  comparison: greater than or equal
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    bool operator>=(const iter_impl& other) const
+    {
+        return !operator<(other);
+    }
+
+    /*!
+    @brief  add to iterator
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    iter_impl& operator+=(difference_type i)
+    {
+        JSON_ASSERT(m_object != nullptr);
+
+        switch (m_object->m_type)
+        {
+            case value_t::object:
+                JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
+
+            case value_t::array:
+            {
+                std::advance(m_it.array_iterator, i);
+                break;
+            }
+
+            default:
+            {
+                m_it.primitive_iterator += i;
+                break;
+            }
+        }
+
+        return *this;
+    }
+
+    /*!
+    @brief  subtract from iterator
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    iter_impl& operator-=(difference_type i)
+    {
+        return operator+=(-i);
+    }
+
+    /*!
+    @brief  add to iterator
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    iter_impl operator+(difference_type i) const
+    {
+        auto result = *this;
+        result += i;
+        return result;
+    }
+
+    /*!
+    @brief  addition of distance and iterator
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    friend iter_impl operator+(difference_type i, const iter_impl& it)
+    {
+        auto result = it;
+        result += i;
+        return result;
+    }
+
+    /*!
+    @brief  subtract from iterator
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    iter_impl operator-(difference_type i) const
+    {
+        auto result = *this;
+        result -= i;
+        return result;
+    }
+
+    /*!
+    @brief  return difference
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    difference_type operator-(const iter_impl& other) const
+    {
+        JSON_ASSERT(m_object != nullptr);
+
+        switch (m_object->m_type)
+        {
+            case value_t::object:
+                JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
+
+            case value_t::array:
+                return m_it.array_iterator - other.m_it.array_iterator;
+
+            default:
+                return m_it.primitive_iterator - other.m_it.primitive_iterator;
+        }
+    }
+
+    /*!
+    @brief  access to successor
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    reference operator[](difference_type n) const
+    {
+        JSON_ASSERT(m_object != nullptr);
+
+        switch (m_object->m_type)
+        {
+            case value_t::object:
+                JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
+
+            case value_t::array:
+                return *std::next(m_it.array_iterator, n);
+
+            case value_t::null:
+                JSON_THROW(invalid_iterator::create(214, "cannot get value"));
+
+            default:
+            {
+                if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
+                {
+                    return *m_object;
+                }
+
+                JSON_THROW(invalid_iterator::create(214, "cannot get value"));
+            }
+        }
+    }
+
+    /*!
+    @brief  return the key of an object iterator
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    const typename object_t::key_type& key() const
+    {
+        JSON_ASSERT(m_object != nullptr);
+
+        if (JSON_HEDLEY_LIKELY(m_object->is_object()))
+        {
+            return m_it.object_iterator->first;
+        }
+
+        JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
+    }
+
+    /*!
+    @brief  return the value of an iterator
+    @pre The iterator is initialized; i.e. `m_object != nullptr`.
+    */
+    reference value() const
+    {
+        return operator*();
+    }
+
+  private:
+    /// associated JSON instance
+    pointer m_object = nullptr;
+    /// the actual iterator of the associated instance
+    internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
+};
+} // namespace detail
+} // namespace nlohmann
+
+// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
+
+// #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
+
+
+#include <cstddef> // ptrdiff_t
+#include <iterator> // reverse_iterator
+#include <utility> // declval
+
+namespace nlohmann
+{
+namespace detail
+{
+//////////////////////
+// reverse_iterator //
+//////////////////////
+
+/*!
+@brief a template for a reverse iterator class
+
+@tparam Base the base iterator type to reverse. Valid types are @ref
+iterator (to create @ref reverse_iterator) and @ref const_iterator (to
+create @ref const_reverse_iterator).
+
+@requirement The class satisfies the following concept requirements:
+-
+[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
+  The iterator that can be moved can be moved in both directions (i.e.
+  incremented and decremented).
+- [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator):
+  It is possible to write to the pointed-to element (only if @a Base is
+  @ref iterator).
+
+@since version 1.0.0
+*/
+template<typename Base>
+class json_reverse_iterator : public std::reverse_iterator<Base>
+{
+  public:
+    using difference_type = std::ptrdiff_t;
+    /// shortcut to the reverse iterator adapter
+    using base_iterator = std::reverse_iterator<Base>;
+    /// the reference type for the pointed-to element
+    using reference = typename Base::reference;
+
+    /// create reverse iterator from iterator
+    explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
+        : base_iterator(it) {}
+
+    /// create reverse iterator from base class
+    explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
+
+    /// post-increment (it++)
+    json_reverse_iterator const operator++(int)
+    {
+        return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
+    }
+
+    /// pre-increment (++it)
+    json_reverse_iterator& operator++()
+    {
+        return static_cast<json_reverse_iterator&>(base_iterator::operator++());
+    }
+
+    /// post-decrement (it--)
+    json_reverse_iterator const operator--(int)
+    {
+        return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
+    }
+
+    /// pre-decrement (--it)
+    json_reverse_iterator& operator--()
+    {
+        return static_cast<json_reverse_iterator&>(base_iterator::operator--());
+    }
+
+    /// add to iterator
+    json_reverse_iterator& operator+=(difference_type i)
+    {
+        return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
+    }
+
+    /// add to iterator
+    json_reverse_iterator operator+(difference_type i) const
+    {
+        return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
+    }
+
+    /// subtract from iterator
+    json_reverse_iterator operator-(difference_type i) const
+    {
+        return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
+    }
+
+    /// return difference
+    difference_type operator-(const json_reverse_iterator& other) const
+    {
+        return base_iterator(*this) - base_iterator(other);
+    }
+
+    /// access to successor
+    reference operator[](difference_type n) const
+    {
+        return *(this->operator+(n));
+    }
+
+    /// return the key of an object iterator
+    auto key() const -> decltype(std::declval<Base>().key())
+    {
+        auto it = --this->base();
+        return it.key();
+    }
+
+    /// return the value of an iterator
+    reference value() const
+    {
+        auto it = --this->base();
+        return it.operator * ();
+    }
+};
+}  // namespace detail
+}  // namespace nlohmann
+
+// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
+
+// #include <nlohmann/detail/json_pointer.hpp>
+
+
+#include <algorithm> // all_of
+#include <cctype> // isdigit
+#include <limits> // max
+#include <numeric> // accumulate
+#include <string> // string
+#include <utility> // move
+#include <vector> // vector
+
+// #include <nlohmann/detail/exceptions.hpp>
+
+// #include <nlohmann/detail/macro_scope.hpp>
+
+// #include <nlohmann/detail/value_t.hpp>
+
+
+namespace nlohmann
+{
+template<typename BasicJsonType>
+class json_pointer
+{
+    // allow basic_json to access private members
+    NLOHMANN_BASIC_JSON_TPL_DECLARATION
+    friend class basic_json;
+
+  public:
+    /*!
+    @brief create JSON pointer
+
+    Create a JSON pointer according to the syntax described in
+    [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
+
+    @param[in] s  string representing the JSON pointer; if omitted, the empty
+                  string is assumed which references the whole JSON value
+
+    @throw parse_error.107 if the given JSON pointer @a s is nonempty and does
+                           not begin with a slash (`/`); see example below
+
+    @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s is
+    not followed by `0` (representing `~`) or `1` (representing `/`); see
+    example below
+
+    @liveexample{The example shows the construction several valid JSON pointers
+    as well as the exceptional behavior.,json_pointer}
+
+    @since version 2.0.0
+    */
+    explicit json_pointer(const std::string& s = "")
+        : reference_tokens(split(s))
+    {}
+
+    /*!
+    @brief return a string representation of the JSON pointer
+
+    @invariant For each JSON pointer `ptr`, it holds:
+    @code {.cpp}
+    ptr == json_pointer(ptr.to_string());
+    @endcode
+
+    @return a string representation of the JSON pointer
+
+    @liveexample{The example shows the result of `to_string`.,json_pointer__to_string}
+
+    @since version 2.0.0
+    */
+    std::string to_string() const
+    {
+        return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
+                               std::string{},
+                               [](const std::string & a, const std::string & b)
+        {
+            return a + "/" + escape(b);
+        });
+    }
+
+    /// @copydoc to_string()
+    operator std::string() const
+    {
+        return to_string();
+    }
+
+    /*!
+    @brief append another JSON pointer at the end of this JSON pointer
+
+    @param[in] ptr  JSON pointer to append
+    @return JSON pointer with @a ptr appended
+
+    @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
+
+    @complexity Linear in the length of @a ptr.
+
+    @sa @ref operator/=(std::string) to append a reference token
+    @sa @ref operator/=(std::size_t) to append an array index
+    @sa @ref operator/(const json_pointer&, const json_pointer&) for a binary operator
+
+    @since version 3.6.0
+    */
+    json_pointer& operator/=(const json_pointer& ptr)
+    {
+        reference_tokens.insert(reference_tokens.end(),
+                                ptr.reference_tokens.begin(),
+                                ptr.reference_tokens.end());
+        return *this;
+    }
+
+    /*!
+    @brief append an unescaped reference token at the end of this JSON pointer
+
+    @param[in] token  reference token to append
+    @return JSON pointer with @a token appended without escaping @a token
+
+    @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
+
+    @complexity Amortized constant.
+
+    @sa @ref operator/=(const json_pointer&) to append a JSON pointer
+    @sa @ref operator/=(std::size_t) to append an array index
+    @sa @ref operator/(const json_pointer&, std::size_t) for a binary operator
+
+    @since version 3.6.0
+    */
+    json_pointer& operator/=(std::string token)
+    {
+        push_back(std::move(token));
+        return *this;
+    }
+
+    /*!
+    @brief append an array index at the end of this JSON pointer
+
+    @param[in] array_idx  array index to append
+    @return JSON pointer with @a array_idx appended
+
+    @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
+
+    @complexity Amortized constant.
+
+    @sa @ref operator/=(const json_pointer&) to append a JSON pointer
+    @sa @ref operator/=(std::string) to append a reference token
+    @sa @ref operator/(const json_pointer&, std::string) for a binary operator
+
+    @since version 3.6.0
+    */
+    json_pointer& operator/=(std::size_t array_idx)
+    {
+        return *this /= std::to_string(array_idx);
+    }
+
+    /*!
+    @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
+
+    @param[in] lhs  JSON pointer
+    @param[in] rhs  JSON pointer
+    @return a new JSON pointer with @a rhs appended to @a lhs
+
+    @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
+
+    @complexity Linear in the length of @a lhs and @a rhs.
+
+    @sa @ref operator/=(const json_pointer&) to append a JSON pointer
+
+    @since version 3.6.0
+    */
+    friend json_pointer operator/(const json_pointer& lhs,
+                                  const json_pointer& rhs)
+    {
+        return json_pointer(lhs) /= rhs;
+    }
+
+    /*!
+    @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
+
+    @param[in] ptr  JSON pointer
+    @param[in] token  reference token
+    @return a new JSON pointer with unescaped @a token appended to @a ptr
+
+    @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
+
+    @complexity Linear in the length of @a ptr.
+
+    @sa @ref operator/=(std::string) to append a reference token
+
+    @since version 3.6.0
+    */
+    friend json_pointer operator/(const json_pointer& ptr, std::string token)
+    {
+        return json_pointer(ptr) /= std::move(token);
+    }
+
+    /*!
+    @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
+
+    @param[in] ptr  JSON pointer
+    @param[in] array_idx  array index
+    @return a new JSON pointer with @a array_idx appended to @a ptr
+
+    @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
+
+    @complexity Linear in the length of @a ptr.
+
+    @sa @ref operator/=(std::size_t) to append an array index
+
+    @since version 3.6.0
+    */
+    friend json_pointer operator/(const json_pointer& ptr, std::size_t array_idx)
+    {
+        return json_pointer(ptr) /= array_idx;
+    }
+
+    /*!
+    @brief returns the parent of this JSON pointer
+
+    @return parent of this JSON pointer; in case this JSON pointer is the root,
+            the root itself is returned
+
+    @complexity Linear in the length of the JSON pointer.
+
+    @liveexample{The example shows the result of `parent_pointer` for different
+    JSON Pointers.,json_pointer__parent_pointer}
+
+    @since version 3.6.0
+    */
+    json_pointer parent_pointer() const
+    {
+        if (empty())
+        {
+            return *this;
+        }
+
+        json_pointer res = *this;
+        res.pop_back();
+        return res;
+    }
+
+    /*!
+    @brief remove last reference token
+
+    @pre not `empty()`
+
+    @liveexample{The example shows the usage of `pop_back`.,json_pointer__pop_back}
+
+    @complexity Constant.
+
+    @throw out_of_range.405 if JSON pointer has no parent
+
+    @since version 3.6.0
+    */
+    void pop_back()
+    {
+        if (JSON_HEDLEY_UNLIKELY(empty()))
+        {
+            JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
+        }
+
+        reference_tokens.pop_back();
+    }
+
+    /*!
+    @brief return last reference token
+
+    @pre not `empty()`
+    @return last reference token
+
+    @liveexample{The example shows the usage of `back`.,json_pointer__back}
+
+    @complexity Constant.
+
+    @throw out_of_range.405 if JSON pointer has no parent
+
+    @since version 3.6.0
+    */
+    const std::string& back() const
+    {
+        if (JSON_HEDLEY_UNLIKELY(empty()))
+        {
+            JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
+        }
+
+        return reference_tokens.back();
+    }
+
+    /*!
+    @brief append an unescaped token at the end of the reference pointer
+
+    @param[in] token  token to add
+
+    @complexity Amortized constant.
+
+    @liveexample{The example shows the result of `push_back` for different
+    JSON Pointers.,json_pointer__push_back}
+
+    @since version 3.6.0
+    */
+    void push_back(const std::string& token)
+    {
+        reference_tokens.push_back(token);
+    }
+
+    /// @copydoc push_back(const std::string&)
+    void push_back(std::string&& token)
+    {
+        reference_tokens.push_back(std::move(token));
+    }
+
+    /*!
+    @brief return whether pointer points to the root document
+
+    @return true iff the JSON pointer points to the root document
+
+    @complexity Constant.
+
+    @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
+    @liveexample{The example shows the result of `empty` for different JSON
+    Pointers.,json_pointer__empty}
+
+    @since version 3.6.0
+    */
+    bool empty() const noexcept
+    {
+        return reference_tokens.empty();
+    }
+
+  private:
+    /*!
+    @param[in] s  reference token to be converted into an array index
+
+    @return integer representation of @a s
+
+    @throw parse_error.106  if an array index begins with '0'
+    @throw parse_error.109  if an array index begins not with a digit
+    @throw out_of_range.404 if string @a s could not be converted to an integer
+    @throw out_of_range.410 if an array index exceeds size_type
+    */
+    static typename BasicJsonType::size_type array_index(const std::string& s)
+    {
+        using size_type = typename BasicJsonType::size_type;
+
+        // error condition (cf. RFC 6901, Sect. 4)
+        if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
+        {
+            JSON_THROW(detail::parse_error::create(106, 0,
+                                                   "array index '" + s +
+                                                   "' must not begin with '0'"));
+        }
+
+        // error condition (cf. RFC 6901, Sect. 4)
+        if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
+        {
+            JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number"));
+        }
+
+        std::size_t processed_chars = 0;
+        unsigned long long res = 0;
+        JSON_TRY
+        {
+            res = std::stoull(s, &processed_chars);
+        }
+        JSON_CATCH(std::out_of_range&)
+        {
+            JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
+        }
+
+        // check if the string was completely read
+        if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
+        {
+            JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
+        }
+
+        // only triggered on special platforms (like 32bit), see also
+        // https://github.com/nlohmann/json/pull/2203
+        if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)()))
+        {
+            JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type")); // LCOV_EXCL_LINE
+        }
+
+        return static_cast<size_type>(res);
+    }
+
+    json_pointer top() const
+    {
+        if (JSON_HEDLEY_UNLIKELY(empty()))
+        {
+            JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
+        }
+
+        json_pointer result = *this;
+        result.reference_tokens = {reference_tokens[0]};
+        return result;
+    }
+
+    /*!
+    @brief create and return a reference to the pointed to value
+
+    @complexity Linear in the number of reference tokens.
+
+    @throw parse_error.109 if array index is not a number
+    @throw type_error.313 if value cannot be unflattened
+    */
+    BasicJsonType& get_and_create(BasicJsonType& j) const
+    {
+        auto result = &j;
+
+        // in case no reference tokens exist, return a reference to the JSON value
+        // j which will be overwritten by a primitive value
+        for (const auto& reference_token : reference_tokens)
+        {
+            switch (result->type())
+            {
+                case detail::value_t::null:
+                {
+                    if (reference_token == "0")
+                    {
+                        // start a new array if reference token is 0
+                        result = &result->operator[](0);
+                    }
+                    else
+                    {
+                        // start a new object otherwise
+                        result = &result->operator[](reference_token);
+                    }
+                    break;
+                }
+
+                case detail::value_t::object:
+                {
+                    // create an entry in the object
+                    result = &result->operator[](reference_token);
+                    break;
+                }
+
+                case detail::value_t::array:
+                {
+                    // create an entry in the array
+                    result = &result->operator[](array_index(reference_token));
+                    break;
+                }
+
+                /*
+                The following code is only reached if there exists a reference
+                token _and_ the current value is primitive. In this case, we have
+                an error situation, because primitive values may only occur as
+                single value; that is, with an empty list of reference tokens.
+                */
+                default:
+                    JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
+            }
+        }
+
+        return *result;
+    }
+
+    /*!
+    @brief return a reference to the pointed to value
+
+    @note This version does not throw if a value is not present, but tries to
+          create nested values instead. For instance, calling this function
+          with pointer `"/this/that"` on a null value is equivalent to calling
+          `operator[]("this").operator[]("that")` on that value, effectively
+          changing the null value to an object.
+
+    @param[in] ptr  a JSON value
+
+    @return reference to the JSON value pointed to by the JSON pointer
+
+    @complexity Linear in the length of the JSON pointer.
+
+    @throw parse_error.106   if an array index begins with '0'
+    @throw parse_error.109   if an array index was not a number
+    @throw out_of_range.404  if the JSON pointer can not be resolved
+    */
+    BasicJsonType& get_unchecked(BasicJsonType* ptr) const
+    {
+        for (const auto& reference_token : reference_tokens)
+        {
+            // convert null values to arrays or objects before continuing
+            if (ptr->is_null())
+            {
+                // check if reference token is a number
+                const bool nums =
+                    std::all_of(reference_token.begin(), reference_token.end(),
+                                [](const unsigned char x)
+                {
+                    return std::isdigit(x);
+                });
+
+                // change value to array for numbers or "-" or to object otherwise
+                *ptr = (nums || reference_token == "-")
+                       ? detail::value_t::array
+                       : detail::value_t::object;
+            }
+
+            switch (ptr->type())
+            {
+                case detail::value_t::object:
+                {
+                    // use unchecked object access
+                    ptr = &ptr->operator[](reference_token);
+                    break;
+                }
+
+                case detail::value_t::array:
+                {
+                    if (reference_token == "-")
+                    {
+                        // explicitly treat "-" as index beyond the end
+                        ptr = &ptr->operator[](ptr->m_value.array->size());
+                    }
+                    else
+                    {
+                        // convert array index to number; unchecked access
+                        ptr = &ptr->operator[](array_index(reference_token));
+                    }
+                    break;
+                }
+
+                default:
+                    JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
+            }
+        }
+
+        return *ptr;
+    }
+
+    /*!
+    @throw parse_error.106   if an array index begins with '0'
+    @throw parse_error.109   if an array index was not a number
+    @throw out_of_range.402  if the array index '-' is used
+    @throw out_of_range.404  if the JSON pointer can not be resolved
+    */
+    BasicJsonType& get_checked(BasicJsonType* ptr) const
+    {
+        for (const auto& reference_token : reference_tokens)
+        {
+            switch (ptr->type())
+            {
+                case detail::value_t::object:
+                {
+                    // note: at performs range check
+                    ptr = &ptr->at(reference_token);
+                    break;
+                }
+
+                case detail::value_t::array:
+                {
+                    if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
+                    {
+                        // "-" always fails the range check
+                        JSON_THROW(detail::out_of_range::create(402,
+                                                                "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
+                                                                ") is out of range"));
+                    }
+
+                    // note: at performs range check
+                    ptr = &ptr->at(array_index(reference_token));
+                    break;
+                }
+
+                default:
+                    JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
+            }
+        }
+
+        return *ptr;
+    }
+
+    /*!
+    @brief return a const reference to the pointed to value
+
+    @param[in] ptr  a JSON value
+
+    @return const reference to the JSON value pointed to by the JSON
+    pointer
+
+    @throw parse_error.106   if an array index begins with '0'
+    @throw parse_error.109   if an array index was not a number
+    @throw out_of_range.402  if the array index '-' is used
+    @throw out_of_range.404  if the JSON pointer can not be resolved
+    */
+    const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
+    {
+        for (const auto& reference_token : reference_tokens)
+        {
+            switch (ptr->type())
+            {
+                case detail::value_t::object:
+                {
+                    // use unchecked object access
+                    ptr = &ptr->operator[](reference_token);
+                    break;
+                }
+
+                case detail::value_t::array:
+                {
+                    if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
+                    {
+                        // "-" cannot be used for const access
+                        JSON_THROW(detail::out_of_range::create(402,
+                                                                "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
+                                                                ") is out of range"));
+                    }
+
+                    // use unchecked array access
+                    ptr = &ptr->operator[](array_index(reference_token));
+                    break;
+                }
+
+                default:
+                    JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
+            }
+        }
+
+        return *ptr;
+    }
+
+    /*!
+    @throw parse_error.106   if an array index begins with '0'
+    @throw parse_error.109   if an array index was not a number
+    @throw out_of_range.402  if the array index '-' is used
+    @throw out_of_range.404  if the JSON pointer can not be resolved
+    */
+    const BasicJsonType& get_checked(const BasicJsonType* ptr) const
+    {
+        for (const auto& reference_token : reference_tokens)
+        {
+            switch (ptr->type())
+            {
+                case detail::value_t::object:
+                {
+                    // note: at performs range check
+                    ptr = &ptr->at(reference_token);
+                    break;
+                }
+
+                case detail::value_t::array:
+                {
+                    if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
+                    {
+                        // "-" always fails the range check
+                        JSON_THROW(detail::out_of_range::create(402,
+                                                                "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
+                                                                ") is out of range"));
+                    }
+
+                    // note: at performs range check
+                    ptr = &ptr->at(array_index(reference_token));
+                    break;
+                }
+
+                default:
+                    JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
+            }
+        }
+
+        return *ptr;
+    }
+
+    /*!
+    @throw parse_error.106   if an array index begins with '0'
+    @throw parse_error.109   if an array index was not a number
+    */
+    bool contains(const BasicJsonType* ptr) const
+    {
+        for (const auto& reference_token : reference_tokens)
+        {
+            switch (ptr->type())
+            {
+                case detail::value_t::object:
+                {
+                    if (!ptr->contains(reference_token))
+                    {
+                        // we did not find the key in the object
+                        return false;
+                    }
+
+                    ptr = &ptr->operator[](reference_token);
+                    break;
+                }
+
+                case detail::value_t::array:
+                {
+                    if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
+                    {
+                        // "-" always fails the range check
+                        return false;
+                    }
+                    if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
+                    {
+                        // invalid char
+                        return false;
+                    }
+                    if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
+                    {
+                        if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
+                        {
+                            // first char should be between '1' and '9'
+                            return false;
+                        }
+                        for (std::size_t i = 1; i < reference_token.size(); i++)
+                        {
+                            if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
+                            {
+                                // other char should be between '0' and '9'
+                                return false;
+                            }
+                        }
+                    }
+
+                    const auto idx = array_index(reference_token);
+                    if (idx >= ptr->size())
+                    {
+                        // index out of range
+                        return false;
+                    }
+
+                    ptr = &ptr->operator[](idx);
+                    break;
+                }
+
+                default:
+                {
+                    // we do not expect primitive values if there is still a
+                    // reference token to process
+                    return false;
+                }
+            }
+        }
+
+        // no reference token left means we found a primitive value
+        return true;
+    }
+
+    /*!
+    @brief split the string input to reference tokens
+
+    @note This function is only called by the json_pointer constructor.
+          All exceptions below are documented there.
+
+    @throw parse_error.107  if the pointer is not empty or begins with '/'
+    @throw parse_error.108  if character '~' is not followed by '0' or '1'
+    */
+    static std::vector<std::string> split(const std::string& reference_string)
+    {
+        std::vector<std::string> result;
+
+        // special case: empty reference string -> no reference tokens
+        if (reference_string.empty())
+        {
+            return result;
+        }
+
+        // check if nonempty reference string begins with slash
+        if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
+        {
+            JSON_THROW(detail::parse_error::create(107, 1,
+                                                   "JSON pointer must be empty or begin with '/' - was: '" +
+                                                   reference_string + "'"));
+        }
+
+        // extract the reference tokens:
+        // - slash: position of the last read slash (or end of string)
+        // - start: position after the previous slash
+        for (
+            // search for the first slash after the first character
+            std::size_t slash = reference_string.find_first_of('/', 1),
+            // set the beginning of the first reference token
+            start = 1;
+            // we can stop if start == 0 (if slash == std::string::npos)
+            start != 0;
+            // set the beginning of the next reference token
+            // (will eventually be 0 if slash == std::string::npos)
+            start = (slash == std::string::npos) ? 0 : slash + 1,
+            // find next slash
+            slash = reference_string.find_first_of('/', start))
+        {
+            // use the text between the beginning of the reference token
+            // (start) and the last slash (slash).
+            auto reference_token = reference_string.substr(start, slash - start);
+
+            // check reference tokens are properly escaped
+            for (std::size_t pos = reference_token.find_first_of('~');
+                    pos != std::string::npos;
+                    pos = reference_token.find_first_of('~', pos + 1))
+            {
+                JSON_ASSERT(reference_token[pos] == '~');
+
+                // ~ must be followed by 0 or 1
+                if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
+                                         (reference_token[pos + 1] != '0' &&
+                                          reference_token[pos + 1] != '1')))
+                {
+                    JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
+                }
+            }
+
+            // finally, store the reference token
+            unescape(reference_token);
+            result.push_back(reference_token);
+        }
+
+        return result;
+    }
+
+    /*!
+    @brief replace all occurrences of a substring by another string
+
+    @param[in,out] s  the string to manipulate; changed so that all
+                   occurrences of @a f are replaced with @a t
+    @param[in]     f  the substring to replace with @a t
+    @param[in]     t  the string to replace @a f
+
+    @pre The search string @a f must not be empty. **This precondition is
+    enforced with an assertion.**
+
+    @since version 2.0.0
+    */
+    static void replace_substring(std::string& s, const std::string& f,
+                                  const std::string& t)
+    {
+        JSON_ASSERT(!f.empty());
+        for (auto pos = s.find(f);                // find first occurrence of f
+                pos != std::string::npos;         // make sure f was found
+                s.replace(pos, f.size(), t),      // replace with t, and
+                pos = s.find(f, pos + t.size()))  // find next occurrence of f
+        {}
+    }
+
+    /// escape "~" to "~0" and "/" to "~1"
+    static std::string escape(std::string s)
+    {
+        replace_substring(s, "~", "~0");
+        replace_substring(s, "/", "~1");
+        return s;
+    }
+
+    /// unescape "~1" to tilde and "~0" to slash (order is important!)
+    static void unescape(std::string& s)
+    {
+        replace_substring(s, "~1", "/");
+        replace_substring(s, "~0", "~");
+    }
+
+    /*!
+    @param[in] reference_string  the reference string to the current value
+    @param[in] value             the value to consider
+    @param[in,out] result        the result object to insert values to
+
+    @note Empty objects or arrays are flattened to `null`.
+    */
+    static void flatten(const std::string& reference_string,
+                        const BasicJsonType& value,
+                        BasicJsonType& result)
+    {
+        switch (value.type())
+        {
+            case detail::value_t::array:
+            {
+                if (value.m_value.array->empty())
+                {
+                    // flatten empty array as null
+                    result[reference_string] = nullptr;
+                }
+                else
+                {
+                    // iterate array and use index as reference string
+                    for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
+                    {
+                        flatten(reference_string + "/" + std::to_string(i),
+                                value.m_value.array->operator[](i), result);
+                    }
+                }
+                break;
+            }
+
+            case detail::value_t::object:
+            {
+                if (value.m_value.object->empty())
+                {
+                    // flatten empty object as null
+                    result[reference_string] = nullptr;
+                }
+                else
+                {
+                    // iterate object and use keys as reference string
+                    for (const auto& element : *value.m_value.object)
+                    {
+                        flatten(reference_string + "/" + escape(element.first), element.second, result);
+                    }
+                }
+                break;
+            }
+
+            default:
+            {
+                // add primitive value with its reference string
+                result[reference_string] = value;
+                break;
+            }
+        }
+    }
+
+    /*!
+    @param[in] value  flattened JSON
+
+    @return unflattened JSON
+
+    @throw parse_error.109 if array index is not a number
+    @throw type_error.314  if value is not an object
+    @throw type_error.315  if object values are not primitive
+    @throw type_error.313  if value cannot be unflattened
+    */
+    static BasicJsonType
+    unflatten(const BasicJsonType& value)
+    {
+        if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
+        {
+            JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
+        }
+
+        BasicJsonType result;
+
+        // iterate the JSON object values
+        for (const auto& element : *value.m_value.object)
+        {
+            if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
+            {
+                JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
+            }
+
+            // assign value to reference pointed to by JSON pointer; Note that if
+            // the JSON pointer is "" (i.e., points to the whole value), function
+            // get_and_create returns a reference to result itself. An assignment
+            // will then create a primitive value.
+            json_pointer(element.first).get_and_create(result) = element.second;
+        }
+
+        return result;
+    }
+
+    /*!
+    @brief compares two JSON pointers for equality
+
+    @param[in] lhs  JSON pointer to compare
+    @param[in] rhs  JSON pointer to compare
+    @return whether @a lhs is equal to @a rhs
+
+    @complexity Linear in the length of the JSON pointer
+
+    @exceptionsafety No-throw guarantee: this function never throws exceptions.
+    */
+    friend bool operator==(json_pointer const& lhs,
+                           json_pointer const& rhs) noexcept
+    {
+        return lhs.reference_tokens == rhs.reference_tokens;
+    }
+
+    /*!
+    @brief compares two JSON pointers for inequality
+
+    @param[in] lhs  JSON pointer to compare
+    @param[in] rhs  JSON pointer to compare
+    @return whether @a lhs is not equal @a rhs
+
+    @complexity Linear in the length of the JSON pointer
+
+    @exceptionsafety No-throw guarantee: this function never throws exceptions.
+    */
+    friend bool operator!=(json_pointer const& lhs,
+                           json_pointer const& rhs) noexcept
+    {
+        return !(lhs == rhs);
+    }
+
+    /// the reference tokens
+    std::vector<std::string> reference_tokens;
+};
+}  // namespace nlohmann
+
+// #include <nlohmann/detail/json_ref.hpp>
+
+
+#include <initializer_list>
+#include <utility>
+
+// #include <nlohmann/detail/meta/type_traits.hpp>
+
+
+namespace nlohmann
+{
+namespace detail
+{
+template<typename BasicJsonType>
+class json_ref
+{
+  public:
+    using value_type = BasicJsonType;
+
+    json_ref(value_type&& value)
+        : owned_value(std::move(value))
+        , value_ref(&owned_value)
+        , is_rvalue(true)
+    {}
+
+    json_ref(const value_type& value)
+        : value_ref(const_cast<value_type*>(&value))
+        , is_rvalue(false)
+    {}
+
+    json_ref(std::initializer_list<json_ref> init)
+        : owned_value(init)
+        , value_ref(&owned_value)
+        , is_rvalue(true)
+    {}
+
+    template <
+        class... Args,
+        enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
+    json_ref(Args && ... args)
+        : owned_value(std::forward<Args>(args)...)
+        , value_ref(&owned_value)
+        , is_rvalue(true)
+    {}
+
+    // class should be movable only
+    json_ref(json_ref&&) = default;
+    json_ref(const json_ref&) = delete;
+    json_ref& operator=(const json_ref&) = delete;
+    json_ref& operator=(json_ref&&) = delete;
+    ~json_ref() = default;
+
+    value_type moved_or_copied() const
+    {
+        if (is_rvalue)
+        {
+            return std::move(*value_ref);
+        }
+        return *value_ref;
+    }
+
+    value_type const& operator*() const
+    {
+        return *static_cast<value_type const*>(value_ref);
+    }
+
+    value_type const* operator->() const
+    {
+        return static_cast<value_type const*>(value_ref);
+    }
+
+  private:
+    mutable value_type owned_value = nullptr;
+    value_type* value_ref = nullptr;
+    const bool is_rvalue = true;
+};
+}  // namespace detail
+}  // namespace nlohmann
+
+// #include <nlohmann/detail/macro_scope.hpp>
+
+// #include <nlohmann/detail/meta/cpp_future.hpp>
+
+// #include <nlohmann/detail/meta/type_traits.hpp>
+
+// #include <nlohmann/detail/output/binary_writer.hpp>
+
+
+#include <algorithm> // reverse
+#include <array> // array
+#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
+#include <cstring> // memcpy
+#include <limits> // numeric_limits
+#include <string> // string
+#include <cmath> // isnan, isinf
+
+// #include <nlohmann/detail/input/binary_reader.hpp>
+
+// #include <nlohmann/detail/macro_scope.hpp>
+
+// #include <nlohmann/detail/output/output_adapters.hpp>
+
+
+#include <algorithm> // copy
+#include <cstddef> // size_t
+#include <ios> // streamsize
+#include <iterator> // back_inserter
+#include <memory> // shared_ptr, make_shared
+#include <ostream> // basic_ostream
+#include <string> // basic_string
+#include <vector> // vector
+// #include <nlohmann/detail/macro_scope.hpp>
+
+
+namespace nlohmann
+{
+namespace detail
+{
+/// abstract output adapter interface
+template<typename CharType> struct output_adapter_protocol
+{
+    virtual void write_character(CharType c) = 0;
+    virtual void write_characters(const CharType* s, std::size_t length) = 0;
+    virtual ~output_adapter_protocol() = default;
+};
+
+/// a type to simplify interfaces
+template<typename CharType>
+using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
+
+/// output adapter for byte vectors
+template<typename CharType>
+class output_vector_adapter : public output_adapter_protocol<CharType>
+{
+  public:
+    explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
+        : v(vec)
+    {}
+
+    void write_character(CharType c) override
+    {
+        v.push_back(c);
+    }
+
+    JSON_HEDLEY_NON_NULL(2)
+    void write_characters(const CharType* s, std::size_t length) override
+    {
+        std::copy(s, s + length, std::back_inserter(v));
+    }
+
+  private:
+    std::vector<CharType>& v;
+};
+
+/// output adapter for output streams
+template<typename CharType>
+class output_stream_adapter : public output_adapter_protocol<CharType>
+{
+  public:
+    explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
+        : stream(s)
+    {}
+
+    void write_character(CharType c) override
+    {
+        stream.put(c);
+    }
+
+    JSON_HEDLEY_NON_NULL(2)
+    void write_characters(const CharType* s, std::size_t length) override
+    {
+        stream.write(s, static_cast<std::streamsize>(length));
+    }
+
+  private:
+    std::basic_ostream<CharType>& stream;
+};
+
+/// output adapter for basic_string
+template<typename CharType, typename StringType = std::basic_string<CharType>>
+class output_string_adapter : public output_adapter_protocol<CharType>
+{
+  public:
+    explicit output_string_adapter(StringType& s) noexcept
+        : str(s)
+    {}
+
+    void write_character(CharType c) override
+    {
+        str.push_back(c);
+    }
+
+    JSON_HEDLEY_NON_NULL(2)
+    void write_characters(const CharType* s, std::size_t length) override
+    {
+        str.append(s, length);
+    }
+
+  private:
+    StringType& str;
+};
+
+template<typename CharType, typename StringType = std::basic_string<CharType>>
+class output_adapter
+{
+  public:
+    output_adapter(std::vector<CharType>& vec)
+        : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
+
+    output_adapter(std::basic_ostream<CharType>& s)
+        : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
+
+    output_adapter(StringType& s)
+        : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
+
+    operator output_adapter_t<CharType>()
+    {
+        return oa;
+    }
+
+  private:
+    output_adapter_t<CharType> oa = nullptr;
+};
+}  // namespace detail
+}  // namespace nlohmann
+
+
+namespace nlohmann
+{
+namespace detail
+{
+///////////////////
+// binary writer //
+///////////////////
+
+/*!
+@brief serialization to CBOR and MessagePack values
+*/
+template<typename BasicJsonType, typename CharType>
+class binary_writer
+{
+    using string_t = typename BasicJsonType::string_t;
+    using binary_t = typename BasicJsonType::binary_t;
+    using number_float_t = typename BasicJsonType::number_float_t;
+
+  public:
+    /*!
+    @brief create a binary writer
+
+    @param[in] adapter  output adapter to write to
+    */
+    explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
+    {
+        JSON_ASSERT(oa);
+    }
+
+    /*!
+    @param[in] j  JSON value to serialize
+    @pre       j.type() == value_t::object
+    */
+    void write_bson(const BasicJsonType& j)
+    {
+        switch (j.type())
+        {
+            case value_t::object:
+            {
+                write_bson_object(*j.m_value.object);
+                break;
+            }
+
+            default:
+            {
+                JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name())));
+            }
+        }
+    }
+
+    /*!
+    @param[in] j  JSON value to serialize
+    */
+    void write_cbor(const BasicJsonType& j)
+    {
+        switch (j.type())
+        {
+            case value_t::null:
+            {
+                oa->write_character(to_char_type(0xF6));
+                break;
+            }
+
+            case value_t::boolean:
+            {
+                oa->write_character(j.m_value.boolean
+                                    ? to_char_type(0xF5)
+                                    : to_char_type(0xF4));
+                break;
+            }
+
+            case value_t::number_integer:
+            {
+                if (j.m_value.number_integer >= 0)
+                {
+                    // CBOR does not differentiate between positive signed
+                    // integers and unsigned integers. Therefore, we used the
+                    // code from the value_t::number_unsigned case here.
+                    if (j.m_value.number_integer <= 0x17)
+                    {
+                        write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
+                    }
+                    else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
+                    {
+                        oa->write_character(to_char_type(0x18));
+                        write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
+                    }
+                    else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
+                    {
+                        oa->write_character(to_char_type(0x19));
+                        write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
+                    }
+                    else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
+                    {
+                        oa->write_character(to_char_type(0x1A));
+                        write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
+                    }
+                    else
+                    {
+                        oa->write_character(to_char_type(0x1B));
+                        write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
+                    }
+                }
+                else
+                {
+                    // The conversions below encode the sign in the first
+                    // byte, and the value is converted to a positive number.
+                    const auto positive_number = -1 - j.m_value.number_integer;
+                    if (j.m_value.number_integer >= -24)
+                    {
+                        write_number(static_cast<std::uint8_t>(0x20 + positive_number));
+                    }
+                    else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
+                    {
+                        oa->write_character(to_char_type(0x38));
+                        write_number(static_cast<std::uint8_t>(positive_number));
+                    }
+                    else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
+                    {
+                        oa->write_character(to_char_type(0x39));
+                        write_number(static_cast<std::uint16_t>(positive_number));
+                    }
+                    else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
+                    {
+                        oa->write_character(to_char_type(0x3A));
+                        write_number(static_cast<std::uint32_t>(positive_number));
+                    }
+                    else
+                    {
+                        oa->write_character(to_char_type(0x3B));
+                        write_number(static_cast<std::uint64_t>(positive_number));
+                    }
+                }
+                break;
+            }
+
+            case value_t::number_unsigned:
+            {
+                if (j.m_value.number_unsigned <= 0x17)
+                {
+                    write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
+                }
+                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
+                {
+                    oa->write_character(to_char_type(0x18));
+                    write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
+                }
+                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
+                {
+                    oa->write_character(to_char_type(0x19));
+                    write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
+                }
+                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
+                {
+                    oa->write_character(to_char_type(0x1A));
+                    write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
+                }
+                else
+                {
+                    oa->write_character(to_char_type(0x1B));
+                    write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
+                }
+                break;
+            }
+
+            case value_t::number_float:
+            {
+                if (std::isnan(j.m_value.number_float))
+                {
+                    // NaN is 0xf97e00 in CBOR
+                    oa->write_character(to_char_type(0xF9));
+                    oa->write_character(to_char_type(0x7E));
+                    oa->write_character(to_char_type(0x00));
+                }
+                else if (std::isinf(j.m_value.number_float))
+                {
+                    // Infinity is 0xf97c00, -Infinity is 0xf9fc00
+                    oa->write_character(to_char_type(0xf9));
+                    oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
+                    oa->write_character(to_char_type(0x00));
+                }
+                else
+                {
+                    write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
+                }
+                break;
+            }
+
+            case value_t::string:
+            {
+                // step 1: write control byte and the string length
+                const auto N = j.m_value.string->size();
+                if (N <= 0x17)
+                {
+                    write_number(static_cast<std::uint8_t>(0x60 + N));
+                }
+                else if (N <= (std::numeric_limits<std::uint8_t>::max)())
+                {
+                    oa->write_character(to_char_type(0x78));
+                    write_number(static_cast<std::uint8_t>(N));
+                }
+                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
+                {
+                    oa->write_character(to_char_type(0x79));
+                    write_number(static_cast<std::uint16_t>(N));
+                }
+                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
+                {
+                    oa->write_character(to_char_type(0x7A));
+                    write_number(static_cast<std::uint32_t>(N));
+                }
+                // LCOV_EXCL_START
+                else if (N <= (std::numeric_limits<std::uint64_t>::max)())
+                {
+                    oa->write_character(to_char_type(0x7B));
+                    write_number(static_cast<std::uint64_t>(N));
+                }
+                // LCOV_EXCL_STOP
+
+                // step 2: write the string
+                oa->write_characters(
+                    reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
+                    j.m_value.string->size());
+                break;
+            }
+
+            case value_t::array:
+            {
+                // step 1: write control byte and the array size
+                const auto N = j.m_value.array->size();
+                if (N <= 0x17)
+                {
+                    write_number(static_cast<std::uint8_t>(0x80 + N));
+                }
+                else if (N <= (std::numeric_limits<std::uint8_t>::max)())
+                {
+                    oa->write_character(to_char_type(0x98));
+                    write_number(static_cast<std::uint8_t>(N));
+                }
+                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
+                {
+                    oa->write_character(to_char_type(0x99));
+                    write_number(static_cast<std::uint16_t>(N));
+                }
+                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
+                {
+                    oa->write_character(to_char_type(0x9A));
+                    write_number(static_cast<std::uint32_t>(N));
+                }
+                // LCOV_EXCL_START
+                else if (N <= (std::numeric_limits<std::uint64_t>::max)())
+                {
+                    oa->write_character(to_char_type(0x9B));
+                    write_number(static_cast<std::uint64_t>(N));
+                }
+                // LCOV_EXCL_STOP
+
+                // step 2: write each element
+                for (const auto& el : *j.m_value.array)
+                {
+                    write_cbor(el);
+                }
+                break;
+            }
+
+            case value_t::binary:
+            {
+                if (j.m_value.binary->has_subtype())
+                {
+                    write_number(static_cast<std::uint8_t>(0xd8));
+                    write_number(j.m_value.binary->subtype());
+                }
+
+                // step 1: write control byte and the binary array size
+                const auto N = j.m_value.binary->size();
+                if (N <= 0x17)
+                {
+                    write_number(static_cast<std::uint8_t>(0x40 + N));
+                }
+                else if (N <= (std::numeric_limits<std::uint8_t>::max)())
+                {
+                    oa->write_character(to_char_type(0x58));
+                    write_number(static_cast<std::uint8_t>(N));
+                }
+                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
+                {
+                    oa->write_character(to_char_type(0x59));
+                    write_number(static_cast<std::uint16_t>(N));
+                }
+                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
+                {
+                    oa->write_character(to_char_type(0x5A));
+                    write_number(static_cast<std::uint32_t>(N));
+                }
+                // LCOV_EXCL_START
+                else if (N <= (std::numeric_limits<std::uint64_t>::max)())
+                {
+                    oa->write_character(to_char_type(0x5B));
+                    write_number(static_cast<std::uint64_t>(N));
+                }
+                // LCOV_EXCL_STOP
+
+                // step 2: write each element
+                oa->write_characters(
+                    reinterpret_cast<const CharType*>(j.m_value.binary->data()),
+                    N);
+
+                break;
+            }
+
+            case value_t::object:
+            {
+                // step 1: write control byte and the object size
+                const auto N = j.m_value.object->size();
+                if (N <= 0x17)
+                {
+                    write_number(static_cast<std::uint8_t>(0xA0 + N));
+                }
+                else if (N <= (std::numeric_limits<std::uint8_t>::max)())
+                {
+                    oa->write_character(to_char_type(0xB8));
+                    write_number(static_cast<std::uint8_t>(N));
+                }
+                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
+                {
+                    oa->write_character(to_char_type(0xB9));
+                    write_number(static_cast<std::uint16_t>(N));
+                }
+                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
+                {
+                    oa->write_character(to_char_type(0xBA));
+                    write_number(static_cast<std::uint32_t>(N));
+                }
+                // LCOV_EXCL_START
+                else if (N <= (std::numeric_limits<std::uint64_t>::max)())
+                {
+                    oa->write_character(to_char_type(0xBB));
+                    write_number(static_cast<std::uint64_t>(N));
+                }
+                // LCOV_EXCL_STOP
+
+                // step 2: write each element
+                for (const auto& el : *j.m_value.object)
+                {
+                    write_cbor(el.first);
+                    write_cbor(el.second);
+                }
+                break;
+            }
+
+            default:
+                break;
+        }
+    }
+
+    /*!
+    @param[in] j  JSON value to serialize
+    */
+    void write_msgpack(const BasicJsonType& j)
+    {
+        switch (j.type())
+        {
+            case value_t::null: // nil
+            {
+                oa->write_character(to_char_type(0xC0));
+                break;
+            }
+
+            case value_t::boolean: // true and false
+            {
+                oa->write_character(j.m_value.boolean
+                                    ? to_char_type(0xC3)
+                                    : to_char_type(0xC2));
+                break;
+            }
+
+            case value_t::number_integer:
+            {
+                if (j.m_value.number_integer >= 0)
+                {
+                    // MessagePack does not differentiate between positive
+                    // signed integers and unsigned integers. Therefore, we used
+                    // the code from the value_t::number_unsigned case here.
+                    if (j.m_value.number_unsigned < 128)
+                    {
+                        // positive fixnum
+                        write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
+                    }
+                    else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
+                    {
+                        // uint 8
+                        oa->write_character(to_char_type(0xCC));
+                        write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
+                    }
+                    else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
+                    {
+                        // uint 16
+                        oa->write_character(to_char_type(0xCD));
+                        write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
+                    }
+                    else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
+                    {
+                        // uint 32
+                        oa->write_character(to_char_type(0xCE));
+                        write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
+                    }
+                    else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
+                    {
+                        // uint 64
+                        oa->write_character(to_char_type(0xCF));
+                        write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
+                    }
+                }
+                else
+                {
+                    if (j.m_value.number_integer >= -32)
+                    {
+                        // negative fixnum
+                        write_number(static_cast<std::int8_t>(j.m_value.number_integer));
+                    }
+                    else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
+                             j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
+                    {
+                        // int 8
+                        oa->write_character(to_char_type(0xD0));
+                        write_number(static_cast<std::int8_t>(j.m_value.number_integer));
+                    }
+                    else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
+                             j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
+                    {
+                        // int 16
+                        oa->write_character(to_char_type(0xD1));
+                        write_number(static_cast<std::int16_t>(j.m_value.number_integer));
+                    }
+                    else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
+                             j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
+                    {
+                        // int 32
+                        oa->write_character(to_char_type(0xD2));
+                        write_number(static_cast<std::int32_t>(j.m_value.number_integer));
+                    }
+                    else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
+                             j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
+                    {
+                        // int 64
+                        oa->write_character(to_char_type(0xD3));
+                        write_number(static_cast<std::int64_t>(j.m_value.number_integer));
+                    }
+                }
+                break;
+            }
+
+            case value_t::number_unsigned:
+            {
+                if (j.m_value.number_unsigned < 128)
+                {
+                    // positive fixnum
+                    write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
+                }
+                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
+                {
+                    // uint 8
+                    oa->write_character(to_char_type(0xCC));
+                    write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
+                }
+                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
+                {
+                    // uint 16
+                    oa->write_character(to_char_type(0xCD));
+                    write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
+                }
+                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
+                {
+                    // uint 32
+                    oa->write_character(to_char_type(0xCE));
+                    write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
+                }
+                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
+                {
+                    // uint 64
+                    oa->write_character(to_char_type(0xCF));
+                    write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
+                }
+                break;
+            }
+
+            case value_t::number_float:
+            {
+                write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
+                break;
+            }
+
+            case value_t::string:
+            {
+                // step 1: write control byte and the string length
+                const auto N = j.m_value.string->size();
+                if (N <= 31)
+                {
+                    // fixstr
+                    write_number(static_cast<std::uint8_t>(0xA0 | N));
+                }
+                else if (N <= (std::numeric_limits<std::uint8_t>::max)())
+                {
+                    // str 8
+                    oa->write_character(to_char_type(0xD9));
+                    write_number(static_cast<std::uint8_t>(N));
+                }
+                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
+                {
+                    // str 16
+                    oa->write_character(to_char_type(0xDA));
+                    write_number(static_cast<std::uint16_t>(N));
+                }
+                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
+                {
+                    // str 32
+                    oa->write_character(to_char_type(0xDB));
+                    write_number(static_cast<std::uint32_t>(N));
+                }
+
+                // step 2: write the string
+                oa->write_characters(
+                    reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
+                    j.m_value.string->size());
+                break;
+            }
+
+            case value_t::array:
+            {
+                // step 1: write control byte and the array size
+                const auto N = j.m_value.array->size();
+                if (N <= 15)
+                {
+                    // fixarray
+                    write_number(static_cast<std::uint8_t>(0x90 | N));
+                }
+                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
+                {
+                    // array 16
+                    oa->write_character(to_char_type(0xDC));
+                    write_number(static_cast<std::uint16_t>(N));
+                }
+                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
+                {
+                    // array 32
+                    oa->write_character(to_char_type(0xDD));
+                    write_number(static_cast<std::uint32_t>(N));
+                }
+
+                // step 2: write each element
+                for (const auto& el : *j.m_value.array)
+                {
+                    write_msgpack(el);
+                }
+                break;
+            }
+
+            case value_t::binary:
+            {
+                // step 0: determine if the binary type has a set subtype to
+                // determine whether or not to use the ext or fixext types
+                const bool use_ext = j.m_value.binary->has_subtype();
+
+                // step 1: write control byte and the byte string length
+                const auto N = j.m_value.binary->size();
+                if (N <= (std::numeric_limits<std::uint8_t>::max)())
+                {
+                    std::uint8_t output_type{};
+                    bool fixed = true;
+                    if (use_ext)
+                    {
+                        switch (N)
+                        {
+                            case 1:
+                                output_type = 0xD4; // fixext 1
+                                break;
+                            case 2:
+                                output_type = 0xD5; // fixext 2
+                                break;
+                            case 4:
+                                output_type = 0xD6; // fixext 4
+                                break;
+                            case 8:
+                                output_type = 0xD7; // fixext 8
+                                break;
+                            case 16:
+                                output_type = 0xD8; // fixext 16
+                                break;
+                            default:
+                                output_type = 0xC7; // ext 8
+                                fixed = false;
+                                break;
+                        }
+
+                    }
+                    else
+                    {
+                        output_type = 0xC4; // bin 8
+                        fixed = false;
+                    }
+
+                    oa->write_character(to_char_type(output_type));
+                    if (!fixed)
+                    {
+                        write_number(static_cast<std::uint8_t>(N));
+                    }
+                }
+                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
+                {
+                    std::uint8_t output_type = use_ext
+                                               ? 0xC8 // ext 16
+                                               : 0xC5; // bin 16
+
+                    oa->write_character(to_char_type(output_type));
+                    write_number(static_cast<std::uint16_t>(N));
+                }
+                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
+                {
+                    std::uint8_t output_type = use_ext
+                                               ? 0xC9 // ext 32
+                                               : 0xC6; // bin 32
+
+                    oa->write_character(to_char_type(output_type));
+                    write_number(static_cast<std::uint32_t>(N));
+                }
+
+                // step 1.5: if this is an ext type, write the subtype
+                if (use_ext)
+                {
+                    write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
+                }
+
+                // step 2: write the byte string
+                oa->write_characters(
+                    reinterpret_cast<const CharType*>(j.m_value.binary->data()),
+                    N);
+
+                break;
+            }
+
+            case value_t::object:
+            {
+                // step 1: write control byte and the object size
+                const auto N = j.m_value.object->size();
+                if (N <= 15)
+                {
+                    // fixmap
+                    write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
+                }
+                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
+                {
+                    // map 16
+                    oa->write_character(to_char_type(0xDE));
+                    write_number(static_cast<std::uint16_t>(N));
+                }
+                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
+                {
+                    // map 32
+                    oa->write_character(to_char_type(0xDF));
+                    write_number(static_cast<std::uint32_t>(N));
+                }
+
+                // step 2: write each element
+                for (const auto& el : *j.m_value.object)
+                {
+                    write_msgpack(el.first);
+                    write_msgpack(el.second);
+                }
+                break;
+            }
+
+            default:
+                break;
+        }
+    }
+
+    /*!
+    @param[in] j  JSON value to serialize
+    @param[in] use_count   whether to use '#' prefixes (optimized format)
+    @param[in] use_type    whether to use '$' prefixes (optimized format)
+    @param[in] add_prefix  whether prefixes need to be used for this value
+    */
+    void write_ubjson(const BasicJsonType& j, const bool use_count,
+                      const bool use_type, const bool add_prefix = true)
+    {
+        switch (j.type())
+        {
+            case value_t::null:
+            {
+                if (add_prefix)
+                {
+                    oa->write_character(to_char_type('Z'));
+                }
+                break;
+            }
+
+            case value_t::boolean:
+            {
+                if (add_prefix)
+                {
+                    oa->write_character(j.m_value.boolean
+                                        ? to_char_type('T')
+                                        : to_char_type('F'));
+                }
+                break;
+            }
+
+            case value_t::number_integer:
+            {
+                write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
+                break;
+            }
+
+            case value_t::number_unsigned:
+            {
+                write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
+                break;
+            }
+
+            case value_t::number_float:
+            {
+                write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
+                break;
+            }
+
+            case value_t::string:
+            {
+                if (add_prefix)
+                {
+                    oa->write_character(to_char_type('S'));
+                }
+                write_number_with_ubjson_prefix(j.m_value.string->size(), true);
+                oa->write_characters(
+                    reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
+                    j.m_value.string->size());
+                break;
+            }
+
+            case value_t::array:
+            {
+                if (add_prefix)
+                {
+                    oa->write_character(to_char_type('['));
+                }
+
+                bool prefix_required = true;
+                if (use_type && !j.m_value.array->empty())
+                {
+                    JSON_ASSERT(use_count);
+                    const CharType first_prefix = ubjson_prefix(j.front());
+                    const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
+                                                         [this, first_prefix](const BasicJsonType & v)
+                    {
+                        return ubjson_prefix(v) == first_prefix;
+                    });
+
+                    if (same_prefix)
+                    {
+                        prefix_required = false;
+                        oa->write_character(to_char_type('$'));
+                        oa->write_character(first_prefix);
+                    }
+                }
+
+                if (use_count)
+                {
+                    oa->write_character(to_char_type('#'));
+                    write_number_with_ubjson_prefix(j.m_value.array->size(), true);
+                }
+
+                for (const auto& el : *j.m_value.array)
+                {
+                    write_ubjson(el, use_count, use_type, prefix_required);
+                }
+
+                if (!use_count)
+                {
+                    oa->write_character(to_char_type(']'));
+                }
+
+                break;
+            }
+
+            case value_t::binary:
+            {
+                if (add_prefix)
+                {
+                    oa->write_character(to_char_type('['));
+                }
+
+                if (use_type && !j.m_value.binary->empty())
+                {
+                    JSON_ASSERT(use_count);
+                    oa->write_character(to_char_type('$'));
+                    oa->write_character('U');
+                }
+
+                if (use_count)
+                {
+                    oa->write_character(to_char_type('#'));
+                    write_number_with_ubjson_prefix(j.m_value.binary->size(), true);
+                }
+
+                if (use_type)
+                {
+                    oa->write_characters(
+                        reinterpret_cast<const CharType*>(j.m_value.binary->data()),
+                        j.m_value.binary->size());
+                }
+                else
+                {
+                    for (size_t i = 0; i < j.m_value.binary->size(); ++i)
+                    {
+                        oa->write_character(to_char_type('U'));
+                        oa->write_character(j.m_value.binary->data()[i]);
+                    }
+                }
+
+                if (!use_count)
+                {
+                    oa->write_character(to_char_type(']'));
+                }
+
+                break;
+            }
+
+            case value_t::object:
+            {
+                if (add_prefix)
+                {
+                    oa->write_character(to_char_type('{'));
+                }
+
+                bool prefix_required = true;
+                if (use_type && !j.m_value.object->empty())
+                {
+                    JSON_ASSERT(use_count);
+                    const CharType first_prefix = ubjson_prefix(j.front());
+                    const bool same_prefix = std::all_of(j.begin(), j.end(),
+                                                         [this, first_prefix](const BasicJsonType & v)
+                    {
+                        return ubjson_prefix(v) == first_prefix;
+                    });
+
+                    if (same_prefix)
+                    {
+                        prefix_required = false;
+                        oa->write_character(to_char_type('$'));
+                        oa->write_character(first_prefix);
+                    }
+                }
+
+                if (use_count)
+                {
+                    oa->write_character(to_char_type('#'));
+                    write_number_with_ubjson_prefix(j.m_value.object->size(), true);
+                }
+
+                for (const auto& el : *j.m_value.object)
+                {
+                    write_number_with_ubjson_prefix(el.first.size(), true);
+                    oa->write_characters(
+                        reinterpret_cast<const CharType*>(el.first.c_str()),
+                        el.first.size());
+                    write_ubjson(el.second, use_count, use_type, prefix_required);
+                }
+
+                if (!use_count)
+                {
+                    oa->write_character(to_char_type('}'));
+                }
+
+                break;
+            }
+
+            default:
+                break;
+        }
+    }
+
+  private:
+    //////////
+    // BSON //
+    //////////
+
+    /*!
+    @return The size of a BSON document entry header, including the id marker
+            and the entry name size (and its null-terminator).
+    */
+    static std::size_t calc_bson_entry_header_size(const string_t& name)
+    {
+        const auto it = name.find(static_cast<typename string_t::value_type>(0));
+        if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
+        {
+            JSON_THROW(out_of_range::create(409,
+                                            "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")"));
+        }
+
+        return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
+    }
+
+    /*!
+    @brief Writes the given @a element_type and @a name to the output adapter
+    */
+    void write_bson_entry_header(const string_t& name,
+                                 const std::uint8_t element_type)
+    {
+        oa->write_character(to_char_type(element_type)); // boolean
+        oa->write_characters(
+            reinterpret_cast<const CharType*>(name.c_str()),
+            name.size() + 1u);
+    }
+
+    /*!
+    @brief Writes a BSON element with key @a name and boolean value @a value
+    */
+    void write_bson_boolean(const string_t& name,
+                            const bool value)
+    {
+        write_bson_entry_header(name, 0x08);
+        oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
+    }
+
+    /*!
+    @brief Writes a BSON element with key @a name and double value @a value
+    */
+    void write_bson_double(const string_t& name,
+                           const double value)
+    {
+        write_bson_entry_header(name, 0x01);
+        write_number<double, true>(value);
+    }
+
+    /*!
+    @return The size of the BSON-encoded string in @a value
+    */
+    static std::size_t calc_bson_string_size(const string_t& value)
+    {
+        return sizeof(std::int32_t) + value.size() + 1ul;
+    }
+
+    /*!
+    @brief Writes a BSON element with key @a name and string value @a value
+    */
+    void write_bson_string(const string_t& name,
+                           const string_t& value)
+    {
+        write_bson_entry_header(name, 0x02);
+
+        write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
+        oa->write_characters(
+            reinterpret_cast<const CharType*>(value.c_str()),
+            value.size() + 1);
+    }
+
+    /*!
+    @brief Writes a BSON element with key @a name and null value
+    */
+    void write_bson_null(const string_t& name)
+    {
+        write_bson_entry_header(name, 0x0A);
+    }
+
+    /*!
+    @return The size of the BSON-encoded integer @a value
+    */
+    static std::size_t calc_bson_integer_size(const std::int64_t value)
+    {
+        return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
+               ? sizeof(std::int32_t)
+               : sizeof(std::int64_t);
+    }
+
+    /*!
+    @brief Writes a BSON element with key @a name and integer @a value
+    */
+    void write_bson_integer(const string_t& name,
+                            const std::int64_t value)
+    {
+        if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
+        {
+            write_bson_entry_header(name, 0x10); // int32
+            write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
+        }
+        else
+        {
+            write_bson_entry_header(name, 0x12); // int64
+            write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
+        }
+    }
+
+    /*!
+    @return The size of the BSON-encoded unsigned integer in @a j
+    */
+    static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
+    {
+        return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
+               ? sizeof(std::int32_t)
+               : sizeof(std::int64_t);
+    }
+
+    /*!
+    @brief Writes a BSON element with key @a name and unsigned @a value
+    */
+    void write_bson_unsigned(const string_t& name,
+                             const std::uint64_t value)
+    {
+        if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
+        {
+            write_bson_entry_header(name, 0x10 /* int32 */);
+            write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
+        }
+        else if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
+        {
+            write_bson_entry_header(name, 0x12 /* int64 */);
+            write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
+        }
+        else
+        {
+            JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(value) + " cannot be represented by BSON as it does not fit int64"));
+        }
+    }
+
+    /*!
+    @brief Writes a BSON element with key @a name and object @a value
+    */
+    void write_bson_object_entry(const string_t& name,
+                                 const typename BasicJsonType::object_t& value)
+    {
+        write_bson_entry_header(name, 0x03); // object
+        write_bson_object(value);
+    }
+
+    /*!
+    @return The size of the BSON-encoded array @a value
+    */
+    static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
+    {
+        std::size_t array_index = 0ul;
+
+        const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), std::size_t(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
+        {
+            return result + calc_bson_element_size(std::to_string(array_index++), el);
+        });
+
+        return sizeof(std::int32_t) + embedded_document_size + 1ul;
+    }
+
+    /*!
+    @return The size of the BSON-encoded binary array @a value
+    */
+    static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
+    {
+        return sizeof(std::int32_t) + value.size() + 1ul;
+    }
+
+    /*!
+    @brief Writes a BSON element with key @a name and array @a value
+    */
+    void write_bson_array(const string_t& name,
+                          const typename BasicJsonType::array_t& value)
+    {
+        write_bson_entry_header(name, 0x04); // array
+        write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
+
+        std::size_t array_index = 0ul;
+
+        for (const auto& el : value)
+        {
+            write_bson_element(std::to_string(array_index++), el);
+        }
+
+        oa->write_character(to_char_type(0x00));
+    }
+
+    /*!
+    @brief Writes a BSON element with key @a name and binary value @a value
+    */
+    void write_bson_binary(const string_t& name,
+                           const binary_t& value)
+    {
+        write_bson_entry_header(name, 0x05);
+
+        write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
+        write_number(value.has_subtype() ? value.subtype() : std::uint8_t(0x00));
+
+        oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
+    }
+
+    /*!
+    @brief Calculates the size necessary to serialize the JSON value @a j with its @a name
+    @return The calculated size for the BSON document entry for @a j with the given @a name.
+    */
+    static std::size_t calc_bson_element_size(const string_t& name,
+            const BasicJsonType& j)
+    {
+        const auto header_size = calc_bson_entry_header_size(name);
+        switch (j.type())
+        {
+            case value_t::object:
+                return header_size + calc_bson_object_size(*j.m_value.object);
+
+            case value_t::array:
+                return header_size + calc_bson_array_size(*j.m_value.array);
+
+            case value_t::binary:
+                return header_size + calc_bson_binary_size(*j.m_value.binary);
+
+            case value_t::boolean:
+                return header_size + 1ul;
+
+            case value_t::number_float:
+                return header_size + 8ul;
+
+            case value_t::number_integer:
+                return header_size + calc_bson_integer_size(j.m_value.number_integer);
+
+            case value_t::number_unsigned:
+                return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
+
+            case value_t::string:
+                return header_size + calc_bson_string_size(*j.m_value.string);
+
+            case value_t::null:
+                return header_size + 0ul;
+
+            // LCOV_EXCL_START
+            default:
+                JSON_ASSERT(false);
+                return 0ul;
+                // LCOV_EXCL_STOP
+        }
+    }
+
+    /*!
+    @brief Serializes the JSON value @a j to BSON and associates it with the
+           key @a name.
+    @param name The name to associate with the JSON entity @a j within the
+                current BSON document
+    @return The size of the BSON entry
+    */
+    void write_bson_element(const string_t& name,
+                            const BasicJsonType& j)
+    {
+        switch (j.type())
+        {
+            case value_t::object:
+                return write_bson_object_entry(name, *j.m_value.object);
+
+            case value_t::array:
+                return write_bson_array(name, *j.m_value.array);
+
+            case value_t::binary:
+                return write_bson_binary(name, *j.m_value.binary);
+
+            case value_t::boolean:
+                return write_bson_boolean(name, j.m_value.boolean);
+
+            case value_t::number_float:
+                return write_bson_double(name, j.m_value.number_float);
+
+            case value_t::number_integer:
+                return write_bson_integer(name, j.m_value.number_integer);
+
+            case value_t::number_unsigned:
+                return write_bson_unsigned(name, j.m_value.number_unsigned);
+
+            case value_t::string:
+                return write_bson_string(name, *j.m_value.string);
+
+            case value_t::null:
+                return write_bson_null(name);
+
+            // LCOV_EXCL_START
+            default:
+                JSON_ASSERT(false);
+                return;
+                // LCOV_EXCL_STOP
+        }
+    }
+
+    /*!
+    @brief Calculates the size of the BSON serialization of the given
+           JSON-object @a j.
+    @param[in] j  JSON value to serialize
+    @pre       j.type() == value_t::object
+    */
+    static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
+    {
+        std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0),
+                                    [](size_t result, const typename BasicJsonType::object_t::value_type & el)
+        {
+            return result += calc_bson_element_size(el.first, el.second);
+        });
+
+        return sizeof(std::int32_t) + document_size + 1ul;
+    }
+
+    /*!
+    @param[in] j  JSON value to serialize
+    @pre       j.type() == value_t::object
+    */
+    void write_bson_object(const typename BasicJsonType::object_t& value)
+    {
+        write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
+
+        for (const auto& el : value)
+        {
+            write_bson_element(el.first, el.second);
+        }
+
+        oa->write_character(to_char_type(0x00));
+    }
+
+    //////////
+    // CBOR //
+    //////////
+
+    static constexpr CharType get_cbor_float_prefix(float /*unused*/)
+    {
+        return to_char_type(0xFA);  // Single-Precision Float
+    }
+
+    static constexpr CharType get_cbor_float_prefix(double /*unused*/)
+    {
+        return to_char_type(0xFB);  // Double-Precision Float
+    }
+
+    /////////////
+    // MsgPack //
+    /////////////
+
+    static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
+    {
+        return to_char_type(0xCA);  // float 32
+    }
+
+    static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
+    {
+        return to_char_type(0xCB);  // float 64
+    }
+
+    ////////////
+    // UBJSON //
+    ////////////
+
+    // UBJSON: write number (floating point)
+    template<typename NumberType, typename std::enable_if<
+                 std::is_floating_point<NumberType>::value, int>::type = 0>
+    void write_number_with_ubjson_prefix(const NumberType n,
+                                         const bool add_prefix)
+    {
+        if (add_prefix)
+        {
+            oa->write_character(get_ubjson_float_prefix(n));
+        }
+        write_number(n);
+    }
+
+    // UBJSON: write number (unsigned integer)
+    template<typename NumberType, typename std::enable_if<
+                 std::is_unsigned<NumberType>::value, int>::type = 0>
+    void write_number_with_ubjson_prefix(const NumberType n,
+                                         const bool add_prefix)
+    {
+        if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
+        {
+            if (add_prefix)
+            {
+                oa->write_character(to_char_type('i'));  // int8
+            }
+            write_number(static_cast<std::uint8_t>(n));
+        }
+        else if (n <= (std::numeric_limits<std::uint8_t>::max)())
+        {
+            if (add_prefix)
+            {
+                oa->write_character(to_char_type('U'));  // uint8
+            }
+            write_number(static_cast<std::uint8_t>(n));
+        }
+        else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
+        {
+            if (add_prefix)
+            {
+                oa->write_character(to_char_type('I'));  // int16
+            }
+            write_number(static_cast<std::int16_t>(n));
+        }
+        else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
+        {
+            if (add_prefix)
+            {
+                oa->write_character(to_char_type('l'));  // int32
+            }
+            write_number(static_cast<std::int32_t>(n));
+        }
+        else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
+        {
+            if (add_prefix)
+            {
+                oa->write_character(to_char_type('L'));  // int64
+            }
+            write_number(static_cast<std::int64_t>(n));
+        }
+        else
+        {
+            if (add_prefix)
+            {
+                oa->write_character(to_char_type('H'));  // high-precision number
+            }
+
+            const auto number = BasicJsonType(n).dump();
+            write_number_with_ubjson_prefix(number.size(), true);
+            for (std::size_t i = 0; i < number.size(); ++i)
+            {
+                oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
+            }
+        }
+    }
+
+    // UBJSON: write number (signed integer)
+    template < typename NumberType, typename std::enable_if <
+                   std::is_signed<NumberType>::value&&
+                   !std::is_floating_point<NumberType>::value, int >::type = 0 >
+    void write_number_with_ubjson_prefix(const NumberType n,
+                                         const bool add_prefix)
+    {
+        if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
+        {
+            if (add_prefix)
+            {
+                oa->write_character(to_char_type('i'));  // int8
+            }
+            write_number(static_cast<std::int8_t>(n));
+        }
+        else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
+        {
+            if (add_prefix)
+            {
+                oa->write_character(to_char_type('U'));  // uint8
+            }
+            write_number(static_cast<std::uint8_t>(n));
+        }
+        else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
+        {
+            if (add_prefix)
+            {
+                oa->write_character(to_char_type('I'));  // int16
+            }
+            write_number(static_cast<std::int16_t>(n));
+        }
+        else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
+        {
+            if (add_prefix)
+            {
+                oa->write_character(to_char_type('l'));  // int32
+            }
+            write_number(static_cast<std::int32_t>(n));
+        }
+        else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
+        {
+            if (add_prefix)
+            {
+                oa->write_character(to_char_type('L'));  // int64
+            }
+            write_number(static_cast<std::int64_t>(n));
+        }
+        // LCOV_EXCL_START
+        else
+        {
+            if (add_prefix)
+            {
+                oa->write_character(to_char_type('H'));  // high-precision number
+            }
+
+            const auto number = BasicJsonType(n).dump();
+            write_number_with_ubjson_prefix(number.size(), true);
+            for (std::size_t i = 0; i < number.size(); ++i)
+            {
+                oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
+            }
+        }
+        // LCOV_EXCL_STOP
+    }
+
+    /*!
+    @brief determine the type prefix of container values
+    */
+    CharType ubjson_prefix(const BasicJsonType& j) const noexcept
+    {
+        switch (j.type())
+        {
+            case value_t::null:
+                return 'Z';
+
+            case value_t::boolean:
+                return j.m_value.boolean ? 'T' : 'F';
+
+            case value_t::number_integer:
+            {
+                if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
+                {
+                    return 'i';
+                }
+                if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
+                {
+                    return 'U';
+                }
+                if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
+                {
+                    return 'I';
+                }
+                if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
+                {
+                    return 'l';
+                }
+                if ((std::numeric_limits<std::int64_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
+                {
+                    return 'L';
+                }
+                // anything else is treated as high-precision number
+                return 'H'; // LCOV_EXCL_LINE
+            }
+
+            case value_t::number_unsigned:
+            {
+                if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
+                {
+                    return 'i';
+                }
+                if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
+                {
+                    return 'U';
+                }
+                if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
+                {
+                    return 'I';
+                }
+                if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
+                {
+                    return 'l';
+                }
+                if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
+                {
+                    return 'L';
+                }
+                // anything else is treated as high-precision number
+                return 'H'; // LCOV_EXCL_LINE
+            }
+
+            case value_t::number_float:
+                return get_ubjson_float_prefix(j.m_value.number_float);
+
+            case value_t::string:
+                return 'S';
+
+            case value_t::array: // fallthrough
+            case value_t::binary:
+                return '[';
+
+            case value_t::object:
+                return '{';
+
+            default:  // discarded values
+                return 'N';
+        }
+    }
+
+    static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
+    {
+        return 'd';  // float 32
+    }
+
+    static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
+    {
+        return 'D';  // float 64
+    }
+
+    ///////////////////////
+    // Utility functions //
+    ///////////////////////
+
+    /*
+    @brief write a number to output input
+    @param[in] n number of type @a NumberType
+    @tparam NumberType the type of the number
+    @tparam OutputIsLittleEndian Set to true if output data is
+                                 required to be little endian
+
+    @note This function needs to respect the system's endianess, because bytes
+          in CBOR, MessagePack, and UBJSON are stored in network order (big
+          endian) and therefore need reordering on little endian systems.
+    */
+    template<typename NumberType, bool OutputIsLittleEndian = false>
+    void write_number(const NumberType n)
+    {
+        // step 1: write number to array of length NumberType
+        std::array<CharType, sizeof(NumberType)> vec;
+        std::memcpy(vec.data(), &n, sizeof(NumberType));
+
+        // step 2: write array to output (with possible reordering)
+        if (is_little_endian != OutputIsLittleEndian)
+        {
+            // reverse byte order prior to conversion if necessary
+            std::reverse(vec.begin(), vec.end());
+        }
+
+        oa->write_characters(vec.data(), sizeof(NumberType));
+    }
+
+    void write_compact_float(const number_float_t n, detail::input_format_t format)
+    {
+        if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
+                static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
+                static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
+        {
+            oa->write_character(format == detail::input_format_t::cbor
+                                ? get_cbor_float_prefix(static_cast<float>(n))
+                                : get_msgpack_float_prefix(static_cast<float>(n)));
+            write_number(static_cast<float>(n));
+        }
+        else
+        {
+            oa->write_character(format == detail::input_format_t::cbor
+                                ? get_cbor_float_prefix(n)
+                                : get_msgpack_float_prefix(n));
+            write_number(n);
+        }
+    }
+
+  public:
+    // The following to_char_type functions are implement the conversion
+    // between uint8_t and CharType. In case CharType is not unsigned,
+    // such a conversion is required to allow values greater than 128.
+    // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
+    template < typename C = CharType,
+               enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
+    static constexpr CharType to_char_type(std::uint8_t x) noexcept
+    {
+        return *reinterpret_cast<char*>(&x);
+    }
+
+    template < typename C = CharType,
+               enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
+    static CharType to_char_type(std::uint8_t x) noexcept
+    {
+        static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
+        static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
+        CharType result;
+        std::memcpy(&result, &x, sizeof(x));
+        return result;
+    }
+
+    template<typename C = CharType,
+             enable_if_t<std::is_unsigned<C>::value>* = nullptr>
+    static constexpr CharType to_char_type(std::uint8_t x) noexcept
+    {
+        return x;
+    }
+
+    template < typename InputCharType, typename C = CharType,
+               enable_if_t <
+                   std::is_signed<C>::value &&
+                   std::is_signed<char>::value &&
+                   std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
+                   > * = nullptr >
+    static constexpr CharType to_char_type(InputCharType x) noexcept
+    {
+        return x;
+    }
+
+  private:
+    /// whether we can assume little endianess
+    const bool is_little_endian = little_endianess();
+
+    /// the output
+    output_adapter_t<CharType> oa = nullptr;
+};
+}  // namespace detail
+}  // namespace nlohmann
+
+// #include <nlohmann/detail/output/output_adapters.hpp>
+
+// #include <nlohmann/detail/output/serializer.hpp>
+
+
+#include <algorithm> // reverse, remove, fill, find, none_of
+#include <array> // array
+#include <clocale> // localeconv, lconv
+#include <cmath> // labs, isfinite, isnan, signbit
+#include <cstddef> // size_t, ptrdiff_t
+#include <cstdint> // uint8_t
+#include <cstdio> // snprintf
+#include <limits> // numeric_limits
+#include <string> // string, char_traits
+#include <type_traits> // is_same
+#include <utility> // move
+
+// #include <nlohmann/detail/conversions/to_chars.hpp>
+
+
+#include <array> // array
+#include <cmath>   // signbit, isfinite
+#include <cstdint> // intN_t, uintN_t
+#include <cstring> // memcpy, memmove
+#include <limits> // numeric_limits
+#include <type_traits> // conditional
+
+// #include <nlohmann/detail/macro_scope.hpp>
+
+
+namespace nlohmann
+{
+namespace detail
+{
+
+/*!
+@brief implements the Grisu2 algorithm for binary to decimal floating-point
+conversion.
+
+This implementation is a slightly modified version of the reference
+implementation which may be obtained from
+http://florian.loitsch.com/publications (bench.tar.gz).
+
+The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch.
+
+For a detailed description of the algorithm see:
+
+[1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with
+    Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming
+    Language Design and Implementation, PLDI 2010
+[2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately",
+    Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language
+    Design and Implementation, PLDI 1996
+*/
+namespace dtoa_impl
+{
+
+template<typename Target, typename Source>
+Target reinterpret_bits(const Source source)
+{
+    static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
+
+    Target target;
+    std::memcpy(&target, &source, sizeof(Source));
+    return target;
+}
+
+struct diyfp // f * 2^e
+{
+    static constexpr int kPrecision = 64; // = q
+
+    std::uint64_t f = 0;
+    int e = 0;
+
+    constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
+
+    /*!
+    @brief returns x - y
+    @pre x.e == y.e and x.f >= y.f
+    */
+    static diyfp sub(const diyfp& x, const diyfp& y) noexcept
+    {
+        JSON_ASSERT(x.e == y.e);
+        JSON_ASSERT(x.f >= y.f);
+
+        return {x.f - y.f, x.e};
+    }
+
+    /*!
+    @brief returns x * y
+    @note The result is rounded. (Only the upper q bits are returned.)
+    */
+    static diyfp mul(const diyfp& x, const diyfp& y) noexcept
+    {
+        static_assert(kPrecision == 64, "internal error");
+
+        // Computes:
+        //  f = round((x.f * y.f) / 2^q)
+        //  e = x.e + y.e + q
+
+        // Emulate the 64-bit * 64-bit multiplication:
+        //
+        // p = u * v
+        //   = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
+        //   = (u_lo v_lo         ) + 2^32 ((u_lo v_hi         ) + (u_hi v_lo         )) + 2^64 (u_hi v_hi         )
+        //   = (p0                ) + 2^32 ((p1                ) + (p2                )) + 2^64 (p3                )
+        //   = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3                )
+        //   = (p0_lo             ) + 2^32 (p0_hi + p1_lo + p2_lo                      ) + 2^64 (p1_hi + p2_hi + p3)
+        //   = (p0_lo             ) + 2^32 (Q                                          ) + 2^64 (H                 )
+        //   = (p0_lo             ) + 2^32 (Q_lo + 2^32 Q_hi                           ) + 2^64 (H                 )
+        //
+        // (Since Q might be larger than 2^32 - 1)
+        //
+        //   = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
+        //
+        // (Q_hi + H does not overflow a 64-bit int)
+        //
+        //   = p_lo + 2^64 p_hi
+
+        const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
+        const std::uint64_t u_hi = x.f >> 32u;
+        const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
+        const std::uint64_t v_hi = y.f >> 32u;
+
+        const std::uint64_t p0 = u_lo * v_lo;
+        const std::uint64_t p1 = u_lo * v_hi;
+        const std::uint64_t p2 = u_hi * v_lo;
+        const std::uint64_t p3 = u_hi * v_hi;
+
+        const std::uint64_t p0_hi = p0 >> 32u;
+        const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
+        const std::uint64_t p1_hi = p1 >> 32u;
+        const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
+        const std::uint64_t p2_hi = p2 >> 32u;
+
+        std::uint64_t Q = p0_hi + p1_lo + p2_lo;
+
+        // The full product might now be computed as
+        //
+        // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
+        // p_lo = p0_lo + (Q << 32)
+        //
+        // But in this particular case here, the full p_lo is not required.
+        // Effectively we only need to add the highest bit in p_lo to p_hi (and
+        // Q_hi + 1 does not overflow).
+
+        Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
+
+        const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
+
+        return {h, x.e + y.e + 64};
+    }
+
+    /*!
+    @brief normalize x such that the significand is >= 2^(q-1)
+    @pre x.f != 0
+    */
+    static diyfp normalize(diyfp x) noexcept
+    {
+        JSON_ASSERT(x.f != 0);
+
+        while ((x.f >> 63u) == 0)
+        {
+            x.f <<= 1u;
+            x.e--;
+        }
+
+        return x;
+    }
+
+    /*!
+    @brief normalize x such that the result has the exponent E
+    @pre e >= x.e and the upper e - x.e bits of x.f must be zero.
+    */
+    static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
+    {
+        const int delta = x.e - target_exponent;
+
+        JSON_ASSERT(delta >= 0);
+        JSON_ASSERT(((x.f << delta) >> delta) == x.f);
+
+        return {x.f << delta, target_exponent};
+    }
+};
+
+struct boundaries
+{
+    diyfp w;
+    diyfp minus;
+    diyfp plus;
+};
+
+/*!
+Compute the (normalized) diyfp representing the input number 'value' and its
+boundaries.
+
+@pre value must be finite and positive
+*/
+template<typename FloatType>
+boundaries compute_boundaries(FloatType value)
+{
+    JSON_ASSERT(std::isfinite(value));
+    JSON_ASSERT(value > 0);
+
+    // Convert the IEEE representation into a diyfp.
+    //
+    // If v is denormal:
+    //      value = 0.F * 2^(1 - bias) = (          F) * 2^(1 - bias - (p-1))
+    // If v is normalized:
+    //      value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
+
+    static_assert(std::numeric_limits<FloatType>::is_iec559,
+                  "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
+
+    constexpr int      kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
+    constexpr int      kBias      = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
+    constexpr int      kMinExp    = 1 - kBias;
+    constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
+
+    using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
+
+    const std::uint64_t bits = reinterpret_bits<bits_type>(value);
+    const std::uint64_t E = bits >> (kPrecision - 1);
+    const std::uint64_t F = bits & (kHiddenBit - 1);
+
+    const bool is_denormal = E == 0;
+    const diyfp v = is_denormal
+                    ? diyfp(F, kMinExp)
+                    : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
+
+    // Compute the boundaries m- and m+ of the floating-point value
+    // v = f * 2^e.
+    //
+    // Determine v- and v+, the floating-point predecessor and successor if v,
+    // respectively.
+    //
+    //      v- = v - 2^e        if f != 2^(p-1) or e == e_min                (A)
+    //         = v - 2^(e-1)    if f == 2^(p-1) and e > e_min                (B)
+    //
+    //      v+ = v + 2^e
+    //
+    // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
+    // between m- and m+ round to v, regardless of how the input rounding
+    // algorithm breaks ties.
+    //
+    //      ---+-------------+-------------+-------------+-------------+---  (A)
+    //         v-            m-            v             m+            v+
+    //
+    //      -----------------+------+------+-------------+-------------+---  (B)
+    //                       v-     m-     v             m+            v+
+
+    const bool lower_boundary_is_closer = F == 0 && E > 1;
+    const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
+    const diyfp m_minus = lower_boundary_is_closer
+                          ? diyfp(4 * v.f - 1, v.e - 2)  // (B)
+                          : diyfp(2 * v.f - 1, v.e - 1); // (A)
+
+    // Determine the normalized w+ = m+.
+    const diyfp w_plus = diyfp::normalize(m_plus);
+
+    // Determine w- = m- such that e_(w-) = e_(w+).
+    const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
+
+    return {diyfp::normalize(v), w_minus, w_plus};
+}
+
+// Given normalized diyfp w, Grisu needs to find a (normalized) cached
+// power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
+// within a certain range [alpha, gamma] (Definition 3.2 from [1])
+//
+//      alpha <= e = e_c + e_w + q <= gamma
+//
+// or
+//
+//      f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
+//                          <= f_c * f_w * 2^gamma
+//
+// Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
+//
+//      2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
+//
+// or
+//
+//      2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
+//
+// The choice of (alpha,gamma) determines the size of the table and the form of
+// the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
+// in practice:
+//
+// The idea is to cut the number c * w = f * 2^e into two parts, which can be
+// processed independently: An integral part p1, and a fractional part p2:
+//
+//      f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
+//              = (f div 2^-e) + (f mod 2^-e) * 2^e
+//              = p1 + p2 * 2^e
+//
+// The conversion of p1 into decimal form requires a series of divisions and
+// modulos by (a power of) 10. These operations are faster for 32-bit than for
+// 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
+// achieved by choosing
+//
+//      -e >= 32   or   e <= -32 := gamma
+//
+// In order to convert the fractional part
+//
+//      p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
+//
+// into decimal form, the fraction is repeatedly multiplied by 10 and the digits
+// d[-i] are extracted in order:
+//
+//      (10 * p2) div 2^-e = d[-1]
+//      (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
+//
+// The multiplication by 10 must not overflow. It is sufficient to choose
+//
+//      10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
+//
+// Since p2 = f mod 2^-e < 2^-e,
+//
+//      -e <= 60   or   e >= -60 := alpha
+
+constexpr int kAlpha = -60;
+constexpr int kGamma = -32;
+
+struct cached_power // c = f * 2^e ~= 10^k
+{
+    std::uint64_t f;
+    int e;
+    int k;
+};
+
+/*!
+For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached
+power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c
+satisfies (Definition 3.2 from [1])
+
+     alpha <= e_c + e + q <= gamma.
+*/
+inline cached_power get_cached_power_for_binary_exponent(int e)
+{
+    // Now
+    //
+    //      alpha <= e_c + e + q <= gamma                                    (1)
+    //      ==> f_c * 2^alpha <= c * 2^e * 2^q
+    //
+    // and since the c's are normalized, 2^(q-1) <= f_c,
+    //
+    //      ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
+    //      ==> 2^(alpha - e - 1) <= c
+    //
+    // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
+    //
+    //      k = ceil( log_10( 2^(alpha - e - 1) ) )
+    //        = ceil( (alpha - e - 1) * log_10(2) )
+    //
+    // From the paper:
+    // "In theory the result of the procedure could be wrong since c is rounded,
+    //  and the computation itself is approximated [...]. In practice, however,
+    //  this simple function is sufficient."
+    //
+    // For IEEE double precision floating-point numbers converted into
+    // normalized diyfp's w = f * 2^e, with q = 64,
+    //
+    //      e >= -1022      (min IEEE exponent)
+    //           -52        (p - 1)
+    //           -52        (p - 1, possibly normalize denormal IEEE numbers)
+    //           -11        (normalize the diyfp)
+    //         = -1137
+    //
+    // and
+    //
+    //      e <= +1023      (max IEEE exponent)
+    //           -52        (p - 1)
+    //           -11        (normalize the diyfp)
+    //         = 960
+    //
+    // This binary exponent range [-1137,960] results in a decimal exponent
+    // range [-307,324]. One does not need to store a cached power for each
+    // k in this range. For each such k it suffices to find a cached power
+    // such that the exponent of the product lies in [alpha,gamma].
+    // This implies that the difference of the decimal exponents of adjacent
+    // table entries must be less than or equal to
+    //
+    //      floor( (gamma - alpha) * log_10(2) ) = 8.
+    //
+    // (A smaller distance gamma-alpha would require a larger table.)
+
+    // NB:
+    // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
+
+    constexpr int kCachedPowersMinDecExp = -300;
+    constexpr int kCachedPowersDecStep = 8;
+
+    static constexpr std::array<cached_power, 79> kCachedPowers =
+    {
+        {
+            { 0xAB70FE17C79AC6CA, -1060, -300 },
+            { 0xFF77B1FCBEBCDC4F, -1034, -292 },
+            { 0xBE5691EF416BD60C, -1007, -284 },
+            { 0x8DD01FAD907FFC3C,  -980, -276 },
+            { 0xD3515C2831559A83,  -954, -268 },
+            { 0x9D71AC8FADA6C9B5,  -927, -260 },
+            { 0xEA9C227723EE8BCB,  -901, -252 },
+            { 0xAECC49914078536D,  -874, -244 },
+            { 0x823C12795DB6CE57,  -847, -236 },
+            { 0xC21094364DFB5637,  -821, -228 },
+            { 0x9096EA6F3848984F,  -794, -220 },
+            { 0xD77485CB25823AC7,  -768, -212 },
+            { 0xA086CFCD97BF97F4,  -741, -204 },
+            { 0xEF340A98172AACE5,  -715, -196 },
+            { 0xB23867FB2A35B28E,  -688, -188 },
+            { 0x84C8D4DFD2C63F3B,  -661, -180 },
+            { 0xC5DD44271AD3CDBA,  -635, -172 },
+            { 0x936B9FCEBB25C996,  -608, -164 },
+            { 0xDBAC6C247D62A584,  -582, -156 },
+            { 0xA3AB66580D5FDAF6,  -555, -148 },
+            { 0xF3E2F893DEC3F126,  -529, -140 },
+            { 0xB5B5ADA8AAFF80B8,  -502, -132 },
+            { 0x87625F056C7C4A8B,  -475, -124 },
+            { 0xC9BCFF6034C13053,  -449, -116 },
+            { 0x964E858C91BA2655,  -422, -108 },
+            { 0xDFF9772470297EBD,  -396, -100 },
+            { 0xA6DFBD9FB8E5B88F,  -369,  -92 },
+            { 0xF8A95FCF88747D94,  -343,  -84 },
+            { 0xB94470938FA89BCF,  -316,  -76 },
+            { 0x8A08F0F8BF0F156B,  -289,  -68 },
+            { 0xCDB02555653131B6,  -263,  -60 },
+            { 0x993FE2C6D07B7FAC,  -236,  -52 },
+            { 0xE45C10C42A2B3B06,  -210,  -44 },
+            { 0xAA242499697392D3,  -183,  -36 },
+            { 0xFD87B5F28300CA0E,  -157,  -28 },
+            { 0xBCE5086492111AEB,  -130,  -20 },
+            { 0x8CBCCC096F5088CC,  -103,  -12 },
+            { 0xD1B71758E219652C,   -77,   -4 },
+            { 0x9C40000000000000,   -50,    4 },
+            { 0xE8D4A51000000000,   -24,   12 },
+            { 0xAD78EBC5AC620000,     3,   20 },
+            { 0x813F3978F8940984,    30,   28 },
+            { 0xC097CE7BC90715B3,    56,   36 },
+            { 0x8F7E32CE7BEA5C70,    83,   44 },
+            { 0xD5D238A4ABE98068,   109,   52 },
+            { 0x9F4F2726179A2245,   136,   60 },
+            { 0xED63A231D4C4FB27,   162,   68 },
+            { 0xB0DE65388CC8ADA8,   189,   76 },
+            { 0x83C7088E1AAB65DB,   216,   84 },
+            { 0xC45D1DF942711D9A,   242,   92 },
+            { 0x924D692CA61BE758,   269,  100 },
+            { 0xDA01EE641A708DEA,   295,  108 },
+            { 0xA26DA3999AEF774A,   322,  116 },
+            { 0xF209787BB47D6B85,   348,  124 },
+            { 0xB454E4A179DD1877,   375,  132 },
+            { 0x865B86925B9BC5C2,   402,  140 },
+            { 0xC83553C5C8965D3D,   428,  148 },
+            { 0x952AB45CFA97A0B3,   455,  156 },
+            { 0xDE469FBD99A05FE3,   481,  164 },
+            { 0xA59BC234DB398C25,   508,  172 },
+            { 0xF6C69A72A3989F5C,   534,  180 },
+            { 0xB7DCBF5354E9BECE,   561,  188 },
+            { 0x88FCF317F22241E2,   588,  196 },
+            { 0xCC20CE9BD35C78A5,   614,  204 },
+            { 0x98165AF37B2153DF,   641,  212 },
+            { 0xE2A0B5DC971F303A,   667,  220 },
+            { 0xA8D9D1535CE3B396,   694,  228 },
+            { 0xFB9B7CD9A4A7443C,   720,  236 },
+            { 0xBB764C4CA7A44410,   747,  244 },
+            { 0x8BAB8EEFB6409C1A,   774,  252 },
+            { 0xD01FEF10A657842C,   800,  260 },
+            { 0x9B10A4E5E9913129,   827,  268 },
+            { 0xE7109BFBA19C0C9D,   853,  276 },
+            { 0xAC2820D9623BF429,   880,  284 },
+            { 0x80444B5E7AA7CF85,   907,  292 },
+            { 0xBF21E44003ACDD2D,   933,  300 },
+            { 0x8E679C2F5E44FF8F,   960,  308 },
+            { 0xD433179D9C8CB841,   986,  316 },
+            { 0x9E19DB92B4E31BA9,  1013,  324 },
+        }
+    };
+
+    // This computation gives exactly the same results for k as
+    //      k = ceil((kAlpha - e - 1) * 0.30102999566398114)
+    // for |e| <= 1500, but doesn't require floating-point operations.
+    // NB: log_10(2) ~= 78913 / 2^18
+    JSON_ASSERT(e >= -1500);
+    JSON_ASSERT(e <=  1500);
+    const int f = kAlpha - e - 1;
+    const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
+
+    const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
+    JSON_ASSERT(index >= 0);
+    JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
+
+    const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
+    JSON_ASSERT(kAlpha <= cached.e + e + 64);
+    JSON_ASSERT(kGamma >= cached.e + e + 64);
+
+    return cached;
+}
+
+/*!
+For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k.
+For n == 0, returns 1 and sets pow10 := 1.
+*/
+inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
+{
+    // LCOV_EXCL_START
+    if (n >= 1000000000)
+    {
+        pow10 = 1000000000;
+        return 10;
+    }
+    // LCOV_EXCL_STOP
+    else if (n >= 100000000)
+    {
+        pow10 = 100000000;
+        return  9;
+    }
+    else if (n >= 10000000)
+    {
+        pow10 = 10000000;
+        return  8;
+    }
+    else if (n >= 1000000)
+    {
+        pow10 = 1000000;
+        return  7;
+    }
+    else if (n >= 100000)
+    {
+        pow10 = 100000;
+        return  6;
+    }
+    else if (n >= 10000)
+    {
+        pow10 = 10000;
+        return  5;
+    }
+    else if (n >= 1000)
+    {
+        pow10 = 1000;
+        return  4;
+    }
+    else if (n >= 100)
+    {
+        pow10 = 100;
+        return  3;
+    }
+    else if (n >= 10)
+    {
+        pow10 = 10;
+        return  2;
+    }
+    else
+    {
+        pow10 = 1;
+        return 1;
+    }
+}
+
+inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
+                         std::uint64_t rest, std::uint64_t ten_k)
+{
+    JSON_ASSERT(len >= 1);
+    JSON_ASSERT(dist <= delta);
+    JSON_ASSERT(rest <= delta);
+    JSON_ASSERT(ten_k > 0);
+
+    //               <--------------------------- delta ---->
+    //                                  <---- dist --------->
+    // --------------[------------------+-------------------]--------------
+    //               M-                 w                   M+
+    //
+    //                                  ten_k
+    //                                <------>
+    //                                       <---- rest ---->
+    // --------------[------------------+----+--------------]--------------
+    //                                  w    V
+    //                                       = buf * 10^k
+    //
+    // ten_k represents a unit-in-the-last-place in the decimal representation
+    // stored in buf.
+    // Decrement buf by ten_k while this takes buf closer to w.
+
+    // The tests are written in this order to avoid overflow in unsigned
+    // integer arithmetic.
+
+    while (rest < dist
+            && delta - rest >= ten_k
+            && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
+    {
+        JSON_ASSERT(buf[len - 1] != '0');
+        buf[len - 1]--;
+        rest += ten_k;
+    }
+}
+
+/*!
+Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.
+M- and M+ must be normalized and share the same exponent -60 <= e <= -32.
+*/
+inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
+                             diyfp M_minus, diyfp w, diyfp M_plus)
+{
+    static_assert(kAlpha >= -60, "internal error");
+    static_assert(kGamma <= -32, "internal error");
+
+    // Generates the digits (and the exponent) of a decimal floating-point
+    // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
+    // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
+    //
+    //               <--------------------------- delta ---->
+    //                                  <---- dist --------->
+    // --------------[------------------+-------------------]--------------
+    //               M-                 w                   M+
+    //
+    // Grisu2 generates the digits of M+ from left to right and stops as soon as
+    // V is in [M-,M+].
+
+    JSON_ASSERT(M_plus.e >= kAlpha);
+    JSON_ASSERT(M_plus.e <= kGamma);
+
+    std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
+    std::uint64_t dist  = diyfp::sub(M_plus, w      ).f; // (significand of (M+ - w ), implicit exponent is e)
+
+    // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
+    //
+    //      M+ = f * 2^e
+    //         = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
+    //         = ((p1        ) * 2^-e + (p2        )) * 2^e
+    //         = p1 + p2 * 2^e
+
+    const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
+
+    auto p1 = static_cast<std::uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.)
+    std::uint64_t p2 = M_plus.f & (one.f - 1);                    // p2 = f mod 2^-e
+
+    // 1)
+    //
+    // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
+
+    JSON_ASSERT(p1 > 0);
+
+    std::uint32_t pow10;
+    const int k = find_largest_pow10(p1, pow10);
+
+    //      10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
+    //
+    //      p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
+    //         = (d[k-1]         ) * 10^(k-1) + (p1 mod 10^(k-1))
+    //
+    //      M+ = p1                                             + p2 * 2^e
+    //         = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1))          + p2 * 2^e
+    //         = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
+    //         = d[k-1] * 10^(k-1) + (                         rest) * 2^e
+    //
+    // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
+    //
+    //      p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
+    //
+    // but stop as soon as
+    //
+    //      rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
+
+    int n = k;
+    while (n > 0)
+    {
+        // Invariants:
+        //      M+ = buffer * 10^n + (p1 + p2 * 2^e)    (buffer = 0 for n = k)
+        //      pow10 = 10^(n-1) <= p1 < 10^n
+        //
+        const std::uint32_t d = p1 / pow10;  // d = p1 div 10^(n-1)
+        const std::uint32_t r = p1 % pow10;  // r = p1 mod 10^(n-1)
+        //
+        //      M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
+        //         = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
+        //
+        JSON_ASSERT(d <= 9);
+        buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
+        //
+        //      M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
+        //
+        p1 = r;
+        n--;
+        //
+        //      M+ = buffer * 10^n + (p1 + p2 * 2^e)
+        //      pow10 = 10^n
+        //
+
+        // Now check if enough digits have been generated.
+        // Compute
+        //
+        //      p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
+        //
+        // Note:
+        // Since rest and delta share the same exponent e, it suffices to
+        // compare the significands.
+        const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
+        if (rest <= delta)
+        {
+            // V = buffer * 10^n, with M- <= V <= M+.
+
+            decimal_exponent += n;
+
+            // We may now just stop. But instead look if the buffer could be
+            // decremented to bring V closer to w.
+            //
+            // pow10 = 10^n is now 1 ulp in the decimal representation V.
+            // The rounding procedure works with diyfp's with an implicit
+            // exponent of e.
+            //
+            //      10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
+            //
+            const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
+            grisu2_round(buffer, length, dist, delta, rest, ten_n);
+
+            return;
+        }
+
+        pow10 /= 10;
+        //
+        //      pow10 = 10^(n-1) <= p1 < 10^n
+        // Invariants restored.
+    }
+
+    // 2)
+    //
+    // The digits of the integral part have been generated:
+    //
+    //      M+ = d[k-1]...d[1]d[0] + p2 * 2^e
+    //         = buffer            + p2 * 2^e
+    //
+    // Now generate the digits of the fractional part p2 * 2^e.
+    //
+    // Note:
+    // No decimal point is generated: the exponent is adjusted instead.
+    //
+    // p2 actually represents the fraction
+    //
+    //      p2 * 2^e
+    //          = p2 / 2^-e
+    //          = d[-1] / 10^1 + d[-2] / 10^2 + ...
+    //
+    // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
+    //
+    //      p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
+    //                      + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
+    //
+    // using
+    //
+    //      10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
+    //                = (                   d) * 2^-e + (                   r)
+    //
+    // or
+    //      10^m * p2 * 2^e = d + r * 2^e
+    //
+    // i.e.
+    //
+    //      M+ = buffer + p2 * 2^e
+    //         = buffer + 10^-m * (d + r * 2^e)
+    //         = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
+    //
+    // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
+
+    JSON_ASSERT(p2 > delta);
+
+    int m = 0;
+    for (;;)
+    {
+        // Invariant:
+        //      M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
+        //         = buffer * 10^-m + 10^-m * (p2                                 ) * 2^e
+        //         = buffer * 10^-m + 10^-m * (1/10 * (10 * p2)                   ) * 2^e
+        //         = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
+        //
+        JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
+        p2 *= 10;
+        const std::uint64_t d = p2 >> -one.e;     // d = (10 * p2) div 2^-e
+        const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
+        //
+        //      M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
+        //         = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
+        //         = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
+        //
+        JSON_ASSERT(d <= 9);
+        buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
+        //
+        //      M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
+        //
+        p2 = r;
+        m++;
+        //
+        //      M+ = buffer * 10^-m + 10^-m * p2 * 2^e
+        // Invariant restored.
+
+        // Check if enough digits have been generated.
+        //
+        //      10^-m * p2 * 2^e <= delta * 2^e
+        //              p2 * 2^e <= 10^m * delta * 2^e
+        //                    p2 <= 10^m * delta
+        delta *= 10;
+        dist  *= 10;
+        if (p2 <= delta)
+        {
+            break;
+        }
+    }
+
+    // V = buffer * 10^-m, with M- <= V <= M+.
+
+    decimal_exponent -= m;
+
+    // 1 ulp in the decimal representation is now 10^-m.
+    // Since delta and dist are now scaled by 10^m, we need to do the
+    // same with ulp in order to keep the units in sync.
+    //
+    //      10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
+    //
+    const std::uint64_t ten_m = one.f;
+    grisu2_round(buffer, length, dist, delta, p2, ten_m);
+
+    // By construction this algorithm generates the shortest possible decimal
+    // number (Loitsch, Theorem 6.2) which rounds back to w.
+    // For an input number of precision p, at least
+    //
+    //      N = 1 + ceil(p * log_10(2))
+    //
+    // decimal digits are sufficient to identify all binary floating-point
+    // numbers (Matula, "In-and-Out conversions").
+    // This implies that the algorithm does not produce more than N decimal
+    // digits.
+    //
+    //      N = 17 for p = 53 (IEEE double precision)
+    //      N = 9  for p = 24 (IEEE single precision)
+}
+
+/*!
+v = buf * 10^decimal_exponent
+len is the length of the buffer (number of decimal digits)
+The buffer must be large enough, i.e. >= max_digits10.
+*/
+JSON_HEDLEY_NON_NULL(1)
+inline void grisu2(char* buf, int& len, int& decimal_exponent,
+                   diyfp m_minus, diyfp v, diyfp m_plus)
+{
+    JSON_ASSERT(m_plus.e == m_minus.e);
+    JSON_ASSERT(m_plus.e == v.e);
+
+    //  --------(-----------------------+-----------------------)--------    (A)
+    //          m-                      v                       m+
+    //
+    //  --------------------(-----------+-----------------------)--------    (B)
+    //                      m-          v                       m+
+    //
+    // First scale v (and m- and m+) such that the exponent is in the range
+    // [alpha, gamma].
+
+    const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
+
+    const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
+
+    // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
+    const diyfp w       = diyfp::mul(v,       c_minus_k);
+    const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
+    const diyfp w_plus  = diyfp::mul(m_plus,  c_minus_k);
+
+    //  ----(---+---)---------------(---+---)---------------(---+---)----
+    //          w-                      w                       w+
+    //          = c*m-                  = c*v                   = c*m+
+    //
+    // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
+    // w+ are now off by a small amount.
+    // In fact:
+    //
+    //      w - v * 10^k < 1 ulp
+    //
+    // To account for this inaccuracy, add resp. subtract 1 ulp.
+    //
+    //  --------+---[---------------(---+---)---------------]---+--------
+    //          w-  M-                  w                   M+  w+
+    //
+    // Now any number in [M-, M+] (bounds included) will round to w when input,
+    // regardless of how the input rounding algorithm breaks ties.
+    //
+    // And digit_gen generates the shortest possible such number in [M-, M+].
+    // Note that this does not mean that Grisu2 always generates the shortest
+    // possible number in the interval (m-, m+).
+    const diyfp M_minus(w_minus.f + 1, w_minus.e);
+    const diyfp M_plus (w_plus.f  - 1, w_plus.e );
+
+    decimal_exponent = -cached.k; // = -(-k) = k
+
+    grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
+}
+
+/*!
+v = buf * 10^decimal_exponent
+len is the length of the buffer (number of decimal digits)
+The buffer must be large enough, i.e. >= max_digits10.
+*/
+template<typename FloatType>
+JSON_HEDLEY_NON_NULL(1)
+void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
+{
+    static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
+                  "internal error: not enough precision");
+
+    JSON_ASSERT(std::isfinite(value));
+    JSON_ASSERT(value > 0);
+
+    // If the neighbors (and boundaries) of 'value' are always computed for double-precision
+    // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
+    // decimal representations are not exactly "short".
+    //
+    // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
+    // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
+    // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
+    // does.
+    // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
+    // representation using the corresponding std::from_chars function recovers value exactly". That
+    // indicates that single precision floating-point numbers should be recovered using
+    // 'std::strtof'.
+    //
+    // NB: If the neighbors are computed for single-precision numbers, there is a single float
+    //     (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
+    //     value is off by 1 ulp.
+#if 0
+    const boundaries w = compute_boundaries(static_cast<double>(value));
+#else
+    const boundaries w = compute_boundaries(value);
+#endif
+
+    grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
+}
+
+/*!
+@brief appends a decimal representation of e to buf
+@return a pointer to the element following the exponent.
+@pre -1000 < e < 1000
+*/
+JSON_HEDLEY_NON_NULL(1)
+JSON_HEDLEY_RETURNS_NON_NULL
+inline char* append_exponent(char* buf, int e)
+{
+    JSON_ASSERT(e > -1000);
+    JSON_ASSERT(e <  1000);
+
+    if (e < 0)
+    {
+        e = -e;
+        *buf++ = '-';
+    }
+    else
+    {
+        *buf++ = '+';
+    }
+
+    auto k = static_cast<std::uint32_t>(e);
+    if (k < 10)
+    {
+        // Always print at least two digits in the exponent.
+        // This is for compatibility with printf("%g").
+        *buf++ = '0';
+        *buf++ = static_cast<char>('0' + k);
+    }
+    else if (k < 100)
+    {
+        *buf++ = static_cast<char>('0' + k / 10);
+        k %= 10;
+        *buf++ = static_cast<char>('0' + k);
+    }
+    else
+    {
+        *buf++ = static_cast<char>('0' + k / 100);
+        k %= 100;
+        *buf++ = static_cast<char>('0' + k / 10);
+        k %= 10;
+        *buf++ = static_cast<char>('0' + k);
+    }
+
+    return buf;
+}
+
+/*!
+@brief prettify v = buf * 10^decimal_exponent
+
+If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point
+notation. Otherwise it will be printed in exponential notation.
+
+@pre min_exp < 0
+@pre max_exp > 0
+*/
+JSON_HEDLEY_NON_NULL(1)
+JSON_HEDLEY_RETURNS_NON_NULL
+inline char* format_buffer(char* buf, int len, int decimal_exponent,
+                           int min_exp, int max_exp)
+{
+    JSON_ASSERT(min_exp < 0);
+    JSON_ASSERT(max_exp > 0);
+
+    const int k = len;
+    const int n = len + decimal_exponent;
+
+    // v = buf * 10^(n-k)
+    // k is the length of the buffer (number of decimal digits)
+    // n is the position of the decimal point relative to the start of the buffer.
+
+    if (k <= n && n <= max_exp)
+    {
+        // digits[000]
+        // len <= max_exp + 2
+
+        std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
+        // Make it look like a floating-point number (#362, #378)
+        buf[n + 0] = '.';
+        buf[n + 1] = '0';
+        return buf + (static_cast<size_t>(n) + 2);
+    }
+
+    if (0 < n && n <= max_exp)
+    {
+        // dig.its
+        // len <= max_digits10 + 1
+
+        JSON_ASSERT(k > n);
+
+        std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
+        buf[n] = '.';
+        return buf + (static_cast<size_t>(k) + 1U);
+    }
+
+    if (min_exp < n && n <= 0)
+    {
+        // 0.[000]digits
+        // len <= 2 + (-min_exp - 1) + max_digits10
+
+        std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
+        buf[0] = '0';
+        buf[1] = '.';
+        std::memset(buf + 2, '0', static_cast<size_t>(-n));
+        return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
+    }
+
+    if (k == 1)
+    {
+        // dE+123
+        // len <= 1 + 5
+
+        buf += 1;
+    }
+    else
+    {
+        // d.igitsE+123
+        // len <= max_digits10 + 1 + 5
+
+        std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
+        buf[1] = '.';
+        buf += 1 + static_cast<size_t>(k);
+    }
+
+    *buf++ = 'e';
+    return append_exponent(buf, n - 1);
+}
+
+} // namespace dtoa_impl
+
+/*!
+@brief generates a decimal representation of the floating-point number value in [first, last).
+
+The format of the resulting decimal representation is similar to printf's %g
+format. Returns an iterator pointing past-the-end of the decimal representation.
+
+@note The input number must be finite, i.e. NaN's and Inf's are not supported.
+@note The buffer must be large enough.
+@note The result is NOT null-terminated.
+*/
+template<typename FloatType>
+JSON_HEDLEY_NON_NULL(1, 2)
+JSON_HEDLEY_RETURNS_NON_NULL
+char* to_chars(char* first, const char* last, FloatType value)
+{
+    static_cast<void>(last); // maybe unused - fix warning
+    JSON_ASSERT(std::isfinite(value));
+
+    // Use signbit(value) instead of (value < 0) since signbit works for -0.
+    if (std::signbit(value))
+    {
+        value = -value;
+        *first++ = '-';
+    }
+
+    if (value == 0) // +-0
+    {
+        *first++ = '0';
+        // Make it look like a floating-point number (#362, #378)
+        *first++ = '.';
+        *first++ = '0';
+        return first;
+    }
+
+    JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
+
+    // Compute v = buffer * 10^decimal_exponent.
+    // The decimal digits are stored in the buffer, which needs to be interpreted
+    // as an unsigned decimal integer.
+    // len is the length of the buffer, i.e. the number of decimal digits.
+    int len = 0;
+    int decimal_exponent = 0;
+    dtoa_impl::grisu2(first, len, decimal_exponent, value);
+
+    JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
+
+    // Format the buffer like printf("%.*g", prec, value)
+    constexpr int kMinExp = -4;
+    // Use digits10 here to increase compatibility with version 2.
+    constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
+
+    JSON_ASSERT(last - first >= kMaxExp + 2);
+    JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
+    JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
+
+    return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
+}
+
+} // namespace detail
+} // namespace nlohmann
+
+// #include <nlohmann/detail/exceptions.hpp>
+
+// #include <nlohmann/detail/macro_scope.hpp>
+
+// #include <nlohmann/detail/meta/cpp_future.hpp>
+
+// #include <nlohmann/detail/output/binary_writer.hpp>
+
+// #include <nlohmann/detail/output/output_adapters.hpp>
+
+// #include <nlohmann/detail/value_t.hpp>
+
+
+namespace nlohmann
+{
+namespace detail
+{
+///////////////////
+// serialization //
+///////////////////
+
+/// how to treat decoding errors
+enum class error_handler_t
+{
+    strict,  ///< throw a type_error exception in case of invalid UTF-8
+    replace, ///< replace invalid UTF-8 sequences with U+FFFD
+    ignore   ///< ignore invalid UTF-8 sequences
+};
+
+template<typename BasicJsonType>
+class serializer
+{
+    using string_t = typename BasicJsonType::string_t;
+    using number_float_t = typename BasicJsonType::number_float_t;
+    using number_integer_t = typename BasicJsonType::number_integer_t;
+    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+    using binary_char_t = typename BasicJsonType::binary_t::value_type;
+    static constexpr std::uint8_t UTF8_ACCEPT = 0;
+    static constexpr std::uint8_t UTF8_REJECT = 1;
+
+  public:
+    /*!
+    @param[in] s  output stream to serialize to
+    @param[in] ichar  indentation character to use
+    @param[in] error_handler_  how to react on decoding errors
+    */
+    serializer(output_adapter_t<char> s, const char ichar,
+               error_handler_t error_handler_ = error_handler_t::strict)
+        : o(std::move(s))
+        , loc(std::localeconv())
+        , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
+        , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
+        , indent_char(ichar)
+        , indent_string(512, indent_char)
+        , error_handler(error_handler_)
+    {}
+
+    // delete because of pointer members
+    serializer(const serializer&) = delete;
+    serializer& operator=(const serializer&) = delete;
+    serializer(serializer&&) = delete;
+    serializer& operator=(serializer&&) = delete;
+    ~serializer() = default;
+
+    /*!
+    @brief internal implementation of the serialization function
+
+    This function is called by the public member function dump and organizes
+    the serialization internally. The indentation level is propagated as
+    additional parameter. In case of arrays and objects, the function is
+    called recursively.
+
+    - strings and object keys are escaped using `escape_string()`
+    - integer numbers are converted implicitly via `operator<<`
+    - floating-point numbers are converted to a string using `"%g"` format
+    - binary values are serialized as objects containing the subtype and the
+      byte array
+
+    @param[in] val               value to serialize
+    @param[in] pretty_print      whether the output shall be pretty-printed
+    @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
+    in the output are escaped with `\uXXXX` sequences, and the result consists
+    of ASCII characters only.
+    @param[in] indent_step       the indent level
+    @param[in] current_indent    the current indent level (only used internally)
+    */
+    void dump(const BasicJsonType& val,
+              const bool pretty_print,
+              const bool ensure_ascii,
+              const unsigned int indent_step,
+              const unsigned int current_indent = 0)
+    {
+        switch (val.m_type)
+        {
+            case value_t::object:
+            {
+                if (val.m_value.object->empty())
+                {
+                    o->write_characters("{}", 2);
+                    return;
+                }
+
+                if (pretty_print)
+                {
+                    o->write_characters("{\n", 2);
+
+                    // variable to hold indentation for recursive calls
+                    const auto new_indent = current_indent + indent_step;
+                    if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
+                    {
+                        indent_string.resize(indent_string.size() * 2, ' ');
+                    }
+
+                    // first n-1 elements
+                    auto i = val.m_value.object->cbegin();
+                    for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
+                    {
+                        o->write_characters(indent_string.c_str(), new_indent);
+                        o->write_character('\"');
+                        dump_escaped(i->first, ensure_ascii);
+                        o->write_characters("\": ", 3);
+                        dump(i->second, true, ensure_ascii, indent_step, new_indent);
+                        o->write_characters(",\n", 2);
+                    }
+
+                    // last element
+                    JSON_ASSERT(i != val.m_value.object->cend());
+                    JSON_ASSERT(std::next(i) == val.m_value.object->cend());
+                    o->write_characters(indent_string.c_str(), new_indent);
+                    o->write_character('\"');
+                    dump_escaped(i->first, ensure_ascii);
+                    o->write_characters("\": ", 3);
+                    dump(i->second, true, ensure_ascii, indent_step, new_indent);
+
+                    o->write_character('\n');
+                    o->write_characters(indent_string.c_str(), current_indent);
+                    o->write_character('}');
+                }
+                else
+                {
+                    o->write_character('{');
+
+                    // first n-1 elements
+                    auto i = val.m_value.object->cbegin();
+                    for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
+                    {
+                        o->write_character('\"');
+                        dump_escaped(i->first, ensure_ascii);
+                        o->write_characters("\":", 2);
+                        dump(i->second, false, ensure_ascii, indent_step, current_indent);
+                        o->write_character(',');
+                    }
+
+                    // last element
+                    JSON_ASSERT(i != val.m_value.object->cend());
+                    JSON_ASSERT(std::next(i) == val.m_value.object->cend());
+                    o->write_character('\"');
+                    dump_escaped(i->first, ensure_ascii);
+                    o->write_characters("\":", 2);
+                    dump(i->second, false, ensure_ascii, indent_step, current_indent);
+
+                    o->write_character('}');
+                }
+
+                return;
+            }
+
+            case value_t::array:
+            {
+                if (val.m_value.array->empty())
+                {
+                    o->write_characters("[]", 2);
+                    return;
+                }
+
+                if (pretty_print)
+                {
+                    o->write_characters("[\n", 2);
+
+                    // variable to hold indentation for recursive calls
+                    const auto new_indent = current_indent + indent_step;
+                    if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
+                    {
+                        indent_string.resize(indent_string.size() * 2, ' ');
+                    }
+
+                    // first n-1 elements
+                    for (auto i = val.m_value.array->cbegin();
+                            i != val.m_value.array->cend() - 1; ++i)
+                    {
+                        o->write_characters(indent_string.c_str(), new_indent);
+                        dump(*i, true, ensure_ascii, indent_step, new_indent);
+                        o->write_characters(",\n", 2);
+                    }
+
+                    // last element
+                    JSON_ASSERT(!val.m_value.array->empty());
+                    o->write_characters(indent_string.c_str(), new_indent);
+                    dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
+
+                    o->write_character('\n');
+                    o->write_characters(indent_string.c_str(), current_indent);
+                    o->write_character(']');
+                }
+                else
+                {
+                    o->write_character('[');
+
+                    // first n-1 elements
+                    for (auto i = val.m_value.array->cbegin();
+                            i != val.m_value.array->cend() - 1; ++i)
+                    {
+                        dump(*i, false, ensure_ascii, indent_step, current_indent);
+                        o->write_character(',');
+                    }
+
+                    // last element
+                    JSON_ASSERT(!val.m_value.array->empty());
+                    dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
+
+                    o->write_character(']');
+                }
+
+                return;
+            }
+
+            case value_t::string:
+            {
+                o->write_character('\"');
+                dump_escaped(*val.m_value.string, ensure_ascii);
+                o->write_character('\"');
+                return;
+            }
+
+            case value_t::binary:
+            {
+                if (pretty_print)
+                {
+                    o->write_characters("{\n", 2);
+
+                    // variable to hold indentation for recursive calls
+                    const auto new_indent = current_indent + indent_step;
+                    if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
+                    {
+                        indent_string.resize(indent_string.size() * 2, ' ');
+                    }
+
+                    o->write_characters(indent_string.c_str(), new_indent);
+
+                    o->write_characters("\"bytes\": [", 10);
+
+                    if (!val.m_value.binary->empty())
+                    {
+                        for (auto i = val.m_value.binary->cbegin();
+                                i != val.m_value.binary->cend() - 1; ++i)
+                        {
+                            dump_integer(*i);
+                            o->write_characters(", ", 2);
+                        }
+                        dump_integer(val.m_value.binary->back());
+                    }
+
+                    o->write_characters("],\n", 3);
+                    o->write_characters(indent_string.c_str(), new_indent);
+
+                    o->write_characters("\"subtype\": ", 11);
+                    if (val.m_value.binary->has_subtype())
+                    {
+                        dump_integer(val.m_value.binary->subtype());
+                    }
+                    else
+                    {
+                        o->write_characters("null", 4);
+                    }
+                    o->write_character('\n');
+                    o->write_characters(indent_string.c_str(), current_indent);
+                    o->write_character('}');
+                }
+                else
+                {
+                    o->write_characters("{\"bytes\":[", 10);
+
+                    if (!val.m_value.binary->empty())
+                    {
+                        for (auto i = val.m_value.binary->cbegin();
+                                i != val.m_value.binary->cend() - 1; ++i)
+                        {
+                            dump_integer(*i);
+                            o->write_character(',');
+                        }
+                        dump_integer(val.m_value.binary->back());
+                    }
+
+                    o->write_characters("],\"subtype\":", 12);
+                    if (val.m_value.binary->has_subtype())
+                    {
+                        dump_integer(val.m_value.binary->subtype());
+                        o->write_character('}');
+                    }
+                    else
+                    {
+                        o->write_characters("null}", 5);
+                    }
+                }
+                return;
+            }
+
+            case value_t::boolean:
+            {
+                if (val.m_value.boolean)
+                {
+                    o->write_characters("true", 4);
+                }
+                else
+                {
+                    o->write_characters("false", 5);
+                }
+                return;
+            }
+
+            case value_t::number_integer:
+            {
+                dump_integer(val.m_value.number_integer);
+                return;
+            }
+
+            case value_t::number_unsigned:
+            {
+                dump_integer(val.m_value.number_unsigned);
+                return;
+            }
+
+            case value_t::number_float:
+            {
+                dump_float(val.m_value.number_float);
+                return;
+            }
+
+            case value_t::discarded:
+            {
+                o->write_characters("<discarded>", 11);
+                return;
+            }
+
+            case value_t::null:
+            {
+                o->write_characters("null", 4);
+                return;
+            }
+
+            default:            // LCOV_EXCL_LINE
+                JSON_ASSERT(false);  // LCOV_EXCL_LINE
+        }
+    }
+
+  private:
+    /*!
+    @brief dump escaped string
+
+    Escape a string by replacing certain special characters by a sequence of an
+    escape character (backslash) and another character and other control
+    characters by a sequence of "\u" followed by a four-digit hex
+    representation. The escaped string is written to output stream @a o.
+
+    @param[in] s  the string to escape
+    @param[in] ensure_ascii  whether to escape non-ASCII characters with
+                             \uXXXX sequences
+
+    @complexity Linear in the length of string @a s.
+    */
+    void dump_escaped(const string_t& s, const bool ensure_ascii)
+    {
+        std::uint32_t codepoint;
+        std::uint8_t state = UTF8_ACCEPT;
+        std::size_t bytes = 0;  // number of bytes written to string_buffer
+
+        // number of bytes written at the point of the last valid byte
+        std::size_t bytes_after_last_accept = 0;
+        std::size_t undumped_chars = 0;
+
+        for (std::size_t i = 0; i < s.size(); ++i)
+        {
+            const auto byte = static_cast<uint8_t>(s[i]);
+
+            switch (decode(state, codepoint, byte))
+            {
+                case UTF8_ACCEPT:  // decode found a new code point
+                {
+                    switch (codepoint)
+                    {
+                        case 0x08: // backspace
+                        {
+                            string_buffer[bytes++] = '\\';
+                            string_buffer[bytes++] = 'b';
+                            break;
+                        }
+
+                        case 0x09: // horizontal tab
+                        {
+                            string_buffer[bytes++] = '\\';
+                            string_buffer[bytes++] = 't';
+                            break;
+                        }
+
+                        case 0x0A: // newline
+                        {
+                            string_buffer[bytes++] = '\\';
+                            string_buffer[bytes++] = 'n';
+                            break;
+                        }
+
+                        case 0x0C: // formfeed
+                        {
+                            string_buffer[bytes++] = '\\';
+                            string_buffer[bytes++] = 'f';
+                            break;
+                        }
+
+                        case 0x0D: // carriage return
+                        {
+                            string_buffer[bytes++] = '\\';
+                            string_buffer[bytes++] = 'r';
+                            break;
+                        }
+
+                        case 0x22: // quotation mark
+                        {
+                            string_buffer[bytes++] = '\\';
+                            string_buffer[bytes++] = '\"';
+                            break;
+                        }
+
+                        case 0x5C: // reverse solidus
+                        {
+                            string_buffer[bytes++] = '\\';
+                            string_buffer[bytes++] = '\\';
+                            break;
+                        }
+
+                        default:
+                        {
+                            // escape control characters (0x00..0x1F) or, if
+                            // ensure_ascii parameter is used, non-ASCII characters
+                            if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
+                            {
+                                if (codepoint <= 0xFFFF)
+                                {
+                                    (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
+                                                    static_cast<std::uint16_t>(codepoint));
+                                    bytes += 6;
+                                }
+                                else
+                                {
+                                    (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
+                                                    static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
+                                                    static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
+                                    bytes += 12;
+                                }
+                            }
+                            else
+                            {
+                                // copy byte to buffer (all previous bytes
+                                // been copied have in default case above)
+                                string_buffer[bytes++] = s[i];
+                            }
+                            break;
+                        }
+                    }
+
+                    // write buffer and reset index; there must be 13 bytes
+                    // left, as this is the maximal number of bytes to be
+                    // written ("\uxxxx\uxxxx\0") for one code point
+                    if (string_buffer.size() - bytes < 13)
+                    {
+                        o->write_characters(string_buffer.data(), bytes);
+                        bytes = 0;
+                    }
+
+                    // remember the byte position of this accept
+                    bytes_after_last_accept = bytes;
+                    undumped_chars = 0;
+                    break;
+                }
+
+                case UTF8_REJECT:  // decode found invalid UTF-8 byte
+                {
+                    switch (error_handler)
+                    {
+                        case error_handler_t::strict:
+                        {
+                            std::string sn(3, '\0');
+                            (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
+                            JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
+                        }
+
+                        case error_handler_t::ignore:
+                        case error_handler_t::replace:
+                        {
+                            // in case we saw this character the first time, we
+                            // would like to read it again, because the byte
+                            // may be OK for itself, but just not OK for the
+                            // previous sequence
+                            if (undumped_chars > 0)
+                            {
+                                --i;
+                            }
+
+                            // reset length buffer to the last accepted index;
+                            // thus removing/ignoring the invalid characters
+                            bytes = bytes_after_last_accept;
+
+                            if (error_handler == error_handler_t::replace)
+                            {
+                                // add a replacement character
+                                if (ensure_ascii)
+                                {
+                                    string_buffer[bytes++] = '\\';
+                                    string_buffer[bytes++] = 'u';
+                                    string_buffer[bytes++] = 'f';
+                                    string_buffer[bytes++] = 'f';
+                                    string_buffer[bytes++] = 'f';
+                                    string_buffer[bytes++] = 'd';
+                                }
+                                else
+                                {
+                                    string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
+                                    string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
+                                    string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
+                                }
+
+                                // write buffer and reset index; there must be 13 bytes
+                                // left, as this is the maximal number of bytes to be
+                                // written ("\uxxxx\uxxxx\0") for one code point
+                                if (string_buffer.size() - bytes < 13)
+                                {
+                                    o->write_characters(string_buffer.data(), bytes);
+                                    bytes = 0;
+                                }
+
+                                bytes_after_last_accept = bytes;
+                            }
+
+                            undumped_chars = 0;
+
+                            // continue processing the string
+                            state = UTF8_ACCEPT;
+                            break;
+                        }
+
+                        default:            // LCOV_EXCL_LINE
+                            JSON_ASSERT(false);  // LCOV_EXCL_LINE
+                    }
+                    break;
+                }
+
+                default:  // decode found yet incomplete multi-byte code point
+                {
+                    if (!ensure_ascii)
+                    {
+                        // code point will not be escaped - copy byte to buffer
+                        string_buffer[bytes++] = s[i];
+                    }
+                    ++undumped_chars;
+                    break;
+                }
+            }
+        }
+
+        // we finished processing the string
+        if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
+        {
+            // write buffer
+            if (bytes > 0)
+            {
+                o->write_characters(string_buffer.data(), bytes);
+            }
+        }
+        else
+        {
+            // we finish reading, but do not accept: string was incomplete
+            switch (error_handler)
+            {
+                case error_handler_t::strict:
+                {
+                    std::string sn(3, '\0');
+                    (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
+                    JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
+                }
+
+                case error_handler_t::ignore:
+                {
+                    // write all accepted bytes
+                    o->write_characters(string_buffer.data(), bytes_after_last_accept);
+                    break;
+                }
+
+                case error_handler_t::replace:
+                {
+                    // write all accepted bytes
+                    o->write_characters(string_buffer.data(), bytes_after_last_accept);
+                    // add a replacement character
+                    if (ensure_ascii)
+                    {
+                        o->write_characters("\\ufffd", 6);
+                    }
+                    else
+                    {
+                        o->write_characters("\xEF\xBF\xBD", 3);
+                    }
+                    break;
+                }
+
+                default:            // LCOV_EXCL_LINE
+                    JSON_ASSERT(false);  // LCOV_EXCL_LINE
+            }
+        }
+    }
+
+    /*!
+    @brief count digits
+
+    Count the number of decimal (base 10) digits for an input unsigned integer.
+
+    @param[in] x  unsigned integer number to count its digits
+    @return    number of decimal digits
+    */
+    inline unsigned int count_digits(number_unsigned_t x) noexcept
+    {
+        unsigned int n_digits = 1;
+        for (;;)
+        {
+            if (x < 10)
+            {
+                return n_digits;
+            }
+            if (x < 100)
+            {
+                return n_digits + 1;
+            }
+            if (x < 1000)
+            {
+                return n_digits + 2;
+            }
+            if (x < 10000)
+            {
+                return n_digits + 3;
+            }
+            x = x / 10000u;
+            n_digits += 4;
+        }
+    }
+
+    /*!
+    @brief dump an integer
+
+    Dump a given integer to output stream @a o. Works internally with
+    @a number_buffer.
+
+    @param[in] x  integer number (signed or unsigned) to dump
+    @tparam NumberType either @a number_integer_t or @a number_unsigned_t
+    */
+    template < typename NumberType, detail::enable_if_t <
+                   std::is_same<NumberType, number_unsigned_t>::value ||
+                   std::is_same<NumberType, number_integer_t>::value ||
+                   std::is_same<NumberType, binary_char_t>::value,
+                   int > = 0 >
+    void dump_integer(NumberType x)
+    {
+        static constexpr std::array<std::array<char, 2>, 100> digits_to_99
+        {
+            {
+                {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
+                {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
+                {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
+                {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
+                {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
+                {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
+                {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
+                {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
+                {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
+                {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
+            }
+        };
+
+        // special case for "0"
+        if (x == 0)
+        {
+            o->write_character('0');
+            return;
+        }
+
+        // use a pointer to fill the buffer
+        auto buffer_ptr = number_buffer.begin();
+
+        const bool is_negative = std::is_same<NumberType, number_integer_t>::value && !(x >= 0); // see issue #755
+        number_unsigned_t abs_value;
+
+        unsigned int n_chars;
+
+        if (is_negative)
+        {
+            *buffer_ptr = '-';
+            abs_value = remove_sign(static_cast<number_integer_t>(x));
+
+            // account one more byte for the minus sign
+            n_chars = 1 + count_digits(abs_value);
+        }
+        else
+        {
+            abs_value = static_cast<number_unsigned_t>(x);
+            n_chars = count_digits(abs_value);
+        }
+
+        // spare 1 byte for '\0'
+        JSON_ASSERT(n_chars < number_buffer.size() - 1);
+
+        // jump to the end to generate the string from backward
+        // so we later avoid reversing the result
+        buffer_ptr += n_chars;
+
+        // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
+        // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
+        while (abs_value >= 100)
+        {
+            const auto digits_index = static_cast<unsigned>((abs_value % 100));
+            abs_value /= 100;
+            *(--buffer_ptr) = digits_to_99[digits_index][1];
+            *(--buffer_ptr) = digits_to_99[digits_index][0];
+        }
+
+        if (abs_value >= 10)
+        {
+            const auto digits_index = static_cast<unsigned>(abs_value);
+            *(--buffer_ptr) = digits_to_99[digits_index][1];
+            *(--buffer_ptr) = digits_to_99[digits_index][0];
+        }
+        else
+        {
+            *(--buffer_ptr) = static_cast<char>('0' + abs_value);
+        }
+
+        o->write_characters(number_buffer.data(), n_chars);
+    }
+
+    /*!
+    @brief dump a floating-point number
+
+    Dump a given floating-point number to output stream @a o. Works internally
+    with @a number_buffer.
+
+    @param[in] x  floating-point number to dump
+    */
+    void dump_float(number_float_t x)
+    {
+        // NaN / inf
+        if (!std::isfinite(x))
+        {
+            o->write_characters("null", 4);
+            return;
+        }
+
+        // If number_float_t is an IEEE-754 single or double precision number,
+        // use the Grisu2 algorithm to produce short numbers which are
+        // guaranteed to round-trip, using strtof and strtod, resp.
+        //
+        // NB: The test below works if <long double> == <double>.
+        static constexpr bool is_ieee_single_or_double
+            = (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 24 && std::numeric_limits<number_float_t>::max_exponent == 128) ||
+              (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 53 && std::numeric_limits<number_float_t>::max_exponent == 1024);
+
+        dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
+    }
+
+    void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
+    {
+        char* begin = number_buffer.data();
+        char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
+
+        o->write_characters(begin, static_cast<size_t>(end - begin));
+    }
+
+    void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
+    {
+        // get number of digits for a float -> text -> float round-trip
+        static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
+
+        // the actual conversion
+        std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
+
+        // negative value indicates an error
+        JSON_ASSERT(len > 0);
+        // check if buffer was large enough
+        JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
+
+        // erase thousands separator
+        if (thousands_sep != '\0')
+        {
+            const auto end = std::remove(number_buffer.begin(),
+                                         number_buffer.begin() + len, thousands_sep);
+            std::fill(end, number_buffer.end(), '\0');
+            JSON_ASSERT((end - number_buffer.begin()) <= len);
+            len = (end - number_buffer.begin());
+        }
+
+        // convert decimal point to '.'
+        if (decimal_point != '\0' && decimal_point != '.')
+        {
+            const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
+            if (dec_pos != number_buffer.end())
+            {
+                *dec_pos = '.';
+            }
+        }
+
+        o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
+
+        // determine if need to append ".0"
+        const bool value_is_int_like =
+            std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
+                         [](char c)
+        {
+            return c == '.' || c == 'e';
+        });
+
+        if (value_is_int_like)
+        {
+            o->write_characters(".0", 2);
+        }
+    }
+
+    /*!
+    @brief check whether a string is UTF-8 encoded
+
+    The function checks each byte of a string whether it is UTF-8 encoded. The
+    result of the check is stored in the @a state parameter. The function must
+    be called initially with state 0 (accept). State 1 means the string must
+    be rejected, because the current byte is not allowed. If the string is
+    completely processed, but the state is non-zero, the string ended
+    prematurely; that is, the last byte indicated more bytes should have
+    followed.
+
+    @param[in,out] state  the state of the decoding
+    @param[in,out] codep  codepoint (valid only if resulting state is UTF8_ACCEPT)
+    @param[in] byte       next byte to decode
+    @return               new state
+
+    @note The function has been edited: a std::array is used.
+
+    @copyright Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
+    @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
+    */
+    static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
+    {
+        static const std::array<std::uint8_t, 400> utf8d =
+        {
+            {
+                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F
+                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F
+                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F
+                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F
+                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F
+                7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF
+                8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF
+                0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
+                0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
+                0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
+                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
+                1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
+                1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
+                1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8
+            }
+        };
+
+        const std::uint8_t type = utf8d[byte];
+
+        codep = (state != UTF8_ACCEPT)
+                ? (byte & 0x3fu) | (codep << 6u)
+                : (0xFFu >> type) & (byte);
+
+        std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
+        JSON_ASSERT(index < 400);
+        state = utf8d[index];
+        return state;
+    }
+
+    /*
+     * Overload to make the compiler happy while it is instantiating
+     * dump_integer for number_unsigned_t.
+     * Must never be called.
+     */
+    number_unsigned_t remove_sign(number_unsigned_t x)
+    {
+        JSON_ASSERT(false); // LCOV_EXCL_LINE
+        return x; // LCOV_EXCL_LINE
+    }
+
+    /*
+     * Helper function for dump_integer
+     *
+     * This function takes a negative signed integer and returns its absolute
+     * value as unsigned integer. The plus/minus shuffling is necessary as we can
+     * not directly remove the sign of an arbitrary signed integer as the
+     * absolute values of INT_MIN and INT_MAX are usually not the same. See
+     * #1708 for details.
+     */
+    inline number_unsigned_t remove_sign(number_integer_t x) noexcept
+    {
+        JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)());
+        return static_cast<number_unsigned_t>(-(x + 1)) + 1;
+    }
+
+  private:
+    /// the output of the serializer
+    output_adapter_t<char> o = nullptr;
+
+    /// a (hopefully) large enough character buffer
+    std::array<char, 64> number_buffer{{}};
+
+    /// the locale
+    const std::lconv* loc = nullptr;
+    /// the locale's thousand separator character
+    const char thousands_sep = '\0';
+    /// the locale's decimal point character
+    const char decimal_point = '\0';
+
+    /// string buffer
+    std::array<char, 512> string_buffer{{}};
+
+    /// the indentation character
+    const char indent_char;
+    /// the indentation string
+    string_t indent_string;
+
+    /// error_handler how to react on decoding errors
+    const error_handler_t error_handler;
+};
+}  // namespace detail
+}  // namespace nlohmann
+
+// #include <nlohmann/detail/value_t.hpp>
+
+// #include <nlohmann/json_fwd.hpp>
+
+// #include <nlohmann/ordered_map.hpp>
+
+
+#include <functional> // less
+#include <memory> // allocator
+#include <utility> // pair
+#include <vector> // vector
+
+namespace nlohmann
+{
+
+/// ordered_map: a minimal map-like container that preserves insertion order
+/// for use within nlohmann::basic_json<ordered_map>
+template <class Key, class T, class IgnoredLess = std::less<Key>,
+          class Allocator = std::allocator<std::pair<const Key, T>>>
+                  struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
+{
+    using key_type = Key;
+    using mapped_type = T;
+    using Container = std::vector<std::pair<const Key, T>, Allocator>;
+    using typename Container::iterator;
+    using typename Container::const_iterator;
+    using typename Container::size_type;
+    using typename Container::value_type;
+
+    // Explicit constructors instead of `using Container::Container`
+    // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
+    ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}
+    template <class It>
+    ordered_map(It first, It last, const Allocator& alloc = Allocator())
+        : Container{first, last, alloc} {}
+    ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )
+        : Container{init, alloc} {}
+
+    std::pair<iterator, bool> emplace(const key_type& key, T&& t)
+    {
+        for (auto it = this->begin(); it != this->end(); ++it)
+        {
+            if (it->first == key)
+            {
+                return {it, false};
+            }
+        }
+        Container::emplace_back(key, t);
+        return {--this->end(), true};
+    }
+
+    T& operator[](const Key& key)
+    {
+        return emplace(key, T{}).first->second;
+    }
+
+    const T& operator[](const Key& key) const
+    {
+        return at(key);
+    }
+
+    T& at(const Key& key)
+    {
+        for (auto it = this->begin(); it != this->end(); ++it)
+        {
+            if (it->first == key)
+            {
+                return it->second;
+            }
+        }
+
+        throw std::out_of_range("key not found");
+    }
+
+    const T& at(const Key& key) const
+    {
+        for (auto it = this->begin(); it != this->end(); ++it)
+        {
+            if (it->first == key)
+            {
+                return it->second;
+            }
+        }
+
+        throw std::out_of_range("key not found");
+    }
+
+    size_type erase(const Key& key)
+    {
+        for (auto it = this->begin(); it != this->end(); ++it)
+        {
+            if (it->first == key)
+            {
+                // Since we cannot move const Keys, re-construct them in place
+                for (auto next = it; ++next != this->end(); ++it)
+                {
+                    it->~value_type(); // Destroy but keep allocation
+                    new (&*it) value_type{std::move(*next)};
+                }
+                Container::pop_back();
+                return 1;
+            }
+        }
+        return 0;
+    }
+
+    iterator erase(iterator pos)
+    {
+        auto it = pos;
+
+        // Since we cannot move const Keys, re-construct them in place
+        for (auto next = it; ++next != this->end(); ++it)
+        {
+            it->~value_type(); // Destroy but keep allocation
+            new (&*it) value_type{std::move(*next)};
+        }
+        Container::pop_back();
+        return pos;
+    }
+
+    size_type count(const Key& key) const
+    {
+        for (auto it = this->begin(); it != this->end(); ++it)
+        {
+            if (it->first == key)
+            {
+                return 1;
+            }
+        }
+        return 0;
+    }
+
+    iterator find(const Key& key)
+    {
+        for (auto it = this->begin(); it != this->end(); ++it)
+        {
+            if (it->first == key)
+            {
+                return it;
+            }
+        }
+        return Container::end();
+    }
+
+    const_iterator find(const Key& key) const
+    {
+        for (auto it = this->begin(); it != this->end(); ++it)
+        {
+            if (it->first == key)
+            {
+                return it;
+            }
+        }
+        return Container::end();
+    }
+
+    std::pair<iterator, bool> insert( value_type&& value )
+    {
+        return emplace(value.first, std::move(value.second));
+    }
+
+    std::pair<iterator, bool> insert( const value_type& value )
+    {
+        for (auto it = this->begin(); it != this->end(); ++it)
+        {
+            if (it->first == value.first)
+            {
+                return {it, false};
+            }
+        }
+        Container::push_back(value);
+        return {--this->end(), true};
+    }
+};
+
+}  // namespace nlohmann
+
+
+/*!
+@brief namespace for Niels Lohmann
+@see https://github.com/nlohmann
+@since version 1.0.0
+*/
+namespace nlohmann
+{
+
+/*!
+@brief a class to store JSON values
+
+@tparam ObjectType type for JSON objects (`std::map` by default; will be used
+in @ref object_t)
+@tparam ArrayType type for JSON arrays (`std::vector` by default; will be used
+in @ref array_t)
+@tparam StringType type for JSON strings and object keys (`std::string` by
+default; will be used in @ref string_t)
+@tparam BooleanType type for JSON booleans (`bool` by default; will be used
+in @ref boolean_t)
+@tparam NumberIntegerType type for JSON integer numbers (`int64_t` by
+default; will be used in @ref number_integer_t)
+@tparam NumberUnsignedType type for JSON unsigned integer numbers (@c
+`uint64_t` by default; will be used in @ref number_unsigned_t)
+@tparam NumberFloatType type for JSON floating-point numbers (`double` by
+default; will be used in @ref number_float_t)
+@tparam BinaryType type for packed binary data for compatibility with binary
+serialization formats (`std::vector<std::uint8_t>` by default; will be used in
+@ref binary_t)
+@tparam AllocatorType type of the allocator to use (`std::allocator` by
+default)
+@tparam JSONSerializer the serializer to resolve internal calls to `to_json()`
+and `from_json()` (@ref adl_serializer by default)
+
+@requirement The class satisfies the following concept requirements:
+- Basic
+ - [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible):
+   JSON values can be default constructed. The result will be a JSON null
+   value.
+ - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible):
+   A JSON value can be constructed from an rvalue argument.
+ - [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible):
+   A JSON value can be copy-constructed from an lvalue expression.
+ - [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable):
+   A JSON value van be assigned from an rvalue argument.
+ - [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable):
+   A JSON value can be copy-assigned from an lvalue expression.
+ - [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible):
+   JSON values can be destructed.
+- Layout
+ - [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType):
+   JSON values have
+   [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
+   All non-static data members are private and standard layout types, the
+   class has no virtual functions or (virtual) base classes.
+- Library-wide
+ - [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable):
+   JSON values can be compared with `==`, see @ref
+   operator==(const_reference,const_reference).
+ - [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable):
+   JSON values can be compared with `<`, see @ref
+   operator<(const_reference,const_reference).
+ - [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable):
+   Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
+   other compatible types, using unqualified function call @ref swap().
+ - [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer):
+   JSON values can be compared against `std::nullptr_t` objects which are used
+   to model the `null` value.
+- Container
+ - [Container](https://en.cppreference.com/w/cpp/named_req/Container):
+   JSON values can be used like STL containers and provide iterator access.
+ - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer);
+   JSON values can be used like STL containers and provide reverse iterator
+   access.
+
+@invariant The member variables @a m_value and @a m_type have the following
+relationship:
+- If `m_type == value_t::object`, then `m_value.object != nullptr`.
+- If `m_type == value_t::array`, then `m_value.array != nullptr`.
+- If `m_type == value_t::string`, then `m_value.string != nullptr`.
+The invariants are checked by member function assert_invariant().
+
+@internal
+@note ObjectType trick from https://stackoverflow.com/a/9860911
+@endinternal
+
+@see [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange
+Format](http://rfc7159.net/rfc7159)
+
+@since version 1.0.0
+
+@nosubgrouping
+*/
+NLOHMANN_BASIC_JSON_TPL_DECLARATION
+class basic_json
+{
+  private:
+    template<detail::value_t> friend struct detail::external_constructor;
+    friend ::nlohmann::json_pointer<basic_json>;
+
+    template<typename BasicJsonType, typename InputType>
+    friend class ::nlohmann::detail::parser;
+    friend ::nlohmann::detail::serializer<basic_json>;
+    template<typename BasicJsonType>
+    friend class ::nlohmann::detail::iter_impl;
+    template<typename BasicJsonType, typename CharType>
+    friend class ::nlohmann::detail::binary_writer;
+    template<typename BasicJsonType, typename InputType, typename SAX>
+    friend class ::nlohmann::detail::binary_reader;
+    template<typename BasicJsonType>
+    friend class ::nlohmann::detail::json_sax_dom_parser;
+    template<typename BasicJsonType>
+    friend class ::nlohmann::detail::json_sax_dom_callback_parser;
+
+    /// workaround type for MSVC
+    using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
+
+    // convenience aliases for types residing in namespace detail;
+    using lexer = ::nlohmann::detail::lexer_base<basic_json>;
+
+    template<typename InputAdapterType>
+    static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
+        InputAdapterType adapter,
+        detail::parser_callback_t<basic_json>cb = nullptr,
+        const bool allow_exceptions = true,
+        const bool ignore_comments = false
+                                 )
+    {
+        return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
+                std::move(cb), allow_exceptions, ignore_comments);
+    }
+
+    using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
+    template<typename BasicJsonType>
+    using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
+    template<typename BasicJsonType>
+    using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
+    template<typename Iterator>
+    using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
+    template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
+
+    template<typename CharType>
+    using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
+
+    template<typename InputType>
+    using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
+    template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
+
+    using serializer = ::nlohmann::detail::serializer<basic_json>;
+
+  public:
+    using value_t = detail::value_t;
+    /// JSON Pointer, see @ref nlohmann::json_pointer
+    using json_pointer = ::nlohmann::json_pointer<basic_json>;
+    template<typename T, typename SFINAE>
+    using json_serializer = JSONSerializer<T, SFINAE>;
+    /// how to treat decoding errors
+    using error_handler_t = detail::error_handler_t;
+    /// how to treat CBOR tags
+    using cbor_tag_handler_t = detail::cbor_tag_handler_t;
+    /// helper type for initializer lists of basic_json values
+    using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
+
+    using input_format_t = detail::input_format_t;
+    /// SAX interface type, see @ref nlohmann::json_sax
+    using json_sax_t = json_sax<basic_json>;
+
+    ////////////////
+    // exceptions //
+    ////////////////
+
+    /// @name exceptions
+    /// Classes to implement user-defined exceptions.
+    /// @{
+
+    /// @copydoc detail::exception
+    using exception = detail::exception;
+    /// @copydoc detail::parse_error
+    using parse_error = detail::parse_error;
+    /// @copydoc detail::invalid_iterator
+    using invalid_iterator = detail::invalid_iterator;
+    /// @copydoc detail::type_error
+    using type_error = detail::type_error;
+    /// @copydoc detail::out_of_range
+    using out_of_range = detail::out_of_range;
+    /// @copydoc detail::other_error
+    using other_error = detail::other_error;
+
+    /// @}
+
+
+    /////////////////////
+    // container types //
+    /////////////////////
+
+    /// @name container types
+    /// The canonic container types to use @ref basic_json like any other STL
+    /// container.
+    /// @{
+
+    /// the type of elements in a basic_json container
+    using value_type = basic_json;
+
+    /// the type of an element reference
+    using reference = value_type&;
+    /// the type of an element const reference
+    using const_reference = const value_type&;
+
+    /// a type to represent differences between iterators
+    using difference_type = std::ptrdiff_t;
+    /// a type to represent container sizes
+    using size_type = std::size_t;
+
+    /// the allocator type
+    using allocator_type = AllocatorType<basic_json>;
+
+    /// the type of an element pointer
+    using pointer = typename std::allocator_traits<allocator_type>::pointer;
+    /// the type of an element const pointer
+    using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
+
+    /// an iterator for a basic_json container
+    using iterator = iter_impl<basic_json>;
+    /// a const iterator for a basic_json container
+    using const_iterator = iter_impl<const basic_json>;
+    /// a reverse iterator for a basic_json container
+    using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
+    /// a const reverse iterator for a basic_json container
+    using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
+
+    /// @}
+
+
+    /*!
+    @brief returns the allocator associated with the container
+    */
+    static allocator_type get_allocator()
+    {
+        return allocator_type();
+    }
+
+    /*!
+    @brief returns version information on the library
+
+    This function returns a JSON object with information about the library,
+    including the version number and information on the platform and compiler.
+
+    @return JSON object holding version information
+    key         | description
+    ----------- | ---------------
+    `compiler`  | Information on the used compiler. It is an object with the following keys: `c++` (the used C++ standard), `family` (the compiler family; possible values are `clang`, `icc`, `gcc`, `ilecpp`, `msvc`, `pgcpp`, `sunpro`, and `unknown`), and `version` (the compiler version).
+    `copyright` | The copyright line for the library as string.
+    `name`      | The name of the library as string.
+    `platform`  | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.
+    `url`       | The URL of the project as string.
+    `version`   | The version of the library. It is an object with the following keys: `major`, `minor`, and `patch` as defined by [Semantic Versioning](http://semver.org), and `string` (the version string).
+
+    @liveexample{The following code shows an example output of the `meta()`
+    function.,meta}
+
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes to any JSON value.
+
+    @complexity Constant.
+
+    @since 2.1.0
+    */
+    JSON_HEDLEY_WARN_UNUSED_RESULT
+    static basic_json meta()
+    {
+        basic_json result;
+
+        result["copyright"] = "(C) 2013-2020 Niels Lohmann";
+        result["name"] = "JSON for Modern C++";
+        result["url"] = "https://github.com/nlohmann/json";
+        result["version"]["string"] =
+            std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
+            std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
+            std::to_string(NLOHMANN_JSON_VERSION_PATCH);
+        result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
+        result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
+        result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
+
+#ifdef _WIN32
+        result["platform"] = "win32";
+#elif defined __linux__
+        result["platform"] = "linux";
+#elif defined __APPLE__
+        result["platform"] = "apple";
+#elif defined __unix__
+        result["platform"] = "unix";
+#else
+        result["platform"] = "unknown";
+#endif
+
+#if defined(__ICC) || defined(__INTEL_COMPILER)
+        result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
+#elif defined(__clang__)
+        result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
+#elif defined(__GNUC__) || defined(__GNUG__)
+        result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
+#elif defined(__HP_cc) || defined(__HP_aCC)
+        result["compiler"] = "hp"
+#elif defined(__IBMCPP__)
+        result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
+#elif defined(_MSC_VER)
+        result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
+#elif defined(__PGI)
+        result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
+#elif defined(__SUNPRO_CC)
+        result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
+#else
+        result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
+#endif
+
+#ifdef __cplusplus
+        result["compiler"]["c++"] = std::to_string(__cplusplus);
+#else
+        result["compiler"]["c++"] = "unknown";
+#endif
+        return result;
+    }
+
+
+    ///////////////////////////
+    // JSON value data types //
+    ///////////////////////////
+
+    /// @name JSON value data types
+    /// The data types to store a JSON value. These types are derived from
+    /// the template arguments passed to class @ref basic_json.
+    /// @{
+
+#if defined(JSON_HAS_CPP_14)
+    // Use transparent comparator if possible, combined with perfect forwarding
+    // on find() and count() calls prevents unnecessary string construction.
+    using object_comparator_t = std::less<>;
+#else
+    using object_comparator_t = std::less<StringType>;
+#endif
+
+    /*!
+    @brief a type for an object
+
+    [RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows:
+    > An object is an unordered collection of zero or more name/value pairs,
+    > where a name is a string and a value is a string, number, boolean, null,
+    > object, or array.
+
+    To store objects in C++, a type is defined by the template parameters
+    described below.
+
+    @tparam ObjectType  the container to store objects (e.g., `std::map` or
+    `std::unordered_map`)
+    @tparam StringType the type of the keys or names (e.g., `std::string`).
+    The comparison function `std::less<StringType>` is used to order elements
+    inside the container.
+    @tparam AllocatorType the allocator to use for objects (e.g.,
+    `std::allocator`)
+
+    #### Default type
+
+    With the default values for @a ObjectType (`std::map`), @a StringType
+    (`std::string`), and @a AllocatorType (`std::allocator`), the default
+    value for @a object_t is:
+
+    @code {.cpp}
+    std::map<
+      std::string, // key_type
+      basic_json, // value_type
+      std::less<std::string>, // key_compare
+      std::allocator<std::pair<const std::string, basic_json>> // allocator_type
+    >
+    @endcode
+
+    #### Behavior
+
+    The choice of @a object_t influences the behavior of the JSON class. With
+    the default type, objects have the following behavior:
+
+    - When all names are unique, objects will be interoperable in the sense
+      that all software implementations receiving that object will agree on
+      the name-value mappings.
+    - When the names within an object are not unique, it is unspecified which
+      one of the values for a given key will be chosen. For instance,
+      `{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or
+      `{"key": 2}`.
+    - Internally, name/value pairs are stored in lexicographical order of the
+      names. Objects will also be serialized (see @ref dump) in this order.
+      For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
+      and serialized as `{"a": 2, "b": 1}`.
+    - When comparing objects, the order of the name/value pairs is irrelevant.
+      This makes objects interoperable in the sense that they will not be
+      affected by these differences. For instance, `{"b": 1, "a": 2}` and
+      `{"a": 2, "b": 1}` will be treated as equal.
+
+    #### Limits
+
+    [RFC 7159](http://rfc7159.net/rfc7159) specifies:
+    > An implementation may set limits on the maximum depth of nesting.
+
+    In this class, the object's limit of nesting is not explicitly constrained.
+    However, a maximum depth of nesting may be introduced by the compiler or
+    runtime environment. A theoretical limit can be queried by calling the
+    @ref max_size function of a JSON object.
+
+    #### Storage
+
+    Objects are stored as pointers in a @ref basic_json type. That is, for any
+    access to object values, a pointer of type `object_t*` must be
+    dereferenced.
+
+    @sa @ref array_t -- type for an array value
+
+    @since version 1.0.0
+
+    @note The order name/value pairs are added to the object is *not*
+    preserved by the library. Therefore, iterating an object may return
+    name/value pairs in a different order than they were originally stored. In
+    fact, keys will be traversed in alphabetical order as `std::map` with
+    `std::less` is used by default. Please note this behavior conforms to [RFC
+    7159](http://rfc7159.net/rfc7159), because any order implements the
+    specified "unordered" nature of JSON objects.
+    */
+    using object_t = ObjectType<StringType,
+          basic_json,
+          object_comparator_t,
+          AllocatorType<std::pair<const StringType,
+          basic_json>>>;
+
+    /*!
+    @brief a type for an array
+
+    [RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows:
+    > An array is an ordered sequence of zero or more values.
+
+    To store objects in C++, a type is defined by the template parameters
+    explained below.
+
+    @tparam ArrayType  container type to store arrays (e.g., `std::vector` or
+    `std::list`)
+    @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)
+
+    #### Default type
+
+    With the default values for @a ArrayType (`std::vector`) and @a
+    AllocatorType (`std::allocator`), the default value for @a array_t is:
+
+    @code {.cpp}
+    std::vector<
+      basic_json, // value_type
+      std::allocator<basic_json> // allocator_type
+    >
+    @endcode
+
+    #### Limits
+
+    [RFC 7159](http://rfc7159.net/rfc7159) specifies:
+    > An implementation may set limits on the maximum depth of nesting.
+
+    In this class, the array's limit of nesting is not explicitly constrained.
+    However, a maximum depth of nesting may be introduced by the compiler or
+    runtime environment. A theoretical limit can be queried by calling the
+    @ref max_size function of a JSON array.
+
+    #### Storage
+
+    Arrays are stored as pointers in a @ref basic_json type. That is, for any
+    access to array values, a pointer of type `array_t*` must be dereferenced.
+
+    @sa @ref object_t -- type for an object value
+
+    @since version 1.0.0
+    */
+    using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
+
+    /*!
+    @brief a type for a string
+
+    [RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows:
+    > A string is a sequence of zero or more Unicode characters.
+
+    To store objects in C++, a type is defined by the template parameter
+    described below. Unicode values are split by the JSON class into
+    byte-sized characters during deserialization.
+
+    @tparam StringType  the container to store strings (e.g., `std::string`).
+    Note this container is used for keys/names in objects, see @ref object_t.
+
+    #### Default type
+
+    With the default values for @a StringType (`std::string`), the default
+    value for @a string_t is:
+
+    @code {.cpp}
+    std::string
+    @endcode
+
+    #### Encoding
+
+    Strings are stored in UTF-8 encoding. Therefore, functions like
+    `std::string::size()` or `std::string::length()` return the number of
+    bytes in the string rather than the number of characters or glyphs.
+
+    #### String comparison
+
+    [RFC 7159](http://rfc7159.net/rfc7159) states:
+    > Software implementations are typically required to test names of object
+    > members for equality. Implementations that transform the textual
+    > representation into sequences of Unicode code units and then perform the
+    > comparison numerically, code unit by code unit, are interoperable in the
+    > sense that implementations will agree in all cases on equality or
+    > inequality of two strings. For example, implementations that compare
+    > strings with escaped characters unconverted may incorrectly find that
+    > `"a\\b"` and `"a\u005Cb"` are not equal.
+
+    This implementation is interoperable as it does compare strings code unit
+    by code unit.
+
+    #### Storage
+
+    String values are stored as pointers in a @ref basic_json type. That is,
+    for any access to string values, a pointer of type `string_t*` must be
+    dereferenced.
+
+    @since version 1.0.0
+    */
+    using string_t = StringType;
+
+    /*!
+    @brief a type for a boolean
+
+    [RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a
+    type which differentiates the two literals `true` and `false`.
+
+    To store objects in C++, a type is defined by the template parameter @a
+    BooleanType which chooses the type to use.
+
+    #### Default type
+
+    With the default values for @a BooleanType (`bool`), the default value for
+    @a boolean_t is:
+
+    @code {.cpp}
+    bool
+    @endcode
+
+    #### Storage
+
+    Boolean values are stored directly inside a @ref basic_json type.
+
+    @since version 1.0.0
+    */
+    using boolean_t = BooleanType;
+
+    /*!
+    @brief a type for a number (integer)
+
+    [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
+    > The representation of numbers is similar to that used in most
+    > programming languages. A number is represented in base 10 using decimal
+    > digits. It contains an integer component that may be prefixed with an
+    > optional minus sign, which may be followed by a fraction part and/or an
+    > exponent part. Leading zeros are not allowed. (...) Numeric values that
+    > cannot be represented in the grammar below (such as Infinity and NaN)
+    > are not permitted.
+
+    This description includes both integer and floating-point numbers.
+    However, C++ allows more precise storage if it is known whether the number
+    is a signed integer, an unsigned integer or a floating-point number.
+    Therefore, three different types, @ref number_integer_t, @ref
+    number_unsigned_t and @ref number_float_t are used.
+
+    To store integer numbers in C++, a type is defined by the template
+    parameter @a NumberIntegerType which chooses the type to use.
+
+    #### Default type
+
+    With the default values for @a NumberIntegerType (`int64_t`), the default
+    value for @a number_integer_t is:
+
+    @code {.cpp}
+    int64_t
+    @endcode
+
+    #### Default behavior
+
+    - The restrictions about leading zeros is not enforced in C++. Instead,
+      leading zeros in integer literals lead to an interpretation as octal
+      number. Internally, the value will be stored as decimal number. For
+      instance, the C++ integer literal `010` will be serialized to `8`.
+      During deserialization, leading zeros yield an error.
+    - Not-a-number (NaN) values will be serialized to `null`.
+
+    #### Limits
+
+    [RFC 7159](http://rfc7159.net/rfc7159) specifies:
+    > An implementation may set limits on the range and precision of numbers.
+
+    When the default type is used, the maximal integer number that can be
+    stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
+    that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
+    that are out of range will yield over/underflow when used in a
+    constructor. During deserialization, too large or small integer numbers
+    will be automatically be stored as @ref number_unsigned_t or @ref
+    number_float_t.
+
+    [RFC 7159](http://rfc7159.net/rfc7159) further states:
+    > Note that when such software is used, numbers that are integers and are
+    > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
+    > that implementations will agree exactly on their numeric values.
+
+    As this range is a subrange of the exactly supported range [INT64_MIN,
+    INT64_MAX], this class's integer type is interoperable.
+
+    #### Storage
+
+    Integer number values are stored directly inside a @ref basic_json type.
+
+    @sa @ref number_float_t -- type for number values (floating-point)
+
+    @sa @ref number_unsigned_t -- type for number values (unsigned integer)
+
+    @since version 1.0.0
+    */
+    using number_integer_t = NumberIntegerType;
+
+    /*!
+    @brief a type for a number (unsigned)
+
+    [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
+    > The representation of numbers is similar to that used in most
+    > programming languages. A number is represented in base 10 using decimal
+    > digits. It contains an integer component that may be prefixed with an
+    > optional minus sign, which may be followed by a fraction part and/or an
+    > exponent part. Leading zeros are not allowed. (...) Numeric values that
+    > cannot be represented in the grammar below (such as Infinity and NaN)
+    > are not permitted.
+
+    This description includes both integer and floating-point numbers.
+    However, C++ allows more precise storage if it is known whether the number
+    is a signed integer, an unsigned integer or a floating-point number.
+    Therefore, three different types, @ref number_integer_t, @ref
+    number_unsigned_t and @ref number_float_t are used.
+
+    To store unsigned integer numbers in C++, a type is defined by the
+    template parameter @a NumberUnsignedType which chooses the type to use.
+
+    #### Default type
+
+    With the default values for @a NumberUnsignedType (`uint64_t`), the
+    default value for @a number_unsigned_t is:
+
+    @code {.cpp}
+    uint64_t
+    @endcode
+
+    #### Default behavior
+
+    - The restrictions about leading zeros is not enforced in C++. Instead,
+      leading zeros in integer literals lead to an interpretation as octal
+      number. Internally, the value will be stored as decimal number. For
+      instance, the C++ integer literal `010` will be serialized to `8`.
+      During deserialization, leading zeros yield an error.
+    - Not-a-number (NaN) values will be serialized to `null`.
+
+    #### Limits
+
+    [RFC 7159](http://rfc7159.net/rfc7159) specifies:
+    > An implementation may set limits on the range and precision of numbers.
+
+    When the default type is used, the maximal integer number that can be
+    stored is `18446744073709551615` (UINT64_MAX) and the minimal integer
+    number that can be stored is `0`. Integer numbers that are out of range
+    will yield over/underflow when used in a constructor. During
+    deserialization, too large or small integer numbers will be automatically
+    be stored as @ref number_integer_t or @ref number_float_t.
+
+    [RFC 7159](http://rfc7159.net/rfc7159) further states:
+    > Note that when such software is used, numbers that are integers and are
+    > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
+    > that implementations will agree exactly on their numeric values.
+
+    As this range is a subrange (when considered in conjunction with the
+    number_integer_t type) of the exactly supported range [0, UINT64_MAX],
+    this class's integer type is interoperable.
+
+    #### Storage
+
+    Integer number values are stored directly inside a @ref basic_json type.
+
+    @sa @ref number_float_t -- type for number values (floating-point)
+    @sa @ref number_integer_t -- type for number values (integer)
+
+    @since version 2.0.0
+    */
+    using number_unsigned_t = NumberUnsignedType;
+
+    /*!
+    @brief a type for a number (floating-point)
+
+    [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
+    > The representation of numbers is similar to that used in most
+    > programming languages. A number is represented in base 10 using decimal
+    > digits. It contains an integer component that may be prefixed with an
+    > optional minus sign, which may be followed by a fraction part and/or an
+    > exponent part. Leading zeros are not allowed. (...) Numeric values that
+    > cannot be represented in the grammar below (such as Infinity and NaN)
+    > are not permitted.
+
+    This description includes both integer and floating-point numbers.
+    However, C++ allows more precise storage if it is known whether the number
+    is a signed integer, an unsigned integer or a floating-point number.
+    Therefore, three different types, @ref number_integer_t, @ref
+    number_unsigned_t and @ref number_float_t are used.
+
+    To store floating-point numbers in C++, a type is defined by the template
+    parameter @a NumberFloatType which chooses the type to use.
+
+    #### Default type
+
+    With the default values for @a NumberFloatType (`double`), the default
+    value for @a number_float_t is:
+
+    @code {.cpp}
+    double
+    @endcode
+
+    #### Default behavior
+
+    - The restrictions about leading zeros is not enforced in C++. Instead,
+      leading zeros in floating-point literals will be ignored. Internally,
+      the value will be stored as decimal number. For instance, the C++
+      floating-point literal `01.2` will be serialized to `1.2`. During
+      deserialization, leading zeros yield an error.
+    - Not-a-number (NaN) values will be serialized to `null`.
+
+    #### Limits
+
+    [RFC 7159](http://rfc7159.net/rfc7159) states:
+    > This specification allows implementations to set limits on the range and
+    > precision of numbers accepted. Since software that implements IEEE
+    > 754-2008 binary64 (double precision) numbers is generally available and
+    > widely used, good interoperability can be achieved by implementations
+    > that expect no more precision or range than these provide, in the sense
+    > that implementations will approximate JSON numbers within the expected
+    > precision.
+
+    This implementation does exactly follow this approach, as it uses double
+    precision floating-point numbers. Note values smaller than
+    `-1.79769313486232e+308` and values greater than `1.79769313486232e+308`
+    will be stored as NaN internally and be serialized to `null`.
+
+    #### Storage
+
+    Floating-point number values are stored directly inside a @ref basic_json
+    type.
+
+    @sa @ref number_integer_t -- type for number values (integer)
+
+    @sa @ref number_unsigned_t -- type for number values (unsigned integer)
+
+    @since version 1.0.0
+    */
+    using number_float_t = NumberFloatType;
+
+    /*!
+    @brief a type for a packed binary type
+
+    This type is a type designed to carry binary data that appears in various
+    serialized formats, such as CBOR's Major Type 2, MessagePack's bin, and
+    BSON's generic binary subtype. This type is NOT a part of standard JSON and
+    exists solely for compatibility with these binary types. As such, it is
+    simply defined as an ordered sequence of zero or more byte values.
+
+    Additionally, as an implementation detail, the subtype of the binary data is
+    carried around as a `std::uint8_t`, which is compatible with both of the
+    binary data formats that use binary subtyping, (though the specific
+    numbering is incompatible with each other, and it is up to the user to
+    translate between them).
+
+    [CBOR's RFC 7049](https://tools.ietf.org/html/rfc7049) describes this type
+    as:
+    > Major type 2: a byte string. The string's length in bytes is represented
+    > following the rules for positive integers (major type 0).
+
+    [MessagePack's documentation on the bin type
+    family](https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family)
+    describes this type as:
+    > Bin format family stores an byte array in 2, 3, or 5 bytes of extra bytes
+    > in addition to the size of the byte array.
+
+    [BSON's specifications](http://bsonspec.org/spec.html) describe several
+    binary types; however, this type is intended to represent the generic binary
+    type which has the description:
+    > Generic binary subtype - This is the most commonly used binary subtype and
+    > should be the 'default' for drivers and tools.
+
+    None of these impose any limitations on the internal representation other
+    than the basic unit of storage be some type of array whose parts are
+    decomposable into bytes.
+
+    The default representation of this binary format is a
+    `std::vector<std::uint8_t>`, which is a very common way to represent a byte
+    array in modern C++.
+
+    #### Default type
+
+    The default values for @a BinaryType is `std::vector<std::uint8_t>`
+
+    #### Storage
+
+    Binary Arrays are stored as pointers in a @ref basic_json type. That is,
+    for any access to array values, a pointer of the type `binary_t*` must be
+    dereferenced.
+
+    #### Notes on subtypes
+
+    - CBOR
+       - Binary values are represented as byte strings. No subtypes are
+         supported and will be ignored when CBOR is written.
+    - MessagePack
+       - If a subtype is given and the binary array contains exactly 1, 2, 4, 8,
+         or 16 elements, the fixext family (fixext1, fixext2, fixext4, fixext8)
+         is used. For other sizes, the ext family (ext8, ext16, ext32) is used.
+         The subtype is then added as singed 8-bit integer.
+       - If no subtype is given, the bin family (bin8, bin16, bin32) is used.
+    - BSON
+       - If a subtype is given, it is used and added as unsigned 8-bit integer.
+       - If no subtype is given, the generic binary subtype 0x00 is used.
+
+    @sa @ref binary -- create a binary array
+
+    @since version 3.8.0
+    */
+    using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
+    /// @}
+
+  private:
+
+    /// helper for exception-safe object creation
+    template<typename T, typename... Args>
+    JSON_HEDLEY_RETURNS_NON_NULL
+    static T* create(Args&& ... args)
+    {
+        AllocatorType<T> alloc;
+        using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
+
+        auto deleter = [&](T * object)
+        {
+            AllocatorTraits::deallocate(alloc, object, 1);
+        };
+        std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
+        AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
+        JSON_ASSERT(object != nullptr);
+        return object.release();
+    }
+
+    ////////////////////////
+    // JSON value storage //
+    ////////////////////////
+
+    /*!
+    @brief a JSON value
+
+    The actual storage for a JSON value of the @ref basic_json class. This
+    union combines the different storage types for the JSON value types
+    defined in @ref value_t.
+
+    JSON type | value_t type    | used type
+    --------- | --------------- | ------------------------
+    object    | object          | pointer to @ref object_t
+    array     | array           | pointer to @ref array_t
+    string    | string          | pointer to @ref string_t
+    boolean   | boolean         | @ref boolean_t
+    number    | number_integer  | @ref number_integer_t
+    number    | number_unsigned | @ref number_unsigned_t
+    number    | number_float    | @ref number_float_t
+    binary    | binary          | pointer to @ref binary_t
+    null      | null            | *no value is stored*
+
+    @note Variable-length types (objects, arrays, and strings) are stored as
+    pointers. The size of the union should not exceed 64 bits if the default
+    value types are used.
+
+    @since version 1.0.0
+    */
+    union json_value
+    {
+        /// object (stored with pointer to save storage)
+        object_t* object;
+        /// array (stored with pointer to save storage)
+        array_t* array;
+        /// string (stored with pointer to save storage)
+        string_t* string;
+        /// binary (stored with pointer to save storage)
+        binary_t* binary;
+        /// boolean
+        boolean_t boolean;
+        /// number (integer)
+        number_integer_t number_integer;
+        /// number (unsigned integer)
+        number_unsigned_t number_unsigned;
+        /// number (floating-point)
+        number_float_t number_float;
+
+        /// default constructor (for null values)
+        json_value() = default;
+        /// constructor for booleans
+        json_value(boolean_t v) noexcept : boolean(v) {}
+        /// constructor for numbers (integer)
+        json_value(number_integer_t v) noexcept : number_integer(v) {}
+        /// constructor for numbers (unsigned)
+        json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
+        /// constructor for numbers (floating-point)
+        json_value(number_float_t v) noexcept : number_float(v) {}
+        /// constructor for empty values of a given type
+        json_value(value_t t)
+        {
+            switch (t)
+            {
+                case value_t::object:
+                {
+                    object = create<object_t>();
+                    break;
+                }
+
+                case value_t::array:
+                {
+                    array = create<array_t>();
+                    break;
+                }
+
+                case value_t::string:
+                {
+                    string = create<string_t>("");
+                    break;
+                }
+
+                case value_t::binary:
+                {
+                    binary = create<binary_t>();
+                    break;
+                }
+
+                case value_t::boolean:
+                {
+                    boolean = boolean_t(false);
+                    break;
+                }
+
+                case value_t::number_integer:
+                {
+                    number_integer = number_integer_t(0);
+                    break;
+                }
+
+                case value_t::number_unsigned:
+                {
+                    number_unsigned = number_unsigned_t(0);
+                    break;
+                }
+
+                case value_t::number_float:
+                {
+                    number_float = number_float_t(0.0);
+                    break;
+                }
+
+                case value_t::null:
+                {
+                    object = nullptr;  // silence warning, see #821
+                    break;
+                }
+
+                default:
+                {
+                    object = nullptr;  // silence warning, see #821
+                    if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
+                    {
+                        JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.9.1")); // LCOV_EXCL_LINE
+                    }
+                    break;
+                }
+            }
+        }
+
+        /// constructor for strings
+        json_value(const string_t& value)
+        {
+            string = create<string_t>(value);
+        }
+
+        /// constructor for rvalue strings
+        json_value(string_t&& value)
+        {
+            string = create<string_t>(std::move(value));
+        }
+
+        /// constructor for objects
+        json_value(const object_t& value)
+        {
+            object = create<object_t>(value);
+        }
+
+        /// constructor for rvalue objects
+        json_value(object_t&& value)
+        {
+            object = create<object_t>(std::move(value));
+        }
+
+        /// constructor for arrays
+        json_value(const array_t& value)
+        {
+            array = create<array_t>(value);
+        }
+
+        /// constructor for rvalue arrays
+        json_value(array_t&& value)
+        {
+            array = create<array_t>(std::move(value));
+        }
+
+        /// constructor for binary arrays
+        json_value(const typename binary_t::container_type& value)
+        {
+            binary = create<binary_t>(value);
+        }
+
+        /// constructor for rvalue binary arrays
+        json_value(typename binary_t::container_type&& value)
+        {
+            binary = create<binary_t>(std::move(value));
+        }
+
+        /// constructor for binary arrays (internal type)
+        json_value(const binary_t& value)
+        {
+            binary = create<binary_t>(value);
+        }
+
+        /// constructor for rvalue binary arrays (internal type)
+        json_value(binary_t&& value)
+        {
+            binary = create<binary_t>(std::move(value));
+        }
+
+        void destroy(value_t t) noexcept
+        {
+            // flatten the current json_value to a heap-allocated stack
+            std::vector<basic_json> stack;
+
+            // move the top-level items to stack
+            if (t == value_t::array)
+            {
+                stack.reserve(array->size());
+                std::move(array->begin(), array->end(), std::back_inserter(stack));
+            }
+            else if (t == value_t::object)
+            {
+                stack.reserve(object->size());
+                for (auto&& it : *object)
+                {
+                    stack.push_back(std::move(it.second));
+                }
+            }
+
+            while (!stack.empty())
+            {
+                // move the last item to local variable to be processed
+                basic_json current_item(std::move(stack.back()));
+                stack.pop_back();
+
+                // if current_item is array/object, move
+                // its children to the stack to be processed later
+                if (current_item.is_array())
+                {
+                    std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(),
+                              std::back_inserter(stack));
+
+                    current_item.m_value.array->clear();
+                }
+                else if (current_item.is_object())
+                {
+                    for (auto&& it : *current_item.m_value.object)
+                    {
+                        stack.push_back(std::move(it.second));
+                    }
+
+                    current_item.m_value.object->clear();
+                }
+
+                // it's now safe that current_item get destructed
+                // since it doesn't have any children
+            }
+
+            switch (t)
+            {
+                case value_t::object:
+                {
+                    AllocatorType<object_t> alloc;
+                    std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
+                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
+                    break;
+                }
+
+                case value_t::array:
+                {
+                    AllocatorType<array_t> alloc;
+                    std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
+                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
+                    break;
+                }
+
+                case value_t::string:
+                {
+                    AllocatorType<string_t> alloc;
+                    std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
+                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
+                    break;
+                }
+
+                case value_t::binary:
+                {
+                    AllocatorType<binary_t> alloc;
+                    std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
+                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
+                    break;
+                }
+
+                default:
+                {
+                    break;
+                }
+            }
+        }
+    };
+
+    /*!
+    @brief checks the class invariants
+
+    This function asserts the class invariants. It needs to be called at the
+    end of every constructor to make sure that created objects respect the
+    invariant. Furthermore, it has to be called each time the type of a JSON
+    value is changed, because the invariant expresses a relationship between
+    @a m_type and @a m_value.
+    */
+    void assert_invariant() const noexcept
+    {
+        JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
+        JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
+        JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
+        JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
+    }
+
+  public:
+    //////////////////////////
+    // JSON parser callback //
+    //////////////////////////
+
+    /*!
+    @brief parser event types
+
+    The parser callback distinguishes the following events:
+    - `object_start`: the parser read `{` and started to process a JSON object
+    - `key`: the parser read a key of a value in an object
+    - `object_end`: the parser read `}` and finished processing a JSON object
+    - `array_start`: the parser read `[` and started to process a JSON array
+    - `array_end`: the parser read `]` and finished processing a JSON array
+    - `value`: the parser finished reading a JSON value
+
+    @image html callback_events.png "Example when certain parse events are triggered"
+
+    @sa @ref parser_callback_t for more information and examples
+    */
+    using parse_event_t = detail::parse_event_t;
+
+    /*!
+    @brief per-element parser callback type
+
+    With a parser callback function, the result of parsing a JSON text can be
+    influenced. When passed to @ref parse, it is called on certain events
+    (passed as @ref parse_event_t via parameter @a event) with a set recursion
+    depth @a depth and context JSON value @a parsed. The return value of the
+    callback function is a boolean indicating whether the element that emitted
+    the callback shall be kept or not.
+
+    We distinguish six scenarios (determined by the event type) in which the
+    callback function can be called. The following table describes the values
+    of the parameters @a depth, @a event, and @a parsed.
+
+    parameter @a event | description | parameter @a depth | parameter @a parsed
+    ------------------ | ----------- | ------------------ | -------------------
+    parse_event_t::object_start | the parser read `{` and started to process a JSON object | depth of the parent of the JSON object | a JSON value with type discarded
+    parse_event_t::key | the parser read a key of a value in an object | depth of the currently parsed JSON object | a JSON string containing the key
+    parse_event_t::object_end | the parser read `}` and finished processing a JSON object | depth of the parent of the JSON object | the parsed JSON object
+    parse_event_t::array_start | the parser read `[` and started to process a JSON array | depth of the parent of the JSON array | a JSON value with type discarded
+    parse_event_t::array_end | the parser read `]` and finished processing a JSON array | depth of the parent of the JSON array | the parsed JSON array
+    parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
+
+    @image html callback_events.png "Example when certain parse events are triggered"
+
+    Discarding a value (i.e., returning `false`) has different effects
+    depending on the context in which function was called:
+
+    - Discarded values in structured types are skipped. That is, the parser
+      will behave as if the discarded value was never read.
+    - In case a value outside a structured type is skipped, it is replaced
+      with `null`. This case happens if the top-level element is skipped.
+
+    @param[in] depth  the depth of the recursion during parsing
+
+    @param[in] event  an event of type parse_event_t indicating the context in
+    the callback function has been called
+
+    @param[in,out] parsed  the current intermediate parse result; note that
+    writing to this value has no effect for parse_event_t::key events
+
+    @return Whether the JSON value which called the function during parsing
+    should be kept (`true`) or not (`false`). In the latter case, it is either
+    skipped completely or replaced by an empty discarded object.
+
+    @sa @ref parse for examples
+
+    @since version 1.0.0
+    */
+    using parser_callback_t = detail::parser_callback_t<basic_json>;
+
+    //////////////////
+    // constructors //
+    //////////////////
+
+    /// @name constructors and destructors
+    /// Constructors of class @ref basic_json, copy/move constructor, copy
+    /// assignment, static functions creating objects, and the destructor.
+    /// @{
+
+    /*!
+    @brief create an empty value with a given type
+
+    Create an empty JSON value with a given type. The value will be default
+    initialized with an empty value which depends on the type:
+
+    Value type  | initial value
+    ----------- | -------------
+    null        | `null`
+    boolean     | `false`
+    string      | `""`
+    number      | `0`
+    object      | `{}`
+    array       | `[]`
+    binary      | empty array
+
+    @param[in] v  the type of the value to create
+
+    @complexity Constant.
+
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes to any JSON value.
+
+    @liveexample{The following code shows the constructor for different @ref
+    value_t values,basic_json__value_t}
+
+    @sa @ref clear() -- restores the postcondition of this constructor
+
+    @since version 1.0.0
+    */
+    basic_json(const value_t v)
+        : m_type(v), m_value(v)
+    {
+        assert_invariant();
+    }
+
+    /*!
+    @brief create a null object
+
+    Create a `null` JSON value. It either takes a null pointer as parameter
+    (explicitly creating `null`) or no parameter (implicitly creating `null`).
+    The passed null pointer itself is not read -- it is only used to choose
+    the right constructor.
+
+    @complexity Constant.
+
+    @exceptionsafety No-throw guarantee: this constructor never throws
+    exceptions.
+
+    @liveexample{The following code shows the constructor with and without a
+    null pointer parameter.,basic_json__nullptr_t}
+
+    @since version 1.0.0
+    */
+    basic_json(std::nullptr_t = nullptr) noexcept
+        : basic_json(value_t::null)
+    {
+        assert_invariant();
+    }
+
+    /*!
+    @brief create a JSON value
+
+    This is a "catch all" constructor for all compatible JSON types; that is,
+    types for which a `to_json()` method exists. The constructor forwards the
+    parameter @a val to that method (to `json_serializer<U>::to_json` method
+    with `U = uncvref_t<CompatibleType>`, to be exact).
+
+    Template type @a CompatibleType includes, but is not limited to, the
+    following types:
+    - **arrays**: @ref array_t and all kinds of compatible containers such as
+      `std::vector`, `std::deque`, `std::list`, `std::forward_list`,
+      `std::array`, `std::valarray`, `std::set`, `std::unordered_set`,
+      `std::multiset`, and `std::unordered_multiset` with a `value_type` from
+      which a @ref basic_json value can be constructed.
+    - **objects**: @ref object_t and all kinds of compatible associative
+      containers such as `std::map`, `std::unordered_map`, `std::multimap`,
+      and `std::unordered_multimap` with a `key_type` compatible to
+      @ref string_t and a `value_type` from which a @ref basic_json value can
+      be constructed.
+    - **strings**: @ref string_t, string literals, and all compatible string
+      containers can be used.
+    - **numbers**: @ref number_integer_t, @ref number_unsigned_t,
+      @ref number_float_t, and all convertible number types such as `int`,
+      `size_t`, `int64_t`, `float` or `double` can be used.
+    - **boolean**: @ref boolean_t / `bool` can be used.
+    - **binary**: @ref binary_t / `std::vector<uint8_t>` may be used,
+      unfortunately because string literals cannot be distinguished from binary
+      character arrays by the C++ type system, all types compatible with `const
+      char*` will be directed to the string constructor instead.  This is both
+      for backwards compatibility, and due to the fact that a binary type is not
+      a standard JSON type.
+
+    See the examples below.
+
+    @tparam CompatibleType a type such that:
+    - @a CompatibleType is not derived from `std::istream`,
+    - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
+         constructors),
+    - @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments)
+    - @a CompatibleType is not a @ref basic_json nested type (e.g.,
+         @ref json_pointer, @ref iterator, etc ...)
+    - @ref @ref json_serializer<U> has a
+         `to_json(basic_json_t&, CompatibleType&&)` method
+
+    @tparam U = `uncvref_t<CompatibleType>`
+
+    @param[in] val the value to be forwarded to the respective constructor
+
+    @complexity Usually linear in the size of the passed @a val, also
+                depending on the implementation of the called `to_json()`
+                method.
+
+    @exceptionsafety Depends on the called constructor. For types directly
+    supported by the library (i.e., all types for which no `to_json()` function
+    was provided), strong guarantee holds: if an exception is thrown, there are
+    no changes to any JSON value.
+
+    @liveexample{The following code shows the constructor with several
+    compatible types.,basic_json__CompatibleType}
+
+    @since version 2.1.0
+    */
+    template < typename CompatibleType,
+               typename U = detail::uncvref_t<CompatibleType>,
+               detail::enable_if_t <
+                   !detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >
+    basic_json(CompatibleType && val) noexcept(noexcept(
+                JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
+                                           std::forward<CompatibleType>(val))))
+    {
+        JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
+        assert_invariant();
+    }
+
+    /*!
+    @brief create a JSON value from an existing one
+
+    This is a constructor for existing @ref basic_json types.
+    It does not hijack copy/move constructors, since the parameter has different
+    template arguments than the current ones.
+
+    The constructor tries to convert the internal @ref m_value of the parameter.
+
+    @tparam BasicJsonType a type such that:
+    - @a BasicJsonType is a @ref basic_json type.
+    - @a BasicJsonType has different template arguments than @ref basic_json_t.
+
+    @param[in] val the @ref basic_json value to be converted.
+
+    @complexity Usually linear in the size of the passed @a val, also
+                depending on the implementation of the called `to_json()`
+                method.
+
+    @exceptionsafety Depends on the called constructor. For types directly
+    supported by the library (i.e., all types for which no `to_json()` function
+    was provided), strong guarantee holds: if an exception is thrown, there are
+    no changes to any JSON value.
+
+    @since version 3.2.0
+    */
+    template < typename BasicJsonType,
+               detail::enable_if_t <
+                   detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
+    basic_json(const BasicJsonType& val)
+    {
+        using other_boolean_t = typename BasicJsonType::boolean_t;
+        using other_number_float_t = typename BasicJsonType::number_float_t;
+        using other_number_integer_t = typename BasicJsonType::number_integer_t;
+        using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+        using other_string_t = typename BasicJsonType::string_t;
+        using other_object_t = typename BasicJsonType::object_t;
+        using other_array_t = typename BasicJsonType::array_t;
+        using other_binary_t = typename BasicJsonType::binary_t;
+
+        switch (val.type())
+        {
+            case value_t::boolean:
+                JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
+                break;
+            case value_t::number_float:
+                JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
+                break;
+            case value_t::number_integer:
+                JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
+                break;
+            case value_t::number_unsigned:
+                JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
+                break;
+            case value_t::string:
+                JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
+                break;
+            case value_t::object:
+                JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
+                break;
+            case value_t::array:
+                JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
+                break;
+            case value_t::binary:
+                JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
+                break;
+            case value_t::null:
+                *this = nullptr;
+                break;
+            case value_t::discarded:
+                m_type = value_t::discarded;
+                break;
+            default:            // LCOV_EXCL_LINE
+                JSON_ASSERT(false);  // LCOV_EXCL_LINE
+        }
+        assert_invariant();
+    }
+
+    /*!
+    @brief create a container (array or object) from an initializer list
+
+    Creates a JSON value of type array or object from the passed initializer
+    list @a init. In case @a type_deduction is `true` (default), the type of
+    the JSON value to be created is deducted from the initializer list @a init
+    according to the following rules:
+
+    1. If the list is empty, an empty JSON object value `{}` is created.
+    2. If the list consists of pairs whose first element is a string, a JSON
+       object value is created where the first elements of the pairs are
+       treated as keys and the second elements are as values.
+    3. In all other cases, an array is created.
+
+    The rules aim to create the best fit between a C++ initializer list and
+    JSON values. The rationale is as follows:
+
+    1. The empty initializer list is written as `{}` which is exactly an empty
+       JSON object.
+    2. C++ has no way of describing mapped types other than to list a list of
+       pairs. As JSON requires that keys must be of type string, rule 2 is the
+       weakest constraint one can pose on initializer lists to interpret them
+       as an object.
+    3. In all other cases, the initializer list could not be interpreted as
+       JSON object type, so interpreting it as JSON array type is safe.
+
+    With the rules described above, the following JSON values cannot be
+    expressed by an initializer list:
+
+    - the empty array (`[]`): use @ref array(initializer_list_t)
+      with an empty initializer list in this case
+    - arrays whose elements satisfy rule 2: use @ref
+      array(initializer_list_t) with the same initializer list
+      in this case
+
+    @note When used without parentheses around an empty initializer list, @ref
+    basic_json() is called instead of this function, yielding the JSON null
+    value.
+
+    @param[in] init  initializer list with JSON values
+
+    @param[in] type_deduction internal parameter; when set to `true`, the type
+    of the JSON value is deducted from the initializer list @a init; when set
+    to `false`, the type provided via @a manual_type is forced. This mode is
+    used by the functions @ref array(initializer_list_t) and
+    @ref object(initializer_list_t).
+
+    @param[in] manual_type internal parameter; when @a type_deduction is set
+    to `false`, the created JSON value will use the provided type (only @ref
+    value_t::array and @ref value_t::object are valid); when @a type_deduction
+    is set to `true`, this parameter has no effect
+
+    @throw type_error.301 if @a type_deduction is `false`, @a manual_type is
+    `value_t::object`, but @a init contains an element which is not a pair
+    whose first element is a string. In this case, the constructor could not
+    create an object. If @a type_deduction would have be `true`, an array
+    would have been created. See @ref object(initializer_list_t)
+    for an example.
+
+    @complexity Linear in the size of the initializer list @a init.
+
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes to any JSON value.
+
+    @liveexample{The example below shows how JSON values are created from
+    initializer lists.,basic_json__list_init_t}
+
+    @sa @ref array(initializer_list_t) -- create a JSON array
+    value from an initializer list
+    @sa @ref object(initializer_list_t) -- create a JSON object
+    value from an initializer list
+
+    @since version 1.0.0
+    */
+    basic_json(initializer_list_t init,
+               bool type_deduction = true,
+               value_t manual_type = value_t::array)
+    {
+        // check if each element is an array with two elements whose first
+        // element is a string
+        bool is_an_object = std::all_of(init.begin(), init.end(),
+                                        [](const detail::json_ref<basic_json>& element_ref)
+        {
+            return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
+        });
+
+        // adjust type if type deduction is not wanted
+        if (!type_deduction)
+        {
+            // if array is wanted, do not create an object though possible
+            if (manual_type == value_t::array)
+            {
+                is_an_object = false;
+            }
+
+            // if object is wanted but impossible, throw an exception
+            if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
+            {
+                JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
+            }
+        }
+
+        if (is_an_object)
+        {
+            // the initializer list is a list of pairs -> create object
+            m_type = value_t::object;
+            m_value = value_t::object;
+
+            std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
+            {
+                auto element = element_ref.moved_or_copied();
+                m_value.object->emplace(
+                    std::move(*((*element.m_value.array)[0].m_value.string)),
+                    std::move((*element.m_value.array)[1]));
+            });
+        }
+        else
+        {
+            // the initializer list describes an array -> create array
+            m_type = value_t::array;
+            m_value.array = create<array_t>(init.begin(), init.end());
+        }
+
+        assert_invariant();
+    }
+
+    /*!
+    @brief explicitly create a binary array (without subtype)
+
+    Creates a JSON binary array value from a given binary container. Binary
+    values are part of various binary formats, such as CBOR, MessagePack, and
+    BSON. This constructor is used to create a value for serialization to those
+    formats.
+
+    @note Note, this function exists because of the difficulty in correctly
+    specifying the correct template overload in the standard value ctor, as both
+    JSON arrays and JSON binary arrays are backed with some form of a
+    `std::vector`. Because JSON binary arrays are a non-standard extension it
+    was decided that it would be best to prevent automatic initialization of a
+    binary array type, for backwards compatibility and so it does not happen on
+    accident.
+
+    @param[in] init container containing bytes to use as binary type
+
+    @return JSON binary array value
+
+    @complexity Linear in the size of @a init.
+
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes to any JSON value.
+
+    @since version 3.8.0
+    */
+    JSON_HEDLEY_WARN_UNUSED_RESULT
+    static basic_json binary(const typename binary_t::container_type& init)
+    {
+        auto res = basic_json();
+        res.m_type = value_t::binary;
+        res.m_value = init;
+        return res;
+    }
+
+    /*!
+    @brief explicitly create a binary array (with subtype)
+
+    Creates a JSON binary array value from a given binary container. Binary
+    values are part of various binary formats, such as CBOR, MessagePack, and
+    BSON. This constructor is used to create a value for serialization to those
+    formats.
+
+    @note Note, this function exists because of the difficulty in correctly
+    specifying the correct template overload in the standard value ctor, as both
+    JSON arrays and JSON binary arrays are backed with some form of a
+    `std::vector`. Because JSON binary arrays are a non-standard extension it
+    was decided that it would be best to prevent automatic initialization of a
+    binary array type, for backwards compatibility and so it does not happen on
+    accident.
+
+    @param[in] init container containing bytes to use as binary type
+    @param[in] subtype subtype to use in MessagePack and BSON
+
+    @return JSON binary array value
+
+    @complexity Linear in the size of @a init.
+
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes to any JSON value.
+
+    @since version 3.8.0
+    */
+    JSON_HEDLEY_WARN_UNUSED_RESULT
+    static basic_json binary(const typename binary_t::container_type& init, std::uint8_t subtype)
+    {
+        auto res = basic_json();
+        res.m_type = value_t::binary;
+        res.m_value = binary_t(init, subtype);
+        return res;
+    }
+
+    /// @copydoc binary(const typename binary_t::container_type&)
+    JSON_HEDLEY_WARN_UNUSED_RESULT
+    static basic_json binary(typename binary_t::container_type&& init)
+    {
+        auto res = basic_json();
+        res.m_type = value_t::binary;
+        res.m_value = std::move(init);
+        return res;
+    }
+
+    /// @copydoc binary(const typename binary_t::container_type&, std::uint8_t)
+    JSON_HEDLEY_WARN_UNUSED_RESULT
+    static basic_json binary(typename binary_t::container_type&& init, std::uint8_t subtype)
+    {
+        auto res = basic_json();
+        res.m_type = value_t::binary;
+        res.m_value = binary_t(std::move(init), subtype);
+        return res;
+    }
+
+    /*!
+    @brief explicitly create an array from an initializer list
+
+    Creates a JSON array value from a given initializer list. That is, given a
+    list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
+    initializer list is empty, the empty array `[]` is created.
+
+    @note This function is only needed to express two edge cases that cannot
+    be realized with the initializer list constructor (@ref
+    basic_json(initializer_list_t, bool, value_t)). These cases
+    are:
+    1. creating an array whose elements are all pairs whose first element is a
+    string -- in this case, the initializer list constructor would create an
+    object, taking the first elements as keys
+    2. creating an empty array -- passing the empty initializer list to the
+    initializer list constructor yields an empty object
+
+    @param[in] init  initializer list with JSON values to create an array from
+    (optional)
+
+    @return JSON array value
+
+    @complexity Linear in the size of @a init.
+
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes to any JSON value.
+
+    @liveexample{The following code shows an example for the `array`
+    function.,array}
+
+    @sa @ref basic_json(initializer_list_t, bool, value_t) --
+    create a JSON value from an initializer list
+    @sa @ref object(initializer_list_t) -- create a JSON object
+    value from an initializer list
+
+    @since version 1.0.0
+    */
+    JSON_HEDLEY_WARN_UNUSED_RESULT
+    static basic_json array(initializer_list_t init = {})
+    {
+        return basic_json(init, false, value_t::array);
+    }
+
+    /*!
+    @brief explicitly create an object from an initializer list
+
+    Creates a JSON object value from a given initializer list. The initializer
+    lists elements must be pairs, and their first elements must be strings. If
+    the initializer list is empty, the empty object `{}` is created.
+
+    @note This function is only added for symmetry reasons. In contrast to the
+    related function @ref array(initializer_list_t), there are
+    no cases which can only be expressed by this function. That is, any
+    initializer list @a init can also be passed to the initializer list
+    constructor @ref basic_json(initializer_list_t, bool, value_t).
+
+    @param[in] init  initializer list to create an object from (optional)
+
+    @return JSON object value
+
+    @throw type_error.301 if @a init is not a list of pairs whose first
+    elements are strings. In this case, no object can be created. When such a
+    value is passed to @ref basic_json(initializer_list_t, bool, value_t),
+    an array would have been created from the passed initializer list @a init.
+    See example below.
+
+    @complexity Linear in the size of @a init.
+
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes to any JSON value.
+
+    @liveexample{The following code shows an example for the `object`
+    function.,object}
+
+    @sa @ref basic_json(initializer_list_t, bool, value_t) --
+    create a JSON value from an initializer list
+    @sa @ref array(initializer_list_t) -- create a JSON array
+    value from an initializer list
+
+    @since version 1.0.0
+    */
+    JSON_HEDLEY_WARN_UNUSED_RESULT
+    static basic_json object(initializer_list_t init = {})
+    {
+        return basic_json(init, false, value_t::object);
+    }
+
+    /*!
+    @brief construct an array with count copies of given value
+
+    Constructs a JSON array value by creating @a cnt copies of a passed value.
+    In case @a cnt is `0`, an empty array is created.
+
+    @param[in] cnt  the number of JSON copies of @a val to create
+    @param[in] val  the JSON value to copy
+
+    @post `std::distance(begin(),end()) == cnt` holds.
+
+    @complexity Linear in @a cnt.
+
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes to any JSON value.
+
+    @liveexample{The following code shows examples for the @ref
+    basic_json(size_type\, const basic_json&)
+    constructor.,basic_json__size_type_basic_json}
+
+    @since version 1.0.0
+    */
+    basic_json(size_type cnt, const basic_json& val)
+        : m_type(value_t::array)
+    {
+        m_value.array = create<array_t>(cnt, val);
+        assert_invariant();
+    }
+
+    /*!
+    @brief construct a JSON container given an iterator range
+
+    Constructs the JSON value with the contents of the range `[first, last)`.
+    The semantics depends on the different types a JSON value can have:
+    - In case of a null type, invalid_iterator.206 is thrown.
+    - In case of other primitive types (number, boolean, or string), @a first
+      must be `begin()` and @a last must be `end()`. In this case, the value is
+      copied. Otherwise, invalid_iterator.204 is thrown.
+    - In case of structured types (array, object), the constructor behaves as
+      similar versions for `std::vector` or `std::map`; that is, a JSON array
+      or object is constructed from the values in the range.
+
+    @tparam InputIT an input iterator type (@ref iterator or @ref
+    const_iterator)
+
+    @param[in] first begin of the range to copy from (included)
+    @param[in] last end of the range to copy from (excluded)
+
+    @pre Iterators @a first and @a last must be initialized. **This
+         precondition is enforced with an assertion (see warning).** If
+         assertions are switched off, a violation of this precondition yields
+         undefined behavior.
+
+    @pre Range `[first, last)` is valid. Usually, this precondition cannot be
+         checked efficiently. Only certain edge cases are detected; see the
+         description of the exceptions below. A violation of this precondition
+         yields undefined behavior.
+
+    @warning A precondition is enforced with a runtime assertion that will
+             result in calling `std::abort` if this precondition is not met.
+             Assertions can be disabled by defining `NDEBUG` at compile time.
+             See https://en.cppreference.com/w/cpp/error/assert for more
+             information.
+
+    @throw invalid_iterator.201 if iterators @a first and @a last are not
+    compatible (i.e., do not belong to the same JSON value). In this case,
+    the range `[first, last)` is undefined.
+    @throw invalid_iterator.204 if iterators @a first and @a last belong to a
+    primitive type (number, boolean, or string), but @a first does not point
+    to the first element any more. In this case, the range `[first, last)` is
+    undefined. See example code below.
+    @throw invalid_iterator.206 if iterators @a first and @a last belong to a
+    null value. In this case, the range `[first, last)` is undefined.
+
+    @complexity Linear in distance between @a first and @a last.
+
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes to any JSON value.
+
+    @liveexample{The example below shows several ways to create JSON values by
+    specifying a subrange with iterators.,basic_json__InputIt_InputIt}
+
+    @since version 1.0.0
+    */
+    template < class InputIT, typename std::enable_if <
+                   std::is_same<InputIT, typename basic_json_t::iterator>::value ||
+                   std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
+    basic_json(InputIT first, InputIT last)
+    {
+        JSON_ASSERT(first.m_object != nullptr);
+        JSON_ASSERT(last.m_object != nullptr);
+
+        // make sure iterator fits the current value
+        if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
+        {
+            JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
+        }
+
+        // copy type from first iterator
+        m_type = first.m_object->m_type;
+
+        // check if iterator range is complete for primitive values
+        switch (m_type)
+        {
+            case value_t::boolean:
+            case value_t::number_float:
+            case value_t::number_integer:
+            case value_t::number_unsigned:
+            case value_t::string:
+            {
+                if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
+                                         || !last.m_it.primitive_iterator.is_end()))
+                {
+                    JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
+                }
+                break;
+            }
+
+            default:
+                break;
+        }
+
+        switch (m_type)
+        {
+            case value_t::number_integer:
+            {
+                m_value.number_integer = first.m_object->m_value.number_integer;
+                break;
+            }
+
+            case value_t::number_unsigned:
+            {
+                m_value.number_unsigned = first.m_object->m_value.number_unsigned;
+                break;
+            }
+
+            case value_t::number_float:
+            {
+                m_value.number_float = first.m_object->m_value.number_float;
+                break;
+            }
+
+            case value_t::boolean:
+            {
+                m_value.boolean = first.m_object->m_value.boolean;
+                break;
+            }
+
+            case value_t::string:
+            {
+                m_value = *first.m_object->m_value.string;
+                break;
+            }
+
+            case value_t::object:
+            {
+                m_value.object = create<object_t>(first.m_it.object_iterator,
+                                                  last.m_it.object_iterator);
+                break;
+            }
+
+            case value_t::array:
+            {
+                m_value.array = create<array_t>(first.m_it.array_iterator,
+                                                last.m_it.array_iterator);
+                break;
+            }
+
+            case value_t::binary:
+            {
+                m_value = *first.m_object->m_value.binary;
+                break;
+            }
+
+            default:
+                JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
+                                                    std::string(first.m_object->type_name())));
+        }
+
+        assert_invariant();
+    }
+
+
+    ///////////////////////////////////////
+    // other constructors and destructor //
+    ///////////////////////////////////////
+
+    template<typename JsonRef,
+             detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
+                                 std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
+    basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
+
+    /*!
+    @brief copy constructor
+
+    Creates a copy of a given JSON value.
+
+    @param[in] other  the JSON value to copy
+
+    @post `*this == other`
+
+    @complexity Linear in the size of @a other.
+
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes to any JSON value.
+
+    @requirement This function helps `basic_json` satisfying the
+    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
+    requirements:
+    - The complexity is linear.
+    - As postcondition, it holds: `other == basic_json(other)`.
+
+    @liveexample{The following code shows an example for the copy
+    constructor.,basic_json__basic_json}
+
+    @since version 1.0.0
+    */
+    basic_json(const basic_json& other)
+        : m_type(other.m_type)
+    {
+        // check of passed value is valid
+        other.assert_invariant();
+
+        switch (m_type)
+        {
+            case value_t::object:
+            {
+                m_value = *other.m_value.object;
+                break;
+            }
+
+            case value_t::array:
+            {
+                m_value = *other.m_value.array;
+                break;
+            }
+
+            case value_t::string:
+            {
+                m_value = *other.m_value.string;
+                break;
+            }
+
+            case value_t::boolean:
+            {
+                m_value = other.m_value.boolean;
+                break;
+            }
+
+            case value_t::number_integer:
+            {
+                m_value = other.m_value.number_integer;
+                break;
+            }
+
+            case value_t::number_unsigned:
+            {
+                m_value = other.m_value.number_unsigned;
+                break;
+            }
+
+            case value_t::number_float:
+            {
+                m_value = other.m_value.number_float;
+                break;
+            }
+
+            case value_t::binary:
+            {
+                m_value = *other.m_value.binary;
+                break;
+            }
+
+            default:
+                break;
+        }
+
+        assert_invariant();
+    }
+
+    /*!
+    @brief move constructor
+
+    Move constructor. Constructs a JSON value with the contents of the given
+    value @a other using move semantics. It "steals" the resources from @a
+    other and leaves it as JSON null value.
+
+    @param[in,out] other  value to move to this object
+
+    @post `*this` has the same value as @a other before the call.
+    @post @a other is a JSON null value.
+
+    @complexity Constant.
+
+    @exceptionsafety No-throw guarantee: this constructor never throws
+    exceptions.
+
+    @requirement This function helps `basic_json` satisfying the
+    [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible)
+    requirements.
+
+    @liveexample{The code below shows the move constructor explicitly called
+    via std::move.,basic_json__moveconstructor}
+
+    @since version 1.0.0
+    */
+    basic_json(basic_json&& other) noexcept
+        : m_type(std::move(other.m_type)),
+          m_value(std::move(other.m_value))
+    {
+        // check that passed value is valid
+        other.assert_invariant();
+
+        // invalidate payload
+        other.m_type = value_t::null;
+        other.m_value = {};
+
+        assert_invariant();
+    }
+
+    /*!
+    @brief copy assignment
+
+    Copy assignment operator. Copies a JSON value via the "copy and swap"
+    strategy: It is expressed in terms of the copy constructor, destructor,
+    and the `swap()` member function.
+
+    @param[in] other  value to copy from
+
+    @complexity Linear.
+
+    @requirement This function helps `basic_json` satisfying the
+    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
+    requirements:
+    - The complexity is linear.
+
+    @liveexample{The code below shows and example for the copy assignment. It
+    creates a copy of value `a` which is then swapped with `b`. Finally\, the
+    copy of `a` (which is the null value after the swap) is
+    destroyed.,basic_json__copyassignment}
+
+    @since version 1.0.0
+    */
+    basic_json& operator=(basic_json other) noexcept (
+        std::is_nothrow_move_constructible<value_t>::value&&
+        std::is_nothrow_move_assignable<value_t>::value&&
+        std::is_nothrow_move_constructible<json_value>::value&&
+        std::is_nothrow_move_assignable<json_value>::value
+    )
+    {
+        // check that passed value is valid
+        other.assert_invariant();
+
+        using std::swap;
+        swap(m_type, other.m_type);
+        swap(m_value, other.m_value);
+
+        assert_invariant();
+        return *this;
+    }
+
+    /*!
+    @brief destructor
+
+    Destroys the JSON value and frees all allocated memory.
+
+    @complexity Linear.
+
+    @requirement This function helps `basic_json` satisfying the
+    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
+    requirements:
+    - The complexity is linear.
+    - All stored elements are destroyed and all memory is freed.
+
+    @since version 1.0.0
+    */
+    ~basic_json() noexcept
+    {
+        assert_invariant();
+        m_value.destroy(m_type);
+    }
+
+    /// @}
+
+  public:
+    ///////////////////////
+    // object inspection //
+    ///////////////////////
+
+    /// @name object inspection
+    /// Functions to inspect the type of a JSON value.
+    /// @{
+
+    /*!
+    @brief serialization
+
+    Serialization function for JSON values. The function tries to mimic
+    Python's `json.dumps()` function, and currently supports its @a indent
+    and @a ensure_ascii parameters.
+
+    @param[in] indent If indent is nonnegative, then array elements and object
+    members will be pretty-printed with that indent level. An indent level of
+    `0` will only insert newlines. `-1` (the default) selects the most compact
+    representation.
+    @param[in] indent_char The character to use for indentation if @a indent is
+    greater than `0`. The default is ` ` (space).
+    @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
+    in the output are escaped with `\uXXXX` sequences, and the result consists
+    of ASCII characters only.
+    @param[in] error_handler  how to react on decoding errors; there are three
+    possible values: `strict` (throws and exception in case a decoding error
+    occurs; default), `replace` (replace invalid UTF-8 sequences with U+FFFD),
+    and `ignore` (ignore invalid UTF-8 sequences during serialization; all
+    bytes are copied to the output unchanged).
+
+    @return string containing the serialization of the JSON value
+
+    @throw type_error.316 if a string stored inside the JSON value is not
+                          UTF-8 encoded and @a error_handler is set to strict
+
+    @note Binary values are serialized as object containing two keys:
+      - "bytes": an array of bytes as integers
+      - "subtype": the subtype as integer or "null" if the binary has no subtype
+
+    @complexity Linear.
+
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes in the JSON value.
+
+    @liveexample{The following example shows the effect of different @a indent\,
+    @a indent_char\, and @a ensure_ascii parameters to the result of the
+    serialization.,dump}
+
+    @see https://docs.python.org/2/library/json.html#json.dump
+
+    @since version 1.0.0; indentation character @a indent_char, option
+           @a ensure_ascii and exceptions added in version 3.0.0; error
+           handlers added in version 3.4.0; serialization of binary values added
+           in version 3.8.0.
+    */
+    string_t dump(const int indent = -1,
+                  const char indent_char = ' ',
+                  const bool ensure_ascii = false,
+                  const error_handler_t error_handler = error_handler_t::strict) const
+    {
+        string_t result;
+        serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
+
+        if (indent >= 0)
+        {
+            s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
+        }
+        else
+        {
+            s.dump(*this, false, ensure_ascii, 0);
+        }
+
+        return result;
+    }
+
+    /*!
+    @brief return the type of the JSON value (explicit)
+
+    Return the type of the JSON value as a value from the @ref value_t
+    enumeration.
+
+    @return the type of the JSON value
+            Value type                | return value
+            ------------------------- | -------------------------
+            null                      | value_t::null
+            boolean                   | value_t::boolean
+            string                    | value_t::string
+            number (integer)          | value_t::number_integer
+            number (unsigned integer) | value_t::number_unsigned
+            number (floating-point)   | value_t::number_float
+            object                    | value_t::object
+            array                     | value_t::array
+            binary                    | value_t::binary
+            discarded                 | value_t::discarded
+
+    @complexity Constant.
+
+    @exceptionsafety No-throw guarantee: this member function never throws
+    exceptions.
+
+    @liveexample{The following code exemplifies `type()` for all JSON
+    types.,type}
+
+    @sa @ref operator value_t() -- return the type of the JSON value (implicit)
+    @sa @ref type_name() -- return the type as string
+
+    @since version 1.0.0
+    */
+    constexpr value_t type() const noexcept
+    {
+        return m_type;
+    }
+
+    /*!
+    @brief return whether type is primitive
+
+    This function returns true if and only if the JSON type is primitive
+    (string, number, boolean, or null).
+
+    @return `true` if type is primitive (string, number, boolean, or null),
+    `false` otherwise.
+
+    @complexity Constant.
+
+    @exceptionsafety No-throw guarantee: this member function never throws
+    exceptions.
+
+    @liveexample{The following code exemplifies `is_primitive()` for all JSON
+    types.,is_primitive}
+
+    @sa @ref is_structured() -- returns whether JSON value is structured
+    @sa @ref is_null() -- returns whether JSON value is `null`
+    @sa @ref is_string() -- returns whether JSON value is a string
+    @sa @ref is_boolean() -- returns whether JSON value is a boolean
+    @sa @ref is_number() -- returns whether JSON value is a number
+    @sa @ref is_binary() -- returns whether JSON value is a binary array
+
+    @since version 1.0.0
+    */
+    constexpr bool is_primitive() const noexcept
+    {
+        return is_null() || is_string() || is_boolean() || is_number() || is_binary();
+    }
+
+    /*!
+    @brief return whether type is structured
+
+    This function returns true if and only if the JSON type is structured
+    (array or object).
+
+    @return `true` if type is structured (array or object), `false` otherwise.
+
+    @complexity Constant.
+
+    @exceptionsafety No-throw guarantee: this member function never throws
+    exceptions.
+
+    @liveexample{The following code exemplifies `is_structured()` for all JSON
+    types.,is_structured}
+
+    @sa @ref is_primitive() -- returns whether value is primitive
+    @sa @ref is_array() -- returns whether value is an array
+    @sa @ref is_object() -- returns whether value is an object
+
+    @since version 1.0.0
+    */
+    constexpr bool is_structured() const noexcept
+    {
+        return is_array() || is_object();
+    }
+
+    /*!
+    @brief return whether value is null
+
+    This function returns true if and only if the JSON value is null.
+
+    @return `true` if type is null, `false` otherwise.
+
+    @complexity Constant.
+
+    @exceptionsafety No-throw guarantee: this member function never throws
+    exceptions.
+
+    @liveexample{The following code exemplifies `is_null()` for all JSON
+    types.,is_null}
+
+    @since version 1.0.0
+    */
+    constexpr bool is_null() const noexcept
+    {
+        return m_type == value_t::null;
+    }
+
+    /*!
+    @brief return whether value is a boolean
+
+    This function returns true if and only if the JSON value is a boolean.
+
+    @return `true` if type is boolean, `false` otherwise.
+
+    @complexity Constant.
+
+    @exceptionsafety No-throw guarantee: this member function never throws
+    exceptions.
+
+    @liveexample{The following code exemplifies `is_boolean()` for all JSON
+    types.,is_boolean}
+
+    @since version 1.0.0
+    */
+    constexpr bool is_boolean() const noexcept
+    {
+        return m_type == value_t::boolean;
+    }
+
+    /*!
+    @brief return whether value is a number
+
+    This function returns true if and only if the JSON value is a number. This
+    includes both integer (signed and unsigned) and floating-point values.
+
+    @return `true` if type is number (regardless whether integer, unsigned
+    integer or floating-type), `false` otherwise.
+
+    @complexity Constant.
+
+    @exceptionsafety No-throw guarantee: this member function never throws
+    exceptions.
+
+    @liveexample{The following code exemplifies `is_number()` for all JSON
+    types.,is_number}
+
+    @sa @ref is_number_integer() -- check if value is an integer or unsigned
+    integer number
+    @sa @ref is_number_unsigned() -- check if value is an unsigned integer
+    number
+    @sa @ref is_number_float() -- check if value is a floating-point number
+
+    @since version 1.0.0
+    */
+    constexpr bool is_number() const noexcept
+    {
+        return is_number_integer() || is_number_float();
+    }
+
+    /*!
+    @brief return whether value is an integer number
+
+    This function returns true if and only if the JSON value is a signed or
+    unsigned integer number. This excludes floating-point values.
+
+    @return `true` if type is an integer or unsigned integer number, `false`
+    otherwise.
+
+    @complexity Constant.
+
+    @exceptionsafety No-throw guarantee: this member function never throws
+    exceptions.
+
+    @liveexample{The following code exemplifies `is_number_integer()` for all
+    JSON types.,is_number_integer}
+
+    @sa @ref is_number() -- check if value is a number
+    @sa @ref is_number_unsigned() -- check if value is an unsigned integer
+    number
+    @sa @ref is_number_float() -- check if value is a floating-point number
+
+    @since version 1.0.0
+    */
+    constexpr bool is_number_integer() const noexcept
+    {
+        return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
+    }
+
+    /*!
+    @brief return whether value is an unsigned integer number
+
+    This function returns true if and only if the JSON value is an unsigned
+    integer number. This excludes floating-point and signed integer values.
+
+    @return `true` if type is an unsigned integer number, `false` otherwise.
+
+    @complexity Constant.
+
+    @exceptionsafety No-throw guarantee: this member function never throws
+    exceptions.
+
+    @liveexample{The following code exemplifies `is_number_unsigned()` for all
+    JSON types.,is_number_unsigned}
+
+    @sa @ref is_number() -- check if value is a number
+    @sa @ref is_number_integer() -- check if value is an integer or unsigned
+    integer number
+    @sa @ref is_number_float() -- check if value is a floating-point number
+
+    @since version 2.0.0
+    */
+    constexpr bool is_number_unsigned() const noexcept
+    {
+        return m_type == value_t::number_unsigned;
+    }
+
+    /*!
+    @brief return whether value is a floating-point number
+
+    This function returns true if and only if the JSON value is a
+    floating-point number. This excludes signed and unsigned integer values.
+
+    @return `true` if type is a floating-point number, `false` otherwise.
+
+    @complexity Constant.
+
+    @exceptionsafety No-throw guarantee: this member function never throws
+    exceptions.
+
+    @liveexample{The following code exemplifies `is_number_float()` for all
+    JSON types.,is_number_float}
+
+    @sa @ref is_number() -- check if value is number
+    @sa @ref is_number_integer() -- check if value is an integer number
+    @sa @ref is_number_unsigned() -- check if value is an unsigned integer
+    number
+
+    @since version 1.0.0
+    */
+    constexpr bool is_number_float() const noexcept
+    {
+        return m_type == value_t::number_float;
+    }
+
+    /*!
+    @brief return whether value is an object
+
+    This function returns true if and only if the JSON value is an object.
+
+    @return `true` if type is object, `false` otherwise.
+
+    @complexity Constant.
+
+    @exceptionsafety No-throw guarantee: this member function never throws
+    exceptions.
+
+    @liveexample{The following code exemplifies `is_object()` for all JSON
+    types.,is_object}
+
+    @since version 1.0.0
+    */
+    constexpr bool is_object() const noexcept
+    {
+        return m_type == value_t::object;
+    }
+
+    /*!
+    @brief return whether value is an array
+
+    This function returns true if and only if the JSON value is an array.
+
+    @return `true` if type is array, `false` otherwise.
+
+    @complexity Constant.
+
+    @exceptionsafety No-throw guarantee: this member function never throws
+    exceptions.
+
+    @liveexample{The following code exemplifies `is_array()` for all JSON
+    types.,is_array}
+
+    @since version 1.0.0
+    */
+    constexpr bool is_array() const noexcept
+    {
+        return m_type == value_t::array;
+    }
+
+    /*!
+    @brief return whether value is a string
+
+    This function returns true if and only if the JSON value is a string.
+
+    @return `true` if type is string, `false` otherwise.
+
+    @complexity Constant.
+
+    @exceptionsafety No-throw guarantee: this member function never throws
+    exceptions.
+
+    @liveexample{The following code exemplifies `is_string()` for all JSON
+    types.,is_string}
+
+    @since version 1.0.0
+    */
+    constexpr bool is_string() const noexcept
+    {
+        return m_type == value_t::string;
+    }
+
+    /*!
+    @brief return whether value is a binary array
+
+    This function returns true if and only if the JSON value is a binary array.
+
+    @return `true` if type is binary array, `false` otherwise.
+
+    @complexity Constant.
+
+    @exceptionsafety No-throw guarantee: this member function never throws
+    exceptions.
+
+    @liveexample{The following code exemplifies `is_binary()` for all JSON
+    types.,is_binary}
+
+    @since version 3.8.0
+    */
+    constexpr bool is_binary() const noexcept
+    {
+        return m_type == value_t::binary;
+    }
+
+    /*!
+    @brief return whether value is discarded
+
+    This function returns true if and only if the JSON value was discarded
+    during parsing with a callback function (see @ref parser_callback_t).
+
+    @note This function will always be `false` for JSON values after parsing.
+    That is, discarded values can only occur during parsing, but will be
+    removed when inside a structured value or replaced by null in other cases.
+
+    @return `true` if type is discarded, `false` otherwise.
+
+    @complexity Constant.
+
+    @exceptionsafety No-throw guarantee: this member function never throws
+    exceptions.
+
+    @liveexample{The following code exemplifies `is_discarded()` for all JSON
+    types.,is_discarded}
+
+    @since version 1.0.0
+    */
+    constexpr bool is_discarded() const noexcept
+    {
+        return m_type == value_t::discarded;
+    }
+
+    /*!
+    @brief return the type of the JSON value (implicit)
+
+    Implicitly return the type of the JSON value as a value from the @ref
+    value_t enumeration.
+
+    @return the type of the JSON value
+
+    @complexity Constant.
+
+    @exceptionsafety No-throw guarantee: this member function never throws
+    exceptions.
+
+    @liveexample{The following code exemplifies the @ref value_t operator for
+    all JSON types.,operator__value_t}
+
+    @sa @ref type() -- return the type of the JSON value (explicit)
+    @sa @ref type_name() -- return the type as string
+
+    @since version 1.0.0
+    */
+    constexpr operator value_t() const noexcept
+    {
+        return m_type;
+    }
+
+    /// @}
+
+  private:
+    //////////////////
+    // value access //
+    //////////////////
+
+    /// get a boolean (explicit)
+    boolean_t get_impl(boolean_t* /*unused*/) const
+    {
+        if (JSON_HEDLEY_LIKELY(is_boolean()))
+        {
+            return m_value.boolean;
+        }
+
+        JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
+    }
+
+    /// get a pointer to the value (object)
+    object_t* get_impl_ptr(object_t* /*unused*/) noexcept
+    {
+        return is_object() ? m_value.object : nullptr;
+    }
+
+    /// get a pointer to the value (object)
+    constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
+    {
+        return is_object() ? m_value.object : nullptr;
+    }
+
+    /// get a pointer to the value (array)
+    array_t* get_impl_ptr(array_t* /*unused*/) noexcept
+    {
+        return is_array() ? m_value.array : nullptr;
+    }
+
+    /// get a pointer to the value (array)
+    constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
+    {
+        return is_array() ? m_value.array : nullptr;
+    }
+
+    /// get a pointer to the value (string)
+    string_t* get_impl_ptr(string_t* /*unused*/) noexcept
+    {
+        return is_string() ? m_value.string : nullptr;
+    }
+
+    /// get a pointer to the value (string)
+    constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
+    {
+        return is_string() ? m_value.string : nullptr;
+    }
+
+    /// get a pointer to the value (boolean)
+    boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
+    {
+        return is_boolean() ? &m_value.boolean : nullptr;
+    }
+
+    /// get a pointer to the value (boolean)
+    constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
+    {
+        return is_boolean() ? &m_value.boolean : nullptr;
+    }
+
+    /// get a pointer to the value (integer number)
+    number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
+    {
+        return is_number_integer() ? &m_value.number_integer : nullptr;
+    }
+
+    /// get a pointer to the value (integer number)
+    constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
+    {
+        return is_number_integer() ? &m_value.number_integer : nullptr;
+    }
+
+    /// get a pointer to the value (unsigned number)
+    number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
+    {
+        return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
+    }
+
+    /// get a pointer to the value (unsigned number)
+    constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
+    {
+        return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
+    }
+
+    /// get a pointer to the value (floating-point number)
+    number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
+    {
+        return is_number_float() ? &m_value.number_float : nullptr;
+    }
+
+    /// get a pointer to the value (floating-point number)
+    constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
+    {
+        return is_number_float() ? &m_value.number_float : nullptr;
+    }
+
+    /// get a pointer to the value (binary)
+    binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
+    {
+        return is_binary() ? m_value.binary : nullptr;
+    }
+
+    /// get a pointer to the value (binary)
+    constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
+    {
+        return is_binary() ? m_value.binary : nullptr;
+    }
+
+    /*!
+    @brief helper function to implement get_ref()
+
+    This function helps to implement get_ref() without code duplication for
+    const and non-const overloads
+
+    @tparam ThisType will be deduced as `basic_json` or `const basic_json`
+
+    @throw type_error.303 if ReferenceType does not match underlying value
+    type of the current JSON
+    */
+    template<typename ReferenceType, typename ThisType>
+    static ReferenceType get_ref_impl(ThisType& obj)
+    {
+        // delegate the call to get_ptr<>()
+        auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
+
+        if (JSON_HEDLEY_LIKELY(ptr != nullptr))
+        {
+            return *ptr;
+        }
+
+        JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
+    }
+
+  public:
+    /// @name value access
+    /// Direct access to the stored value of a JSON value.
+    /// @{
+
+    /*!
+    @brief get special-case overload
+
+    This overloads avoids a lot of template boilerplate, it can be seen as the
+    identity method
+
+    @tparam BasicJsonType == @ref basic_json
+
+    @return a copy of *this
+
+    @complexity Constant.
+
+    @since version 2.1.0
+    */
+    template<typename BasicJsonType, detail::enable_if_t<
+                 std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
+                 int> = 0>
+    basic_json get() const
+    {
+        return *this;
+    }
+
+    /*!
+    @brief get special-case overload
+
+    This overloads converts the current @ref basic_json in a different
+    @ref basic_json type
+
+    @tparam BasicJsonType == @ref basic_json
+
+    @return a copy of *this, converted into @tparam BasicJsonType
+
+    @complexity Depending on the implementation of the called `from_json()`
+                method.
+
+    @since version 3.2.0
+    */
+    template < typename BasicJsonType, detail::enable_if_t <
+                   !std::is_same<BasicJsonType, basic_json>::value&&
+                   detail::is_basic_json<BasicJsonType>::value, int > = 0 >
+    BasicJsonType get() const
+    {
+        return *this;
+    }
+
+    /*!
+    @brief get a value (explicit)
+
+    Explicit type conversion between the JSON value and a compatible value
+    which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
+    and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
+    The value is converted by calling the @ref json_serializer<ValueType>
+    `from_json()` method.
+
+    The function is equivalent to executing
+    @code {.cpp}
+    ValueType ret;
+    JSONSerializer<ValueType>::from_json(*this, ret);
+    return ret;
+    @endcode
+
+    This overloads is chosen if:
+    - @a ValueType is not @ref basic_json,
+    - @ref json_serializer<ValueType> has a `from_json()` method of the form
+      `void from_json(const basic_json&, ValueType&)`, and
+    - @ref json_serializer<ValueType> does not have a `from_json()` method of
+      the form `ValueType from_json(const basic_json&)`
+
+    @tparam ValueTypeCV the provided value type
+    @tparam ValueType the returned value type
+
+    @return copy of the JSON value, converted to @a ValueType
+
+    @throw what @ref json_serializer<ValueType> `from_json()` method throws
+
+    @liveexample{The example below shows several conversions from JSON values
+    to other types. There a few things to note: (1) Floating-point numbers can
+    be converted to integers\, (2) A JSON array can be converted to a standard
+    `std::vector<short>`\, (3) A JSON object can be converted to C++
+    associative containers such as `std::unordered_map<std::string\,
+    json>`.,get__ValueType_const}
+
+    @since version 2.1.0
+    */
+    template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
+               detail::enable_if_t <
+                   !detail::is_basic_json<ValueType>::value &&
+                   detail::has_from_json<basic_json_t, ValueType>::value &&
+                   !detail::has_non_default_from_json<basic_json_t, ValueType>::value,
+                   int > = 0 >
+    ValueType get() const noexcept(noexcept(
+                                       JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
+    {
+        // we cannot static_assert on ValueTypeCV being non-const, because
+        // there is support for get<const basic_json_t>(), which is why we
+        // still need the uncvref
+        static_assert(!std::is_reference<ValueTypeCV>::value,
+                      "get() cannot be used with reference types, you might want to use get_ref()");
+        static_assert(std::is_default_constructible<ValueType>::value,
+                      "types must be DefaultConstructible when used with get()");
+
+        ValueType ret;
+        JSONSerializer<ValueType>::from_json(*this, ret);
+        return ret;
+    }
+
+    /*!
+    @brief get a value (explicit); special case
+
+    Explicit type conversion between the JSON value and a compatible value
+    which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
+    and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
+    The value is converted by calling the @ref json_serializer<ValueType>
+    `from_json()` method.
+
+    The function is equivalent to executing
+    @code {.cpp}
+    return JSONSerializer<ValueTypeCV>::from_json(*this);
+    @endcode
+
+    This overloads is chosen if:
+    - @a ValueType is not @ref basic_json and
+    - @ref json_serializer<ValueType> has a `from_json()` method of the form
+      `ValueType from_json(const basic_json&)`
+
+    @note If @ref json_serializer<ValueType> has both overloads of
+    `from_json()`, this one is chosen.
+
+    @tparam ValueTypeCV the provided value type
+    @tparam ValueType the returned value type
+
+    @return copy of the JSON value, converted to @a ValueType
+
+    @throw what @ref json_serializer<ValueType> `from_json()` method throws
+
+    @since version 2.1.0
+    */
+    template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
+               detail::enable_if_t < !std::is_same<basic_json_t, ValueType>::value &&
+                                     detail::has_non_default_from_json<basic_json_t, ValueType>::value,
+                                     int > = 0 >
+    ValueType get() const noexcept(noexcept(
+                                       JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
+    {
+        static_assert(!std::is_reference<ValueTypeCV>::value,
+                      "get() cannot be used with reference types, you might want to use get_ref()");
+        return JSONSerializer<ValueType>::from_json(*this);
+    }
+
+    /*!
+    @brief get a value (explicit)
+
+    Explicit type conversion between the JSON value and a compatible value.
+    The value is filled into the input parameter by calling the @ref json_serializer<ValueType>
+    `from_json()` method.
+
+    The function is equivalent to executing
+    @code {.cpp}
+    ValueType v;
+    JSONSerializer<ValueType>::from_json(*this, v);
+    @endcode
+
+    This overloads is chosen if:
+    - @a ValueType is not @ref basic_json,
+    - @ref json_serializer<ValueType> has a `from_json()` method of the form
+      `void from_json(const basic_json&, ValueType&)`, and
+
+    @tparam ValueType the input parameter type.
+
+    @return the input parameter, allowing chaining calls.
+
+    @throw what @ref json_serializer<ValueType> `from_json()` method throws
+
+    @liveexample{The example below shows several conversions from JSON values
+    to other types. There a few things to note: (1) Floating-point numbers can
+    be converted to integers\, (2) A JSON array can be converted to a standard
+    `std::vector<short>`\, (3) A JSON object can be converted to C++
+    associative containers such as `std::unordered_map<std::string\,
+    json>`.,get_to}
+
+    @since version 3.3.0
+    */
+    template < typename ValueType,
+               detail::enable_if_t <
+                   !detail::is_basic_json<ValueType>::value&&
+                   detail::has_from_json<basic_json_t, ValueType>::value,
+                   int > = 0 >
+    ValueType & get_to(ValueType& v) const noexcept(noexcept(
+                JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
+    {
+        JSONSerializer<ValueType>::from_json(*this, v);
+        return v;
+    }
+
+    // specialization to allow to call get_to with a basic_json value
+    // see https://github.com/nlohmann/json/issues/2175
+    template<typename ValueType,
+             detail::enable_if_t <
+                 detail::is_basic_json<ValueType>::value,
+                 int> = 0>
+    ValueType & get_to(ValueType& v) const
+    {
+        v = *this;
+        return v;
+    }
+
+    template <
+        typename T, std::size_t N,
+        typename Array = T (&)[N],
+        detail::enable_if_t <
+            detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
+    Array get_to(T (&v)[N]) const
+    noexcept(noexcept(JSONSerializer<Array>::from_json(
+                          std::declval<const basic_json_t&>(), v)))
+    {
+        JSONSerializer<Array>::from_json(*this, v);
+        return v;
+    }
+
+
+    /*!
+    @brief get a pointer value (implicit)
+
+    Implicit pointer access to the internally stored JSON value. No copies are
+    made.
+
+    @warning Writing data to the pointee of the result yields an undefined
+    state.
+
+    @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
+    object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
+    @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
+    assertion.
+
+    @return pointer to the internally stored JSON value if the requested
+    pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
+
+    @complexity Constant.
+
+    @liveexample{The example below shows how pointers to internal values of a
+    JSON value can be requested. Note that no type conversions are made and a
+    `nullptr` is returned if the value and the requested pointer type does not
+    match.,get_ptr}
+
+    @since version 1.0.0
+    */
+    template<typename PointerType, typename std::enable_if<
+                 std::is_pointer<PointerType>::value, int>::type = 0>
+    auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
+    {
+        // delegate the call to get_impl_ptr<>()
+        return get_impl_ptr(static_cast<PointerType>(nullptr));
+    }
+
+    /*!
+    @brief get a pointer value (implicit)
+    @copydoc get_ptr()
+    */
+    template < typename PointerType, typename std::enable_if <
+                   std::is_pointer<PointerType>::value&&
+                   std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
+    constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
+    {
+        // delegate the call to get_impl_ptr<>() const
+        return get_impl_ptr(static_cast<PointerType>(nullptr));
+    }
+
+    /*!
+    @brief get a pointer value (explicit)
+
+    Explicit pointer access to the internally stored JSON value. No copies are
+    made.
+
+    @warning The pointer becomes invalid if the underlying JSON object
+    changes.
+
+    @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
+    object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
+    @ref number_unsigned_t, or @ref number_float_t.
+
+    @return pointer to the internally stored JSON value if the requested
+    pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
+
+    @complexity Constant.
+
+    @liveexample{The example below shows how pointers to internal values of a
+    JSON value can be requested. Note that no type conversions are made and a
+    `nullptr` is returned if the value and the requested pointer type does not
+    match.,get__PointerType}
+
+    @sa @ref get_ptr() for explicit pointer-member access
+
+    @since version 1.0.0
+    */
+    template<typename PointerType, typename std::enable_if<
+                 std::is_pointer<PointerType>::value, int>::type = 0>
+    auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
+    {
+        // delegate the call to get_ptr
+        return get_ptr<PointerType>();
+    }
+
+    /*!
+    @brief get a pointer value (explicit)
+    @copydoc get()
+    */
+    template<typename PointerType, typename std::enable_if<
+                 std::is_pointer<PointerType>::value, int>::type = 0>
+    constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
+    {
+        // delegate the call to get_ptr
+        return get_ptr<PointerType>();
+    }
+
+    /*!
+    @brief get a reference value (implicit)
+
+    Implicit reference access to the internally stored JSON value. No copies
+    are made.
+
+    @warning Writing data to the referee of the result yields an undefined
+    state.
+
+    @tparam ReferenceType reference type; must be a reference to @ref array_t,
+    @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
+    @ref number_float_t. Enforced by static assertion.
+
+    @return reference to the internally stored JSON value if the requested
+    reference type @a ReferenceType fits to the JSON value; throws
+    type_error.303 otherwise
+
+    @throw type_error.303 in case passed type @a ReferenceType is incompatible
+    with the stored JSON value; see example below
+
+    @complexity Constant.
+
+    @liveexample{The example shows several calls to `get_ref()`.,get_ref}
+
+    @since version 1.1.0
+    */
+    template<typename ReferenceType, typename std::enable_if<
+                 std::is_reference<ReferenceType>::value, int>::type = 0>
+    ReferenceType get_ref()
+    {
+        // delegate call to get_ref_impl
+        return get_ref_impl<ReferenceType>(*this);
+    }
+
+    /*!
+    @brief get a reference value (implicit)
+    @copydoc get_ref()
+    */
+    template < typename ReferenceType, typename std::enable_if <
+                   std::is_reference<ReferenceType>::value&&
+                   std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
+    ReferenceType get_ref() const
+    {
+        // delegate call to get_ref_impl
+        return get_ref_impl<ReferenceType>(*this);
+    }
+
+    /*!
+    @brief get a value (implicit)
+
+    Implicit type conversion between the JSON value and a compatible value.
+    The call is realized by calling @ref get() const.
+
+    @tparam ValueType non-pointer type compatible to the JSON value, for
+    instance `int` for JSON integer numbers, `bool` for JSON booleans, or
+    `std::vector` types for JSON arrays. The character type of @ref string_t
+    as well as an initializer list of this type is excluded to avoid
+    ambiguities as these types implicitly convert to `std::string`.
+
+    @return copy of the JSON value, converted to type @a ValueType
+
+    @throw type_error.302 in case passed type @a ValueType is incompatible
+    to the JSON value type (e.g., the JSON value is of type boolean, but a
+    string is requested); see example below
+
+    @complexity Linear in the size of the JSON value.
+
+    @liveexample{The example below shows several conversions from JSON values
+    to other types. There a few things to note: (1) Floating-point numbers can
+    be converted to integers\, (2) A JSON array can be converted to a standard
+    `std::vector<short>`\, (3) A JSON object can be converted to C++
+    associative containers such as `std::unordered_map<std::string\,
+    json>`.,operator__ValueType}
+
+    @since version 1.0.0
+    */
+    template < typename ValueType, typename std::enable_if <
+                   !std::is_pointer<ValueType>::value&&
+                   !std::is_same<ValueType, detail::json_ref<basic_json>>::value&&
+                   !std::is_same<ValueType, typename string_t::value_type>::value&&
+                   !detail::is_basic_json<ValueType>::value
+                   && !std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
+#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
+                   && !std::is_same<ValueType, typename std::string_view>::value
+#endif
+                   && detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
+                   , int >::type = 0 >
+    JSON_EXPLICIT operator ValueType() const
+    {
+        // delegate the call to get<>() const
+        return get<ValueType>();
+    }
+
+    /*!
+    @return reference to the binary value
+
+    @throw type_error.302 if the value is not binary
+
+    @sa @ref is_binary() to check if the value is binary
+
+    @since version 3.8.0
+    */
+    binary_t& get_binary()
+    {
+        if (!is_binary())
+        {
+            JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
+        }
+
+        return *get_ptr<binary_t*>();
+    }
+
+    /// @copydoc get_binary()
+    const binary_t& get_binary() const
+    {
+        if (!is_binary())
+        {
+            JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
+        }
+
+        return *get_ptr<const binary_t*>();
+    }
+
+    /// @}
+
+
+    ////////////////////
+    // element access //
+    ////////////////////
+
+    /// @name element access
+    /// Access to the JSON value.
+    /// @{
+
+    /*!
+    @brief access specified array element with bounds checking
+
+    Returns a reference to the element at specified location @a idx, with
+    bounds checking.
+
+    @param[in] idx  index of the element to access
+
+    @return reference to the element at index @a idx
+
+    @throw type_error.304 if the JSON value is not an array; in this case,
+    calling `at` with an index makes no sense. See example below.
+    @throw out_of_range.401 if the index @a idx is out of range of the array;
+    that is, `idx >= size()`. See example below.
+
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes in the JSON value.
+
+    @complexity Constant.
+
+    @since version 1.0.0
+
+    @liveexample{The example below shows how array elements can be read and
+    written using `at()`. It also demonstrates the different exceptions that
+    can be thrown.,at__size_type}
+    */
+    reference at(size_type idx)
+    {
+        // at only works for arrays
+        if (JSON_HEDLEY_LIKELY(is_array()))
+        {
+            JSON_TRY
+            {
+                return m_value.array->at(idx);
+            }
+            JSON_CATCH (std::out_of_range&)
+            {
+                // create better exception explanation
+                JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
+            }
+        }
+        else
+        {
+            JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
+        }
+    }
+
+    /*!
+    @brief access specified array element with bounds checking
+
+    Returns a const reference to the element at specified location @a idx,
+    with bounds checking.
+
+    @param[in] idx  index of the element to access
+
+    @return const reference to the element at index @a idx
+
+    @throw type_error.304 if the JSON value is not an array; in this case,
+    calling `at` with an index makes no sense. See example below.
+    @throw out_of_range.401 if the index @a idx is out of range of the array;
+    that is, `idx >= size()`. See example below.
+
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes in the JSON value.
+
+    @complexity Constant.
+
+    @since version 1.0.0
+
+    @liveexample{The example below shows how array elements can be read using
+    `at()`. It also demonstrates the different exceptions that can be thrown.,
+    at__size_type_const}
+    */
+    const_reference at(size_type idx) const
+    {
+        // at only works for arrays
+        if (JSON_HEDLEY_LIKELY(is_array()))
+        {
+            JSON_TRY
+            {
+                return m_value.array->at(idx);
+            }
+            JSON_CATCH (std::out_of_range&)
+            {
+                // create better exception explanation
+                JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
+            }
+        }
+        else
+        {
+            JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
+        }
+    }
+
+    /*!
+    @brief access specified object element with bounds checking
+
+    Returns a reference to the element at with specified key @a key, with
+    bounds checking.
+
+    @param[in] key  key of the element to access
+
+    @return reference to the element at key @a key
+
+    @throw type_error.304 if the JSON value is not an object; in this case,
+    calling `at` with a key makes no sense. See example below.
+    @throw out_of_range.403 if the key @a key is is not stored in the object;
+    that is, `find(key) == end()`. See example below.
+
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes in the JSON value.
+
+    @complexity Logarithmic in the size of the container.
+
+    @sa @ref operator[](const typename object_t::key_type&) for unchecked
+    access by reference
+    @sa @ref value() for access by value with a default value
+
+    @since version 1.0.0
+
+    @liveexample{The example below shows how object elements can be read and
+    written using `at()`. It also demonstrates the different exceptions that
+    can be thrown.,at__object_t_key_type}
+    */
+    reference at(const typename object_t::key_type& key)
+    {
+        // at only works for objects
+        if (JSON_HEDLEY_LIKELY(is_object()))
+        {
+            JSON_TRY
+            {
+                return m_value.object->at(key);
+            }
+            JSON_CATCH (std::out_of_range&)
+            {
+                // create better exception explanation
+                JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
+            }
+        }
+        else
+        {
+            JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
+        }
+    }
+
+    /*!
+    @brief access specified object element with bounds checking
+
+    Returns a const reference to the element at with specified key @a key,
+    with bounds checking.
+
+    @param[in] key  key of the element to access
+
+    @return const reference to the element at key @a key
+
+    @throw type_error.304 if the JSON value is not an object; in this case,
+    calling `at` with a key makes no sense. See example below.
+    @throw out_of_range.403 if the key @a key is is not stored in the object;
+    that is, `find(key) == end()`. See example below.
+
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes in the JSON value.
+
+    @complexity Logarithmic in the size of the container.
+
+    @sa @ref operator[](const typename object_t::key_type&) for unchecked
+    access by reference
+    @sa @ref value() for access by value with a default value
+
+    @since version 1.0.0
+
+    @liveexample{The example below shows how object elements can be read using
+    `at()`. It also demonstrates the different exceptions that can be thrown.,
+    at__object_t_key_type_const}
+    */
+    const_reference at(const typename object_t::key_type& key) const
+    {
+        // at only works for objects
+        if (JSON_HEDLEY_LIKELY(is_object()))
+        {
+            JSON_TRY
+            {
+                return m_value.object->at(key);
+            }
+            JSON_CATCH (std::out_of_range&)
+            {
+                // create better exception explanation
+                JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
+            }
+        }
+        else
+        {
+            JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
+        }
+    }
+
+    /*!
+    @brief access specified array element
+
+    Returns a reference to the element at specified location @a idx.
+
+    @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
+    then the array is silently filled up with `null` values to make `idx` a
+    valid reference to the last stored element.
+
+    @param[in] idx  index of the element to access
+
+    @return reference to the element at index @a idx
+
+    @throw type_error.305 if the JSON value is not an array or null; in that
+    cases, using the [] operator with an index makes no sense.
+
+    @complexity Constant if @a idx is in the range of the array. Otherwise
+    linear in `idx - size()`.
+
+    @liveexample{The example below shows how array elements can be read and
+    written using `[]` operator. Note the addition of `null`
+    values.,operatorarray__size_type}
+
+    @since version 1.0.0
+    */
+    reference operator[](size_type idx)
+    {
+        // implicitly convert null value to an empty array
+        if (is_null())
+        {
+            m_type = value_t::array;
+            m_value.array = create<array_t>();
+            assert_invariant();
+        }
+
+        // operator[] only works for arrays
+        if (JSON_HEDLEY_LIKELY(is_array()))
+        {
+            // fill up array with null values if given idx is outside range
+            if (idx >= m_value.array->size())
+            {
+                m_value.array->insert(m_value.array->end(),
+                                      idx - m_value.array->size() + 1,
+                                      basic_json());
+            }
+
+            return m_value.array->operator[](idx);
+        }
+
+        JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
+    }
+
+    /*!
+    @brief access specified array element
+
+    Returns a const reference to the element at specified location @a idx.
+
+    @param[in] idx  index of the element to access
+
+    @return const reference to the element at index @a idx
+
+    @throw type_error.305 if the JSON value is not an array; in that case,
+    using the [] operator with an index makes no sense.
+
+    @complexity Constant.
+
+    @liveexample{The example below shows how array elements can be read using
+    the `[]` operator.,operatorarray__size_type_const}
+
+    @since version 1.0.0
+    */
+    const_reference operator[](size_type idx) const
+    {
+        // const operator[] only works for arrays
+        if (JSON_HEDLEY_LIKELY(is_array()))
+        {
+            return m_value.array->operator[](idx);
+        }
+
+        JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
+    }
+
+    /*!
+    @brief access specified object element
+
+    Returns a reference to the element at with specified key @a key.
+
+    @note If @a key is not found in the object, then it is silently added to
+    the object and filled with a `null` value to make `key` a valid reference.
+    In case the value was `null` before, it is converted to an object.
+
+    @param[in] key  key of the element to access
+
+    @return reference to the element at key @a key
+
+    @throw type_error.305 if the JSON value is not an object or null; in that
+    cases, using the [] operator with a key makes no sense.
+
+    @complexity Logarithmic in the size of the container.
+
+    @liveexample{The example below shows how object elements can be read and
+    written using the `[]` operator.,operatorarray__key_type}
+
+    @sa @ref at(const typename object_t::key_type&) for access by reference
+    with range checking
+    @sa @ref value() for access by value with a default value
+
+    @since version 1.0.0
+    */
+    reference operator[](const typename object_t::key_type& key)
+    {
+        // implicitly convert null value to an empty object
+        if (is_null())
+        {
+            m_type = value_t::object;
+            m_value.object = create<object_t>();
+            assert_invariant();
+        }
+
+        // operator[] only works for objects
+        if (JSON_HEDLEY_LIKELY(is_object()))
+        {
+            return m_value.object->operator[](key);
+        }
+
+        JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
+    }
+
+    /*!
+    @brief read-only access specified object element
+
+    Returns a const reference to the element at with specified key @a key. No
+    bounds checking is performed.
+
+    @warning If the element with key @a key does not exist, the behavior is
+    undefined.
+
+    @param[in] key  key of the element to access
+
+    @return const reference to the element at key @a key
+
+    @pre The element with key @a key must exist. **This precondition is
+         enforced with an assertion.**
+
+    @throw type_error.305 if the JSON value is not an object; in that case,
+    using the [] operator with a key makes no sense.
+
+    @complexity Logarithmic in the size of the container.
+
+    @liveexample{The example below shows how object elements can be read using
+    the `[]` operator.,operatorarray__key_type_const}
+
+    @sa @ref at(const typename object_t::key_type&) for access by reference
+    with range checking
+    @sa @ref value() for access by value with a default value
+
+    @since version 1.0.0
+    */
+    const_reference operator[](const typename object_t::key_type& key) const
+    {
+        // const operator[] only works for objects
+        if (JSON_HEDLEY_LIKELY(is_object()))
+        {
+            JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
+            return m_value.object->find(key)->second;
+        }
+
+        JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
+    }
+
+    /*!
+    @brief access specified object element
+
+    Returns a reference to the element at with specified key @a key.
+
+    @note If @a key is not found in the object, then it is silently added to
+    the object and filled with a `null` value to make `key` a valid reference.
+    In case the value was `null` before, it is converted to an object.
+
+    @param[in] key  key of the element to access
+
+    @return reference to the element at key @a key
+
+    @throw type_error.305 if the JSON value is not an object or null; in that
+    cases, using the [] operator with a key makes no sense.
+
+    @complexity Logarithmic in the size of the container.
+
+    @liveexample{The example below shows how object elements can be read and
+    written using the `[]` operator.,operatorarray__key_type}
+
+    @sa @ref at(const typename object_t::key_type&) for access by reference
+    with range checking
+    @sa @ref value() for access by value with a default value
+
+    @since version 1.1.0
+    */
+    template<typename T>
+    JSON_HEDLEY_NON_NULL(2)
+    reference operator[](T* key)
+    {
+        // implicitly convert null to object
+        if (is_null())
+        {
+            m_type = value_t::object;
+            m_value = value_t::object;
+            assert_invariant();
+        }
+
+        // at only works for objects
+        if (JSON_HEDLEY_LIKELY(is_object()))
+        {
+            return m_value.object->operator[](key);
+        }
+
+        JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
+    }
+
+    /*!
+    @brief read-only access specified object element
+
+    Returns a const reference to the element at with specified key @a key. No
+    bounds checking is performed.
+
+    @warning If the element with key @a key does not exist, the behavior is
+    undefined.
+
+    @param[in] key  key of the element to access
+
+    @return const reference to the element at key @a key
+
+    @pre The element with key @a key must exist. **This precondition is
+         enforced with an assertion.**
+
+    @throw type_error.305 if the JSON value is not an object; in that case,
+    using the [] operator with a key makes no sense.
+
+    @complexity Logarithmic in the size of the container.
+
+    @liveexample{The example below shows how object elements can be read using
+    the `[]` operator.,operatorarray__key_type_const}
+
+    @sa @ref at(const typename object_t::key_type&) for access by reference
+    with range checking
+    @sa @ref value() for access by value with a default value
+
+    @since version 1.1.0
+    */
+    template<typename T>
+    JSON_HEDLEY_NON_NULL(2)
+    const_reference operator[](T* key) const
+    {
+        // at only works for objects
+        if (JSON_HEDLEY_LIKELY(is_object()))
+        {
+            JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
+            return m_value.object->find(key)->second;
+        }
+
+        JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
+    }
+
+    /*!
+    @brief access specified object element with default value
+
+    Returns either a copy of an object's element at the specified key @a key
+    or a given default value if no element with key @a key exists.
+
+    The function is basically equivalent to executing
+    @code {.cpp}
+    try {
+        return at(key);
+    } catch(out_of_range) {
+        return default_value;
+    }
+    @endcode
+
+    @note Unlike @ref at(const typename object_t::key_type&), this function
+    does not throw if the given key @a key was not found.
+
+    @note Unlike @ref operator[](const typename object_t::key_type& key), this
+    function does not implicitly add an element to the position defined by @a
+    key. This function is furthermore also applicable to const objects.
+
+    @param[in] key  key of the element to access
+    @param[in] default_value  the value to return if @a key is not found
+
+    @tparam ValueType type compatible to JSON values, for instance `int` for
+    JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
+    JSON arrays. Note the type of the expected value at @a key and the default
+    value @a default_value must be compatible.
+
+    @return copy of the element at key @a key or @a default_value if @a key
+    is not found
+
+    @throw type_error.302 if @a default_value does not match the type of the
+    value at @a key
+    @throw type_error.306 if the JSON value is not an object; in that case,
+    using `value()` with a key makes no sense.
+
+    @complexity Logarithmic in the size of the container.
+
+    @liveexample{The example below shows how object elements can be queried
+    with a default value.,basic_json__value}
+
+    @sa @ref at(const typename object_t::key_type&) for access by reference
+    with range checking
+    @sa @ref operator[](const typename object_t::key_type&) for unchecked
+    access by reference
+
+    @since version 1.0.0
+    */
+    // using std::is_convertible in a std::enable_if will fail when using explicit conversions
+    template < class ValueType, typename std::enable_if <
+                   detail::is_getable<basic_json_t, ValueType>::value
+                   && !std::is_same<value_t, ValueType>::value, int >::type = 0 >
+    ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
+    {
+        // at only works for objects
+        if (JSON_HEDLEY_LIKELY(is_object()))
+        {
+            // if key is found, return value and given default value otherwise
+            const auto it = find(key);
+            if (it != end())
+            {
+                return it->template get<ValueType>();
+            }
+
+            return default_value;
+        }
+
+        JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
+    }
+
+    /*!
+    @brief overload for a default value of type const char*
+    @copydoc basic_json::value(const typename object_t::key_type&, const ValueType&) const
+    */
+    string_t value(const typename object_t::key_type& key, const char* default_value) const
+    {
+        return value(key, string_t(default_value));
+    }
+
+    /*!
+    @brief access specified object element via JSON Pointer with default value
+
+    Returns either a copy of an object's element at the specified key @a key
+    or a given default value if no element with key @a key exists.
+
+    The function is basically equivalent to executing
+    @code {.cpp}
+    try {
+        return at(ptr);
+    } catch(out_of_range) {
+        return default_value;
+    }
+    @endcode
+
+    @note Unlike @ref at(const json_pointer&), this function does not throw
+    if the given key @a key was not found.
+
+    @param[in] ptr  a JSON pointer to the element to access
+    @param[in] default_value  the value to return if @a ptr found no value
+
+    @tparam ValueType type compatible to JSON values, for instance `int` for
+    JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
+    JSON arrays. Note the type of the expected value at @a key and the default
+    value @a default_value must be compatible.
+
+    @return copy of the element at key @a key or @a default_value if @a key
+    is not found
+
+    @throw type_error.302 if @a default_value does not match the type of the
+    value at @a ptr
+    @throw type_error.306 if the JSON value is not an object; in that case,
+    using `value()` with a key makes no sense.
+
+    @complexity Logarithmic in the size of the container.
+
+    @liveexample{The example below shows how object elements can be queried
+    with a default value.,basic_json__value_ptr}
+
+    @sa @ref operator[](const json_pointer&) for unchecked access by reference
+
+    @since version 2.0.2
+    */
+    template<class ValueType, typename std::enable_if<
+                 detail::is_getable<basic_json_t, ValueType>::value, int>::type = 0>
+    ValueType value(const json_pointer& ptr, const ValueType& default_value) const
+    {
+        // at only works for objects
+        if (JSON_HEDLEY_LIKELY(is_object()))
+        {
+            // if pointer resolves a value, return it or use default value
+            JSON_TRY
+            {
+                return ptr.get_checked(this).template get<ValueType>();
+            }
+            JSON_INTERNAL_CATCH (out_of_range&)
+            {
+                return default_value;
+            }
+        }
+
+        JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
+    }
+
+    /*!
+    @brief overload for a default value of type const char*
+    @copydoc basic_json::value(const json_pointer&, ValueType) const
+    */
+    JSON_HEDLEY_NON_NULL(3)
+    string_t value(const json_pointer& ptr, const char* default_value) const
+    {
+        return value(ptr, string_t(default_value));
+    }
+
+    /*!
+    @brief access the first element
+
+    Returns a reference to the first element in the container. For a JSON
+    container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
+
+    @return In case of a structured type (array or object), a reference to the
+    first element is returned. In case of number, string, boolean, or binary
+    values, a reference to the value is returned.
+
+    @complexity Constant.
+
+    @pre The JSON value must not be `null` (would throw `std::out_of_range`)
+    or an empty array or object (undefined behavior, **guarded by
+    assertions**).
+    @post The JSON value remains unchanged.
+
+    @throw invalid_iterator.214 when called on `null` value
+
+    @liveexample{The following code shows an example for `front()`.,front}
+
+    @sa @ref back() -- access the last element
+
+    @since version 1.0.0
+    */
+    reference front()
+    {
+        return *begin();
+    }
+
+    /*!
+    @copydoc basic_json::front()
+    */
+    const_reference front() const
+    {
+        return *cbegin();
+    }
+
+    /*!
+    @brief access the last element
+
+    Returns a reference to the last element in the container. For a JSON
+    container `c`, the expression `c.back()` is equivalent to
+    @code {.cpp}
+    auto tmp = c.end();
+    --tmp;
+    return *tmp;
+    @endcode
+
+    @return In case of a structured type (array or object), a reference to the
+    last element is returned. In case of number, string, boolean, or binary
+    values, a reference to the value is returned.
+
+    @complexity Constant.
+
+    @pre The JSON value must not be `null` (would throw `std::out_of_range`)
+    or an empty array or object (undefined behavior, **guarded by
+    assertions**).
+    @post The JSON value remains unchanged.
+
+    @throw invalid_iterator.214 when called on a `null` value. See example
+    below.
+
+    @liveexample{The following code shows an example for `back()`.,back}
+
+    @sa @ref front() -- access the first element
+
+    @since version 1.0.0
+    */
+    reference back()
+    {
+        auto tmp = end();
+        --tmp;
+        return *tmp;
+    }
+
+    /*!
+    @copydoc basic_json::back()
+    */
+    const_reference back() const
+    {
+        auto tmp = cend();
+        --tmp;
+        return *tmp;
+    }
+
+    /*!
+    @brief remove element given an iterator
+
+    Removes the element specified by iterator @a pos. The iterator @a pos must
+    be valid and dereferenceable. Thus the `end()` iterator (which is valid,
+    but is not dereferenceable) cannot be used as a value for @a pos.
+
+    If called on a primitive type other than `null`, the resulting JSON value
+    will be `null`.
+
+    @param[in] pos iterator to the element to remove
+    @return Iterator following the last removed element. If the iterator @a
+    pos refers to the last element, the `end()` iterator is returned.
+
+    @tparam IteratorType an @ref iterator or @ref const_iterator
+
+    @post Invalidates iterators and references at or after the point of the
+    erase, including the `end()` iterator.
+
+    @throw type_error.307 if called on a `null` value; example: `"cannot use
+    erase() with null"`
+    @throw invalid_iterator.202 if called on an iterator which does not belong
+    to the current JSON value; example: `"iterator does not fit current
+    value"`
+    @throw invalid_iterator.205 if called on a primitive type with invalid
+    iterator (i.e., any iterator which is not `begin()`); example: `"iterator
+    out of range"`
+
+    @complexity The complexity depends on the type:
+    - objects: amortized constant
+    - arrays: linear in distance between @a pos and the end of the container
+    - strings and binary: linear in the length of the member
+    - other types: constant
+
+    @liveexample{The example shows the result of `erase()` for different JSON
+    types.,erase__IteratorType}
+
+    @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
+    the given range
+    @sa @ref erase(const typename object_t::key_type&) -- removes the element
+    from an object at the given key
+    @sa @ref erase(const size_type) -- removes the element from an array at
+    the given index
+
+    @since version 1.0.0
+    */
+    template < class IteratorType, typename std::enable_if <
+                   std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
+                   std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
+               = 0 >
+    IteratorType erase(IteratorType pos)
+    {
+        // make sure iterator fits the current value
+        if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
+        {
+            JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
+        }
+
+        IteratorType result = end();
+
+        switch (m_type)
+        {
+            case value_t::boolean:
+            case value_t::number_float:
+            case value_t::number_integer:
+            case value_t::number_unsigned:
+            case value_t::string:
+            case value_t::binary:
+            {
+                if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
+                {
+                    JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
+                }
+
+                if (is_string())
+                {
+                    AllocatorType<string_t> alloc;
+                    std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
+                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
+                    m_value.string = nullptr;
+                }
+                else if (is_binary())
+                {
+                    AllocatorType<binary_t> alloc;
+                    std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
+                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
+                    m_value.binary = nullptr;
+                }
+
+                m_type = value_t::null;
+                assert_invariant();
+                break;
+            }
+
+            case value_t::object:
+            {
+                result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
+                break;
+            }
+
+            case value_t::array:
+            {
+                result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
+                break;
+            }
+
+            default:
+                JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
+        }
+
+        return result;
+    }
+
+    /*!
+    @brief remove elements given an iterator range
+
+    Removes the element specified by the range `[first; last)`. The iterator
+    @a first does not need to be dereferenceable if `first == last`: erasing
+    an empty range is a no-op.
+
+    If called on a primitive type other than `null`, the resulting JSON value
+    will be `null`.
+
+    @param[in] first iterator to the beginning of the range to remove
+    @param[in] last iterator past the end of the range to remove
+    @return Iterator following the last removed element. If the iterator @a
+    second refers to the last element, the `end()` iterator is returned.
+
+    @tparam IteratorType an @ref iterator or @ref const_iterator
+
+    @post Invalidates iterators and references at or after the point of the
+    erase, including the `end()` iterator.
+
+    @throw type_error.307 if called on a `null` value; example: `"cannot use
+    erase() with null"`
+    @throw invalid_iterator.203 if called on iterators which does not belong
+    to the current JSON value; example: `"iterators do not fit current value"`
+    @throw invalid_iterator.204 if called on a primitive type with invalid
+    iterators (i.e., if `first != begin()` and `last != end()`); example:
+    `"iterators out of range"`
+
+    @complexity The complexity depends on the type:
+    - objects: `log(size()) + std::distance(first, last)`
+    - arrays: linear in the distance between @a first and @a last, plus linear
+      in the distance between @a last and end of the container
+    - strings and binary: linear in the length of the member
+    - other types: constant
+
+    @liveexample{The example shows the result of `erase()` for different JSON
+    types.,erase__IteratorType_IteratorType}
+
+    @sa @ref erase(IteratorType) -- removes the element at a given position
+    @sa @ref erase(const typename object_t::key_type&) -- removes the element
+    from an object at the given key
+    @sa @ref erase(const size_type) -- removes the element from an array at
+    the given index
+
+    @since version 1.0.0
+    */
+    template < class IteratorType, typename std::enable_if <
+                   std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
+                   std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
+               = 0 >
+    IteratorType erase(IteratorType first, IteratorType last)
+    {
+        // make sure iterator fits the current value
+        if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
+        {
+            JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
+        }
+
+        IteratorType result = end();
+
+        switch (m_type)
+        {
+            case value_t::boolean:
+            case value_t::number_float:
+            case value_t::number_integer:
+            case value_t::number_unsigned:
+            case value_t::string:
+            case value_t::binary:
+            {
+                if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
+                                       || !last.m_it.primitive_iterator.is_end()))
+                {
+                    JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
+                }
+
+                if (is_string())
+                {
+                    AllocatorType<string_t> alloc;
+                    std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
+                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
+                    m_value.string = nullptr;
+                }
+                else if (is_binary())
+                {
+                    AllocatorType<binary_t> alloc;
+                    std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
+                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
+                    m_value.binary = nullptr;
+                }
+
+                m_type = value_t::null;
+                assert_invariant();
+                break;
+            }
+
+            case value_t::object:
+            {
+                result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
+                                              last.m_it.object_iterator);
+                break;
+            }
+
+            case value_t::array:
+            {
+                result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
+                                             last.m_it.array_iterator);
+                break;
+            }
+
+            default:
+                JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
+        }
+
+        return result;
+    }
+
+    /*!
+    @brief remove element from a JSON object given a key
+
+    Removes elements from a JSON object with the key value @a key.
+
+    @param[in] key value of the elements to remove
+
+    @return Number of elements removed. If @a ObjectType is the default
+    `std::map` type, the return value will always be `0` (@a key was not
+    found) or `1` (@a key was found).
+
+    @post References and iterators to the erased elements are invalidated.
+    Other references and iterators are not affected.
+
+    @throw type_error.307 when called on a type other than JSON object;
+    example: `"cannot use erase() with null"`
+
+    @complexity `log(size()) + count(key)`
+
+    @liveexample{The example shows the effect of `erase()`.,erase__key_type}
+
+    @sa @ref erase(IteratorType) -- removes the element at a given position
+    @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
+    the given range
+    @sa @ref erase(const size_type) -- removes the element from an array at
+    the given index
+
+    @since version 1.0.0
+    */
+    size_type erase(const typename object_t::key_type& key)
+    {
+        // this erase only works for objects
+        if (JSON_HEDLEY_LIKELY(is_object()))
+        {
+            return m_value.object->erase(key);
+        }
+
+        JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
+    }
+
+    /*!
+    @brief remove element from a JSON array given an index
+
+    Removes element from a JSON array at the index @a idx.
+
+    @param[in] idx index of the element to remove
+
+    @throw type_error.307 when called on a type other than JSON object;
+    example: `"cannot use erase() with null"`
+    @throw out_of_range.401 when `idx >= size()`; example: `"array index 17
+    is out of range"`
+
+    @complexity Linear in distance between @a idx and the end of the container.
+
+    @liveexample{The example shows the effect of `erase()`.,erase__size_type}
+
+    @sa @ref erase(IteratorType) -- removes the element at a given position
+    @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
+    the given range
+    @sa @ref erase(const typename object_t::key_type&) -- removes the element
+    from an object at the given key
+
+    @since version 1.0.0
+    */
+    void erase(const size_type idx)
+    {
+        // this erase only works for arrays
+        if (JSON_HEDLEY_LIKELY(is_array()))
+        {
+            if (JSON_HEDLEY_UNLIKELY(idx >= size()))
+            {
+                JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
+            }
+
+            m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
+        }
+        else
+        {
+            JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
+        }
+    }
+
+    /// @}
+
+
+    ////////////
+    // lookup //
+    ////////////
+
+    /// @name lookup
+    /// @{
+
+    /*!
+    @brief find an element in a JSON object
+
+    Finds an element in a JSON object with key equivalent to @a key. If the
+    element is not found or the JSON value is not an object, end() is
+    returned.
+
+    @note This method always returns @ref end() when executed on a JSON type
+          that is not an object.
+
+    @param[in] key key value of the element to search for.
+
+    @return Iterator to an element with key equivalent to @a key. If no such
+    element is found or the JSON value is not an object, past-the-end (see
+    @ref end()) iterator is returned.
+
+    @complexity Logarithmic in the size of the JSON object.
+
+    @liveexample{The example shows how `find()` is used.,find__key_type}
+
+    @sa @ref contains(KeyT&&) const -- checks whether a key exists
+
+    @since version 1.0.0
+    */
+    template<typename KeyT>
+    iterator find(KeyT&& key)
+    {
+        auto result = end();
+
+        if (is_object())
+        {
+            result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
+        }
+
+        return result;
+    }
+
+    /*!
+    @brief find an element in a JSON object
+    @copydoc find(KeyT&&)
+    */
+    template<typename KeyT>
+    const_iterator find(KeyT&& key) const
+    {
+        auto result = cend();
+
+        if (is_object())
+        {
+            result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
+        }
+
+        return result;
+    }
+
+    /*!
+    @brief returns the number of occurrences of a key in a JSON object
+
+    Returns the number of elements with key @a key. If ObjectType is the
+    default `std::map` type, the return value will always be `0` (@a key was
+    not found) or `1` (@a key was found).
+
+    @note This method always returns `0` when executed on a JSON type that is
+          not an object.
+
+    @param[in] key key value of the element to count
+
+    @return Number of elements with key @a key. If the JSON value is not an
+    object, the return value will be `0`.
+
+    @complexity Logarithmic in the size of the JSON object.
+
+    @liveexample{The example shows how `count()` is used.,count}
+
+    @since version 1.0.0
+    */
+    template<typename KeyT>
+    size_type count(KeyT&& key) const
+    {
+        // return 0 for all nonobject types
+        return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
+    }
+
+    /*!
+    @brief check the existence of an element in a JSON object
+
+    Check whether an element exists in a JSON object with key equivalent to
+    @a key. If the element is not found or the JSON value is not an object,
+    false is returned.
+
+    @note This method always returns false when executed on a JSON type
+          that is not an object.
+
+    @param[in] key key value to check its existence.
+
+    @return true if an element with specified @a key exists. If no such
+    element with such key is found or the JSON value is not an object,
+    false is returned.
+
+    @complexity Logarithmic in the size of the JSON object.
+
+    @liveexample{The following code shows an example for `contains()`.,contains}
+
+    @sa @ref find(KeyT&&) -- returns an iterator to an object element
+    @sa @ref contains(const json_pointer&) const -- checks the existence for a JSON pointer
+
+    @since version 3.6.0
+    */
+    template < typename KeyT, typename std::enable_if <
+                   !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >
+    bool contains(KeyT && key) const
+    {
+        return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
+    }
+
+    /*!
+    @brief check the existence of an element in a JSON object given a JSON pointer
+
+    Check whether the given JSON pointer @a ptr can be resolved in the current
+    JSON value.
+
+    @note This method can be executed on any JSON value type.
+
+    @param[in] ptr JSON pointer to check its existence.
+
+    @return true if the JSON pointer can be resolved to a stored value, false
+    otherwise.
+
+    @post If `j.contains(ptr)` returns true, it is safe to call `j[ptr]`.
+
+    @throw parse_error.106   if an array index begins with '0'
+    @throw parse_error.109   if an array index was not a number
+
+    @complexity Logarithmic in the size of the JSON object.
+
+    @liveexample{The following code shows an example for `contains()`.,contains_json_pointer}
+
+    @sa @ref contains(KeyT &&) const -- checks the existence of a key
+
+    @since version 3.7.0
+    */
+    bool contains(const json_pointer& ptr) const
+    {
+        return ptr.contains(this);
+    }
+
+    /// @}
+
+
+    ///////////////
+    // iterators //
+    ///////////////
+
+    /// @name iterators
+    /// @{
+
+    /*!
+    @brief returns an iterator to the first element
+
+    Returns an iterator to the first element.
+
+    @image html range-begin-end.svg "Illustration from cppreference.com"
+
+    @return iterator to the first element
+
+    @complexity Constant.
+
+    @requirement This function helps `basic_json` satisfying the
+    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
+    requirements:
+    - The complexity is constant.
+
+    @liveexample{The following code shows an example for `begin()`.,begin}
+
+    @sa @ref cbegin() -- returns a const iterator to the beginning
+    @sa @ref end() -- returns an iterator to the end
+    @sa @ref cend() -- returns a const iterator to the end
+
+    @since version 1.0.0
+    */
+    iterator begin() noexcept
+    {
+        iterator result(this);
+        result.set_begin();
+        return result;
+    }
+
+    /*!
+    @copydoc basic_json::cbegin()
+    */
+    const_iterator begin() const noexcept
+    {
+        return cbegin();
+    }
+
+    /*!
+    @brief returns a const iterator to the first element
+
+    Returns a const iterator to the first element.
+
+    @image html range-begin-end.svg "Illustration from cppreference.com"
+
+    @return const iterator to the first element
+
+    @complexity Constant.
+
+    @requirement This function helps `basic_json` satisfying the
+    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
+    requirements:
+    - The complexity is constant.
+    - Has the semantics of `const_cast<const basic_json&>(*this).begin()`.
+
+    @liveexample{The following code shows an example for `cbegin()`.,cbegin}
+
+    @sa @ref begin() -- returns an iterator to the beginning
+    @sa @ref end() -- returns an iterator to the end
+    @sa @ref cend() -- returns a const iterator to the end
+
+    @since version 1.0.0
+    */
+    const_iterator cbegin() const noexcept
+    {
+        const_iterator result(this);
+        result.set_begin();
+        return result;
+    }
+
+    /*!
+    @brief returns an iterator to one past the last element
+
+    Returns an iterator to one past the last element.
+
+    @image html range-begin-end.svg "Illustration from cppreference.com"
+
+    @return iterator one past the last element
+
+    @complexity Constant.
+
+    @requirement This function helps `basic_json` satisfying the
+    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
+    requirements:
+    - The complexity is constant.
+
+    @liveexample{The following code shows an example for `end()`.,end}
+
+    @sa @ref cend() -- returns a const iterator to the end
+    @sa @ref begin() -- returns an iterator to the beginning
+    @sa @ref cbegin() -- returns a const iterator to the beginning
+
+    @since version 1.0.0
+    */
+    iterator end() noexcept
+    {
+        iterator result(this);
+        result.set_end();
+        return result;
+    }
+
+    /*!
+    @copydoc basic_json::cend()
+    */
+    const_iterator end() const noexcept
+    {
+        return cend();
+    }
+
+    /*!
+    @brief returns a const iterator to one past the last element
+
+    Returns a const iterator to one past the last element.
+
+    @image html range-begin-end.svg "Illustration from cppreference.com"
+
+    @return const iterator one past the last element
+
+    @complexity Constant.
+
+    @requirement This function helps `basic_json` satisfying the
+    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
+    requirements:
+    - The complexity is constant.
+    - Has the semantics of `const_cast<const basic_json&>(*this).end()`.
+
+    @liveexample{The following code shows an example for `cend()`.,cend}
+
+    @sa @ref end() -- returns an iterator to the end
+    @sa @ref begin() -- returns an iterator to the beginning
+    @sa @ref cbegin() -- returns a const iterator to the beginning
+
+    @since version 1.0.0
+    */
+    const_iterator cend() const noexcept
+    {
+        const_iterator result(this);
+        result.set_end();
+        return result;
+    }
+
+    /*!
+    @brief returns an iterator to the reverse-beginning
+
+    Returns an iterator to the reverse-beginning; that is, the last element.
+
+    @image html range-rbegin-rend.svg "Illustration from cppreference.com"
+
+    @complexity Constant.
+
+    @requirement This function helps `basic_json` satisfying the
+    [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
+    requirements:
+    - The complexity is constant.
+    - Has the semantics of `reverse_iterator(end())`.
+
+    @liveexample{The following code shows an example for `rbegin()`.,rbegin}
+
+    @sa @ref crbegin() -- returns a const reverse iterator to the beginning
+    @sa @ref rend() -- returns a reverse iterator to the end
+    @sa @ref crend() -- returns a const reverse iterator to the end
+
+    @since version 1.0.0
+    */
+    reverse_iterator rbegin() noexcept
+    {
+        return reverse_iterator(end());
+    }
+
+    /*!
+    @copydoc basic_json::crbegin()
+    */
+    const_reverse_iterator rbegin() const noexcept
+    {
+        return crbegin();
+    }
+
+    /*!
+    @brief returns an iterator to the reverse-end
+
+    Returns an iterator to the reverse-end; that is, one before the first
+    element.
+
+    @image html range-rbegin-rend.svg "Illustration from cppreference.com"
+
+    @complexity Constant.
+
+    @requirement This function helps `basic_json` satisfying the
+    [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
+    requirements:
+    - The complexity is constant.
+    - Has the semantics of `reverse_iterator(begin())`.
+
+    @liveexample{The following code shows an example for `rend()`.,rend}
+
+    @sa @ref crend() -- returns a const reverse iterator to the end
+    @sa @ref rbegin() -- returns a reverse iterator to the beginning
+    @sa @ref crbegin() -- returns a const reverse iterator to the beginning
+
+    @since version 1.0.0
+    */
+    reverse_iterator rend() noexcept
+    {
+        return reverse_iterator(begin());
+    }
+
+    /*!
+    @copydoc basic_json::crend()
+    */
+    const_reverse_iterator rend() const noexcept
+    {
+        return crend();
+    }
+
+    /*!
+    @brief returns a const reverse iterator to the last element
+
+    Returns a const iterator to the reverse-beginning; that is, the last
+    element.
+
+    @image html range-rbegin-rend.svg "Illustration from cppreference.com"
+
+    @complexity Constant.
+
+    @requirement This function helps `basic_json` satisfying the
+    [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
+    requirements:
+    - The complexity is constant.
+    - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.
+
+    @liveexample{The following code shows an example for `crbegin()`.,crbegin}
+
+    @sa @ref rbegin() -- returns a reverse iterator to the beginning
+    @sa @ref rend() -- returns a reverse iterator to the end
+    @sa @ref crend() -- returns a const reverse iterator to the end
+
+    @since version 1.0.0
+    */
+    const_reverse_iterator crbegin() const noexcept
+    {
+        return const_reverse_iterator(cend());
+    }
+
+    /*!
+    @brief returns a const reverse iterator to one before the first
+
+    Returns a const reverse iterator to the reverse-end; that is, one before
+    the first element.
+
+    @image html range-rbegin-rend.svg "Illustration from cppreference.com"
+
+    @complexity Constant.
+
+    @requirement This function helps `basic_json` satisfying the
+    [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
+    requirements:
+    - The complexity is constant.
+    - Has the semantics of `const_cast<const basic_json&>(*this).rend()`.
+
+    @liveexample{The following code shows an example for `crend()`.,crend}
+
+    @sa @ref rend() -- returns a reverse iterator to the end
+    @sa @ref rbegin() -- returns a reverse iterator to the beginning
+    @sa @ref crbegin() -- returns a const reverse iterator to the beginning
+
+    @since version 1.0.0
+    */
+    const_reverse_iterator crend() const noexcept
+    {
+        return const_reverse_iterator(cbegin());
+    }
+
+  public:
+    /*!
+    @brief wrapper to access iterator member functions in range-based for
+
+    This function allows to access @ref iterator::key() and @ref
+    iterator::value() during range-based for loops. In these loops, a
+    reference to the JSON values is returned, so there is no access to the
+    underlying iterator.
+
+    For loop without iterator_wrapper:
+
+    @code{cpp}
+    for (auto it = j_object.begin(); it != j_object.end(); ++it)
+    {
+        std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
+    }
+    @endcode
+
+    Range-based for loop without iterator proxy:
+
+    @code{cpp}
+    for (auto it : j_object)
+    {
+        // "it" is of type json::reference and has no key() member
+        std::cout << "value: " << it << '\n';
+    }
+    @endcode
+
+    Range-based for loop with iterator proxy:
+
+    @code{cpp}
+    for (auto it : json::iterator_wrapper(j_object))
+    {
+        std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
+    }
+    @endcode
+
+    @note When iterating over an array, `key()` will return the index of the
+          element as string (see example).
+
+    @param[in] ref  reference to a JSON value
+    @return iteration proxy object wrapping @a ref with an interface to use in
+            range-based for loops
+
+    @liveexample{The following code shows how the wrapper is used,iterator_wrapper}
+
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes in the JSON value.
+
+    @complexity Constant.
+
+    @note The name of this function is not yet final and may change in the
+    future.
+
+    @deprecated This stream operator is deprecated and will be removed in
+                future 4.0.0 of the library. Please use @ref items() instead;
+                that is, replace `json::iterator_wrapper(j)` with `j.items()`.
+    */
+    JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
+    static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
+    {
+        return ref.items();
+    }
+
+    /*!
+    @copydoc iterator_wrapper(reference)
+    */
+    JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
+    static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
+    {
+        return ref.items();
+    }
+
+    /*!
+    @brief helper to access iterator member functions in range-based for
+
+    This function allows to access @ref iterator::key() and @ref
+    iterator::value() during range-based for loops. In these loops, a
+    reference to the JSON values is returned, so there is no access to the
+    underlying iterator.
+
+    For loop without `items()` function:
+
+    @code{cpp}
+    for (auto it = j_object.begin(); it != j_object.end(); ++it)
+    {
+        std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
+    }
+    @endcode
+
+    Range-based for loop without `items()` function:
+
+    @code{cpp}
+    for (auto it : j_object)
+    {
+        // "it" is of type json::reference and has no key() member
+        std::cout << "value: " << it << '\n';
+    }
+    @endcode
+
+    Range-based for loop with `items()` function:
+
+    @code{cpp}
+    for (auto& el : j_object.items())
+    {
+        std::cout << "key: " << el.key() << ", value:" << el.value() << '\n';
+    }
+    @endcode
+
+    The `items()` function also allows to use
+    [structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding)
+    (C++17):
+
+    @code{cpp}
+    for (auto& [key, val] : j_object.items())
+    {
+        std::cout << "key: " << key << ", value:" << val << '\n';
+    }
+    @endcode
+
+    @note When iterating over an array, `key()` will return the index of the
+          element as string (see example). For primitive types (e.g., numbers),
+          `key()` returns an empty string.
+
+    @warning Using `items()` on temporary objects is dangerous. Make sure the
+             object's lifetime exeeds the iteration. See
+             <https://github.com/nlohmann/json/issues/2040> for more
+             information.
+
+    @return iteration proxy object wrapping @a ref with an interface to use in
+            range-based for loops
+
+    @liveexample{The following code shows how the function is used.,items}
+
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes in the JSON value.
+
+    @complexity Constant.
+
+    @since version 3.1.0, structured bindings support since 3.5.0.
+    */
+    iteration_proxy<iterator> items() noexcept
+    {
+        return iteration_proxy<iterator>(*this);
+    }
+
+    /*!
+    @copydoc items()
+    */
+    iteration_proxy<const_iterator> items() const noexcept
+    {
+        return iteration_proxy<const_iterator>(*this);
+    }
+
+    /// @}
+
+
+    //////////////
+    // capacity //
+    //////////////
+
+    /// @name capacity
+    /// @{
+
+    /*!
+    @brief checks whether the container is empty.
+
+    Checks if a JSON value has no elements (i.e. whether its @ref size is `0`).
+
+    @return The return value depends on the different types and is
+            defined as follows:
+            Value type  | return value
+            ----------- | -------------
+            null        | `true`
+            boolean     | `false`
+            string      | `false`
+            number      | `false`
+            binary      | `false`
+            object      | result of function `object_t::empty()`
+            array       | result of function `array_t::empty()`
+
+    @liveexample{The following code uses `empty()` to check if a JSON
+    object contains any elements.,empty}
+
+    @complexity Constant, as long as @ref array_t and @ref object_t satisfy
+    the Container concept; that is, their `empty()` functions have constant
+    complexity.
+
+    @iterators No changes.
+
+    @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
+    @note This function does not return whether a string stored as JSON value
+    is empty - it returns whether the JSON container itself is empty which is
+    false in the case of a string.
+
+    @requirement This function helps `basic_json` satisfying the
+    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
+    requirements:
+    - The complexity is constant.
+    - Has the semantics of `begin() == end()`.
+
+    @sa @ref size() -- returns the number of elements
+
+    @since version 1.0.0
+    */
+    bool empty() const noexcept
+    {
+        switch (m_type)
+        {
+            case value_t::null:
+            {
+                // null values are empty
+                return true;
+            }
+
+            case value_t::array:
+            {
+                // delegate call to array_t::empty()
+                return m_value.array->empty();
+            }
+
+            case value_t::object:
+            {
+                // delegate call to object_t::empty()
+                return m_value.object->empty();
+            }
+
+            default:
+            {
+                // all other types are nonempty
+                return false;
+            }
+        }
+    }
+
+    /*!
+    @brief returns the number of elements
+
+    Returns the number of elements in a JSON value.
+
+    @return The return value depends on the different types and is
+            defined as follows:
+            Value type  | return value
+            ----------- | -------------
+            null        | `0`
+            boolean     | `1`
+            string      | `1`
+            number      | `1`
+            binary      | `1`
+            object      | result of function object_t::size()
+            array       | result of function array_t::size()
+
+    @liveexample{The following code calls `size()` on the different value
+    types.,size}
+
+    @complexity Constant, as long as @ref array_t and @ref object_t satisfy
+    the Container concept; that is, their size() functions have constant
+    complexity.
+
+    @iterators No changes.
+
+    @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
+    @note This function does not return the length of a string stored as JSON
+    value - it returns the number of elements in the JSON value which is 1 in
+    the case of a string.
+
+    @requirement This function helps `basic_json` satisfying the
+    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
+    requirements:
+    - The complexity is constant.
+    - Has the semantics of `std::distance(begin(), end())`.
+
+    @sa @ref empty() -- checks whether the container is empty
+    @sa @ref max_size() -- returns the maximal number of elements
+
+    @since version 1.0.0
+    */
+    size_type size() const noexcept
+    {
+        switch (m_type)
+        {
+            case value_t::null:
+            {
+                // null values are empty
+                return 0;
+            }
+
+            case value_t::array:
+            {
+                // delegate call to array_t::size()
+                return m_value.array->size();
+            }
+
+            case value_t::object:
+            {
+                // delegate call to object_t::size()
+                return m_value.object->size();
+            }
+
+            default:
+            {
+                // all other types have size 1
+                return 1;
+            }
+        }
+    }
+
+    /*!
+    @brief returns the maximum possible number of elements
+
+    Returns the maximum number of elements a JSON value is able to hold due to
+    system or library implementation limitations, i.e. `std::distance(begin(),
+    end())` for the JSON value.
+
+    @return The return value depends on the different types and is
+            defined as follows:
+            Value type  | return value
+            ----------- | -------------
+            null        | `0` (same as `size()`)
+            boolean     | `1` (same as `size()`)
+            string      | `1` (same as `size()`)
+            number      | `1` (same as `size()`)
+            binary      | `1` (same as `size()`)
+            object      | result of function `object_t::max_size()`
+            array       | result of function `array_t::max_size()`
+
+    @liveexample{The following code calls `max_size()` on the different value
+    types. Note the output is implementation specific.,max_size}
+
+    @complexity Constant, as long as @ref array_t and @ref object_t satisfy
+    the Container concept; that is, their `max_size()` functions have constant
+    complexity.
+
+    @iterators No changes.
+
+    @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
+    @requirement This function helps `basic_json` satisfying the
+    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
+    requirements:
+    - The complexity is constant.
+    - Has the semantics of returning `b.size()` where `b` is the largest
+      possible JSON value.
+
+    @sa @ref size() -- returns the number of elements
+
+    @since version 1.0.0
+    */
+    size_type max_size() const noexcept
+    {
+        switch (m_type)
+        {
+            case value_t::array:
+            {
+                // delegate call to array_t::max_size()
+                return m_value.array->max_size();
+            }
+
+            case value_t::object:
+            {
+                // delegate call to object_t::max_size()
+                return m_value.object->max_size();
+            }
+
+            default:
+            {
+                // all other types have max_size() == size()
+                return size();
+            }
+        }
+    }
+
+    /// @}
+
+
+    ///////////////
+    // modifiers //
+    ///////////////
+
+    /// @name modifiers
+    /// @{
+
+    /*!
+    @brief clears the contents
+
+    Clears the content of a JSON value and resets it to the default value as
+    if @ref basic_json(value_t) would have been called with the current value
+    type from @ref type():
+
+    Value type  | initial value
+    ----------- | -------------
+    null        | `null`
+    boolean     | `false`
+    string      | `""`
+    number      | `0`
+    binary      | An empty byte vector
+    object      | `{}`
+    array       | `[]`
+
+    @post Has the same effect as calling
+    @code {.cpp}
+    *this = basic_json(type());
+    @endcode
+
+    @liveexample{The example below shows the effect of `clear()` to different
+    JSON types.,clear}
+
+    @complexity Linear in the size of the JSON value.
+
+    @iterators All iterators, pointers and references related to this container
+               are invalidated.
+
+    @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
+    @sa @ref basic_json(value_t) -- constructor that creates an object with the
+        same value than calling `clear()`
+
+    @since version 1.0.0
+    */
+    void clear() noexcept
+    {
+        switch (m_type)
+        {
+            case value_t::number_integer:
+            {
+                m_value.number_integer = 0;
+                break;
+            }
+
+            case value_t::number_unsigned:
+            {
+                m_value.number_unsigned = 0;
+                break;
+            }
+
+            case value_t::number_float:
+            {
+                m_value.number_float = 0.0;
+                break;
+            }
+
+            case value_t::boolean:
+            {
+                m_value.boolean = false;
+                break;
+            }
+
+            case value_t::string:
+            {
+                m_value.string->clear();
+                break;
+            }
+
+            case value_t::binary:
+            {
+                m_value.binary->clear();
+                break;
+            }
+
+            case value_t::array:
+            {
+                m_value.array->clear();
+                break;
+            }
+
+            case value_t::object:
+            {
+                m_value.object->clear();
+                break;
+            }
+
+            default:
+                break;
+        }
+    }
+
+    /*!
+    @brief add an object to an array
+
+    Appends the given element @a val to the end of the JSON value. If the
+    function is called on a JSON null value, an empty array is created before
+    appending @a val.
+
+    @param[in] val the value to add to the JSON array
+
+    @throw type_error.308 when called on a type other than JSON array or
+    null; example: `"cannot use push_back() with number"`
+
+    @complexity Amortized constant.
+
+    @liveexample{The example shows how `push_back()` and `+=` can be used to
+    add elements to a JSON array. Note how the `null` value was silently
+    converted to a JSON array.,push_back}
+
+    @since version 1.0.0
+    */
+    void push_back(basic_json&& val)
+    {
+        // push_back only works for null objects or arrays
+        if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
+        {
+            JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
+        }
+
+        // transform null object into an array
+        if (is_null())
+        {
+            m_type = value_t::array;
+            m_value = value_t::array;
+            assert_invariant();
+        }
+
+        // add element to array (move semantics)
+        m_value.array->push_back(std::move(val));
+        // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
+    }
+
+    /*!
+    @brief add an object to an array
+    @copydoc push_back(basic_json&&)
+    */
+    reference operator+=(basic_json&& val)
+    {
+        push_back(std::move(val));
+        return *this;
+    }
+
+    /*!
+    @brief add an object to an array
+    @copydoc push_back(basic_json&&)
+    */
+    void push_back(const basic_json& val)
+    {
+        // push_back only works for null objects or arrays
+        if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
+        {
+            JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
+        }
+
+        // transform null object into an array
+        if (is_null())
+        {
+            m_type = value_t::array;
+            m_value = value_t::array;
+            assert_invariant();
+        }
+
+        // add element to array
+        m_value.array->push_back(val);
+    }
+
+    /*!
+    @brief add an object to an array
+    @copydoc push_back(basic_json&&)
+    */
+    reference operator+=(const basic_json& val)
+    {
+        push_back(val);
+        return *this;
+    }
+
+    /*!
+    @brief add an object to an object
+
+    Inserts the given element @a val to the JSON object. If the function is
+    called on a JSON null value, an empty object is created before inserting
+    @a val.
+
+    @param[in] val the value to add to the JSON object
+
+    @throw type_error.308 when called on a type other than JSON object or
+    null; example: `"cannot use push_back() with number"`
+
+    @complexity Logarithmic in the size of the container, O(log(`size()`)).
+
+    @liveexample{The example shows how `push_back()` and `+=` can be used to
+    add elements to a JSON object. Note how the `null` value was silently
+    converted to a JSON object.,push_back__object_t__value}
+
+    @since version 1.0.0
+    */
+    void push_back(const typename object_t::value_type& val)
+    {
+        // push_back only works for null objects or objects
+        if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
+        {
+            JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
+        }
+
+        // transform null object into an object
+        if (is_null())
+        {
+            m_type = value_t::object;
+            m_value = value_t::object;
+            assert_invariant();
+        }
+
+        // add element to array
+        m_value.object->insert(val);
+    }
+
+    /*!
+    @brief add an object to an object
+    @copydoc push_back(const typename object_t::value_type&)
+    */
+    reference operator+=(const typename object_t::value_type& val)
+    {
+        push_back(val);
+        return *this;
+    }
+
+    /*!
+    @brief add an object to an object
+
+    This function allows to use `push_back` with an initializer list. In case
+
+    1. the current value is an object,
+    2. the initializer list @a init contains only two elements, and
+    3. the first element of @a init is a string,
+
+    @a init is converted into an object element and added using
+    @ref push_back(const typename object_t::value_type&). Otherwise, @a init
+    is converted to a JSON value and added using @ref push_back(basic_json&&).
+
+    @param[in] init  an initializer list
+
+    @complexity Linear in the size of the initializer list @a init.
+
+    @note This function is required to resolve an ambiguous overload error,
+          because pairs like `{"key", "value"}` can be both interpreted as
+          `object_t::value_type` or `std::initializer_list<basic_json>`, see
+          https://github.com/nlohmann/json/issues/235 for more information.
+
+    @liveexample{The example shows how initializer lists are treated as
+    objects when possible.,push_back__initializer_list}
+    */
+    void push_back(initializer_list_t init)
+    {
+        if (is_object() && init.size() == 2 && (*init.begin())->is_string())
+        {
+            basic_json&& key = init.begin()->moved_or_copied();
+            push_back(typename object_t::value_type(
+                          std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
+        }
+        else
+        {
+            push_back(basic_json(init));
+        }
+    }
+
+    /*!
+    @brief add an object to an object
+    @copydoc push_back(initializer_list_t)
+    */
+    reference operator+=(initializer_list_t init)
+    {
+        push_back(init);
+        return *this;
+    }
+
+    /*!
+    @brief add an object to an array
+
+    Creates a JSON value from the passed parameters @a args to the end of the
+    JSON value. If the function is called on a JSON null value, an empty array
+    is created before appending the value created from @a args.
+
+    @param[in] args arguments to forward to a constructor of @ref basic_json
+    @tparam Args compatible types to create a @ref basic_json object
+
+    @return reference to the inserted element
+
+    @throw type_error.311 when called on a type other than JSON array or
+    null; example: `"cannot use emplace_back() with number"`
+
+    @complexity Amortized constant.
+
+    @liveexample{The example shows how `push_back()` can be used to add
+    elements to a JSON array. Note how the `null` value was silently converted
+    to a JSON array.,emplace_back}
+
+    @since version 2.0.8, returns reference since 3.7.0
+    */
+    template<class... Args>
+    reference emplace_back(Args&& ... args)
+    {
+        // emplace_back only works for null objects or arrays
+        if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
+        {
+            JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
+        }
+
+        // transform null object into an array
+        if (is_null())
+        {
+            m_type = value_t::array;
+            m_value = value_t::array;
+            assert_invariant();
+        }
+
+        // add element to array (perfect forwarding)
+#ifdef JSON_HAS_CPP_17
+        return m_value.array->emplace_back(std::forward<Args>(args)...);
+#else
+        m_value.array->emplace_back(std::forward<Args>(args)...);
+        return m_value.array->back();
+#endif
+    }
+
+    /*!
+    @brief add an object to an object if key does not exist
+
+    Inserts a new element into a JSON object constructed in-place with the
+    given @a args if there is no element with the key in the container. If the
+    function is called on a JSON null value, an empty object is created before
+    appending the value created from @a args.
+
+    @param[in] args arguments to forward to a constructor of @ref basic_json
+    @tparam Args compatible types to create a @ref basic_json object
+
+    @return a pair consisting of an iterator to the inserted element, or the
+            already-existing element if no insertion happened, and a bool
+            denoting whether the insertion took place.
+
+    @throw type_error.311 when called on a type other than JSON object or
+    null; example: `"cannot use emplace() with number"`
+
+    @complexity Logarithmic in the size of the container, O(log(`size()`)).
+
+    @liveexample{The example shows how `emplace()` can be used to add elements
+    to a JSON object. Note how the `null` value was silently converted to a
+    JSON object. Further note how no value is added if there was already one
+    value stored with the same key.,emplace}
+
+    @since version 2.0.8
+    */
+    template<class... Args>
+    std::pair<iterator, bool> emplace(Args&& ... args)
+    {
+        // emplace only works for null objects or arrays
+        if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
+        {
+            JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
+        }
+
+        // transform null object into an object
+        if (is_null())
+        {
+            m_type = value_t::object;
+            m_value = value_t::object;
+            assert_invariant();
+        }
+
+        // add element to array (perfect forwarding)
+        auto res = m_value.object->emplace(std::forward<Args>(args)...);
+        // create result iterator and set iterator to the result of emplace
+        auto it = begin();
+        it.m_it.object_iterator = res.first;
+
+        // return pair of iterator and boolean
+        return {it, res.second};
+    }
+
+    /// Helper for insertion of an iterator
+    /// @note: This uses std::distance to support GCC 4.8,
+    ///        see https://github.com/nlohmann/json/pull/1257
+    template<typename... Args>
+    iterator insert_iterator(const_iterator pos, Args&& ... args)
+    {
+        iterator result(this);
+        JSON_ASSERT(m_value.array != nullptr);
+
+        auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
+        m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
+        result.m_it.array_iterator = m_value.array->begin() + insert_pos;
+
+        // This could have been written as:
+        // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
+        // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
+
+        return result;
+    }
+
+    /*!
+    @brief inserts element
+
+    Inserts element @a val before iterator @a pos.
+
+    @param[in] pos iterator before which the content will be inserted; may be
+    the end() iterator
+    @param[in] val element to insert
+    @return iterator pointing to the inserted @a val.
+
+    @throw type_error.309 if called on JSON values other than arrays;
+    example: `"cannot use insert() with string"`
+    @throw invalid_iterator.202 if @a pos is not an iterator of *this;
+    example: `"iterator does not fit current value"`
+
+    @complexity Constant plus linear in the distance between @a pos and end of
+    the container.
+
+    @liveexample{The example shows how `insert()` is used.,insert}
+
+    @since version 1.0.0
+    */
+    iterator insert(const_iterator pos, const basic_json& val)
+    {
+        // insert only works for arrays
+        if (JSON_HEDLEY_LIKELY(is_array()))
+        {
+            // check if iterator pos fits to this JSON value
+            if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
+            {
+                JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
+            }
+
+            // insert to array and return iterator
+            return insert_iterator(pos, val);
+        }
+
+        JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
+    }
+
+    /*!
+    @brief inserts element
+    @copydoc insert(const_iterator, const basic_json&)
+    */
+    iterator insert(const_iterator pos, basic_json&& val)
+    {
+        return insert(pos, val);
+    }
+
+    /*!
+    @brief inserts elements
+
+    Inserts @a cnt copies of @a val before iterator @a pos.
+
+    @param[in] pos iterator before which the content will be inserted; may be
+    the end() iterator
+    @param[in] cnt number of copies of @a val to insert
+    @param[in] val element to insert
+    @return iterator pointing to the first element inserted, or @a pos if
+    `cnt==0`
+
+    @throw type_error.309 if called on JSON values other than arrays; example:
+    `"cannot use insert() with string"`
+    @throw invalid_iterator.202 if @a pos is not an iterator of *this;
+    example: `"iterator does not fit current value"`
+
+    @complexity Linear in @a cnt plus linear in the distance between @a pos
+    and end of the container.
+
+    @liveexample{The example shows how `insert()` is used.,insert__count}
+
+    @since version 1.0.0
+    */
+    iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
+    {
+        // insert only works for arrays
+        if (JSON_HEDLEY_LIKELY(is_array()))
+        {
+            // check if iterator pos fits to this JSON value
+            if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
+            {
+                JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
+            }
+
+            // insert to array and return iterator
+            return insert_iterator(pos, cnt, val);
+        }
+
+        JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
+    }
+
+    /*!
+    @brief inserts elements
+
+    Inserts elements from range `[first, last)` before iterator @a pos.
+
+    @param[in] pos iterator before which the content will be inserted; may be
+    the end() iterator
+    @param[in] first begin of the range of elements to insert
+    @param[in] last end of the range of elements to insert
+
+    @throw type_error.309 if called on JSON values other than arrays; example:
+    `"cannot use insert() with string"`
+    @throw invalid_iterator.202 if @a pos is not an iterator of *this;
+    example: `"iterator does not fit current value"`
+    @throw invalid_iterator.210 if @a first and @a last do not belong to the
+    same JSON value; example: `"iterators do not fit"`
+    @throw invalid_iterator.211 if @a first or @a last are iterators into
+    container for which insert is called; example: `"passed iterators may not
+    belong to container"`
+
+    @return iterator pointing to the first element inserted, or @a pos if
+    `first==last`
+
+    @complexity Linear in `std::distance(first, last)` plus linear in the
+    distance between @a pos and end of the container.
+
+    @liveexample{The example shows how `insert()` is used.,insert__range}
+
+    @since version 1.0.0
+    */
+    iterator insert(const_iterator pos, const_iterator first, const_iterator last)
+    {
+        // insert only works for arrays
+        if (JSON_HEDLEY_UNLIKELY(!is_array()))
+        {
+            JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
+        }
+
+        // check if iterator pos fits to this JSON value
+        if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
+        {
+            JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
+        }
+
+        // check if range iterators belong to the same JSON object
+        if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
+        {
+            JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
+        }
+
+        if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
+        {
+            JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
+        }
+
+        // insert to array and return iterator
+        return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
+    }
+
+    /*!
+    @brief inserts elements
+
+    Inserts elements from initializer list @a ilist before iterator @a pos.
+
+    @param[in] pos iterator before which the content will be inserted; may be
+    the end() iterator
+    @param[in] ilist initializer list to insert the values from
+
+    @throw type_error.309 if called on JSON values other than arrays; example:
+    `"cannot use insert() with string"`
+    @throw invalid_iterator.202 if @a pos is not an iterator of *this;
+    example: `"iterator does not fit current value"`
+
+    @return iterator pointing to the first element inserted, or @a pos if
+    `ilist` is empty
+
+    @complexity Linear in `ilist.size()` plus linear in the distance between
+    @a pos and end of the container.
+
+    @liveexample{The example shows how `insert()` is used.,insert__ilist}
+
+    @since version 1.0.0
+    */
+    iterator insert(const_iterator pos, initializer_list_t ilist)
+    {
+        // insert only works for arrays
+        if (JSON_HEDLEY_UNLIKELY(!is_array()))
+        {
+            JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
+        }
+
+        // check if iterator pos fits to this JSON value
+        if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
+        {
+            JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
+        }
+
+        // insert to array and return iterator
+        return insert_iterator(pos, ilist.begin(), ilist.end());
+    }
+
+    /*!
+    @brief inserts elements
+
+    Inserts elements from range `[first, last)`.
+
+    @param[in] first begin of the range of elements to insert
+    @param[in] last end of the range of elements to insert
+
+    @throw type_error.309 if called on JSON values other than objects; example:
+    `"cannot use insert() with string"`
+    @throw invalid_iterator.202 if iterator @a first or @a last does does not
+    point to an object; example: `"iterators first and last must point to
+    objects"`
+    @throw invalid_iterator.210 if @a first and @a last do not belong to the
+    same JSON value; example: `"iterators do not fit"`
+
+    @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number
+    of elements to insert.
+
+    @liveexample{The example shows how `insert()` is used.,insert__range_object}
+
+    @since version 3.0.0
+    */
+    void insert(const_iterator first, const_iterator last)
+    {
+        // insert only works for objects
+        if (JSON_HEDLEY_UNLIKELY(!is_object()))
+        {
+            JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
+        }
+
+        // check if range iterators belong to the same JSON object
+        if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
+        {
+            JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
+        }
+
+        // passed iterators must belong to objects
+        if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
+        {
+            JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
+        }
+
+        m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
+    }
+
+    /*!
+    @brief updates a JSON object from another object, overwriting existing keys
+
+    Inserts all values from JSON object @a j and overwrites existing keys.
+
+    @param[in] j  JSON object to read values from
+
+    @throw type_error.312 if called on JSON values other than objects; example:
+    `"cannot use update() with string"`
+
+    @complexity O(N*log(size() + N)), where N is the number of elements to
+                insert.
+
+    @liveexample{The example shows how `update()` is used.,update}
+
+    @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
+
+    @since version 3.0.0
+    */
+    void update(const_reference j)
+    {
+        // implicitly convert null value to an empty object
+        if (is_null())
+        {
+            m_type = value_t::object;
+            m_value.object = create<object_t>();
+            assert_invariant();
+        }
+
+        if (JSON_HEDLEY_UNLIKELY(!is_object()))
+        {
+            JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
+        }
+        if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
+        {
+            JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
+        }
+
+        for (auto it = j.cbegin(); it != j.cend(); ++it)
+        {
+            m_value.object->operator[](it.key()) = it.value();
+        }
+    }
+
+    /*!
+    @brief updates a JSON object from another object, overwriting existing keys
+
+    Inserts all values from from range `[first, last)` and overwrites existing
+    keys.
+
+    @param[in] first begin of the range of elements to insert
+    @param[in] last end of the range of elements to insert
+
+    @throw type_error.312 if called on JSON values other than objects; example:
+    `"cannot use update() with string"`
+    @throw invalid_iterator.202 if iterator @a first or @a last does does not
+    point to an object; example: `"iterators first and last must point to
+    objects"`
+    @throw invalid_iterator.210 if @a first and @a last do not belong to the
+    same JSON value; example: `"iterators do not fit"`
+
+    @complexity O(N*log(size() + N)), where N is the number of elements to
+                insert.
+
+    @liveexample{The example shows how `update()` is used__range.,update}
+
+    @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
+
+    @since version 3.0.0
+    */
+    void update(const_iterator first, const_iterator last)
+    {
+        // implicitly convert null value to an empty object
+        if (is_null())
+        {
+            m_type = value_t::object;
+            m_value.object = create<object_t>();
+            assert_invariant();
+        }
+
+        if (JSON_HEDLEY_UNLIKELY(!is_object()))
+        {
+            JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
+        }
+
+        // check if range iterators belong to the same JSON object
+        if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
+        {
+            JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
+        }
+
+        // passed iterators must belong to objects
+        if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()
+                                 || !last.m_object->is_object()))
+        {
+            JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
+        }
+
+        for (auto it = first; it != last; ++it)
+        {
+            m_value.object->operator[](it.key()) = it.value();
+        }
+    }
+
+    /*!
+    @brief exchanges the values
+
+    Exchanges the contents of the JSON value with those of @a other. Does not
+    invoke any move, copy, or swap operations on individual elements. All
+    iterators and references remain valid. The past-the-end iterator is
+    invalidated.
+
+    @param[in,out] other JSON value to exchange the contents with
+
+    @complexity Constant.
+
+    @liveexample{The example below shows how JSON values can be swapped with
+    `swap()`.,swap__reference}
+
+    @since version 1.0.0
+    */
+    void swap(reference other) noexcept (
+        std::is_nothrow_move_constructible<value_t>::value&&
+        std::is_nothrow_move_assignable<value_t>::value&&
+        std::is_nothrow_move_constructible<json_value>::value&&
+        std::is_nothrow_move_assignable<json_value>::value
+    )
+    {
+        std::swap(m_type, other.m_type);
+        std::swap(m_value, other.m_value);
+        assert_invariant();
+    }
+
+    /*!
+    @brief exchanges the values
+
+    Exchanges the contents of the JSON value from @a left with those of @a right. Does not
+    invoke any move, copy, or swap operations on individual elements. All
+    iterators and references remain valid. The past-the-end iterator is
+    invalidated. implemented as a friend function callable via ADL.
+
+    @param[in,out] left JSON value to exchange the contents with
+    @param[in,out] right JSON value to exchange the contents with
+
+    @complexity Constant.
+
+    @liveexample{The example below shows how JSON values can be swapped with
+    `swap()`.,swap__reference}
+
+    @since version 1.0.0
+    */
+    friend void swap(reference left, reference right) noexcept (
+        std::is_nothrow_move_constructible<value_t>::value&&
+        std::is_nothrow_move_assignable<value_t>::value&&
+        std::is_nothrow_move_constructible<json_value>::value&&
+        std::is_nothrow_move_assignable<json_value>::value
+    )
+    {
+        left.swap(right);
+    }
+
+    /*!
+    @brief exchanges the values
+
+    Exchanges the contents of a JSON array with those of @a other. Does not
+    invoke any move, copy, or swap operations on individual elements. All
+    iterators and references remain valid. The past-the-end iterator is
+    invalidated.
+
+    @param[in,out] other array to exchange the contents with
+
+    @throw type_error.310 when JSON value is not an array; example: `"cannot
+    use swap() with string"`
+
+    @complexity Constant.
+
+    @liveexample{The example below shows how arrays can be swapped with
+    `swap()`.,swap__array_t}
+
+    @since version 1.0.0
+    */
+    void swap(array_t& other)
+    {
+        // swap only works for arrays
+        if (JSON_HEDLEY_LIKELY(is_array()))
+        {
+            std::swap(*(m_value.array), other);
+        }
+        else
+        {
+            JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
+        }
+    }
+
+    /*!
+    @brief exchanges the values
+
+    Exchanges the contents of a JSON object with those of @a other. Does not
+    invoke any move, copy, or swap operations on individual elements. All
+    iterators and references remain valid. The past-the-end iterator is
+    invalidated.
+
+    @param[in,out] other object to exchange the contents with
+
+    @throw type_error.310 when JSON value is not an object; example:
+    `"cannot use swap() with string"`
+
+    @complexity Constant.
+
+    @liveexample{The example below shows how objects can be swapped with
+    `swap()`.,swap__object_t}
+
+    @since version 1.0.0
+    */
+    void swap(object_t& other)
+    {
+        // swap only works for objects
+        if (JSON_HEDLEY_LIKELY(is_object()))
+        {
+            std::swap(*(m_value.object), other);
+        }
+        else
+        {
+            JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
+        }
+    }
+
+    /*!
+    @brief exchanges the values
+
+    Exchanges the contents of a JSON string with those of @a other. Does not
+    invoke any move, copy, or swap operations on individual elements. All
+    iterators and references remain valid. The past-the-end iterator is
+    invalidated.
+
+    @param[in,out] other string to exchange the contents with
+
+    @throw type_error.310 when JSON value is not a string; example: `"cannot
+    use swap() with boolean"`
+
+    @complexity Constant.
+
+    @liveexample{The example below shows how strings can be swapped with
+    `swap()`.,swap__string_t}
+
+    @since version 1.0.0
+    */
+    void swap(string_t& other)
+    {
+        // swap only works for strings
+        if (JSON_HEDLEY_LIKELY(is_string()))
+        {
+            std::swap(*(m_value.string), other);
+        }
+        else
+        {
+            JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
+        }
+    }
+
+    /*!
+    @brief exchanges the values
+
+    Exchanges the contents of a JSON string with those of @a other. Does not
+    invoke any move, copy, or swap operations on individual elements. All
+    iterators and references remain valid. The past-the-end iterator is
+    invalidated.
+
+    @param[in,out] other binary to exchange the contents with
+
+    @throw type_error.310 when JSON value is not a string; example: `"cannot
+    use swap() with boolean"`
+
+    @complexity Constant.
+
+    @liveexample{The example below shows how strings can be swapped with
+    `swap()`.,swap__binary_t}
+
+    @since version 3.8.0
+    */
+    void swap(binary_t& other)
+    {
+        // swap only works for strings
+        if (JSON_HEDLEY_LIKELY(is_binary()))
+        {
+            std::swap(*(m_value.binary), other);
+        }
+        else
+        {
+            JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
+        }
+    }
+
+    /// @copydoc swap(binary_t)
+    void swap(typename binary_t::container_type& other)
+    {
+        // swap only works for strings
+        if (JSON_HEDLEY_LIKELY(is_binary()))
+        {
+            std::swap(*(m_value.binary), other);
+        }
+        else
+        {
+            JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
+        }
+    }
+
+    /// @}
+
+  public:
+    //////////////////////////////////////////
+    // lexicographical comparison operators //
+    //////////////////////////////////////////
+
+    /// @name lexicographical comparison operators
+    /// @{
+
+    /*!
+    @brief comparison: equal
+
+    Compares two JSON values for equality according to the following rules:
+    - Two JSON values are equal if (1) they are from the same type and (2)
+      their stored values are the same according to their respective
+      `operator==`.
+    - Integer and floating-point numbers are automatically converted before
+      comparison. Note that two NaN values are always treated as unequal.
+    - Two JSON null values are equal.
+
+    @note Floating-point inside JSON values numbers are compared with
+    `json::number_float_t::operator==` which is `double::operator==` by
+    default. To compare floating-point while respecting an epsilon, an alternative
+    [comparison function](https://github.com/mariokonrad/marnav/blob/master/include/marnav/math/floatingpoint.hpp#L34-#L39)
+    could be used, for instance
+    @code {.cpp}
+    template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>
+    inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept
+    {
+        return std::abs(a - b) <= epsilon;
+    }
+    @endcode
+    Or you can self-defined operator equal function like this:
+    @code {.cpp}
+    bool my_equal(const_reference lhs, const_reference rhs) {
+    const auto lhs_type lhs.type();
+    const auto rhs_type rhs.type();
+    if (lhs_type == rhs_type) {
+        switch(lhs_type)
+            // self_defined case
+            case value_t::number_float:
+                return std::abs(lhs - rhs) <= std::numeric_limits<float>::epsilon();
+            // other cases remain the same with the original
+            ...
+    }
+    ...
+    }
+    @endcode
+
+    @note NaN values never compare equal to themselves or to other NaN values.
+
+    @param[in] lhs  first JSON value to consider
+    @param[in] rhs  second JSON value to consider
+    @return whether the values @a lhs and @a rhs are equal
+
+    @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
+    @complexity Linear.
+
+    @liveexample{The example demonstrates comparing several JSON
+    types.,operator__equal}
+
+    @since version 1.0.0
+    */
+    friend bool operator==(const_reference lhs, const_reference rhs) noexcept
+    {
+        const auto lhs_type = lhs.type();
+        const auto rhs_type = rhs.type();
+
+        if (lhs_type == rhs_type)
+        {
+            switch (lhs_type)
+            {
+                case value_t::array:
+                    return *lhs.m_value.array == *rhs.m_value.array;
+
+                case value_t::object:
+                    return *lhs.m_value.object == *rhs.m_value.object;
+
+                case value_t::null:
+                    return true;
+
+                case value_t::string:
+                    return *lhs.m_value.string == *rhs.m_value.string;
+
+                case value_t::boolean:
+                    return lhs.m_value.boolean == rhs.m_value.boolean;
+
+                case value_t::number_integer:
+                    return lhs.m_value.number_integer == rhs.m_value.number_integer;
+
+                case value_t::number_unsigned:
+                    return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
+
+                case value_t::number_float:
+                    return lhs.m_value.number_float == rhs.m_value.number_float;
+
+                case value_t::binary:
+                    return *lhs.m_value.binary == *rhs.m_value.binary;
+
+                default:
+                    return false;
+            }
+        }
+        else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
+        {
+            return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
+        }
+        else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
+        {
+            return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
+        }
+        else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
+        {
+            return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
+        }
+        else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
+        {
+            return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
+        }
+        else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
+        {
+            return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
+        }
+        else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
+        {
+            return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
+        }
+
+        return false;
+    }
+
+    /*!
+    @brief comparison: equal
+    @copydoc operator==(const_reference, const_reference)
+    */
+    template<typename ScalarType, typename std::enable_if<
+                 std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
+    {
+        return lhs == basic_json(rhs);
+    }
+
+    /*!
+    @brief comparison: equal
+    @copydoc operator==(const_reference, const_reference)
+    */
+    template<typename ScalarType, typename std::enable_if<
+                 std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
+    {
+        return basic_json(lhs) == rhs;
+    }
+
+    /*!
+    @brief comparison: not equal
+
+    Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
+
+    @param[in] lhs  first JSON value to consider
+    @param[in] rhs  second JSON value to consider
+    @return whether the values @a lhs and @a rhs are not equal
+
+    @complexity Linear.
+
+    @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
+    @liveexample{The example demonstrates comparing several JSON
+    types.,operator__notequal}
+
+    @since version 1.0.0
+    */
+    friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
+    {
+        return !(lhs == rhs);
+    }
+
+    /*!
+    @brief comparison: not equal
+    @copydoc operator!=(const_reference, const_reference)
+    */
+    template<typename ScalarType, typename std::enable_if<
+                 std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
+    {
+        return lhs != basic_json(rhs);
+    }
+
+    /*!
+    @brief comparison: not equal
+    @copydoc operator!=(const_reference, const_reference)
+    */
+    template<typename ScalarType, typename std::enable_if<
+                 std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
+    {
+        return basic_json(lhs) != rhs;
+    }
+
+    /*!
+    @brief comparison: less than
+
+    Compares whether one JSON value @a lhs is less than another JSON value @a
+    rhs according to the following rules:
+    - If @a lhs and @a rhs have the same type, the values are compared using
+      the default `<` operator.
+    - Integer and floating-point numbers are automatically converted before
+      comparison
+    - In case @a lhs and @a rhs have different types, the values are ignored
+      and the order of the types is considered, see
+      @ref operator<(const value_t, const value_t).
+
+    @param[in] lhs  first JSON value to consider
+    @param[in] rhs  second JSON value to consider
+    @return whether @a lhs is less than @a rhs
+
+    @complexity Linear.
+
+    @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
+    @liveexample{The example demonstrates comparing several JSON
+    types.,operator__less}
+
+    @since version 1.0.0
+    */
+    friend bool operator<(const_reference lhs, const_reference rhs) noexcept
+    {
+        const auto lhs_type = lhs.type();
+        const auto rhs_type = rhs.type();
+
+        if (lhs_type == rhs_type)
+        {
+            switch (lhs_type)
+            {
+                case value_t::array:
+                    // note parentheses are necessary, see
+                    // https://github.com/nlohmann/json/issues/1530
+                    return (*lhs.m_value.array) < (*rhs.m_value.array);
+
+                case value_t::object:
+                    return (*lhs.m_value.object) < (*rhs.m_value.object);
+
+                case value_t::null:
+                    return false;
+
+                case value_t::string:
+                    return (*lhs.m_value.string) < (*rhs.m_value.string);
+
+                case value_t::boolean:
+                    return (lhs.m_value.boolean) < (rhs.m_value.boolean);
+
+                case value_t::number_integer:
+                    return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
+
+                case value_t::number_unsigned:
+                    return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
+
+                case value_t::number_float:
+                    return (lhs.m_value.number_float) < (rhs.m_value.number_float);
+
+                case value_t::binary:
+                    return (*lhs.m_value.binary) < (*rhs.m_value.binary);
+
+                default:
+                    return false;
+            }
+        }
+        else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
+        {
+            return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
+        }
+        else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
+        {
+            return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
+        }
+        else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
+        {
+            return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
+        }
+        else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
+        {
+            return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
+        }
+        else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
+        {
+            return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
+        }
+        else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
+        {
+            return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
+        }
+
+        // We only reach this line if we cannot compare values. In that case,
+        // we compare types. Note we have to call the operator explicitly,
+        // because MSVC has problems otherwise.
+        return operator<(lhs_type, rhs_type);
+    }
+
+    /*!
+    @brief comparison: less than
+    @copydoc operator<(const_reference, const_reference)
+    */
+    template<typename ScalarType, typename std::enable_if<
+                 std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
+    {
+        return lhs < basic_json(rhs);
+    }
+
+    /*!
+    @brief comparison: less than
+    @copydoc operator<(const_reference, const_reference)
+    */
+    template<typename ScalarType, typename std::enable_if<
+                 std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
+    {
+        return basic_json(lhs) < rhs;
+    }
+
+    /*!
+    @brief comparison: less than or equal
+
+    Compares whether one JSON value @a lhs is less than or equal to another
+    JSON value by calculating `not (rhs < lhs)`.
+
+    @param[in] lhs  first JSON value to consider
+    @param[in] rhs  second JSON value to consider
+    @return whether @a lhs is less than or equal to @a rhs
+
+    @complexity Linear.
+
+    @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
+    @liveexample{The example demonstrates comparing several JSON
+    types.,operator__greater}
+
+    @since version 1.0.0
+    */
+    friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
+    {
+        return !(rhs < lhs);
+    }
+
+    /*!
+    @brief comparison: less than or equal
+    @copydoc operator<=(const_reference, const_reference)
+    */
+    template<typename ScalarType, typename std::enable_if<
+                 std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
+    {
+        return lhs <= basic_json(rhs);
+    }
+
+    /*!
+    @brief comparison: less than or equal
+    @copydoc operator<=(const_reference, const_reference)
+    */
+    template<typename ScalarType, typename std::enable_if<
+                 std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
+    {
+        return basic_json(lhs) <= rhs;
+    }
+
+    /*!
+    @brief comparison: greater than
+
+    Compares whether one JSON value @a lhs is greater than another
+    JSON value by calculating `not (lhs <= rhs)`.
+
+    @param[in] lhs  first JSON value to consider
+    @param[in] rhs  second JSON value to consider
+    @return whether @a lhs is greater than to @a rhs
+
+    @complexity Linear.
+
+    @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
+    @liveexample{The example demonstrates comparing several JSON
+    types.,operator__lessequal}
+
+    @since version 1.0.0
+    */
+    friend bool operator>(const_reference lhs, const_reference rhs) noexcept
+    {
+        return !(lhs <= rhs);
+    }
+
+    /*!
+    @brief comparison: greater than
+    @copydoc operator>(const_reference, const_reference)
+    */
+    template<typename ScalarType, typename std::enable_if<
+                 std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
+    {
+        return lhs > basic_json(rhs);
+    }
+
+    /*!
+    @brief comparison: greater than
+    @copydoc operator>(const_reference, const_reference)
+    */
+    template<typename ScalarType, typename std::enable_if<
+                 std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
+    {
+        return basic_json(lhs) > rhs;
+    }
+
+    /*!
+    @brief comparison: greater than or equal
+
+    Compares whether one JSON value @a lhs is greater than or equal to another
+    JSON value by calculating `not (lhs < rhs)`.
+
+    @param[in] lhs  first JSON value to consider
+    @param[in] rhs  second JSON value to consider
+    @return whether @a lhs is greater than or equal to @a rhs
+
+    @complexity Linear.
+
+    @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
+    @liveexample{The example demonstrates comparing several JSON
+    types.,operator__greaterequal}
+
+    @since version 1.0.0
+    */
+    friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
+    {
+        return !(lhs < rhs);
+    }
+
+    /*!
+    @brief comparison: greater than or equal
+    @copydoc operator>=(const_reference, const_reference)
+    */
+    template<typename ScalarType, typename std::enable_if<
+                 std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
+    {
+        return lhs >= basic_json(rhs);
+    }
+
+    /*!
+    @brief comparison: greater than or equal
+    @copydoc operator>=(const_reference, const_reference)
+    */
+    template<typename ScalarType, typename std::enable_if<
+                 std::is_scalar<ScalarType>::value, int>::type = 0>
+    friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
+    {
+        return basic_json(lhs) >= rhs;
+    }
+
+    /// @}
+
+    ///////////////////
+    // serialization //
+    ///////////////////
+
+    /// @name serialization
+    /// @{
+
+    /*!
+    @brief serialize to stream
+
+    Serialize the given JSON value @a j to the output stream @a o. The JSON
+    value will be serialized using the @ref dump member function.
+
+    - The indentation of the output can be controlled with the member variable
+      `width` of the output stream @a o. For instance, using the manipulator
+      `std::setw(4)` on @a o sets the indentation level to `4` and the
+      serialization result is the same as calling `dump(4)`.
+
+    - The indentation character can be controlled with the member variable
+      `fill` of the output stream @a o. For instance, the manipulator
+      `std::setfill('\\t')` sets indentation to use a tab character rather than
+      the default space character.
+
+    @param[in,out] o  stream to serialize to
+    @param[in] j  JSON value to serialize
+
+    @return the stream @a o
+
+    @throw type_error.316 if a string stored inside the JSON value is not
+                          UTF-8 encoded
+
+    @complexity Linear.
+
+    @liveexample{The example below shows the serialization with different
+    parameters to `width` to adjust the indentation level.,operator_serialize}
+
+    @since version 1.0.0; indentation character added in version 3.0.0
+    */
+    friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
+    {
+        // read width member and use it as indentation parameter if nonzero
+        const bool pretty_print = o.width() > 0;
+        const auto indentation = pretty_print ? o.width() : 0;
+
+        // reset width to 0 for subsequent calls to this stream
+        o.width(0);
+
+        // do the actual serialization
+        serializer s(detail::output_adapter<char>(o), o.fill());
+        s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
+        return o;
+    }
+
+    /*!
+    @brief serialize to stream
+    @deprecated This stream operator is deprecated and will be removed in
+                future 4.0.0 of the library. Please use
+                @ref operator<<(std::ostream&, const basic_json&)
+                instead; that is, replace calls like `j >> o;` with `o << j;`.
+    @since version 1.0.0; deprecated since version 3.0.0
+    */
+    JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
+    friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
+    {
+        return o << j;
+    }
+
+    /// @}
+
+
+    /////////////////////
+    // deserialization //
+    /////////////////////
+
+    /// @name deserialization
+    /// @{
+
+    /*!
+    @brief deserialize from a compatible input
+
+    @tparam InputType A compatible input, for instance
+    - an std::istream object
+    - a FILE pointer
+    - a C-style array of characters
+    - a pointer to a null-terminated string of single byte characters
+    - an object obj for which begin(obj) and end(obj) produces a valid pair of
+      iterators.
+
+    @param[in] i  input to read from
+    @param[in] cb  a parser callback function of type @ref parser_callback_t
+    which is used to control the deserialization by filtering unwanted values
+    (optional)
+    @param[in] allow_exceptions  whether to throw exceptions in case of a
+    parse error (optional, true by default)
+    @param[in] ignore_comments  whether comments should be ignored and treated
+    like whitespace (true) or yield a parse error (true); (optional, false by
+    default)
+
+    @return deserialized JSON value; in case of a parse error and
+            @a allow_exceptions set to `false`, the return value will be
+            value_t::discarded.
+
+    @throw parse_error.101 if a parse error occurs; example: `""unexpected end
+    of input; expected string literal""`
+    @throw parse_error.102 if to_unicode fails or surrogate error
+    @throw parse_error.103 if to_unicode fails
+
+    @complexity Linear in the length of the input. The parser is a predictive
+    LL(1) parser. The complexity can be higher if the parser callback function
+    @a cb or reading from the input @a i has a super-linear complexity.
+
+    @note A UTF-8 byte order mark is silently ignored.
+
+    @liveexample{The example below demonstrates the `parse()` function reading
+    from an array.,parse__array__parser_callback_t}
+
+    @liveexample{The example below demonstrates the `parse()` function with
+    and without callback function.,parse__string__parser_callback_t}
+
+    @liveexample{The example below demonstrates the `parse()` function with
+    and without callback function.,parse__istream__parser_callback_t}
+
+    @liveexample{The example below demonstrates the `parse()` function reading
+    from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
+
+    @since version 2.0.3 (contiguous containers); version 3.9.0 allowed to
+    ignore comments.
+    */
+    template<typename InputType>
+    JSON_HEDLEY_WARN_UNUSED_RESULT
+    static basic_json parse(InputType&& i,
+                            const parser_callback_t cb = nullptr,
+                            const bool allow_exceptions = true,
+                            const bool ignore_comments = false)
+    {
+        basic_json result;
+        parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
+        return result;
+    }
+
+    /*!
+    @brief deserialize from a pair of character iterators
+
+    The value_type of the iterator must be a integral type with size of 1, 2 or
+    4 bytes, which will be interpreted respectively as UTF-8, UTF-16 and UTF-32.
+
+    @param[in] first iterator to start of character range
+    @param[in] last  iterator to end of character range
+    @param[in] cb  a parser callback function of type @ref parser_callback_t
+    which is used to control the deserialization by filtering unwanted values
+    (optional)
+    @param[in] allow_exceptions  whether to throw exceptions in case of a
+    parse error (optional, true by default)
+    @param[in] ignore_comments  whether comments should be ignored and treated
+    like whitespace (true) or yield a parse error (true); (optional, false by
+    default)
+
+    @return deserialized JSON value; in case of a parse error and
+            @a allow_exceptions set to `false`, the return value will be
+            value_t::discarded.
+
+    @throw parse_error.101 if a parse error occurs; example: `""unexpected end
+    of input; expected string literal""`
+    @throw parse_error.102 if to_unicode fails or surrogate error
+    @throw parse_error.103 if to_unicode fails
+    */
+    template<typename IteratorType>
+    JSON_HEDLEY_WARN_UNUSED_RESULT
+    static basic_json parse(IteratorType first,
+                            IteratorType last,
+                            const parser_callback_t cb = nullptr,
+                            const bool allow_exceptions = true,
+                            const bool ignore_comments = false)
+    {
+        basic_json result;
+        parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
+        return result;
+    }
+
+    JSON_HEDLEY_WARN_UNUSED_RESULT
+    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
+    static basic_json parse(detail::span_input_adapter&& i,
+                            const parser_callback_t cb = nullptr,
+                            const bool allow_exceptions = true,
+                            const bool ignore_comments = false)
+    {
+        basic_json result;
+        parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
+        return result;
+    }
+
+    /*!
+    @brief check if the input is valid JSON
+
+    Unlike the @ref parse(InputType&&, const parser_callback_t,const bool)
+    function, this function neither throws an exception in case of invalid JSON
+    input (i.e., a parse error) nor creates diagnostic information.
+
+    @tparam InputType A compatible input, for instance
+    - an std::istream object
+    - a FILE pointer
+    - a C-style array of characters
+    - a pointer to a null-terminated string of single byte characters
+    - an object obj for which begin(obj) and end(obj) produces a valid pair of
+      iterators.
+
+    @param[in] i input to read from
+    @param[in] ignore_comments  whether comments should be ignored and treated
+    like whitespace (true) or yield a parse error (true); (optional, false by
+    default)
+
+    @return Whether the input read from @a i is valid JSON.
+
+    @complexity Linear in the length of the input. The parser is a predictive
+    LL(1) parser.
+
+    @note A UTF-8 byte order mark is silently ignored.
+
+    @liveexample{The example below demonstrates the `accept()` function reading
+    from a string.,accept__string}
+    */
+    template<typename InputType>
+    static bool accept(InputType&& i,
+                       const bool ignore_comments = false)
+    {
+        return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
+    }
+
+    template<typename IteratorType>
+    static bool accept(IteratorType first, IteratorType last,
+                       const bool ignore_comments = false)
+    {
+        return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
+    }
+
+    JSON_HEDLEY_WARN_UNUSED_RESULT
+    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
+    static bool accept(detail::span_input_adapter&& i,
+                       const bool ignore_comments = false)
+    {
+        return parser(i.get(), nullptr, false, ignore_comments).accept(true);
+    }
+
+    /*!
+    @brief generate SAX events
+
+    The SAX event lister must follow the interface of @ref json_sax.
+
+    This function reads from a compatible input. Examples are:
+    - an std::istream object
+    - a FILE pointer
+    - a C-style array of characters
+    - a pointer to a null-terminated string of single byte characters
+    - an object obj for which begin(obj) and end(obj) produces a valid pair of
+      iterators.
+
+    @param[in] i  input to read from
+    @param[in,out] sax  SAX event listener
+    @param[in] format  the format to parse (JSON, CBOR, MessagePack, or UBJSON)
+    @param[in] strict  whether the input has to be consumed completely
+    @param[in] ignore_comments  whether comments should be ignored and treated
+    like whitespace (true) or yield a parse error (true); (optional, false by
+    default); only applies to the JSON file format.
+
+    @return return value of the last processed SAX event
+
+    @throw parse_error.101 if a parse error occurs; example: `""unexpected end
+    of input; expected string literal""`
+    @throw parse_error.102 if to_unicode fails or surrogate error
+    @throw parse_error.103 if to_unicode fails
+
+    @complexity Linear in the length of the input. The parser is a predictive
+    LL(1) parser. The complexity can be higher if the SAX consumer @a sax has
+    a super-linear complexity.
+
+    @note A UTF-8 byte order mark is silently ignored.
+
+    @liveexample{The example below demonstrates the `sax_parse()` function
+    reading from string and processing the events with a user-defined SAX
+    event consumer.,sax_parse}
+
+    @since version 3.2.0
+    */
+    template <typename InputType, typename SAX>
+    JSON_HEDLEY_NON_NULL(2)
+    static bool sax_parse(InputType&& i, SAX* sax,
+                          input_format_t format = input_format_t::json,
+                          const bool strict = true,
+                          const bool ignore_comments = false)
+    {
+        auto ia = detail::input_adapter(std::forward<InputType>(i));
+        return format == input_format_t::json
+               ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
+               : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
+    }
+
+    template<class IteratorType, class SAX>
+    JSON_HEDLEY_NON_NULL(3)
+    static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
+                          input_format_t format = input_format_t::json,
+                          const bool strict = true,
+                          const bool ignore_comments = false)
+    {
+        auto ia = detail::input_adapter(std::move(first), std::move(last));
+        return format == input_format_t::json
+               ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
+               : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
+    }
+
+    template <typename SAX>
+    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
+    JSON_HEDLEY_NON_NULL(2)
+    static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
+                          input_format_t format = input_format_t::json,
+                          const bool strict = true,
+                          const bool ignore_comments = false)
+    {
+        auto ia = i.get();
+        return format == input_format_t::json
+               ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
+               : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
+    }
+
+    /*!
+    @brief deserialize from stream
+    @deprecated This stream operator is deprecated and will be removed in
+                version 4.0.0 of the library. Please use
+                @ref operator>>(std::istream&, basic_json&)
+                instead; that is, replace calls like `j << i;` with `i >> j;`.
+    @since version 1.0.0; deprecated since version 3.0.0
+    */
+    JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
+    friend std::istream& operator<<(basic_json& j, std::istream& i)
+    {
+        return operator>>(i, j);
+    }
+
+    /*!
+    @brief deserialize from stream
+
+    Deserializes an input stream to a JSON value.
+
+    @param[in,out] i  input stream to read a serialized JSON value from
+    @param[in,out] j  JSON value to write the deserialized input to
+
+    @throw parse_error.101 in case of an unexpected token
+    @throw parse_error.102 if to_unicode fails or surrogate error
+    @throw parse_error.103 if to_unicode fails
+
+    @complexity Linear in the length of the input. The parser is a predictive
+    LL(1) parser.
+
+    @note A UTF-8 byte order mark is silently ignored.
+
+    @liveexample{The example below shows how a JSON value is constructed by
+    reading a serialization from a stream.,operator_deserialize}
+
+    @sa parse(std::istream&, const parser_callback_t) for a variant with a
+    parser callback function to filter values while parsing
+
+    @since version 1.0.0
+    */
+    friend std::istream& operator>>(std::istream& i, basic_json& j)
+    {
+        parser(detail::input_adapter(i)).parse(false, j);
+        return i;
+    }
+
+    /// @}
+
+    ///////////////////////////
+    // convenience functions //
+    ///////////////////////////
+
+    /*!
+    @brief return the type as string
+
+    Returns the type name as string to be used in error messages - usually to
+    indicate that a function was called on a wrong JSON type.
+
+    @return a string representation of a the @a m_type member:
+            Value type  | return value
+            ----------- | -------------
+            null        | `"null"`
+            boolean     | `"boolean"`
+            string      | `"string"`
+            number      | `"number"` (for all number types)
+            object      | `"object"`
+            array       | `"array"`
+            binary      | `"binary"`
+            discarded   | `"discarded"`
+
+    @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
+    @complexity Constant.
+
+    @liveexample{The following code exemplifies `type_name()` for all JSON
+    types.,type_name}
+
+    @sa @ref type() -- return the type of the JSON value
+    @sa @ref operator value_t() -- return the type of the JSON value (implicit)
+
+    @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept`
+    since 3.0.0
+    */
+    JSON_HEDLEY_RETURNS_NON_NULL
+    const char* type_name() const noexcept
+    {
+        {
+            switch (m_type)
+            {
+                case value_t::null:
+                    return "null";
+                case value_t::object:
+                    return "object";
+                case value_t::array:
+                    return "array";
+                case value_t::string:
+                    return "string";
+                case value_t::boolean:
+                    return "boolean";
+                case value_t::binary:
+                    return "binary";
+                case value_t::discarded:
+                    return "discarded";
+                default:
+                    return "number";
+            }
+        }
+    }
+
+
+  private:
+    //////////////////////
+    // member variables //
+    //////////////////////
+
+    /// the type of the current element
+    value_t m_type = value_t::null;
+
+    /// the value of the current element
+    json_value m_value = {};
+
+    //////////////////////////////////////////
+    // binary serialization/deserialization //
+    //////////////////////////////////////////
+
+    /// @name binary serialization/deserialization support
+    /// @{
+
+  public:
+    /*!
+    @brief create a CBOR serialization of a given JSON value
+
+    Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
+    Binary Object Representation) serialization format. CBOR is a binary
+    serialization format which aims to be more compact than JSON itself, yet
+    more efficient to parse.
+
+    The library uses the following mapping from JSON values types to
+    CBOR types according to the CBOR specification (RFC 7049):
+
+    JSON value type | value/range                                | CBOR type                          | first byte
+    --------------- | ------------------------------------------ | ---------------------------------- | ---------------
+    null            | `null`                                     | Null                               | 0xF6
+    boolean         | `true`                                     | True                               | 0xF5
+    boolean         | `false`                                    | False                              | 0xF4
+    number_integer  | -9223372036854775808..-2147483649          | Negative integer (8 bytes follow)  | 0x3B
+    number_integer  | -2147483648..-32769                        | Negative integer (4 bytes follow)  | 0x3A
+    number_integer  | -32768..-129                               | Negative integer (2 bytes follow)  | 0x39
+    number_integer  | -128..-25                                  | Negative integer (1 byte follow)   | 0x38
+    number_integer  | -24..-1                                    | Negative integer                   | 0x20..0x37
+    number_integer  | 0..23                                      | Integer                            | 0x00..0x17
+    number_integer  | 24..255                                    | Unsigned integer (1 byte follow)   | 0x18
+    number_integer  | 256..65535                                 | Unsigned integer (2 bytes follow)  | 0x19
+    number_integer  | 65536..4294967295                          | Unsigned integer (4 bytes follow)  | 0x1A
+    number_integer  | 4294967296..18446744073709551615           | Unsigned integer (8 bytes follow)  | 0x1B
+    number_unsigned | 0..23                                      | Integer                            | 0x00..0x17
+    number_unsigned | 24..255                                    | Unsigned integer (1 byte follow)   | 0x18
+    number_unsigned | 256..65535                                 | Unsigned integer (2 bytes follow)  | 0x19
+    number_unsigned | 65536..4294967295                          | Unsigned integer (4 bytes follow)  | 0x1A
+    number_unsigned | 4294967296..18446744073709551615           | Unsigned integer (8 bytes follow)  | 0x1B
+    number_float    | *any value representable by a float*       | Single-Precision Float             | 0xFA
+    number_float    | *any value NOT representable by a float*   | Double-Precision Float             | 0xFB
+    string          | *length*: 0..23                            | UTF-8 string                       | 0x60..0x77
+    string          | *length*: 23..255                          | UTF-8 string (1 byte follow)       | 0x78
+    string          | *length*: 256..65535                       | UTF-8 string (2 bytes follow)      | 0x79
+    string          | *length*: 65536..4294967295                | UTF-8 string (4 bytes follow)      | 0x7A
+    string          | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow)      | 0x7B
+    array           | *size*: 0..23                              | array                              | 0x80..0x97
+    array           | *size*: 23..255                            | array (1 byte follow)              | 0x98
+    array           | *size*: 256..65535                         | array (2 bytes follow)             | 0x99
+    array           | *size*: 65536..4294967295                  | array (4 bytes follow)             | 0x9A
+    array           | *size*: 4294967296..18446744073709551615   | array (8 bytes follow)             | 0x9B
+    object          | *size*: 0..23                              | map                                | 0xA0..0xB7
+    object          | *size*: 23..255                            | map (1 byte follow)                | 0xB8
+    object          | *size*: 256..65535                         | map (2 bytes follow)               | 0xB9
+    object          | *size*: 65536..4294967295                  | map (4 bytes follow)               | 0xBA
+    object          | *size*: 4294967296..18446744073709551615   | map (8 bytes follow)               | 0xBB
+    binary          | *size*: 0..23                              | byte string                        | 0x40..0x57
+    binary          | *size*: 23..255                            | byte string (1 byte follow)        | 0x58
+    binary          | *size*: 256..65535                         | byte string (2 bytes follow)       | 0x59
+    binary          | *size*: 65536..4294967295                  | byte string (4 bytes follow)       | 0x5A
+    binary          | *size*: 4294967296..18446744073709551615   | byte string (8 bytes follow)       | 0x5B
+
+    @note The mapping is **complete** in the sense that any JSON value type
+          can be converted to a CBOR value.
+
+    @note If NaN or Infinity are stored inside a JSON number, they are
+          serialized properly. This behavior differs from the @ref dump()
+          function which serializes NaN or Infinity to `null`.
+
+    @note The following CBOR types are not used in the conversion:
+          - UTF-8 strings terminated by "break" (0x7F)
+          - arrays terminated by "break" (0x9F)
+          - maps terminated by "break" (0xBF)
+          - byte strings terminated by "break" (0x5F)
+          - date/time (0xC0..0xC1)
+          - bignum (0xC2..0xC3)
+          - decimal fraction (0xC4)
+          - bigfloat (0xC5)
+          - expected conversions (0xD5..0xD7)
+          - simple values (0xE0..0xF3, 0xF8)
+          - undefined (0xF7)
+          - half-precision floats (0xF9)
+          - break (0xFF)
+
+    @param[in] j  JSON value to serialize
+    @return CBOR serialization as byte vector
+
+    @complexity Linear in the size of the JSON value @a j.
+
+    @liveexample{The example shows the serialization of a JSON value to a byte
+    vector in CBOR format.,to_cbor}
+
+    @sa http://cbor.io
+    @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t) for the
+        analogous deserialization
+    @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
+    @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
+             related UBJSON format
+
+    @since version 2.0.9; compact representation of floating-point numbers
+           since version 3.8.0
+    */
+    static std::vector<uint8_t> to_cbor(const basic_json& j)
+    {
+        std::vector<uint8_t> result;
+        to_cbor(j, result);
+        return result;
+    }
+
+    static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
+    {
+        binary_writer<uint8_t>(o).write_cbor(j);
+    }
+
+    static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
+    {
+        binary_writer<char>(o).write_cbor(j);
+    }
+
+    /*!
+    @brief create a MessagePack serialization of a given JSON value
+
+    Serializes a given JSON value @a j to a byte vector using the MessagePack
+    serialization format. MessagePack is a binary serialization format which
+    aims to be more compact than JSON itself, yet more efficient to parse.
+
+    The library uses the following mapping from JSON values types to
+    MessagePack types according to the MessagePack specification:
+
+    JSON value type | value/range                       | MessagePack type | first byte
+    --------------- | --------------------------------- | ---------------- | ----------
+    null            | `null`                            | nil              | 0xC0
+    boolean         | `true`                            | true             | 0xC3
+    boolean         | `false`                           | false            | 0xC2
+    number_integer  | -9223372036854775808..-2147483649 | int64            | 0xD3
+    number_integer  | -2147483648..-32769               | int32            | 0xD2
+    number_integer  | -32768..-129                      | int16            | 0xD1
+    number_integer  | -128..-33                         | int8             | 0xD0
+    number_integer  | -32..-1                           | negative fixint  | 0xE0..0xFF
+    number_integer  | 0..127                            | positive fixint  | 0x00..0x7F
+    number_integer  | 128..255                          | uint 8           | 0xCC
+    number_integer  | 256..65535                        | uint 16          | 0xCD
+    number_integer  | 65536..4294967295                 | uint 32          | 0xCE
+    number_integer  | 4294967296..18446744073709551615  | uint 64          | 0xCF
+    number_unsigned | 0..127                            | positive fixint  | 0x00..0x7F
+    number_unsigned | 128..255                          | uint 8           | 0xCC
+    number_unsigned | 256..65535                        | uint 16          | 0xCD
+    number_unsigned | 65536..4294967295                 | uint 32          | 0xCE
+    number_unsigned | 4294967296..18446744073709551615  | uint 64          | 0xCF
+    number_float    | *any value representable by a float*     | float 32 | 0xCA
+    number_float    | *any value NOT representable by a float* | float 64 | 0xCB
+    string          | *length*: 0..31                   | fixstr           | 0xA0..0xBF
+    string          | *length*: 32..255                 | str 8            | 0xD9
+    string          | *length*: 256..65535              | str 16           | 0xDA
+    string          | *length*: 65536..4294967295       | str 32           | 0xDB
+    array           | *size*: 0..15                     | fixarray         | 0x90..0x9F
+    array           | *size*: 16..65535                 | array 16         | 0xDC
+    array           | *size*: 65536..4294967295         | array 32         | 0xDD
+    object          | *size*: 0..15                     | fix map          | 0x80..0x8F
+    object          | *size*: 16..65535                 | map 16           | 0xDE
+    object          | *size*: 65536..4294967295         | map 32           | 0xDF
+    binary          | *size*: 0..255                    | bin 8            | 0xC4
+    binary          | *size*: 256..65535                | bin 16           | 0xC5
+    binary          | *size*: 65536..4294967295         | bin 32           | 0xC6
+
+    @note The mapping is **complete** in the sense that any JSON value type
+          can be converted to a MessagePack value.
+
+    @note The following values can **not** be converted to a MessagePack value:
+          - strings with more than 4294967295 bytes
+          - byte strings with more than 4294967295 bytes
+          - arrays with more than 4294967295 elements
+          - objects with more than 4294967295 elements
+
+    @note Any MessagePack output created @ref to_msgpack can be successfully
+          parsed by @ref from_msgpack.
+
+    @note If NaN or Infinity are stored inside a JSON number, they are
+          serialized properly. This behavior differs from the @ref dump()
+          function which serializes NaN or Infinity to `null`.
+
+    @param[in] j  JSON value to serialize
+    @return MessagePack serialization as byte vector
+
+    @complexity Linear in the size of the JSON value @a j.
+
+    @liveexample{The example shows the serialization of a JSON value to a byte
+    vector in MessagePack format.,to_msgpack}
+
+    @sa http://msgpack.org
+    @sa @ref from_msgpack for the analogous deserialization
+    @sa @ref to_cbor(const basic_json& for the related CBOR format
+    @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
+             related UBJSON format
+
+    @since version 2.0.9
+    */
+    static std::vector<uint8_t> to_msgpack(const basic_json& j)
+    {
+        std::vector<uint8_t> result;
+        to_msgpack(j, result);
+        return result;
+    }
+
+    static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
+    {
+        binary_writer<uint8_t>(o).write_msgpack(j);
+    }
+
+    static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
+    {
+        binary_writer<char>(o).write_msgpack(j);
+    }
+
+    /*!
+    @brief create a UBJSON serialization of a given JSON value
+
+    Serializes a given JSON value @a j to a byte vector using the UBJSON
+    (Universal Binary JSON) serialization format. UBJSON aims to be more compact
+    than JSON itself, yet more efficient to parse.
+
+    The library uses the following mapping from JSON values types to
+    UBJSON types according to the UBJSON specification:
+
+    JSON value type | value/range                       | UBJSON type | marker
+    --------------- | --------------------------------- | ----------- | ------
+    null            | `null`                            | null        | `Z`
+    boolean         | `true`                            | true        | `T`
+    boolean         | `false`                           | false       | `F`
+    number_integer  | -9223372036854775808..-2147483649 | int64       | `L`
+    number_integer  | -2147483648..-32769               | int32       | `l`
+    number_integer  | -32768..-129                      | int16       | `I`
+    number_integer  | -128..127                         | int8        | `i`
+    number_integer  | 128..255                          | uint8       | `U`
+    number_integer  | 256..32767                        | int16       | `I`
+    number_integer  | 32768..2147483647                 | int32       | `l`
+    number_integer  | 2147483648..9223372036854775807   | int64       | `L`
+    number_unsigned | 0..127                            | int8        | `i`
+    number_unsigned | 128..255                          | uint8       | `U`
+    number_unsigned | 256..32767                        | int16       | `I`
+    number_unsigned | 32768..2147483647                 | int32       | `l`
+    number_unsigned | 2147483648..9223372036854775807   | int64       | `L`
+    number_unsigned | 2147483649..18446744073709551615  | high-precision | `H`
+    number_float    | *any value*                       | float64     | `D`
+    string          | *with shortest length indicator*  | string      | `S`
+    array           | *see notes on optimized format*   | array       | `[`
+    object          | *see notes on optimized format*   | map         | `{`
+
+    @note The mapping is **complete** in the sense that any JSON value type
+          can be converted to a UBJSON value.
+
+    @note The following values can **not** be converted to a UBJSON value:
+          - strings with more than 9223372036854775807 bytes (theoretical)
+
+    @note The following markers are not used in the conversion:
+          - `Z`: no-op values are not created.
+          - `C`: single-byte strings are serialized with `S` markers.
+
+    @note Any UBJSON output created @ref to_ubjson can be successfully parsed
+          by @ref from_ubjson.
+
+    @note If NaN or Infinity are stored inside a JSON number, they are
+          serialized properly. This behavior differs from the @ref dump()
+          function which serializes NaN or Infinity to `null`.
+
+    @note The optimized formats for containers are supported: Parameter
+          @a use_size adds size information to the beginning of a container and
+          removes the closing marker. Parameter @a use_type further checks
+          whether all elements of a container have the same type and adds the
+          type marker to the beginning of the container. The @a use_type
+          parameter must only be used together with @a use_size = true. Note
+          that @a use_size = true alone may result in larger representations -
+          the benefit of this parameter is that the receiving side is
+          immediately informed on the number of elements of the container.
+
+    @note If the JSON data contains the binary type, the value stored is a list
+          of integers, as suggested by the UBJSON documentation.  In particular,
+          this means that serialization and the deserialization of a JSON
+          containing binary values into UBJSON and back will result in a
+          different JSON object.
+
+    @param[in] j  JSON value to serialize
+    @param[in] use_size  whether to add size annotations to container types
+    @param[in] use_type  whether to add type annotations to container types
+                         (must be combined with @a use_size = true)
+    @return UBJSON serialization as byte vector
+
+    @complexity Linear in the size of the JSON value @a j.
+
+    @liveexample{The example shows the serialization of a JSON value to a byte
+    vector in UBJSON format.,to_ubjson}
+
+    @sa http://ubjson.org
+    @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
+        analogous deserialization
+    @sa @ref to_cbor(const basic_json& for the related CBOR format
+    @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
+
+    @since version 3.1.0
+    */
+    static std::vector<uint8_t> to_ubjson(const basic_json& j,
+                                          const bool use_size = false,
+                                          const bool use_type = false)
+    {
+        std::vector<uint8_t> result;
+        to_ubjson(j, result, use_size, use_type);
+        return result;
+    }
+
+    static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
+                          const bool use_size = false, const bool use_type = false)
+    {
+        binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
+    }
+
+    static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
+                          const bool use_size = false, const bool use_type = false)
+    {
+        binary_writer<char>(o).write_ubjson(j, use_size, use_type);
+    }
+
+
+    /*!
+    @brief Serializes the given JSON object `j` to BSON and returns a vector
+           containing the corresponding BSON-representation.
+
+    BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are
+    stored as a single entity (a so-called document).
+
+    The library uses the following mapping from JSON values types to BSON types:
+
+    JSON value type | value/range                       | BSON type   | marker
+    --------------- | --------------------------------- | ----------- | ------
+    null            | `null`                            | null        | 0x0A
+    boolean         | `true`, `false`                   | boolean     | 0x08
+    number_integer  | -9223372036854775808..-2147483649 | int64       | 0x12
+    number_integer  | -2147483648..2147483647           | int32       | 0x10
+    number_integer  | 2147483648..9223372036854775807   | int64       | 0x12
+    number_unsigned | 0..2147483647                     | int32       | 0x10
+    number_unsigned | 2147483648..9223372036854775807   | int64       | 0x12
+    number_unsigned | 9223372036854775808..18446744073709551615| --   | --
+    number_float    | *any value*                       | double      | 0x01
+    string          | *any value*                       | string      | 0x02
+    array           | *any value*                       | document    | 0x04
+    object          | *any value*                       | document    | 0x03
+    binary          | *any value*                       | binary      | 0x05
+
+    @warning The mapping is **incomplete**, since only JSON-objects (and things
+    contained therein) can be serialized to BSON.
+    Also, integers larger than 9223372036854775807 cannot be serialized to BSON,
+    and the keys may not contain U+0000, since they are serialized a
+    zero-terminated c-strings.
+
+    @throw out_of_range.407  if `j.is_number_unsigned() && j.get<std::uint64_t>() > 9223372036854775807`
+    @throw out_of_range.409  if a key in `j` contains a NULL (U+0000)
+    @throw type_error.317    if `!j.is_object()`
+
+    @pre The input `j` is required to be an object: `j.is_object() == true`.
+
+    @note Any BSON output created via @ref to_bson can be successfully parsed
+          by @ref from_bson.
+
+    @param[in] j  JSON value to serialize
+    @return BSON serialization as byte vector
+
+    @complexity Linear in the size of the JSON value @a j.
+
+    @liveexample{The example shows the serialization of a JSON value to a byte
+    vector in BSON format.,to_bson}
+
+    @sa http://bsonspec.org/spec.html
+    @sa @ref from_bson(detail::input_adapter&&, const bool strict) for the
+        analogous deserialization
+    @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
+             related UBJSON format
+    @sa @ref to_cbor(const basic_json&) for the related CBOR format
+    @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
+    */
+    static std::vector<uint8_t> to_bson(const basic_json& j)
+    {
+        std::vector<uint8_t> result;
+        to_bson(j, result);
+        return result;
+    }
+
+    /*!
+    @brief Serializes the given JSON object `j` to BSON and forwards the
+           corresponding BSON-representation to the given output_adapter `o`.
+    @param j The JSON object to convert to BSON.
+    @param o The output adapter that receives the binary BSON representation.
+    @pre The input `j` shall be an object: `j.is_object() == true`
+    @sa @ref to_bson(const basic_json&)
+    */
+    static void to_bson(const basic_json& j, detail::output_adapter<uint8_t> o)
+    {
+        binary_writer<uint8_t>(o).write_bson(j);
+    }
+
+    /*!
+    @copydoc to_bson(const basic_json&, detail::output_adapter<uint8_t>)
+    */
+    static void to_bson(const basic_json& j, detail::output_adapter<char> o)
+    {
+        binary_writer<char>(o).write_bson(j);
+    }
+
+
+    /*!
+    @brief create a JSON value from an input in CBOR format
+
+    Deserializes a given input @a i to a JSON value using the CBOR (Concise
+    Binary Object Representation) serialization format.
+
+    The library maps CBOR types to JSON value types as follows:
+
+    CBOR type              | JSON value type | first byte
+    ---------------------- | --------------- | ----------
+    Integer                | number_unsigned | 0x00..0x17
+    Unsigned integer       | number_unsigned | 0x18
+    Unsigned integer       | number_unsigned | 0x19
+    Unsigned integer       | number_unsigned | 0x1A
+    Unsigned integer       | number_unsigned | 0x1B
+    Negative integer       | number_integer  | 0x20..0x37
+    Negative integer       | number_integer  | 0x38
+    Negative integer       | number_integer  | 0x39
+    Negative integer       | number_integer  | 0x3A
+    Negative integer       | number_integer  | 0x3B
+    Byte string            | binary          | 0x40..0x57
+    Byte string            | binary          | 0x58
+    Byte string            | binary          | 0x59
+    Byte string            | binary          | 0x5A
+    Byte string            | binary          | 0x5B
+    UTF-8 string           | string          | 0x60..0x77
+    UTF-8 string           | string          | 0x78
+    UTF-8 string           | string          | 0x79
+    UTF-8 string           | string          | 0x7A
+    UTF-8 string           | string          | 0x7B
+    UTF-8 string           | string          | 0x7F
+    array                  | array           | 0x80..0x97
+    array                  | array           | 0x98
+    array                  | array           | 0x99
+    array                  | array           | 0x9A
+    array                  | array           | 0x9B
+    array                  | array           | 0x9F
+    map                    | object          | 0xA0..0xB7
+    map                    | object          | 0xB8
+    map                    | object          | 0xB9
+    map                    | object          | 0xBA
+    map                    | object          | 0xBB
+    map                    | object          | 0xBF
+    False                  | `false`         | 0xF4
+    True                   | `true`          | 0xF5
+    Null                   | `null`          | 0xF6
+    Half-Precision Float   | number_float    | 0xF9
+    Single-Precision Float | number_float    | 0xFA
+    Double-Precision Float | number_float    | 0xFB
+
+    @warning The mapping is **incomplete** in the sense that not all CBOR
+             types can be converted to a JSON value. The following CBOR types
+             are not supported and will yield parse errors (parse_error.112):
+             - date/time (0xC0..0xC1)
+             - bignum (0xC2..0xC3)
+             - decimal fraction (0xC4)
+             - bigfloat (0xC5)
+             - expected conversions (0xD5..0xD7)
+             - simple values (0xE0..0xF3, 0xF8)
+             - undefined (0xF7)
+
+    @warning CBOR allows map keys of any type, whereas JSON only allows
+             strings as keys in object values. Therefore, CBOR maps with keys
+             other than UTF-8 strings are rejected (parse_error.113).
+
+    @note Any CBOR output created @ref to_cbor can be successfully parsed by
+          @ref from_cbor.
+
+    @param[in] i  an input in CBOR format convertible to an input adapter
+    @param[in] strict  whether to expect the input to be consumed until EOF
+                       (true by default)
+    @param[in] allow_exceptions  whether to throw exceptions in case of a
+    parse error (optional, true by default)
+    @param[in] tag_handler how to treat CBOR tags (optional, error by default)
+
+    @return deserialized JSON value; in case of a parse error and
+            @a allow_exceptions set to `false`, the return value will be
+            value_t::discarded.
+
+    @throw parse_error.110 if the given input ends prematurely or the end of
+    file was not reached when @a strict was set to true
+    @throw parse_error.112 if unsupported features from CBOR were
+    used in the given input @a v or if the input is not valid CBOR
+    @throw parse_error.113 if a string was expected as map key, but not found
+
+    @complexity Linear in the size of the input @a i.
+
+    @liveexample{The example shows the deserialization of a byte vector in CBOR
+    format to a JSON value.,from_cbor}
+
+    @sa http://cbor.io
+    @sa @ref to_cbor(const basic_json&) for the analogous serialization
+    @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for the
+        related MessagePack format
+    @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
+        related UBJSON format
+
+    @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
+           consume input adapters, removed start_index parameter, and added
+           @a strict parameter since 3.0.0; added @a allow_exceptions parameter
+           since 3.2.0; added @a tag_handler parameter since 3.9.0.
+    */
+    template<typename InputType>
+    JSON_HEDLEY_WARN_UNUSED_RESULT
+    static basic_json from_cbor(InputType&& i,
+                                const bool strict = true,
+                                const bool allow_exceptions = true,
+                                const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
+    {
+        basic_json result;
+        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
+        auto ia = detail::input_adapter(std::forward<InputType>(i));
+        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
+        return res ? result : basic_json(value_t::discarded);
+    }
+
+    /*!
+    @copydoc from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t)
+    */
+    template<typename IteratorType>
+    JSON_HEDLEY_WARN_UNUSED_RESULT
+    static basic_json from_cbor(IteratorType first, IteratorType last,
+                                const bool strict = true,
+                                const bool allow_exceptions = true,
+                                const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
+    {
+        basic_json result;
+        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
+        auto ia = detail::input_adapter(std::move(first), std::move(last));
+        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
+        return res ? result : basic_json(value_t::discarded);
+    }
+
+    template<typename T>
+    JSON_HEDLEY_WARN_UNUSED_RESULT
+    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
+    static basic_json from_cbor(const T* ptr, std::size_t len,
+                                const bool strict = true,
+                                const bool allow_exceptions = true,
+                                const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
+    {
+        return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
+    }
+
+
+    JSON_HEDLEY_WARN_UNUSED_RESULT
+    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
+    static basic_json from_cbor(detail::span_input_adapter&& i,
+                                const bool strict = true,
+                                const bool allow_exceptions = true,
+                                const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
+    {
+        basic_json result;
+        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
+        auto ia = i.get();
+        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
+        return res ? result : basic_json(value_t::discarded);
+    }
+
+    /*!
+    @brief create a JSON value from an input in MessagePack format
+
+    Deserializes a given input @a i to a JSON value using the MessagePack
+    serialization format.
+
+    The library maps MessagePack types to JSON value types as follows:
+
+    MessagePack type | JSON value type | first byte
+    ---------------- | --------------- | ----------
+    positive fixint  | number_unsigned | 0x00..0x7F
+    fixmap           | object          | 0x80..0x8F
+    fixarray         | array           | 0x90..0x9F
+    fixstr           | string          | 0xA0..0xBF
+    nil              | `null`          | 0xC0
+    false            | `false`         | 0xC2
+    true             | `true`          | 0xC3
+    float 32         | number_float    | 0xCA
+    float 64         | number_float    | 0xCB
+    uint 8           | number_unsigned | 0xCC
+    uint 16          | number_unsigned | 0xCD
+    uint 32          | number_unsigned | 0xCE
+    uint 64          | number_unsigned | 0xCF
+    int 8            | number_integer  | 0xD0
+    int 16           | number_integer  | 0xD1
+    int 32           | number_integer  | 0xD2
+    int 64           | number_integer  | 0xD3
+    str 8            | string          | 0xD9
+    str 16           | string          | 0xDA
+    str 32           | string          | 0xDB
+    array 16         | array           | 0xDC
+    array 32         | array           | 0xDD
+    map 16           | object          | 0xDE
+    map 32           | object          | 0xDF
+    bin 8            | binary          | 0xC4
+    bin 16           | binary          | 0xC5
+    bin 32           | binary          | 0xC6
+    ext 8            | binary          | 0xC7
+    ext 16           | binary          | 0xC8
+    ext 32           | binary          | 0xC9
+    fixext 1         | binary          | 0xD4
+    fixext 2         | binary          | 0xD5
+    fixext 4         | binary          | 0xD6
+    fixext 8         | binary          | 0xD7
+    fixext 16        | binary          | 0xD8
+    negative fixint  | number_integer  | 0xE0-0xFF
+
+    @note Any MessagePack output created @ref to_msgpack can be successfully
+          parsed by @ref from_msgpack.
+
+    @param[in] i  an input in MessagePack format convertible to an input
+                  adapter
+    @param[in] strict  whether to expect the input to be consumed until EOF
+                       (true by default)
+    @param[in] allow_exceptions  whether to throw exceptions in case of a
+    parse error (optional, true by default)
+
+    @return deserialized JSON value; in case of a parse error and
+            @a allow_exceptions set to `false`, the return value will be
+            value_t::discarded.
+
+    @throw parse_error.110 if the given input ends prematurely or the end of
+    file was not reached when @a strict was set to true
+    @throw parse_error.112 if unsupported features from MessagePack were
+    used in the given input @a i or if the input is not valid MessagePack
+    @throw parse_error.113 if a string was expected as map key, but not found
+
+    @complexity Linear in the size of the input @a i.
+
+    @liveexample{The example shows the deserialization of a byte vector in
+    MessagePack format to a JSON value.,from_msgpack}
+
+    @sa http://msgpack.org
+    @sa @ref to_msgpack(const basic_json&) for the analogous serialization
+    @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t) for the
+        related CBOR format
+    @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for
+        the related UBJSON format
+    @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for
+        the related BSON format
+
+    @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
+           consume input adapters, removed start_index parameter, and added
+           @a strict parameter since 3.0.0; added @a allow_exceptions parameter
+           since 3.2.0
+    */
+    template<typename InputType>
+    JSON_HEDLEY_WARN_UNUSED_RESULT
+    static basic_json from_msgpack(InputType&& i,
+                                   const bool strict = true,
+                                   const bool allow_exceptions = true)
+    {
+        basic_json result;
+        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
+        auto ia = detail::input_adapter(std::forward<InputType>(i));
+        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
+        return res ? result : basic_json(value_t::discarded);
+    }
+
+    /*!
+    @copydoc from_msgpack(detail::input_adapter&&, const bool, const bool)
+    */
+    template<typename IteratorType>
+    JSON_HEDLEY_WARN_UNUSED_RESULT
+    static basic_json from_msgpack(IteratorType first, IteratorType last,
+                                   const bool strict = true,
+                                   const bool allow_exceptions = true)
+    {
+        basic_json result;
+        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
+        auto ia = detail::input_adapter(std::move(first), std::move(last));
+        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
+        return res ? result : basic_json(value_t::discarded);
+    }
+
+
+    template<typename T>
+    JSON_HEDLEY_WARN_UNUSED_RESULT
+    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
+    static basic_json from_msgpack(const T* ptr, std::size_t len,
+                                   const bool strict = true,
+                                   const bool allow_exceptions = true)
+    {
+        return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
+    }
+
+    JSON_HEDLEY_WARN_UNUSED_RESULT
+    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
+    static basic_json from_msgpack(detail::span_input_adapter&& i,
+                                   const bool strict = true,
+                                   const bool allow_exceptions = true)
+    {
+        basic_json result;
+        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
+        auto ia = i.get();
+        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
+        return res ? result : basic_json(value_t::discarded);
+    }
+
+
+    /*!
+    @brief create a JSON value from an input in UBJSON format
+
+    Deserializes a given input @a i to a JSON value using the UBJSON (Universal
+    Binary JSON) serialization format.
+
+    The library maps UBJSON types to JSON value types as follows:
+
+    UBJSON type | JSON value type                         | marker
+    ----------- | --------------------------------------- | ------
+    no-op       | *no value, next value is read*          | `N`
+    null        | `null`                                  | `Z`
+    false       | `false`                                 | `F`
+    true        | `true`                                  | `T`
+    float32     | number_float                            | `d`
+    float64     | number_float                            | `D`
+    uint8       | number_unsigned                         | `U`
+    int8        | number_integer                          | `i`
+    int16       | number_integer                          | `I`
+    int32       | number_integer                          | `l`
+    int64       | number_integer                          | `L`
+    high-precision number | number_integer, number_unsigned, or number_float - depends on number string | 'H'
+    string      | string                                  | `S`
+    char        | string                                  | `C`
+    array       | array (optimized values are supported)  | `[`
+    object      | object (optimized values are supported) | `{`
+
+    @note The mapping is **complete** in the sense that any UBJSON value can
+          be converted to a JSON value.
+
+    @param[in] i  an input in UBJSON format convertible to an input adapter
+    @param[in] strict  whether to expect the input to be consumed until EOF
+                       (true by default)
+    @param[in] allow_exceptions  whether to throw exceptions in case of a
+    parse error (optional, true by default)
+
+    @return deserialized JSON value; in case of a parse error and
+            @a allow_exceptions set to `false`, the return value will be
+            value_t::discarded.
+
+    @throw parse_error.110 if the given input ends prematurely or the end of
+    file was not reached when @a strict was set to true
+    @throw parse_error.112 if a parse error occurs
+    @throw parse_error.113 if a string could not be parsed successfully
+
+    @complexity Linear in the size of the input @a i.
+
+    @liveexample{The example shows the deserialization of a byte vector in
+    UBJSON format to a JSON value.,from_ubjson}
+
+    @sa http://ubjson.org
+    @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
+             analogous serialization
+    @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t) for the
+        related CBOR format
+    @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for
+        the related MessagePack format
+    @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for
+        the related BSON format
+
+    @since version 3.1.0; added @a allow_exceptions parameter since 3.2.0
+    */
+    template<typename InputType>
+    JSON_HEDLEY_WARN_UNUSED_RESULT
+    static basic_json from_ubjson(InputType&& i,
+                                  const bool strict = true,
+                                  const bool allow_exceptions = true)
+    {
+        basic_json result;
+        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
+        auto ia = detail::input_adapter(std::forward<InputType>(i));
+        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
+        return res ? result : basic_json(value_t::discarded);
+    }
+
+    /*!
+    @copydoc from_ubjson(detail::input_adapter&&, const bool, const bool)
+    */
+    template<typename IteratorType>
+    JSON_HEDLEY_WARN_UNUSED_RESULT
+    static basic_json from_ubjson(IteratorType first, IteratorType last,
+                                  const bool strict = true,
+                                  const bool allow_exceptions = true)
+    {
+        basic_json result;
+        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
+        auto ia = detail::input_adapter(std::move(first), std::move(last));
+        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
+        return res ? result : basic_json(value_t::discarded);
+    }
+
+    template<typename T>
+    JSON_HEDLEY_WARN_UNUSED_RESULT
+    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
+    static basic_json from_ubjson(const T* ptr, std::size_t len,
+                                  const bool strict = true,
+                                  const bool allow_exceptions = true)
+    {
+        return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
+    }
+
+    JSON_HEDLEY_WARN_UNUSED_RESULT
+    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
+    static basic_json from_ubjson(detail::span_input_adapter&& i,
+                                  const bool strict = true,
+                                  const bool allow_exceptions = true)
+    {
+        basic_json result;
+        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
+        auto ia = i.get();
+        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
+        return res ? result : basic_json(value_t::discarded);
+    }
+
+
+    /*!
+    @brief Create a JSON value from an input in BSON format
+
+    Deserializes a given input @a i to a JSON value using the BSON (Binary JSON)
+    serialization format.
+
+    The library maps BSON record types to JSON value types as follows:
+
+    BSON type       | BSON marker byte | JSON value type
+    --------------- | ---------------- | ---------------------------
+    double          | 0x01             | number_float
+    string          | 0x02             | string
+    document        | 0x03             | object
+    array           | 0x04             | array
+    binary          | 0x05             | still unsupported
+    undefined       | 0x06             | still unsupported
+    ObjectId        | 0x07             | still unsupported
+    boolean         | 0x08             | boolean
+    UTC Date-Time   | 0x09             | still unsupported
+    null            | 0x0A             | null
+    Regular Expr.   | 0x0B             | still unsupported
+    DB Pointer      | 0x0C             | still unsupported
+    JavaScript Code | 0x0D             | still unsupported
+    Symbol          | 0x0E             | still unsupported
+    JavaScript Code | 0x0F             | still unsupported
+    int32           | 0x10             | number_integer
+    Timestamp       | 0x11             | still unsupported
+    128-bit decimal float | 0x13       | still unsupported
+    Max Key         | 0x7F             | still unsupported
+    Min Key         | 0xFF             | still unsupported
+
+    @warning The mapping is **incomplete**. The unsupported mappings
+             are indicated in the table above.
+
+    @param[in] i  an input in BSON format convertible to an input adapter
+    @param[in] strict  whether to expect the input to be consumed until EOF
+                       (true by default)
+    @param[in] allow_exceptions  whether to throw exceptions in case of a
+    parse error (optional, true by default)
+
+    @return deserialized JSON value; in case of a parse error and
+            @a allow_exceptions set to `false`, the return value will be
+            value_t::discarded.
+
+    @throw parse_error.114 if an unsupported BSON record type is encountered
+
+    @complexity Linear in the size of the input @a i.
+
+    @liveexample{The example shows the deserialization of a byte vector in
+    BSON format to a JSON value.,from_bson}
+
+    @sa http://bsonspec.org/spec.html
+    @sa @ref to_bson(const basic_json&) for the analogous serialization
+    @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t) for the
+        related CBOR format
+    @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for
+        the related MessagePack format
+    @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
+        related UBJSON format
+    */
+    template<typename InputType>
+    JSON_HEDLEY_WARN_UNUSED_RESULT
+    static basic_json from_bson(InputType&& i,
+                                const bool strict = true,
+                                const bool allow_exceptions = true)
+    {
+        basic_json result;
+        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
+        auto ia = detail::input_adapter(std::forward<InputType>(i));
+        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
+        return res ? result : basic_json(value_t::discarded);
+    }
+
+    /*!
+    @copydoc from_bson(detail::input_adapter&&, const bool, const bool)
+    */
+    template<typename IteratorType>
+    JSON_HEDLEY_WARN_UNUSED_RESULT
+    static basic_json from_bson(IteratorType first, IteratorType last,
+                                const bool strict = true,
+                                const bool allow_exceptions = true)
+    {
+        basic_json result;
+        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
+        auto ia = detail::input_adapter(std::move(first), std::move(last));
+        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
+        return res ? result : basic_json(value_t::discarded);
+    }
+
+    template<typename T>
+    JSON_HEDLEY_WARN_UNUSED_RESULT
+    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
+    static basic_json from_bson(const T* ptr, std::size_t len,
+                                const bool strict = true,
+                                const bool allow_exceptions = true)
+    {
+        return from_bson(ptr, ptr + len, strict, allow_exceptions);
+    }
+
+    JSON_HEDLEY_WARN_UNUSED_RESULT
+    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
+    static basic_json from_bson(detail::span_input_adapter&& i,
+                                const bool strict = true,
+                                const bool allow_exceptions = true)
+    {
+        basic_json result;
+        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
+        auto ia = i.get();
+        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
+        return res ? result : basic_json(value_t::discarded);
+    }
+    /// @}
+
+    //////////////////////////
+    // JSON Pointer support //
+    //////////////////////////
+
+    /// @name JSON Pointer functions
+    /// @{
+
+    /*!
+    @brief access specified element via JSON Pointer
+
+    Uses a JSON pointer to retrieve a reference to the respective JSON value.
+    No bound checking is performed. Similar to @ref operator[](const typename
+    object_t::key_type&), `null` values are created in arrays and objects if
+    necessary.
+
+    In particular:
+    - If the JSON pointer points to an object key that does not exist, it
+      is created an filled with a `null` value before a reference to it
+      is returned.
+    - If the JSON pointer points to an array index that does not exist, it
+      is created an filled with a `null` value before a reference to it
+      is returned. All indices between the current maximum and the given
+      index are also filled with `null`.
+    - The special value `-` is treated as a synonym for the index past the
+      end.
+
+    @param[in] ptr  a JSON pointer
+
+    @return reference to the element pointed to by @a ptr
+
+    @complexity Constant.
+
+    @throw parse_error.106   if an array index begins with '0'
+    @throw parse_error.109   if an array index was not a number
+    @throw out_of_range.404  if the JSON pointer can not be resolved
+
+    @liveexample{The behavior is shown in the example.,operatorjson_pointer}
+
+    @since version 2.0.0
+    */
+    reference operator[](const json_pointer& ptr)
+    {
+        return ptr.get_unchecked(this);
+    }
+
+    /*!
+    @brief access specified element via JSON Pointer
+
+    Uses a JSON pointer to retrieve a reference to the respective JSON value.
+    No bound checking is performed. The function does not change the JSON
+    value; no `null` values are created. In particular, the special value
+    `-` yields an exception.
+
+    @param[in] ptr  JSON pointer to the desired element
+
+    @return const reference to the element pointed to by @a ptr
+
+    @complexity Constant.
+
+    @throw parse_error.106   if an array index begins with '0'
+    @throw parse_error.109   if an array index was not a number
+    @throw out_of_range.402  if the array index '-' is used
+    @throw out_of_range.404  if the JSON pointer can not be resolved
+
+    @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
+
+    @since version 2.0.0
+    */
+    const_reference operator[](const json_pointer& ptr) const
+    {
+        return ptr.get_unchecked(this);
+    }
+
+    /*!
+    @brief access specified element via JSON Pointer
+
+    Returns a reference to the element at with specified JSON pointer @a ptr,
+    with bounds checking.
+
+    @param[in] ptr  JSON pointer to the desired element
+
+    @return reference to the element pointed to by @a ptr
+
+    @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
+    begins with '0'. See example below.
+
+    @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
+    is not a number. See example below.
+
+    @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
+    is out of range. See example below.
+
+    @throw out_of_range.402 if the array index '-' is used in the passed JSON
+    pointer @a ptr. As `at` provides checked access (and no elements are
+    implicitly inserted), the index '-' is always invalid. See example below.
+
+    @throw out_of_range.403 if the JSON pointer describes a key of an object
+    which cannot be found. See example below.
+
+    @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
+    See example below.
+
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes in the JSON value.
+
+    @complexity Constant.
+
+    @since version 2.0.0
+
+    @liveexample{The behavior is shown in the example.,at_json_pointer}
+    */
+    reference at(const json_pointer& ptr)
+    {
+        return ptr.get_checked(this);
+    }
+
+    /*!
+    @brief access specified element via JSON Pointer
+
+    Returns a const reference to the element at with specified JSON pointer @a
+    ptr, with bounds checking.
+
+    @param[in] ptr  JSON pointer to the desired element
+
+    @return reference to the element pointed to by @a ptr
+
+    @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
+    begins with '0'. See example below.
+
+    @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
+    is not a number. See example below.
+
+    @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
+    is out of range. See example below.
+
+    @throw out_of_range.402 if the array index '-' is used in the passed JSON
+    pointer @a ptr. As `at` provides checked access (and no elements are
+    implicitly inserted), the index '-' is always invalid. See example below.
+
+    @throw out_of_range.403 if the JSON pointer describes a key of an object
+    which cannot be found. See example below.
+
+    @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
+    See example below.
+
+    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+    changes in the JSON value.
+
+    @complexity Constant.
+
+    @since version 2.0.0
+
+    @liveexample{The behavior is shown in the example.,at_json_pointer_const}
+    */
+    const_reference at(const json_pointer& ptr) const
+    {
+        return ptr.get_checked(this);
+    }
+
+    /*!
+    @brief return flattened JSON value
+
+    The function creates a JSON object whose keys are JSON pointers (see [RFC
+    6901](https://tools.ietf.org/html/rfc6901)) and whose values are all
+    primitive. The original JSON value can be restored using the @ref
+    unflatten() function.
+
+    @return an object that maps JSON pointers to primitive values
+
+    @note Empty objects and arrays are flattened to `null` and will not be
+          reconstructed correctly by the @ref unflatten() function.
+
+    @complexity Linear in the size the JSON value.
+
+    @liveexample{The following code shows how a JSON object is flattened to an
+    object whose keys consist of JSON pointers.,flatten}
+
+    @sa @ref unflatten() for the reverse function
+
+    @since version 2.0.0
+    */
+    basic_json flatten() const
+    {
+        basic_json result(value_t::object);
+        json_pointer::flatten("", *this, result);
+        return result;
+    }
+
+    /*!
+    @brief unflatten a previously flattened JSON value
+
+    The function restores the arbitrary nesting of a JSON value that has been
+    flattened before using the @ref flatten() function. The JSON value must
+    meet certain constraints:
+    1. The value must be an object.
+    2. The keys must be JSON pointers (see
+       [RFC 6901](https://tools.ietf.org/html/rfc6901))
+    3. The mapped values must be primitive JSON types.
+
+    @return the original JSON from a flattened version
+
+    @note Empty objects and arrays are flattened by @ref flatten() to `null`
+          values and can not unflattened to their original type. Apart from
+          this example, for a JSON value `j`, the following is always true:
+          `j == j.flatten().unflatten()`.
+
+    @complexity Linear in the size the JSON value.
+
+    @throw type_error.314  if value is not an object
+    @throw type_error.315  if object values are not primitive
+
+    @liveexample{The following code shows how a flattened JSON object is
+    unflattened into the original nested JSON object.,unflatten}
+
+    @sa @ref flatten() for the reverse function
+
+    @since version 2.0.0
+    */
+    basic_json unflatten() const
+    {
+        return json_pointer::unflatten(*this);
+    }
+
+    /// @}
+
+    //////////////////////////
+    // JSON Patch functions //
+    //////////////////////////
+
+    /// @name JSON Patch functions
+    /// @{
+
+    /*!
+    @brief applies a JSON patch
+
+    [JSON Patch](http://jsonpatch.com) defines a JSON document structure for
+    expressing a sequence of operations to apply to a JSON) document. With
+    this function, a JSON Patch is applied to the current JSON value by
+    executing all operations from the patch.
+
+    @param[in] json_patch  JSON patch document
+    @return patched document
+
+    @note The application of a patch is atomic: Either all operations succeed
+          and the patched document is returned or an exception is thrown. In
+          any case, the original value is not changed: the patch is applied
+          to a copy of the value.
+
+    @throw parse_error.104 if the JSON patch does not consist of an array of
+    objects
+
+    @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory
+    attributes are missing); example: `"operation add must have member path"`
+
+    @throw out_of_range.401 if an array index is out of range.
+
+    @throw out_of_range.403 if a JSON pointer inside the patch could not be
+    resolved successfully in the current JSON value; example: `"key baz not
+    found"`
+
+    @throw out_of_range.405 if JSON pointer has no parent ("add", "remove",
+    "move")
+
+    @throw other_error.501 if "test" operation was unsuccessful
+
+    @complexity Linear in the size of the JSON value and the length of the
+    JSON patch. As usually only a fraction of the JSON value is affected by
+    the patch, the complexity can usually be neglected.
+
+    @liveexample{The following code shows how a JSON patch is applied to a
+    value.,patch}
+
+    @sa @ref diff -- create a JSON patch by comparing two JSON values
+
+    @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
+    @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
+
+    @since version 2.0.0
+    */
+    basic_json patch(const basic_json& json_patch) const
+    {
+        // make a working copy to apply the patch to
+        basic_json result = *this;
+
+        // the valid JSON Patch operations
+        enum class patch_operations {add, remove, replace, move, copy, test, invalid};
+
+        const auto get_op = [](const std::string & op)
+        {
+            if (op == "add")
+            {
+                return patch_operations::add;
+            }
+            if (op == "remove")
+            {
+                return patch_operations::remove;
+            }
+            if (op == "replace")
+            {
+                return patch_operations::replace;
+            }
+            if (op == "move")
+            {
+                return patch_operations::move;
+            }
+            if (op == "copy")
+            {
+                return patch_operations::copy;
+            }
+            if (op == "test")
+            {
+                return patch_operations::test;
+            }
+
+            return patch_operations::invalid;
+        };
+
+        // wrapper for "add" operation; add value at ptr
+        const auto operation_add = [&result](json_pointer & ptr, basic_json val)
+        {
+            // adding to the root of the target document means replacing it
+            if (ptr.empty())
+            {
+                result = val;
+                return;
+            }
+
+            // make sure the top element of the pointer exists
+            json_pointer top_pointer = ptr.top();
+            if (top_pointer != ptr)
+            {
+                result.at(top_pointer);
+            }
+
+            // get reference to parent of JSON pointer ptr
+            const auto last_path = ptr.back();
+            ptr.pop_back();
+            basic_json& parent = result[ptr];
+
+            switch (parent.m_type)
+            {
+                case value_t::null:
+                case value_t::object:
+                {
+                    // use operator[] to add value
+                    parent[last_path] = val;
+                    break;
+                }
+
+                case value_t::array:
+                {
+                    if (last_path == "-")
+                    {
+                        // special case: append to back
+                        parent.push_back(val);
+                    }
+                    else
+                    {
+                        const auto idx = json_pointer::array_index(last_path);
+                        if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
+                        {
+                            // avoid undefined behavior
+                            JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
+                        }
+
+                        // default case: insert add offset
+                        parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
+                    }
+                    break;
+                }
+
+                // if there exists a parent it cannot be primitive
+                default:            // LCOV_EXCL_LINE
+                    JSON_ASSERT(false);  // LCOV_EXCL_LINE
+            }
+        };
+
+        // wrapper for "remove" operation; remove value at ptr
+        const auto operation_remove = [&result](json_pointer & ptr)
+        {
+            // get reference to parent of JSON pointer ptr
+            const auto last_path = ptr.back();
+            ptr.pop_back();
+            basic_json& parent = result.at(ptr);
+
+            // remove child
+            if (parent.is_object())
+            {
+                // perform range check
+                auto it = parent.find(last_path);
+                if (JSON_HEDLEY_LIKELY(it != parent.end()))
+                {
+                    parent.erase(it);
+                }
+                else
+                {
+                    JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
+                }
+            }
+            else if (parent.is_array())
+            {
+                // note erase performs range check
+                parent.erase(json_pointer::array_index(last_path));
+            }
+        };
+
+        // type check: top level value must be an array
+        if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
+        {
+            JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
+        }
+
+        // iterate and apply the operations
+        for (const auto& val : json_patch)
+        {
+            // wrapper to get a value for an operation
+            const auto get_value = [&val](const std::string & op,
+                                          const std::string & member,
+                                          bool string_type) -> basic_json &
+            {
+                // find value
+                auto it = val.m_value.object->find(member);
+
+                // context-sensitive error message
+                const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
+
+                // check if desired value is present
+                if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
+                {
+                    JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
+                }
+
+                // check if result is of type string
+                if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
+                {
+                    JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
+                }
+
+                // no error: return value
+                return it->second;
+            };
+
+            // type check: every element of the array must be an object
+            if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
+            {
+                JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
+            }
+
+            // collect mandatory members
+            const auto op = get_value("op", "op", true).template get<std::string>();
+            const auto path = get_value(op, "path", true).template get<std::string>();
+            json_pointer ptr(path);
+
+            switch (get_op(op))
+            {
+                case patch_operations::add:
+                {
+                    operation_add(ptr, get_value("add", "value", false));
+                    break;
+                }
+
+                case patch_operations::remove:
+                {
+                    operation_remove(ptr);
+                    break;
+                }
+
+                case patch_operations::replace:
+                {
+                    // the "path" location must exist - use at()
+                    result.at(ptr) = get_value("replace", "value", false);
+                    break;
+                }
+
+                case patch_operations::move:
+                {
+                    const auto from_path = get_value("move", "from", true).template get<std::string>();
+                    json_pointer from_ptr(from_path);
+
+                    // the "from" location must exist - use at()
+                    basic_json v = result.at(from_ptr);
+
+                    // The move operation is functionally identical to a
+                    // "remove" operation on the "from" location, followed
+                    // immediately by an "add" operation at the target
+                    // location with the value that was just removed.
+                    operation_remove(from_ptr);
+                    operation_add(ptr, v);
+                    break;
+                }
+
+                case patch_operations::copy:
+                {
+                    const auto from_path = get_value("copy", "from", true).template get<std::string>();
+                    const json_pointer from_ptr(from_path);
+
+                    // the "from" location must exist - use at()
+                    basic_json v = result.at(from_ptr);
+
+                    // The copy is functionally identical to an "add"
+                    // operation at the target location using the value
+                    // specified in the "from" member.
+                    operation_add(ptr, v);
+                    break;
+                }
+
+                case patch_operations::test:
+                {
+                    bool success = false;
+                    JSON_TRY
+                    {
+                        // check if "value" matches the one at "path"
+                        // the "path" location must exist - use at()
+                        success = (result.at(ptr) == get_value("test", "value", false));
+                    }
+                    JSON_INTERNAL_CATCH (out_of_range&)
+                    {
+                        // ignore out of range errors: success remains false
+                    }
+
+                    // throw an exception if test fails
+                    if (JSON_HEDLEY_UNLIKELY(!success))
+                    {
+                        JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
+                    }
+
+                    break;
+                }
+
+                default:
+                {
+                    // op must be "add", "remove", "replace", "move", "copy", or
+                    // "test"
+                    JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
+                }
+            }
+        }
+
+        return result;
+    }
+
+    /*!
+    @brief creates a diff as a JSON patch
+
+    Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can
+    be changed into the value @a target by calling @ref patch function.
+
+    @invariant For two JSON values @a source and @a target, the following code
+    yields always `true`:
+    @code {.cpp}
+    source.patch(diff(source, target)) == target;
+    @endcode
+
+    @note Currently, only `remove`, `add`, and `replace` operations are
+          generated.
+
+    @param[in] source  JSON value to compare from
+    @param[in] target  JSON value to compare against
+    @param[in] path    helper value to create JSON pointers
+
+    @return a JSON patch to convert the @a source to @a target
+
+    @complexity Linear in the lengths of @a source and @a target.
+
+    @liveexample{The following code shows how a JSON patch is created as a
+    diff for two JSON values.,diff}
+
+    @sa @ref patch -- apply a JSON patch
+    @sa @ref merge_patch -- apply a JSON Merge Patch
+
+    @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
+
+    @since version 2.0.0
+    */
+    JSON_HEDLEY_WARN_UNUSED_RESULT
+    static basic_json diff(const basic_json& source, const basic_json& target,
+                           const std::string& path = "")
+    {
+        // the patch
+        basic_json result(value_t::array);
+
+        // if the values are the same, return empty patch
+        if (source == target)
+        {
+            return result;
+        }
+
+        if (source.type() != target.type())
+        {
+            // different types: replace value
+            result.push_back(
+            {
+                {"op", "replace"}, {"path", path}, {"value", target}
+            });
+            return result;
+        }
+
+        switch (source.type())
+        {
+            case value_t::array:
+            {
+                // first pass: traverse common elements
+                std::size_t i = 0;
+                while (i < source.size() && i < target.size())
+                {
+                    // recursive call to compare array values at index i
+                    auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
+                    result.insert(result.end(), temp_diff.begin(), temp_diff.end());
+                    ++i;
+                }
+
+                // i now reached the end of at least one array
+                // in a second pass, traverse the remaining elements
+
+                // remove my remaining elements
+                const auto end_index = static_cast<difference_type>(result.size());
+                while (i < source.size())
+                {
+                    // add operations in reverse order to avoid invalid
+                    // indices
+                    result.insert(result.begin() + end_index, object(
+                    {
+                        {"op", "remove"},
+                        {"path", path + "/" + std::to_string(i)}
+                    }));
+                    ++i;
+                }
+
+                // add other remaining elements
+                while (i < target.size())
+                {
+                    result.push_back(
+                    {
+                        {"op", "add"},
+                        {"path", path + "/-"},
+                        {"value", target[i]}
+                    });
+                    ++i;
+                }
+
+                break;
+            }
+
+            case value_t::object:
+            {
+                // first pass: traverse this object's elements
+                for (auto it = source.cbegin(); it != source.cend(); ++it)
+                {
+                    // escape the key name to be used in a JSON patch
+                    const auto key = json_pointer::escape(it.key());
+
+                    if (target.find(it.key()) != target.end())
+                    {
+                        // recursive call to compare object values at key it
+                        auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
+                        result.insert(result.end(), temp_diff.begin(), temp_diff.end());
+                    }
+                    else
+                    {
+                        // found a key that is not in o -> remove it
+                        result.push_back(object(
+                        {
+                            {"op", "remove"}, {"path", path + "/" + key}
+                        }));
+                    }
+                }
+
+                // second pass: traverse other object's elements
+                for (auto it = target.cbegin(); it != target.cend(); ++it)
+                {
+                    if (source.find(it.key()) == source.end())
+                    {
+                        // found a key that is not in this -> add it
+                        const auto key = json_pointer::escape(it.key());
+                        result.push_back(
+                        {
+                            {"op", "add"}, {"path", path + "/" + key},
+                            {"value", it.value()}
+                        });
+                    }
+                }
+
+                break;
+            }
+
+            default:
+            {
+                // both primitive type: replace value
+                result.push_back(
+                {
+                    {"op", "replace"}, {"path", path}, {"value", target}
+                });
+                break;
+            }
+        }
+
+        return result;
+    }
+
+    /// @}
+
+    ////////////////////////////////
+    // JSON Merge Patch functions //
+    ////////////////////////////////
+
+    /// @name JSON Merge Patch functions
+    /// @{
+
+    /*!
+    @brief applies a JSON Merge Patch
+
+    The merge patch format is primarily intended for use with the HTTP PATCH
+    method as a means of describing a set of modifications to a target
+    resource's content. This function applies a merge patch to the current
+    JSON value.
+
+    The function implements the following algorithm from Section 2 of
+    [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396):
+
+    ```
+    define MergePatch(Target, Patch):
+      if Patch is an Object:
+        if Target is not an Object:
+          Target = {} // Ignore the contents and set it to an empty Object
+        for each Name/Value pair in Patch:
+          if Value is null:
+            if Name exists in Target:
+              remove the Name/Value pair from Target
+          else:
+            Target[Name] = MergePatch(Target[Name], Value)
+        return Target
+      else:
+        return Patch
+    ```
+
+    Thereby, `Target` is the current object; that is, the patch is applied to
+    the current value.
+
+    @param[in] apply_patch  the patch to apply
+
+    @complexity Linear in the lengths of @a patch.
+
+    @liveexample{The following code shows how a JSON Merge Patch is applied to
+    a JSON document.,merge_patch}
+
+    @sa @ref patch -- apply a JSON patch
+    @sa [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396)
+
+    @since version 3.0.0
+    */
+    void merge_patch(const basic_json& apply_patch)
+    {
+        if (apply_patch.is_object())
+        {
+            if (!is_object())
+            {
+                *this = object();
+            }
+            for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
+            {
+                if (it.value().is_null())
+                {
+                    erase(it.key());
+                }
+                else
+                {
+                    operator[](it.key()).merge_patch(it.value());
+                }
+            }
+        }
+        else
+        {
+            *this = apply_patch;
+        }
+    }
+
+    /// @}
+};
+
+/*!
+@brief user-defined to_string function for JSON values
+
+This function implements a user-defined to_string  for JSON objects.
+
+@param[in] j  a JSON object
+@return a std::string object
+*/
+
+NLOHMANN_BASIC_JSON_TPL_DECLARATION
+std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
+{
+    return j.dump();
+}
+} // namespace nlohmann
+
+///////////////////////
+// nonmember support //
+///////////////////////
+
+// specialization of std::swap, and std::hash
+namespace std
+{
+
+/// hash value for JSON objects
+template<>
+struct hash<nlohmann::json>
+{
+    /*!
+    @brief return a hash value for a JSON object
+
+    @since version 1.0.0
+    */
+    std::size_t operator()(const nlohmann::json& j) const
+    {
+        return nlohmann::detail::hash(j);
+    }
+};
+
+/// specialization for std::less<value_t>
+/// @note: do not remove the space after '<',
+///        see https://github.com/nlohmann/json/pull/679
+template<>
+struct less<::nlohmann::detail::value_t>
+{
+    /*!
+    @brief compare two value_t enum values
+    @since version 3.0.0
+    */
+    bool operator()(nlohmann::detail::value_t lhs,
+                    nlohmann::detail::value_t rhs) const noexcept
+    {
+        return nlohmann::detail::operator<(lhs, rhs);
+    }
+};
+
+// C++20 prohibit function specialization in the std namespace.
+#ifndef JSON_HAS_CPP_20
+
+/*!
+@brief exchanges the values of two JSON objects
+
+@since version 1.0.0
+*/
+template<>
+inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
+    is_nothrow_move_constructible<nlohmann::json>::value&&
+    is_nothrow_move_assignable<nlohmann::json>::value
+                              )
+{
+    j1.swap(j2);
+}
+
+#endif
+
+} // namespace std
+
+/*!
+@brief user-defined string literal for JSON values
+
+This operator implements a user-defined string literal for JSON objects. It
+can be used by adding `"_json"` to a string literal and returns a JSON object
+if no parse error occurred.
+
+@param[in] s  a string representation of a JSON object
+@param[in] n  the length of string @a s
+@return a JSON object
+
+@since version 1.0.0
+*/
+JSON_HEDLEY_NON_NULL(1)
+inline nlohmann::json operator "" _json(const char* s, std::size_t n)
+{
+    return nlohmann::json::parse(s, s + n);
+}
+
+/*!
+@brief user-defined string literal for JSON pointer
+
+This operator implements a user-defined string literal for JSON Pointers. It
+can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer
+object if no parse error occurred.
+
+@param[in] s  a string representation of a JSON Pointer
+@param[in] n  the length of string @a s
+@return a JSON pointer object
+
+@since version 2.0.0
+*/
+JSON_HEDLEY_NON_NULL(1)
+inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
+{
+    return nlohmann::json::json_pointer(std::string(s, n));
+}
+
+// #include <nlohmann/detail/macro_unscope.hpp>
+
+
+// restore GCC/clang diagnostic settings
+#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
+    #pragma GCC diagnostic pop
+#endif
+#if defined(__clang__)
+    #pragma GCC diagnostic pop
+#endif
+
+// clean up
+#undef JSON_ASSERT
+#undef JSON_INTERNAL_CATCH
+#undef JSON_CATCH
+#undef JSON_THROW
+#undef JSON_TRY
+#undef JSON_HAS_CPP_14
+#undef JSON_HAS_CPP_17
+#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
+#undef NLOHMANN_BASIC_JSON_TPL
+#undef JSON_EXPLICIT
+
+// #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
+#undef JSON_HEDLEY_ALWAYS_INLINE
+#undef JSON_HEDLEY_ARM_VERSION
+#undef JSON_HEDLEY_ARM_VERSION_CHECK
+#undef JSON_HEDLEY_ARRAY_PARAM
+#undef JSON_HEDLEY_ASSUME
+#undef JSON_HEDLEY_BEGIN_C_DECLS
+#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
+#undef JSON_HEDLEY_CLANG_HAS_BUILTIN
+#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
+#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
+#undef JSON_HEDLEY_CLANG_HAS_EXTENSION
+#undef JSON_HEDLEY_CLANG_HAS_FEATURE
+#undef JSON_HEDLEY_CLANG_HAS_WARNING
+#undef JSON_HEDLEY_COMPCERT_VERSION
+#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
+#undef JSON_HEDLEY_CONCAT
+#undef JSON_HEDLEY_CONCAT3
+#undef JSON_HEDLEY_CONCAT3_EX
+#undef JSON_HEDLEY_CONCAT_EX
+#undef JSON_HEDLEY_CONST
+#undef JSON_HEDLEY_CONSTEXPR
+#undef JSON_HEDLEY_CONST_CAST
+#undef JSON_HEDLEY_CPP_CAST
+#undef JSON_HEDLEY_CRAY_VERSION
+#undef JSON_HEDLEY_CRAY_VERSION_CHECK
+#undef JSON_HEDLEY_C_DECL
+#undef JSON_HEDLEY_DEPRECATED
+#undef JSON_HEDLEY_DEPRECATED_FOR
+#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
+#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
+#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
+#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
+#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
+#undef JSON_HEDLEY_DIAGNOSTIC_POP
+#undef JSON_HEDLEY_DIAGNOSTIC_PUSH
+#undef JSON_HEDLEY_DMC_VERSION
+#undef JSON_HEDLEY_DMC_VERSION_CHECK
+#undef JSON_HEDLEY_EMPTY_BASES
+#undef JSON_HEDLEY_EMSCRIPTEN_VERSION
+#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
+#undef JSON_HEDLEY_END_C_DECLS
+#undef JSON_HEDLEY_FLAGS
+#undef JSON_HEDLEY_FLAGS_CAST
+#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
+#undef JSON_HEDLEY_GCC_HAS_BUILTIN
+#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
+#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
+#undef JSON_HEDLEY_GCC_HAS_EXTENSION
+#undef JSON_HEDLEY_GCC_HAS_FEATURE
+#undef JSON_HEDLEY_GCC_HAS_WARNING
+#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
+#undef JSON_HEDLEY_GCC_VERSION
+#undef JSON_HEDLEY_GCC_VERSION_CHECK
+#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
+#undef JSON_HEDLEY_GNUC_HAS_BUILTIN
+#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
+#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
+#undef JSON_HEDLEY_GNUC_HAS_EXTENSION
+#undef JSON_HEDLEY_GNUC_HAS_FEATURE
+#undef JSON_HEDLEY_GNUC_HAS_WARNING
+#undef JSON_HEDLEY_GNUC_VERSION
+#undef JSON_HEDLEY_GNUC_VERSION_CHECK
+#undef JSON_HEDLEY_HAS_ATTRIBUTE
+#undef JSON_HEDLEY_HAS_BUILTIN
+#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
+#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
+#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
+#undef JSON_HEDLEY_HAS_EXTENSION
+#undef JSON_HEDLEY_HAS_FEATURE
+#undef JSON_HEDLEY_HAS_WARNING
+#undef JSON_HEDLEY_IAR_VERSION
+#undef JSON_HEDLEY_IAR_VERSION_CHECK
+#undef JSON_HEDLEY_IBM_VERSION
+#undef JSON_HEDLEY_IBM_VERSION_CHECK
+#undef JSON_HEDLEY_IMPORT
+#undef JSON_HEDLEY_INLINE
+#undef JSON_HEDLEY_INTEL_VERSION
+#undef JSON_HEDLEY_INTEL_VERSION_CHECK
+#undef JSON_HEDLEY_IS_CONSTANT
+#undef JSON_HEDLEY_IS_CONSTEXPR_
+#undef JSON_HEDLEY_LIKELY
+#undef JSON_HEDLEY_MALLOC
+#undef JSON_HEDLEY_MESSAGE
+#undef JSON_HEDLEY_MSVC_VERSION
+#undef JSON_HEDLEY_MSVC_VERSION_CHECK
+#undef JSON_HEDLEY_NEVER_INLINE
+#undef JSON_HEDLEY_NON_NULL
+#undef JSON_HEDLEY_NO_ESCAPE
+#undef JSON_HEDLEY_NO_RETURN
+#undef JSON_HEDLEY_NO_THROW
+#undef JSON_HEDLEY_NULL
+#undef JSON_HEDLEY_PELLES_VERSION
+#undef JSON_HEDLEY_PELLES_VERSION_CHECK
+#undef JSON_HEDLEY_PGI_VERSION
+#undef JSON_HEDLEY_PGI_VERSION_CHECK
+#undef JSON_HEDLEY_PREDICT
+#undef JSON_HEDLEY_PRINTF_FORMAT
+#undef JSON_HEDLEY_PRIVATE
+#undef JSON_HEDLEY_PUBLIC
+#undef JSON_HEDLEY_PURE
+#undef JSON_HEDLEY_REINTERPRET_CAST
+#undef JSON_HEDLEY_REQUIRE
+#undef JSON_HEDLEY_REQUIRE_CONSTEXPR
+#undef JSON_HEDLEY_REQUIRE_MSG
+#undef JSON_HEDLEY_RESTRICT
+#undef JSON_HEDLEY_RETURNS_NON_NULL
+#undef JSON_HEDLEY_SENTINEL
+#undef JSON_HEDLEY_STATIC_ASSERT
+#undef JSON_HEDLEY_STATIC_CAST
+#undef JSON_HEDLEY_STRINGIFY
+#undef JSON_HEDLEY_STRINGIFY_EX
+#undef JSON_HEDLEY_SUNPRO_VERSION
+#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
+#undef JSON_HEDLEY_TINYC_VERSION
+#undef JSON_HEDLEY_TINYC_VERSION_CHECK
+#undef JSON_HEDLEY_TI_ARMCL_VERSION
+#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
+#undef JSON_HEDLEY_TI_CL2000_VERSION
+#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
+#undef JSON_HEDLEY_TI_CL430_VERSION
+#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
+#undef JSON_HEDLEY_TI_CL6X_VERSION
+#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
+#undef JSON_HEDLEY_TI_CL7X_VERSION
+#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
+#undef JSON_HEDLEY_TI_CLPRU_VERSION
+#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
+#undef JSON_HEDLEY_TI_VERSION
+#undef JSON_HEDLEY_TI_VERSION_CHECK
+#undef JSON_HEDLEY_UNAVAILABLE
+#undef JSON_HEDLEY_UNLIKELY
+#undef JSON_HEDLEY_UNPREDICTABLE
+#undef JSON_HEDLEY_UNREACHABLE
+#undef JSON_HEDLEY_UNREACHABLE_RETURN
+#undef JSON_HEDLEY_VERSION
+#undef JSON_HEDLEY_VERSION_DECODE_MAJOR
+#undef JSON_HEDLEY_VERSION_DECODE_MINOR
+#undef JSON_HEDLEY_VERSION_DECODE_REVISION
+#undef JSON_HEDLEY_VERSION_ENCODE
+#undef JSON_HEDLEY_WARNING
+#undef JSON_HEDLEY_WARN_UNUSED_RESULT
+#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
+#undef JSON_HEDLEY_FALL_THROUGH
+
+
+
+#endif  // INCLUDE_NLOHMANN_JSON_HPP_
diff --git a/src/libretro/FrameBufferLIBRETRO.cxx b/src/libretro/FBBackendLIBRETRO.cxx
similarity index 51%
rename from src/libretro/FrameBufferLIBRETRO.cxx
rename to src/libretro/FBBackendLIBRETRO.cxx
index 1c4235772..f7e4299de 100644
--- a/src/libretro/FrameBufferLIBRETRO.cxx
+++ b/src/libretro/FBBackendLIBRETRO.cxx
@@ -16,25 +16,13 @@
 //============================================================================
 
 #include "bspf.hxx"
-
-#include "OSystem.hxx"
-#include "AtariNTSC.hxx"
-#include "TIAConstants.hxx"
-
 #include "FBSurfaceLIBRETRO.hxx"
-#include "FrameBufferLIBRETRO.hxx"
+#include "FBBackendLIBRETRO.hxx"
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-FrameBufferLIBRETRO::FrameBufferLIBRETRO(OSystem& osystem)
-  : FrameBuffer(osystem),
-    myRenderSurface(nullptr)
-{
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void FrameBufferLIBRETRO::queryHardware(vector<Common::Size>& fullscreenRes,
-                                        vector<Common::Size>& windowedRes,
-                                        VariantList& renderers)
+void FBBackendLIBRETRO::queryHardware(vector<Common::Size>& fullscreenRes,
+                                      vector<Common::Size>& windowedRes,
+                                      VariantList& renderers)
 {
   fullscreenRes.emplace_back(1920, 1080);
   windowedRes.emplace_back(1920, 1080);
@@ -43,18 +31,8 @@ void FrameBufferLIBRETRO::queryHardware(vector<Common::Size>& fullscreenRes,
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-unique_ptr<FBSurface>
-    FrameBufferLIBRETRO::createSurface(uInt32 w, uInt32 h, FrameBuffer::ScalingInterpolation, const uInt32* data) const
+unique_ptr<FBSurface> FBBackendLIBRETRO::createSurface(
+    uInt32 w, uInt32 h, ScalingInterpolation, const uInt32*) const
 {
-  unique_ptr<FBSurface> ptr = make_unique<FBSurfaceLIBRETRO>
-      (const_cast<FrameBufferLIBRETRO&>(*this), w, h, data);
-
-  if(w == AtariNTSC::outWidth(TIAConstants::frameBufferWidth) &&
-     h == TIAConstants::frameBufferHeight)
-  {
-    uInt32 pitch;
-    ptr.get()->basePtr(myRenderSurface, pitch);
-  }
-
-  return ptr;
+  return make_unique<FBSurfaceLIBRETRO>(w, h);
 }
diff --git a/src/libretro/FBBackendLIBRETRO.hxx b/src/libretro/FBBackendLIBRETRO.hxx
new file mode 100644
index 000000000..7b1dc6b4a
--- /dev/null
+++ b/src/libretro/FBBackendLIBRETRO.hxx
@@ -0,0 +1,110 @@
+//============================================================================
+//
+//   SSSS    tt          lll  lll
+//  SS  SS   tt           ll   ll
+//  SS     tttttt  eeee   ll   ll   aaaa
+//   SSSS    tt   ee  ee  ll   ll      aa
+//      SS   tt   eeeeee  ll   ll   aaaaa  --  "An Atari 2600 VCS Emulator"
+//  SS  SS   tt   ee      ll   ll  aa  aa
+//   SSSS     ttt  eeeee llll llll  aaaaa
+//
+// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
+// and the Stella Team
+//
+// See the file "License.txt" for information on usage and redistribution of
+// this file, and for a DISCLAIMER OF ALL WARRANTIES.
+//============================================================================
+
+#ifndef FB_BACKEND_LIBRETRO_HXX
+#define FB_BACKEND_LIBRETRO_HXX
+
+class OSystem;
+
+#include "bspf.hxx"
+#include "FBBackend.hxx"
+
+/**
+  This class implements a standard LIBRETRO framebuffer backend.  Most of
+  the functionality is not used, since libretro has its own rendering system.
+
+  @author  Stephen Anthony
+*/
+class FBBackendLIBRETRO : public FBBackend
+{
+  public:
+    explicit FBBackendLIBRETRO(OSystem&) { }
+    ~FBBackendLIBRETRO() override { }
+
+  protected:
+    /**
+      This method is called to map a given R/G/B triple to the screen palette.
+
+      @param r  The red component of the color.
+      @param g  The green component of the color.
+      @param b  The blue component of the color.
+    */
+    uInt32 mapRGB(uInt8 r, uInt8 g, uInt8 b) const override {
+      return (r << 16) | (g << 8) | b;
+    }
+
+    /**
+      This method is called to query and initialize the video hardware
+      for desktop and fullscreen resolution information.  Since several
+      monitors may be attached, we need the resolution for all of them.
+
+      @param fullscreenRes  Maximum resolution supported in fullscreen mode
+      @param windowedRes    Maximum resolution supported in windowed mode
+      @param renderers      List of renderer names (internal name -> end-user name)
+    */
+    void queryHardware(vector<Common::Size>& fullscreenRes,
+                       vector<Common::Size>& windowedRes,
+                       VariantList& renderers) override;
+
+    /**
+      This method is called to create a surface with the given attributes.
+
+      @param w     The requested width of the new surface.
+      @param h     The requested height of the new surface.
+    */
+    unique_ptr<FBSurface>
+      createSurface(uInt32 w, uInt32 h, ScalingInterpolation,
+                    const uInt32*) const override;
+
+    /**
+      This method is called to provide information about the backend.
+    */
+    string about() const override { return "Video system: libretro"; }
+
+
+    //////////////////////////////////////////////////////////////////////
+    // Most methods here aren't used at all.  See FBBacked class for
+    // description, if needed.
+    //////////////////////////////////////////////////////////////////////
+
+    int scaleX(int x) const override { return x; }
+    int scaleY(int y) const override { return y; }
+    void setTitle(const string&) override { }
+    void showCursor(bool) override { }
+    bool fullScreen() const override { return true; }
+    void getRGB(uInt32, uInt8*, uInt8*, uInt8*) const override { }
+    void readPixels(uInt8*, uInt32, const Common::Rect&) const override { }
+    bool isCurrentWindowPositioned() const override { return true; }
+    Common::Point getCurrentWindowPos() const override { return Common::Point{}; }
+    Int32 getCurrentDisplayIndex() const override { return 0; }
+    void clear() override { }
+    bool setVideoMode(const VideoModeHandler::Mode&,
+                      int, const Common::Point&) override { return true; }
+    void grabMouse(bool) override { }
+    void renderToScreen() override { }
+    int refreshRate() const override { return 0; }
+
+  private:
+    // Following constructors and assignment operators not supported
+    FBBackendLIBRETRO() = delete;
+    FBBackendLIBRETRO(const FBBackendLIBRETRO&) = delete;
+    FBBackendLIBRETRO(FBBackendLIBRETRO&&) = delete;
+    FBBackendLIBRETRO& operator=(const FBBackendLIBRETRO&) = delete;
+    FBBackendLIBRETRO& operator=(FBBackendLIBRETRO&&) = delete;
+};
+
+#endif
diff --git a/src/libretro/FBSurfaceLIBRETRO.cxx b/src/libretro/FBSurfaceLIBRETRO.cxx
index 0857ee128..1f3d7e549 100644
--- a/src/libretro/FBSurfaceLIBRETRO.cxx
+++ b/src/libretro/FBSurfaceLIBRETRO.cxx
@@ -18,15 +18,7 @@
 #include "FBSurfaceLIBRETRO.hxx"
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-FBSurfaceLIBRETRO::FBSurfaceLIBRETRO(FrameBufferLIBRETRO&,
-                                     uInt32 width, uInt32 height, const uInt32* data)
-{
-  createSurface(width, height, data);
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void FBSurfaceLIBRETRO::createSurface(uInt32 width, uInt32 height,
-                                      const uInt32* data)
+FBSurfaceLIBRETRO::FBSurfaceLIBRETRO(uInt32 width, uInt32 height)
 {
   myWidth = width;
   myHeight = height;
@@ -39,9 +31,3 @@ void FBSurfaceLIBRETRO::createSurface(uInt32 width, uInt32 height,
   myPitch = width;
   ////////////////////////////////////////////////////
 }
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-bool FBSurfaceLIBRETRO::render()
-{
-  return true;
-}
diff --git a/src/libretro/FBSurfaceLIBRETRO.hxx b/src/libretro/FBSurfaceLIBRETRO.hxx
index 89809e011..f6bf3320b 100644
--- a/src/libretro/FBSurfaceLIBRETRO.hxx
+++ b/src/libretro/FBSurfaceLIBRETRO.hxx
@@ -20,23 +20,22 @@
 
 #include "bspf.hxx"
 #include "FBSurface.hxx"
-#include "FrameBufferLIBRETRO.hxx"
 
 /**
-  An FBSurface suitable for the LIBRETRO Render2D API, making use of hardware
-  acceleration behind the scenes.
+  An FBSurface suitable for the LIBRETRO API.  As with FBBackend,
+  most of the functionality here is handled by libretro directly.
 
   @author  Stephen Anthony
 */
 class FBSurfaceLIBRETRO : public FBSurface
 {
   public:
-    FBSurfaceLIBRETRO(FrameBufferLIBRETRO& buffer, uInt32 width, uInt32 height,
-                  const uInt32* data);
+    FBSurfaceLIBRETRO(uInt32 width, uInt32 height);
     ~FBSurfaceLIBRETRO() override { }
 
     // Most of the surface drawing primitives are implemented in FBSurface;
-    void fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, ColorId color) override { }
+    void fillRect(uInt32 x, uInt32 y, uInt32 w,
+                  uInt32 h, ColorId color) override { }
 
     uInt32 width() const override { return myWidth; }
     uInt32 height() const override { return myHeight; }
@@ -45,38 +44,37 @@ class FBSurfaceLIBRETRO : public FBSurface
     const Common::Rect& dstRect() const override { return myDstGUIR; }
     void setSrcPos(uInt32 x, uInt32 y) override { }
     void setSrcSize(uInt32 w, uInt32 h) override { }
+    void setSrcRect(const Common::Rect& r) override { }
     void setDstPos(uInt32 x, uInt32 y) override { }
     void setDstSize(uInt32 w, uInt32 h) override { }
+    void setDstRect(const Common::Rect& r) override { }
+
     void setVisible(bool visible) override { }
 
     void translateCoords(Int32& x, Int32& y) const override { }
-    bool render() override;
+    bool render() override { return true; }
     void invalidate() override { }
+    void invalidateRect(uInt32, uInt32, uInt32, uInt32) override { }
     void free() override { }
     void reload() override { }
     void resize(uInt32 width, uInt32 height) override { }
-    void setScalingInterpolation(FrameBuffer::ScalingInterpolation) override { }
+    void setScalingInterpolation(ScalingInterpolation) override { }
 
   protected:
     void applyAttributes() override { }
 
   private:
-    void createSurface(uInt32 width, uInt32 height, const uInt32* data);
+    unique_ptr<uInt32[]> myPixelData;
+    uInt32 myWidth, myHeight;
+    Common::Rect mySrcGUIR, myDstGUIR;
 
+  private:
     // Following constructors and assignment operators not supported
     FBSurfaceLIBRETRO() = delete;
     FBSurfaceLIBRETRO(const FBSurfaceLIBRETRO&) = delete;
     FBSurfaceLIBRETRO(FBSurfaceLIBRETRO&&) = delete;
     FBSurfaceLIBRETRO& operator=(const FBSurfaceLIBRETRO&) = delete;
     FBSurfaceLIBRETRO& operator=(FBSurfaceLIBRETRO&&) = delete;
-
-  private:
-    Common::Rect mySrcGUIR, myDstGUIR;
-
-  private:
-    unique_ptr<uInt32[]> myPixelData;
-
-    uInt32 myWidth, myHeight;
 };
 
 #endif
diff --git a/src/libretro/FrameBufferLIBRETRO.hxx b/src/libretro/FrameBufferLIBRETRO.hxx
deleted file mode 100644
index a57a218d2..000000000
--- a/src/libretro/FrameBufferLIBRETRO.hxx
+++ /dev/null
@@ -1,201 +0,0 @@
-//============================================================================
-//
-//   SSSS    tt          lll  lll
-//  SS  SS   tt           ll   ll
-//  SS     tttttt  eeee   ll   ll   aaaa
-//   SSSS    tt   ee  ee  ll   ll      aa
-//      SS   tt   eeeeee  ll   ll   aaaaa  --  "An Atari 2600 VCS Emulator"
-//  SS  SS   tt   ee      ll   ll  aa  aa
-//   SSSS     ttt  eeeee llll llll  aaaaa
-//
-// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
-// and the Stella Team
-//
-// See the file "License.txt" for information on usage and redistribution of
-// this file, and for a DISCLAIMER OF ALL WARRANTIES.
-//============================================================================
-
-#ifndef FRAMEBUFFER_LIBRETRO_HXX
-#define FRAMEBUFFER_LIBRETRO_HXX
-
-class OSystem;
-class FBSurfaceLIBRETRO;
-
-#include "bspf.hxx"
-#include "FrameBuffer.hxx"
-
-/**
-  This class implements a standard LIBRETRO 2D, hardware accelerated framebuffer.
-  Behind the scenes, it may be using Direct3D, OpenGL(ES), etc.
-
-  @author  Stephen Anthony
-*/
-class FrameBufferLIBRETRO : public FrameBuffer
-{
-  friend class FBSurfaceLIBRETRO;
-
-  public:
-    /**
-      Creates a new LIBRETRO framebuffer
-    */
-    explicit FrameBufferLIBRETRO(OSystem& osystem);
-    ~FrameBufferLIBRETRO() override { }
-
-    //////////////////////////////////////////////////////////////////////
-    // The following are derived from public methods in FrameBuffer.hxx
-    //////////////////////////////////////////////////////////////////////
-
-    /**
-      Updates window title.
-
-      @param title  The title of the application / window
-    */
-    void setTitle(const string& title) override { }
-
-    /**
-      Shows or hides the cursor based on the given boolean value.
-    */
-    void showCursor(bool show) override { }
-
-    /**
-      Answers if the display is currently in fullscreen mode.
-    */
-    bool fullScreen() const override { return true; }
-
-    /**
-      This method is called to retrieve the R/G/B data from the given pixel.
-
-      @param pixel  The pixel containing R/G/B data
-      @param r      The red component of the color
-      @param g      The green component of the color
-      @param b      The blue component of the color
-    */
-    inline void getRGB(uInt32 pixel, uInt8* r, uInt8* g, uInt8* b) const override { }
-
-    /**
-      This method is called to map a given R/G/B triple to the screen palette.
-
-      @param r  The red component of the color.
-      @param g  The green component of the color.
-      @param b  The blue component of the color.
-    */
-    inline uInt32 mapRGB(uInt8 r, uInt8 g, uInt8 b) const override { return (r << 16) | (g << 8) | b; }
-
-    /**
-      This method is called to get a copy of the specified ARGB data from the
-      viewable FrameBuffer area.  Note that this isn't the same as any
-      internal surfaces that may be in use; it should return the actual data
-      as it is currently seen onscreen.
-
-      @param buffer  A copy of the pixel data in ARGB8888 format
-      @param pitch   The pitch (in bytes) for the pixel data
-      @param rect    The bounding rectangle for the buffer
-    */
-    void readPixels(uInt8* buffer, uInt32 pitch, const Common::Rect& rect) const override { }
-
-    /**
-      Clear the frame buffer
-    */
-    void clear() override { }
-
-  protected:
-    //////////////////////////////////////////////////////////////////////
-    // The following are derived from protected methods in FrameBuffer.hxx
-    //////////////////////////////////////////////////////////////////////
-    /**
-      This method is called to query and initialize the video hardware
-      for desktop and fullscreen resolution information.  Since several
-      monitors may be attached, we need the resolution for all of them.
-
-      @param fullscreenRes  Maximum resolution supported in fullscreen mode
-      @param windowedRes    Maximum resolution supported in windowed mode
-      @param renderers      List of renderer names (internal name -> end-user name)
-    */
-    void queryHardware(vector<Common::Size>& fullscreenRes,
-                       vector<Common::Size>& windowedRes,
-                       VariantList& renderers) override;
-
-    /**
-      This method is called to query if the current window is not centered or fullscreen.
-
-      @return  True, if the current window is positioned
-    */
-    bool isCurrentWindowPositioned() const override { return true; }
-
-    /**
-      This method is called to query the video hardware for position of
-      the current window
-
-      @return  The position of the currently displayed window
-    */
-    Common::Point getCurrentWindowPos() const override { return Common::Point{}; }
-
-    /**
-      This method is called to query the video hardware for the index
-      of the display the current window is displayed on
-
-      @return  the current display index or a negative value if no
-               window is displayed
-    */
-    Int32 getCurrentDisplayIndex() const override { return 0; }
-
-    /**
-      This method is called to change to the given video mode.
-
-      @param title The title for the created window
-      @param mode  The video mode to use
-
-      @return  False on any errors, else true
-    */
-    bool setVideoMode(const string& title, const VideoMode& mode) override { return true; }
-
-    /**
-      This method is called to create a surface with the given attributes.
-
-      @param w     The requested width of the new surface.
-      @param h     The requested height of the new surface.
-      @param data  If non-null, use the given data values as a static surface
-    */
-    unique_ptr<FBSurface>
-        createSurface(uInt32 w, uInt32 h, FrameBuffer::ScalingInterpolation, const uInt32* data) const override;
-
-    /**
-      Grabs or ungrabs the mouse based on the given boolean value.
-    */
-    void grabMouse(bool grab) override { }
-
-    /**
-      Set the icon for the main SDL window.
-    */
-    void setWindowIcon() override { }
-
-    /**
-      This method is called to provide information about the FrameBuffer.
-    */
-    string about() const override { return "Video system: libretro"; }
-
-    /**
-      This method must be called after all drawing is done, and indicates
-      that the buffers should be pushed to the physical screen.
-    */
-    void renderToScreen() override { }
-
-  public:
-    /**
-      Returns a pointer to the output rendering buffer
-    */
-    uInt32* getRenderSurface() const { return myRenderSurface; }
-
-  private:
-    mutable uInt32* myRenderSurface;
-
-  private:
-    // Following constructors and assignment operators not supported
-    FrameBufferLIBRETRO() = delete;
-    FrameBufferLIBRETRO(const FrameBufferLIBRETRO&) = delete;
-    FrameBufferLIBRETRO(FrameBufferLIBRETRO&&) = delete;
-    FrameBufferLIBRETRO& operator=(const FrameBufferLIBRETRO&) = delete;
-    FrameBufferLIBRETRO& operator=(FrameBufferLIBRETRO&&) = delete;
-};
-
-#endif
diff --git a/src/libretro/Makefile b/src/libretro/Makefile
index 8d17db9db..6f8eb6599 100644
--- a/src/libretro/Makefile
+++ b/src/libretro/Makefile
@@ -43,7 +43,7 @@ TARGET_NAME = stella
 
 
 ifeq (,$(findstring msvc,$(platform)))
-   CXXFLAGS += -std=c++14 -fno-rtti
+   CXXFLAGS += -std=c++17 -fno-rtti
    LIBS := -lm
 else
    LIBS :=
@@ -282,8 +282,8 @@ else ifneq (,$(filter $(platform), ngc wii wiiu))
 else ifeq ($(platform), emscripten)
    TARGET := $(TARGET_NAME)_libretro_$(platform).bc
    STATIC_LINKING = 1
-   CXXFLAGS += $(PTHREAD_FLAGS) -std=c++14
-   LDFLAGS += $(PTHREAD_FLAGS) -std=c++14
+   CXXFLAGS += $(PTHREAD_FLAGS) -std=c++17
+   LDFLAGS += $(PTHREAD_FLAGS) -std=c++17
 
 # Genode
 else ifeq ($(platform), genode)
diff --git a/src/libretro/Makefile.common b/src/libretro/Makefile.common
index 994628725..e26399c7e 100644
--- a/src/libretro/Makefile.common
+++ b/src/libretro/Makefile.common
@@ -9,8 +9,8 @@ SOURCES_CXX := \
 	$(CORE_DIR)/libretro/libretro.cxx \
 	$(CORE_DIR)/libretro/EventHandlerLIBRETRO.cxx \
 	$(CORE_DIR)/libretro/FSNodeLIBRETRO.cxx \
+	$(CORE_DIR)/libretro/FBBackendLIBRETRO.cxx \
 	$(CORE_DIR)/libretro/FBSurfaceLIBRETRO.cxx \
-	$(CORE_DIR)/libretro/FrameBufferLIBRETRO.cxx \
 	$(CORE_DIR)/libretro/OSystemLIBRETRO.cxx \
 	$(CORE_DIR)/libretro/SoundLIBRETRO.cxx \
 	$(CORE_DIR)/libretro/StellaLIBRETRO.cxx \
@@ -33,6 +33,7 @@ SOURCES_CXX := \
 	$(CORE_DIR)/common/StaggeredLogger.cxx \
 	$(CORE_DIR)/common/StateManager.cxx \
 	$(CORE_DIR)/common/TimerManager.cxx \
+	$(CORE_DIR)/common/VideoModeHandler.cxx \
 	$(CORE_DIR)/common/tv_filters/AtariNTSC.cxx \
 	$(CORE_DIR)/common/tv_filters/NTSCFilter.cxx \
 	$(CORE_DIR)/emucore/AtariVox.cxx \
@@ -113,6 +114,7 @@ SOURCES_CXX := \
 	$(CORE_DIR)/emucore/PointingDevice.cxx \
 	$(CORE_DIR)/emucore/Props.cxx \
 	$(CORE_DIR)/emucore/PropsSet.cxx \
+	$(CORE_DIR)/emucore/QuadTari.cxx \
 	$(CORE_DIR)/emucore/SaveKey.cxx \
 	$(CORE_DIR)/emucore/Serializer.cxx \
 	$(CORE_DIR)/emucore/Settings.cxx \
diff --git a/src/libretro/SoundLIBRETRO.cxx b/src/libretro/SoundLIBRETRO.cxx
index eef9c7dd5..2c15ce04d 100644
--- a/src/libretro/SoundLIBRETRO.cxx
+++ b/src/libretro/SoundLIBRETRO.cxx
@@ -31,15 +31,10 @@
 #include "AudioQueue.hxx"
 #include "EmulationTiming.hxx"
 #include "AudioSettings.hxx"
-#include "StaggeredLogger.hxx"
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 SoundLIBRETRO::SoundLIBRETRO(OSystem& osystem, AudioSettings& audioSettings)
   : Sound(osystem),
-    myIsInitializedFlag(false),
-    myEmulationTiming(nullptr),
-    myCurrentFragment(nullptr),
-    myUnderrun(false),
     myAudioSettings(audioSettings)
 {
   Logger::debug("SoundLIBRETRO::SoundLIBRETRO started ...");
@@ -99,7 +94,6 @@ void SoundLIBRETRO::dequeue(Int16* stream, uInt32* samples)
 
     myCurrentFragment = nextFragment;
 
-
     for (uInt32 i = 0; i < myAudioQueue->fragmentSize(); ++i)
     {
       Int16 sampleL, sampleR;
@@ -120,9 +114,4 @@ void SoundLIBRETRO::dequeue(Int16* stream, uInt32* samples)
   *samples = outIndex / 2;
 }
 
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void SoundLIBRETRO::queryHardware(VariantList& devices)
-{
-}
-
 #endif  // SOUND_SUPPORT
diff --git a/src/libretro/SoundLIBRETRO.hxx b/src/libretro/SoundLIBRETRO.hxx
index 8bdb77fd3..b8da9566f 100644
--- a/src/libretro/SoundLIBRETRO.hxx
+++ b/src/libretro/SoundLIBRETRO.hxx
@@ -44,18 +44,12 @@ class SoundLIBRETRO : public Sound
     ~SoundLIBRETRO() override;
 
   public:
-    /**
-      Enables/disables the sound subsystem.
-
-      @param enable  Either true or false, to enable or disable the sound system
-    */
-    void setEnabled(bool enable) override { }
-
     /**
       Initializes the sound device.  This must be called before any
       calls are made to derived methods.
     */
-    void open(shared_ptr<AudioQueue> audioQueue, EmulationTiming* emulationTiming) override;
+    void open(shared_ptr<AudioQueue> audioQueue,
+              EmulationTiming* emulationTiming) override;
 
     /**
       Should be called to close the sound device.  Once called the sound
@@ -63,43 +57,6 @@ class SoundLIBRETRO : public Sound
     */
     void close() override;
 
-    /**
-      Set the mute state of the sound object.  While muted no sound is played.
-
-      @param state Mutes sound if true, unmute if false
-
-      @return  The previous (old) mute state
-    */
-    bool mute(bool state) override { return !myIsInitializedFlag; }
-
-    /**
-      Toggles the sound mute state.  While muted no sound is played.
-
-      @return  The previous (old) mute state
-    */
-    bool toggleMute() override { return !myIsInitializedFlag; }
-
-    /**
-      Sets the volume of the sound device to the specified level.  The
-      volume is given as a percentage from 0 to 100.  Values outside
-      this range indicate that the volume shouldn't be changed at all.
-
-      @param percent  The new volume percentage level for the sound device
-    */
-    void setVolume(uInt32 percent) override { }
-
-    /**
-      Adjusts the volume of the sound device based on the given direction.
-
-      @param direction  +1 indicates increase, -1 indicates decrease.
-    */
-    void adjustVolume(int direction = +1) override { }
-
-    /**
-      This method is called to provide information about the sound device.
-    */
-    string about() const override { return ""; }
-
     /**
       Empties the playback buffer.
 
@@ -109,23 +66,29 @@ class SoundLIBRETRO : public Sound
     void dequeue(Int16* stream, uInt32* samples);
 
   protected:
-    /**
-      This method is called to query the audio devices.
+    //////////////////////////////////////////////////////////////////////
+    // Most methods here aren't used at all.  See Sound class for
+    // description, if needed.
+    //////////////////////////////////////////////////////////////////////
 
-      @param devices  List of device names
-    */
-    void queryHardware(VariantList& devices) override;
+    void setEnabled(bool enable) override { }
+    void queryHardware(VariantList& devices) override { }
+    void setVolume(uInt32 percent) override { }
+    void adjustVolume(int direction = +1) override { }
+    bool mute(bool state) override { return !myIsInitializedFlag; }
+    bool toggleMute() override { return !myIsInitializedFlag; }
+    string about() const override { return ""; }
 
   private:
     // Indicates if the sound device was successfully initialized
-    bool myIsInitializedFlag;
+    bool myIsInitializedFlag{false};
 
     shared_ptr<AudioQueue> myAudioQueue;
 
-    EmulationTiming* myEmulationTiming;
+    EmulationTiming* myEmulationTiming{nullptr};
 
-    Int16* myCurrentFragment;
-    bool myUnderrun;
+    Int16* myCurrentFragment{nullptr};
+    bool myUnderrun{false};
 
     AudioSettings& myAudioSettings;
 
diff --git a/src/libretro/Stella.vcxproj b/src/libretro/Stella.vcxproj
index f92e5ea11..2d0a777db 100644
--- a/src/libretro/Stella.vcxproj
+++ b/src/libretro/Stella.vcxproj
@@ -140,8 +140,14 @@
     <ClCompile Include="..\common\JoyMap.cxx" />
     <ClCompile Include="..\common\KeyMap.cxx" />
     <ClCompile Include="..\common\Logger.cxx" />
+    <ClCompile Include="..\common\PaletteHandler.cxx" />
     <ClCompile Include="..\common\PhosphorHandler.cxx" />
+    <ClCompile Include="..\emucore\Cart3EX.cxx" />
+    <ClCompile Include="..\emucore\CartCreator.cxx" />
+    <ClCompile Include="..\emucore\CartEnhanced.cxx" />
     <ClCompile Include="..\emucore\CartFC.cxx" />
+    <ClCompile Include="..\emucore\CartTVBoy.cxx" />
+    <ClCompile Include="..\emucore\Lightgun.cxx" />
     <ClCompile Include="libretro.cxx" />
     <ClCompile Include="EventHandlerLIBRETRO.cxx" />
     <ClCompile Include="FBSurfaceLIBRETRO.cxx" />
@@ -174,8 +180,6 @@
     <ClCompile Include="..\emucore\CartCDF.cxx" />
     <ClCompile Include="..\emucore\CartCM.cxx" />
     <ClCompile Include="..\emucore\CartCTY.cxx" />
-    <ClCompile Include="..\emucore\CartCVPlus.cxx" />
-    <ClCompile Include="..\emucore\CartDASH.cxx" />
     <ClCompile Include="..\emucore\CartDetector.cxx" />
     <ClCompile Include="..\emucore\CartDF.cxx" />
     <ClCompile Include="..\emucore\CartDFSC.cxx" />
@@ -248,7 +252,6 @@
     <ClCompile Include="..\emucore\Joystick.cxx" />
     <ClCompile Include="..\emucore\Keyboard.cxx" />
     <ClCompile Include="..\emucore\KidVid.cxx" />
-    <ClCompile Include="..\emucore\Lighgun.cxx" />
     <ClCompile Include="..\emucore\M6502.cxx" />
     <ClCompile Include="..\emucore\M6532.cxx" />
     <ClCompile Include="..\emucore\MD5.cxx" />
@@ -276,6 +279,7 @@
     <ClInclude Include="..\common\Logger.hxx" />
     <ClInclude Include="..\common\MediaFactory.hxx" />
     <ClInclude Include="..\common\MouseControl.hxx" />
+    <ClInclude Include="..\common\PaletteHandler.hxx" />
     <ClInclude Include="..\common\PhosphorHandler.hxx" />
     <ClInclude Include="..\common\PhysicalJoystick.hxx" />
     <ClInclude Include="..\common\PJoystickHandler.hxx" />
@@ -296,23 +300,25 @@
     <ClInclude Include="..\emucore\Bankswitch.hxx" />
     <ClInclude Include="..\emucore\BSType.hxx" />
     <ClInclude Include="..\emucore\Cart3EPlus.hxx" />
+    <ClInclude Include="..\emucore\Cart3EX.hxx" />
     <ClInclude Include="..\emucore\Cart4KSC.hxx" />
     <ClInclude Include="..\emucore\CartBF.hxx" />
     <ClInclude Include="..\emucore\CartBFSC.hxx" />
     <ClInclude Include="..\emucore\CartBUS.hxx" />
     <ClInclude Include="..\emucore\CartCDF.hxx" />
     <ClInclude Include="..\emucore\CartCM.hxx" />
+    <ClInclude Include="..\emucore\CartCreator.hxx" />
     <ClInclude Include="..\emucore\CartCTY.hxx" />
-    <ClInclude Include="..\emucore\CartCVPlus.hxx" />
-    <ClInclude Include="..\emucore\CartDASH.hxx" />
     <ClInclude Include="..\emucore\CartDetector.hxx" />
     <ClInclude Include="..\emucore\CartDF.hxx" />
     <ClInclude Include="..\emucore\CartDFSC.hxx" />
+    <ClInclude Include="..\emucore\CartEnhanced.hxx" />
     <ClInclude Include="..\emucore\CartFA2.hxx" />
     <ClInclude Include="..\emucore\CartFC.hxx" />
     <ClInclude Include="..\emucore\CartMDM.hxx" />
     <ClInclude Include="..\emucore\CartMNetwork.hxx" />
     <ClInclude Include="..\emucore\CartE78K.hxx" />
+    <ClInclude Include="..\emucore\CartTVBoy.hxx" />
     <ClInclude Include="..\emucore\CartWD.hxx" />
     <ClInclude Include="..\emucore\CompuMate.hxx" />
     <ClInclude Include="..\emucore\ControllerDetector.hxx" />
@@ -325,6 +331,7 @@
     <ClInclude Include="..\emucore\exception\FatalEmulationError.hxx" />
     <ClInclude Include="..\emucore\FBSurface.hxx" />
     <ClInclude Include="..\emucore\FrameBufferConstants.hxx" />
+    <ClInclude Include="..\emucore\Lightgun.hxx" />
     <ClInclude Include="..\emucore\MindLink.hxx" />
     <ClInclude Include="..\emucore\PointingDevice.hxx" />
     <ClInclude Include="..\emucore\ProfilingRunner.hxx" />
diff --git a/src/libretro/StellaLIBRETRO.cxx b/src/libretro/StellaLIBRETRO.cxx
index 38e52e734..b80d517d9 100644
--- a/src/libretro/StellaLIBRETRO.cxx
+++ b/src/libretro/StellaLIBRETRO.cxx
@@ -18,10 +18,10 @@
 #include "bspf.hxx"
 #include "StellaLIBRETRO.hxx"
 #include "SoundLIBRETRO.hxx"
-#include "FrameBufferLIBRETRO.hxx"
+#include "FBBackendLIBRETRO.hxx"
+#include "FBSurfaceLIBRETRO.hxx"
 
 #include "AtariNTSC.hxx"
-#include "PaletteHandler.hxx"
 #include "AudioSettings.hxx"
 #include "Serializer.hxx"
 #include "StateManager.hxx"
@@ -33,27 +33,7 @@
 StellaLIBRETRO::StellaLIBRETRO()
 {
   audio_buffer = make_unique<Int16[]>(audio_buffer_max);
-
-  console_timing = ConsoleTiming::ntsc;
-  console_format = "AUTO";
-
-  video_aspect_ntsc = 0;
-  video_aspect_pal = 0;
-
-  video_palette = PaletteHandler::SETTING_STANDARD;
-  video_filter = NTSCFilter::Preset::OFF;
-  video_ready = false;
-
-  audio_samples = 0;
-  audio_mode = "byrom";
-
-  video_phosphor = "byrom";
-  video_phosphor_blend = 60;
-  phosphor_default = false;
-
   rom_image = make_unique<uInt8[]>(getROMMax());
-
-  system_ready = false;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -302,20 +282,22 @@ float StellaLIBRETRO::getVideoAspect() const
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void* StellaLIBRETRO::getVideoBuffer() const
 {
-  FrameBufferLIBRETRO& frame = static_cast<FrameBufferLIBRETRO&>(myOSystem->frameBuffer());
+  if (!render_surface)
+  {
+    const FBSurface& surface =
+        myOSystem->frameBuffer().tiaSurface().tiaSurface();
 
-  return static_cast<void*>(frame.getRenderSurface());
+    uInt32 pitch = 0;
+    surface.basePtr(render_surface, pitch);
+  }
+
+  return render_surface;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 bool StellaLIBRETRO::getVideoNTSC() const
 {
-  const ConsoleInfo& console_info = myOSystem->console().about();
-  string format = console_info.DisplayFormat;
-
-  return (format == "NTSC") || (format == "NTSC*") ||
-         (format == "PAL60") || (format == "PAL60*") ||
-         (format == "SECAM60") || (format == "SECAM60*");
+  return myOSystem->console().gameRefreshRate() == 60;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/libretro/StellaLIBRETRO.hxx b/src/libretro/StellaLIBRETRO.hxx
index 64bc91651..d4ae39c87 100644
--- a/src/libretro/StellaLIBRETRO.hxx
+++ b/src/libretro/StellaLIBRETRO.hxx
@@ -29,6 +29,7 @@
 #include "EventHandler.hxx"
 #include "M6532.hxx"
 #include "Paddles.hxx"
+#include "PaletteHandler.hxx"
 #include "System.hxx"
 #include "TIA.hxx"
 #include "TIASurface.hxx"
@@ -122,7 +123,7 @@ class StellaLIBRETRO
     void   setAudioStereo(int mode);
 
     void   setInputEvent(Event::Type type, Int32 state) {
-      myOSystem->eventHandler().handleEvent(type, state);
+             myOSystem->eventHandler().handleEvent(type, state);
     }
 
     Controller::Type getLeftControllerType() const {
@@ -153,39 +154,40 @@ class StellaLIBRETRO
     StellaLIBRETRO& operator=(StellaLIBRETRO&&) = delete;
 
     unique_ptr<OSystemLIBRETRO> myOSystem;
-    uInt32 system_ready;
+    uInt32 system_ready{false};
 
     ByteBuffer rom_image;
-    uInt32 rom_size;
+    uInt32 rom_size{0};
     string rom_path;
 
-    ConsoleTiming console_timing;
-    string console_format;
+    ConsoleTiming console_timing{ConsoleTiming::ntsc};
+    string console_format{"AUTO"};
 
-    uInt32 render_width, render_height;
+    mutable uInt32* render_surface{nullptr};
+    uInt32 render_width{0}, render_height{0};
 
-    bool video_ready;
+    bool video_ready{false};
 
     unique_ptr<Int16[]> audio_buffer;
-    uInt32 audio_samples;
-
-    // (31440 rate / 50 Hz) * 16-bit stereo * 1.25x padding
-    const uInt32 audio_buffer_max = (31440 / 50 * 4 * 5) / 4;
+    uInt32 audio_samples{0};
 
     uInt8 system_ram[128];
 
+    // (31440 rate / 50 Hz) * 16-bit stereo * 1.25x padding
+    static constexpr uInt32 audio_buffer_max = (31440 / 50 * 4 * 5) / 4;
+
   private:
-    string video_palette;
-    string video_phosphor;
-    uInt32 video_phosphor_blend;
+    string video_palette{PaletteHandler::SETTING_STANDARD};
+    string video_phosphor{"byrom"};
+    uInt32 video_phosphor_blend{60};
 
-    uInt32 video_aspect_ntsc;
-    uInt32 video_aspect_pal;
-    NTSCFilter::Preset video_filter;
+    uInt32 video_aspect_ntsc{0};
+    uInt32 video_aspect_pal{0};
+    NTSCFilter::Preset video_filter{NTSCFilter::Preset::OFF};
 
-    string audio_mode;
+    string audio_mode{"byrom"};
 
-    bool phosphor_default;
+    bool phosphor_default{false};
 };
 
 #endif
diff --git a/src/libretro/jni/Android.mk b/src/libretro/jni/Android.mk
index 3115baa53..644f983ae 100644
--- a/src/libretro/jni/Android.mk
+++ b/src/libretro/jni/Android.mk
@@ -14,6 +14,6 @@ endif
 include $(CLEAR_VARS)
 LOCAL_MODULE    := retro
 LOCAL_SRC_FILES := $(SOURCES_CXX) $(SOURCES_C)
-LOCAL_CXXFLAGS  := $(COREFLAGS) -std=c++14
+LOCAL_CXXFLAGS  := $(COREFLAGS) -std=c++17
 LOCAL_LDFLAGS   := -Wl,-version-script=$(CORE_DIR)/libretro/link.T
 include $(BUILD_SHARED_LIBRARY)
diff --git a/src/macos/Info-Stella.plist b/src/macos/Info-Stella.plist
index d9eb7520e..02d53466d 100644
--- a/src/macos/Info-Stella.plist
+++ b/src/macos/Info-Stella.plist
@@ -45,7 +45,7 @@
 	<key>CFBundleIdentifier</key>
 	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
 	<key>CFBundleInfoDictionaryVersion</key>
-	<string>6.2.1</string>
+	<string>6.4</string>
 	<key>CFBundleName</key>
 	<string>Stella</string>
 	<key>CFBundlePackageType</key>
@@ -53,7 +53,7 @@
 	<key>CFBundleSignature</key>
 	<string>StLa</string>
 	<key>CFBundleVersion</key>
-	<string>6.2.1</string>
+	<string>6.4</string>
 	<key>LSApplicationCategoryType</key>
 	<string>public.app-category.games</string>
 	<key>LSMinimumSystemVersionByArchitecture</key>
diff --git a/src/macos/SerialPortMACOS.cxx b/src/macos/SerialPortMACOS.cxx
index 3a4d2530b..85fba0032 100644
--- a/src/macos/SerialPortMACOS.cxx
+++ b/src/macos/SerialPortMACOS.cxx
@@ -25,6 +25,7 @@
 #include <sys/filio.h>
 #include <sys/ioctl.h>
 
+#include "FSNode.hxx"
 #include "SerialPortMACOS.hxx"
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -92,3 +93,34 @@ bool SerialPortMACOS::isCTS()
   }
   return false;
 }
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+StringList SerialPortMACOS::portNames()
+{
+  StringList ports;
+
+  // Check if port is valid; for now that means if it can be opened
+  // Eventually we may extend this to do more intensive checks
+  auto isPortValid = [](const string& port) {
+    int handle = open(port.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);
+    if(handle > 0)  close(handle);
+    return handle > 0;
+  };
+
+  // Get all possible devices in the '/dev' directory
+  FilesystemNode::NameFilter filter = [](const FilesystemNode& node) {
+    return BSPF::startsWithIgnoreCase(node.getPath(), "/dev/cu.usb");
+  };
+  FSList portList;
+  portList.reserve(5);
+
+  FilesystemNode dev("/dev/");
+  dev.getChildren(portList, FilesystemNode::ListMode::All, filter, false);
+
+  // Add only those that can be opened
+  for(const auto& port: portList)
+    if(isPortValid(port.getPath()))
+      ports.emplace_back(port.getPath());
+
+  return ports;
+}
diff --git a/src/macos/SerialPortMACOS.hxx b/src/macos/SerialPortMACOS.hxx
index 3fd9595d3..ea55ddc3d 100644
--- a/src/macos/SerialPortMACOS.hxx
+++ b/src/macos/SerialPortMACOS.hxx
@@ -21,8 +21,7 @@
 #include "SerialPort.hxx"
 
 /**
-  Implement reading and writing from a serial port under macOS.  For now,
-  reading isn't actually supported at all.
+  Implement reading and writing from a serial port under macOS.
 
   @author  Stephen Anthony & D. Spice
 */
@@ -56,12 +55,19 @@ class SerialPortMACOS : public SerialPort
     */
     bool writeByte(uInt8 data) override;
 
-  /**
-    Test for 'Clear To Send' enabled.
+    /**
+      Test for 'Clear To Send' enabled.
 
-    @return  True if CTS signal enabled, else false
-  */
-  bool isCTS() override;
+      @return  True if CTS signal enabled, else false
+    */
+    bool isCTS() override;
+
+    /**
+      Get all valid serial ports detected on this system.
+
+      @return  The (possibly empty) list of detected serial ports
+    */
+    StringList portNames() override;
 
   private:
     // File descriptor for serial connection
diff --git a/src/macos/stella.xcodeproj/project.pbxproj b/src/macos/stella.xcodeproj/project.pbxproj
index 44732af79..d0892bdce 100644
--- a/src/macos/stella.xcodeproj/project.pbxproj
+++ b/src/macos/stella.xcodeproj/project.pbxproj
@@ -228,6 +228,12 @@
 		DC21E5C021CA903E007D0E1A /* OSystemMACOS.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC21E5BA21CA903E007D0E1A /* OSystemMACOS.hxx */; };
 		DC21E5C121CA903E007D0E1A /* SerialPortMACOS.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC21E5BB21CA903E007D0E1A /* SerialPortMACOS.cxx */; };
 		DC21E5C221CA903E007D0E1A /* SerialPortMACOS.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC21E5BC21CA903E007D0E1A /* SerialPortMACOS.hxx */; };
+		DC22F12D2507D20800AB43E9 /* QuadTari.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC22F12B2507D20800AB43E9 /* QuadTari.hxx */; };
+		DC22F12E2507D20800AB43E9 /* QuadTari.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC22F12C2507D20800AB43E9 /* QuadTari.cxx */; };
+		DC22F1312507D22500AB43E9 /* QuadTariWidget.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC22F12F2507D22500AB43E9 /* QuadTariWidget.hxx */; };
+		DC22F1322507D22500AB43E9 /* QuadTariWidget.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC22F1302507D22500AB43E9 /* QuadTariWidget.cxx */; };
+		DC22F1352507D24E00AB43E9 /* QuadTariDialog.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC22F1332507D24D00AB43E9 /* QuadTariDialog.hxx */; };
+		DC22F1362507D24E00AB43E9 /* QuadTariDialog.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC22F1342507D24E00AB43E9 /* QuadTariDialog.cxx */; };
 		DC2410E32274BDA8007A4CBF /* MinUICommandDialog.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC2410E12274BDA7007A4CBF /* MinUICommandDialog.hxx */; };
 		DC2410E42274BDA8007A4CBF /* MinUICommandDialog.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC2410E22274BDA8007A4CBF /* MinUICommandDialog.cxx */; };
 		DC2874071F8F2278004BF21A /* TrapArray.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC2874061F8F2278004BF21A /* TrapArray.hxx */; };
@@ -240,8 +246,6 @@
 		DC2C5EDB1F8F2403007D2A09 /* smartmod.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC2C5EDA1F8F2403007D2A09 /* smartmod.hxx */; };
 		DC30924C212F74930020DAD0 /* TimerManager.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC30924A212F74930020DAD0 /* TimerManager.cxx */; };
 		DC30924D212F74930020DAD0 /* TimerManager.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC30924B212F74930020DAD0 /* TimerManager.hxx */; };
-		DC368F5618A2FB710084199C /* FrameBufferSDL2.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC368F5018A2FB710084199C /* FrameBufferSDL2.cxx */; };
-		DC368F5718A2FB710084199C /* FrameBufferSDL2.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC368F5118A2FB710084199C /* FrameBufferSDL2.hxx */; };
 		DC368F5818A2FB710084199C /* SoundSDL2.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC368F5218A2FB710084199C /* SoundSDL2.cxx */; };
 		DC368F5918A2FB710084199C /* SoundSDL2.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC368F5318A2FB710084199C /* SoundSDL2.hxx */; };
 		DC36D2C814CAFAB0007DC821 /* CartFA2.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC36D2C614CAFAB0007DC821 /* CartFA2.cxx */; };
@@ -511,7 +515,15 @@
 		DCB20EC71A0C506C0048F595 /* main.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCB20EC61A0C506C0048F595 /* main.cxx */; };
 		DCB2ECAF1F0AECA3009738A6 /* CartDetector.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCB2ECAC1F0AECA3009738A6 /* CartDetector.cxx */; };
 		DCB2ECB01F0AECA3009738A6 /* CartDetector.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCB2ECAD1F0AECA3009738A6 /* CartDetector.hxx */; };
+		DCB60AC92535E30600A5C1D2 /* VideoModeHandler.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCB60AC72535E30500A5C1D2 /* VideoModeHandler.cxx */; };
+		DCB60ACA2535E30600A5C1D2 /* VideoModeHandler.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCB60AC82535E30600A5C1D2 /* VideoModeHandler.hxx */; };
+		DCB60ACC25430FC600A5C1D2 /* FBBackend.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCB60ACB25430FC600A5C1D2 /* FBBackend.hxx */; };
+		DCB60AD02543100900A5C1D2 /* FBBackendSDL2.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCB60ACD2543100900A5C1D2 /* FBBackendSDL2.cxx */; };
+		DCB60AD12543100900A5C1D2 /* FBBackendSDL2.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCB60ACE2543100900A5C1D2 /* FBBackendSDL2.hxx */; };
+		DCB60AD22543100900A5C1D2 /* audio in Resources */ = {isa = PBXBuildFile; fileRef = DCB60ACF2543100900A5C1D2 /* audio */; };
 		DCB87E581A104C1E00BF2A3B /* MediaFactory.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCB87E571A104C1E00BF2A3B /* MediaFactory.hxx */; };
+		DCBA539925557E2800087DD7 /* UndoHandler.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCBA539725557E2700087DD7 /* UndoHandler.hxx */; };
+		DCBA539A25557E2800087DD7 /* UndoHandler.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCBA539825557E2800087DD7 /* UndoHandler.cxx */; };
 		DCBD31E82299ADB400567357 /* KeyMap.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCBD31E52299ADB400567357 /* KeyMap.hxx */; };
 		DCBD31E92299ADB400567357 /* Rect.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCBD31E62299ADB400567357 /* Rect.hxx */; };
 		DCBD31EA2299ADB400567357 /* KeyMap.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCBD31E72299ADB400567357 /* KeyMap.cxx */; };
@@ -519,6 +531,10 @@
 		DCBDDE9B1D6A5F0E009DF1E9 /* Cart3EPlusWidget.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCBDDE991D6A5F0E009DF1E9 /* Cart3EPlusWidget.hxx */; };
 		DCBDDE9E1D6A5F2F009DF1E9 /* Cart3EPlus.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCBDDE9C1D6A5F2F009DF1E9 /* Cart3EPlus.cxx */; };
 		DCBDDE9F1D6A5F2F009DF1E9 /* Cart3EPlus.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCBDDE9D1D6A5F2F009DF1E9 /* Cart3EPlus.hxx */; };
+		DCC2FDF5255EB82500FA5E81 /* ToolTip.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCC2FDF3255EB82500FA5E81 /* ToolTip.hxx */; };
+		DCC2FDF6255EB82500FA5E81 /* ToolTip.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCC2FDF4255EB82500FA5E81 /* ToolTip.cxx */; };
+		DCC2FDF92566AD8800FA5E81 /* DataGridRamWidget.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCC2FDF72566AD8800FA5E81 /* DataGridRamWidget.cxx */; };
+		DCC2FDFA2566AD8800FA5E81 /* DataGridRamWidget.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCC2FDF82566AD8800FA5E81 /* DataGridRamWidget.hxx */; };
 		DCC527D110B9DA19005E1287 /* Device.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCC527C910B9DA19005E1287 /* Device.hxx */; };
 		DCC527D210B9DA19005E1287 /* M6502.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCC527CA10B9DA19005E1287 /* M6502.cxx */; };
 		DCC527D310B9DA19005E1287 /* M6502.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCC527CB10B9DA19005E1287 /* M6502.hxx */; };
@@ -981,6 +997,12 @@
 		DC21E5BA21CA903E007D0E1A /* OSystemMACOS.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = OSystemMACOS.hxx; sourceTree = SOURCE_ROOT; };
 		DC21E5BB21CA903E007D0E1A /* SerialPortMACOS.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SerialPortMACOS.cxx; sourceTree = SOURCE_ROOT; };
 		DC21E5BC21CA903E007D0E1A /* SerialPortMACOS.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SerialPortMACOS.hxx; sourceTree = SOURCE_ROOT; };
+		DC22F12B2507D20800AB43E9 /* QuadTari.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = QuadTari.hxx; sourceTree = "<group>"; };
+		DC22F12C2507D20800AB43E9 /* QuadTari.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadTari.cxx; sourceTree = "<group>"; };
+		DC22F12F2507D22500AB43E9 /* QuadTariWidget.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = QuadTariWidget.hxx; sourceTree = "<group>"; };
+		DC22F1302507D22500AB43E9 /* QuadTariWidget.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadTariWidget.cxx; sourceTree = "<group>"; };
+		DC22F1332507D24D00AB43E9 /* QuadTariDialog.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = QuadTariDialog.hxx; sourceTree = "<group>"; };
+		DC22F1342507D24E00AB43E9 /* QuadTariDialog.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadTariDialog.cxx; sourceTree = "<group>"; };
 		DC2410E12274BDA7007A4CBF /* MinUICommandDialog.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = MinUICommandDialog.hxx; sourceTree = "<group>"; };
 		DC2410E22274BDA8007A4CBF /* MinUICommandDialog.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MinUICommandDialog.cxx; sourceTree = "<group>"; };
 		DC2874061F8F2278004BF21A /* TrapArray.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = TrapArray.hxx; sourceTree = "<group>"; };
@@ -993,8 +1015,6 @@
 		DC2C5EDA1F8F2403007D2A09 /* smartmod.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = smartmod.hxx; sourceTree = "<group>"; };
 		DC30924A212F74930020DAD0 /* TimerManager.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TimerManager.cxx; sourceTree = "<group>"; };
 		DC30924B212F74930020DAD0 /* TimerManager.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = TimerManager.hxx; sourceTree = "<group>"; };
-		DC368F5018A2FB710084199C /* FrameBufferSDL2.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FrameBufferSDL2.cxx; sourceTree = "<group>"; };
-		DC368F5118A2FB710084199C /* FrameBufferSDL2.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FrameBufferSDL2.hxx; sourceTree = "<group>"; };
 		DC368F5218A2FB710084199C /* SoundSDL2.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SoundSDL2.cxx; sourceTree = "<group>"; };
 		DC368F5318A2FB710084199C /* SoundSDL2.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SoundSDL2.hxx; sourceTree = "<group>"; };
 		DC36D2C614CAFAB0007DC821 /* CartFA2.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CartFA2.cxx; sourceTree = "<group>"; };
@@ -1265,7 +1285,15 @@
 		DCB20EC61A0C506C0048F595 /* main.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cxx; sourceTree = "<group>"; };
 		DCB2ECAC1F0AECA3009738A6 /* CartDetector.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CartDetector.cxx; sourceTree = "<group>"; };
 		DCB2ECAD1F0AECA3009738A6 /* CartDetector.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartDetector.hxx; sourceTree = "<group>"; };
+		DCB60AC72535E30500A5C1D2 /* VideoModeHandler.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VideoModeHandler.cxx; sourceTree = "<group>"; };
+		DCB60AC82535E30600A5C1D2 /* VideoModeHandler.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = VideoModeHandler.hxx; sourceTree = "<group>"; };
+		DCB60ACB25430FC600A5C1D2 /* FBBackend.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FBBackend.hxx; sourceTree = "<group>"; };
+		DCB60ACD2543100900A5C1D2 /* FBBackendSDL2.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FBBackendSDL2.cxx; sourceTree = "<group>"; };
+		DCB60ACE2543100900A5C1D2 /* FBBackendSDL2.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FBBackendSDL2.hxx; sourceTree = "<group>"; };
+		DCB60ACF2543100900A5C1D2 /* audio */ = {isa = PBXFileReference; lastKnownFileType = folder; path = audio; sourceTree = "<group>"; };
 		DCB87E571A104C1E00BF2A3B /* MediaFactory.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = MediaFactory.hxx; sourceTree = "<group>"; };
+		DCBA539725557E2700087DD7 /* UndoHandler.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = UndoHandler.hxx; sourceTree = "<group>"; };
+		DCBA539825557E2800087DD7 /* UndoHandler.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UndoHandler.cxx; sourceTree = "<group>"; };
 		DCBA710010DED62E0077193B /* Stella.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Stella.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		DCBD31E52299ADB400567357 /* KeyMap.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = KeyMap.hxx; sourceTree = "<group>"; };
 		DCBD31E62299ADB400567357 /* Rect.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Rect.hxx; sourceTree = "<group>"; };
@@ -1274,6 +1302,10 @@
 		DCBDDE991D6A5F0E009DF1E9 /* Cart3EPlusWidget.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Cart3EPlusWidget.hxx; sourceTree = "<group>"; };
 		DCBDDE9C1D6A5F2F009DF1E9 /* Cart3EPlus.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Cart3EPlus.cxx; sourceTree = "<group>"; };
 		DCBDDE9D1D6A5F2F009DF1E9 /* Cart3EPlus.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Cart3EPlus.hxx; sourceTree = "<group>"; };
+		DCC2FDF3255EB82500FA5E81 /* ToolTip.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ToolTip.hxx; sourceTree = "<group>"; };
+		DCC2FDF4255EB82500FA5E81 /* ToolTip.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ToolTip.cxx; sourceTree = "<group>"; };
+		DCC2FDF72566AD8800FA5E81 /* DataGridRamWidget.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DataGridRamWidget.cxx; sourceTree = "<group>"; };
+		DCC2FDF82566AD8800FA5E81 /* DataGridRamWidget.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = DataGridRamWidget.hxx; sourceTree = "<group>"; };
 		DCC527C910B9DA19005E1287 /* Device.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Device.hxx; sourceTree = "<group>"; };
 		DCC527CA10B9DA19005E1287 /* M6502.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = M6502.cxx; sourceTree = "<group>"; };
 		DCC527CB10B9DA19005E1287 /* M6502.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = M6502.hxx; sourceTree = "<group>"; };
@@ -1678,6 +1710,8 @@
 				2D20F9E708C603EC00A73076 /* CpuWidget.hxx */,
 				2D20F9E808C603EC00A73076 /* DataGridOpsWidget.cxx */,
 				2D20F9E908C603EC00A73076 /* DataGridOpsWidget.hxx */,
+				DCC2FDF72566AD8800FA5E81 /* DataGridRamWidget.cxx */,
+				DCC2FDF82566AD8800FA5E81 /* DataGridRamWidget.hxx */,
 				2D20F9EA08C603EC00A73076 /* DataGridWidget.cxx */,
 				2D20F9EB08C603EC00A73076 /* DataGridWidget.hxx */,
 				2D20F9EC08C603EC00A73076 /* DebuggerDialog.cxx */,
@@ -1701,6 +1735,8 @@
 				DC9616291F817830008A2206 /* PointingDeviceWidget.hxx */,
 				2D20F9EE08C603EC00A73076 /* PromptWidget.cxx */,
 				2D20F9EF08C603EC00A73076 /* PromptWidget.hxx */,
+				DC22F1302507D22500AB43E9 /* QuadTariWidget.cxx */,
+				DC22F12F2507D22500AB43E9 /* QuadTariWidget.hxx */,
 				2D20F9F008C603EC00A73076 /* RamWidget.cxx */,
 				2D20F9F108C603EC00A73076 /* RamWidget.hxx */,
 				DCE5CDE11BA10024005CD08A /* RiotRamWidget.cxx */,
@@ -1737,6 +1773,7 @@
 			isa = PBXGroup;
 			children = (
 				DCC6A4AD20A2620D00863C59 /* audio */,
+				DCB60ACF2543100900A5C1D2 /* audio */,
 				E09F413A201E901D004A3391 /* AudioQueue.cxx */,
 				E09F4139201E901C004A3391 /* AudioQueue.hxx */,
 				E0FABEEA20E9948100EB8E28 /* AudioSettings.cxx */,
@@ -1746,12 +1783,12 @@
 				DCC527D810B9DA6A005E1287 /* bspf.hxx */,
 				DCFF14CB18B0260300A20364 /* EventHandlerSDL2.cxx */,
 				DCFF14CC18B0260300A20364 /* EventHandlerSDL2.hxx */,
+				DCB60ACD2543100900A5C1D2 /* FBBackendSDL2.cxx */,
+				DCB60ACE2543100900A5C1D2 /* FBBackendSDL2.hxx */,
 				DC73BD831915E5B1003FAFAD /* FBSurfaceSDL2.cxx */,
 				DC73BD841915E5B1003FAFAD /* FBSurfaceSDL2.hxx */,
 				E007231D210FBF5D002CF343 /* FpsMeter.cxx */,
 				E007231C210FBF5C002CF343 /* FpsMeter.hxx */,
-				DC368F5018A2FB710084199C /* FrameBufferSDL2.cxx */,
-				DC368F5118A2FB710084199C /* FrameBufferSDL2.hxx */,
 				DCE395EA16CB0B5F008DB1E5 /* FSNodeFactory.hxx */,
 				DCE395EB16CB0B5F008DB1E5 /* FSNodeZIP.cxx */,
 				DCE395EC16CB0B5F008DB1E5 /* FSNodeZIP.hxx */,
@@ -1803,6 +1840,8 @@
 				DC7A24D4173B1CF600B20FE9 /* Variant.hxx */,
 				DCF490791A0ECE5B00A67AA9 /* Vec.hxx */,
 				DCF467BC0F9399F500B25D7A /* Version.hxx */,
+				DCB60AC72535E30500A5C1D2 /* VideoModeHandler.cxx */,
+				DCB60AC82535E30600A5C1D2 /* VideoModeHandler.hxx */,
 				DCE395ED16CB0B5F008DB1E5 /* ZipHandler.cxx */,
 				DCE395EE16CB0B5F008DB1E5 /* ZipHandler.hxx */,
 			);
@@ -1962,6 +2001,7 @@
 				2D733D6F062895B2006265D9 /* EventHandler.hxx */,
 				DC5AAC261FCB24AB00C420A6 /* EventHandlerConstants.hxx */,
 				DC6F394621B897AD00897AD8 /* exception */,
+				DCB60ACB25430FC600A5C1D2 /* FBBackend.hxx */,
 				DC73BD871915E5E3003FAFAD /* FBSurface.cxx */,
 				DC73BD881915E5E3003FAFAD /* FBSurface.hxx */,
 				2D733D70062895B2006265D9 /* FrameBuffer.cxx */,
@@ -2002,6 +2042,8 @@
 				2DE2DF850627AE34006BEC99 /* Props.hxx */,
 				2DE2DF860627AE34006BEC99 /* PropsSet.cxx */,
 				2DE2DF870627AE34006BEC99 /* PropsSet.hxx */,
+				DC22F12C2507D20800AB43E9 /* QuadTari.cxx */,
+				DC22F12B2507D20800AB43E9 /* QuadTari.hxx */,
 				2DE2DF890627AE34006BEC99 /* Random.hxx */,
 				DC4AC6F10DC8DAEF00CD3AD2 /* SaveKey.cxx */,
 				DC4AC6F20DC8DAEF00CD3AD2 /* SaveKey.hxx */,
@@ -2105,6 +2147,8 @@
 				2DDBEAC7084578BF00812C11 /* PopUpWidget.hxx */,
 				2DDBEAC8084578BF00812C11 /* ProgressDialog.cxx */,
 				2DDBEAC9084578BF00812C11 /* ProgressDialog.hxx */,
+				DC22F1342507D24E00AB43E9 /* QuadTariDialog.cxx */,
+				DC22F1332507D24D00AB43E9 /* QuadTariDialog.hxx */,
 				DC5AAC2A1FCB24DF00C420A6 /* RadioButtonWidget.cxx */,
 				DC5AAC2B1FCB24DF00C420A6 /* RadioButtonWidget.hxx */,
 				DC4613650D92C03600D8DAB9 /* RomAuditDialog.cxx */,
@@ -2133,8 +2177,12 @@
 				DCA82C6E1FEB4E780059340F /* TimeMachine.hxx */,
 				DCA82C6F1FEB4E780059340F /* TimeMachineDialog.cxx */,
 				DCA82C701FEB4E780059340F /* TimeMachineDialog.hxx */,
+				DCC2FDF4255EB82500FA5E81 /* ToolTip.cxx */,
+				DCC2FDF3255EB82500FA5E81 /* ToolTip.hxx */,
 				DC8078E60B4BD697005E9305 /* UIDialog.cxx */,
 				DC8078E70B4BD697005E9305 /* UIDialog.hxx */,
+				DCBA539825557E2800087DD7 /* UndoHandler.cxx */,
+				DCBA539725557E2700087DD7 /* UndoHandler.hxx */,
 				DC3C9BC72469C93D00CF2D47 /* VideoAudioDialog.cxx */,
 				DC3C9BC92469C93D00CF2D47 /* VideoAudioDialog.hxx */,
 				DC1E474C24D34F3A0047E61A /* WhatsNewDialog.cxx */,
@@ -2467,6 +2515,7 @@
 				DCE801E3236DC25600D43EDD /* CartFC.hxx in Headers */,
 				DC2AADB5194F390F0026C7A4 /* CartRamWidget.hxx in Headers */,
 				2D91740E09BA90380026E9FF /* ListWidget.hxx in Headers */,
+				DC22F1312507D22500AB43E9 /* QuadTariWidget.hxx in Headers */,
 				2D91740F09BA90380026E9FF /* Menu.hxx in Headers */,
 				2D91741009BA90380026E9FF /* OptionsDialog.hxx in Headers */,
 				DCEC58591E945125002F0246 /* DelayQueueWidget.hxx in Headers */,
@@ -2475,12 +2524,14 @@
 				2D91741209BA90380026E9FF /* ProgressDialog.hxx in Headers */,
 				2D91741309BA90380026E9FF /* ScrollBarWidget.hxx in Headers */,
 				2D91741609BA90380026E9FF /* TabWidget.hxx in Headers */,
+				DCB60ACC25430FC600A5C1D2 /* FBBackend.hxx in Headers */,
 				DCB2ECB01F0AECA3009738A6 /* CartDetector.hxx in Headers */,
 				2D91741809BA90380026E9FF /* Widget.hxx in Headers */,
 				2D91741909BA90380026E9FF /* CartUA.hxx in Headers */,
 				DCE8B1871E7E03B300189864 /* FrameLayout.hxx in Headers */,
 				DCA233B523BAB1300032ABF3 /* Lightgun.hxx in Headers */,
 				DCBD31E92299ADB400567357 /* Rect.hxx in Headers */,
+				DCBA539925557E2800087DD7 /* UndoHandler.hxx in Headers */,
 				2D91741A09BA90380026E9FF /* FSNode.hxx in Headers */,
 				2D91741B09BA90380026E9FF /* OSystem.hxx in Headers */,
 				DC6A18F919B3E65500DEB242 /* CartMDMWidget.hxx in Headers */,
@@ -2513,6 +2564,7 @@
 				2D91745109BA90380026E9FF /* StringListWidget.hxx in Headers */,
 				DC62E64A1960E87B007AEF05 /* SaveKeyWidget.hxx in Headers */,
 				2D91745209BA90380026E9FF /* CommandDialog.hxx in Headers */,
+				DC22F1352507D24E00AB43E9 /* QuadTariDialog.hxx in Headers */,
 				2D91745309BA90380026E9FF /* CommandMenu.hxx in Headers */,
 				E0306E111F93E916003DDD52 /* JitterEmulation.hxx in Headers */,
 				DC1E474F24D34F3B0047E61A /* WhatsNewDialog.hxx in Headers */,
@@ -2532,6 +2584,7 @@
 				E08FCD5823A037EB0051F59B /* QisBlitter.hxx in Headers */,
 				DCA078351F8C1B04008EFEE5 /* SDL_lib.hxx in Headers */,
 				DCDA03B11A2009BB00711920 /* CartWD.hxx in Headers */,
+				DCC2FDFA2566AD8800FA5E81 /* DataGridRamWidget.hxx in Headers */,
 				2D91745909BA90380026E9FF /* PromptWidget.hxx in Headers */,
 				DC3C9BC62469C8F700CF2D47 /* PaletteHandler.hxx in Headers */,
 				2D91745A09BA90380026E9FF /* RamWidget.hxx in Headers */,
@@ -2584,9 +2637,11 @@
 				DC173F770E2CAC1E00320F94 /* ContextMenu.hxx in Headers */,
 				DC0DF86A0F0DAAF500B0F1F3 /* GlobalPropsDialog.hxx in Headers */,
 				E0DCD3A920A64E96000B614E /* ConvolutionBuffer.hxx in Headers */,
+				DC22F12D2507D20800AB43E9 /* QuadTari.hxx in Headers */,
 				DC71EAA81FDA070D008827CB /* CartMNetworkWidget.hxx in Headers */,
 				DC5D2C530F117CFD004D1660 /* StellaFont.hxx in Headers */,
 				DC5D2C540F117CFD004D1660 /* StellaLargeFont.hxx in Headers */,
+				DCB60AD12543100900A5C1D2 /* FBBackendSDL2.hxx in Headers */,
 				DC5D2C550F117CFD004D1660 /* StellaMediumFont.hxx in Headers */,
 				DC3EE8681E2C0E6D00905161 /* inftrees.h in Headers */,
 				DC932D440F278A5200FEFEFC /* DefProps.hxx in Headers */,
@@ -2609,6 +2664,7 @@
 				DC5D1AA7102C6FC900E59AC1 /* Stack.hxx in Headers */,
 				DCF7B0DE10A762FC007A2870 /* CartF0.hxx in Headers */,
 				DCF7B0E010A762FC007A2870 /* CartFA.hxx in Headers */,
+				DCC2FDF5255EB82500FA5E81 /* ToolTip.hxx in Headers */,
 				DCC527D110B9DA19005E1287 /* Device.hxx in Headers */,
 				DC6F394E21B897F300897AD8 /* ThreadDebugging.hxx in Headers */,
 				DCC527D310B9DA19005E1287 /* M6502.hxx in Headers */,
@@ -2673,6 +2729,7 @@
 				DCAAE5D41715887B0080BB82 /* Cart2KWidget.hxx in Headers */,
 				DCF7F129223D796000701A47 /* ProfilingRunner.hxx in Headers */,
 				DCAAE5D61715887B0080BB82 /* Cart3FWidget.hxx in Headers */,
+				DCB60ACA2535E30600A5C1D2 /* VideoModeHandler.hxx in Headers */,
 				DCAAE5D81715887B0080BB82 /* Cart4KWidget.hxx in Headers */,
 				DCAAE5DA1715887B0080BB82 /* Cart0840Widget.hxx in Headers */,
 				DCAAE5DC1715887B0080BB82 /* CartCVWidget.hxx in Headers */,
@@ -2741,7 +2798,6 @@
 				DC96162D1F817830008A2206 /* AmigaMouseWidget.hxx in Headers */,
 				DCAACB17188D636F00A4D282 /* CartDFWidget.hxx in Headers */,
 				DCF3A6FF1DFC75E3008A8AF3 /* TIA.hxx in Headers */,
-				DC368F5718A2FB710084199C /* FrameBufferSDL2.hxx in Headers */,
 				DC368F5918A2FB710084199C /* SoundSDL2.hxx in Headers */,
 				DCF3A6F91DFC75E3008A8AF3 /* PaddleReader.hxx in Headers */,
 				DCFF14CE18B0260300A20364 /* EventHandlerSDL2.hxx in Headers */,
@@ -2820,6 +2876,7 @@
 				2D91747109BA90380026E9FF /* docs in Resources */,
 				2D91747209BA90380026E9FF /* AboutBox.nib in Resources */,
 				2DEFB40C09C3386F00754289 /* Cart.icns in Resources */,
+				DCB60AD22543100900A5C1D2 /* audio in Resources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2889,6 +2946,7 @@
 				2D91748C09BA90380026E9FF /* Driving.cxx in Sources */,
 				E0306E101F93E916003DDD52 /* FrameLayoutDetector.cxx in Sources */,
 				2D91748E09BA90380026E9FF /* Joystick.cxx in Sources */,
+				DCB60AC92535E30600A5C1D2 /* VideoModeHandler.cxx in Sources */,
 				2D91748F09BA90380026E9FF /* Keyboard.cxx in Sources */,
 				2D91749009BA90380026E9FF /* M6532.cxx in Sources */,
 				2D91749109BA90380026E9FF /* MD5.cxx in Sources */,
@@ -2972,6 +3030,7 @@
 				DC21E5C121CA903E007D0E1A /* SerialPortMACOS.cxx in Sources */,
 				E007231F210FBF5E002CF343 /* FpsMeter.cxx in Sources */,
 				2D9174FD09BA90380026E9FF /* RomListWidget.cxx in Sources */,
+				DC22F1362507D24E00AB43E9 /* QuadTariDialog.cxx in Sources */,
 				DCF3A6F81DFC75E3008A8AF3 /* PaddleReader.cxx in Sources */,
 				2D9174FE09BA90380026E9FF /* RomWidget.cxx in Sources */,
 				DCA82C731FEB4E780059340F /* TimeMachineDialog.cxx in Sources */,
@@ -3034,6 +3093,7 @@
 				DCF7B0DD10A762FC007A2870 /* CartF0.cxx in Sources */,
 				DCF7B0DF10A762FC007A2870 /* CartFA.cxx in Sources */,
 				DCC527D210B9DA19005E1287 /* M6502.cxx in Sources */,
+				DC22F12E2507D20800AB43E9 /* QuadTari.cxx in Sources */,
 				DC3EE86B1E2C0E6D00905161 /* uncompr.c in Sources */,
 				DCC527D610B9DA19005E1287 /* System.cxx in Sources */,
 				DC6B2BA411037FF200F199A7 /* CartDebug.cxx in Sources */,
@@ -3066,6 +3126,7 @@
 				DCD6FC7E11C281ED005DA767 /* pngtrans.c in Sources */,
 				DC6F394D21B897F300897AD8 /* ThreadDebugging.cxx in Sources */,
 				DCD6FC7F11C281ED005DA767 /* pngwio.c in Sources */,
+				DC22F1322507D22500AB43E9 /* QuadTariWidget.cxx in Sources */,
 				DCD6FC8011C281ED005DA767 /* pngwrite.c in Sources */,
 				DC3EE8621E2C0E6D00905161 /* inffast.c in Sources */,
 				DCD6FC8111C281ED005DA767 /* pngwtran.c in Sources */,
@@ -3126,6 +3187,7 @@
 				DCAAE5F01715887B0080BB82 /* CartFAWidget.cxx in Sources */,
 				DCAAE5F21715887B0080BB82 /* CartUAWidget.cxx in Sources */,
 				DC676A411729A0B000E4E73D /* Cart3EWidget.cxx in Sources */,
+				DCBA539A25557E2800087DD7 /* UndoHandler.cxx in Sources */,
 				DC676A431729A0B000E4E73D /* Cart4A50Widget.cxx in Sources */,
 				DC3EE85A1E2C0E6D00905161 /* deflate.c in Sources */,
 				DC676A451729A0B000E4E73D /* CartARWidget.cxx in Sources */,
@@ -3143,6 +3205,7 @@
 				DC676A591729A0B000E4E73D /* CartSBWidget.cxx in Sources */,
 				DC3C9BCC2469C93D00CF2D47 /* EmulationDialog.cxx in Sources */,
 				DC676A5B1729A0B000E4E73D /* CartX07Widget.cxx in Sources */,
+				DCC2FDF92566AD8800FA5E81 /* DataGridRamWidget.cxx in Sources */,
 				DC7A24DF173B1DBC00B20FE9 /* FileListWidget.cxx in Sources */,
 				DC13B53F176FF2F500B8B4BB /* RomListSettings.cxx in Sources */,
 				DC3EE8581E2C0E6D00905161 /* crc32.c in Sources */,
@@ -3155,11 +3218,12 @@
 				DCAACAFC188D631500A4D282 /* CartDF.cxx in Sources */,
 				DCAACAFE188D631500A4D282 /* CartDFSC.cxx in Sources */,
 				DCAACB0E188D636F00A4D282 /* Cart4KSCWidget.cxx in Sources */,
+				DCB60AD02543100900A5C1D2 /* FBBackendSDL2.cxx in Sources */,
 				DCAACB10188D636F00A4D282 /* CartBFSCWidget.cxx in Sources */,
+				DCC2FDF6255EB82500FA5E81 /* ToolTip.cxx in Sources */,
 				DCAACB12188D636F00A4D282 /* CartBFWidget.cxx in Sources */,
 				DCAACB14188D636F00A4D282 /* CartDFSCWidget.cxx in Sources */,
 				DCAACB16188D636F00A4D282 /* CartDFWidget.cxx in Sources */,
-				DC368F5618A2FB710084199C /* FrameBufferSDL2.cxx in Sources */,
 				DC368F5818A2FB710084199C /* SoundSDL2.cxx in Sources */,
 				DCFF14CD18B0260300A20364 /* EventHandlerSDL2.cxx in Sources */,
 				DC3EE8561E2C0E6D00905161 /* adler32.c in Sources */,
@@ -3341,7 +3405,7 @@
 					.,
 					"$(HOME)/Library/Frameworks",
 				);
-				GCC_ENABLE_CPP_RTTI = NO;
+				GCC_ENABLE_CPP_RTTI = YES;
 				GCC_NO_COMMON_BLOCKS = YES;
 				GCC_OPTIMIZATION_LEVEL = 0;
 				GCC_VERSION = "";
@@ -3416,7 +3480,7 @@
 					.,
 					"$(HOME)/Library/Frameworks",
 				);
-				GCC_ENABLE_CPP_RTTI = NO;
+				GCC_ENABLE_CPP_RTTI = YES;
 				GCC_NO_COMMON_BLOCKS = YES;
 				GCC_OPTIMIZATION_LEVEL = 3;
 				GCC_VERSION = "";
diff --git a/src/tools/PropSet.pm b/src/tools/PropSet.pm
index 0c40d7452..346f01e89 100755
--- a/src/tools/PropSet.pm
+++ b/src/tools/PropSet.pm
@@ -17,15 +17,19 @@ my %prop_type = (
   "Console.TVType"            => 11,
   "Console.SwapPorts"         => 12,
   "Controller.Left"           => 13,
-  "Controller.Right"          => 14,
-  "Controller.SwapPaddles"    => 15,
-  "Controller.PaddlesXCenter" => 16,
-  "Controller.PaddlesYCenter" => 17,
-  "Controller.MouseAxis"      => 18,
-  "Display.Format"            => 19,
-  "Display.VCenter"           => 20,
-  "Display.Phosphor"          => 21,
-  "Display.PPBlend"           => 22
+  "Controller.Left1"          => 14,
+  "Controller.Left2"          => 15,
+  "Controller.Right"          => 16,
+  "Controller.Right1"         => 17,
+  "Controller.Right2"         => 18,
+  "Controller.SwapPaddles"    => 19,
+  "Controller.PaddlesXCenter" => 20,
+  "Controller.PaddlesYCenter" => 21,
+  "Controller.MouseAxis"      => 22,
+  "Display.Format"            => 23,
+  "Display.VCenter"           => 24,
+  "Display.Phosphor"          => 25,
+  "Display.PPBlend"           => 26
 );
 my @prop_type_as_string = (
   "Cart.MD5",
@@ -42,7 +46,11 @@ my @prop_type_as_string = (
   "Console.TVType",
   "Console.SwapPorts",
   "Controller.Left",
+  "Controller.Left1",
+  "Controller.Left2",
   "Controller.Right",
+  "Controller.Right1",
+  "Controller.Right2",
   "Controller.SwapPaddles",
   "Controller.PaddlesXCenter",
   "Controller.PaddlesYCenter",
@@ -69,7 +77,13 @@ my @prop_defaults = (
   "NO",
   "",
   "",
+  "",
+  "",
+  "",
+  "",
   "NO",
+  "0",
+  "0",
   "AUTO",
   "AUTO",
   "0",
diff --git a/src/unix/SerialPortUNIX.cxx b/src/unix/SerialPortUNIX.cxx
index 7c39b3fb9..4ecc11a25 100644
--- a/src/unix/SerialPortUNIX.cxx
+++ b/src/unix/SerialPortUNIX.cxx
@@ -24,6 +24,7 @@
 #include <sys/ioctl.h>
 #include <cstring>
 
+#include "FSNode.hxx"
 #include "SerialPortUNIX.hxx"
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -95,3 +96,35 @@ bool SerialPortUNIX::isCTS()
   }
   return false;
 }
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+StringList SerialPortUNIX::portNames()
+{
+  StringList ports;
+
+  // Check if port is valid; for now that means if it can be opened
+  // Eventually we may extend this to do more intensive checks
+  auto isPortValid = [](const string& port) {
+    int handle = open(port.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);
+    if(handle > 0)  close(handle);
+    return handle > 0;
+  };
+
+  // Get all possible devices in the '/dev' directory
+  FilesystemNode::NameFilter filter = [](const FilesystemNode& node) {
+    return BSPF::startsWithIgnoreCase(node.getPath(), "/dev/ttyACM") ||
+           BSPF::startsWithIgnoreCase(node.getPath(), "/dev/ttyUSB");
+  };
+  FSList portList;
+  portList.reserve(5);
+
+  FilesystemNode dev("/dev/");
+  dev.getChildren(portList, FilesystemNode::ListMode::All, filter, false);
+
+  // Add only those that can be opened
+  for(const auto& port: portList)
+    if(isPortValid(port.getPath()))
+      ports.emplace_back(port.getPath());
+
+  return ports;
+}
diff --git a/src/unix/SerialPortUNIX.hxx b/src/unix/SerialPortUNIX.hxx
index dbf5f3299..640ee9b85 100644
--- a/src/unix/SerialPortUNIX.hxx
+++ b/src/unix/SerialPortUNIX.hxx
@@ -22,7 +22,7 @@
 
 /**
   Implement reading and writing from a serial port under UNIX.  For now,
-  it seems to be Linux-only, and reading isn't actually supported at all.
+  it seems to be Linux-only.
 
   @author  Stephen Anthony
 */
@@ -63,6 +63,13 @@ class SerialPortUNIX : public SerialPort
     */
     bool isCTS() override;
 
+    /**
+      Get all valid serial ports detected on this system.
+
+      @return  The (possibly empty) list of detected serial ports
+    */
+    StringList portNames() override;
+
   private:
     // File descriptor for serial connection
     int myHandle{0};
diff --git a/src/unix/stella.spec b/src/unix/stella.spec
index ad6819995..49be7f97b 100644
--- a/src/unix/stella.spec
+++ b/src/unix/stella.spec
@@ -1,5 +1,5 @@
 %define name    stella
-%define version 6.2.1
+%define version 6.4
 %define rel     1
 
 %define enable_sound 1
@@ -100,6 +100,12 @@ rm -rf $RPM_BUILD_DIR/%{name}-%{version}
 %_datadir/icons/large/%{name}.png
 
 %changelog
+* Mon Nov 2 2020 Stephen Anthony <sa666666@gmail.com> 6.4-1
+- Version 6.4 release
+
+* Wed Oct 7 2020 Stephen Anthony <sa666666@gmail.com> 6.3-1
+- Version 6.3 release
+
 * Sat Jun 20 2020 Stephen Anthony <sa666666@gmail.com> 6.2.1-1
 - Version 6.2.1 release
 
diff --git a/src/windows/FSNodeWINDOWS.cxx b/src/windows/FSNodeWINDOWS.cxx
index 0fecc3e1c..c8676e542 100644
--- a/src/windows/FSNodeWINDOWS.cxx
+++ b/src/windows/FSNodeWINDOWS.cxx
@@ -18,16 +18,8 @@
 #include <cassert>
 #pragma warning( disable : 4091 )
 #include <shlobj.h>
-
-#ifdef ARRAYSIZE
-  #undef ARRAYSIZE
-#endif
-
 #include <io.h>
 #include <stdio.h>
-#include <windows.h>
-// winnt.h defines ARRAYSIZE, but we want our own one...
-#undef ARRAYSIZE
 
 // F_OK, R_OK and W_OK are not defined under MSVC, so we define them here
 // For more information on the modes used by MSVC, check:
@@ -44,6 +36,7 @@
   #define W_OK 2
 #endif
 
+#include "Windows.hxx"
 #include "FSNodeWINDOWS.hxx"
 
 /**
diff --git a/src/windows/SerialPortWINDOWS.cxx b/src/windows/SerialPortWINDOWS.cxx
index 2772821d6..00154d0ea 100644
--- a/src/windows/SerialPortWINDOWS.cxx
+++ b/src/windows/SerialPortWINDOWS.cxx
@@ -15,8 +15,7 @@
 // this file, and for a DISCLAIMER OF ALL WARRANTIES.
 //============================================================================
 
-#include <windows.h>
-
+#include "Windows.hxx"
 #include "SerialPortWINDOWS.hxx"
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -28,22 +27,22 @@ SerialPortWINDOWS::SerialPortWINDOWS()
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 SerialPortWINDOWS::~SerialPortWINDOWS()
 {
-  if(myHandle)
+  if(myHandle != INVALID_HANDLE_VALUE)
   {
     CloseHandle(myHandle);
-    myHandle = 0;
+    myHandle = INVALID_HANDLE_VALUE;
   }
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 bool SerialPortWINDOWS::openPort(const string& device)
 {
-  if(!myHandle)
+  if(myHandle == INVALID_HANDLE_VALUE)
   {
     myHandle = CreateFile(device.c_str(), GENERIC_READ|GENERIC_WRITE, 0,
                           NULL, OPEN_EXISTING, 0, NULL);
 
-    if(myHandle)
+    if(myHandle != INVALID_HANDLE_VALUE)
     {
       DCB dcb;
 
@@ -52,7 +51,7 @@ bool SerialPortWINDOWS::openPort(const string& device)
       if(!BuildCommDCB("19200,n,8,1", &dcb))
       {
         CloseHandle(myHandle);
-        myHandle = 0;
+        myHandle = INVALID_HANDLE_VALUE;
         return false;
       }
 
@@ -80,7 +79,7 @@ bool SerialPortWINDOWS::openPort(const string& device)
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 bool SerialPortWINDOWS::readByte(uInt8& data)
 {
-  if(myHandle)
+  if(myHandle != INVALID_HANDLE_VALUE)
   {
     DWORD read;
     ReadFile(myHandle, &data, 1, &read, NULL);
@@ -92,7 +91,7 @@ bool SerialPortWINDOWS::readByte(uInt8& data)
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 bool SerialPortWINDOWS::writeByte(uInt8 data)
 {
-  if(myHandle)
+  if(myHandle != INVALID_HANDLE_VALUE)
   {
     DWORD written;
     WriteFile(myHandle, &data, 1, &written, NULL);
@@ -104,7 +103,7 @@ bool SerialPortWINDOWS::writeByte(uInt8 data)
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 bool SerialPortWINDOWS::isCTS()
 {
-  if(myHandle)
+  if(myHandle != INVALID_HANDLE_VALUE)
   {
     DWORD modemStat;
     GetCommModemStatus(myHandle, &modemStat);
@@ -112,3 +111,39 @@ bool SerialPortWINDOWS::isCTS()
   }
   return false;
 }
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+StringList SerialPortWINDOWS::portNames()
+{
+  StringList ports;
+
+  HKEY hKey = NULL;
+  LSTATUS result = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+    L"HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_READ, &hKey);
+  if (result == ERROR_SUCCESS)
+  {
+    TCHAR deviceName[2048], friendlyName[32];
+    DWORD numValues = 0;
+
+    result = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL,
+      &numValues, NULL, NULL, NULL, NULL);
+    if (result == ERROR_SUCCESS)
+    {
+      DWORD type = 0;
+      DWORD deviceNameLen = 2047;
+      DWORD friendlyNameLen = 31;
+
+      for (DWORD i = 0; i < numValues; ++i)
+      {
+        result = RegEnumValue(hKey, i, deviceName, &deviceNameLen,
+          NULL, &type, (LPBYTE)friendlyName, &friendlyNameLen);
+
+        if (result == ERROR_SUCCESS && type == REG_SZ)
+          ports.emplace_back(friendlyName);
+      }
+    }
+  }
+  RegCloseKey(hKey);
+
+  return ports;
+}
diff --git a/src/windows/SerialPortWINDOWS.hxx b/src/windows/SerialPortWINDOWS.hxx
index 9a7aec2e6..9a123440c 100644
--- a/src/windows/SerialPortWINDOWS.hxx
+++ b/src/windows/SerialPortWINDOWS.hxx
@@ -18,8 +18,7 @@
 #ifndef SERIALPORT_WINDOWS_HXX
 #define SERIALPORT_WINDOWS_HXX
 
-#include <windows.h>
-
+#include "Windows.hxx"
 #include "SerialPort.hxx"
 
 /**
@@ -63,9 +62,16 @@ class SerialPortWINDOWS : public SerialPort
     */
     bool isCTS() override;
 
+    /**
+      Get all valid serial ports detected on this system.
+
+      @return  The (possibly empty) list of detected serial ports
+    */
+    StringList portNames() override;
+
   private:
     // Handle to serial port
-    HANDLE myHandle{0};
+    HANDLE myHandle{INVALID_HANDLE_VALUE};
 
   private:
     // Following constructors and assignment operators not supported
diff --git a/src/windows/Stella.vcxproj b/src/windows/Stella.vcxproj
index b407d547a..d1cf96c6b 100644
--- a/src/windows/Stella.vcxproj
+++ b/src/windows/Stella.vcxproj
@@ -495,9 +495,9 @@
     <ClCompile Include="..\common\audio\SimpleResampler.cxx" />
     <ClCompile Include="..\common\Base.cxx" />
     <ClCompile Include="..\common\EventHandlerSDL2.cxx" />
+    <ClCompile Include="..\common\FBBackendSDL2.cxx" />
     <ClCompile Include="..\common\FBSurfaceSDL2.cxx" />
     <ClCompile Include="..\common\FpsMeter.cxx" />
-    <ClCompile Include="..\common\FrameBufferSDL2.cxx" />
     <ClCompile Include="..\common\FSNodeZIP.cxx" />
     <ClCompile Include="..\common\JoyMap.cxx" />
     <ClCompile Include="..\common\KeyMap.cxx" />
@@ -520,6 +520,7 @@
     <ClCompile Include="..\common\TimerManager.cxx" />
     <ClCompile Include="..\common\tv_filters\AtariNTSC.cxx" />
     <ClCompile Include="..\common\tv_filters\NTSCFilter.cxx" />
+    <ClCompile Include="..\common\VideoModeHandler.cxx" />
     <ClCompile Include="..\common\ZipHandler.cxx" />
     <ClCompile Include="..\debugger\BreakpointMap.cxx">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
@@ -620,7 +621,9 @@
     <ClCompile Include="..\debugger\gui\CartEFWidget.cxx">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
     </ClCompile>
-    <ClCompile Include="..\debugger\gui\CartEnhancedWidget.cxx" />
+    <ClCompile Include="..\debugger\gui\CartEnhancedWidget.cxx">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="..\debugger\gui\CartF0Widget.cxx">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
     </ClCompile>
@@ -678,6 +681,7 @@
     <ClCompile Include="..\debugger\gui\CartX07Widget.cxx">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
     </ClCompile>
+    <ClCompile Include="..\debugger\gui\DataGridRamWidget.cxx" />
     <ClCompile Include="..\debugger\gui\DelayQueueWidget.cxx">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
     </ClCompile>
@@ -702,6 +706,9 @@
     <ClCompile Include="..\debugger\gui\PointingDeviceWidget.cxx">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
     </ClCompile>
+    <ClCompile Include="..\debugger\gui\QuadTariWidget.cxx">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="..\debugger\gui\RiotRamWidget.cxx">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
     </ClCompile>
@@ -746,6 +753,7 @@
     <ClCompile Include="..\emucore\MindLink.cxx" />
     <ClCompile Include="..\emucore\PointingDevice.cxx" />
     <ClCompile Include="..\emucore\ProfilingRunner.cxx" />
+    <ClCompile Include="..\emucore\QuadTari.cxx" />
     <ClCompile Include="..\emucore\TIASurface.cxx" />
     <ClCompile Include="..\emucore\tia\Audio.cxx" />
     <ClCompile Include="..\emucore\tia\AudioChannel.cxx" />
@@ -771,6 +779,7 @@
     <ClCompile Include="..\gui\MessageDialog.cxx" />
     <ClCompile Include="..\gui\MessageMenu.cxx" />
     <ClCompile Include="..\gui\MinUICommandDialog.cxx" />
+    <ClCompile Include="..\gui\QuadTariDialog.cxx" />
     <ClCompile Include="..\gui\R77HelpDialog.cxx" />
     <ClCompile Include="..\gui\RadioButtonWidget.cxx" />
     <ClCompile Include="..\gui\SnapshotDialog.cxx" />
@@ -778,6 +787,8 @@
     <ClCompile Include="..\gui\TimeLineWidget.cxx" />
     <ClCompile Include="..\gui\TimeMachine.cxx" />
     <ClCompile Include="..\gui\TimeMachineDialog.cxx" />
+    <ClCompile Include="..\gui\ToolTip.cxx" />
+    <ClCompile Include="..\gui\UndoHandler.cxx" />
     <ClCompile Include="..\gui\WhatsNewDialog.cxx" />
     <ClCompile Include="FSNodeWINDOWS.cxx" />
     <ClCompile Include="OSystemWINDOWS.cxx" />
@@ -1500,9 +1511,9 @@
     <ClInclude Include="..\common\Base.hxx" />
     <ClInclude Include="..\common\bspf.hxx" />
     <ClInclude Include="..\common\EventHandlerSDL2.hxx" />
+    <ClInclude Include="..\common\FBBackendSDL2.hxx" />
     <ClInclude Include="..\common\FBSurfaceSDL2.hxx" />
     <ClInclude Include="..\common\FpsMeter.hxx" />
-    <ClInclude Include="..\common\FrameBufferSDL2.hxx" />
     <ClInclude Include="..\common\FSNodeFactory.hxx" />
     <ClInclude Include="..\common\FSNodeZIP.hxx" />
     <ClInclude Include="..\common\JoyMap.hxx" />
@@ -1535,6 +1546,7 @@
     <ClInclude Include="..\common\tv_filters\NTSCFilter.hxx" />
     <ClInclude Include="..\common\Variant.hxx" />
     <ClInclude Include="..\common\Vec.hxx" />
+    <ClInclude Include="..\common\VideoModeHandler.hxx" />
     <ClInclude Include="..\common\ZipHandler.hxx" />
     <ClInclude Include="..\debugger\BreakpointMap.hxx">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
@@ -1632,7 +1644,9 @@
     <ClInclude Include="..\debugger\gui\CartEFWidget.hxx">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
     </ClInclude>
-    <ClInclude Include="..\debugger\gui\CartEnhancedWidget.hxx" />
+    <ClInclude Include="..\debugger\gui\CartEnhancedWidget.hxx">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
+    </ClInclude>
     <ClInclude Include="..\debugger\gui\CartF0Widget.hxx">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
     </ClInclude>
@@ -1693,6 +1707,7 @@
     <ClInclude Include="..\debugger\gui\ControllerWidget.hxx">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
     </ClInclude>
+    <ClInclude Include="..\debugger\gui\DataGridRamWidget.hxx" />
     <ClInclude Include="..\debugger\gui\DelayQueueWidget.hxx">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
     </ClInclude>
@@ -1720,6 +1735,9 @@
     <ClInclude Include="..\debugger\gui\PointingDeviceWidget.hxx">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
     </ClInclude>
+    <ClInclude Include="..\debugger\gui\QuadTariWidget.hxx">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
+    </ClInclude>
     <ClInclude Include="..\debugger\gui\RiotRamWidget.hxx">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
     </ClInclude>
@@ -1738,7 +1756,6 @@
     <ClInclude Include="..\emucore\AmigaMouse.hxx" />
     <ClInclude Include="..\emucore\AtariMouse.hxx" />
     <ClInclude Include="..\emucore\Bankswitch.hxx" />
-    <ClInclude Include="..\emucore\BSType.hxx" />
     <ClInclude Include="..\emucore\Cart3EPlus.hxx" />
     <ClInclude Include="..\emucore\Cart3EX.hxx" />
     <ClInclude Include="..\emucore\Cart4KSC.hxx" />
@@ -1769,12 +1786,14 @@
     <ClInclude Include="..\emucore\EventHandlerConstants.hxx" />
     <ClInclude Include="..\emucore\exception\EmulationWarning.hxx" />
     <ClInclude Include="..\emucore\exception\FatalEmulationError.hxx" />
+    <ClInclude Include="..\emucore\FBBackend.hxx" />
     <ClInclude Include="..\emucore\FBSurface.hxx" />
     <ClInclude Include="..\emucore\FrameBufferConstants.hxx" />
     <ClInclude Include="..\emucore\Lightgun.hxx" />
     <ClInclude Include="..\emucore\MindLink.hxx" />
     <ClInclude Include="..\emucore\PointingDevice.hxx" />
     <ClInclude Include="..\emucore\ProfilingRunner.hxx" />
+    <ClInclude Include="..\emucore\QuadTari.hxx" />
     <ClInclude Include="..\emucore\SerialPort.hxx" />
     <ClInclude Include="..\emucore\TIASurface.hxx" />
     <ClInclude Include="..\emucore\tia\Audio.hxx" />
@@ -1811,6 +1830,7 @@
     <ClInclude Include="..\gui\MessageDialog.hxx" />
     <ClInclude Include="..\gui\MessageMenu.hxx" />
     <ClInclude Include="..\gui\MinUICommandDialog.hxx" />
+    <ClInclude Include="..\gui\QuadTariDialog.hxx" />
     <ClInclude Include="..\gui\R77HelpDialog.hxx" />
     <ClInclude Include="..\gui\RadioButtonWidget.hxx" />
     <ClInclude Include="..\gui\SnapshotDialog.hxx" />
@@ -1821,6 +1841,8 @@
     <ClInclude Include="..\gui\TimeLineWidget.hxx" />
     <ClInclude Include="..\gui\TimeMachine.hxx" />
     <ClInclude Include="..\gui\TimeMachineDialog.hxx" />
+    <ClInclude Include="..\gui\ToolTip.hxx" />
+    <ClInclude Include="..\gui\UndoHandler.hxx" />
     <ClInclude Include="..\gui\WhatsNewDialog.hxx" />
     <ClInclude Include="..\libpng\pngdebug.h" />
     <ClInclude Include="..\libpng\pnginfo.h" />
@@ -2033,6 +2055,7 @@
     <ClInclude Include="..\libpng\png.h" />
     <ClInclude Include="..\libpng\pngconf.h" />
     <ClInclude Include="..\libpng\pngpriv.h" />
+    <ClInclude Include="Windows.hxx" />
   </ItemGroup>
   <ItemGroup>
     <None Include="..\emucore\tia\frame-manager\module.mk" />
diff --git a/src/windows/Stella.vcxproj.filters b/src/windows/Stella.vcxproj.filters
index 5875efb8c..a8cac63d6 100644
--- a/src/windows/Stella.vcxproj.filters
+++ b/src/windows/Stella.vcxproj.filters
@@ -72,7 +72,7 @@
     </Filter>
   </ItemGroup>
   <ItemGroup>
-    <ClCompile Include="..\common\FrameBufferSDL2.cxx">
+    <ClCompile Include="..\common\FBBackendSDL2.cxx">
       <Filter>Source Files</Filter>
     </ClCompile>
     <ClCompile Include="FSNodeWINDOWS.cxx">
@@ -1008,21 +1008,42 @@
     <ClCompile Include="..\emucore\CartTVBoy.cxx">
       <Filter>Source Files\emucore</Filter>
     </ClCompile>
-    <ClCompile Include="..\debugger\gui\CartTVBoyWidget.cxx">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="..\emucore\CartCreator.cxx">
       <Filter>Source Files\emucore</Filter>
     </ClCompile>
     <ClCompile Include="..\gui\WhatsNewDialog.cxx">
       <Filter>Source Files\gui</Filter>
     </ClCompile>
+    <ClCompile Include="..\emucore\QuadTari.cxx">
+      <Filter>Source Files\emucore</Filter>
+    </ClCompile>
+    <ClCompile Include="..\debugger\gui\QuadTariWidget.cxx">
+      <Filter>Source Files\debugger</Filter>
+    </ClCompile>
+    <ClCompile Include="..\gui\QuadTariDialog.cxx">
+      <Filter>Source Files\gui</Filter>
+    </ClCompile>
+    <ClCompile Include="..\debugger\gui\CartTVBoyWidget.cxx">
+      <Filter>Source Files\debugger</Filter>
+    </ClCompile>
+    <ClCompile Include="..\common\VideoModeHandler.cxx">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\gui\UndoHandler.cxx">
+      <Filter>Source Files\gui</Filter>
+    </ClCompile>
+    <ClCompile Include="..\gui\ToolTip.cxx">
+      <Filter>Source Files\gui</Filter>
+    </ClCompile>
+    <ClCompile Include="..\debugger\gui\DataGridRamWidget.cxx">
+      <Filter>Source Files\debugger</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\common\bspf.hxx">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="..\common\FrameBufferSDL2.hxx">
+    <ClInclude Include="..\common\FBBackendSDL2.hxx">
       <Filter>Header Files</Filter>
     </ClInclude>
     <ClInclude Include="HomeFinder.hxx">
@@ -1820,9 +1841,6 @@
     <ClInclude Include="..\common\tv_filters\AtariNTSC.hxx">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="..\emucore\BSType.hxx">
-      <Filter>Header Files\emucore</Filter>
-    </ClInclude>
     <ClInclude Include="..\emucore\CartDetector.hxx">
       <Filter>Header Files\emucore</Filter>
     </ClInclude>
@@ -2078,9 +2096,6 @@
     <ClInclude Include="..\emucore\CartTVBoy.hxx">
       <Filter>Header Files\emucore</Filter>
     </ClInclude>
-    <ClInclude Include="..\debugger\gui\CartTVBoyWidget.hxx">
-      <Filter>Header Files</Filter>
-    </ClInclude>
     <ClInclude Include="..\emucore\CartCreator.hxx">
       <Filter>Header Files\emucore</Filter>
     </ClInclude>
@@ -2090,6 +2105,36 @@
     <ClInclude Include="..\emucore\SerialPort.hxx">
       <Filter>Header Files\emucore</Filter>
     </ClInclude>
+    <ClInclude Include="..\emucore\QuadTari.hxx">
+      <Filter>Header Files\emucore</Filter>
+    </ClInclude>
+    <ClInclude Include="..\debugger\gui\QuadTariWidget.hxx">
+      <Filter>Header Files\debugger</Filter>
+    </ClInclude>
+    <ClInclude Include="..\gui\QuadTariDialog.hxx">
+      <Filter>Header Files\gui</Filter>
+    </ClInclude>
+    <ClInclude Include="Windows.hxx">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\debugger\gui\CartTVBoyWidget.hxx">
+      <Filter>Header Files\debugger</Filter>
+    </ClInclude>
+    <ClInclude Include="..\common\VideoModeHandler.hxx">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\emucore\FBBackend.hxx">
+      <Filter>Header Files\emucore</Filter>
+    </ClInclude>
+    <ClInclude Include="..\gui\UndoHandler.hxx">
+      <Filter>Header Files\gui</Filter>
+    </ClInclude>
+    <ClInclude Include="..\gui\ToolTip.hxx">
+      <Filter>Header Files\gui</Filter>
+    </ClInclude>
+    <ClInclude Include="..\debugger\gui\DataGridRamWidget.hxx">
+      <Filter>Header Files\debugger</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="stella.ico">
diff --git a/src/windows/Windows.hxx b/src/windows/Windows.hxx
new file mode 100644
index 000000000..3c45cfcf2
--- /dev/null
+++ b/src/windows/Windows.hxx
@@ -0,0 +1,33 @@
+//============================================================================
+//
+//   SSSS    tt          lll  lll
+//  SS  SS   tt           ll   ll
+//  SS     tttttt  eeee   ll   ll   aaaa
+//   SSSS    tt   ee  ee  ll   ll      aa
+//      SS   tt   eeeeee  ll   ll   aaaaa  --  "An Atari 2600 VCS Emulator"
+//  SS  SS   tt   ee      ll   ll  aa  aa
+//   SSSS     ttt  eeeee llll llll  aaaaa
+//
+// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
+// and the Stella Team
+//
+// See the file "License.txt" for information on usage and redistribution of
+// this file, and for a DISCLAIMER OF ALL WARRANTIES.
+//============================================================================
+
+#ifndef WINDOWS_LIB_HXX
+#define WINDOWS_LIB_HXX
+
+/*
+  Using window.h directly can cause problems, since it's a C library
+  that doesn't support namespacing, etc.
+
+  Anyone needing 'windows.h' should include this file instead.
+*/
+
+#include <windows.h>
+
+#undef MessageBox
+#undef ARRAYSIZE
+
+#endif  // WINDOWS_LIB_HXX
diff --git a/src/windows/stella.rc b/src/windows/stella.rc
index 0958a136d..6b99a297c 100755
--- a/src/windows/stella.rc
+++ b/src/windows/stella.rc
@@ -36,8 +36,8 @@ IDI_ICON                ICON                    "stella.ico"
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 6,2,1,0
- PRODUCTVERSION 6,2,1,0
+ FILEVERSION 6,4,0,0
+ PRODUCTVERSION 6,4,0,0
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -55,12 +55,12 @@ BEGIN
             VALUE "Comments", "The multi-platform Atari 2600 emulator.  Stella is released under the GPLv2."
             VALUE "CompanyName", "The Stella Team (https://stella-emu.github.io)"
             VALUE "FileDescription", "Stella"
-            VALUE "FileVersion", "6.2.1"
+            VALUE "FileVersion", "6.4"
             VALUE "InternalName", "Stella"
             VALUE "LegalCopyright", "Copyright (c) 1995-2020 The Stella Team"
             VALUE "OriginalFilename", "Stella.exe"
             VALUE "ProductName", "Stella"
-            VALUE "ProductVersion", "6.2.1"
+            VALUE "ProductVersion", "6.4"
         END
     END
     BLOCK "VarFileInfo"
diff --git a/src/yacc/YaccParser.cxx b/src/yacc/YaccParser.cxx
index 8bc728ca0..ba74728dd 100644
--- a/src/yacc/YaccParser.cxx
+++ b/src/yacc/YaccParser.cxx
@@ -228,6 +228,20 @@ CpuMethod getCpuSpecial(char* ch)
     return nullptr;
 }
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// special methods that get RIOT internal state
+RiotMethod getRiotSpecial(char* ch)
+{
+  if(BSPF::equalsIgnoreCase(ch, "_timwrapread"))
+    return &RiotDebug::timWrappedOnRead;
+  else if(BSPF::equalsIgnoreCase(ch, "_timwrapwrite"))
+    return &RiotDebug::timWrappedOnWrite;
+  else if(BSPF::equalsIgnoreCase(ch, "_ftimreadcycles"))
+    return &RiotDebug::timReadCycles;
+  else
+    return nullptr;
+}
+
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 // special methods that get TIA internal state
 TiaMethod getTiaSpecial(char* ch)
@@ -242,6 +256,8 @@ TiaMethod getTiaSpecial(char* ch)
     return &TIADebug::frameCount;
   else if(BSPF::equalsIgnoreCase(ch, "_fcycles"))
     return &TIADebug::frameCycles;
+  else if(BSPF::equalsIgnoreCase(ch, "_fwsynccycles"))
+    return &TIADebug::frameWsyncCycles;
   else if(BSPF::equalsIgnoreCase(ch, "_cyclesLo"))
     return &TIADebug::cyclesLo;
   else if(BSPF::equalsIgnoreCase(ch, "_cyclesHi"))
@@ -281,6 +297,7 @@ int yylex() {
         {
           CartMethod cartMeth;
           CpuMethod  cpuMeth;
+          RiotMethod riotMeth;
           TiaMethod  tiaMeth;
 
           char *bufp = idbuf;
@@ -309,6 +326,9 @@ int yylex() {
           } else if( (cartMeth = getCartSpecial(idbuf)) ) {
             yylval.cartMethod = cartMeth;
             return CART_METHOD;
+          } else if( (riotMeth = getRiotSpecial(idbuf)) ) {
+            yylval.riotMethod = riotMeth;
+            return RIOT_METHOD;
           } else if( (tiaMeth = getTiaSpecial(idbuf)) ) {
             yylval.tiaMethod = tiaMeth;
             return TIA_METHOD;
diff --git a/src/yacc/YaccParser.hxx b/src/yacc/YaccParser.hxx
index 0ce067c27..050d4a7e5 100644
--- a/src/yacc/YaccParser.hxx
+++ b/src/yacc/YaccParser.hxx
@@ -21,6 +21,7 @@
 #include "Expression.hxx"
 #include "CartDebug.hxx"
 #include "CpuDebug.hxx"
+#include "RiotDebug.hxx"
 #include "TIADebug.hxx"
 
 #include "bspf.hxx"
@@ -37,6 +38,7 @@ namespace YaccParser
 
   CartMethod getCartSpecial(char* ch);
   CpuMethod getCpuSpecial(char* ch);
+  RiotMethod getRiotSpecial(char* ch);
   TiaMethod getTiaSpecial(char* ch);
 }
 
diff --git a/src/yacc/stella.y b/src/yacc/stella.y
index 4f13cb6d4..6836d00cd 100644
--- a/src/yacc/stella.y
+++ b/src/yacc/stella.y
@@ -30,6 +30,7 @@ void yyerror(const char *e) {
 	char* Equate;
 	CartMethod cartMethod;
 	CpuMethod cpuMethod;
+	RiotMethod riotMethod;
 	TiaMethod tiaMethod;
 	Expression* exp;
 	char* DefinedFunction;
@@ -41,6 +42,7 @@ void yyerror(const char *e) {
 %token <Equate> EQUATE
 %token <cartMethod> CART_METHOD
 %token <cpuMethod>  CPU_METHOD
+%token <riotMethod> RIOT_METHOD
 %token <tiaMethod>  TIA_METHOD
 %token <DefinedFunction> FUNCTION
 
@@ -97,6 +99,7 @@ expression:	expression '+' expression { if(DEBUG_EXP) fprintf(stderr, " +"); $$
 	|	EQUATE { if(DEBUG_EXP) fprintf(stderr, "equate %s", $1); $$ = new EquateExpression($1); lastExp = $$; }
 	|	CPU_METHOD { if(DEBUG_EXP) fprintf(stderr, " (CpuMethod)"); $$ = new CpuMethodExpression($1); lastExp = $$; }
 	|	CART_METHOD { if(DEBUG_EXP) fprintf(stderr, " (CartMethod)"); $$ = new CartMethodExpression($1); lastExp = $$; }
+	|	RIOT_METHOD { if(DEBUG_EXP) fprintf(stderr, " (RiotMethod)"); $$ = new RiotMethodExpression($1); lastExp = $$; }
 	|	TIA_METHOD { if(DEBUG_EXP) fprintf(stderr, " (TiaMethod)"); $$ = new TiaMethodExpression($1); lastExp = $$; }
 	|	FUNCTION { if(DEBUG_EXP) fprintf(stderr, " (DefinedFunction)"); $$ = new FunctionExpression($1); lastExp = $$; }
 	|  ERR { if(DEBUG_EXP) fprintf(stderr, " ERR: "); yyerror((const char*)"Invalid label or constant"); return 1; }
diff --git a/src/yacc/y.tab.c b/src/yacc/y.tab.c
index fcd1b4c72..ed1d99c58 100644
--- a/src/yacc/y.tab.c
+++ b/src/yacc/y.tab.c
@@ -1,8 +1,9 @@
-/* A Bison parser, made by GNU Bison 3.0.4.  */
+/* A Bison parser, made by GNU Bison 3.5.1.  */
 
 /* Bison implementation for Yacc-like parsers in C
 
-   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation,
+   Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -40,11 +41,14 @@
    define necessary library symbols; they are noted "INFRINGES ON
    USER NAME SPACE" below.  */
 
+/* Undocumented macros, especially those whose name start with YY_,
+   are private implementation details.  Do not rely on them.  */
+
 /* Identify Bison output.  */
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "3.0.4"
+#define YYBISON_VERSION "3.5.1"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
@@ -61,8 +65,8 @@
 
 
 
-/* Copy the first part of user declarations.  */
-#line 1 "stella.y" /* yacc.c:339  */
+/* First part of user prologue.  */
+#line 1 "stella.y"
 
 #include <stdio.h>
 
@@ -89,13 +93,26 @@ void yyerror(const char *e) {
 }
 
 
-#line 93 "y.tab.c" /* yacc.c:339  */
+#line 97 "y.tab.c"
 
-# ifndef YY_NULLPTR
-#  if defined __cplusplus && 201103L <= __cplusplus
-#   define YY_NULLPTR nullptr
+# ifndef YY_CAST
+#  ifdef __cplusplus
+#   define YY_CAST(Type, Val) static_cast<Type> (Val)
+#   define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast<Type> (Val)
 #  else
-#   define YY_NULLPTR 0
+#   define YY_CAST(Type, Val) ((Type) (Val))
+#   define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val))
+#  endif
+# endif
+# ifndef YY_NULLPTR
+#  if defined __cplusplus
+#   if 201103L <= __cplusplus
+#    define YY_NULLPTR nullptr
+#   else
+#    define YY_NULLPTR 0
+#   endif
+#  else
+#   define YY_NULLPTR ((void*)0)
 #  endif
 # endif
 
@@ -107,8 +124,8 @@ void yyerror(const char *e) {
 # define YYERROR_VERBOSE 0
 #endif
 
-/* In a future release of Bison, this section will be replaced
-   by #include "y.tab.h".  */
+/* Use api.header.include to #include this header
+   instead of duplicating it here.  */
 #ifndef YY_YY_Y_TAB_H_INCLUDED
 # define YY_YY_Y_TAB_H_INCLUDED
 /* Debug traces.  */
@@ -129,19 +146,20 @@ extern int yydebug;
     EQUATE = 260,
     CART_METHOD = 261,
     CPU_METHOD = 262,
-    TIA_METHOD = 263,
-    FUNCTION = 264,
-    LOG_OR = 265,
-    LOG_AND = 266,
-    LOG_NOT = 267,
-    SHR = 268,
-    SHL = 269,
-    GTE = 270,
-    LTE = 271,
-    NE = 272,
-    EQ = 273,
-    DEREF = 274,
-    UMINUS = 275
+    RIOT_METHOD = 263,
+    TIA_METHOD = 264,
+    FUNCTION = 265,
+    LOG_OR = 266,
+    LOG_AND = 267,
+    LOG_NOT = 268,
+    SHR = 269,
+    SHL = 270,
+    GTE = 271,
+    LTE = 272,
+    NE = 273,
+    EQ = 274,
+    DEREF = 275,
+    UMINUS = 276
   };
 #endif
 /* Tokens.  */
@@ -150,38 +168,39 @@ extern int yydebug;
 #define EQUATE 260
 #define CART_METHOD 261
 #define CPU_METHOD 262
-#define TIA_METHOD 263
-#define FUNCTION 264
-#define LOG_OR 265
-#define LOG_AND 266
-#define LOG_NOT 267
-#define SHR 268
-#define SHL 269
-#define GTE 270
-#define LTE 271
-#define NE 272
-#define EQ 273
-#define DEREF 274
-#define UMINUS 275
+#define RIOT_METHOD 263
+#define TIA_METHOD 264
+#define FUNCTION 265
+#define LOG_OR 266
+#define LOG_AND 267
+#define LOG_NOT 268
+#define SHR 269
+#define SHL 270
+#define GTE 271
+#define LTE 272
+#define NE 273
+#define EQ 274
+#define DEREF 275
+#define UMINUS 276
 
 /* Value type.  */
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-
 union YYSTYPE
 {
-#line 28 "stella.y" /* yacc.c:355  */
+#line 28 "stella.y"
 
 	int val;
 	char* Equate;
 	CartMethod cartMethod;
 	CpuMethod cpuMethod;
+	RiotMethod riotMethod;
 	TiaMethod tiaMethod;
 	Expression* exp;
 	char* DefinedFunction;
 
-#line 183 "y.tab.c" /* yacc.c:355  */
-};
+#line 202 "y.tab.c"
 
+};
 typedef union YYSTYPE YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1
 # define YYSTYPE_IS_DECLARED 1
@@ -194,36 +213,81 @@ int yyparse (void);
 
 #endif /* !YY_YY_Y_TAB_H_INCLUDED  */
 
-/* Copy the second part of user declarations.  */
 
-#line 200 "y.tab.c" /* yacc.c:358  */
 
 #ifdef short
 # undef short
 #endif
 
-#ifdef YYTYPE_UINT8
-typedef YYTYPE_UINT8 yytype_uint8;
-#else
-typedef unsigned char yytype_uint8;
+/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure
+   <limits.h> and (if available) <stdint.h> are included
+   so that the code can choose integer types of a good width.  */
+
+#ifndef __PTRDIFF_MAX__
+# include <limits.h> /* INFRINGES ON USER NAME SPACE */
+# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
+#  include <stdint.h> /* INFRINGES ON USER NAME SPACE */
+#  define YY_STDINT_H
+# endif
 #endif
 
-#ifdef YYTYPE_INT8
-typedef YYTYPE_INT8 yytype_int8;
+/* Narrow types that promote to a signed type and that can represent a
+   signed or unsigned integer of at least N bits.  In tables they can
+   save space and decrease cache pressure.  Promoting to a signed type
+   helps avoid bugs in integer arithmetic.  */
+
+#ifdef __INT_LEAST8_MAX__
+typedef __INT_LEAST8_TYPE__ yytype_int8;
+#elif defined YY_STDINT_H
+typedef int_least8_t yytype_int8;
 #else
 typedef signed char yytype_int8;
 #endif
 
-#ifdef YYTYPE_UINT16
-typedef YYTYPE_UINT16 yytype_uint16;
+#ifdef __INT_LEAST16_MAX__
+typedef __INT_LEAST16_TYPE__ yytype_int16;
+#elif defined YY_STDINT_H
+typedef int_least16_t yytype_int16;
 #else
-typedef unsigned short int yytype_uint16;
+typedef short yytype_int16;
 #endif
 
-#ifdef YYTYPE_INT16
-typedef YYTYPE_INT16 yytype_int16;
+#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__
+typedef __UINT_LEAST8_TYPE__ yytype_uint8;
+#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \
+       && UINT_LEAST8_MAX <= INT_MAX)
+typedef uint_least8_t yytype_uint8;
+#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX
+typedef unsigned char yytype_uint8;
 #else
-typedef short int yytype_int16;
+typedef short yytype_uint8;
+#endif
+
+#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__
+typedef __UINT_LEAST16_TYPE__ yytype_uint16;
+#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \
+       && UINT_LEAST16_MAX <= INT_MAX)
+typedef uint_least16_t yytype_uint16;
+#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX
+typedef unsigned short yytype_uint16;
+#else
+typedef int yytype_uint16;
+#endif
+
+#ifndef YYPTRDIFF_T
+# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__
+#  define YYPTRDIFF_T __PTRDIFF_TYPE__
+#  define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__
+# elif defined PTRDIFF_MAX
+#  ifndef ptrdiff_t
+#   include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  endif
+#  define YYPTRDIFF_T ptrdiff_t
+#  define YYPTRDIFF_MAXIMUM PTRDIFF_MAX
+# else
+#  define YYPTRDIFF_T long
+#  define YYPTRDIFF_MAXIMUM LONG_MAX
+# endif
 #endif
 
 #ifndef YYSIZE_T
@@ -231,15 +295,27 @@ typedef short int yytype_int16;
 #  define YYSIZE_T __SIZE_TYPE__
 # elif defined size_t
 #  define YYSIZE_T size_t
-# elif ! defined YYSIZE_T
+# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
 #  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
 #  define YYSIZE_T size_t
 # else
-#  define YYSIZE_T unsigned int
+#  define YYSIZE_T unsigned
 # endif
 #endif
 
-#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+#define YYSIZE_MAXIMUM                                  \
+  YY_CAST (YYPTRDIFF_T,                                 \
+           (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1)  \
+            ? YYPTRDIFF_MAXIMUM                         \
+            : YY_CAST (YYSIZE_T, -1)))
+
+#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X))
+
+/* Stored state numbers (used for stacks). */
+typedef yytype_int8 yy_state_t;
+
+/* State numbers in computations.  */
+typedef int yy_state_fast_t;
 
 #ifndef YY_
 # if defined YYENABLE_NLS && YYENABLE_NLS
@@ -253,30 +329,19 @@ typedef short int yytype_int16;
 # endif
 #endif
 
-#ifndef YY_ATTRIBUTE
-# if (defined __GNUC__                                               \
-      && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__)))  \
-     || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
-#  define YY_ATTRIBUTE(Spec) __attribute__(Spec)
+#ifndef YY_ATTRIBUTE_PURE
+# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__)
+#  define YY_ATTRIBUTE_PURE __attribute__ ((__pure__))
 # else
-#  define YY_ATTRIBUTE(Spec) /* empty */
+#  define YY_ATTRIBUTE_PURE
 # endif
 #endif
 
-#ifndef YY_ATTRIBUTE_PURE
-# define YY_ATTRIBUTE_PURE   YY_ATTRIBUTE ((__pure__))
-#endif
-
 #ifndef YY_ATTRIBUTE_UNUSED
-# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
-#endif
-
-#if !defined _Noreturn \
-     && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
-# if defined _MSC_VER && 1200 <= _MSC_VER
-#  define _Noreturn __declspec (noreturn)
+# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
+#  define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__))
 # else
-#  define _Noreturn YY_ATTRIBUTE ((__noreturn__))
+#  define YY_ATTRIBUTE_UNUSED
 # endif
 #endif
 
@@ -287,13 +352,13 @@ typedef short int yytype_int16;
 # define YYUSE(E) /* empty */
 #endif
 
-#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
 /* Suppress an incorrect diagnostic about yylval being uninitialized.  */
-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
-    _Pragma ("GCC diagnostic push") \
-    _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN                            \
+    _Pragma ("GCC diagnostic push")                                     \
+    _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")              \
     _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
-# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END      \
     _Pragma ("GCC diagnostic pop")
 #else
 # define YY_INITIAL_VALUE(Value) Value
@@ -306,6 +371,20 @@ typedef short int yytype_int16;
 # define YY_INITIAL_VALUE(Value) /* Nothing. */
 #endif
 
+#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__
+# define YY_IGNORE_USELESS_CAST_BEGIN                          \
+    _Pragma ("GCC diagnostic push")                            \
+    _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"")
+# define YY_IGNORE_USELESS_CAST_END            \
+    _Pragma ("GCC diagnostic pop")
+#endif
+#ifndef YY_IGNORE_USELESS_CAST_BEGIN
+# define YY_IGNORE_USELESS_CAST_BEGIN
+# define YY_IGNORE_USELESS_CAST_END
+#endif
+
+
+#define YY_ASSERT(E) ((void) (0 && (E)))
 
 #if ! defined yyoverflow || YYERROR_VERBOSE
 
@@ -382,17 +461,17 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
 /* A type that is properly aligned for any stack member.  */
 union yyalloc
 {
-  yytype_int16 yyss_alloc;
+  yy_state_t yyss_alloc;
   YYSTYPE yyvs_alloc;
 };
 
 /* The size of the maximum gap between one aligned stack and the next.  */
-# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1)
 
 /* The size of an array large to enough to hold all stacks, each with
    N elements.  */
 # define YYSTACK_BYTES(N) \
-     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+     ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \
       + YYSTACK_GAP_MAXIMUM)
 
 # define YYCOPY_NEEDED 1
@@ -405,11 +484,11 @@ union yyalloc
 # define YYSTACK_RELOCATE(Stack_alloc, Stack)                           \
     do                                                                  \
       {                                                                 \
-        YYSIZE_T yynewbytes;                                            \
+        YYPTRDIFF_T yynewbytes;                                         \
         YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \
         Stack = &yyptr->Stack_alloc;                                    \
-        yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
-        yyptr += yynewbytes / sizeof (*yyptr);                          \
+        yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \
+        yyptr += yynewbytes / YYSIZEOF (*yyptr);                        \
       }                                                                 \
     while (0)
 
@@ -421,12 +500,12 @@ union yyalloc
 # ifndef YYCOPY
 #  if defined __GNUC__ && 1 < __GNUC__
 #   define YYCOPY(Dst, Src, Count) \
-      __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
+      __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src)))
 #  else
 #   define YYCOPY(Dst, Src, Count)              \
       do                                        \
         {                                       \
-          YYSIZE_T yyi;                         \
+          YYPTRDIFF_T yyi;                      \
           for (yyi = 0; yyi < (Count); yyi++)   \
             (Dst)[yyi] = (Src)[yyi];            \
         }                                       \
@@ -436,44 +515,45 @@ union yyalloc
 #endif /* !YYCOPY_NEEDED */
 
 /* YYFINAL -- State number of the termination state.  */
-#define YYFINAL  26
+#define YYFINAL  27
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   227
+#define YYLAST   228
 
 /* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  38
+#define YYNTOKENS  39
 /* YYNNTS -- Number of nonterminals.  */
 #define YYNNTS  3
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  36
+#define YYNRULES  37
 /* YYNSTATES -- Number of states.  */
-#define YYNSTATES  67
+#define YYNSTATES  68
 
-/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
-   by yylex, with out-of-bounds checking.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   275
+#define YYMAXUTOK   276
 
+
+/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
+   as returned by yylex, with out-of-bounds checking.  */
 #define YYTRANSLATE(YYX)                                                \
-  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+  (0 <= (YYX) && (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
 
 /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
-   as returned by yylex, without out-of-bounds checking.  */
-static const yytype_uint8 yytranslate[] =
+   as returned by yylex.  */
+static const yytype_int8 yytranslate[] =
 {
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,    33,     2,     2,     2,    14,    20,     2,
-      35,    36,    12,    11,     2,    10,     2,    13,     2,     2,
+       2,     2,     2,    34,     2,     2,     2,    15,    21,     2,
+      36,    37,    13,    12,     2,    11,     2,    14,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-      23,     2,    24,     2,    34,     2,     2,     2,     2,     2,
+      24,     2,    25,     2,    35,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,    31,     2,    37,    19,     2,     2,     2,     2,     2,
+       2,    32,     2,    38,    20,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,    18,     2,    32,     2,     2,     2,
+       2,     2,     2,     2,    19,     2,    33,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -487,18 +567,18 @@ static const yytype_uint8 yytranslate[] =
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
-       5,     6,     7,     8,     9,    15,    16,    17,    21,    22,
-      25,    26,    27,    28,    29,    30
+       5,     6,     7,     8,     9,    10,    16,    17,    18,    22,
+      23,    26,    27,    28,    29,    30,    31
 };
 
 #if YYDEBUG
   /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
-static const yytype_uint8 yyrline[] =
+static const yytype_int8 yyrline[] =
 {
-       0,    66,    66,    69,    70,    71,    72,    73,    74,    75,
-      76,    77,    78,    79,    80,    81,    82,    83,    84,    85,
-      86,    87,    88,    89,    90,    91,    92,    93,    94,    95,
-      96,    97,    98,    99,   100,   101,   102
+       0,    68,    68,    71,    72,    73,    74,    75,    76,    77,
+      78,    79,    80,    81,    82,    83,    84,    85,    86,    87,
+      88,    89,    90,    91,    92,    93,    94,    95,    96,    97,
+      98,    99,   100,   101,   102,   103,   104,   105
 };
 #endif
 
@@ -508,72 +588,73 @@ static const yytype_uint8 yyrline[] =
 static const char *const yytname[] =
 {
   "$end", "error", "$undefined", "NUMBER", "ERR", "EQUATE", "CART_METHOD",
-  "CPU_METHOD", "TIA_METHOD", "FUNCTION", "'-'", "'+'", "'*'", "'/'",
-  "'%'", "LOG_OR", "LOG_AND", "LOG_NOT", "'|'", "'^'", "'&'", "SHR", "SHL",
-  "'<'", "'>'", "GTE", "LTE", "NE", "EQ", "DEREF", "UMINUS", "'['", "'~'",
-  "'!'", "'@'", "'('", "')'", "']'", "$accept", "statement", "expression", YY_NULLPTR
+  "CPU_METHOD", "RIOT_METHOD", "TIA_METHOD", "FUNCTION", "'-'", "'+'",
+  "'*'", "'/'", "'%'", "LOG_OR", "LOG_AND", "LOG_NOT", "'|'", "'^'", "'&'",
+  "SHR", "SHL", "'<'", "'>'", "GTE", "LTE", "NE", "EQ", "DEREF", "UMINUS",
+  "'['", "'~'", "'!'", "'@'", "'('", "')'", "']'", "$accept", "statement",
+  "expression", YY_NULLPTR
 };
 #endif
 
 # ifdef YYPRINT
 /* YYTOKNUM[NUM] -- (External) token number corresponding to the
    (internal) symbol number NUM (which must be that of a token).  */
-static const yytype_uint16 yytoknum[] =
+static const yytype_int16 yytoknum[] =
 {
        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
-      45,    43,    42,    47,    37,   265,   266,   267,   124,    94,
-      38,   268,   269,    60,    62,   270,   271,   272,   273,   274,
-     275,    91,   126,    33,    64,    40,    41,    93
+     265,    45,    43,    42,    47,    37,   266,   267,   268,   124,
+      94,    38,   269,   270,    60,    62,   271,   272,   273,   274,
+     275,   276,    91,   126,    33,    64,    40,    41,    93
 };
 # endif
 
-#define YYPACT_NINF -15
+#define YYPACT_NINF (-16)
 
-#define yypact_value_is_default(Yystate) \
-  (!!((Yystate) == (-15)))
+#define yypact_value_is_default(Yyn) \
+  ((Yyn) == YYPACT_NINF)
 
-#define YYTABLE_NINF -1
+#define YYTABLE_NINF (-1)
 
-#define yytable_value_is_error(Yytable_value) \
-  (!!((Yytable_value) == (-1)))
+#define yytable_value_is_error(Yyn) \
+  ((Yyn) == YYTABLE_NINF)
 
   /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
      STATE-NUM.  */
 static const yytype_int16 yypact[] =
 {
-      35,   -15,   -15,   -15,   -15,   -15,   -15,   -15,    35,    35,
-      35,    35,    35,    35,    35,    35,    16,   116,   -14,   -14,
-     187,   187,   -14,   -14,   -14,    89,   -15,    35,    35,    35,
+      35,   -16,   -16,   -16,   -16,   -16,   -16,   -16,   -16,    35,
+      35,    35,    35,    35,    35,    35,    35,    16,   116,   -15,
+     -15,   187,   187,   -15,   -15,   -15,    89,   -16,    35,    35,
       35,    35,    35,    35,    35,    35,    35,    35,    35,    35,
-      35,    35,    35,    35,    35,    35,   -15,   136,   136,   150,
-     150,   150,   164,   178,    29,    29,   -13,   196,   196,   187,
-     187,   187,   187,   187,   187,    61,   -15
+      35,    35,    35,    35,    35,    35,    35,   -16,   136,   136,
+     150,   150,   150,   164,   178,    29,    29,   -14,   196,   196,
+     187,   187,   187,   187,   187,   187,    61,   -16
 };
 
   /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
      Performed when YYTABLE does not specify something else to do.  Zero
      means the default is an error.  */
-static const yytype_uint8 yydefact[] =
+static const yytype_int8 yydefact[] =
 {
-       0,    30,    36,    31,    33,    32,    34,    35,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     2,    21,    24,
-      26,    27,    22,    23,    25,     0,     1,     0,     0,     0,
+       0,    30,    37,    31,    33,    32,    34,    35,    36,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     2,    21,
+      24,    26,    27,    22,    23,    25,     0,     1,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,    28,     4,     3,     5,
-       6,     7,    19,    20,     9,    10,     8,    17,    18,    11,
-      12,    13,    14,    15,    16,     0,    29
+       0,     0,     0,     0,     0,     0,     0,    28,     4,     3,
+       5,     6,     7,    19,    20,     9,    10,     8,    17,    18,
+      11,    12,    13,    14,    15,    16,     0,    29
 };
 
   /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int8 yypgoto[] =
 {
-     -15,   -15,    -8
+     -16,   -16,    -9
 };
 
   /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int8 yydefgoto[] =
 {
-      -1,    16,    17
+      -1,    17,    18
 };
 
   /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
@@ -581,87 +662,87 @@ static const yytype_int8 yydefgoto[] =
      number is the opposite.  If YYTABLE_NINF, syntax error.  */
 static const yytype_int8 yytable[] =
 {
-      18,    19,    20,    21,    22,    23,    24,    25,    37,    38,
-      39,    40,    41,    42,    43,    44,    26,    45,    45,    47,
-      48,    49,    50,    51,    52,    53,    54,    55,    56,    57,
-      58,    59,    60,    61,    62,    63,    64,    65,     1,     2,
-       3,     4,     5,     6,     7,     8,     0,     9,     0,    36,
-      37,    38,    39,    40,    41,    42,    43,    44,    10,    11,
-      45,     0,     0,     0,     0,     0,     0,    12,    13,    14,
-      15,    27,    28,    29,    30,    31,    32,    33,     0,    34,
+      19,    20,    21,    22,    23,    24,    25,    26,    38,    39,
+      40,    41,    42,    43,    44,    45,    27,    46,    46,    48,
+      49,    50,    51,    52,    53,    54,    55,    56,    57,    58,
+      59,    60,    61,    62,    63,    64,    65,    66,     1,     2,
+       3,     4,     5,     6,     7,     8,     9,     0,    10,     0,
+      37,    38,    39,    40,    41,    42,    43,    44,    45,    11,
+      12,    46,     0,     0,     0,     0,     0,     0,    13,    14,
+      15,    16,    28,    29,    30,    31,    32,    33,    34,     0,
       35,    36,    37,    38,    39,    40,    41,    42,    43,    44,
-       0,     0,    45,     0,     0,     0,     0,     0,    66,    27,
-      28,    29,    30,    31,    32,    33,     0,    34,    35,    36,
-      37,    38,    39,    40,    41,    42,    43,    44,     0,     0,
-      45,     0,     0,     0,     0,    46,    27,    28,    29,    30,
-      31,    32,    33,     0,    34,    35,    36,    37,    38,    39,
-      40,    41,    42,    43,    44,     0,     0,    45,    29,    30,
-      31,    32,    33,     0,    34,    35,    36,    37,    38,    39,
-      40,    41,    42,    43,    44,    32,    33,    45,    34,    35,
-      36,    37,    38,    39,    40,    41,    42,    43,    44,     0,
-      33,    45,    34,    35,    36,    37,    38,    39,    40,    41,
-      42,    43,    44,     0,     0,    45,    34,    35,    36,    37,
-      38,    39,    40,    41,    42,    43,    44,     0,     0,    45,
-      -1,    -1,    -1,    -1,    -1,    -1,     0,     0,    45,    39,
-      40,    41,    42,    43,    44,     0,     0,    45
+      45,     0,     0,    46,     0,     0,     0,     0,     0,    67,
+      28,    29,    30,    31,    32,    33,    34,     0,    35,    36,
+      37,    38,    39,    40,    41,    42,    43,    44,    45,     0,
+       0,    46,     0,     0,     0,     0,    47,    28,    29,    30,
+      31,    32,    33,    34,     0,    35,    36,    37,    38,    39,
+      40,    41,    42,    43,    44,    45,     0,     0,    46,    30,
+      31,    32,    33,    34,     0,    35,    36,    37,    38,    39,
+      40,    41,    42,    43,    44,    45,    33,    34,    46,    35,
+      36,    37,    38,    39,    40,    41,    42,    43,    44,    45,
+       0,    34,    46,    35,    36,    37,    38,    39,    40,    41,
+      42,    43,    44,    45,     0,     0,    46,    35,    36,    37,
+      38,    39,    40,    41,    42,    43,    44,    45,     0,     0,
+      46,    -1,    -1,    -1,    -1,    -1,    -1,     0,     0,    46,
+      40,    41,    42,    43,    44,    45,     0,     0,    46
 };
 
 static const yytype_int8 yycheck[] =
 {
-       8,     9,    10,    11,    12,    13,    14,    15,    21,    22,
-      23,    24,    25,    26,    27,    28,     0,    31,    31,    27,
-      28,    29,    30,    31,    32,    33,    34,    35,    36,    37,
-      38,    39,    40,    41,    42,    43,    44,    45,     3,     4,
-       5,     6,     7,     8,     9,    10,    -1,    12,    -1,    20,
-      21,    22,    23,    24,    25,    26,    27,    28,    23,    24,
-      31,    -1,    -1,    -1,    -1,    -1,    -1,    32,    33,    34,
-      35,    10,    11,    12,    13,    14,    15,    16,    -1,    18,
+       9,    10,    11,    12,    13,    14,    15,    16,    22,    23,
+      24,    25,    26,    27,    28,    29,     0,    32,    32,    28,
+      29,    30,    31,    32,    33,    34,    35,    36,    37,    38,
+      39,    40,    41,    42,    43,    44,    45,    46,     3,     4,
+       5,     6,     7,     8,     9,    10,    11,    -1,    13,    -1,
+      21,    22,    23,    24,    25,    26,    27,    28,    29,    24,
+      25,    32,    -1,    -1,    -1,    -1,    -1,    -1,    33,    34,
+      35,    36,    11,    12,    13,    14,    15,    16,    17,    -1,
       19,    20,    21,    22,    23,    24,    25,    26,    27,    28,
-      -1,    -1,    31,    -1,    -1,    -1,    -1,    -1,    37,    10,
-      11,    12,    13,    14,    15,    16,    -1,    18,    19,    20,
-      21,    22,    23,    24,    25,    26,    27,    28,    -1,    -1,
-      31,    -1,    -1,    -1,    -1,    36,    10,    11,    12,    13,
-      14,    15,    16,    -1,    18,    19,    20,    21,    22,    23,
-      24,    25,    26,    27,    28,    -1,    -1,    31,    12,    13,
-      14,    15,    16,    -1,    18,    19,    20,    21,    22,    23,
-      24,    25,    26,    27,    28,    15,    16,    31,    18,    19,
-      20,    21,    22,    23,    24,    25,    26,    27,    28,    -1,
-      16,    31,    18,    19,    20,    21,    22,    23,    24,    25,
-      26,    27,    28,    -1,    -1,    31,    18,    19,    20,    21,
-      22,    23,    24,    25,    26,    27,    28,    -1,    -1,    31,
-      23,    24,    25,    26,    27,    28,    -1,    -1,    31,    23,
-      24,    25,    26,    27,    28,    -1,    -1,    31
+      29,    -1,    -1,    32,    -1,    -1,    -1,    -1,    -1,    38,
+      11,    12,    13,    14,    15,    16,    17,    -1,    19,    20,
+      21,    22,    23,    24,    25,    26,    27,    28,    29,    -1,
+      -1,    32,    -1,    -1,    -1,    -1,    37,    11,    12,    13,
+      14,    15,    16,    17,    -1,    19,    20,    21,    22,    23,
+      24,    25,    26,    27,    28,    29,    -1,    -1,    32,    13,
+      14,    15,    16,    17,    -1,    19,    20,    21,    22,    23,
+      24,    25,    26,    27,    28,    29,    16,    17,    32,    19,
+      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
+      -1,    17,    32,    19,    20,    21,    22,    23,    24,    25,
+      26,    27,    28,    29,    -1,    -1,    32,    19,    20,    21,
+      22,    23,    24,    25,    26,    27,    28,    29,    -1,    -1,
+      32,    24,    25,    26,    27,    28,    29,    -1,    -1,    32,
+      24,    25,    26,    27,    28,    29,    -1,    -1,    32
 };
 
   /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
      symbol of state STATE-NUM.  */
-static const yytype_uint8 yystos[] =
+static const yytype_int8 yystos[] =
 {
-       0,     3,     4,     5,     6,     7,     8,     9,    10,    12,
-      23,    24,    32,    33,    34,    35,    39,    40,    40,    40,
-      40,    40,    40,    40,    40,    40,     0,    10,    11,    12,
-      13,    14,    15,    16,    18,    19,    20,    21,    22,    23,
-      24,    25,    26,    27,    28,    31,    36,    40,    40,    40,
-      40,    40,    40,    40,    40,    40,    40,    40,    40,    40,
-      40,    40,    40,    40,    40,    40,    37
+       0,     3,     4,     5,     6,     7,     8,     9,    10,    11,
+      13,    24,    25,    33,    34,    35,    36,    40,    41,    41,
+      41,    41,    41,    41,    41,    41,    41,     0,    11,    12,
+      13,    14,    15,    16,    17,    19,    20,    21,    22,    23,
+      24,    25,    26,    27,    28,    29,    32,    37,    41,    41,
+      41,    41,    41,    41,    41,    41,    41,    41,    41,    41,
+      41,    41,    41,    41,    41,    41,    41,    38
 };
 
   /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
-static const yytype_uint8 yyr1[] =
+static const yytype_int8 yyr1[] =
 {
-       0,    38,    39,    40,    40,    40,    40,    40,    40,    40,
-      40,    40,    40,    40,    40,    40,    40,    40,    40,    40,
-      40,    40,    40,    40,    40,    40,    40,    40,    40,    40,
-      40,    40,    40,    40,    40,    40,    40
+       0,    39,    40,    41,    41,    41,    41,    41,    41,    41,
+      41,    41,    41,    41,    41,    41,    41,    41,    41,    41,
+      41,    41,    41,    41,    41,    41,    41,    41,    41,    41,
+      41,    41,    41,    41,    41,    41,    41,    41
 };
 
   /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */
-static const yytype_uint8 yyr2[] =
+static const yytype_int8 yyr2[] =
 {
        0,     2,     1,     3,     3,     3,     3,     3,     3,     3,
        3,     3,     3,     3,     3,     3,     3,     3,     3,     3,
        3,     2,     2,     2,     2,     2,     2,     2,     3,     4,
-       1,     1,     1,     1,     1,     1,     1
+       1,     1,     1,     1,     1,     1,     1,     1
 };
 
 
@@ -677,22 +758,22 @@ static const yytype_uint8 yyr2[] =
 
 #define YYRECOVERING()  (!!yyerrstatus)
 
-#define YYBACKUP(Token, Value)                                  \
-do                                                              \
-  if (yychar == YYEMPTY)                                        \
-    {                                                           \
-      yychar = (Token);                                         \
-      yylval = (Value);                                         \
-      YYPOPSTACK (yylen);                                       \
-      yystate = *yyssp;                                         \
-      goto yybackup;                                            \
-    }                                                           \
-  else                                                          \
-    {                                                           \
-      yyerror (YY_("syntax error: cannot back up")); \
-      YYERROR;                                                  \
-    }                                                           \
-while (0)
+#define YYBACKUP(Token, Value)                                    \
+  do                                                              \
+    if (yychar == YYEMPTY)                                        \
+      {                                                           \
+        yychar = (Token);                                         \
+        yylval = (Value);                                         \
+        YYPOPSTACK (yylen);                                       \
+        yystate = *yyssp;                                         \
+        goto yybackup;                                            \
+      }                                                           \
+    else                                                          \
+      {                                                           \
+        yyerror (YY_("syntax error: cannot back up")); \
+        YYERROR;                                                  \
+      }                                                           \
+  while (0)
 
 /* Error token number */
 #define YYTERROR        1
@@ -732,37 +813,39 @@ do {                                                                      \
 } while (0)
 
 
-/*----------------------------------------.
-| Print this symbol's value on YYOUTPUT.  |
-`----------------------------------------*/
+/*-----------------------------------.
+| Print this symbol's value on YYO.  |
+`-----------------------------------*/
 
 static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep)
 {
-  FILE *yyo = yyoutput;
-  YYUSE (yyo);
+  FILE *yyoutput = yyo;
+  YYUSE (yyoutput);
   if (!yyvaluep)
     return;
 # ifdef YYPRINT
   if (yytype < YYNTOKENS)
-    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+    YYPRINT (yyo, yytoknum[yytype], *yyvaluep);
 # endif
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
   YYUSE (yytype);
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
 }
 
 
-/*--------------------------------.
-| Print this symbol on YYOUTPUT.  |
-`--------------------------------*/
+/*---------------------------.
+| Print this symbol on YYO.  |
+`---------------------------*/
 
 static void
-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep)
 {
-  YYFPRINTF (yyoutput, "%s %s (",
+  YYFPRINTF (yyo, "%s %s (",
              yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
 
-  yy_symbol_value_print (yyoutput, yytype, yyvaluep);
-  YYFPRINTF (yyoutput, ")");
+  yy_symbol_value_print (yyo, yytype, yyvaluep);
+  YYFPRINTF (yyo, ")");
 }
 
 /*------------------------------------------------------------------.
@@ -771,7 +854,7 @@ yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
 `------------------------------------------------------------------*/
 
 static void
-yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop)
 {
   YYFPRINTF (stderr, "Stack now");
   for (; yybottom <= yytop; yybottom++)
@@ -794,20 +877,20 @@ do {                                                            \
 `------------------------------------------------*/
 
 static void
-yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule)
+yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, int yyrule)
 {
-  unsigned long int yylno = yyrline[yyrule];
+  int yylno = yyrline[yyrule];
   int yynrhs = yyr2[yyrule];
   int yyi;
-  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+  YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n",
              yyrule - 1, yylno);
   /* The symbols being reduced.  */
   for (yyi = 0; yyi < yynrhs; yyi++)
     {
       YYFPRINTF (stderr, "   $%d = ", yyi + 1);
       yy_symbol_print (stderr,
-                       yystos[yyssp[yyi + 1 - yynrhs]],
-                       &(yyvsp[(yyi + 1) - (yynrhs)])
+                       yystos[+yyssp[yyi + 1 - yynrhs]],
+                       &yyvsp[(yyi + 1) - (yynrhs)]
                                               );
       YYFPRINTF (stderr, "\n");
     }
@@ -851,13 +934,13 @@ int yydebug;
 
 # ifndef yystrlen
 #  if defined __GLIBC__ && defined _STRING_H
-#   define yystrlen strlen
+#   define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S)))
 #  else
 /* Return the length of YYSTR.  */
-static YYSIZE_T
+static YYPTRDIFF_T
 yystrlen (const char *yystr)
 {
-  YYSIZE_T yylen;
+  YYPTRDIFF_T yylen;
   for (yylen = 0; yystr[yylen]; yylen++)
     continue;
   return yylen;
@@ -893,12 +976,12 @@ yystpcpy (char *yydest, const char *yysrc)
    backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
    null, do not copy; instead, return the length of what the result
    would have been.  */
-static YYSIZE_T
+static YYPTRDIFF_T
 yytnamerr (char *yyres, const char *yystr)
 {
   if (*yystr == '"')
     {
-      YYSIZE_T yyn = 0;
+      YYPTRDIFF_T yyn = 0;
       char const *yyp = yystr;
 
       for (;;)
@@ -911,7 +994,10 @@ yytnamerr (char *yyres, const char *yystr)
           case '\\':
             if (*++yyp != '\\')
               goto do_not_strip_quotes;
-            /* Fall through.  */
+            else
+              goto append;
+
+          append:
           default:
             if (yyres)
               yyres[yyn] = *yyp;
@@ -926,10 +1012,10 @@ yytnamerr (char *yyres, const char *yystr)
     do_not_strip_quotes: ;
     }
 
-  if (! yyres)
+  if (yyres)
+    return yystpcpy (yyres, yystr) - yyres;
+  else
     return yystrlen (yystr);
-
-  return yystpcpy (yyres, yystr) - yyres;
 }
 # endif
 
@@ -942,19 +1028,19 @@ yytnamerr (char *yyres, const char *yystr)
    *YYMSG_ALLOC to the required number of bytes.  Return 2 if the
    required number of bytes is too large to store.  */
 static int
-yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
-                yytype_int16 *yyssp, int yytoken)
+yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg,
+                yy_state_t *yyssp, int yytoken)
 {
-  YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
-  YYSIZE_T yysize = yysize0;
   enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
   /* Internationalized format string. */
   const char *yyformat = YY_NULLPTR;
-  /* Arguments of yyformat. */
+  /* Arguments of yyformat: reported tokens (one for the "unexpected",
+     one per "expected"). */
   char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
-  /* Number of reported tokens (one for the "unexpected", one per
-     "expected"). */
+  /* Actual size of YYARG. */
   int yycount = 0;
+  /* Cumulated lengths of YYARG.  */
+  YYPTRDIFF_T yysize = 0;
 
   /* There are many possibilities here to consider:
      - If this state is a consistent state with a default action, then
@@ -981,7 +1067,9 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
   */
   if (yytoken != YYEMPTY)
     {
-      int yyn = yypact[*yyssp];
+      int yyn = yypact[+*yyssp];
+      YYPTRDIFF_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
+      yysize = yysize0;
       yyarg[yycount++] = yytname[yytoken];
       if (!yypact_value_is_default (yyn))
         {
@@ -1006,11 +1094,12 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
                   }
                 yyarg[yycount++] = yytname[yyx];
                 {
-                  YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
-                  if (! (yysize <= yysize1
-                         && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+                  YYPTRDIFF_T yysize1
+                    = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
+                  if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+                    yysize = yysize1;
+                  else
                     return 2;
-                  yysize = yysize1;
                 }
               }
         }
@@ -1022,6 +1111,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
       case N:                               \
         yyformat = S;                       \
       break
+    default: /* Avoid compiler warnings. */
       YYCASE_(0, YY_("syntax error"));
       YYCASE_(1, YY_("syntax error, unexpected %s"));
       YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
@@ -1032,10 +1122,13 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
     }
 
   {
-    YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
-    if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+    /* Don't count the "%s"s in the final size, but reserve room for
+       the terminator.  */
+    YYPTRDIFF_T yysize1 = yysize + (yystrlen (yyformat) - 2 * yycount) + 1;
+    if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+      yysize = yysize1;
+    else
       return 2;
-    yysize = yysize1;
   }
 
   if (*yymsg_alloc < yysize)
@@ -1061,8 +1154,8 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
         }
       else
         {
-          yyp++;
-          yyformat++;
+          ++yyp;
+          ++yyformat;
         }
   }
   return 0;
@@ -1105,7 +1198,7 @@ int yynerrs;
 int
 yyparse (void)
 {
-    int yystate;
+    yy_state_fast_t yystate;
     /* Number of tokens to shift before error messages enabled.  */
     int yyerrstatus;
 
@@ -1117,16 +1210,16 @@ yyparse (void)
        to reallocate them elsewhere.  */
 
     /* The state stack.  */
-    yytype_int16 yyssa[YYINITDEPTH];
-    yytype_int16 *yyss;
-    yytype_int16 *yyssp;
+    yy_state_t yyssa[YYINITDEPTH];
+    yy_state_t *yyss;
+    yy_state_t *yyssp;
 
     /* The semantic value stack.  */
     YYSTYPE yyvsa[YYINITDEPTH];
     YYSTYPE *yyvs;
     YYSTYPE *yyvsp;
 
-    YYSIZE_T yystacksize;
+    YYPTRDIFF_T yystacksize;
 
   int yyn;
   int yyresult;
@@ -1140,7 +1233,7 @@ yyparse (void)
   /* Buffer for error messages, and its allocated size.  */
   char yymsgbuf[128];
   char *yymsg = yymsgbuf;
-  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+  YYPTRDIFF_T yymsg_alloc = sizeof yymsgbuf;
 #endif
 
 #define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
@@ -1161,46 +1254,54 @@ yyparse (void)
   yychar = YYEMPTY; /* Cause a token to be read.  */
   goto yysetstate;
 
+
 /*------------------------------------------------------------.
-| yynewstate -- Push a new state, which is found in yystate.  |
+| yynewstate -- push a new state, which is found in yystate.  |
 `------------------------------------------------------------*/
- yynewstate:
+yynewstate:
   /* In all cases, when you get here, the value and location stacks
      have just been pushed.  So pushing a state here evens the stacks.  */
   yyssp++;
 
- yysetstate:
-  *yyssp = yystate;
+
+/*--------------------------------------------------------------------.
+| yysetstate -- set current state (the top of the stack) to yystate.  |
+`--------------------------------------------------------------------*/
+yysetstate:
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+  YY_ASSERT (0 <= yystate && yystate < YYNSTATES);
+  YY_IGNORE_USELESS_CAST_BEGIN
+  *yyssp = YY_CAST (yy_state_t, yystate);
+  YY_IGNORE_USELESS_CAST_END
 
   if (yyss + yystacksize - 1 <= yyssp)
+#if !defined yyoverflow && !defined YYSTACK_RELOCATE
+    goto yyexhaustedlab;
+#else
     {
       /* Get the current used size of the three stacks, in elements.  */
-      YYSIZE_T yysize = yyssp - yyss + 1;
+      YYPTRDIFF_T yysize = yyssp - yyss + 1;
 
-#ifdef yyoverflow
+# if defined yyoverflow
       {
         /* Give user a chance to reallocate the stack.  Use copies of
            these so that the &'s don't force the real ones into
            memory.  */
+        yy_state_t *yyss1 = yyss;
         YYSTYPE *yyvs1 = yyvs;
-        yytype_int16 *yyss1 = yyss;
 
         /* Each stack pointer address is followed by the size of the
            data in use in that stack, in bytes.  This used to be a
            conditional around just the two extra args, but that might
            be undefined if yyoverflow is a macro.  */
         yyoverflow (YY_("memory exhausted"),
-                    &yyss1, yysize * sizeof (*yyssp),
-                    &yyvs1, yysize * sizeof (*yyvsp),
+                    &yyss1, yysize * YYSIZEOF (*yyssp),
+                    &yyvs1, yysize * YYSIZEOF (*yyvsp),
                     &yystacksize);
-
         yyss = yyss1;
         yyvs = yyvs1;
       }
-#else /* no yyoverflow */
-# ifndef YYSTACK_RELOCATE
-      goto yyexhaustedlab;
-# else
+# else /* defined YYSTACK_RELOCATE */
       /* Extend the stack our own way.  */
       if (YYMAXDEPTH <= yystacksize)
         goto yyexhaustedlab;
@@ -1209,42 +1310,43 @@ yyparse (void)
         yystacksize = YYMAXDEPTH;
 
       {
-        yytype_int16 *yyss1 = yyss;
+        yy_state_t *yyss1 = yyss;
         union yyalloc *yyptr =
-          (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+          YY_CAST (union yyalloc *,
+                   YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize))));
         if (! yyptr)
           goto yyexhaustedlab;
         YYSTACK_RELOCATE (yyss_alloc, yyss);
         YYSTACK_RELOCATE (yyvs_alloc, yyvs);
-#  undef YYSTACK_RELOCATE
+# undef YYSTACK_RELOCATE
         if (yyss1 != yyssa)
           YYSTACK_FREE (yyss1);
       }
 # endif
-#endif /* no yyoverflow */
 
       yyssp = yyss + yysize - 1;
       yyvsp = yyvs + yysize - 1;
 
-      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
-                  (unsigned long int) yystacksize));
+      YY_IGNORE_USELESS_CAST_BEGIN
+      YYDPRINTF ((stderr, "Stack size increased to %ld\n",
+                  YY_CAST (long, yystacksize)));
+      YY_IGNORE_USELESS_CAST_END
 
       if (yyss + yystacksize - 1 <= yyssp)
         YYABORT;
     }
-
-  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
 
   if (yystate == YYFINAL)
     YYACCEPT;
 
   goto yybackup;
 
+
 /*-----------.
 | yybackup.  |
 `-----------*/
 yybackup:
-
   /* Do appropriate processing given the current state.  Read a
      lookahead token if we need one and don't already have one.  */
 
@@ -1294,15 +1396,13 @@ yybackup:
 
   /* Shift the lookahead token.  */
   YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
-
-  /* Discard the shifted token.  */
-  yychar = YYEMPTY;
-
   yystate = yyn;
   YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
   *++yyvsp = yylval;
   YY_IGNORE_MAYBE_UNINITIALIZED_END
 
+  /* Discard the shifted token.  */
+  yychar = YYEMPTY;
   goto yynewstate;
 
 
@@ -1317,7 +1417,7 @@ yydefault:
 
 
 /*-----------------------------.
-| yyreduce -- Do a reduction.  |
+| yyreduce -- do a reduction.  |
 `-----------------------------*/
 yyreduce:
   /* yyn is the number of a rule to reduce with.  */
@@ -1337,218 +1437,225 @@ yyreduce:
   YY_REDUCE_PRINT (yyn);
   switch (yyn)
     {
-        case 2:
-#line 66 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, "\ndone\n"); result.exp = (yyvsp[0].exp); }
-#line 1344 "y.tab.c" /* yacc.c:1646  */
+  case 2:
+#line 68 "stella.y"
+                           { if(DEBUG_EXP) fprintf(stderr, "\ndone\n"); result.exp = (yyvsp[0].exp); }
+#line 1444 "y.tab.c"
     break;
 
   case 3:
-#line 69 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " +"); (yyval.exp) = new PlusExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
-#line 1350 "y.tab.c" /* yacc.c:1646  */
+#line 71 "stella.y"
+                                          { if(DEBUG_EXP) fprintf(stderr, " +"); (yyval.exp) = new PlusExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
+#line 1450 "y.tab.c"
     break;
 
   case 4:
-#line 70 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " -"); (yyval.exp) = new MinusExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
-#line 1356 "y.tab.c" /* yacc.c:1646  */
+#line 72 "stella.y"
+                                          { if(DEBUG_EXP) fprintf(stderr, " -"); (yyval.exp) = new MinusExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
+#line 1456 "y.tab.c"
     break;
 
   case 5:
-#line 71 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " *"); (yyval.exp) = new MultExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
-#line 1362 "y.tab.c" /* yacc.c:1646  */
+#line 73 "stella.y"
+                                          { if(DEBUG_EXP) fprintf(stderr, " *"); (yyval.exp) = new MultExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
+#line 1462 "y.tab.c"
     break;
 
   case 6:
-#line 72 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " /"); (yyval.exp) = new DivExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
-#line 1368 "y.tab.c" /* yacc.c:1646  */
+#line 74 "stella.y"
+                                          { if(DEBUG_EXP) fprintf(stderr, " /"); (yyval.exp) = new DivExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
+#line 1468 "y.tab.c"
     break;
 
   case 7:
-#line 73 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " %%"); (yyval.exp) = new ModExpression((yyvsp[-2].exp), (yyvsp[0].exp));  lastExp = (yyval.exp); }
-#line 1374 "y.tab.c" /* yacc.c:1646  */
+#line 75 "stella.y"
+                                          { if(DEBUG_EXP) fprintf(stderr, " %%"); (yyval.exp) = new ModExpression((yyvsp[-2].exp), (yyvsp[0].exp));  lastExp = (yyval.exp); }
+#line 1474 "y.tab.c"
     break;
 
   case 8:
-#line 74 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " &"); (yyval.exp) = new BinAndExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
-#line 1380 "y.tab.c" /* yacc.c:1646  */
+#line 76 "stella.y"
+                                          { if(DEBUG_EXP) fprintf(stderr, " &"); (yyval.exp) = new BinAndExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
+#line 1480 "y.tab.c"
     break;
 
   case 9:
-#line 75 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " |"); (yyval.exp) = new BinOrExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
-#line 1386 "y.tab.c" /* yacc.c:1646  */
+#line 77 "stella.y"
+                                          { if(DEBUG_EXP) fprintf(stderr, " |"); (yyval.exp) = new BinOrExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
+#line 1486 "y.tab.c"
     break;
 
   case 10:
-#line 76 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " ^"); (yyval.exp) = new BinXorExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
-#line 1392 "y.tab.c" /* yacc.c:1646  */
+#line 78 "stella.y"
+                                          { if(DEBUG_EXP) fprintf(stderr, " ^"); (yyval.exp) = new BinXorExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
+#line 1492 "y.tab.c"
     break;
 
   case 11:
-#line 77 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " <"); (yyval.exp) = new LessExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
-#line 1398 "y.tab.c" /* yacc.c:1646  */
+#line 79 "stella.y"
+                                          { if(DEBUG_EXP) fprintf(stderr, " <"); (yyval.exp) = new LessExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
+#line 1498 "y.tab.c"
     break;
 
   case 12:
-#line 78 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " >"); (yyval.exp) = new GreaterExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
-#line 1404 "y.tab.c" /* yacc.c:1646  */
+#line 80 "stella.y"
+                                          { if(DEBUG_EXP) fprintf(stderr, " >"); (yyval.exp) = new GreaterExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
+#line 1504 "y.tab.c"
     break;
 
   case 13:
-#line 79 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " >="); (yyval.exp) = new GreaterEqualsExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
-#line 1410 "y.tab.c" /* yacc.c:1646  */
+#line 81 "stella.y"
+                                          { if(DEBUG_EXP) fprintf(stderr, " >="); (yyval.exp) = new GreaterEqualsExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
+#line 1510 "y.tab.c"
     break;
 
   case 14:
-#line 80 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " <="); (yyval.exp) = new LessEqualsExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
-#line 1416 "y.tab.c" /* yacc.c:1646  */
+#line 82 "stella.y"
+                                          { if(DEBUG_EXP) fprintf(stderr, " <="); (yyval.exp) = new LessEqualsExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
+#line 1516 "y.tab.c"
     break;
 
   case 15:
-#line 81 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " !="); (yyval.exp) = new NotEqualsExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
-#line 1422 "y.tab.c" /* yacc.c:1646  */
+#line 83 "stella.y"
+                                          { if(DEBUG_EXP) fprintf(stderr, " !="); (yyval.exp) = new NotEqualsExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
+#line 1522 "y.tab.c"
     break;
 
   case 16:
-#line 82 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " =="); (yyval.exp) = new EqualsExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
-#line 1428 "y.tab.c" /* yacc.c:1646  */
+#line 84 "stella.y"
+                                          { if(DEBUG_EXP) fprintf(stderr, " =="); (yyval.exp) = new EqualsExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
+#line 1528 "y.tab.c"
     break;
 
   case 17:
-#line 83 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " >>"); (yyval.exp) = new ShiftRightExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
-#line 1434 "y.tab.c" /* yacc.c:1646  */
+#line 85 "stella.y"
+                                          { if(DEBUG_EXP) fprintf(stderr, " >>"); (yyval.exp) = new ShiftRightExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
+#line 1534 "y.tab.c"
     break;
 
   case 18:
-#line 84 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " <<"); (yyval.exp) = new ShiftLeftExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
-#line 1440 "y.tab.c" /* yacc.c:1646  */
+#line 86 "stella.y"
+                                          { if(DEBUG_EXP) fprintf(stderr, " <<"); (yyval.exp) = new ShiftLeftExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
+#line 1540 "y.tab.c"
     break;
 
   case 19:
-#line 85 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " ||"); (yyval.exp) = new LogOrExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
-#line 1446 "y.tab.c" /* yacc.c:1646  */
+#line 87 "stella.y"
+                                             { if(DEBUG_EXP) fprintf(stderr, " ||"); (yyval.exp) = new LogOrExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
+#line 1546 "y.tab.c"
     break;
 
   case 20:
-#line 86 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " &&"); (yyval.exp) = new LogAndExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
-#line 1452 "y.tab.c" /* yacc.c:1646  */
+#line 88 "stella.y"
+                                              { if(DEBUG_EXP) fprintf(stderr, " &&"); (yyval.exp) = new LogAndExpression((yyvsp[-2].exp), (yyvsp[0].exp)); lastExp = (yyval.exp); }
+#line 1552 "y.tab.c"
     break;
 
   case 21:
-#line 87 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " U-"); (yyval.exp) = new UnaryMinusExpression((yyvsp[0].exp)); lastExp = (yyval.exp); }
-#line 1458 "y.tab.c" /* yacc.c:1646  */
+#line 89 "stella.y"
+                                                { if(DEBUG_EXP) fprintf(stderr, " U-"); (yyval.exp) = new UnaryMinusExpression((yyvsp[0].exp)); lastExp = (yyval.exp); }
+#line 1558 "y.tab.c"
     break;
 
   case 22:
-#line 88 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " ~"); (yyval.exp) = new BinNotExpression((yyvsp[0].exp)); lastExp = (yyval.exp); }
-#line 1464 "y.tab.c" /* yacc.c:1646  */
+#line 90 "stella.y"
+                                                { if(DEBUG_EXP) fprintf(stderr, " ~"); (yyval.exp) = new BinNotExpression((yyvsp[0].exp)); lastExp = (yyval.exp); }
+#line 1564 "y.tab.c"
     break;
 
   case 23:
-#line 89 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " !"); (yyval.exp) = new LogNotExpression((yyvsp[0].exp)); lastExp = (yyval.exp); }
-#line 1470 "y.tab.c" /* yacc.c:1646  */
+#line 91 "stella.y"
+                                                { if(DEBUG_EXP) fprintf(stderr, " !"); (yyval.exp) = new LogNotExpression((yyvsp[0].exp)); lastExp = (yyval.exp); }
+#line 1570 "y.tab.c"
     break;
 
   case 24:
-#line 90 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " U*"); (yyval.exp) = new ByteDerefExpression((yyvsp[0].exp)); lastExp = (yyval.exp); }
-#line 1476 "y.tab.c" /* yacc.c:1646  */
+#line 92 "stella.y"
+                                           { if(DEBUG_EXP) fprintf(stderr, " U*"); (yyval.exp) = new ByteDerefExpression((yyvsp[0].exp)); lastExp = (yyval.exp); }
+#line 1576 "y.tab.c"
     break;
 
   case 25:
-#line 91 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " U@"); (yyval.exp) = new WordDerefExpression((yyvsp[0].exp)); lastExp = (yyval.exp); }
-#line 1482 "y.tab.c" /* yacc.c:1646  */
+#line 93 "stella.y"
+                                           { if(DEBUG_EXP) fprintf(stderr, " U@"); (yyval.exp) = new WordDerefExpression((yyvsp[0].exp)); lastExp = (yyval.exp); }
+#line 1582 "y.tab.c"
     break;
 
   case 26:
-#line 92 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " U<");  (yyval.exp) = new LoByteExpression((yyvsp[0].exp));  lastExp = (yyval.exp); }
-#line 1488 "y.tab.c" /* yacc.c:1646  */
+#line 94 "stella.y"
+                               { if(DEBUG_EXP) fprintf(stderr, " U<");  (yyval.exp) = new LoByteExpression((yyvsp[0].exp));  lastExp = (yyval.exp); }
+#line 1588 "y.tab.c"
     break;
 
   case 27:
-#line 93 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " U>");  (yyval.exp) = new HiByteExpression((yyvsp[0].exp));  lastExp = (yyval.exp); }
-#line 1494 "y.tab.c" /* yacc.c:1646  */
+#line 95 "stella.y"
+                               { if(DEBUG_EXP) fprintf(stderr, " U>");  (yyval.exp) = new HiByteExpression((yyvsp[0].exp));  lastExp = (yyval.exp); }
+#line 1594 "y.tab.c"
     break;
 
   case 28:
-#line 94 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " ()"); (yyval.exp) = (yyvsp[-1].exp); lastExp = (yyval.exp); }
-#line 1500 "y.tab.c" /* yacc.c:1646  */
+#line 96 "stella.y"
+                                        { if(DEBUG_EXP) fprintf(stderr, " ()"); (yyval.exp) = (yyvsp[-1].exp); lastExp = (yyval.exp); }
+#line 1600 "y.tab.c"
     break;
 
   case 29:
-#line 95 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " []"); (yyval.exp) = new ByteDerefOffsetExpression((yyvsp[-3].exp), (yyvsp[-1].exp)); lastExp = (yyval.exp); }
-#line 1506 "y.tab.c" /* yacc.c:1646  */
+#line 97 "stella.y"
+                                              { if(DEBUG_EXP) fprintf(stderr, " []"); (yyval.exp) = new ByteDerefOffsetExpression((yyvsp[-3].exp), (yyvsp[-1].exp)); lastExp = (yyval.exp); }
+#line 1606 "y.tab.c"
     break;
 
   case 30:
-#line 96 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, "const %d", (yyvsp[0].val)); (yyval.exp) = new ConstExpression((yyvsp[0].val)); lastExp = (yyval.exp); }
-#line 1512 "y.tab.c" /* yacc.c:1646  */
+#line 98 "stella.y"
+                       { if(DEBUG_EXP) fprintf(stderr, "const %d", (yyvsp[0].val)); (yyval.exp) = new ConstExpression((yyvsp[0].val)); lastExp = (yyval.exp); }
+#line 1612 "y.tab.c"
     break;
 
   case 31:
-#line 97 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, "equate %s", (yyvsp[0].Equate)); (yyval.exp) = new EquateExpression((yyvsp[0].Equate)); lastExp = (yyval.exp); }
-#line 1518 "y.tab.c" /* yacc.c:1646  */
+#line 99 "stella.y"
+                       { if(DEBUG_EXP) fprintf(stderr, "equate %s", (yyvsp[0].Equate)); (yyval.exp) = new EquateExpression((yyvsp[0].Equate)); lastExp = (yyval.exp); }
+#line 1618 "y.tab.c"
     break;
 
   case 32:
-#line 98 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " (CpuMethod)"); (yyval.exp) = new CpuMethodExpression((yyvsp[0].cpuMethod)); lastExp = (yyval.exp); }
-#line 1524 "y.tab.c" /* yacc.c:1646  */
+#line 100 "stella.y"
+                           { if(DEBUG_EXP) fprintf(stderr, " (CpuMethod)"); (yyval.exp) = new CpuMethodExpression((yyvsp[0].cpuMethod)); lastExp = (yyval.exp); }
+#line 1624 "y.tab.c"
     break;
 
   case 33:
-#line 99 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " (CartMethod)"); (yyval.exp) = new CartMethodExpression((yyvsp[0].cartMethod)); lastExp = (yyval.exp); }
-#line 1530 "y.tab.c" /* yacc.c:1646  */
+#line 101 "stella.y"
+                            { if(DEBUG_EXP) fprintf(stderr, " (CartMethod)"); (yyval.exp) = new CartMethodExpression((yyvsp[0].cartMethod)); lastExp = (yyval.exp); }
+#line 1630 "y.tab.c"
     break;
 
   case 34:
-#line 100 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " (TiaMethod)"); (yyval.exp) = new TiaMethodExpression((yyvsp[0].tiaMethod)); lastExp = (yyval.exp); }
-#line 1536 "y.tab.c" /* yacc.c:1646  */
+#line 102 "stella.y"
+                            { if(DEBUG_EXP) fprintf(stderr, " (RiotMethod)"); (yyval.exp) = new RiotMethodExpression((yyvsp[0].riotMethod)); lastExp = (yyval.exp); }
+#line 1636 "y.tab.c"
     break;
 
   case 35:
-#line 101 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " (DefinedFunction)"); (yyval.exp) = new FunctionExpression((yyvsp[0].DefinedFunction)); lastExp = (yyval.exp); }
-#line 1542 "y.tab.c" /* yacc.c:1646  */
+#line 103 "stella.y"
+                           { if(DEBUG_EXP) fprintf(stderr, " (TiaMethod)"); (yyval.exp) = new TiaMethodExpression((yyvsp[0].tiaMethod)); lastExp = (yyval.exp); }
+#line 1642 "y.tab.c"
     break;
 
   case 36:
-#line 102 "stella.y" /* yacc.c:1646  */
-    { if(DEBUG_EXP) fprintf(stderr, " ERR: "); yyerror((const char*)"Invalid label or constant"); return 1; }
-#line 1548 "y.tab.c" /* yacc.c:1646  */
+#line 104 "stella.y"
+                         { if(DEBUG_EXP) fprintf(stderr, " (DefinedFunction)"); (yyval.exp) = new FunctionExpression((yyvsp[0].DefinedFunction)); lastExp = (yyval.exp); }
+#line 1648 "y.tab.c"
+    break;
+
+  case 37:
+#line 105 "stella.y"
+               { if(DEBUG_EXP) fprintf(stderr, " ERR: "); yyerror((const char*)"Invalid label or constant"); return 1; }
+#line 1654 "y.tab.c"
     break;
 
 
-#line 1552 "y.tab.c" /* yacc.c:1646  */
+#line 1658 "y.tab.c"
+
       default: break;
     }
   /* User semantic actions sometimes alter yychar, and that requires
@@ -1573,14 +1680,13 @@ yyreduce:
   /* Now 'shift' the result of the reduction.  Determine what state
      that goes to, based on the state we popped back to and the rule
      number reduced by.  */
-
-  yyn = yyr1[yyn];
-
-  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
-  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
-    yystate = yytable[yystate];
-  else
-    yystate = yydefgoto[yyn - YYNTOKENS];
+  {
+    const int yylhs = yyr1[yyn] - YYNTOKENS;
+    const int yyi = yypgoto[yylhs] + *yyssp;
+    yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp
+               ? yytable[yyi]
+               : yydefgoto[yylhs]);
+  }
 
   goto yynewstate;
 
@@ -1612,7 +1718,7 @@ yyerrlab:
           {
             if (yymsg != yymsgbuf)
               YYSTACK_FREE (yymsg);
-            yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
+            yymsg = YY_CAST (char *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, yymsg_alloc)));
             if (!yymsg)
               {
                 yymsg = yymsgbuf;
@@ -1663,20 +1769,18 @@ yyerrlab:
 | yyerrorlab -- error raised explicitly by YYERROR.  |
 `---------------------------------------------------*/
 yyerrorlab:
-
-  /* Pacify compilers like GCC when the user code never invokes
-     YYERROR and the label yyerrorlab therefore never appears in user
-     code.  */
-  if (/*CONSTCOND*/ 0)
-     goto yyerrorlab;
+  /* Pacify compilers when the user code never invokes YYERROR and the
+     label yyerrorlab therefore never appears in user code.  */
+  if (0)
+    YYERROR;
 
   /* Do not reclaim the symbols of the rule whose action triggered
      this YYERROR.  */
-  /*YYPOPSTACK (yylen);
+  YYPOPSTACK (yylen);
   yylen = 0;
   YY_STACK_PRINT (yyss, yyssp);
   yystate = *yyssp;
-  goto yyerrlab1;*/
+  goto yyerrlab1;
 
 
 /*-------------------------------------------------------------.
@@ -1730,6 +1834,7 @@ yyacceptlab:
   yyresult = 0;
   goto yyreturn;
 
+
 /*-----------------------------------.
 | yyabortlab -- YYABORT comes here.  |
 `-----------------------------------*/
@@ -1737,6 +1842,7 @@ yyabortlab:
   yyresult = 1;
   goto yyreturn;
 
+
 #if !defined yyoverflow || YYERROR_VERBOSE
 /*-------------------------------------------------.
 | yyexhaustedlab -- memory exhaustion comes here.  |
@@ -1747,6 +1853,10 @@ yyexhaustedlab:
   /* Fall through.  */
 #endif
 
+
+/*-----------------------------------------------------.
+| yyreturn -- parsing is finished, return the result.  |
+`-----------------------------------------------------*/
 yyreturn:
   if (yychar != YYEMPTY)
     {
@@ -1763,7 +1873,7 @@ yyreturn:
   while (yyssp != yyss)
     {
       yydestruct ("Cleanup: popping",
-                  yystos[*yyssp], yyvsp);
+                  yystos[+*yyssp], yyvsp);
       YYPOPSTACK (1);
     }
 #ifndef yyoverflow
@@ -1776,5 +1886,5 @@ yyreturn:
 #endif
   return yyresult;
 }
-#line 104 "stella.y" /* yacc.c:1906  */
+#line 107 "stella.y"
 
diff --git a/src/yacc/y.tab.h b/src/yacc/y.tab.h
index d06bfd3eb..0356314bd 100644
--- a/src/yacc/y.tab.h
+++ b/src/yacc/y.tab.h
@@ -1,8 +1,9 @@
-/* A Bison parser, made by GNU Bison 3.0.4.  */
+/* A Bison parser, made by GNU Bison 3.5.1.  */
 
 /* Bison interface for Yacc-like parsers in C
 
-   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation,
+   Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -30,6 +31,9 @@
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
+/* Undocumented macros, especially those whose name start with YY_,
+   are private implementation details.  Do not rely on them.  */
+
 #ifndef YY_YY_Y_TAB_H_INCLUDED
 # define YY_YY_Y_TAB_H_INCLUDED
 /* Debug traces.  */
@@ -50,19 +54,20 @@ extern int yydebug;
     EQUATE = 260,
     CART_METHOD = 261,
     CPU_METHOD = 262,
-    TIA_METHOD = 263,
-    FUNCTION = 264,
-    LOG_OR = 265,
-    LOG_AND = 266,
-    LOG_NOT = 267,
-    SHR = 268,
-    SHL = 269,
-    GTE = 270,
-    LTE = 271,
-    NE = 272,
-    EQ = 273,
-    DEREF = 274,
-    UMINUS = 275
+    RIOT_METHOD = 263,
+    TIA_METHOD = 264,
+    FUNCTION = 265,
+    LOG_OR = 266,
+    LOG_AND = 267,
+    LOG_NOT = 268,
+    SHR = 269,
+    SHL = 270,
+    GTE = 271,
+    LTE = 272,
+    NE = 273,
+    EQ = 274,
+    DEREF = 275,
+    UMINUS = 276
   };
 #endif
 /* Tokens.  */
@@ -71,38 +76,39 @@ extern int yydebug;
 #define EQUATE 260
 #define CART_METHOD 261
 #define CPU_METHOD 262
-#define TIA_METHOD 263
-#define FUNCTION 264
-#define LOG_OR 265
-#define LOG_AND 266
-#define LOG_NOT 267
-#define SHR 268
-#define SHL 269
-#define GTE 270
-#define LTE 271
-#define NE 272
-#define EQ 273
-#define DEREF 274
-#define UMINUS 275
+#define RIOT_METHOD 263
+#define TIA_METHOD 264
+#define FUNCTION 265
+#define LOG_OR 266
+#define LOG_AND 267
+#define LOG_NOT 268
+#define SHR 269
+#define SHL 270
+#define GTE 271
+#define LTE 272
+#define NE 273
+#define EQ 274
+#define DEREF 275
+#define UMINUS 276
 
 /* Value type.  */
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-
 union YYSTYPE
 {
-#line 28 "stella.y" /* yacc.c:1909  */
+#line 28 "stella.y"
 
 	int val;
 	char* Equate;
 	CartMethod cartMethod;
 	CpuMethod cpuMethod;
+	RiotMethod riotMethod;
 	TiaMethod tiaMethod;
 	Expression* exp;
 	char* DefinedFunction;
 
-#line 104 "y.tab.h" /* yacc.c:1909  */
-};
+#line 110 "y.tab.h"
 
+};
 typedef union YYSTYPE YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1
 # define YYSTYPE_IS_DECLARED 1